squared 0.5.11 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +127 -0
- data/README.md +76 -35
- data/lib/squared/common/base.rb +1 -22
- data/lib/squared/common/format.rb +33 -25
- data/lib/squared/common/prompt.rb +58 -36
- data/lib/squared/common/shell.rb +44 -11
- data/lib/squared/common/system.rb +69 -36
- data/lib/squared/common/utils.rb +29 -6
- data/lib/squared/config.rb +17 -21
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +87 -91
- data/lib/squared/workspace/project/base.rb +548 -378
- data/lib/squared/workspace/project/docker.rb +393 -290
- data/lib/squared/workspace/project/git.rb +328 -312
- data/lib/squared/workspace/project/node.rb +545 -280
- data/lib/squared/workspace/project/python.rb +329 -200
- data/lib/squared/workspace/project/ruby.rb +672 -343
- data/lib/squared/workspace/project/support/class.rb +166 -68
- data/lib/squared/workspace/repo.rb +39 -35
- data/lib/squared/workspace/series.rb +6 -6
- data/lib/squared/workspace/support/base.rb +3 -29
- data/lib/squared/workspace/support/variables.rb +48 -0
- data/lib/squared/workspace/support.rb +1 -1
- data/lib/squared/workspace.rb +1 -1
- metadata +4 -7
- data/lib/squared/workspace/support/data.rb +0 -11
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'json'
|
|
4
|
-
require 'date'
|
|
5
4
|
require 'logger'
|
|
6
5
|
|
|
7
6
|
module Squared
|
|
@@ -15,15 +14,17 @@ module Squared
|
|
|
15
14
|
include Prompt
|
|
16
15
|
include Utils
|
|
17
16
|
include Support
|
|
17
|
+
include Workspace::Support::Variables
|
|
18
18
|
include Rake::DSL
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
OPTIONS = Workspace::Support.hashobj
|
|
21
|
+
VAR_SET = %i[parent global script index envname desc dependfile dependname dependindex theme archive env graph
|
|
22
|
+
dev prod pass only exclude asdf].freeze
|
|
22
23
|
BLK_SET = %i[run depend doc lint test copy clean].freeze
|
|
23
24
|
SEM_VER = /\b(\d+)(?:(\.)(\d+))?(?:(\.)(\d+))?[-.]?(\S+)?\b/.freeze
|
|
24
25
|
URI_SCHEME = %r{\A([a-z][a-z\d+-.]*)://[^@:\[\]\\^<>|\s]}i.freeze
|
|
25
26
|
TASK_METADATA = Rake::TaskManager.record_task_metadata
|
|
26
|
-
private_constant :VAR_SET, :BLK_SET, :SEM_VER, :URI_SCHEME, :TASK_METADATA
|
|
27
|
+
private_constant :OPTIONS, :VAR_SET, :BLK_SET, :SEM_VER, :URI_SCHEME, :TASK_METADATA
|
|
27
28
|
|
|
28
29
|
class << self
|
|
29
30
|
def populate(*); end
|
|
@@ -35,13 +36,33 @@ module Squared
|
|
|
35
36
|
(%i[build archive graph prereqs] + BLK_SET).freeze
|
|
36
37
|
end
|
|
37
38
|
|
|
38
|
-
def
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
def options(*args, **kwargs)
|
|
40
|
+
name = nil
|
|
41
|
+
with = []
|
|
42
|
+
proj = []
|
|
43
|
+
opts = []
|
|
44
|
+
args.each do |val|
|
|
45
|
+
case val
|
|
46
|
+
when String
|
|
47
|
+
if name
|
|
48
|
+
opts << val
|
|
49
|
+
else
|
|
50
|
+
name = val
|
|
51
|
+
end
|
|
52
|
+
when Symbol
|
|
53
|
+
if name
|
|
54
|
+
proj << val
|
|
55
|
+
else
|
|
56
|
+
with << val
|
|
57
|
+
end
|
|
58
|
+
end
|
|
44
59
|
end
|
|
60
|
+
return if !name || (opts.empty? && kwargs.empty? && with.empty?)
|
|
61
|
+
|
|
62
|
+
base = OPTIONS[ref]
|
|
63
|
+
data = [opts.freeze, kwargs.freeze, with.freeze].freeze
|
|
64
|
+
proj << :_ if proj.empty?
|
|
65
|
+
proj.each { |val| (base[val] ||= {})[name.to_s] = data }
|
|
45
66
|
end
|
|
46
67
|
|
|
47
68
|
def ref
|
|
@@ -61,27 +82,39 @@ module Squared
|
|
|
61
82
|
def to_s
|
|
62
83
|
super[/[^:]+\z/, 0]
|
|
63
84
|
end
|
|
85
|
+
|
|
86
|
+
private
|
|
87
|
+
|
|
88
|
+
def as_path(val)
|
|
89
|
+
case val
|
|
90
|
+
when Pathname
|
|
91
|
+
val
|
|
92
|
+
when String
|
|
93
|
+
Pathname.new(val)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
64
96
|
end
|
|
65
97
|
|
|
66
98
|
@@tasks = {}
|
|
67
99
|
@@graph = { _: [] }
|
|
68
100
|
@@asdf = Pathname.new("#{Dir.home}/.asdf").yield_self do |path|
|
|
69
|
-
if path.join('asdf.sh').exist?
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
101
|
+
version = if path.join('asdf.sh').exist?
|
|
102
|
+
15
|
|
103
|
+
elsif ENV['ASDF_DATA_DIR'] && (path = Pathname.new(ENV['ASDF_DATA_DIR'])).exist?
|
|
104
|
+
16
|
|
105
|
+
end
|
|
106
|
+
Struct.new(:path, :version).new(path, version) if version
|
|
74
107
|
end
|
|
75
108
|
@@print_order = 0
|
|
76
109
|
|
|
77
110
|
subtasks({
|
|
78
111
|
'graph' => %i[run print].freeze,
|
|
79
|
-
'unpack' => %i[zip tar
|
|
80
|
-
'asdf' => %i[set exec current]
|
|
112
|
+
'unpack' => %i[zip gz tar ext].freeze,
|
|
113
|
+
'asdf' => %i[set exec current update latest where reshim]
|
|
81
114
|
})
|
|
82
115
|
|
|
83
116
|
attr_reader :name, :project, :workspace, :path, :theme, :group, :parent, :dependfile,
|
|
84
|
-
:exception, :pipe, :verbose
|
|
117
|
+
:exception, :pipe, :verbose, :global
|
|
85
118
|
|
|
86
119
|
def initialize(workspace, path, name, *, group: nil, first: {}, last: {}, error: {}, common: ARG[:COMMON],
|
|
87
120
|
**kwargs)
|
|
@@ -99,23 +132,28 @@ module Squared
|
|
|
99
132
|
@clean = kwargs[:clean]
|
|
100
133
|
@release = kwargs[:release]
|
|
101
134
|
self.version = kwargs[:version]
|
|
102
|
-
self.exception = kwargs[:exception]
|
|
103
|
-
self.pipe = kwargs[:pipe]
|
|
104
|
-
self.verbose = kwargs[:verbose]
|
|
135
|
+
self.exception = env_bool(kwargs[:exception], workspace.exception, strict: true)
|
|
136
|
+
self.pipe = env_pipe(kwargs[:pipe], workspace.pipe, strict: true)
|
|
137
|
+
self.verbose = case (val = env('VERBOSE', kwargs[:verbose]))
|
|
138
|
+
when String
|
|
139
|
+
env_bool(val, workspace.verbose, strict: true, index: true)
|
|
140
|
+
else
|
|
141
|
+
val.nil? ? workspace.verbose : val
|
|
142
|
+
end
|
|
143
|
+
self.global = false
|
|
105
144
|
@output = []
|
|
106
145
|
@ref = []
|
|
107
146
|
@children = []
|
|
108
147
|
@events = hashobj.update({ first: first, last: last, error: error })
|
|
109
148
|
@as = hashobj
|
|
110
149
|
@desc = (@name.include?(':') ? @name.split(':').join(ARG[:SPACE]) : @name).freeze
|
|
111
|
-
@parent = nil
|
|
112
|
-
@global = false
|
|
113
150
|
@log = nil
|
|
114
151
|
@dev = nil
|
|
115
152
|
@prod = nil
|
|
116
153
|
@withargs = nil
|
|
117
154
|
@session = nil
|
|
118
155
|
@index = -1
|
|
156
|
+
parent_set kwargs[:parent]
|
|
119
157
|
run_set(kwargs[:run], kwargs[:env], opts: kwargs.fetch(:opts, true))
|
|
120
158
|
graph_set kwargs[:graph]
|
|
121
159
|
pass_set kwargs[:pass]
|
|
@@ -151,32 +189,25 @@ module Squared
|
|
|
151
189
|
|
|
152
190
|
data = @workspace.script_find(*@ref, @group)
|
|
153
191
|
if @output[0].nil?
|
|
154
|
-
if
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
run_set
|
|
192
|
+
if data[:script]
|
|
193
|
+
unless kwargs[:script] == false
|
|
194
|
+
script_set(data[:script], args: data.fetch(:args, kwargs[:args]), prod: kwargs[:prod], global: true)
|
|
195
|
+
end
|
|
196
|
+
elsif data[:run]
|
|
197
|
+
run_set(data[:run], global: true)
|
|
160
198
|
end
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
script_set(scr, args: @script.fetch(:args, kwargs[:args]))
|
|
169
|
-
elsif (run = @script[:run])
|
|
170
|
-
@global = false
|
|
171
|
-
run_set run
|
|
172
|
-
end
|
|
199
|
+
if kwargs[:script]
|
|
200
|
+
script_set(kwargs[:script], args: kwargs[:args]) unless data[:env][:script]
|
|
201
|
+
elsif @script
|
|
202
|
+
if @script[:script]
|
|
203
|
+
script_set(@script[:script], args: @script.fetch(:args, kwargs[:args])) unless data[:global][:script]
|
|
204
|
+
elsif @script[:run] && !data[:global][:run]
|
|
205
|
+
run_set @script[:run]
|
|
173
206
|
end
|
|
174
207
|
end
|
|
175
|
-
elsif data[:
|
|
176
|
-
|
|
177
|
-
run_set data[:run]
|
|
208
|
+
elsif data[:run] && data[:env][:run]
|
|
209
|
+
run_set(data[:run], global: true)
|
|
178
210
|
end
|
|
179
|
-
@global = true
|
|
180
211
|
end
|
|
181
212
|
|
|
182
213
|
def initialize_events(ref, **)
|
|
@@ -189,10 +220,11 @@ module Squared
|
|
|
189
220
|
return if @log
|
|
190
221
|
|
|
191
222
|
log = log.is_a?(Hash) ? log.dup : { file: log }
|
|
192
|
-
if (
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
223
|
+
file = if (val = env('LOG_FILE'))
|
|
224
|
+
Time.now.strftime(val)
|
|
225
|
+
elsif (val = env('LOG_AUTO'))
|
|
226
|
+
require 'date'
|
|
227
|
+
"#{@name}-%s.log" % [case val
|
|
196
228
|
when 'y', 'year'
|
|
197
229
|
Date.today.year
|
|
198
230
|
when 'm', 'month'
|
|
@@ -202,19 +234,21 @@ module Squared
|
|
|
202
234
|
else
|
|
203
235
|
val.include?('%') ? Time.now.strftime(val) : Time.now.strftime('%FT%T%:z')
|
|
204
236
|
end]
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
237
|
+
elsif (val = log[:file])
|
|
238
|
+
if val.is_a?(String)
|
|
239
|
+
Time.now.strftime(val)
|
|
240
|
+
else
|
|
241
|
+
require 'date'
|
|
242
|
+
"#{@name}-#{Date.today}.log"
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
.yield_self do |dir|
|
|
246
|
+
@workspace.home.join(env('LOG_DIR', ''), dir).realdirpath if dir
|
|
247
|
+
rescue StandardError => e
|
|
248
|
+
print_error e
|
|
249
|
+
end
|
|
214
250
|
log[:progname] ||= @name
|
|
215
|
-
if (val = env('LOG_LEVEL', ignore: false))
|
|
216
|
-
log[:level] = val.match?(/\d/) ? log_sym(val.to_i) : val
|
|
217
|
-
end
|
|
251
|
+
log[:level] = val.match?(/\d/) ? log_sym(val.to_i) : val if (val = env('LOG_LEVEL', ignore: false))
|
|
218
252
|
log.delete(:file)
|
|
219
253
|
@log = [file, log]
|
|
220
254
|
end
|
|
@@ -222,7 +256,7 @@ module Squared
|
|
|
222
256
|
def initialize_env(dev: nil, prod: nil, **)
|
|
223
257
|
@dev = env_match('BUILD', dev, suffix: 'DEV', strict: true)
|
|
224
258
|
@prod = env_match('BUILD', prod, suffix: 'PROD', strict: true)
|
|
225
|
-
if (val = env('BUILD', suffix: 'ENV'))
|
|
259
|
+
if @output[2] != false && (val = env('BUILD', suffix: 'ENV'))
|
|
226
260
|
@output[2] = parse_json(val, hint: "BUILD_#{@envname}_ENV") || @output[2]
|
|
227
261
|
end
|
|
228
262
|
unless @output[0] == false || @output[0].is_a?(Array)
|
|
@@ -237,7 +271,6 @@ module Squared
|
|
|
237
271
|
@version = val if (val = env('BUILD', suffix: 'VERSION'))
|
|
238
272
|
return unless (val = env('BUILD', strict: true))
|
|
239
273
|
|
|
240
|
-
@global = false
|
|
241
274
|
if val == '0'
|
|
242
275
|
@output = [false]
|
|
243
276
|
elsif script?
|
|
@@ -293,24 +326,36 @@ module Squared
|
|
|
293
326
|
end
|
|
294
327
|
|
|
295
328
|
def exception=(val)
|
|
296
|
-
@exception =
|
|
329
|
+
@exception = case val
|
|
330
|
+
when Numeric, TrueClass, FalseClass
|
|
331
|
+
val
|
|
332
|
+
else
|
|
333
|
+
workspace.exception
|
|
334
|
+
end
|
|
297
335
|
end
|
|
298
336
|
|
|
299
337
|
def pipe=(val)
|
|
300
|
-
@pipe =
|
|
338
|
+
@pipe = case val
|
|
339
|
+
when Numeric, Pathname
|
|
340
|
+
val
|
|
341
|
+
else
|
|
342
|
+
workspace.pipe
|
|
343
|
+
end
|
|
301
344
|
end
|
|
302
345
|
|
|
303
346
|
def verbose=(val)
|
|
304
|
-
@verbose = case
|
|
305
|
-
when
|
|
306
|
-
workspace.verbose
|
|
307
|
-
when String
|
|
308
|
-
env_bool(val, workspace.verbose, strict: true, index: true)
|
|
309
|
-
else
|
|
347
|
+
@verbose = case val
|
|
348
|
+
when Numeric, TrueClass, FalseClass
|
|
310
349
|
val
|
|
350
|
+
else
|
|
351
|
+
workspace.verbose
|
|
311
352
|
end
|
|
312
353
|
end
|
|
313
354
|
|
|
355
|
+
def global=(val)
|
|
356
|
+
@global = val unless val.nil?
|
|
357
|
+
end
|
|
358
|
+
|
|
314
359
|
def ref
|
|
315
360
|
Base.ref
|
|
316
361
|
end
|
|
@@ -337,45 +382,40 @@ module Squared
|
|
|
337
382
|
else
|
|
338
383
|
out, done = graph(args, out: [])
|
|
339
384
|
out.map! do |val|
|
|
340
|
-
done.
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
val += " (#{i.succ})"
|
|
344
|
-
break
|
|
345
|
-
end
|
|
346
|
-
val
|
|
385
|
+
n = done.index { |proj| val.match?(/ #{Regexp.escape(proj.name)}(?:@\d|\z)/) }
|
|
386
|
+
n ? val.subhint(n.succ) : val
|
|
347
387
|
end
|
|
348
388
|
emphasize(out, title: path, right: true, border: borderstyle, sub: [
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
389
|
+
opt_style(theme[:header], /\A(#{Regexp.escape(path.to_s)})(.*)\z/),
|
|
390
|
+
opt_style(theme[:active], /\A(#{Regexp.escape(name)})(.*)\z/),
|
|
391
|
+
opt_style(theme[:inline], /\A((?~ \() \()(\d+)(\).*)\z/, 2)
|
|
352
392
|
])
|
|
353
393
|
end
|
|
354
394
|
end
|
|
355
395
|
when 'unpack'
|
|
356
|
-
format_desc(action, flag, 'tag/url,dir,digest?,f
|
|
396
|
+
format_desc(action, flag, 'tag/url,dir,digest?,f/orce?', before: ('ext' if flag == :ext))
|
|
357
397
|
params = %i[tag dir digest force]
|
|
358
|
-
params.
|
|
398
|
+
params.unshift(:ext) if flag == :ext
|
|
359
399
|
task flag, params do |_, args|
|
|
360
400
|
ext = flag == :ext ? param_guard(action, flag, args: args, key: :ext) : flag.to_s
|
|
361
401
|
tag = param_guard(action, flag, args: args, key: :tag)
|
|
362
402
|
dir = param_guard(action, flag, args: args, key: :dir)
|
|
363
403
|
unless tag.match?(URI_SCHEME)
|
|
364
|
-
if
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
end
|
|
372
|
-
case (digest = args.digest)
|
|
373
|
-
when 'f', 'force'
|
|
374
|
-
digest = nil
|
|
375
|
-
force = true
|
|
376
|
-
else
|
|
377
|
-
force = args.fetch(:force, false)
|
|
404
|
+
tag = if ext == 'gem'
|
|
405
|
+
"https://rubygems.org/downloads/#{File.basename(tag, '.gem')}.gem"
|
|
406
|
+
elsif @release
|
|
407
|
+
"%s.#{ext}" % [@release.include?('??') ? @release.sub('??', tag) : @release + tag]
|
|
408
|
+
else
|
|
409
|
+
raise_error ArgumentError, "no base uri: #{tag}", hint: ext
|
|
410
|
+
end
|
|
378
411
|
end
|
|
412
|
+
force = case (digest = args.digest)
|
|
413
|
+
when 'f', 'force'
|
|
414
|
+
digest = nil
|
|
415
|
+
true
|
|
416
|
+
else
|
|
417
|
+
args.fetch(:force, false)
|
|
418
|
+
end
|
|
379
419
|
unpack(basepath(dir), uri: tag, digest: digest, ext: ext, force: force)
|
|
380
420
|
end
|
|
381
421
|
when 'asdf'
|
|
@@ -383,7 +423,7 @@ module Squared
|
|
|
383
423
|
|
|
384
424
|
case flag
|
|
385
425
|
when :set
|
|
386
|
-
format_desc action, flag, 'version,
|
|
426
|
+
format_desc action, flag, 'version,dir?=u/home|p/arent'
|
|
387
427
|
task flag, [:version] do |_, args|
|
|
388
428
|
args = if (version = args.version)
|
|
389
429
|
args.extras
|
|
@@ -392,15 +432,15 @@ module Squared
|
|
|
392
432
|
@asdf[1].children
|
|
393
433
|
.map(&:basename)
|
|
394
434
|
.sort { |a, b| b <=> a }
|
|
395
|
-
.
|
|
396
|
-
|
|
397
|
-
values:
|
|
435
|
+
.push('latest', 'system'),
|
|
436
|
+
accept: [accept_y('Confirm?')],
|
|
437
|
+
values: 'Options', force: true)
|
|
398
438
|
OptionPartition.strip(opts)
|
|
399
439
|
end
|
|
400
440
|
asdf(flag, args, version: version)
|
|
401
441
|
end
|
|
402
442
|
else
|
|
403
|
-
format_desc(action, flag, flag == :exec
|
|
443
|
+
format_desc(action, flag, ('command' if flag == :exec))
|
|
404
444
|
task flag do |_, args|
|
|
405
445
|
args = args.to_a
|
|
406
446
|
args << readline('Enter command', force: true) if args.empty? && flag == :exec
|
|
@@ -419,7 +459,7 @@ module Squared
|
|
|
419
459
|
end
|
|
420
460
|
|
|
421
461
|
def with(**kwargs, &blk)
|
|
422
|
-
@withargs = kwargs.empty?
|
|
462
|
+
@withargs = (kwargs unless kwargs.empty?)
|
|
423
463
|
if block_given?
|
|
424
464
|
instance_eval(&blk)
|
|
425
465
|
@withargs = nil
|
|
@@ -428,35 +468,31 @@ module Squared
|
|
|
428
468
|
end
|
|
429
469
|
|
|
430
470
|
def add(path, name = nil, **kwargs, &blk)
|
|
431
|
-
if path.is_a?(String) &&
|
|
432
|
-
return self unless checkdir?(path = basepath(
|
|
471
|
+
if path.is_a?(String) && path =~ %r{\A(.+)[\\/]\*+\z}
|
|
472
|
+
return self unless checkdir?(path = basepath($1))
|
|
433
473
|
|
|
434
474
|
path = path.children.select { |val| checkdir?(val) }
|
|
435
475
|
end
|
|
436
476
|
if path.is_a?(Array)
|
|
437
|
-
name =
|
|
477
|
+
name = self.name if name == true
|
|
438
478
|
path.each { |val| add(val, name && task_join(name, File.basename(val)), **kwargs, &blk) }
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
__send__ :parent_set, parent
|
|
456
|
-
proj = self
|
|
457
|
-
instance_eval(&blk) if block_given?
|
|
479
|
+
elsif projectpath?(path = basepath(path)) && checkdir?(path)
|
|
480
|
+
kwargs = hashdup(@withargs).update(kwargs) if @withargs
|
|
481
|
+
kwargs[:group] = group if group && !kwargs.key?(:group)
|
|
482
|
+
kwargs[:ref] = ref unless kwargs.key?(:ref)
|
|
483
|
+
proj = nil
|
|
484
|
+
name = case name
|
|
485
|
+
when String, Symbol
|
|
486
|
+
name.to_s
|
|
487
|
+
else
|
|
488
|
+
path.basename
|
|
489
|
+
end
|
|
490
|
+
workspace.add(path, name, parent: self, **kwargs) do
|
|
491
|
+
proj = self
|
|
492
|
+
instance_eval(&blk) if block_given?
|
|
493
|
+
end
|
|
494
|
+
@children << proj
|
|
458
495
|
end
|
|
459
|
-
@children << proj
|
|
460
496
|
self
|
|
461
497
|
end
|
|
462
498
|
|
|
@@ -466,15 +502,15 @@ module Squared
|
|
|
466
502
|
end
|
|
467
503
|
|
|
468
504
|
def inject(obj, *args, **kwargs, &blk)
|
|
469
|
-
|
|
505
|
+
if enabled?
|
|
506
|
+
raise 'link not compatible' unless obj.respond_to?(:link) && (out = obj.link(self, *args, **kwargs, &blk))
|
|
470
507
|
|
|
471
|
-
|
|
472
|
-
if !out
|
|
473
|
-
print_error('link not compatible', subject: obj, hint: name)
|
|
474
|
-
elsif out.respond_to?(:build)
|
|
475
|
-
out.build
|
|
508
|
+
out.build if out.respond_to?(:build)
|
|
476
509
|
end
|
|
477
510
|
self
|
|
511
|
+
rescue StandardError => e
|
|
512
|
+
print_error(e, subject: obj, hint: name)
|
|
513
|
+
self
|
|
478
514
|
end
|
|
479
515
|
|
|
480
516
|
def build(*args, sync: invoked_sync?('build'), from: :run, **)
|
|
@@ -482,8 +518,8 @@ module Squared
|
|
|
482
518
|
if args.empty?
|
|
483
519
|
return unless from == :run
|
|
484
520
|
|
|
485
|
-
banner =
|
|
486
|
-
run_b(@run, sync: sync,
|
|
521
|
+
banner = verbose? if from_base?('build')
|
|
522
|
+
run_b(@run, sync: sync, banner: banner, from: from) if series?(@run)
|
|
487
523
|
args = @output
|
|
488
524
|
end
|
|
489
525
|
if args.first.is_a?(Struct)
|
|
@@ -521,12 +557,12 @@ module Squared
|
|
|
521
557
|
if cmd
|
|
522
558
|
return run_b(cmd, sync: sync, from: from) if cmd.is_a?(Proc) || cmd.is_a?(Method)
|
|
523
559
|
|
|
524
|
-
cmd = as_get
|
|
560
|
+
cmd = as_get cmd, from
|
|
525
561
|
opts = compose(opts, script: false) if opts && respond_to?(:compose)
|
|
526
562
|
flags = append_hash(flags, target: []).join(' ') if flags.is_a?(Hash)
|
|
527
563
|
case opts
|
|
528
564
|
when Hash
|
|
529
|
-
cmd = Array(cmd).
|
|
565
|
+
cmd = Array(cmd).push(flags)
|
|
530
566
|
.concat(append_hash(opts, target: [], build: true))
|
|
531
567
|
.compact
|
|
532
568
|
.join(' ')
|
|
@@ -543,7 +579,7 @@ module Squared
|
|
|
543
579
|
cmd = compose(as_get(opts, from), flags, script: true, args: extra, from: from)
|
|
544
580
|
from = :script if from == :run && script?
|
|
545
581
|
end
|
|
546
|
-
run(cmd, var, sync: sync,
|
|
582
|
+
run(cmd, var, sync: sync, banner: banner, from: from)
|
|
547
583
|
end
|
|
548
584
|
|
|
549
585
|
def depend(*, sync: invoked_sync?('depend'), **)
|
|
@@ -556,7 +592,7 @@ module Squared
|
|
|
556
592
|
next if @@graph[:_].include?(proj)
|
|
557
593
|
|
|
558
594
|
if (val = ENV["PREREQS_#{proj.instance_variable_get(:@envname)}"] || ENV["PREREQS_#{proj.ref.upcase}"])
|
|
559
|
-
val
|
|
595
|
+
split_escape(val) do |meth|
|
|
560
596
|
if proj.respond_to?(meth.to_sym)
|
|
561
597
|
begin
|
|
562
598
|
proj.__send__(meth, sync: sync)
|
|
@@ -615,7 +651,7 @@ module Squared
|
|
|
615
651
|
begin
|
|
616
652
|
@clean.each { |cmd, opts| build(cmd.to_s, opts, sync: sync) }
|
|
617
653
|
rescue StandardError => e
|
|
618
|
-
on_error e,
|
|
654
|
+
on_error e, :clean
|
|
619
655
|
end
|
|
620
656
|
else
|
|
621
657
|
if @clean.is_a?(Enumerable) && !series?(@clean)
|
|
@@ -643,9 +679,9 @@ module Squared
|
|
|
643
679
|
end
|
|
644
680
|
|
|
645
681
|
def graph(start = [], tasks = nil, *, sync: invoked_sync?('graph'), pass: [], out: nil, **)
|
|
646
|
-
|
|
682
|
+
env('GRAPH', strict: true) do |val|
|
|
647
683
|
tasks ||= []
|
|
648
|
-
split_escape(val)
|
|
684
|
+
split_escape(val) do |task|
|
|
649
685
|
if ref?(task.to_sym) && (script = workspace.script_get(:graph, ref: task.to_sym))
|
|
650
686
|
tasks.concat(script[:graph])
|
|
651
687
|
else
|
|
@@ -653,7 +689,7 @@ module Squared
|
|
|
653
689
|
end
|
|
654
690
|
end
|
|
655
691
|
end
|
|
656
|
-
|
|
692
|
+
env('GRAPH', suffix: 'PASS') { |val| pass.concat(split_escape(val)) }
|
|
657
693
|
start, neg = start.partition { |name| !name.start_with?('-') }
|
|
658
694
|
data = graph_collect(self, start, pass: neg.map! { |name| name[1..-1] })
|
|
659
695
|
unless out
|
|
@@ -676,9 +712,9 @@ module Squared
|
|
|
676
712
|
if !target.exist?
|
|
677
713
|
target.mkpath
|
|
678
714
|
elsif !target.directory?
|
|
679
|
-
raise_error
|
|
715
|
+
raise_error Errno::EEXIST, target, hint: uri
|
|
680
716
|
elsif !file && !target.empty?
|
|
681
|
-
raise_error
|
|
717
|
+
raise_error Errno::EEXIST, target, hint: uri unless force || env('UNPACK_FORCE')
|
|
682
718
|
create = true
|
|
683
719
|
end
|
|
684
720
|
if digest
|
|
@@ -698,25 +734,27 @@ module Squared
|
|
|
698
734
|
when 128, 'sha512'
|
|
699
735
|
Digest::SHA512
|
|
700
736
|
else
|
|
701
|
-
raise_error "invalid checksum: #{digest}"
|
|
737
|
+
raise_error "invalid checksum: #{digest}", hint: uri
|
|
702
738
|
end
|
|
703
739
|
end
|
|
704
|
-
|
|
705
|
-
|
|
740
|
+
env('HEADERS') do |val|
|
|
741
|
+
if (data = parse_json(val, hint: "HEADERS_#{@envname}"))
|
|
742
|
+
headers = headers.is_a?(Hash) ? headers.merge(data) : data
|
|
743
|
+
end
|
|
706
744
|
end
|
|
707
745
|
if file
|
|
708
746
|
ext ||= File.extname(file)[1..-1]
|
|
709
747
|
else
|
|
710
748
|
require 'open-uri'
|
|
711
749
|
data = nil
|
|
712
|
-
(uri = Array(uri)).each_with_index do |url,
|
|
750
|
+
(uri = Array(uri)).each_with_index do |url, i|
|
|
713
751
|
URI.open(url, headers) do |f|
|
|
714
752
|
data = f.read
|
|
715
753
|
if algo && algo.hexdigest(data) != digest
|
|
716
754
|
data = nil
|
|
717
|
-
raise_error
|
|
755
|
+
raise_error "invalid checksum: #{digest}", hint: url if i == uri.size.pred
|
|
718
756
|
end
|
|
719
|
-
next if ext &&
|
|
757
|
+
next if ext && i == 0
|
|
720
758
|
|
|
721
759
|
case f.content_type
|
|
722
760
|
when 'application/zip'
|
|
@@ -725,12 +763,14 @@ module Squared
|
|
|
725
763
|
ext = 'tgz'
|
|
726
764
|
when 'application/x-xz'
|
|
727
765
|
ext = 'txz'
|
|
766
|
+
when 'application/x-7z-compressed'
|
|
767
|
+
ext = '7z'
|
|
728
768
|
end
|
|
729
769
|
end
|
|
730
770
|
break uri = url if data
|
|
731
771
|
end
|
|
732
772
|
unless data && (ext ||= URI.parse(uri).path[/\.(\w+)(?:\?|\z)/, 1])
|
|
733
|
-
raise_error("no content#{data ? ' type' : ''}", hint: uri)
|
|
773
|
+
raise_error(data ? TypeError : RuntimeError, "no content#{data ? ' type' : ''}", hint: uri)
|
|
734
774
|
end
|
|
735
775
|
end
|
|
736
776
|
ext = ext.downcase
|
|
@@ -739,13 +779,13 @@ module Squared
|
|
|
739
779
|
end
|
|
740
780
|
begin
|
|
741
781
|
unless file
|
|
742
|
-
if ext == 'gem'
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
782
|
+
file = if ext == 'gem'
|
|
783
|
+
dir = Dir.mktmpdir
|
|
784
|
+
File.new(File.join(dir, File.basename(uri)), 'w')
|
|
785
|
+
else
|
|
786
|
+
require 'tempfile'
|
|
787
|
+
Tempfile.new("#{name}-")
|
|
788
|
+
end
|
|
749
789
|
file.write(data)
|
|
750
790
|
file.close
|
|
751
791
|
file = Pathname.new(file)
|
|
@@ -759,7 +799,7 @@ module Squared
|
|
|
759
799
|
case ext
|
|
760
800
|
when 'zip', 'aar'
|
|
761
801
|
session 'unzip', shell_quote(file), quote_option('d', target)
|
|
762
|
-
when 'tar',
|
|
802
|
+
when 'tar', /\A(?:t|tar\.)?[gx]z\z/
|
|
763
803
|
flags = +(verbose ? 'v' : '')
|
|
764
804
|
if ext.end_with?('gz')
|
|
765
805
|
flags += 'z'
|
|
@@ -802,16 +842,17 @@ module Squared
|
|
|
802
842
|
def asdf(flag, opts = [], version: nil)
|
|
803
843
|
return unless @asdf
|
|
804
844
|
|
|
805
|
-
cmd = session 'asdf', flag
|
|
845
|
+
cmd = flag == :update ? session('asdf', 'plugin update') : session('asdf', flag)
|
|
806
846
|
name = @asdf.first
|
|
807
|
-
legacy = @@asdf
|
|
847
|
+
legacy = @@asdf.version == 15
|
|
848
|
+
banner = true
|
|
808
849
|
case flag
|
|
809
850
|
when :set
|
|
810
|
-
u = has_value?(opts,
|
|
851
|
+
u = has_value?(opts, 'u', 'home')
|
|
811
852
|
cmd << if legacy
|
|
812
853
|
cmd.delete(flag)
|
|
813
854
|
u ? 'global' : 'local'
|
|
814
|
-
elsif has_value?(opts,
|
|
855
|
+
elsif has_value?(opts, 'p', 'parent')
|
|
815
856
|
'--parent'
|
|
816
857
|
elsif u
|
|
817
858
|
'--home'
|
|
@@ -822,8 +863,11 @@ module Squared
|
|
|
822
863
|
when :current
|
|
823
864
|
cmd << '--no-header' unless legacy
|
|
824
865
|
cmd << name
|
|
866
|
+
else
|
|
867
|
+
cmd << name
|
|
868
|
+
banner = flag == :update || flag == :reshim
|
|
825
869
|
end
|
|
826
|
-
|
|
870
|
+
success?(run(banner: banner, from: :"asdf:#{flag}"), flag == :set || flag == :reshim)
|
|
827
871
|
end
|
|
828
872
|
|
|
829
873
|
def first(key, *args, **kwargs, &blk)
|
|
@@ -863,28 +907,27 @@ module Squared
|
|
|
863
907
|
instance_variable_set :"@#{key}", [blk]
|
|
864
908
|
end
|
|
865
909
|
else
|
|
866
|
-
log&.warn "series: @#{key}
|
|
910
|
+
log&.warn "series: @#{key}".subhint('invalid')
|
|
867
911
|
end
|
|
868
912
|
self
|
|
869
913
|
end
|
|
870
914
|
|
|
871
|
-
def run(cmd = @session, var = nil, exception: self.exception, sync: true,
|
|
872
|
-
interactive: nil, hint: nil, **)
|
|
873
|
-
unless cmd
|
|
874
|
-
|
|
875
|
-
return
|
|
876
|
-
end
|
|
915
|
+
def run(cmd = @session, var = nil, exception: self.exception, sync: true, banner: true, from: nil, chdir: path,
|
|
916
|
+
interactive: nil, hint: nil, series: true, **)
|
|
917
|
+
return print_error('no command session started', subject: project, hint: from, pass: true) unless cmd
|
|
918
|
+
|
|
877
919
|
cmd = cmd.target if cmd.is_a?(OptionPartition)
|
|
878
|
-
if interactive && (!@session || !option('y'))
|
|
879
|
-
title, y = case interactive
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
920
|
+
if interactive && sync && (!@session || !option('y'))
|
|
921
|
+
title, y, hint = case interactive
|
|
922
|
+
when Array
|
|
923
|
+
interactive
|
|
924
|
+
when String
|
|
925
|
+
[interactive, 'N']
|
|
926
|
+
else
|
|
927
|
+
['Run', 'Y']
|
|
928
|
+
end
|
|
929
|
+
title = "#{title} #{sub_style(hint, styles: theme[:active])}" if hint
|
|
930
|
+
exit 1 unless confirm_basic("#{title}?", cmd, y)
|
|
888
931
|
end
|
|
889
932
|
cmd = session_done cmd
|
|
890
933
|
log&.info cmd
|
|
@@ -894,7 +937,7 @@ module Squared
|
|
|
894
937
|
log&.warn "ENV discarded: #{var}" if var
|
|
895
938
|
task_invoke(cmd, exception: exception, warning: warning?)
|
|
896
939
|
else
|
|
897
|
-
print_item
|
|
940
|
+
print_item(format_banner(cmd, banner: banner, hint: hint), series: series) if sync
|
|
898
941
|
if var != false && (pre = runenv)
|
|
899
942
|
case pre
|
|
900
943
|
when Hash
|
|
@@ -926,14 +969,7 @@ module Squared
|
|
|
926
969
|
args = block_args args, &blk
|
|
927
970
|
end
|
|
928
971
|
if variables.include?(key) || blocks.include?(key)
|
|
929
|
-
val =
|
|
930
|
-
when 0
|
|
931
|
-
nil
|
|
932
|
-
when 1
|
|
933
|
-
args.first
|
|
934
|
-
else
|
|
935
|
-
args
|
|
936
|
-
end
|
|
972
|
+
val = args.size > 1 ? args : args.first
|
|
937
973
|
case key
|
|
938
974
|
when :index
|
|
939
975
|
index_set val
|
|
@@ -963,7 +999,7 @@ module Squared
|
|
|
963
999
|
instance_variable_set(:"@#{key}", val)
|
|
964
1000
|
end
|
|
965
1001
|
else
|
|
966
|
-
log&.warn "variable_set: @#{key}
|
|
1002
|
+
log&.warn "variable_set: @#{key}".subhint('private')
|
|
967
1003
|
end
|
|
968
1004
|
self
|
|
969
1005
|
end
|
|
@@ -986,6 +1022,10 @@ module Squared
|
|
|
986
1022
|
@ref.include?(val)
|
|
987
1023
|
end
|
|
988
1024
|
|
|
1025
|
+
def exist?(*args)
|
|
1026
|
+
basepath(*args).exist?
|
|
1027
|
+
end
|
|
1028
|
+
|
|
989
1029
|
def build?
|
|
990
1030
|
!!@output[0] || script? || series?(@run)
|
|
991
1031
|
end
|
|
@@ -1059,10 +1099,14 @@ module Squared
|
|
|
1059
1099
|
@dependindex ? @dependindex.succ : 0
|
|
1060
1100
|
end
|
|
1061
1101
|
|
|
1102
|
+
def dependname
|
|
1103
|
+
@dependname ||= dependfile&.basename.to_s
|
|
1104
|
+
end
|
|
1105
|
+
|
|
1062
1106
|
def log
|
|
1063
1107
|
return @log unless @log.is_a?(Array)
|
|
1064
1108
|
|
|
1065
|
-
@log = Logger.new(
|
|
1109
|
+
@log = Logger.new((@log.first if enabled?), **@log.last)
|
|
1066
1110
|
end
|
|
1067
1111
|
|
|
1068
1112
|
def allref
|
|
@@ -1089,6 +1133,12 @@ module Squared
|
|
|
1089
1133
|
workspace.task_localname(name)
|
|
1090
1134
|
end
|
|
1091
1135
|
|
|
1136
|
+
def scriptname(from: :run)
|
|
1137
|
+
return unless (name = @output[1]) && respond_to?(:compose)
|
|
1138
|
+
|
|
1139
|
+
as_get name, from
|
|
1140
|
+
end
|
|
1141
|
+
|
|
1092
1142
|
def inspect
|
|
1093
1143
|
"#<#{self.class}: #{name} => #{self}>"
|
|
1094
1144
|
end
|
|
@@ -1107,10 +1157,18 @@ module Squared
|
|
|
1107
1157
|
log_console(*args, pipe: kwargs[:pipe] || pipe)
|
|
1108
1158
|
end
|
|
1109
1159
|
|
|
1110
|
-
def run_s(*cmd,
|
|
1160
|
+
def run_s(*cmd, sync: true, banner: verbosetype > 0, from: nil, **kwargs)
|
|
1161
|
+
cmd.flatten!
|
|
1162
|
+
case cmd.last
|
|
1163
|
+
when Hash, TrueClass, FalseClass
|
|
1164
|
+
var = cmd.pop
|
|
1165
|
+
end
|
|
1111
1166
|
on :first, from
|
|
1112
1167
|
begin
|
|
1113
|
-
cmd.
|
|
1168
|
+
cmd.each do |val|
|
|
1169
|
+
print_run val, banner
|
|
1170
|
+
run(val, var, sync: sync, banner: banner, **kwargs)
|
|
1171
|
+
end
|
|
1114
1172
|
rescue StandardError => e
|
|
1115
1173
|
ret = on :error, from, e
|
|
1116
1174
|
raise unless ret == true
|
|
@@ -1127,7 +1185,12 @@ module Squared
|
|
|
1127
1185
|
when Proc
|
|
1128
1186
|
instance_eval(&obj)
|
|
1129
1187
|
when Method
|
|
1130
|
-
obj.
|
|
1188
|
+
args = if (n = obj.arity.abs) > 0
|
|
1189
|
+
Array.new(n).tap { |data| data[0] = self }
|
|
1190
|
+
else
|
|
1191
|
+
[]
|
|
1192
|
+
end
|
|
1193
|
+
obj.call(*args)
|
|
1131
1194
|
else
|
|
1132
1195
|
if series?(obj)
|
|
1133
1196
|
obj.each(&:call)
|
|
@@ -1142,7 +1205,7 @@ module Squared
|
|
|
1142
1205
|
def graph_branch(target, data, tasks = nil, out = nil, sync: true, pass: [], done: [], depth: 0,
|
|
1143
1206
|
single: false, last: false, context: nil)
|
|
1144
1207
|
tag = ->(proj) { "#{proj.name}#{SEM_VER.match?(proj.version) ? "@#{proj.version}" : ''}" }
|
|
1145
|
-
|
|
1208
|
+
script = ->(proj) { workspace.script_get(:graph, group: proj.group, ref: proj.allref)&.fetch(:graph, nil) }
|
|
1146
1209
|
dedupe = lambda do |name|
|
|
1147
1210
|
next [] unless (ret = data[name])
|
|
1148
1211
|
|
|
@@ -1153,12 +1216,11 @@ module Squared
|
|
|
1153
1216
|
end
|
|
1154
1217
|
ret
|
|
1155
1218
|
end
|
|
1156
|
-
start = target.name
|
|
1157
1219
|
if depth == 0
|
|
1158
|
-
items =
|
|
1220
|
+
items = dedupe.call(target.name) - done
|
|
1159
1221
|
single = items.size == 1
|
|
1160
1222
|
else
|
|
1161
|
-
items =
|
|
1223
|
+
items = data[target.name] - done
|
|
1162
1224
|
end
|
|
1163
1225
|
if out
|
|
1164
1226
|
a, b, c, d, e = ARG[:GRAPH]
|
|
@@ -1173,53 +1235,50 @@ module Squared
|
|
|
1173
1235
|
"#{last ? d : c}#{b * 3}#{e} #{f}"
|
|
1174
1236
|
end
|
|
1175
1237
|
else
|
|
1176
|
-
"#{single ? ' ' : a}#{' ' *
|
|
1238
|
+
"#{single ? ' ' : a}#{' ' * depth.pred}#{last ? d : c}#{b * 3}#{items.empty? ? b : e} #{f}"
|
|
1177
1239
|
end
|
|
1178
1240
|
end
|
|
1179
1241
|
items.each_with_index do |proj, i|
|
|
1180
1242
|
next if done.include?(proj)
|
|
1181
1243
|
|
|
1182
|
-
t = dedupe.call(proj.name)
|
|
1244
|
+
t = dedupe.call(name = proj.name)
|
|
1183
1245
|
j = if out
|
|
1184
|
-
if i == items.size
|
|
1246
|
+
if i == items.size.pred || (post = items[i.succ..-1] - done).empty?
|
|
1185
1247
|
true
|
|
1186
1248
|
elsif !t.empty? && depth > 0
|
|
1187
|
-
post
|
|
1249
|
+
(post - t).empty?
|
|
1188
1250
|
end
|
|
1189
1251
|
end
|
|
1190
|
-
unless
|
|
1252
|
+
unless target.name == name || (none = (t - done).empty?)
|
|
1191
1253
|
graph_branch(proj, data, tasks, out, sync: sync, pass: pass, done: done, depth: depth.succ,
|
|
1192
1254
|
single: single, last: j == true, context: target)
|
|
1193
1255
|
end
|
|
1194
1256
|
if !out
|
|
1195
|
-
|
|
1196
|
-
tasks = script[:graph]
|
|
1197
|
-
end
|
|
1198
|
-
(tasks || (dev? ? ['build', 'copy'] : ['depend', 'build'])).each do |meth|
|
|
1257
|
+
(tasks || (subtasks = script.call(proj)) || (dev? ? %w[build copy] : %w[depend build])).each do |meth|
|
|
1199
1258
|
next if pass.include?(meth)
|
|
1200
1259
|
|
|
1201
|
-
if workspace.task_defined?(cmd = task_join(
|
|
1202
|
-
if ENV.key?(key = "BANNER_#{
|
|
1260
|
+
if workspace.task_defined?(cmd = task_join(name, meth))
|
|
1261
|
+
if ENV.key?(key = "BANNER_#{name.upcase}")
|
|
1203
1262
|
key = nil
|
|
1204
1263
|
else
|
|
1205
1264
|
ENV[key] = '0'
|
|
1206
1265
|
end
|
|
1207
1266
|
run(cmd, sync: false, banner: false)
|
|
1208
1267
|
ENV.delete(key) if key
|
|
1209
|
-
elsif proj.has?(meth,
|
|
1268
|
+
elsif proj.has?(meth, (workspace.baseref unless tasks || subtasks))
|
|
1210
1269
|
proj.__send__(meth.to_sym, sync: sync)
|
|
1211
1270
|
end
|
|
1212
1271
|
end
|
|
1213
1272
|
elsif none
|
|
1214
1273
|
a, b, c, d = ARG[:GRAPH]
|
|
1215
1274
|
out << if depth == 0
|
|
1216
|
-
"#{i == items.size
|
|
1275
|
+
"#{i == items.size.pred ? d : c}#{b * 4} #{tag.call(proj)}"
|
|
1217
1276
|
else
|
|
1218
1277
|
s = ''.dup
|
|
1219
1278
|
k = 0
|
|
1220
1279
|
final = data.keys.last
|
|
1221
1280
|
while k < depth
|
|
1222
|
-
indent = k > 0 ? ((last && !j) || (j && k == depth
|
|
1281
|
+
indent = k > 0 ? ((last && !j) || (j && k == depth.pred) || single) : j && last && depth == 1
|
|
1223
1282
|
s += "#{indent || (last && data[final].last == context) ? ' ' : a} "
|
|
1224
1283
|
k += 1
|
|
1225
1284
|
end
|
|
@@ -1237,22 +1296,19 @@ module Squared
|
|
|
1237
1296
|
next if pass.include?(val)
|
|
1238
1297
|
|
|
1239
1298
|
if (obj = workspace.find(name: val))
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
items = [obj]
|
|
1299
|
+
obj.enabled? ? [obj] : []
|
|
1243
1300
|
else
|
|
1244
|
-
|
|
1245
|
-
end
|
|
1246
|
-
items.each do |proj|
|
|
1301
|
+
workspace.find(group: val, ref: val.to_sym)
|
|
1302
|
+
end.each do |proj|
|
|
1247
1303
|
next if pass.include?(name = proj.name)
|
|
1248
1304
|
|
|
1249
1305
|
if proj.graph? && !data.key?(name) && !root.include?(name)
|
|
1250
1306
|
graph_collect(proj, data: data, pass: pass, root: root + [name, target.name])
|
|
1251
1307
|
end
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1308
|
+
unless (objs = data.fetch(name, [])).include?(target)
|
|
1309
|
+
deps << proj
|
|
1310
|
+
deps.concat(objs)
|
|
1311
|
+
end
|
|
1256
1312
|
end
|
|
1257
1313
|
end
|
|
1258
1314
|
deps.uniq!
|
|
@@ -1278,44 +1334,96 @@ module Squared
|
|
|
1278
1334
|
end
|
|
1279
1335
|
|
|
1280
1336
|
def env(key, default = nil, suffix: nil, equals: nil, ignore: nil, strict: false)
|
|
1281
|
-
|
|
1337
|
+
name = "#{key}_#{@envname}"
|
|
1282
1338
|
ret = if suffix
|
|
1283
|
-
ENV.fetch("#{
|
|
1339
|
+
ENV.fetch("#{name}_#{suffix}", '')
|
|
1284
1340
|
elsif strict
|
|
1285
|
-
ENV[
|
|
1341
|
+
ENV[name].to_s
|
|
1286
1342
|
else
|
|
1287
1343
|
ignore = ['0'].freeze if ignore.nil?
|
|
1288
|
-
ENV[
|
|
1344
|
+
ENV[name] || ENV.fetch(key, '')
|
|
1289
1345
|
end
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
ret.empty? || (ignore && Array(ignore).any? { |val| ret == val.to_s })
|
|
1346
|
+
if !equals.nil?
|
|
1347
|
+
ret = ret == equals.to_s
|
|
1348
|
+
elsif ret.empty? || (ignore && Array(ignore).any? { |val| ret == val.to_s })
|
|
1349
|
+
ret = default
|
|
1350
|
+
end
|
|
1351
|
+
block_given? && !ret.nil? ? yield(ret) : ret
|
|
1293
1352
|
end
|
|
1294
1353
|
|
|
1295
1354
|
def session(*cmd, prefix: cmd.first, main: true, path: true, options: true)
|
|
1296
|
-
prefix =
|
|
1355
|
+
prefix = prefix.to_s.stripext
|
|
1297
1356
|
if path && (val = shell_bin(prefix))
|
|
1298
1357
|
cmd[0] = shell_quote(val, force: false)
|
|
1299
1358
|
end
|
|
1300
1359
|
ret = JoinSet.new(cmd.flatten(1))
|
|
1301
|
-
if options
|
|
1302
|
-
|
|
1360
|
+
if options
|
|
1361
|
+
env("#{prefix.upcase}_OPTIONS") do |val|
|
|
1362
|
+
if val.start_with('-')
|
|
1363
|
+
ret.concat(shell_parse(val))
|
|
1364
|
+
else
|
|
1365
|
+
split_escape(val) { |opt| ret.last(fill_option(opt), /\A(--?[^= ]+)[= ].+\z/m) }
|
|
1366
|
+
end
|
|
1367
|
+
end
|
|
1303
1368
|
end
|
|
1304
1369
|
main ? @session = ret : ret
|
|
1305
1370
|
end
|
|
1306
1371
|
|
|
1307
|
-
def session_delete(*args, target: @session)
|
|
1308
|
-
OptionPartition.delete(target, *args)
|
|
1309
|
-
end
|
|
1310
|
-
|
|
1311
1372
|
def session_output(*cmd, **kwargs)
|
|
1312
1373
|
session(*cmd, main: false, options: false, **kwargs)
|
|
1313
1374
|
end
|
|
1314
1375
|
|
|
1376
|
+
def session_get(val, pass: nil)
|
|
1377
|
+
base = OPTIONS[ref]
|
|
1378
|
+
args = []
|
|
1379
|
+
kwargs = {}
|
|
1380
|
+
with = []
|
|
1381
|
+
[:_, name.to_sym].each do |key|
|
|
1382
|
+
next unless base.key?(key) && (a, b, c = base[key][val])
|
|
1383
|
+
|
|
1384
|
+
args.concat(a)
|
|
1385
|
+
append_keys(kwargs, b, :opts)
|
|
1386
|
+
with.concat(c)
|
|
1387
|
+
end
|
|
1388
|
+
OptionPartition.uniq!(args, pass) if pass
|
|
1389
|
+
[args, kwargs, with]
|
|
1390
|
+
end
|
|
1391
|
+
|
|
1392
|
+
def session_apply(val, args: nil, kwargs: nil, pass: [], keys: [:opts], exclude: [])
|
|
1393
|
+
a = []
|
|
1394
|
+
b = {}
|
|
1395
|
+
Array(val).each do |c|
|
|
1396
|
+
d, e, f = session_get c
|
|
1397
|
+
unless (f -= exclude).empty?
|
|
1398
|
+
h = []
|
|
1399
|
+
i = {}
|
|
1400
|
+
session_apply(f.map!(&:to_s), args: h, kwargs: i, pass: pass, keys: keys, exclude: exclude.concat(f))
|
|
1401
|
+
a.concat(h)
|
|
1402
|
+
append_keys(b, i, *keys)
|
|
1403
|
+
end
|
|
1404
|
+
a.concat(d)
|
|
1405
|
+
append_keys(b, e, *keys)
|
|
1406
|
+
end
|
|
1407
|
+
if args
|
|
1408
|
+
args.unshift(*a)
|
|
1409
|
+
OptionPartition.uniq!(args, pass) if pass
|
|
1410
|
+
end
|
|
1411
|
+
kwargs&.update(b) { |_, val| val }
|
|
1412
|
+
nil
|
|
1413
|
+
end
|
|
1414
|
+
|
|
1415
|
+
def session_opts(val, args: nil, kwargs: nil, pass: nil, keys: [:opts])
|
|
1416
|
+
opts = kwargs.delete(:opts) || []
|
|
1417
|
+
return opts unless val
|
|
1418
|
+
|
|
1419
|
+
session_apply(val, args: args, kwargs: kwargs, pass: pass, keys: keys)
|
|
1420
|
+
kwargs.fetch(:opts, []).concat(opts)
|
|
1421
|
+
end
|
|
1422
|
+
|
|
1315
1423
|
def session_done(cmd)
|
|
1316
|
-
return cmd unless cmd.respond_to?(:done)
|
|
1424
|
+
return cmd.to_s unless cmd.respond_to?(:done)
|
|
1317
1425
|
|
|
1318
|
-
raise_error
|
|
1426
|
+
raise_error 'no command added', hint: cmd.first unless cmd.size > 1
|
|
1319
1427
|
@session = nil if cmd == @session
|
|
1320
1428
|
cmd.done
|
|
1321
1429
|
end
|
|
@@ -1330,20 +1438,22 @@ module Squared
|
|
|
1330
1438
|
return unless prefix
|
|
1331
1439
|
|
|
1332
1440
|
args.each do |val|
|
|
1333
|
-
next unless (ret = env(env_key(stripext
|
|
1441
|
+
next unless (ret = env(env_key(prefix.to_s.stripext, val), **kwargs))
|
|
1334
1442
|
|
|
1335
1443
|
return block_given? ? yield(ret) : ret
|
|
1336
1444
|
end
|
|
1337
1445
|
nil
|
|
1338
1446
|
end
|
|
1339
1447
|
|
|
1340
|
-
def option_clear(opts, target: @session, **kwargs)
|
|
1448
|
+
def option_clear(opts, empty = true, target: @session, **kwargs)
|
|
1341
1449
|
return unless target
|
|
1342
1450
|
|
|
1343
1451
|
OptionPartition.clear(target, opts, styles: theme[:inline], **kwargs)
|
|
1452
|
+
opts.clear if empty
|
|
1453
|
+
nil
|
|
1344
1454
|
end
|
|
1345
1455
|
|
|
1346
|
-
def print_success
|
|
1456
|
+
def print_success
|
|
1347
1457
|
puts 'Success'
|
|
1348
1458
|
end
|
|
1349
1459
|
|
|
@@ -1351,10 +1461,17 @@ module Squared
|
|
|
1351
1461
|
warn log_message(loglevel, *args, **kwargs) if warning?
|
|
1352
1462
|
end
|
|
1353
1463
|
|
|
1354
|
-
def
|
|
1355
|
-
|
|
1464
|
+
def print_run(cmd, banner = true, verbose: nil, **)
|
|
1465
|
+
return if banner || !stdout? || verbose == false
|
|
1466
|
+
|
|
1467
|
+
puts "\n> #{cmd}"
|
|
1356
1468
|
printsucc
|
|
1357
|
-
|
|
1469
|
+
end
|
|
1470
|
+
|
|
1471
|
+
def print_item(*val, series: true)
|
|
1472
|
+
puts unless printfirst?
|
|
1473
|
+
printsucc if series
|
|
1474
|
+
puts val unless val.empty? || (val.size == 1 && !val.first)
|
|
1358
1475
|
end
|
|
1359
1476
|
|
|
1360
1477
|
def print_banner(*lines, client: false, styles: theme[:banner], border: borderstyle, **)
|
|
@@ -1383,14 +1500,15 @@ module Squared
|
|
|
1383
1500
|
|
|
1384
1501
|
def print_footer(*lines, sub: nil, reverse: false, right: false, border: borderstyle, **)
|
|
1385
1502
|
n = line_width lines
|
|
1503
|
+
sub = as_a sub
|
|
1386
1504
|
lines.map! do |val|
|
|
1387
1505
|
s = right ? val.rjust(n) : val.ljust(n)
|
|
1388
|
-
sub
|
|
1506
|
+
sub.each { |h| s = sub_style(s, **h) }
|
|
1389
1507
|
s
|
|
1390
1508
|
end
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1509
|
+
[sub_style(ARG[:BORDER][1] * n, styles: border)].concat(lines)
|
|
1510
|
+
.tap { |ret| ret.reverse! if reverse }
|
|
1511
|
+
.join("\n")
|
|
1394
1512
|
end
|
|
1395
1513
|
|
|
1396
1514
|
def print_status(*args, from: nil, **kwargs)
|
|
@@ -1399,15 +1517,15 @@ module Squared
|
|
|
1399
1517
|
case from
|
|
1400
1518
|
when :outdated
|
|
1401
1519
|
out = print_footer("major #{args[0]} / minor #{args[1]} / patch #{args[2]}", right: true).split("\n")
|
|
1402
|
-
out[1] = sub_style(out[1],
|
|
1403
|
-
out[1] = sub_style(out[1],
|
|
1520
|
+
out[1] = sub_style(out[1], **opt_style(theme[:major], /^( +major )(\d+)(.+)$/, 2))
|
|
1521
|
+
out[1] = sub_style(out[1], **opt_style(theme[:active], /^(.+)(minor )(\d+)(.+)$/, 3))
|
|
1522
|
+
out[1] = sub_style(out[1], **opt_style(theme[:current], /^(.+)(patch )(\d+)(.+)$/, 3)) if theme[:current]
|
|
1404
1523
|
puts out
|
|
1405
1524
|
when :completed
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
end
|
|
1525
|
+
return unless verbose && kwargs[:start]
|
|
1526
|
+
|
|
1527
|
+
puts log_message(Logger::INFO, *args, sub_style('completed', styles: theme[:active]),
|
|
1528
|
+
subject: kwargs[:subject], hint: time_format(time_epoch - kwargs[:start]))
|
|
1411
1529
|
end
|
|
1412
1530
|
end
|
|
1413
1531
|
|
|
@@ -1417,7 +1535,7 @@ module Squared
|
|
|
1417
1535
|
workspace.format_desc([@desc, action, flag].compact, opts, **kwargs)
|
|
1418
1536
|
end
|
|
1419
1537
|
|
|
1420
|
-
def format_banner(cmd, banner: true)
|
|
1538
|
+
def format_banner(cmd, banner: true, hint: nil, strip: nil)
|
|
1421
1539
|
return unless banner && banner?
|
|
1422
1540
|
|
|
1423
1541
|
if (data = workspace.banner_get(*@ref, group: group))
|
|
@@ -1431,11 +1549,14 @@ module Squared
|
|
|
1431
1549
|
out = []
|
|
1432
1550
|
if data.command
|
|
1433
1551
|
if cmd =~ /\A(?:"((?:[^"]|(?<=\\)")+)"|'((?:[^']|(?<=\\)')+)'|(\S+))( |\z)/
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1552
|
+
arg = $3 || $2 || $1
|
|
1553
|
+
cmd = cmd.sub(arg, data.command == 0 ? arg.stripext : arg.stripext.upcase)
|
|
1554
|
+
end
|
|
1555
|
+
if strip || (strip.nil? && data.order.include?(:path))
|
|
1556
|
+
cmd = cmd.gsub(/(?:#{s = Regexp.escape(File.join(path, ''))}?(?=["'])|#{s})/, '')
|
|
1557
|
+
.gsub(/(?: -[^ ])? (?:""|'')/, '')
|
|
1437
1558
|
end
|
|
1438
|
-
out << cmd
|
|
1559
|
+
out << cmd.subhint(hint)
|
|
1439
1560
|
end
|
|
1440
1561
|
data.order.each do |val|
|
|
1441
1562
|
if val.is_a?(Array)
|
|
@@ -1463,7 +1584,7 @@ module Squared
|
|
|
1463
1584
|
end
|
|
1464
1585
|
end
|
|
1465
1586
|
|
|
1466
|
-
def format_list(items, cmd, type, grep: [], from: nil
|
|
1587
|
+
def format_list(items, cmd, type, grep: [], from: nil)
|
|
1467
1588
|
reg = grep.map { |val| Regexp.new(val) }
|
|
1468
1589
|
out = []
|
|
1469
1590
|
unless items.empty?
|
|
@@ -1471,29 +1592,29 @@ module Squared
|
|
|
1471
1592
|
items.each_with_index do |val, i|
|
|
1472
1593
|
next unless matchany?(val.first, reg)
|
|
1473
1594
|
|
|
1474
|
-
out << ('%*d. %s' % [pad, i.succ,
|
|
1595
|
+
out << ('%*d. %s' % [pad, i.succ, block_given? ? yield(val) : val.first])
|
|
1475
1596
|
end
|
|
1476
1597
|
end
|
|
1477
1598
|
sub = [headerstyle]
|
|
1478
|
-
if out.empty?
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
sub <<
|
|
1599
|
+
pat = if out.empty?
|
|
1600
|
+
out = ["No #{type} were found:", '']
|
|
1601
|
+
unless grep.empty?
|
|
1602
|
+
i = 0
|
|
1603
|
+
out.concat(grep.map { |s| "#{i += 1}. #{s}" })
|
|
1604
|
+
out << ''
|
|
1605
|
+
end
|
|
1606
|
+
if from
|
|
1607
|
+
out << (from = from.to_s)
|
|
1608
|
+
/\A(#{Regexp.escape(from)})(.*)\z/
|
|
1609
|
+
end
|
|
1610
|
+
else
|
|
1611
|
+
unless grep.empty?
|
|
1612
|
+
footer = "#{out.size} found "
|
|
1613
|
+
sub << opt_style(theme[:inline], /\A(\d+)( .+)\z/)
|
|
1614
|
+
end
|
|
1615
|
+
/\A(\s*\d+\.)(.+)\z/
|
|
1616
|
+
end
|
|
1617
|
+
sub << opt_style(theme[:active], pat) if pat
|
|
1497
1618
|
emphasize(out, title: task_join(name, cmd), border: borderstyle, sub: sub, footer: footer, right: true)
|
|
1498
1619
|
end
|
|
1499
1620
|
|
|
@@ -1507,8 +1628,7 @@ module Squared
|
|
|
1507
1628
|
|
|
1508
1629
|
def append_hash(data, target: @session || [], build: false)
|
|
1509
1630
|
if build && (type = env('BUILD', suffix: 'TYPE') || ENV['BUILD_TYPE'])
|
|
1510
|
-
type = "__#{type}__"
|
|
1511
|
-
if (extra = data[type] || data[type.to_sym]).is_a?(Hash)
|
|
1631
|
+
if (extra = data[type = "__#{type}__"] || data[type.to_sym]).is_a?(Hash)
|
|
1512
1632
|
data = data.merge(extra)
|
|
1513
1633
|
else
|
|
1514
1634
|
extra = nil
|
|
@@ -1529,30 +1649,24 @@ module Squared
|
|
|
1529
1649
|
when FalseClass
|
|
1530
1650
|
target << shell_option(key).sub(/^--(?!no-)/, '--no-')
|
|
1531
1651
|
else
|
|
1532
|
-
target << shell_option(key, val.is_a?(String)
|
|
1652
|
+
target << shell_option(key, (val if val.is_a?(String)))
|
|
1533
1653
|
end
|
|
1534
1654
|
end
|
|
1535
1655
|
target
|
|
1536
1656
|
end
|
|
1537
1657
|
|
|
1538
1658
|
def append_any(val, target: @session, build: false, delim: false)
|
|
1539
|
-
return unless val
|
|
1540
|
-
|
|
1541
1659
|
if delim && !target.include?('--')
|
|
1542
1660
|
target << '--'
|
|
1543
1661
|
else
|
|
1544
1662
|
delim = false
|
|
1545
1663
|
end
|
|
1546
|
-
val = shell_split
|
|
1664
|
+
val = shell_split val if val.is_a?(String)
|
|
1547
1665
|
case val
|
|
1548
1666
|
when Hash
|
|
1549
1667
|
append_hash(val, target: target, build: build)
|
|
1550
1668
|
when Enumerable
|
|
1551
|
-
|
|
1552
|
-
target.concat(val.to_a)
|
|
1553
|
-
else
|
|
1554
|
-
target.merge(val.to_a)
|
|
1555
|
-
end
|
|
1669
|
+
merge_list target, val
|
|
1556
1670
|
else
|
|
1557
1671
|
target.delete('--') if delim
|
|
1558
1672
|
nil
|
|
@@ -1573,7 +1687,7 @@ module Squared
|
|
|
1573
1687
|
next unless (val = option(opt, **kwargs))
|
|
1574
1688
|
|
|
1575
1689
|
return target << if flag
|
|
1576
|
-
shell_option(opt,
|
|
1690
|
+
shell_option(opt, (val if equals), quote: quote, escape: escape, force: force)
|
|
1577
1691
|
else
|
|
1578
1692
|
shell_quote val
|
|
1579
1693
|
end
|
|
@@ -1593,9 +1707,11 @@ module Squared
|
|
|
1593
1707
|
flag = "no-#{flag}"
|
|
1594
1708
|
val = nil
|
|
1595
1709
|
end
|
|
1596
|
-
ret << shell_option(flag,
|
|
1710
|
+
ret << shell_option(flag, (val if equals), escape: escape, quote: quote, force: force)
|
|
1597
1711
|
end
|
|
1598
|
-
|
|
1712
|
+
next if ret.empty?
|
|
1713
|
+
|
|
1714
|
+
merge_list target, ret
|
|
1599
1715
|
end
|
|
1600
1716
|
end
|
|
1601
1717
|
|
|
@@ -1603,6 +1719,24 @@ module Squared
|
|
|
1603
1719
|
target << '--no-color' if !ARG[:COLOR] || stdin? || option('color', target: target, equals: '0')
|
|
1604
1720
|
end
|
|
1605
1721
|
|
|
1722
|
+
def append_keys(base, data, *keys)
|
|
1723
|
+
out = {}
|
|
1724
|
+
keys.each do |key|
|
|
1725
|
+
next unless data.key?(key)
|
|
1726
|
+
|
|
1727
|
+
out[key] = case (val = data[key])
|
|
1728
|
+
when Array
|
|
1729
|
+
base.fetch(key, []) + val
|
|
1730
|
+
when Hash
|
|
1731
|
+
base.fetch(key, {}).update(val)
|
|
1732
|
+
else
|
|
1733
|
+
val
|
|
1734
|
+
end
|
|
1735
|
+
end
|
|
1736
|
+
base.update(data)
|
|
1737
|
+
.update(out)
|
|
1738
|
+
end
|
|
1739
|
+
|
|
1606
1740
|
def merge_opts(base, data)
|
|
1607
1741
|
case data
|
|
1608
1742
|
when String
|
|
@@ -1643,20 +1777,31 @@ module Squared
|
|
|
1643
1777
|
end
|
|
1644
1778
|
end
|
|
1645
1779
|
|
|
1646
|
-
def
|
|
1647
|
-
|
|
1648
|
-
|
|
1780
|
+
def merge_list(base, data)
|
|
1781
|
+
data = Array(data)
|
|
1782
|
+
case base
|
|
1783
|
+
when Array
|
|
1784
|
+
base.concat(data)
|
|
1785
|
+
when Set
|
|
1786
|
+
base.merge(data)
|
|
1787
|
+
else
|
|
1788
|
+
Array(base).concat(data)
|
|
1649
1789
|
end
|
|
1650
1790
|
end
|
|
1651
1791
|
|
|
1792
|
+
def collect_hash(data, pass: [])
|
|
1793
|
+
ret = []
|
|
1794
|
+
data.each { |key, val| ret.concat(val) unless pass.include?(key) }
|
|
1795
|
+
ret
|
|
1796
|
+
end
|
|
1797
|
+
|
|
1652
1798
|
def parse_json(val, kind: Hash, hint: nil)
|
|
1653
1799
|
ret = JSON.parse(val)
|
|
1654
|
-
raise_error
|
|
1800
|
+
raise_error 'invalid JSON'.subhint(kind.name), val, hint: hint if kind && !ret.is_a?(kind)
|
|
1801
|
+
ret
|
|
1655
1802
|
rescue StandardError => e
|
|
1656
1803
|
log&.warn e
|
|
1657
1804
|
print_error(e, subject: name)
|
|
1658
|
-
else
|
|
1659
|
-
ret
|
|
1660
1805
|
end
|
|
1661
1806
|
|
|
1662
1807
|
def param_guard(action, flag, args:, key: nil, pat: nil, values: nil)
|
|
@@ -1668,12 +1813,16 @@ module Squared
|
|
|
1668
1813
|
raise_error(action, "#{flag}[#{key}]", hint: val.nil? ? 'missing' : 'invalid')
|
|
1669
1814
|
elsif args.is_a?(Array) && args.empty?
|
|
1670
1815
|
@session = nil
|
|
1671
|
-
raise_error
|
|
1816
|
+
raise_error action, "#{flag}+", hint: 'empty'
|
|
1672
1817
|
end
|
|
1673
1818
|
args
|
|
1674
1819
|
end
|
|
1675
1820
|
|
|
1676
|
-
def
|
|
1821
|
+
def confirm_basic(msg, target, default = 'Y', style: :inline, **kwargs)
|
|
1822
|
+
confirm("#{msg} [#{sub_style(target.to_s, styles: theme[style])}]", default, **kwargs)
|
|
1823
|
+
end
|
|
1824
|
+
|
|
1825
|
+
def confirm_outdated(pkg, ver, rev, cur = nil, lock: false, col1: 0, **kwargs)
|
|
1677
1826
|
a = sub_style(case rev
|
|
1678
1827
|
when 1
|
|
1679
1828
|
'MAJOR'
|
|
@@ -1685,16 +1834,17 @@ module Squared
|
|
|
1685
1834
|
b = sub_style(pkg.ljust(col1), styles: theme[:inline])
|
|
1686
1835
|
c = lock ? sub_style((cur || 'locked').rjust(7), styles: color(:red)) : cur&.rjust(7)
|
|
1687
1836
|
d = rev == 1 || lock ? 'N' : 'Y'
|
|
1688
|
-
confirm
|
|
1837
|
+
confirm("#{a}: #{b}#{c} #{sub_style(ver.rjust(col1 > 0 ? 10 : 0), styles: theme[:inline])} ", d, **kwargs)
|
|
1689
1838
|
end
|
|
1690
1839
|
|
|
1691
1840
|
def choice_index(msg, list, values: nil, accept: nil, series: false, trim: nil, column: nil, multiple: false,
|
|
1692
1841
|
force: true, **kwargs)
|
|
1693
|
-
puts
|
|
1694
|
-
|
|
1695
|
-
|
|
1842
|
+
puts unless series || printfirst?
|
|
1843
|
+
ret = choice(msg, list, multiple: multiple, force: force, **kwargs).tap do |val|
|
|
1844
|
+
next unless val.to_s.empty?
|
|
1845
|
+
|
|
1696
1846
|
exit 1 if force
|
|
1697
|
-
return
|
|
1847
|
+
return nil
|
|
1698
1848
|
end
|
|
1699
1849
|
ret = multiple ? ret.map! { |val| val.sub(trim, '') } : ret.sub(trim, '') if trim
|
|
1700
1850
|
if column
|
|
@@ -1708,7 +1858,7 @@ module Squared
|
|
|
1708
1858
|
ret = Array(ret) if accept.any? { |val| val[1] == true }
|
|
1709
1859
|
loop do
|
|
1710
1860
|
item = accept.first
|
|
1711
|
-
c = confirm("#{item[0]}#{hint ? " [#{hint}]" : ''}", item[2] ? 'Y' : 'N'
|
|
1861
|
+
c = confirm("#{item[0]}#{hint ? " [#{hint}]" : ''}", item[2] ? 'Y' : 'N')
|
|
1712
1862
|
if item[1] == true
|
|
1713
1863
|
ret << c
|
|
1714
1864
|
elsif !c
|
|
@@ -1729,25 +1879,29 @@ module Squared
|
|
|
1729
1879
|
force = false
|
|
1730
1880
|
end
|
|
1731
1881
|
val = readline(val, force: force)
|
|
1732
|
-
ret << (val.empty?
|
|
1882
|
+
ret << (val unless val.empty?)
|
|
1733
1883
|
end
|
|
1734
1884
|
end
|
|
1735
1885
|
printsucc unless series
|
|
1736
1886
|
ret
|
|
1737
1887
|
end
|
|
1738
1888
|
|
|
1889
|
+
def accept_b(val, yes = false)
|
|
1890
|
+
[val, true, yes]
|
|
1891
|
+
end
|
|
1892
|
+
|
|
1893
|
+
def accept_y(val, bool = false)
|
|
1894
|
+
[val, bool, true]
|
|
1895
|
+
end
|
|
1896
|
+
|
|
1739
1897
|
def command_args(args, min: 0, force: false, **kwargs)
|
|
1740
1898
|
return if args.size > min || option('i', 'interactive', **kwargs, equals: '0')
|
|
1741
1899
|
|
|
1742
1900
|
readline('Enter arguments', force: force)
|
|
1743
1901
|
end
|
|
1744
1902
|
|
|
1745
|
-
def block_args(
|
|
1746
|
-
|
|
1747
|
-
val
|
|
1748
|
-
else
|
|
1749
|
-
Array(ret)
|
|
1750
|
-
end
|
|
1903
|
+
def block_args(fallback = nil, &blk)
|
|
1904
|
+
(ret = instance_eval(&blk)).nil? ? fallback : Array(ret)
|
|
1751
1905
|
end
|
|
1752
1906
|
|
|
1753
1907
|
def runenv
|
|
@@ -1780,12 +1934,10 @@ module Squared
|
|
|
1780
1934
|
|
|
1781
1935
|
def matchmap(list, prefix = nil)
|
|
1782
1936
|
list.map do |val|
|
|
1783
|
-
if val.is_a?(Regexp)
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
Regexp.new("#{prefix}#{val == '*' ? '.+' : val}")
|
|
1788
|
-
end
|
|
1937
|
+
next val if val.is_a?(Regexp)
|
|
1938
|
+
|
|
1939
|
+
val = ".*#{val}" if prefix && !val.sub!(/\A(\^|\\A)/, '')
|
|
1940
|
+
Regexp.new("#{prefix}#{val == '*' ? '.+' : val}")
|
|
1789
1941
|
end
|
|
1790
1942
|
end
|
|
1791
1943
|
|
|
@@ -1802,15 +1954,14 @@ module Squared
|
|
|
1802
1954
|
end
|
|
1803
1955
|
|
|
1804
1956
|
def semscan(val, fill: true)
|
|
1805
|
-
val.scan(SEM_VER).first
|
|
1957
|
+
ret = val.scan(SEM_VER).first
|
|
1958
|
+
fill ? semver(ret) : ret
|
|
1806
1959
|
end
|
|
1807
1960
|
|
|
1808
1961
|
def semcmp(val, other)
|
|
1809
1962
|
return 0 if val == other
|
|
1810
|
-
|
|
1811
|
-
a
|
|
1812
|
-
return -1 if b.empty?
|
|
1813
|
-
return 1 if a.empty?
|
|
1963
|
+
return -1 if (b = other.scan(SEM_VER)).empty?
|
|
1964
|
+
return 1 if (a = val.scan(SEM_VER)).empty?
|
|
1814
1965
|
|
|
1815
1966
|
a, b = [a.first, b.first].map! do |c|
|
|
1816
1967
|
d = begin
|
|
@@ -1820,14 +1971,38 @@ module Squared
|
|
|
1820
1971
|
end
|
|
1821
1972
|
[c[0], c[2], c[4] || '0', d]
|
|
1822
1973
|
end
|
|
1823
|
-
a.each_with_index do |c,
|
|
1824
|
-
next if c == (d = b[
|
|
1974
|
+
a.each_with_index do |c, i|
|
|
1975
|
+
next if c == (d = b[i])
|
|
1825
1976
|
|
|
1826
1977
|
return c.to_i < d.to_i ? 1 : -1
|
|
1827
1978
|
end
|
|
1828
1979
|
0
|
|
1829
1980
|
end
|
|
1830
1981
|
|
|
1982
|
+
def sembump(val, flag = :patch, join: true)
|
|
1983
|
+
ret = semscan(val, fill: false)
|
|
1984
|
+
case flag
|
|
1985
|
+
when :major
|
|
1986
|
+
ret[2] = if ret[0] != '0' || ret[2].nil?
|
|
1987
|
+
ret[0] = ret[0].succ
|
|
1988
|
+
'0'
|
|
1989
|
+
else
|
|
1990
|
+
ret[2].succ
|
|
1991
|
+
end
|
|
1992
|
+
ret[4] = '0'
|
|
1993
|
+
when :minor
|
|
1994
|
+
if ret[0] == '0'
|
|
1995
|
+
ret[4] &&= ret[4].succ
|
|
1996
|
+
else
|
|
1997
|
+
ret[2] = ret[2].succ
|
|
1998
|
+
ret[4] &&= '0'
|
|
1999
|
+
end
|
|
2000
|
+
when :patch
|
|
2001
|
+
ret[4] &&= ret[4].succ
|
|
2002
|
+
end
|
|
2003
|
+
join ? ret.join : ret
|
|
2004
|
+
end
|
|
2005
|
+
|
|
1831
2006
|
def semgte?(val, other)
|
|
1832
2007
|
semcmp(val, other) != 1
|
|
1833
2008
|
end
|
|
@@ -1837,7 +2012,7 @@ module Squared
|
|
|
1837
2012
|
end
|
|
1838
2013
|
|
|
1839
2014
|
def indexerror(val, list = nil)
|
|
1840
|
-
raise_error
|
|
2015
|
+
raise_error IndexError, "requested index #{val}", hint: list && "of #{list.size}"
|
|
1841
2016
|
end
|
|
1842
2017
|
|
|
1843
2018
|
def indexchar
|
|
@@ -1856,10 +2031,6 @@ module Squared
|
|
|
1856
2031
|
val.compact.flat_map { |s| color(s) }
|
|
1857
2032
|
end
|
|
1858
2033
|
|
|
1859
|
-
def epochtime
|
|
1860
|
-
Time.now.strftime('%s%L').to_i
|
|
1861
|
-
end
|
|
1862
|
-
|
|
1863
2034
|
def verbosetype
|
|
1864
2035
|
case verbose
|
|
1865
2036
|
when TrueClass
|
|
@@ -1891,7 +2062,7 @@ module Squared
|
|
|
1891
2062
|
end
|
|
1892
2063
|
end
|
|
1893
2064
|
|
|
1894
|
-
def on_error(err, from, exception: self.exception,
|
|
2065
|
+
def on_error(err, from, pass: false, exception: self.exception, dryrun: false)
|
|
1895
2066
|
log&.error err
|
|
1896
2067
|
unless dryrun
|
|
1897
2068
|
ret = on :error, from, err
|
|
@@ -1900,20 +2071,17 @@ module Squared
|
|
|
1900
2071
|
print_error(err, pass: pass) unless ret
|
|
1901
2072
|
end
|
|
1902
2073
|
|
|
1903
|
-
def pwd_set(pass: false, dryrun: false, from: nil)
|
|
2074
|
+
def pwd_set(pass: false, exception: self.exception, dryrun: false, from: nil)
|
|
1904
2075
|
pwd = Dir.pwd
|
|
1905
2076
|
return yield if (path.to_s == pwd || pass == true) && (workspace.mri? || !workspace.windows?)
|
|
1906
2077
|
|
|
1907
2078
|
Dir.chdir path
|
|
1908
|
-
|
|
1909
|
-
Dir.chdir pwd
|
|
2079
|
+
yield.tap { Dir.chdir pwd }
|
|
1910
2080
|
rescue StandardError => e
|
|
1911
|
-
on_error(e, from, dryrun: dryrun)
|
|
1912
|
-
else
|
|
1913
|
-
ret
|
|
2081
|
+
on_error(e, from, exception: exception, dryrun: dryrun)
|
|
1914
2082
|
end
|
|
1915
2083
|
|
|
1916
|
-
def run_set(cmd, val = nil, opts: nil, **)
|
|
2084
|
+
def run_set(cmd, val = nil, opts: nil, global: false, **)
|
|
1917
2085
|
noopt = @output[1] == false && !@output[0].nil?
|
|
1918
2086
|
noenv = @output[2] == false
|
|
1919
2087
|
parse = lambda do |data|
|
|
@@ -1932,6 +2100,7 @@ module Squared
|
|
|
1932
2100
|
ret[2] = data[:env] unless dise
|
|
1933
2101
|
ret
|
|
1934
2102
|
end
|
|
2103
|
+
self.global = global
|
|
1935
2104
|
case cmd
|
|
1936
2105
|
when Array
|
|
1937
2106
|
@output = if cmd.all? { |data| data.is_a?(Hash) }
|
|
@@ -1963,11 +2132,12 @@ module Squared
|
|
|
1963
2132
|
end
|
|
1964
2133
|
end
|
|
1965
2134
|
|
|
1966
|
-
def script_set(cmd, prod: nil, args: nil, **)
|
|
2135
|
+
def script_set(cmd, prod: nil, args: nil, global: false, **)
|
|
1967
2136
|
return if @output[1] == false && @output[0].nil?
|
|
1968
2137
|
|
|
2138
|
+
self.global = global
|
|
1969
2139
|
@output[0] = nil
|
|
1970
|
-
@output[1] = if
|
|
2140
|
+
@output[1] = if self.global && cmd.is_a?(Array)
|
|
1971
2141
|
cmd[prod == true ? 1 : 0]
|
|
1972
2142
|
else
|
|
1973
2143
|
cmd
|
|
@@ -2012,7 +2182,7 @@ module Squared
|
|
|
2012
2182
|
|
|
2013
2183
|
def asdf_set(val)
|
|
2014
2184
|
@asdf = if @@asdf && val
|
|
2015
|
-
dir = @@asdf
|
|
2185
|
+
dir = @@asdf.path.join('installs', val)
|
|
2016
2186
|
[val, dir] if dir.exist? && !dir.empty?
|
|
2017
2187
|
end
|
|
2018
2188
|
end
|
|
@@ -2028,9 +2198,12 @@ module Squared
|
|
|
2028
2198
|
end
|
|
2029
2199
|
|
|
2030
2200
|
def dependfile_set(list)
|
|
2031
|
-
@dependindex =
|
|
2032
|
-
|
|
2033
|
-
|
|
2201
|
+
@dependindex = if @dependname
|
|
2202
|
+
@dependfile = basepath @dependname
|
|
2203
|
+
list.index(@dependname)
|
|
2204
|
+
else
|
|
2205
|
+
list.index { |file| exist?(file) }.tap { |i: 0| @dependfile = basepath(list[i]) }
|
|
2206
|
+
end
|
|
2034
2207
|
end
|
|
2035
2208
|
|
|
2036
2209
|
def as_get(val, from)
|
|
@@ -2072,12 +2245,10 @@ module Squared
|
|
|
2072
2245
|
end
|
|
2073
2246
|
|
|
2074
2247
|
def checkdir?(val)
|
|
2075
|
-
if val.directory? && !val.empty?
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
false
|
|
2080
|
-
end
|
|
2248
|
+
return true if val.directory? && !val.empty?
|
|
2249
|
+
|
|
2250
|
+
log&.warn "directory \"#{val}\"".subhint(val.directory? ? 'empty' : 'missing')
|
|
2251
|
+
false
|
|
2081
2252
|
end
|
|
2082
2253
|
|
|
2083
2254
|
def semmajor?(cur, want)
|
|
@@ -2117,14 +2288,24 @@ module Squared
|
|
|
2117
2288
|
return true if val || from_sync?(ac = workspace.task_name(action))
|
|
2118
2289
|
return val if group && !(val = from_sync?(ac, group)).nil?
|
|
2119
2290
|
return val if (base = workspace.find_base(self)) && !(val = from_sync?(ac, base.ref)).nil?
|
|
2120
|
-
return false if workspace.series.chain?(
|
|
2121
|
-
return true if task_invoked?(
|
|
2291
|
+
return false if workspace.series.chain?(key = task_join(name, action))
|
|
2292
|
+
return true if task_invoked?(key) && (!task_invoked?(ac) || !workspace.task_defined?(ac, 'sync'))
|
|
2122
2293
|
|
|
2123
|
-
workspace.series.name_get(action)
|
|
2294
|
+
ret = workspace.series.name_get(action)
|
|
2295
|
+
ret != action && invoked_sync?(ret)
|
|
2124
2296
|
end
|
|
2125
2297
|
|
|
2126
|
-
def success?(
|
|
2127
|
-
|
|
2298
|
+
def success?(run, *cond)
|
|
2299
|
+
case run
|
|
2300
|
+
when TrueClass
|
|
2301
|
+
true
|
|
2302
|
+
when FalseClass
|
|
2303
|
+
false
|
|
2304
|
+
else
|
|
2305
|
+
$?.success?
|
|
2306
|
+
end.tap do |ret|
|
|
2307
|
+
print_success if ret && stdout? && banner? && cond.none? { |val| val == false }
|
|
2308
|
+
end
|
|
2128
2309
|
end
|
|
2129
2310
|
|
|
2130
2311
|
def banner?
|
|
@@ -2151,12 +2332,13 @@ module Squared
|
|
|
2151
2332
|
workspace.warning
|
|
2152
2333
|
end
|
|
2153
2334
|
|
|
2154
|
-
def has_value?(
|
|
2155
|
-
|
|
2335
|
+
def has_value?(target, *args)
|
|
2336
|
+
args = args.first if args.size == 1 && args.first.is_a?(Enumerable)
|
|
2337
|
+
case target
|
|
2156
2338
|
when Hash
|
|
2157
|
-
|
|
2339
|
+
args.is_a?(Enumerable) ? args.any? { |obj| target.value?(obj) } : target.value?(args)
|
|
2158
2340
|
when Enumerable
|
|
2159
|
-
|
|
2341
|
+
args.is_a?(Enumerable) ? args.any? { |obj| target.include?(obj) } : target.include?(args)
|
|
2160
2342
|
else
|
|
2161
2343
|
false
|
|
2162
2344
|
end
|
|
@@ -2170,28 +2352,16 @@ module Squared
|
|
|
2170
2352
|
BLK_SET
|
|
2171
2353
|
end
|
|
2172
2354
|
|
|
2173
|
-
def hashobj
|
|
2174
|
-
Workspace::Support.hashobj
|
|
2175
|
-
end
|
|
2176
|
-
|
|
2177
|
-
def hashlist
|
|
2178
|
-
Workspace::Support.hashlist
|
|
2179
|
-
end
|
|
2180
|
-
|
|
2181
|
-
def hashdup
|
|
2182
|
-
Workspace::Support.hashdup
|
|
2183
|
-
end
|
|
2184
|
-
|
|
2185
2355
|
def borderstyle
|
|
2186
2356
|
workspace.banner_get(*@ref, group: group)&.border || theme[:border]
|
|
2187
2357
|
end
|
|
2188
2358
|
|
|
2189
2359
|
def headerstyle
|
|
2190
|
-
|
|
2360
|
+
opt_style theme[:header], /^(\S+)(\s+)$/
|
|
2191
2361
|
end
|
|
2192
2362
|
|
|
2193
2363
|
def scriptargs
|
|
2194
|
-
{ target: script? ? @output[1] : @output[0], ref: ref, group: group, global: @global }
|
|
2364
|
+
{ target: script? ? @output[1] : @output[0], script: script?, ref: ref, group: group, global: @global }
|
|
2195
2365
|
end
|
|
2196
2366
|
end
|
|
2197
2367
|
|