mushy 0.21.2 → 0.22.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b74a763b3548295aa4227af27f34e3472f057e9091896ecf0afa45a2e0452dfd
4
- data.tar.gz: f5a7f830dea50073856eb0ff645f0904e27f04b546fb6ace2b5f6219d94e31c1
3
+ metadata.gz: 14c83015994e50fb8e7e866d470f04ecf9eab1fe62d9703ae2057193e4096333
4
+ data.tar.gz: fbb42092b84fbe6a033796de99eebe42cd4f3a033e7fc64a4d5a52ba9d17637f
5
5
  SHA512:
6
- metadata.gz: 13a60bf45d09d7d768dab814966301d09ff7156b9c77261af1ec6f27d5e4fb11840f091034be5cd8df2e89e7ef3024503c29640269183e522e75bc8bc1261e5a
7
- data.tar.gz: 4fdf85336bcf80cfaf147f2f4e92f1e4a6956ffb9a014b89b04f57faa523c00ec9c7803909b47c10324490d70472b87bcbc063fb0877d6e8d80b333828967d24
6
+ metadata.gz: 679249c7be4eac1f69d57ebe7df82c4b5d1c7b7b68faaf88744293f1b0519e46e5d6776e0ab0db5d929ec55a47b9b4b197b51d086d3d79be991cbec326a7b85e
7
+ data.tar.gz: 0a07f13c6d8d0013e0b6ac7d24d81695d12ce3377a71fb3b7501cd09977fb2e0d35c56ac0e9f9411c899309f401e3c695dc21a753b82e177e4052fca98a036bb
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