speedflow 0.2.1 → 0.3.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
  SHA1:
3
- metadata.gz: 27374a1174d79f26fffb0eb47bbf2c59b89e315e
4
- data.tar.gz: 07e584e9c840f44764c33b92ee57302718aa42a0
3
+ metadata.gz: 0917a8d9f55cf6d722cbf1819dca1acf62d41262
4
+ data.tar.gz: d48c35ef4a5970b059a9d7b042100ce1bac65921
5
5
  SHA512:
6
- metadata.gz: e5bda2467bf65a6b4078a86e52cafcca8655cb991b23402557559f1ed228929b3f6768d7b965cd76f6fd0ebb6ca4f5eabd589bd66bc67a34933788711dbd6bf7
7
- data.tar.gz: 2691daaa4db69e66ffd1cc4e1f7f422a7a48dfb84ce2fab5e832c3d29912d6b96461fcab82d2627f1eee9fa816a43abd60d0bab61bd51fb2e43742fcd848c196
6
+ metadata.gz: 2797aaa19a525241bf15896d817f4a5c0f3f5b9fc275069590b866f35750e92e67e1906268485d88393be70e9bad117d0fb274f3364c5ed3995c852f058f87e2
7
+ data.tar.gz: a24938e6ed76a465575956ac154f2f73acef4714b9e64f95c8559943f5edda878baa2a845c2a1beddbb0e2837b80777aed15cf121f2edcd6e9b462203e3839b9
data/bin/speedflow CHANGED
@@ -4,6 +4,9 @@ STDOUT.sync = true
4
4
  require 'mercenary'
5
5
  require 'speedflow'
6
6
 
7
+ # Kill exiting error
8
+ Signal.trap('SIGINT') { exit 130 }
9
+
7
10
  # Speedflow program
8
11
  Mercenary.program(:speedflow) do |program|
9
12
  program.version Speedflow::VERSION
@@ -58,7 +58,7 @@ module Speedflow
58
58
  success "Trigger '#{trigger}' successful"
59
59
  rescue FlowTriggerNotFound => exception
60
60
  error "Trigger '#{trigger}' error: #{exception.message}"
61
- rescue PluginNotFound => exception
61
+ rescue Plugin::PluginNotFound => exception
62
62
  error "Plugin error: #{exception.message}"
63
63
  end
64
64
  end
@@ -12,33 +12,57 @@ module Speedflow
12
12
  #
13
13
  # Returns a Hash of config.
14
14
  def initialize(config)
15
+ # TODO: v0.4: Reinforce the SOI.
15
16
  @config = config
16
17
  end
17
18
 
18
19
  # Public: Trigger.
19
20
  #
20
21
  # trigger - Trigger name.
21
- # inputs - Inputs.
22
+ # input - Input Hash.
22
23
  #
23
24
  # Returns nothing.
24
- def trigger(trigger, inputs)
25
+ def trigger(trigger, input)
26
+ # TODO: v0.4: Change by: Configuration.not_empty_key?
27
+ # TODO: v0.4: Move to this class: Flow.trigger?
25
28
  unless @config.flow_trigger?(trigger)
26
29
  raise FlowTriggerNotFound, "Unable to trigger: #{trigger}"
27
30
  end
28
31
 
32
+ # TODO: v0.4: Move in a normal object tree: Flow > Trigger > Action
33
+ output_by_tag = {}
29
34
  output = {}
30
35
  @config['flow'][trigger.to_s].each do |step|
31
- arguments = step['arguments'] || {}
36
+ output = trigger_step(step, input, output, output_by_tag)
37
+ end
38
+ end
32
39
 
33
- step['arguments'] = transform_arguments(arguments, output, inputs)
34
- step['arguments'] = add_config_argument(arguments)
40
+ # Public: Trigger step
41
+ #
42
+ # step - Step Hash.
43
+ # input - Input Hash.
44
+ # output - Output Hash.
45
+ # output_by_tag - Output by tag Hash.
46
+ #
47
+ # Returns output Hash.
48
+ def trigger_step(step, input, output, output_by_tag)
49
+ arguments = step['arguments'] || {}
35
50
 
