eco-helpers 1.1.8 → 1.2.1

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: c8bb65fa77866287c89c165a152c4ae1be166ba503c84bc82b5cd0bc4f170959
4
- data.tar.gz: f929153851479707bc1cad9a44842976c278905dad9068ebeeedce82be5151c9
3
+ metadata.gz: f7f4931954cedd399ca4fc599e4e8b1e1d3f1b4502123f06063160aed254d70c
4
+ data.tar.gz: 1fc36250ebe32d93d03e59d06773a55995e831e55317b3e71ed7fc3193d3565a
5
5
  SHA512:
6
- metadata.gz: fbacc11118acf97dbc8cc8d17505ae5c436c59b4ebb68e50fcf10e388ce8212b6a520c3b81aea6c705fba67ce112ee6850b1d4421da07c20da5f3a16e1929f07
7
- data.tar.gz: '0087ea49d27a64fe48736231f6a65cac4c1ac65308ff5f17232e4d5a3928170ba9d7b758f6ea991766a0bf9d3c61e9a75d42c151c4f3dd6da63d55d7d7ce0b9b'
6
+ metadata.gz: b1519bd960047cba719b9ff5556374b4653fde6f96c666a9369b874bf1eaaa24f8737e69ed05f70c770932432e8832c3a69c9042a63e3c9add6ffc35b2c97584
7
+ data.tar.gz: 52a15098f25c0ebe4ce696356110d33fd79244a1bf9f2edbcf67a29fe5998a87a95f444adbe5e8a8c403907b8b2e9e08ef12d9bf6aa80ecb7b8cac61984c8e8f
@@ -7,5 +7,6 @@ end
7
7
 
8
8
  require_relative 'common/version_patches'
9
9
  require_relative 'common/class_helpers'
10
+ require_relative 'common/class_hierarchy'
10
11
  require_relative 'common/people'
11
12
  require_relative 'common/session'
@@ -27,6 +27,38 @@ module Eco
27
27
  end
28
28
  end
29
29
 
30
+ # Helper to normalize `key` into a correct `ruby` **constant name**
31
+ # @param key [String, Symbol] to be normalized
32
+ # @return [String] a correct constant name
33
+ def to_constant(key)
34
+ str_name = key.to_s.strip.split(/[\-\_ ]/i).compact.map do |str|
35
+ str.slice(0).upcase + str.slice(1..-1).downcase
36
+ end.join("")
37
+ end
38
+
39
+ # If the class for `name` exists, it returns it. Otherwise it generates it.
40
+ # @param name [String, Symbol] the name of the new class
41
+ # @param inherits [Class] the parent class to _inherit_ from
42
+ # @param parent_space [String] parent namespace of the generated class, if not given: `self`
43
+ # @yield [child_class] configure the new class
44
+ # @yieldparam child_class [Class] the new class
45
+ # @return [Class] the new generated class
46
+ def new_class(name, inherits:, parent_space: nil)
47
+ name = name.to_sym.freeze
48
+ class_name = to_constant(name)
49
+ parent_space = parent_space ? resolve_class(parent_space) : self
50
+ full_class_name = "#{parent_space}::#{class_name}"
51
+
52
+ unless target_class = resolve_class(full_class_name, exception: false)
53
+ target_class = Class.new(inherits)
54
+ parent_space.const_set class_name, target_class
55
+ end
56
+
57
+ target_class.tap do |klass|
58
+ yield(klass) if block_given?
59
+ end
60
+ end
61
+
30
62
  end
31
63
  end
32
64
  end
