eco-helpers 0.6.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.
Files changed (123) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.rspec +3 -0
  4. data/README.md +20 -0
  5. data/eco-helpers.gemspec +34 -0
  6. data/lib/eco-helpers.rb +15 -0
  7. data/lib/eco/api.rb +13 -0
  8. data/lib/eco/api/common.rb +10 -0
  9. data/lib/eco/api/common/people.rb +17 -0
  10. data/lib/eco/api/common/people/base_parser.rb +16 -0
  11. data/lib/eco/api/common/people/default_parsers.rb +40 -0
  12. data/lib/eco/api/common/people/default_parsers/boolean_parser.rb +28 -0
  13. data/lib/eco/api/common/people/default_parsers/date_parser.rb +33 -0
  14. data/lib/eco/api/common/people/default_parsers/multi_parser.rb +33 -0
  15. data/lib/eco/api/common/people/default_parsers/numeric_parser.rb +23 -0
  16. data/lib/eco/api/common/people/default_parsers/select_parser.rb +29 -0
  17. data/lib/eco/api/common/people/entries.rb +120 -0
  18. data/lib/eco/api/common/people/person_entry.rb +380 -0
  19. data/lib/eco/api/common/people/person_factory.rb +114 -0
  20. data/lib/eco/api/common/people/person_modifier.rb +62 -0
  21. data/lib/eco/api/common/people/person_parser.rb +140 -0
  22. data/lib/eco/api/common/people/types.rb +47 -0
  23. data/lib/eco/api/common/session.rb +15 -0
  24. data/lib/eco/api/common/session/base_session.rb +46 -0
  25. data/lib/eco/api/common/session/environment.rb +47 -0
  26. data/lib/eco/api/common/session/file_manager.rb +90 -0
  27. data/lib/eco/api/common/session/logger.rb +105 -0
  28. data/lib/eco/api/common/session/mailer.rb +92 -0
  29. data/lib/eco/api/common/session/s3_uploader.rb +110 -0
  30. data/lib/eco/api/common/version_patches.rb +11 -0
  31. data/lib/eco/api/common/version_patches/external_person.rb +11 -0
  32. data/lib/eco/api/eco_faker.rb +59 -0
  33. data/lib/eco/api/organization.rb +13 -0
  34. data/lib/eco/api/organization/account.rb +23 -0
  35. data/lib/eco/api/organization/people.rb +118 -0
  36. data/lib/eco/api/organization/policy_groups.rb +51 -0
  37. data/lib/eco/api/organization/preferences.rb +28 -0
  38. data/lib/eco/api/organization/preferences_reference.json +23 -0
  39. data/lib/eco/api/organization/presets.rb +138 -0
  40. data/lib/eco/api/organization/presets_backup.rb +220 -0
  41. data/lib/eco/api/organization/presets_values.json +10 -0
  42. data/lib/eco/api/organization/tag_tree.rb +134 -0
  43. data/lib/eco/api/organization_old.rb +73 -0
  44. data/lib/eco/api/session.rb +180 -0
  45. data/lib/eco/api/session/batch.rb +132 -0
  46. data/lib/eco/api/session/batch_job.rb +152 -0
  47. data/lib/eco/api/session/batch_jobs.rb +131 -0
  48. data/lib/eco/api/session/batch_status.rb +138 -0
  49. data/lib/eco/api/session/task.rb +92 -0
  50. data/lib/eco/api/session_config.rb +179 -0
  51. data/lib/eco/api/session_config/api.rb +47 -0
  52. data/lib/eco/api/session_config/apis.rb +78 -0
  53. data/lib/eco/api/session_config/files.rb +30 -0
  54. data/lib/eco/api/session_config/logger.rb +54 -0
  55. data/lib/eco/api/session_config/mailer.rb +65 -0
  56. data/lib/eco/api/session_config/people.rb +89 -0
  57. data/lib/eco/api/session_config/s3_bucket.rb +62 -0
  58. data/lib/eco/api/session_config/use_cases.rb +30 -0
  59. data/lib/eco/api/usecases.rb +12 -0
  60. data/lib/eco/api/usecases/base_case.rb +14 -0
  61. data/lib/eco/api/usecases/case_data.rb +13 -0
  62. data/lib/eco/api/usecases/default_cases.rb +53 -0
  63. data/lib/eco/api/usecases/default_cases/change_email_case.rb +47 -0
  64. data/lib/eco/api/usecases/default_cases/create_details_case.rb +29 -0
  65. data/lib/eco/api/usecases/default_cases/create_details_with_supervisor_case.rb +49 -0
  66. data/lib/eco/api/usecases/default_cases/delete_case.rb +20 -0
  67. data/lib/eco/api/usecases/default_cases/email_as_id_case.rb +24 -0
  68. data/lib/eco/api/usecases/default_cases/hris_case.rb +67 -0
  69. data/lib/eco/api/usecases/default_cases/new_email_case.rb +26 -0
  70. data/lib/eco/api/usecases/default_cases/new_id_case.rb +26 -0
  71. data/lib/eco/api/usecases/default_cases/refresh_presets.rb +25 -0
  72. data/lib/eco/api/usecases/default_cases/reinvite_case.rb +22 -0
  73. data/lib/eco/api/usecases/default_cases/remove_account_case.rb +36 -0
  74. data/lib/eco/api/usecases/default_cases/reset_landing_page_case.rb +24 -0
  75. data/lib/eco/api/usecases/default_cases/set_default_tag_case.rb +44 -0
  76. data/lib/eco/api/usecases/default_cases/set_supervisor_case.rb +39 -0
  77. data/lib/eco/api/usecases/default_cases/to_csv_case.rb +36 -0
  78. data/lib/eco/api/usecases/default_cases/update_details_case.rb +30 -0
  79. data/lib/eco/api/usecases/default_cases/upsert_account_case.rb +35 -0
  80. data/lib/eco/api/usecases/use_case.rb +177 -0
  81. data/lib/eco/api/usecases/use_group.rb +104 -0
  82. data/lib/eco/cli.rb +9 -0
  83. data/lib/eco/cli/input.rb +109 -0
  84. data/lib/eco/cli/input_multi.rb +137 -0
  85. data/lib/eco/cli/root.rb +8 -0
  86. data/lib/eco/cli/session.rb +9 -0
  87. data/lib/eco/cli/session/batch.rb +9 -0
  88. data/lib/eco/common.rb +7 -0
  89. data/lib/eco/common/base_cli.rb +116 -0
  90. data/lib/eco/common/language.rb +9 -0
  91. data/lib/eco/data.rb +9 -0
  92. data/lib/eco/data/crypto.rb +7 -0
  93. data/lib/eco/data/crypto/encryption.rb +318 -0
  94. data/lib/eco/data/files.rb +10 -0
  95. data/lib/eco/data/files/directory.rb +93 -0
  96. data/lib/eco/data/files/file_pattern.rb +32 -0
  97. data/lib/eco/data/files/helpers.rb +90 -0
  98. data/lib/eco/data/mapper.rb +54 -0
  99. data/lib/eco/data/random.rb +10 -0
  100. data/lib/eco/data/random/distribution.rb +133 -0
  101. data/lib/eco/data/random/fake.rb +320 -0
  102. data/lib/eco/data/random/values.rb +80 -0
  103. data/lib/eco/language.rb +12 -0
  104. data/lib/eco/language/curry.rb +28 -0
  105. data/lib/eco/language/hash_transform.rb +68 -0
  106. data/lib/eco/language/hash_transform_modifier.rb +114 -0
  107. data/lib/eco/language/match.rb +30 -0
  108. data/lib/eco/language/match_modifier.rb +190 -0
  109. data/lib/eco/language/models.rb +11 -0
  110. data/lib/eco/language/models/attribute_parser.rb +38 -0
  111. data/lib/eco/language/models/collection.rb +181 -0
  112. data/lib/eco/language/models/modifier.rb +68 -0
  113. data/lib/eco/language/models/wrap.rb +114 -0
  114. data/lib/eco/language/values_at.rb +159 -0
  115. data/lib/eco/lexic/dictionary.rb +33 -0
  116. data/lib/eco/lexic/dictionary/dictionary.txt +355484 -0
  117. data/lib/eco/lexic/dictionary/tags.json +38 -0
  118. data/lib/eco/scripting.rb +30 -0
  119. data/lib/eco/scripting/README.md +11 -0
  120. data/lib/eco/scripting/arguments.rb +40 -0
  121. data/lib/eco/tester.rb +97 -0
  122. data/lib/eco/version.rb +3 -0
  123. metadata +325 -0