36
- output = plugin_manager.call_action_from_step(step)
37
- end
51
+ # TODO: v0.4: Move to a normal object: TriggerArgument
52
+ step['arguments'] = transform_arguments(arguments, output, input)
53
+ step['arguments'] = add_config_argument(arguments)
54
+
55
+ # TODO: v0.4: Move to a normal object: TriggerArgument
56
+ output = plugin_manager.action_from_step(step)
57
+ output_by_tag[step['tag']] = output if step.key? 'tag'
58
+
59
+ output.merge(output_by_tag)
38
60
  end
39
61
 
40
62
  # Public: Add config arguement
41
63
  #
64
+ # TODO: v0.4: Move to a normal object: TriggerArgument
65
+ #
42
66
  # arguments - Hash of arguments.
43
67
  #
44
68
  # Returns Hash of arguments.
@@ -53,6 +77,8 @@ module Speedflow
53
77
 
54
78
  # Public: Transform arguments (to add value)
55
79
  #
80
+ # TODO: v0.4: Move to a normal object: TriggerArgument
81
+ #
56
82
  # arguments - Hash of arguments.
57
83
  # prev_values - Hash of previous values.
58
84
  # inputs - Hash of inputs.
@@ -73,6 +99,8 @@ module Speedflow
73
99
 
74
100
  # Public: Get flat arguments from flow.
75
101
  #
102
+ # TODO: v0.4: Move to a normal object: TriggerArgument
103
+ #
76
104
  # Returns flat Array of arguments.
77
105
  def flat_arguments
78
106
  args = []
@@ -88,7 +116,7 @@ module Speedflow
88
116
  #
89
117
  # Returns an instance of plugin manager.
90
118
  def plugin_manager
91
- @plugin_manager ||= PluginManager.new(@config['plugins'])
119
+ @plugin_manager ||= Plugin::Manager.new(@config['plugins'])
92
120
  end
93
121
  end
94
122
 
@@ -1,5 +1,6 @@
1
1
  # Speedflow core
2
2
  module Speedflow
3
+ # TODO: v0.4: Remove, use TTY::Prompt.
3
4
  require 'colorize'
4
5
  # Used to manage the output message
5
6
  module Message