@@ -0,0 +1,48 @@
1
+ module Eco
2
+ module API
3
+ module Common
4
+ # Helpers for dynammic generation of classes based on a hierarchical model
5
+ # @attr_reader model [Hash, nil] the `model` of the current `class`
6
+ module ClassHierarchy
7
+ include Eco::API::Common::ClassHelpers
8
+
9
+ attr_reader :model
10
+
11
+ # @param value [Hash, Enumerable, String, Symbol, nil] unparsed model to be assigned to the `class`
12
+ def model=(value)
13
+ @model = parse_model(value)
14
+ end
15
+
16
+ # @return [Array<String>] the `keys` of the current class' `model`
17
+ def model_attrs
18
+ (model && model.keys) || []
19
+ end
20
+
21
+ # Thanks to this step the format on the declaration of the model is flexible
22
+ # @param value [Hash, Enumerable, String, Symbol, nil]
23
+ # @return [Hash, nil] where keys are `Symbol` s
24
+ def parse_model(model)
25
+ case model
26
+ when String
27
+ return parse_model(model.to_sym)
28
+ when Symbol
29
+ return {model => nil}
30
+ when Hash
31
+ return model.each_with_object({}) do |(k,v), hash|
32
+ hash[k.to_sym] = v
33
+ end
34
+ when Enumerable
35
+ return model.each_with_object({}) do |sub, hash|
36
+ hash.merge!(parse_model(sub))
37
+ end
38
+ when NilClass
39
+ return nil
40
+ else
41
+ raise "Incorrect model declaration, allowed String, Symbol, Hash and Enumerable. Given: #{model.class}"
42
+ end
43
+ end
44
+
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,42 @@
1
+ {
2
+ "read_only" : {
3
+ "files": "browse",
4
+ "data": "view",
5
+ "reports": "view",
6
+ "organization": null,
7
+ "people": null,
8
+ "pages": "view",
9
+ "page_editor": null,
10
+ "registers": "view"
11
+ },
12
+ "forms" : {
13
+ "files": "browse",
14
+ "data": "view",
15
+ "reports": "view",
16
+ "organization": null,
17
+ "people": "attach",
18
+ "pages": "create",
19
+ "page_editor": "basic",
20
+ "registers": "view"
21
+ },
22
+ "editor" : {
23
+ "files": "browse",
24
+ "data": "update",
25
+ "reports": "edit",
26
+ "organization": "view",
27
+ "people": "view",
28
+ "pages": "create",
29
+ "page_editor": "intermediate",
30
+ "registers": "view"
31
+ },
32
+ "administrator" : {
33
+ "files": "administrate",
34
+ "data": "administrate",
35
+ "reports": "administrate",
36
+ "organization": "administrate",
37
+ "people": "edit",
38
+ "pages": "administrate",
39
+ "page_editor": "advanced",
40
+ "registers": "dashboard"
41
+ }
42
+ }
@@ -19,73 +19,20 @@ module Eco
19
19
  # @attr_reader max [Integer] `max` **allowed** number of occurrences of the property
20
20
  # @attr_reader min [Integer] `min` **required** number of occurrences of the property
21
21
  class BasePolicy
22
- extend Eco::API::Common::ClassHelpers
22
+ extend Eco::API::Common::ClassHierarchy
23
23
 
24
- # @attr_reader model [Hash, nil] the `model` of the current `class`
25
24
  class << self
26
- attr_reader :model
27
-
28
- # @param value [Hash, Enumerable, String, Symbol, nil] unparsed model to be assigned to the `class`
29
- def model=(value)
30
- @model = parse_model(value)
31
- end
32
-
33
- # @return [Array<String>] the `keys` of the current class' `model`
34
- def model_attrs
35
- (model && model.keys) || []
36
- end
37
-
38
- # Helper to normalize `key` into a correct `ruby` **constant name**
39
- # @param key [String, Symbol] to be normalized
40
- # @return [String] a correct constant name
41
- def titleize(key)
42
- str_name = key.to_s.strip.split(/[\-\_ ]/i).compact.map do |str|
43
- str.slice(0).upcase + str.slice(1..-1).downcase
44
- end.join("")
45
- end
46
25
 
47
26
  # If the class for `key` exists, it returns it. Otherwise it generates it.
48
27
  # @note for this to work, `key` should be one of the submodels of the current class' `model`
49
28
  # @return [Eco::API::Session::Batch::BasePolicy] or subclass thereof
50
29
  def policy_class(key)
