eco-helpers 3.0.14 → 3.0.16
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 +4 -4
- data/CHANGELOG.md +41 -2
- data/eco-helpers.gemspec +15 -14
- data/lib/eco/api/common/people/default_parsers/date_parser.rb +6 -0
- data/lib/eco/api/common/session/mailer/aws_provider.rb +85 -0
- data/lib/eco/api/common/session/mailer/provider_base.rb +61 -0
- data/lib/eco/api/common/session/mailer/sendgrid_provider.rb +117 -0
- data/lib/eco/api/common/session/mailer.rb +42 -71
- data/lib/eco/api/microcases/people_refresh.rb +1 -1
- data/lib/eco/api/session/batch/errors.rb +2 -2
- data/lib/eco/api/session/batch.rb +83 -37
- data/lib/eco/api/session/config/api.rb +96 -37
- data/lib/eco/api/session/config/apis/enviro_spaces.rb +106 -0
- data/lib/eco/api/session/config/apis/one_off.rb +94 -0
- data/lib/eco/api/session/config/apis/service_up.rb +37 -0
- data/lib/eco/api/session/config/apis/space_helpers.rb +41 -0
- data/lib/eco/api/session/config/apis.rb +81 -132
- data/lib/eco/api/session/config.rb +21 -3
- data/lib/eco/api/usecases/default_cases/samples/sftp_case.rb +1 -1
- data/lib/eco/api/usecases/graphql/helpers/base/error_handling.rb +19 -8
- data/lib/eco/api/usecases/graphql/helpers/base/graphql_env.rb +1 -0
- data/lib/eco/api/usecases/graphql/samples/location/command/dsl.rb +3 -7
- data/lib/eco/api/usecases/graphql/samples/location/command/service/tree_update.rb +6 -2
- data/lib/eco/cli/config/options_set.rb +10 -7
- data/lib/eco/cli/scripting/args_helpers.rb +18 -9
- data/lib/eco/cli_default/options.rb +8 -0
- data/lib/eco/cli_default/people.rb +3 -3
- data/lib/eco/language/basic_logger.rb +4 -2
- data/lib/eco/version.rb +1 -1
- metadata +37 -16
@@ -2,8 +2,9 @@ module Eco
|
|
2
2
|
module API
|
3
3
|
class Session
|
4
4
|
class Batch < Common::Session::BaseSession
|
5
|
-
|
6
|
-
|
5
|
+
DEFAULT_BATCH_SIZE = 50
|
6
|
+
DEFAULT_JOB_SIZE = 100
|
7
|
+
VALID_METHODS = %i[get create update upsert delete].freeze
|
7
8
|
|
8
9
|
class << self
|
9
10
|
# @return [Boolean] `true` if the method is supported, `false` otherwise.
|
@@ -12,13 +13,19 @@ module Eco
|
|
12
13
|
end
|
13
14
|
end
|
14
15
|
|
16
|
+
def batch_size(opts = options)
|
17
|
+
return self.class::DEFAULT_JOB_SIZE if job_mode?(opts)
|
18
|
+
|
19
|
+
self.class::DEFAULT_BATCH_SIZE
|
20
|
+
end
|
21
|
+
|
15
22
|
# @return [Symbol] the batch mode to run
|
16
|
-
def batch_mode(opts =
|
23
|
+
def batch_mode(opts = options)
|
17
24
|
opts.dig(:workflow, :batch, :mode) || :batch
|
18
25
|
end
|
19
26
|
|
20
27
|
# @return [Boolean] are we running in `:job` mode?
|
21
|
-
def job_mode?(opts =
|
28
|
+
def job_mode?(opts = options)
|
22
29
|
batch_mode(opts) == :job
|
23
30
|
end
|
24
31
|
|
@@ -32,10 +39,16 @@ module Eco
|
|
32
39
|
# @option params [String] :per_page the number of people included per each batch api request.
|
33
40
|
# @option params [String] :q some text to search. Omit this parameter to target all the people.
|
34
41
|
# @return [Array<People>] all the people based on `params`
|
35
|
-
def get_people(people = nil, params: {}, silent: false)
|
36
|
-
return
|
37
|
-
|
38
|
-
|
42
|
+
def get_people(people = nil, params: {}, silent: false, options: self.options)
|
43
|
+
return get(params: params, silent: silent, options: options) unless people.is_a?(Enumerable)
|
44
|
+
|
45
|
+
launch(
|
46
|
+
people,
|
47
|
+
method: :get,
|
48
|
+
params: params,
|
49
|
+
silent: silent,
|
50
|
+
options: options
|
51
|
+
).people
|
39
52
|
end
|
40
53
|
|
41
54
|
# launches a batch of `method` type using `people` and the specified `params`
|
@@ -47,14 +60,26 @@ module Eco
|
|
47
60
|
# @param params [Hash] api request options.
|
48
61
|
# @option params [String] :per_page the number of people included per each batch api request.
|
49
62
|
# @return [Batch::Status] the `status` of this batch launch.
|
50
|
-
def launch(people, method:, params: {}, silent: false)
|
51
|
-
batch_from(
|
63
|
+
def launch(people, method:, params: {}, silent: false, options: self.options)
|
64
|
+
batch_from(
|
65
|
+
people,
|
66
|
+
method: method,
|
67
|
+
params: params,
|
68
|
+
silent: silent,
|
69
|
+
options: options
|
70
|
+
)
|
52
71
|
end
|
53
72
|
|
54
|
-
def search(data, silent: false, params: {}) # rubocop:disable Metrics/AbcSize
|
55
|
-
params = {per_page:
|
73
|
+
def search(data, silent: false, params: {}, options: self.options) # rubocop:disable Metrics/AbcSize
|
74
|
+
params = {per_page: batch_size(options)}.merge(params)
|
56
75
|
|
57
|
-
launch(
|
76
|
+
launch(
|
77
|
+
data,
|
78
|
+
method: :get,
|
79
|
+
params: params,
|
80
|
+
silent: silent,
|
81
|
+
options: options
|
82
|
+
).tap do |status|
|
58
83
|
status.mode = :search
|
59
84
|
|
60
85
|
entries = status.queue
|
@@ -78,7 +103,11 @@ module Eco
|
|
78
103
|
people_matching = []
|
79
104
|
email = email.to_s.strip.downcase
|
80
105
|
unless email.empty?
|
81
|
-
people_matching = get(
|
106
|
+
people_matching = get(
|
107
|
+
params: params.merge(q: email),
|
108
|
+
silent: silent,
|
109
|
+
options: options
|
110
|
+
).select do |person|
|
82
111
|
person.email == email
|
83
112
|
end
|
84
113
|
end
|
@@ -95,15 +124,21 @@ module Eco
|
|
95
124
|
|
96
125
|
private
|
97
126
|
|
98
|
-
def get(params: {}, silent: false)
|
127
|
+
def get(params: {}, silent: false, options: self.options)
|
99
128
|
msg = "cannot batch get without api connnection, please provide a valid api connection!"
|
100
129
|
fatal msg unless (people_api = api&.people)
|
101
130
|
|
102
|
-
params = {per_page:
|
131
|
+
params = {per_page: batch_size(options)}.merge(params)
|
103
132
|
people_api.get_all(params: params, silent: silent)
|
104
133
|
end
|
105
134
|
|
106
|
-
def batch_from(
|
135
|
+
def batch_from(
|
136
|
+
data,
|
137
|
+
method:,
|
138
|
+
params: {},
|
139
|
+
silent: false,
|
140
|
+
options: self.options
|
141
|
+
)
|
107
142
|
fatal "Invalid batch method: #{method}." unless self.class.valid_method?(method)
|
108
143
|
return nil if !data || !data.is_a?(Enumerable)
|
109
144
|
|
@@ -111,15 +146,16 @@ module Eco
|
|
111
146
|
fatal msg unless (people_api = api&.people)
|
112
147
|
|
113
148
|
# param q does not make sense here, even for GET method
|
114
|
-
params = {per_page:
|
115
|
-
per_page = params[:per_page] ||
|
149
|
+
params = {per_page: batch_size(options)}.merge(params)
|
150
|
+
per_page = params[:per_page] || batch_size(options)
|
116
151
|
|
117
152
|
launch_batch(
|
118
153
|
data,
|
119
154
|
method: method,
|
120
155
|
per_page: per_page,
|
121
156
|
people_api: people_api,
|
122
|
-
silent: silent
|
157
|
+
silent: silent,
|
158
|
+
options: options
|
123
159
|
)
|
124
160
|
end
|
125
161
|
|
@@ -128,15 +164,15 @@ module Eco
|
|
128
164
|
ASSETS.cli.options
|
129
165
|
end
|
130
166
|
|
131
|
-
def launch_batch( # rubocop:disable Metrics/AbcSize
|
167
|
+
def launch_batch( # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
132
168
|
data,
|
133
169
|
method:,
|
134
170
|
status: nil,
|
135
171
|
job_mode: true, # rubocop:disable Lint/UnusedMethodArgument
|
136
|
-
|
172
|
+
options: self.options,
|
173
|
+
per_page: batch_size(options),
|
137
174
|
people_api: api&.people,
|
138
|
-
silent: false
|
139
|
-
options: self.options
|
175
|
+
silent: false
|
140
176
|
)
|
141
177
|
iteration = 1
|
142
178
|
done = 0
|
@@ -149,17 +185,18 @@ module Eco
|
|
149
185
|
)
|
150
186
|
|
151
187
|
status.tap do
|
152
|
-
start_time = Time.now
|
153
|
-
start_slice = Time.now
|
154
|
-
|
155
188
|
pending_for_server_error = data.to_a[0..]
|
189
|
+
|
190
|
+
start_time = Time.now
|
191
|
+
|
156
192
|
data.each_slice(per_page) do |slice|
|
157
|
-
msg = "starting batch '#{method}' iteration #{iteration}/#{iterations},"
|
158
|
-
msg << "
|
159
|
-
msg << "
|
193
|
+
msg = "starting batch '#{method}' iteration #{iteration}/#{iterations}, "
|
194
|
+
msg << "with #{slice.length} entries of #{data.length} -- #{done} done"
|
195
|
+
msg << (" " * 20)
|
160
196
|
log(:info) { msg } unless silent
|
161
197
|
|
162
198
|
start_slice = Time.now
|
199
|
+
|
163
200
|
offer_retry_on(Ecoportal::API::Errors::TimeOut) do
|
164
201
|
people_api.batch(job_mode: job_mode?(options)) do |batch|
|
165
202
|
slice.each do |person|
|
@@ -175,8 +212,15 @@ module Eco
|
|
175
212
|
end # end batch
|
176
213
|
end
|
177
214
|
|
215
|
+
done += slice.length
|
216
|
+
|
217
|
+
msg = " ... iteration #{iteration}/#{iterations} done "
|
218
|
+
msg << "in #{str_stats(start_slice, slice.length)} "
|
219
|
+
msg << "(average: #{str_stats(start_time, done)})"
|
220
|
+
msg << (" " * 20)
|
221
|
+
log(:info) { msg } unless silent
|
222
|
+
|
178
223
|
iteration += 1
|
179
|
-
done += slice.length
|
180
224
|
end # next slice
|
181
225
|
|
182
226
|
# temporary working around (due to back-end problems with batch/jobs)
|
@@ -191,7 +235,8 @@ module Eco
|
|
191
235
|
job_mode: false,
|
192
236
|
per_page: per_page,
|
193
237
|
people_api: people_api,
|
194
|
-
silent: silent
|
238
|
+
silent: silent,
|
239
|
+
options: options
|
195
240
|
)
|
196
241
|
end
|
197
242
|
end
|
@@ -206,11 +251,12 @@ module Eco
|
|
206
251
|
end
|
207
252
|
|
208
253
|
def offer_retry_on(error_type, retries_left = 3, &block)
|
209
|
-
|
210
|
-
rescue error_type
|
211
|
-
raise unless retries_left.positive?
|
254
|
+
yield
|
255
|
+
rescue error_type => err
|
256
|
+
raise err.class, err.message, cause: nil unless retries_left.positive?
|
212
257
|
|
213
|
-
explanation = "
|
258
|
+
explanation = "#{err}\n"
|
259
|
+
explanation << "You have #{retries_left} retries left."
|
214
260
|
question = " Do you want to retry (y/N)?"
|
215
261
|
|
216
262
|
prompt_user(question, default: "Y", explanation: explanation, timeout: 10) do |response|
|
@@ -223,7 +269,7 @@ module Eco
|
|
223
269
|
|
224
270
|
def str_stats(start, count)
|
225
271
|
now = Time.now
|
226
|
-
secs = (now - start).round(
|
272
|
+
secs = (now - start).round(2)
|
227
273
|
if secs > 0.0
|
228
274
|
per_sec = (count.to_f / secs).round(2)
|
229
275
|
"#{secs}s -> #{per_sec} people/s"
|
@@ -4,6 +4,27 @@ module Eco
|
|
4
4
|
class Config
|
5
5
|
class Api < Hash
|
6
6
|
class << self
|
7
|
+
def to_space(value)
|
8
|
+
value = value.to_s.strip.gsub(/[- ]/, '_').downcase
|
9
|
+
return :default if value.empty?
|
10
|
+
|
11
|
+
value.to_sym
|
12
|
+
end
|
13
|
+
|
14
|
+
def description(api)
|
15
|
+
msg = "Expecting #{self}. Given: #{api.class}"
|
16
|
+
raise ArgumentError, msg unless api.is_a?(self)
|
17
|
+
|
18
|
+
full_name(api.name, space: api.space)
|
19
|
+
end
|
20
|
+
|
21
|
+
def full_name(name, space: :default)
|
22
|
+
space = to_space(space)
|
23
|
+
|
24
|
+
str_space = space == :default ? '' : " (space: :#{space})"
|
25
|
+
"'#{name}'#{str_space}"
|
26
|
+
end
|
27
|
+
|
7
28
|
def to_version(str)
|
8
29
|
case str.to_sym
|
9
30
|
when :external, :v1
|
@@ -35,22 +56,34 @@ module Eco
|
|
35
56
|
end
|
36
57
|
end
|
37
58
|
|
38
|
-
def initialize(
|
39
|
-
|
40
|
-
|
59
|
+
def initialize(
|
60
|
+
name,
|
61
|
+
root:,
|
62
|
+
key:,
|
63
|
+
host:,
|
64
|
+
version:,
|
65
|
+
space: :default,
|
66
|
+
mode: :local,
|
67
|
+
user_key: nil,
|
68
|
+
external_key: nil,
|
69
|
+
email: nil,
|
70
|
+
pass: nil,
|
71
|
+
org_id: nil
|
72
|
+
)
|
41
73
|
super(nil)
|
42
|
-
@root
|
43
|
-
@apis
|
44
|
-
self[
|
45
|
-
self[
|
46
|
-
self[
|
47
|
-
self[
|
48
|
-
self[
|
49
|
-
self[
|
50
|
-
self[
|
51
|
-
self[
|
52
|
-
self[
|
53
|
-
self[
|
74
|
+
@root = root
|
75
|
+
@apis = {}
|
76
|
+
self['name'] = name
|
77
|
+
self['space'] = to_space(space)
|
78
|
+
self['key'] = key
|
79
|
+
self['host'] = host
|
80
|
+
self['version'] = version
|
81
|
+
self['mode'] = mode
|
82
|
+
self['user_key'] = user_key
|
83
|
+
self['external_key'] = external_key
|
84
|
+
self['email'] = email || ENV['USER_EMAIL']
|
85
|
+
self['pass'] = pass || ENV['USER_PASS']
|
86
|
+
self['org_id'] = org_id
|
54
87
|
end
|
55
88
|
|
56
89
|
# @return [Eco::API::Session::Config] the `root` config
|
@@ -67,12 +100,13 @@ module Eco
|
|
67
100
|
switch_logger = (logger != @logger)
|
68
101
|
@logger = logger if logger
|
69
102
|
|
70
|
-
|
71
|
-
|
72
|
-
end
|
103
|
+
current = get(version)
|
104
|
+
return current if current && !switch_logger
|
73
105
|
|
74
106
|
unless api_params?(version)
|
75
|
-
|
107
|
+
msg = "The api configuration for #{description} "
|
108
|
+
msg << "is missing data for the api version '#{self.version(version)}'"
|
109
|
+
raise ArgumentError, msg
|
76
110
|
end
|
77
111
|
|
78
112
|
new_api(version).tap do |pi|
|
@@ -89,7 +123,16 @@ module Eco
|
|
89
123
|
end
|
90
124
|
|
91
125
|
def name
|
92
|
-
self[
|
126
|
+
self['name']
|
127
|
+
end
|
128
|
+
|
129
|
+
def space
|
130
|
+
self['space'] ||= :default
|
131
|
+
to_space(self['space'])
|
132
|
+
end
|
133
|
+
|
134
|
+
def description
|
135
|
+
self.class.description(self)
|
93
136
|
end
|
94
137
|
|
95
138
|
def one_off?
|
@@ -97,45 +140,45 @@ module Eco
|
|
97
140
|
end
|
98
141
|
|
99
142
|
def key
|
100
|
-
self[
|
143
|
+
self['key']
|
101
144
|
end
|
102
145
|
|
103
146
|
def user_key
|
104
|
-
self[
|
147
|
+
self['user_key'] || @root.default_user_key
|
105
148
|
end
|
106
149
|
|
107
150
|
def external_key
|
108
|
-
self[
|
151
|
+
self['external_key'] || (%i[v1 v2].include?(version) && key)
|
109
152
|
end
|
110
153
|
|
111
154
|
def internal_key
|
112
|
-
(version == :v0) && self[
|
155
|
+
(version == :v0) && self['key']
|
113
156
|
end
|
114
157
|
|
115
158
|
def org_id
|
116
|
-
self[
|
159
|
+
self['org_id']
|
117
160
|
end
|
118
161
|
|
119
162
|
def email
|
120
|
-
self[
|
163
|
+
self['email'] || @root.default_email
|
121
164
|
end
|
122
165
|
|
123
166
|
def pass
|
124
|
-
self[
|
167
|
+
self['pass'] || @root.default_pass
|
125
168
|
end
|
126
169
|
|
127
170
|
def host
|
128
|
-
self[
|
171
|
+
self['host']
|
129
172
|
end
|
130
173
|
|
131
174
|
# @param mode [Symbol] to define if running on `:remote` or `:local`
|
132
175
|
def mode=(mode)
|
133
|
-
self[
|
176
|
+
self['mode'] = mode == :remote ? :remote : :local
|
134
177
|
end
|
135
178
|
|
136
179
|
# @return [Symbol] if running on `:remote` or `:local`
|
137
180
|
def mode
|
138
|
-
self[
|
181
|
+
self['mode']
|
139
182
|
end
|
140
183
|
|
141
184
|
def local?
|
@@ -152,7 +195,7 @@ module Eco
|
|
152
195
|
end
|
153
196
|
|
154
197
|
def version(value = nil)
|
155
|
-
self.class.to_version(value || self[
|
198
|
+
self.class.to_version(value || self['version'])
|
156
199
|
end
|
157
200
|
|
158
201
|
# if no low level connection messages: use `IO::NULL`
|
@@ -163,9 +206,14 @@ module Eco
|
|
163
206
|
|
164
207
|
private
|
165
208
|
|
209
|
+
def to_space(...)
|
210
|
+
self.class.to_space(...)
|
211
|
+
end
|
212
|
+
|
166
213
|
# Generates a **new** `API` object of version `version`.
|
167
214
|
def new_api(version) # rubocop:disable Metrics/AbcSize
|
168
215
|
klass = self.class.api_class(version)
|
216
|
+
|
169
217
|
case self.version(version)
|
170
218
|
when :v0
|
171
219
|
klass.new(internal_key, host: host, logger: logger)
|
@@ -174,14 +222,25 @@ module Eco
|
|
174
222
|
when :v2
|
175
223
|
klass.new(user_key: user_key, org_key: external_key, host: host, logger: logger)
|
176
224
|
when :graphql
|
177
|
-
kargs = {
|
225
|
+
kargs = {
|
226
|
+
host: host,
|
227
|
+
org_id: org_id,
|
228
|
+
email: email,
|
229
|
+
pass: pass
|
230
|
+
}
|
231
|
+
|
178
232
|
kargs.merge!({no_schema: true}) if ENV['GRAPHQL_FETCH_SCHEMA'] == "false"
|
179
|
-
klass.new(
|
233
|
+
klass.new(**kargs)
|
180
234
|
end.tap do |api|
|
181
|
-
unless
|
182
|
-
|
183
|
-
|
184
|
-
|
235
|
+
next unless api
|
236
|
+
next if log_connection? # prevent over-logging
|
237
|
+
|
238
|
+
msg = "Created api#{self.version(version)} connection "
|
239
|
+
msg << "on enviro #{description}, "
|
240
|
+
msg << "pointing to '#{host}' in '#{mode}' mode"
|
241
|
+
|
242
|
+
@logger.info(msg)
|
243
|
+
api.logger.level = ::Logger::UNKNOWN if api.respond_to?(:logger)
|
185
244
|
end
|
186
245
|
end
|
187
246
|
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module Eco
|
2
|
+
module API
|
3
|
+
class Session
|
4
|
+
class Config
|
5
|
+
class Apis
|
6
|
+
module EnviroSpaces
|
7
|
+
class << self
|
8
|
+
def included(base)
|
9
|
+
target_class = Eco::API::Session::Config::Apis
|
10
|
+
msg = "To be included in #{target_class}. "
|
11
|
+
msg << "Included in #{base}"
|
12
|
+
raise msg unless base <= target_class
|
13
|
+
|
14
|
+
super
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
include Session::Config::Apis::SpaceHelpers
|
19
|
+
|
20
|
+
def active_space
|
21
|
+
active_api&.space || space_option
|
22
|
+
end
|
23
|
+
|
24
|
+
def enviros(space)
|
25
|
+
apis(space).keys
|
26
|
+
end
|
27
|
+
|
28
|
+
# APIs of a particualr `space`
|
29
|
+
def apis(space = space_option)
|
30
|
+
api_space(space)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Any APIs (of any space or in a particular `space`)
|
34
|
+
def apis?(space = nil)
|
35
|
+
return apis(space).any? unless space.nil?
|
36
|
+
|
37
|
+
spaces.each_key.any? do |space|
|
38
|
+
apis?(space)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def api?(name, space: space_option)
|
43
|
+
apis(space).key?(name)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Deprecated
|
47
|
+
def defined?(name, space: space_option)
|
48
|
+
apis(space).key?(name)
|
49
|
+
end
|
50
|
+
|
51
|
+
def any_defined?(*names, space: space_option)
|
52
|
+
[names].flatten.any? do |name|
|
53
|
+
api?(name, space: space)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [Array<Symbol>] the spaces where the enviro `name`
|
58
|
+
# has an api defined
|
59
|
+
def enviro_spaces(name)
|
60
|
+
spaces.keys.select do |space|
|
61
|
+
api?(name, space: space)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def enviro_spaces_str(name)
|
66
|
+
return '' unless enviro_spaces?(name)
|
67
|
+
|
68
|
+
":#{enviro_spaces(name).join(', :')}"
|
69
|
+
end
|
70
|
+
|
71
|
+
def enviro_spaces?(name)
|
72
|
+
enviro_spaces(name).any?
|
73
|
+
end
|
74
|
+
|
75
|
+
def missing_api_message(name, space: space_option)
|
76
|
+
space ||= space_option
|
77
|
+
|
78
|
+
msg = "Missing credentials for "
|
79
|
+
msg << "#{full_name(name, space: space)} Api env."
|
80
|
+
|
81
|
+
if enviro_spaces?(name)
|
82
|
+
msg << "\n Available space(s) for '#{name}' enviro: "
|
83
|
+
msg << enviro_spaces_str(name)
|
84
|
+
msg << "\n"
|
85
|
+
end
|
86
|
+
|
87
|
+
msg
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def spaces
|
93
|
+
self['spaces'] ||= {}
|
94
|
+
end
|
95
|
+
|
96
|
+
def api_space(space = space_option)
|
97
|
+
space ||= space_option
|
98
|
+
|
99
|
+
spaces[space.to_sym] ||= {}
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Eco
|
2
|
+
module API
|
3
|
+
class Session
|
4
|
+
class Config
|
5
|
+
class Apis
|
6
|
+
module OneOff
|
7
|
+
private
|
8
|
+
|
9
|
+
def one_off?
|
10
|
+
@is_one_off ||=
|
11
|
+
SCR.get_arg('-api-key') ||
|
12
|
+
SCR.get_arg('-one-off')
|
13
|
+
end
|
14
|
+
|
15
|
+
def one_off_key
|
16
|
+
return @one_off_key if instance_variable_defined?(:@one_off_key)
|
17
|
+
|
18
|
+
return unless one_off?
|
19
|
+
|
20
|
+
Dotenv.load('./.env_one_off')
|
21
|
+
SCR.get_arg('-api-key', with_param: true).then do |key|
|
22
|
+
one_off_key_env(key)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def one_off_key_env(key)
|
27
|
+
return unless one_off?
|
28
|
+
|
29
|
+
if key
|
30
|
+
env_file_set_var('./.env_one_off', one_off_key_env_var, key)
|
31
|
+
key
|
32
|
+
else
|
33
|
+
Dotenv.load('./.env_one_off')
|
34
|
+
|
35
|
+
ENV[one_off_key_env_var].tap do |k|
|
36
|
+
msg = "At least the first time, "
|
37
|
+
msg << "you should provide the -api-key"
|
38
|
+
raise msg unless k
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def one_off_key_env_var
|
44
|
+
@one_off_key_env_var ||= "#{one_off_org}_KEY"
|
45
|
+
end
|
46
|
+
|
47
|
+
def one_off_org
|
48
|
+
return @one_off_org if instance_variable_defined?(:@one_off_org)
|
49
|
+
|
50
|
+
msg = "You should specify -org NAME when using -api-key or -one-off"
|
51
|
+
raise msg unless org = SCR.get_arg('-org', with_param: true)
|
52
|
+
|
53
|
+
str_org = "#{org.downcase.split(/[^a-z]+/).join('_')}_#{one_off_enviro.gsub('.', '_')}"
|
54
|
+
@one_off_org ||= str_org.to_sym
|
55
|
+
end
|
56
|
+
|
57
|
+
def one_off_enviro
|
58
|
+
return @one_off_enviro if instance_variable_defined?(:@one_off_enviro)
|
59
|
+
|
60
|
+
enviro = 'live'
|
61
|
+
enviro = SCR.get_arg('-enviro', with_param: true) if SCR.get_arg('-enviro')
|
62
|
+
|
63
|
+
@one_off_enviro ||= enviro.downcase
|
64
|
+
end
|
65
|
+
|
66
|
+
def env_file_set_var(file, var, value)
|
67
|
+
pattern = /"#{var}=(?<value>[^ \r\n]+)"/
|
68
|
+
|
69
|
+
File.open(file, "w+") do |fd|
|
70
|
+
found = false
|
71
|
+
|
72
|
+
fd.each_line do |line|
|
73
|
+
next unless (match = line.match(pattern))
|
74
|
+
|
75
|
+
found = true
|
76
|
+
# IO::SEEK_CUR => Seeks to _amount_ plus current position
|
77
|
+
fd.seek(-(line.length + 1), IO::SEEK_CUR)
|
78
|
+
fd.write line.gsub(match[:value], value)
|
79
|
+
end
|
80
|
+
|
81
|
+
fd << "#{var}=#{value}" unless found
|
82
|
+
end
|
83
|
+
|
84
|
+
true
|
85
|
+
rescue StandardError => err
|
86
|
+
puts "#{err}"
|
87
|
+
false
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|