eco-helpers 1.1.8 → 1.2.1

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: 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