51
30
  key = key.to_sym.freeze
52
- class_name = titleize(key)
53
- full_class_name = "#{self}::#{class_name}"
54
-
55
- unless target_class = resolve_class(full_class_name, exception: false)
56
- submodel = model[key]
57
- target_class = Class.new(self) do |klass|
58
- klass.model = submodel
59
- policy_attrs *klass.model_attrs
60
- end
31
+ class_name = to_constant(key)
61
32
 
62
- self.const_set class_name, target_class
63
- end
64
-
65
- target_class
66
- end
67
-
68
- # Thanks to this step the format on the declaration of the model is flexible
69
- # @param value [Hash, Enumerable, String, Symbol, nil]
70
- # @return [Hash, nil] where keys are `Symbol` s
71
- def parse_model(model)
72
- case model
73
- when String
74
- return parse_model(model.to_sym)
75
- when Symbol
76
- return {model => nil}
77
- when Hash
78
- return model.each_with_object({}) do |(k,v), hash|
79
- hash[k.to_sym] = v
80
- end
81
- when Enumerable
82
- return model.each_with_object({}) do |sub, hash|
83
- hash.merge!(parse_model(sub))
84
- end
85
- when NilClass
86
- return nil
87
- else
88
- raise "Incorrect model declaration, allowed String, Symbol, Hash and Enumerable. Given: #{model.class}"
33
+ new_class(class_name, inherits: Eco::API::Session::Batch::BasePolicy) do |klass|
34
+ klass.model = model[key]
35
+ klass.policy_attrs *klass.model_attrs
89
36
  end
90
37
  end
91
38
 
@@ -99,7 +46,6 @@ module Eco
99
46
  var = "@#{method}".freeze
100
47
 
101
48
  define_method(method) do |&block|
102
-
103
49
  unless policy = self[attr]
104
50
  klass = self.class.policy_class(attr)
105
51
  policy = self[attr] = klass.new(attr, _parent: self)
@@ -3,54 +3,40 @@ module Eco
3
3
  class Session
4
4
  class Config
5
5
  class Workflow
6
- extend Eco::API::Common::ClassHelpers
7
-
8
- @workflow = {
9
- options: nil,
10
- load: {input: nil, people: {get: nil, filter: nil}, filter: nil},
11
- usecases: nil,
12
- launch_jobs: nil,
13
- post_launch: {usecases: nil, launch_jobs: nil},
14
- end: nil,
15
- close: nil
16
- }
6
+ extend Eco::API::Common::ClassHierarchy
7
+
8
+ WORKFLOW_MODEL = [
9
+ :options,
10
+ {load: [:input, {people: [:get, :filter]}, :filter]},
11
+ :usecases, :launch_jobs,
12
+ {post_launch: [:usecases, :launch_jobs]},
13
+ :end, :close
14
+ ]
17
15
 
18
16
  class << self
19
17
  def stages
20
- @stages ||= (@workflow || {}).keys
18
+ model_attrs
21
19
  end
22
20
 
23
- def validate_stage(stage)
24
- "Unknown Workflow stage '#{stage}'. Should be any of #{stages}" unless stages.include?(stage)
21
+ def model
22
+ super || {}
25
23
  end
26
24
 
27
- def titleize(key)
28
- str_name = key.to_s.strip.split(/[\-\_ ]/i).compact.map do |str|
29
- str.slice(0).upcase + str.slice(1..-1).downcase
30
- end.join("")
25
+ def validate_stage(stage)
26
+ "Unknown Workflow stage '#{stage}'. Should be any of #{stages}" unless stages.include?(stage)
31
27
  end
32
28
 
33
- def get_model(key)
34
- raise "Expected Symbol. Given: #{key.class}" unless key.is_a?(Symbol)
35
- workflow = @workflow[key]
36
- raise "Expected Hash. Given #{model.class}" unless !workflow || workflow.is_a?(Hash)
37
-
38
- class_name = titleize(key.to_s)
39
- full_class_name = "#{self}::#{class_name}"
29
+ def workflow_class(key)
30
+ class_name = to_constant(key.to_s)
40
31
 
