mushy 0.21.2 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b74a763b3548295aa4227af27f34e3472f057e9091896ecf0afa45a2e0452dfd
4
- data.tar.gz: f5a7f830dea50073856eb0ff645f0904e27f04b546fb6ace2b5f6219d94e31c1
3
+ metadata.gz: 5e76c4fac239938383546eb9dcec5faa82b28dc94663343c3c16345ddf45ee5f
4
+ data.tar.gz: d5a6e435fa286e0cba5e52bc43752c7a2723d629c15566c214dfab368de00d06
5
5
  SHA512:
6
- metadata.gz: 13a60bf45d09d7d768dab814966301d09ff7156b9c77261af1ec6f27d5e4fb11840f091034be5cd8df2e89e7ef3024503c29640269183e522e75bc8bc1261e5a
7
- data.tar.gz: 4fdf85336bcf80cfaf147f2f4e92f1e4a6956ffb9a014b89b04f57faa523c00ec9c7803909b47c10324490d70472b87bcbc063fb0877d6e8d80b333828967d24
6
+ metadata.gz: 06ed9957d991a0158ddd30b62cf5c2652ec1271f117479e0f4f240bb8b24f0d735e921b9be32f373e5d96f614e8623a1d8e924c52e919173a7e4c8da60446bac
7
+ data.tar.gz: e1d42f2ed6a29433a0c802d46a840e13f5516d607436a2044c8da8265fcc465db29a8aa081c787409ab296f590f5eb045e32126e9050c8f4a08485a19408052e
data/bin/mushy CHANGED
@@ -4,7 +4,6 @@ require 'thor'
4
4
  require 'mushy'
5
5
 
6
6
  class MushyCLI < Thor
7
-
8
7
  argument :file, optional: true, type: :string
9
8
  argument :values, optional: true, type: :hash
10
9
 
@@ -16,29 +15,26 @@ class MushyCLI < Thor
16
15
 
17
16
  desc "build FILE", 'Build a flow.'
18
17
  def build
19
-
20
- MushyCLI.set_special( { method: 'build', file: file } )
21
-
18
+ MushyCLI.set_special_values( { method: 'build', file: file } )
22
19
  end
23
20
 
24
- def self.set_special data
21
+ def self.set_special_values data
25
22
  @special = data
26
23
  end
27
24
 
28
- def self.get_special
25
+ def self.get_special_values
29
26
  @special
30
27
  end
31
-
32
28
  end
33
29
 
34
30
  MushyCLI.start(ARGV)
35
31
 
36
- exit unless MushyCLI.get_special
32
+ exit unless MushyCLI.get_special_values
37
33
 
38
34
  require 'sinatra'
39
35
  enable :run
40
36
 
41
- the_file = MushyCLI.get_special[:file]
37
+ the_file = MushyCLI.get_special_values[:file]
42
38
 
43
39
  get '/' do
44
40
  Mushy::Builder::Index.file
@@ -1,191 +1,185 @@
1
1
  require 'daemons'
2
2
 
3
- module Mushy
3
+ module Mushy::Builder
4
+ end
4
5
 
5
- module Builder
6
+ module Mushy::Builder::Api
7
+ def self.run(data)
8
+ data = SymbolizedHash.new JSON.parse(data)
6
9
 
7
- module Api
10
+ event = SymbolizedHash.new JSON.parse(data[:setup][:event].to_json)
8
11
 
9
- def self.run data
12
+ config = SymbolizedHash.new data[:config]
10
13
 
11
- data = SymbolizedHash.new JSON.parse(data)
14
+ flux = Mushy::Flow.build_flux({ type: data[:setup][:flux], config: config })
12
15
 
13
- event = SymbolizedHash.new JSON.parse(data[:setup][:event].to_json)
16
+ result = flux.execute event
14
17
 
15
- config = SymbolizedHash.new data[:config]
16
-
17
- flux = Mushy::Flow.build_flux( { type: data[:setup][:flux], config: config } )
18
-
19
- result = flux.execute event
20
-
21
- [result].flatten
22
- end
23
-
24
- def self.save file, data
25
-
26
- file = "#{file}.mushy" unless file.downcase.end_with?('.mushy')
27
-
28
- data = SymbolizedHash.new JSON.parse(data)
29
- Mushy::WriteFile.new.process( {}, { name: file, data: JSON.pretty_generate(data) })
30
-
31
- end
32
-
33
- def self.start file, event
34
- original_file = file
35
- file = [file, "#{Dir.home}/.mushy/#{file}"]
36
- .map { |x| (x.downcase.end_with?('.mushy') ? x : "#{x}.mushy") }
37
- .select { |x| File.exist?(x) }
38
- .first
39
-
40
- unless file
41
- puts "#{original_file} does not exist."
42
- return
43
- end
44
-
45
- flow = File.open(file).read
46
- flow = Mushy::Flow.parse flow
18
+ [result].flatten
19
+ end
47
20
 