@@ -0,0 +1,30 @@
1
+ module Speedflow
2
+ module Plugin
3
+ # Plugin abstraction
4
+ class Abstract
5
+ # @return [Speedflow::Plugin::Configuration] Plugin configuration.
6
+ attr_reader :config
7
+
8
+ # @return [Speedflow::Plugin::Prompt] Plugin prompt.
9
+ attr_reader :prompt
10
+
11
+ # Public: Constructor
12
+ #
13
+ # config - Speedflow::Plugin::Configuration object.
14
+ # prompt - Speedflow::Plugin::Prompt object.
15
+ #
16
+ # Examples
17
+ #
18
+ # Manager.new(
19
+ # <Speedflow::Plugin::Configuration.new({})>,
20
+ # <Speedflow::Plugin::Prompt.new>)
21
+ # # => <Speedflow::Plugin::Abstract>
22
+ #
23
+ # Returns nothing.
24
+ def initialize(config, prompt)
25
+ @config = config
26
+ @prompt = prompt
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,97 @@
1
+ module Speedflow
2
+ module Plugin
3
+ # Plugin configuration
4
+ class Configuration
5
+ CONFIG_KEY = '_config'.freeze
6
+
7
+ # Initialize.
8
+ #
9
+ # arguments - Hash of arguments.
10
+ # plugin_name - Name of plugin.
11
+ #
12
+ # Examples
13
+ #
14
+ # Configuration.new({}, 'plugin')
15
+ # # => <Speedflow::Plugin::Configuration>
16
+ #
17
+ # Returns nothing.
18
+ def initialize(arguments, plugin_name)
19
+ @arguments = arguments
20
+ @plugin_name = plugin_name
21
+ end
22
+
23
+ # Public: All config.
24
+ #
25
+ # Returns Hash of all config.
26
+ def all_config
27
+ @arguments.key?(CONFIG_KEY) ? @arguments[CONFIG_KEY] : {}
28
+ end
29
+
30
+ # Public: All input.
31
+ #
32
+ # Returns Hash of all input.
33
+ def all_input
34
+ @arguments.select { |k, _| k != CONFIG_KEY }
35
+ end
36
+
37
+ # Public: Get a specific config.
38
+ #
39
+ # key - Key of config.
40
+ # default_value - Default value.
41
+ #
42
+ # Returns value of config key.
43
+ def by_config(key, default_value = '')
44
+ config = {}
45
+ if @arguments.key?(CONFIG_KEY)
46
+ if @arguments[CONFIG_KEY].key?(@plugin_name)
47
+ config = @arguments[CONFIG_KEY][@plugin_name]
48
+ end
49
+ end
50
+ config.key?(key) ? config[key].to_s : default_value.to_s
51
+ end
52
+
53
+ # Public: Get multiple config.
54
+ #
55
+ # keys_and_defaults - Hash of keys and defaults. { 'key' => 'default' }
56
+ #
57
+ # Returns Hash with values or defaults.
58
+ def by_multiple_config(keys_and_defaults)
59
+ keys_and_defaults.each { |k, v| keys_and_defaults[k] = by_config(k, v) }
60
+ end
61
+
62
+ # Public: Get an input config by key.
63
+ #
64
+ # key - Key of config.
65
+ # default_value - Default value.
66
+ #
67
+ # Returns value of input config key.
68
+ def by_input(key, default_value = '')
69
+ if @arguments.key?(key)
70
+ @arguments[key]['value'].to_s
71
+ else
72
+ default_value.to_s
73
+ end
74
+ end
75
+
76
+ # Public: Get an input config by key but required.
77
+ #
78
+ # key - Key of config.
79
+ # default_value - Default value.
80
+ #
81
+ # Returns value of input config key or Exception.
82
+ def by_required_input(key, default_value = '')
83
+ value = by_input(key, default_value)
84
+
85
+ if by_input(key).empty?
86
+ raise ConfigurationInputRequire, "Required value for '#{key}'."
87
+ end
88
+
89
+ value
90
+ end
91
+ end
92
+
93
+ # Input exception
94
+ class ConfigurationInputRequire < Exception
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,130 @@
1
+ module Speedflow
2
+ # Plugin
3
+ module Plugin
4
+ # Used to manage the plugins
5
+ class Manager
6
+ include ActiveSupport::Inflector
7
+ # TODO: V2: Remove underground prompt.
8
+ include Message
9
+
10
+ PLUGIN_BASE = 'speedflow-plugin-'.freeze
11
+
12
+ # @return [Speedflow::Plugin::Configuration] Plugin configuration object.
13
+ attr_writer :config
14
+
15
+ # @return [Speedflow::Plugin::Prompt] Plugin prompt object.
16
+ attr_writer :prompt
17
+
18
+ # Public: Constructor
19
+ #
20
+ # plugins - Array of plugins
21
+ #
22
+ # Examples
23
+ #
24
+ # Manager.new([])
25
+ # # => <Speedflow::Plugin::Manager>
26
+ #
27
+ # Returns an Arrays of plugins.
28
+ def initialize(plugins = [])
29
+ @plugins = plugins || []
30
+ load_plugins
31
+ end
32
+
33
+ # Public: Load plugins
34
+ #
35
+ # Returns nothing.
36
+ def load_plugins
37
+ @plugins.each { |plugin| require_plugin(plugin) }
38
+ end
39
+
40
+ # Public: Require a plugins (from Gem)
41
+ #
42
+ # Returns nothing.
43
+ def require_plugin(plugin)
44
+ require plugin.downcase.prepend(PLUGIN_BASE)
45
+ rescue LoadError
46
+ message = "Unable to load plugin '#{plugin}'.\n"
47
+ message << "Help: `gem install #{PLUGIN_BASE}#{plugin}`"
48
+ raise PluginNotFound, message
49
+ end
50
+
51
+ # Call action from flow step.
52
+ #
53
+ # step - Hash from flow. {plugin: '', action: '', arguments: ''}.
54
+ #
55
+ # Returns nothing.
56
+ def action_from_step(step)
57
+ plugin = plugin(step['plugin'], step['arguments'])
58
+ action(plugin, step['action'])
59
+ end
60
+
61
+ # Call plugin.
62
+ #
63
+ # plugin_name - Plugin name.
64
+ # arguments - List of arguments.
65
+ #
66
+ # Returns <Speedflow::Plugin::Abstract>.
67
+ def plugin(plugin_name, arguments)
68
+ configuration = config.new(arguments, plugin_name)
69
+ plugin_object(plugin_name).new(configuration, prompt.new)
70
+ end
71
+
72
+ # Call action.
73
+ #
74
+ # plugin_name - Plugin name.
75
+ # action_name - Action name.
76
+ # arguments - List of arguments.
77
+ #
78
+ # Returns Hash of action output.
79
+ def action(plugin, action_name)
80
+ plugin_name = plugin.class.name.split('::')[-2].downcase
81
+ action_name = action_name.prepend('action_').underscore
82
+
83
+ unless plugin.respond_to?(action_name) && plugin_name == 'test'
84
+ message = "Unable to call action: #{plugin_name}.#{action_name}"
85
+ raise PluginActionNotFound, message
86
+ end
87
+
88
+ # TODO: v0.4: Remove underground prompt.
89
+ success "Run action '#{action_name}' of '#{plugin_name}' plugin."
90
+
91
+ plugin.send action_name
92
+ end
93
+
94
+ # Public: Get plugin object from plugin name
95
+ #
96
+ # plugin_name - Plugin name.
97
+ #
98
+ # TODO: v0.4: Create Utils::name_to_object method.
99
+ #
100
+ # Returns Object.
101
+ def plugin_object(plugin_name)
102
+ plugin_name = plugin_name.downcase.capitalize
103
+
104
+ "Speedflow::Plugin::#{plugin_name}::Plugin".constantize
105
+ end
106
+
107
+ # Public: Plugin configuration object.
108
+ #
109
+ # Returns Speedflow::Plugin::Configuration.
110
+ def config
111
+ @config ||= Configuration
112
+ end
113
+
114
+ # Public: Plugin prompt object.
115
+ #
116
+ # Returns Speedflow::Plugin::Prompt.
117
+ def prompt
118
+ @prompt ||= ::TTY::Prompt
119
+ end
120
+ end
121
+
122
+ # Plugin exception
123
+ class PluginNotFound < Exception
124
+ end
125
+
126
+ # Plugin action exception
127
+ class PluginActionNotFound < Exception
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,39 @@
1
+ require 'tty-prompt'
2
+
3
+ module Speedflow
4
+ module Plugin
5
+ # Plugin prompt
6
+ class Prompt
7
+ # @return [TTY::Prompt] TTY::Prompt.
8
+ attr_writer :prompt
9
+
10
+ # Public: Errors.
11
+ #
12
+ # exception - StandardError.
13
+ #
14
+ # Returns nothing.
15
+ def errors(plugin_name, exception)
16
+ prompt.error "#{plugin_name.downcase.capitalize} errors"
17
+ prompt.warn exception.message
18
+ end
19
+
20
+ # Delegate.
21
+ #
22
+ # method - Method.
23
+ # args - Arguments.
24
+ # block - Block.
25
+ #
26
+ # Returns wathever.
27
+ def method_missing(method, *args, &block)
28
+ prompt.send(method, *args, &block)
29
+ end
30
+
31
+ # Public: TTY prompt.
32
+ #
33
+ # Returns ::TTY::Prompt instance.
34
+ def prompt
35
+ @prompt ||= ::TTY::Prompt.new
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,3 +1,3 @@
1
1
  module Speedflow