41
- if target_class = resolve_class(full_class_name, exception: false)
42
- else
43
- target_class = Class.new(Eco::API::Session::Config::Workflow) do
44
- @workflow = workflow
45
- end
46
- self.const_set class_name, target_class
32
+ new_class(class_name, inherits: Eco::API::Session::Config::Workflow) do |klass|
33
+ klass.model = model[key]
47
34
  end
48
-
49
- target_class
50
35
  end
51
36
 
52
37
  end
53
38
 
39
+ self.model = WORKFLOW_MODEL
54
40
  attr_reader :config
55
41
  attr_reader :name
56
42
 
@@ -201,6 +187,7 @@ module Eco
201
187
  # @param key [Symbol, nil] cases:
202
188
  # - if `key` is not provided, it targets the _current stage_
203
189
  # - if `key` is provided, it targets the specific _sub-stage_
190
+ # @param io [Eco::API::UseCases::BaseIO] the input/output object
204
191
  # @yield [stage_workflow, io] if a `block` is provided, see `note`
205
192
  # @yieldparam stage_workflow [Eco::API::Session::Config::Workflow] the _target stage_ referred by `key`
206
193
  # @yieldparam io [Eco::API::UseCases::BaseIO] the input/output object carried througout all the _workflow_
@@ -273,7 +260,7 @@ module Eco
273
260
 
274
261
  def stage(key)
275
262
  self.class.validate_stage(key)
276
- @stages[key] ||= self.class.get_model(key).new(key, _parent: self, config: config)
263
+ @stages[key] ||= self.class.workflow_class(key).new(key, _parent: self, config: config)
277
264
  end
278
265
 
279
266
  end
@@ -43,7 +43,7 @@ module Eco
43
43
  raise "You need to provide Eco::API::UseCases::BaseIO object. Given: #{io.class}"
44
44
  end
45
45
 
46
- io = io.new(type: :import)
46
+ io = io.new(type: :import, input: io.input || [])
47
47
  @people_load.call(*io.params)
48
48
  end
49
49
  end
@@ -1,9 +1,20 @@
1
1
  ASSETS.cli.config do |cnf|
2
2
  cnf.options_set do |options_set, options|
3
3
 
4
- options_set.add(["-dry-run", "-simulate"]) do |options|
4
+ options_set.add("-entries-from") do |options, session|
5
+ options.deep_merge!(input: {entries_from: true})
6
+ end
7
+
8
+ options_set.add("-get-people") do |options, session|
9
+ options.deep_merge!(people: {
10
+ get: {from: :remote, type: :full}
11
+ })
12
+ end
13
+
14
+ options_set.add(["-dry-run", "-simulate"]) do |options, session|
5
15
  options[:dry_run] = true
6
16
  options[:simulate] = true
17
+ session.config.dry_run!
7
18
  end
8
19
 
9
20
  options_set.add("-skip-batch-policy") do |options|
@@ -4,7 +4,7 @@ ASSETS.cli.config do |config|
4
4
  io = nil
5
5
  # default rescue
6
6
  wf.rescue do |exception, io|
7
- #io.session.logger.error(exception.patch_full_message)
7
+ io.session.logger.error(exception.patch_full_message)
8
8
  wf.run(:close, io: io)
9
9
  io
10
10
  end
@@ -14,15 +14,37 @@ ASSETS.cli.config do |config|
14
14
  end
15
15
 
16
16
  wf.for(:load) do |wf_load|
17
+ active_cases = nil
18
+
17
19
  wf_load.on(:input) do |wf_input, io|
18
- io = io.new(input: config.input.get(io: io))
20
+ active_cases = config.usecases.active(io: io)
21
+
22
+ cases_with_input = active_cases.select do |usecase, data|
23
+ io.class.input_required?(usecase.type)
24
+ end
25
+
26
+ next io unless (!io.input || io.input.empty?) && !cases_with_input.empty?
27
+
28
+ if io.options.dig(:input, :entries_from)
29
+ io = io.new(input: config.input.get(io: io))
30
+ else
31
+ opt_case = cases_with_input.values.first[:option]
32
+ io = io.new(input: config.input.get(io: io, option: opt_case))
33
+ end
34
+ io
19
35
  end