48
- service_fluxes = flow.fluxs.select { |x| x.respond_to? :loop }
21
+ def self.save(file, data)
22
+ file = "#{file}.mushy" unless file.downcase.end_with?('.mushy')
49
23
 
50
- pwd = Dir.pwd
24
+ data = SymbolizedHash.new JSON.parse(data)
25
+ Mushy::WriteFile.new.process({}, { name: file, data: JSON.pretty_generate(data) })
26
+ end
51
27
 
52
- if service_fluxes.any?
28
+ def self.start(file, event)
29
+ original_file = file
30
+ file = [file, "#{Dir.home}/.mushy/#{file}"]
31
+ .map { |x| (x.downcase.end_with?('.mushy') ? x : "#{x}.mushy") }
32
+ .select { |x| File.exist?(x) }
33
+ .first
53
34
 
54
- things = service_fluxes
55
- .map { |s| { flux: s, proc: ->(e) do
56
- Dir.chdir pwd
57
- Mushy::Runner.new.start e, s, flow
58
- end,
59
- run_method: (s.config[:run_strategy] == 'daemon' ? :run_this_as_a_daemon : :run_this_inline),
60
- }
61
- }.group_by { |x| x[:run_method] }
35
+ unless file
36
+ puts "#{original_file} does not exist."
37
+ return
38
+ end
62
39
 
63
- calls = (things[:run_this_as_a_daemon] || [])
64
- .map { |p| ->() { p[:flux].loop &p[:proc] } }
65
- .map { |x| ->() { loop &x } }
66
- .map { |x| run_this_as_a_daemon &x }
40
+ flow = File.open(file).read
41
+ flow = Mushy::Flow.parse flow
67
42
 
68
- (things[:run_this_inline] || [])
69
- .map { |p| ->() { p[:flux].loop &p[:proc] } }
70
- .map { |x| ->() { loop &x } }
71
- .map { |x| run_this_inline &x }
43
+ service_fluxes = flow.fluxs.select { |x| x.respond_to? :loop }
72
44
 
73
- exit
74
- end
45
+ pwd = Dir.pwd
75
46
 
76
- cli_flux = flow.fluxs.select { |x| x.kind_of?(Mushy::Cli) }.first
47
+ if service_fluxes.any?
77
48
 
78
- Mushy::Runner.new.start event, cli_flux, flow
79
- end
49
+ things = service_fluxes
50
+ .map do |s|
51
+ {
52
+ flux: s,
53
+ proc: lambda do |e|
54
+ Dir.chdir(pwd)
55
+ Mushy::Runner.new.start(e, s, flow)
56
+ end,
57
+ run_method: (s.config[:run_strategy] == 'daemon' ? :run_this_as_a_daemon : :run_this_inline)
58
+ }
59
+ end.group_by { |x| x[:run_method] }
80
60
 
81
- def self.run_this_inline &block
82
- block.call
83
- end
61
+ (things[:run_this_as_a_daemon] || [])
62
+ .map { |p| -> { p[:flux].loop(&p[:proc]) } }
63
+ .map { |x| -> { loop(&x) } }
64
+ .map { |x| run_this_as_a_daemon(&x) }
84
65
 
85
- def self.run_this_as_a_daemon &block
86
- Daemons.call(&block).pid.pid
87
- end
66
+ (things[:run_this_inline] || [])
67
+ .map { |p| -> { p[:flux].loop(&p[:proc]) } }
68
+ .map { |x| -> { loop(&x) } }
69
+ .map { |x| run_this_inline(&x) }
88
70
 
89
- def self.get_flow file
90
- file = "#{file}.mushy" unless file.downcase.end_with?('.mushy')
91
- data = JSON.parse File.open(file).read
71
+ exit
72
+ end
92
73
 
93
- data['fluxs'] = standardize_these data['fluxs']
94
- data['fluxs'] = organize_as_a_flattened_tree_based_on_parents data['fluxs']
74
+ cli_flux = flow.fluxs.select { |x| x.is_a?(Mushy::Cli) }.first
95
75
 