2
- VERSION = '0.2.1'.freeze
2
+ VERSION = '0.3.0'.freeze
3
3
  end
data/lib/speedflow.rb CHANGED
@@ -6,6 +6,7 @@ require 'safe_yaml/load'
6
6
  require_rel 'speedflow/*.rb'
7
7
  require_rel 'speedflow/core_ext/*.rb'
8
8
  require_rel 'speedflow/commands/*.rb'
9
+ require_rel 'speedflow/plugin/*.rb'
9
10
 
10
11
  # Speedflow core
11
12
  module Speedflow
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: speedflow
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julien Breux
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-04 00:00:00.000000000 Z
11
+ date: 2016-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: require_all
@@ -42,16 +42,16 @@ dependencies:
42
42
  name: activesupport
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '4.2'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '4.2'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: colorize
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -70,16 +70,30 @@ dependencies:
70
70
  name: safe_yaml
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '0'
75
+ version: '1.0'
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ">="
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '0'
82
+ version: '1.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: tty-prompt
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.5.0
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.5.0
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: speedflow-plugin-test
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -242,7 +256,10 @@ files:
242
256
  - lib/speedflow/core_ext/hash.rb
243
257
  - lib/speedflow/flow.rb
244
258
  - lib/speedflow/message.rb
245
- - lib/speedflow/plugin_manager.rb
259
+ - lib/speedflow/plugin/abstract.rb
260
+ - lib/speedflow/plugin/configuration.rb
261
+ - lib/speedflow/plugin/manager.rb
262
+ - lib/speedflow/plugin/prompt.rb
246
263
  - lib/speedflow/version.rb