20
36
 
21
37
  wf_load.on(:people) do |wf_people, io|
38
+ cases_with_people = active_cases.select do |usecase, data|
39
+ io.class.people_required?(usecase.type)
40
+ end
41
+ get_people = io.options.dig(:people, :get, :from) == :remote
42
+ next io unless !cases_with_people.empty? || get_people
22
43
  io = io.new(people: config.people(io: io))
23
44
  end
24
45
 
25
46
  wf_load.on(:filter) do |wf_filter, io|
47
+ next io unless io.people && !io.people.empty?
26
48
  io = io.new(people: config.people_filters.process(io: io))
27
49
  end
28
50
  end
@@ -24,7 +24,7 @@ module Eco
24
24
  end
25
25
 
26
26
  @options_set.each do |arg, callback|
27
- callback.call(io.options) if SCR.get_arg(arg)
27
+ callback.call(io.options, io.session) if SCR.get_arg(arg)
28
28
  end
29
29
  io.options
30
30
  end
@@ -7,9 +7,13 @@ module Eco
7
7
 
8
8
  def initialize(core_config:)
9
9
  @core_config = core_config
10
- @linked_cases = {}
10
+ @linked_opt_cases = {}
11
11
  end
12
12
 
13
+ # Integrates a usecase to the command line
14
+ # @param option_case [String] the command line option to invoke the usecase
15
+ # @param type [Symbol] the type of usecase
16
+ # @param case_name [String, nil] the name of the usecase as defined
13
17
  def add(option_case, type, case_name: nil)
14
18
  Eco::API::UseCases::UseCase.validate_type(type)
15
19
  unless callback = block_given?? Proc.new : nil
@@ -17,68 +21,83 @@ module Eco
17
21
  raise "'case_name' expected to be a String. Given: #{case_name.class}" unless case_name.is_a?(String)
18
22
  end
19
23
 