96
- data
97
- rescue
98
- { fluxs: [] }
99
- end
76
+ Mushy::Runner.new.start event, cli_flux, flow
77
+ end
100
78
 
101
- def self.standardize_these fluxs
102
- fluxs
103
- .reject { |x| x['parents'] }
104
- .each { |x| x['parents'] = [x['parent']].select { |y| y } }
105
- fluxs
106
- .select { |x| x['parent'] }
107
- .each { |x| x.delete 'parent' }
108
- fluxs
109
- .select { |x| x['parents'] }
110
- .each { |x| x['parents'] = x['parents'].select { |y| y } }
111
-
112
- fluxs
113
- end
79
+ def self.run_this_inline(&block)
80
+ block.call
81
+ end
114
82
 
115
- def self.organize_as_a_flattened_tree_based_on_parents fluxs
116
- fluxs = fluxs.sort_by { |x| x['parents'].count }
83
+ def self.run_this_as_a_daemon(&block)
84
+ Daemons.call(&block).pid.pid
85
+ end
117
86
 
118
- new_fluxs = [fluxs.first]
87
+ def self.get_flow(file)
88
+ file = "#{file}.mushy" unless file.downcase.end_with?('.mushy')
89
+ data = JSON.parse File.open(file).read
119
90
 
120
- loop do
91
+ data['fluxs'] = standardize_these data['fluxs']
92
+ data['fluxs'] = organize_as_a_flattened_tree_based_on_parents data['fluxs']
121
93
 
122
- next_fluxs = fluxs.select { |x| x['parents'].include? new_fluxs[-1]['id'] }
94
+ data
95
+ rescue
96
+ { fluxs: [] }
97
+ end
123
98
 
124
- unless next_fluxs.any?
125
- next_fluxs = [fluxs.reject { |x| new_fluxs.map { |y| y['id'] }.include?(x['id']) }[0]].select { |x| x }
126
- end
99
+ def self.standardize_these(fluxs)
100
+ fluxs
101
+ .reject { |x| x['parents'] }
102
+ .each { |x| x['parents'] = [x['parent']].select { |y| y } }
103
+ fluxs
104
+ .select { |x| x['parent'] }
105
+ .each { |x| x.delete 'parent' }
106
+ fluxs
107
+ .select { |x| x['parents'] }
108
+ .each { |x| x['parents'] = x['parents'].select { |y| y } }
109
+
110
+ fluxs
111
+ end
127
112
 
128
- new_fluxs = [new_fluxs, next_fluxs].flatten
113
+ def self.organize_as_a_flattened_tree_based_on_parents(fluxs)
114
+ fluxs = fluxs.sort_by { |x| x['parents'].count }
129
115
 
130
- break unless next_fluxs.any?
116
+ new_fluxs = [fluxs.first]
131
117
 
132
- end
118
+ loop do
119
+ next_fluxs = fluxs.select { |x| x['parents'].include? new_fluxs[-1]['id'] }
133
120
 
134
- new_fluxs
121
+ unless next_fluxs.any?
122
+ next_fluxs = [fluxs.reject { |x| new_fluxs.map { |y| y['id'] }.include?(x['id']) }[0]].select { |x| x }
135
123
  end
136
124
 