247
264
  homepage: https://github.com/speedflow/speedflow
248
265
  licenses:
@@ -1,80 +0,0 @@
1
- module Speedflow
2
- # Used to manage the plugins
3
- class PluginManager
4
- include ActiveSupport::Inflector
5
- include Message
6
-
7
- PLUGIN_BASE = 'speedflow-plugin-'.freeze
8
-
9
- # Public: Constructor
10
- #
11
- # plugins - Array of plugins
12
- #
13
- # Examples
14
- #
15
- # PluginManager.new({})
16
- # # => <Speedflow::PluginManager>
17
- #
18
- # Returns an Arrays of plugins.
19
- def initialize(plugins = [])
20
- @plugins = plugins || []
21
- load_plugins
22
- end
23
-
24
- # Public: Load plugins
25
- #
26
- # Returns nothing.
27
- def load_plugins
28
- @plugins.each { |plugin| require_plugin(plugin) }
29
- end
30
-
31
- # Public: Require a plugins (from Gem)
32
- #
33
- # Returns nothing.
34
- def require_plugin(plugin)
35
- require plugin.downcase.prepend(PLUGIN_BASE)
36
- rescue LoadError
37
- message = "Unable to load plugin '#{plugin}'.\n"
38
- message << "Help: `gem install #{PLUGIN_BASE}#{plugin}`"
39
- raise PluginNotFound, message
40
- end
41
-
42
- # Call action from flow step.
43
- #
44
- # step - Hash from flow. {plugin: '', action: '', arguments: ''}.
45
- #
46
- # Returns nothing.
47
- def call_action_from_step(step)
48
- step['arguments'] ||= {}
49
- success "Run action '#{step['action']}' of '#{step['plugin']}' plugin."
50
- call_plugin_action(step['plugin'], step['action'], step['arguments'])
51
- end
52
-
53
- # Call plugin action.
54
- #
55
- # plugin - Plugin name.
56
- # action - Action name.
57
- # arguments - List of arguments
58
- #
59
- # Returns nothing.
60
- def call_plugin_action(plugin, action, arguments)
61
- action = underscore(action.prepend('action_'))
62
- module_name = plugin.downcase.capitalize.prepend('Speedflow::Plugin::')
63
- begin
64
- Kernel.const_get(module_name).send(action.to_s, arguments)
65
- rescue NoMethodError => exception
66
- message = "Unable to call action: #{module_name}.#{action}\n"
67
- message << exception.message
68
- raise PluginActionNotFound, message
69
- end
70
- end
71
- end
72
-
73
- # Plugin exception
74
- class PluginNotFound < Exception
75
- end
76
-
77
- # Plugin action exception
78
- class PluginActionNotFound < Exception
79
- end
80
- end