20
- @linked_cases[option_case] = {
24
+ @linked_opt_cases[option_case] = {
21
25
  type => {
22
26
  casename: case_name,
23
27
  callback: callback
24
28
  }
25
29
  }
30
+
26
31
  self
27
32
  end
28
33
 
29
- def process(io:)
30
- unless io && io.is_a?(Eco::API::UseCases::BaseIO)
31
- raise "You need to provide Eco::API::UseCases::BaseIO object. Given: #{io.class}"
32
- end
34
+ # Scopes/identifies which usecases are being invoked from the command line
35
+ # @param io [Eco::API::UseCases::BaseIO] the input/output object
36
+ # @return [Hash] where keys are cases and values a `Hash` with `option` String and `callback`
37
+ def active(io:)
38
+ return @active_cases unless !@active_cases
39
+ @active_cases = {}.tap do |opt_cases|
40
+ @linked_opt_cases.each do |option_case, types|
41
+ types.each do |type, data|
42
+ if SCR.get_arg(option_case)
43
+ usecase = nil
44
+ if case_name = data[:casename]
45
+ usecase = io.session.usecases.case(case_name, type: type)
46
+ end
33
47
 
34
- processed = false
35
- @linked_cases.each do |option, types|
36
- types.each do |type, data|
37
- if SCR.get_arg(option)
38
- processed = true
39
- io = solve_io(io: io, type: type, option: option)
40
-
41
- usecase = nil
42
- if case_name = data[:casename]
43
- usecase = io.session.usecases.case(case_name, type: type)
44
- end
48
+ if callback = data[:callback]
49
+ unless usecase
50
+ # identify usecase
51
+ usecase = callback.call(*io.params)
52
+ unless usecase.is_a?(Eco::API::UseCases::UseCase)
53
+ msg = "When adding a usecase, without specifying 'case_name:', "
54
+ msg += "the block that integrates usecase for cli option '#{option_case}'"
55
+ msg += " must return an Eco::API::UseCases::UseCase object. It returns #{usecase.class}"
56
+ raise msg
57
+ end
58
+ end
59
+ end
45
60
 
46
- if callback = data[:callback]
47
61
  if usecase
48
- callback.call(*io.params)
49
- else
50
- usecase = callback.call(*io.params)
51
- unless usecase.is_a?(Eco::API::UseCases::UseCase)
52
- msg = "When adding a usecase, without specifying 'case_name:', "
53
- msg += "the block that integrates usecase for cli option '#{option}'"
54
- msg += " must return an Eco::API::UseCases::UseCase object. It returns #{usecase.class}"
55
- raise msg
56
- end
62
+ opt_cases[usecase] = {
63
+ option: option_case,
64
+ callback: data[:callback]
65
+ }
57
66
  end
58
- end
59
67
 
60
- usecase.launch(io: io)
68
+ end
61
69
  end
62
70
  end
71
+
63
72
  end
64
- processed
65
73
  end
66
74
 
67
- private
75
+ def process(io:)
76
+ unless io && io.is_a?(Eco::API::UseCases::BaseIO)
77
+ raise "You need to provide Eco::API::UseCases::BaseIO object. Given: #{io.class}"
78
+ end
68
79
 
69
- def solve_io(io:, type:, option:)
70
- params = io.params(keyed: true).merge(type: type)
80
+ processed = false
81
+ active(io: io).each do |usecase, data|
82
+ raise "Something went wrong when scoping active cases" unless data
71
83
 
72
- if (!io.people || io.people.empty?) && io.class.people_required?(type)
73
- params.merge!(people: core_config.people(io: io))
74
- end
84
+ processed = true
75
85
 
76
- if (!io.input || io.input.empty?) && io.class.input_required?(type)
77
- input = core_config.input.get(io: io, option: option)
78
- params.merge!(input: input)
79
- end
86
+ params = io.params(keyed: true).merge(type: usecase.type)
87
+
88
+ #if (!io.people || io.people.empty?) && io.class.people_required?(type)
89
+ # params.merge!(people: core_config.people(io: io))
90
+ #end
80
91
 
81
- io.new(**params)
92
+ io.new(**params)
93
+
94
+ if callback = data[:callback]
95
+ callback.call(*io.params)
96
+ end
97
+
98
+ usecase.launch(io: io)
99
+ end
100
+ processed
82
101
  end
83
102
 
84
103
  end
data/lib/eco/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Eco
2
- VERSION = "1.1.8"
2
+ VERSION = "1.2.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eco-helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.8
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oscar Segura
@@ -216,6 +216,7 @@ files:
216
216
  - lib/eco/api.rb
217
217
  - lib/eco/api/common.rb
218
218
  - lib/eco/api/common/class_helpers.rb
219
+ - lib/eco/api/common/class_hierarchy.rb
219
220
  - lib/eco/api/common/people.rb
220
221
  - lib/eco/api/common/people/base_parser.rb
221
222
  - lib/eco/api/common/people/default_parsers.rb
@@ -262,6 +263,7 @@ files:
262
263
  - lib/eco/api/organization/preferences.rb
263
264
  - lib/eco/api/organization/preferences_reference.json
264
265
  - lib/eco/api/organization/presets_factory.rb
266
+ - lib/eco/api/organization/presets_reference.json
265
267
  - lib/eco/api/organization/presets_values.json
266
268
  - lib/eco/api/organization/tag_tree.rb
267
269
  - lib/eco/api/policies.rb
@@ -381,7 +383,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
381
383
  - !ruby/object:Gem::Version
382
384
  version: '0'
383
385
  requirements: []
384
- rubygems_version: 3.0.4
386
+ rubygems_version: 3.0.3
385
387
  signing_key:
386
388
  specification_version: 4
387
389
  summary: eco-helpers to manage people api cases