137
- def self.get_fluxs
138
- {
139
- fluxs: Mushy::Flux.all.select { |x| x.respond_to? :details }.select { |x| x.details }.map do |flux|
140
- details = flux.details
141
-
142
- details[:documentation] = Documentation.build_from details
143
-
144
- details[:config][:incoming_split] = { type: 'text', shrink: true, description: 'Split an incoming event into multiple events by this key, an each event will be processed independently.', default: '' }
145
- details[:config][:outgoing_split] = { type: 'text', shrink: true, description: 'Split an outgoing event into multiple events by this key.', default: '' }
146
- details[:config][:merge] = { type: 'text', shrink: true, description: 'A comma-delimited list of fields from the event to carry through. Use * to merge all fields.', default: '' }
147
- details[:config][:group] = { type: 'text', shrink: true, description: 'Group events by this key, with the value as the key. If a group key is provided like group_by|group_key, then multiple events with the results under group_key will be returned.', default: '' }
148
- details[:config][:limit] = { type: 'integer', shrink: true, description: 'Limit the number of events to this number.', default: '' }
149
- details[:config][:join] = { type: 'text', shrink: true, description: 'Join all of the events from this flux into one event, under this name.', default: '' }
150
- details[:config][:sort] = { type: 'text', shrink: true, description: 'Sort by this key.', default: '' }
151
- details[:config][:ignore] = { type: 'text', shrink: true, description: 'Ignore these keys.', value: '', default: '' }
152
- details[:config][:model] = { type: 'keyvalue', shrink: true, description: 'Reshape the outgoing events.', value: {}, default: {} }
153
-
154
- details[:config][:error_strategy] = {
155
- description: 'Error strategy. (return to return an event with "exception" returning the error, or ignore to ignore the exception)',
156
- type: 'select',
157
- options: ['', 'return', 'ignore'],
158
- value: '',
159
- shrink: true,
160
- }
161
-
162
- if flux.new.respond_to? :loop
163
- details[:config][:run_strategy] = {
164
- description: 'Run this using this strategy. (select "daemon" if this should be run in the background)',
165
- type: 'select',
166
- options: ['', 'inline', 'daemon'],
167
- value: '',
168
- shrink: true,
169
- }
170
- end
171
-
172
- details[:config]
173
- .select { |_, v| v[:type] == 'keyvalue' }
174
- .select { |_, v| v[:editors].nil? }
175
- .each do |_, v|
176
- v[:editors] = [
177
- { id: 'new_key', target: 'key', field: { type: 'text', value: '', default: '' } },
178
- { id: 'new_value', target: 'value', field: { type: 'text', value: '', default: '' } }
179
- ]
180
- end
181
-
182
- details
183
- end.sort_by { |x| x[:name] }
184
- }
185
- end
125
+ new_fluxs = [new_fluxs, next_fluxs].flatten
186
126
 
127
+ break unless next_fluxs.any?
187
128
  end
188
129
 
130
+ new_fluxs
189
131
  end
190
132
 
191
- end
133
+ def self.get_fluxs
134
+ {
135
+ fluxs: Mushy::Flux.all
136
+ .select { |x| x.respond_to? :details }
137
+ .select(&:details)
138
+ .map do |flux|
139
+ details = flux.details
140
+
141
+ details[:documentation] = Mushy::Builder::Documentation.build_from details
142
+
143
+ details[:config][:incoming_split] = { type: 'text', shrink: true, description: 'Split an incoming event into multiple events by this key, an each event will be processed independently.', default: '' }
144
+ details[:config][:outgoing_split] = { type: 'text', shrink: true, description: 'Split an outgoing event into multiple events by this key.', default: '' }
145
+ details[:config][:merge] = { type: 'text', shrink: true, description: 'A comma-delimited list of fields from the event to carry through. Use * to merge all fields.', default: '' }
146
+ details[:config][:group] = { type: 'text', shrink: true, description: 'Group events by this key, with the value as the key. If a group key is provided like group_by|group_key, then multiple events with the results under group_key will be returned.', default: '' }
147
+ details[:config][:limit] = { type: 'integer', shrink: true, description: 'Limit the number of events to this number.', default: '' }
148
+ details[:config][:join] = { type: 'text', shrink: true, description: 'Join all of the events from this flux into one event, under this name.', default: '' }
149
+ details[:config][:sort] = { type: 'text', shrink: true, description: 'Sort by this key.', default: '' }
150
+ details[:config][:ignore] = { type: 'text', shrink: true, description: 'Ignore these keys.', value: '', default: '' }
151
+ details[:config][:model] = { type: 'keyvalue', shrink: true, description: 'Reshape the outgoing events.', value: {}, default: {} }
152
+
153
+ details[:config][:error_strategy] = {
154
+ description: 'Error strategy. (return to return an event with "exception" returning the error, or ignore to ignore the exception)',
155
+ type: 'select',
156
+ options: ['', 'return', 'ignore'],
157
+ value: '',
158
+ shrink: true
159
+ }
160
+
161
+ if flux.new.respond_to? :loop
162
+ details[:config][:run_strategy] = {
163
+ description: 'Run this using this strategy. (select "daemon" if this should be run in the background)',
164
+ type: 'select',
165
+ options: ['', 'inline', 'daemon'],
166
+ value: '',
167
+ shrink: true
168
+ }
169
+ end
170
+
171
+ details[:config]
172
+ .select { |_, v| v[:type] == 'keyvalue' }
173
+ .select { |_, v| v[:editors].nil? }
174
+ .each do |_, v|
175
+ v[:editors] = [
176
+ { id: 'new_key', target: 'key', field: { type: 'text', value: '', default: '' } },
177
+ { id: 'new_value', target: 'value', field: { type: 'text', value: '', default: '' } }
178
+ ]
179
+ end
180
+
181
+ details
182
+ end.sort_by { |x| x[:name] }
183
+ }
184
+ end
185
+ end
@@ -479,6 +479,7 @@ module Mushy
479
479
  Vue.set(app.results, 'errorMessage', '');