@@ -0,0 +1,104 @@
1
+ module Eco
2
+ module API
3
+ module UseCases
4
+ class UseGroup
5
+
6
+ def initialize()
7
+ @usecases = {}
8
+ @cache_init = false
9
+ @cases_by_name = {}
10
+ end
11
+
12
+ def add(usecase)
13
+ raise "Expected UseCase object. Given: #{usecase}" if !usecase || !usecase.is_a?(UseCase)
14
+ name = usecase.name
15
+ type = usecase.type
16
+ puts "Warning: overriding '#{type.to_s}' case #{name}" if self.defined?(name, type: type)
17
+ @cache_init = false
18
+ @usecases[key(name, type)] = usecase
19
+ usecase
20
+ end
21
+
22
+ def define(name, type:, &block)
23
+ add(UseCase.new(name, type: type, root:self, &block))
24
+ end
25
+
26
+ def defined?(name, type: nil)
27
+ return @usecases.key?(key(name,type)) if type
28
+ name?(name)
29
+ end
30
+
31
+ def name?(name)
32
+ !!by_name[name]
33
+ end
34
+
35
+ def types(name)
36
+ return nil if !name?(name)
37
+ by_name[name].map { |usecase| usecase.type }
38
+ end
39
+
40
+ def case(name, type: nil)
41
+ return @usecases[key(name, type)] if type
42
+ return nil unless cases = by_name[name]
43
+
44
+ msg = "There are cases of different types (#{types(name).map(&:to_s).join(", ")}) named '#{name}'. You should specify a correct type"
45
+ raise msg if cases.length > 1
46
+ cases.first
47
+ end
48
+
49
+ def names
50
+ by_name.keys
51
+ end
52
+
53
+ # merges cases overriding self for exisint parsers
54
+ def merge(cases)
55
+ return self if !cases
56
+ raise "Expected a UseGroup object. Given #{cases}" if !cases.is_a?(UseGroup)
57
+ cases_hash = cases.hash
58
+
59
+ @usecases.merge!(cases_hash)
60
+
61
+ cases_hash.transform_values do |usecase|
62
+ usecase.root = self
63
+ end
64
+
65
+ @cache_init = false
66
+ self
67
+ end
68
+
69
+ protected
70
+
71
+ def hash
72
+ @usecases
73
+ end
74
+
75
+ private
76
+
77
+ def by_name
78
+ init_caches
79
+ @by_name
80
+ end
81
+
82
+ def init_caches
83
+ return true if @cache_init
84
+ @cache_init = true
85
+ @by_name = @usecases.values.group_by { |usecase| usecase.name }
86
+ end
87
+
88
+ def key(name, type)
89
+ name + type.to_s
90
+ end
91
+
92
+ def name(key)
93
+ key&.split(":").first
94
+ end
95
+
96
+ def type
97
+ key&.split(":").last&.to_sym
98
+ end
99
+
100
+ end
101
+
102
+ end
103
+ end
104
+ end
data/lib/eco/cli.rb ADDED
@@ -0,0 +1,9 @@
1
+ module Eco
2
+ module CLI
3
+ end
4
+ end
5
+
6
+ require_relative 'cli/root'
7
+ require_relative 'cli/input'
8
+ require_relative 'cli/input_multi'
9
+ require_relative 'cli/session'
@@ -0,0 +1,109 @@
1
+ module Eco
2
+ module CLI
3
+ class Input
4
+ MODES = [:both, :json, :value]
5
+
6
+ attr_reader :mode
7
+
8
+ def initialize(value, mode = :both)
9
+ @mode = mode
10
+ @mode = :both unless MODES.include?(mode)
11
+
12
+ @doc = {}
13
+ @doc['value'] = {} if self.value?
14
+ @doc['json'] = {} if self.json?
15
+
16
+ self.value = value
17
+ end
18
+
19
+ def to_h
20
+ @doc
21
+ end
22
+
23
+ def json?
24
+ @mode == :json || @mode = :both
25
+ end
26
+
27
+ def value?
28
+ @mode == :value || @mode = :both
29
+ end
30
+
31
+ def json
32
+ @doc['json'] if self.json?
33
+ end
34
+
35
+ def parse
36
+ JSON.parse(self.json) if self.json?
37
+ end
38
+
39
+ def json=(value)
40
+ @doc['value'] = value if self.value?
41
+ @doc['json'] = to_json(value) if self.json?
42
+ end
43
+
44
+ def value
45
+ return @doc['value'] if self.value?
46
+ self.parse
47
+ end
48
+
49
+ def value=(value)
50
+ @doc['value'] = value if self.value?
51
+ @doc['json'] = to_json(value) if self.json?
52
+ end
53
+
54
+ def present?(key)
55
+ self[key]&.present?
56
+ end
57
+
58
+ def empty?
59
+ return @doc['value'].keys.length == 0 if self.value?
60
+ @doc['json'].keys.length == 0
61
+ end
62
+
63
+ # merging implies that @mode is equalized to the lesser
64
+ # => :both.merge(:json) == :json ; :value.merge(:both) == :value mode
65
+ # => :json.merge(:value) will raise an exception
66
+ def merge(value)
67
+ merge_hash(hash(value))
68
+ self
69
+ end
70
+
71
+ private
72
+
73
+ def to_json(value)
74
+ if value.respond_to?(:as_json)
75
+ input.as_json
76
+ elsif value.respond_to?(:to_json)
77
+ value.to_json
78
+ end
79
+ end
80
+
81
+ def doc_mode(doc)
82
+ case doc
83
+ when String
84
+ doc = JSON.parse(doc)
85
+ return nil unless doc.is_a?(Hash)
86
+ doc_mode(doc)
87
+ when CliInput
88
+ doc.mode
89
+ when Hash
90
+ mod_json = doc.key?('json')
91
+ mod_value = doc.key?('value')
92
+ mod_json ? (mod_value ? :both : :json) : (mod_value ? :value : nil)
93
+ end
94
+ end
95
+
96
+ def hash(value)
97
+ case value
98
+ when String
99
+ JSON.parse(value)
100
+ when CliInput
101
+ value.to_h
102
+ when Hash
103
+ value
104
+ end
105
+ end
106
+
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,137 @@
1
+ module Eco
2
+ module CLI
3
+ class MultiInput
4
+ MODES = [:both, :json, :value]
5
+
6
+ attr_reader :mode
7
+
8
+ def initialize(doc = {}, mode = :both)
9
+ @mode = doc_mode(doc) || mode
10
+ @mode = :both unless MODES.include?(@mode)
11
+
12
+ @doc = {}
13
+ @doc['value'] = {} if self.value?
14
+ @doc['json'] = {} if self.json?
15
+
16
+ self.merge(doc) unless doc.empty?
17
+ end
18
+
19
+ def to_h
20
+ @doc
21
+ end
22
+
23
+ def json?
24
+ @mode == :json || @mode = :both
25
+ end
26
+
27
+ def value?
28
+ @mode == :value || @mode = :both
29
+ end
30
+
31
+ def json(key)
32
+ @doc.dig('json', key)
33
+ end
34
+
35
+ def [](key)
36
+ return @doc.dig('value', key) if self.value?
37
+ JSON.parse(@doc.dig('json', key))
38
+ end
39
+
40
+ def []=(key, value)
41
+ @doc['value'][key] = value if self.value?
42
+ @doc['json'][key] = to_json(value) if self.json?
43
+ end
44
+
45
+ def delete(key)
46
+ if self.key?(key)
47
+ value = @doc['value'].delete(key) if self.value?
48
+ value2 = JSON.parse(@doc['json'].delete(key)) if self.json?
49
+ return value if self.value?
50
+ value2
51
+ end
52
+ end
53
+
54
+ def key?(key)
55
+ return @doc['value'].key?(key) if self.value?
56
+ @doc['json'].key?(key)
57
+ end
58
+
59
+ def present?(key)
60
+ self[key]&.present?
61
+ end
62
+
63
+ def empty?
64
+ return @doc['value'].keys.length == 0 if self.value?
65
+ @doc['json'].keys.length == 0
66
+ end
67
+
68
+ # merging implies that @mode is equalized to the lesser
69
+ # => :both.merge(:json) == :json ; :value.merge(:both) == :value mode
70
+ # => :json.merge(:value) will raise an exception
71
+ def merge(value)
72
+ merge_hash(hash(value))
73
+ self
74
+ end
75
+
76
+ private
77
+
78
+ def to_json(value)
79
+ if value.respond_to?(:as_json)
80
+ input.as_json
81
+ elsif value.respond_to?(:to_json)
82
+ value.to_json
83
+ end
84
+ end
85
+
86
+ def doc_mode(doc)
87
+ case doc
88
+ when String
89
+ doc = JSON.parse(doc)
90
+ return nil unless doc.is_a?(Hash)
91
+ doc_mode(doc)
92
+ when CliInput
93
+ doc.mode
94
+ when Hash
95
+ mod_json = doc.key?('json')
96
+ mod_value = doc.key?('value')
97
+ mod_json ? (mod_value ? :both : :json) : (mod_value ? :value : nil)
98
+ end
99
+ end
100
+
101
+ def hash(value)
102
+ case value
103
+ when String
104
+ JSON.parse(value)
105
+ when CliInput
106
+ value.to_h
107
+ when Hash
108
+ value
109
+ end
110
+ end
111
+
112
+ def merge_hash(value)
113
+ err_input = "Error: merge requires a correct Hashable value or a #{self.class.name} instance."
114
+ err_incompatible = "Error: can't merge value mode with json mode."
115
+ raise err_input unless value.is_a?(Hash)
116
+ return unless !value.empty?
117
+
118
+ raise err_input if ! (mode = doc_mode(value))
119
+ raise err_incompatible if ! (new_mode = resolve_mode(mode))
120
+ @mode = new_mode
121
+
122
+ @doc.delete('json') unless self.json?
123
+ @doc.delete('value') unless self.value?
124
+
125
+ @doc['json'].merge(value['json']) if self.json?
126
+ @doc['value'].merge(value['value']) if self.value?
127
+ end
128
+
129
+ def resolve_mode(mode)
130
+ return mode if @mode == :both
131
+ return @mode if mode == :both
132
+ return mode if @mode == mode
133
+ end
134
+
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,8 @@
1
+ module Eco
2
+ module CLI
3
+ class Root < Eco::Common::BaseCLI
4
+ class_option :config_file, :aliases => "o", :type => :string,
5
+ :banner => "FILE", :desc => "specifes the session configuration file"
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ module Eco
2
+ module CLI
3
+ class Session < Eco::Common::BaseCLI
4
+
5
+ end
6
+ end
7
+ end
8
+
9
+ require_relative 'session/batch'
@@ -0,0 +1,9 @@
1
+ module Eco
2
+ module CLI
3
+ class Session
4
+ class Batch < Eco::Common::BaseCLI
5
+
6
+ end
7
+ end
8
+ end
9
+ end
data/lib/eco/common.rb ADDED
@@ -0,0 +1,7 @@
1
+ module Eco
2
+ module Common
3
+ end
4
+ end
5
+
6
+ require_relative 'common/base_cli'
7
+ require_relative 'common/language'
@@ -0,0 +1,116 @@
1
+ require 'thor'
2
+
3
+ module Eco
4
+ module Common
5
+ class BaseCLI < Thor
6
+ PIPE = "!"
7
+ CUSTOM_HELP_MAPPINGS = ["?", "help"]
8
+ ALL_HELP_MAPPINGS = Thor::HELP_MAPPINGS + CUSTOM_HELP_MAPPINGS
9
+
10
+ class_option :simulate, type: :boolean, aliases: :s, desc: "do not launch updates or rewrite files"
11
+ class_option :verbosity, type: :numeric, default: 0, desc: "defines the level of verbosity to show feedback"
12
+
13
+ class_option :input, type: :hash, default: {}, required: false, desc: "--input=json:STRING"
14
+
15
+ def self.start(given_args = ARGV, config = {})
16
+ #given_args = splat_namespaces(given_args)
17
+ given_args = BaseCLI.parse_help(given_args)
18
+ super(given_args, config)
19
+ end
20
+
21
+ # incompatible with options / arguments of Hash type
22
+ # see: parse_hash here: https://github.com/erikhuda/thor/blob/master/lib/thor/parser/arguments.rb
23
+ def self.splat_namespaces(args)
24
+ args.reduce([]) do |done, arg|
25
+ done.concat(arg.split(":"))
26
+ end
27
+ end
28
+
29
+ def self.parse_help(args)
30
+ # Help enhancement. Adapted from: https://stackoverflow.com/a/49044225/4352306
31
+ last = args.last
32
+ if args.length > 1 && help?(last)
33
+ # switch last and second last position
34
+ last = "help" if custom_help?(last)
35
+ args.insert(args.length - 2, last).pop
36
+ puts "> #{args.join(" ")}"
37
+ end
38
+ args
39
+ end
40
+
41
+ def self.help?(value)
42
+ case value
43
+ when String
44
+ ALL_HELP_MAPPINGS.include?(value)
45
+ when Symbol
46
+ help?(value.to_s)
47
+ when Array
48
+ value.any? { |v| help?(v) }
49
+ when Hash
50
+ value.keys.any { |k| help?(v) }
51
+ end
52
+ end
53
+
54
+ def self.custom_help?(value)
55
+ CUSTOM_HELP_MAPPINGS.include?(value)
56
+ end
57
+
58
+ protected
59
+
60
+ no_commands do
61
+ def input?(options)
62
+ options&.key?("input") || options&.key?(:input)
63
+ end
64
+
65
+ def input_object(input)
66
+ Eco::CLI::Input.new(input)
67
+ end
68
+
69
+ def input(value)
70
+ case
71
+ when value.is_a?(Eco::CLI::Input)
72
+ value.value
73
+ when value.is_a?(Eco::CLI::MultiInput)
74
+ value.to_h
75
+ when value.is_a?(String)
76
+ input(JSON.parse(value))
77
+ when value&.key?("input")
78
+ input(value["input"])
79
+ when value&.key?(:input)
80
+ input(value[:input])
81
+ when value&.key?("json")
82
+ JSON.parse(value["json"])
83
+ when value&.key?(:json)
84
+ JSON.parse(value[:json])
85
+ end
86
+ end
87
+
88
+ def pipe(input, args)
89
+ command, args, pipe = parse_pipe(args)
90
+ invoke command, args, {input: input_object(input)} if pipe
91
+ pipe
92
+ end
93
+
94
+ def parse_pipe(args)
95
+ args.shift if pipe = (args.first == PIPE)
96
+ subcommand = ""
97
+ if pipe
98
+ raise "Error: bad usage of pipe ('|'). Expected: '| command' " unless subcommand = args.slice!(0)
99
+ if help?(subcommand)
100
+ # Idea adapted from: https://stackoverflow.com/a/46167300/4352306
101
+ self.class.command_help(Thor::Base.shell.new, args.first)
102
+ exit
103
+ end
104
+ end
105
+ [subcommand, args, pipe]
106
+ end
107
+
108
+ def help?(value)
109
+ BaseCLI.help?(value)
110
+ end
111
+
112
+ end
113
+
114
+ end
115
+ end
116
+ end