480
480
  var the_setup = thingToData(app.setup);
481
481
  the_setup.event = c.test_event;
482
+ c['_test_mode'] = true;
482
483
  axios.post('/run', { config: c, setup: the_setup })
483
484
  .then(function(r){
484
485
  Vue.set(app.setup.testResultModal, 'is-active', true);
data/lib/mushy/flux.rb CHANGED
@@ -63,7 +63,8 @@ module Mushy
63
63
  the_original_join = mashed_config[:join]
64
64
  mashed_config[:join] = nil if mashed_config[:incoming_split]
65
65
 
66
- results = process event, mashed_config
66
+ method = config[:_test_mode] && respond_to?(:test) ? :test : :process
67
+ results = send(method, event, mashed_config)
67
68
 
68
69
  returned_one_result = results.is_a?(Hash)
69
70
 
@@ -1,66 +1,58 @@
1
- module Mushy
2
-
3
- class Bash < Flux
4
-
5
- def self.details
6
- {
7
- name: 'Bash',
8
- title: 'Execute a command via bash',
9
- description: 'Run a bash command.',
10
- fluxGroup: { name: 'Execute' },
11
- config: {
12
- command: {
13
- description: 'The command to run in bash.',
14
- type: 'text',
15
- value: '{{command}}',
16
- },
17
- directory: {
18
- description: 'The working directory in which the command will be run.',
19
- type: 'text',
20
- shrink: true,
21
- value: '',
22
- },
1
+ class Mushy::Bash < Mushy::Flux
2
+ def self.details
3
+ {
4
+ name: 'Bash',
5
+ title: 'Execute a command via bash',
6
+ description: 'Run a bash command.',
7
+ fluxGroup: { name: 'Execute' },
8
+ config: {
9
+ command: {
10
+ description: 'The command to run in bash.',
11
+ type: 'text',
12
+ value: '{{command}}'
13
+ },
14
+ directory: {
15
+ description: 'The working directory in which the command will be run.',
16
+ type: 'text',
17
+ shrink: true,
18
+ value: ''
19
+ }
20
+ },
21
+ examples: {
22
+ 'Successful Call' => {
23
+ description: 'This will run the ls command and return the full bash result.',
24
+ input: { command: 'ls' },
25
+ result: {
26
+ text: "bin\nblue_heart.png\nthe_output.txt\n",
27
+ success: true,
28
+ exit_code: 0
29
+ }
23
30
  },
24
- examples: {
25
- "Successful Call" => {
26
- description: 'This will run the ls command and return the full bash result.',
27
- input: {
28
- command: "ls",
29
- },
30
- result: {
31
- "text": "bin\nblue_heart.png\nthe_output.txt\n",
32
- "success": true,
33
- "exit_code": 0
34
- }
35
- },
36
- "Failed Call" => {
37
- description: 'This is an example of what happens when the command fails.',
38
- input: { command: 'rm file_that_does_not_exist.txt' },
39
- result: {
40
- "text": "",
41
- "success": false,
42
- "exit_code": 256
43
- }
44
- },
31
+ 'Failed Call' => {
32
+ description: 'This is an example of what happens when the command fails.',
33
+ input: { command: 'rm file_that_does_not_exist.txt' },
34
+ result: {
35
+ text: '',
36
+ success: false,
37
+ exit_code: 256
45
38
  }
39
+ }
46
40
  }
47
- end
48
-
49
- def process event, config
50
- command = config[:command]
41
+ }
42
+ end
51
43
 
52
- command = "cd #{config[:directory]};#{command}" if config[:directory]
44
+ def process(_, config)
45
+ command = config[:command]
53
46
 
54
- text = `#{command}`
47
+ command = "cd #{config[:directory]};#{command}" if config[:directory]
55
48
 
56
- result = $?
57
- {
58
- text: text,
59
- success: result.success?,
60
- exit_code: result.to_i,
61
- }
62
- end
49
+ text = `#{command}`
63
50
 
51
+ result = $?
52
+ {
53
+ text: text,
54
+ success: result.success?,
55
+ exit_code: result.to_i
56
+ }
64
57
  end
65
-
66
- end
58
+ end