squared 0.5.21 → 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 +87 -178
- data/README.md +104 -72
- data/lib/squared/common/base.rb +1 -22
- data/lib/squared/common/format.rb +40 -34
- data/lib/squared/common/prompt.rb +58 -40
- data/lib/squared/common/shell.rb +71 -56
- data/lib/squared/common/system.rb +69 -36
- data/lib/squared/common/utils.rb +29 -6
- data/lib/squared/config.rb +27 -34
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +85 -86
- data/lib/squared/workspace/project/base.rb +540 -395
- data/lib/squared/workspace/project/docker.rb +394 -290
- data/lib/squared/workspace/project/git.rb +352 -341
- data/lib/squared/workspace/project/node.rb +499 -274
- data/lib/squared/workspace/project/python.rb +367 -242
- data/lib/squared/workspace/project/ruby.rb +694 -393
- data/lib/squared/workspace/project/support/class.rb +208 -205
- data/lib/squared/workspace/repo.rb +46 -43
- data/lib/squared/workspace/series.rb +13 -21
- data/lib/squared/workspace/support/base.rb +3 -24
- data/lib/squared/workspace/support/variables.rb +48 -0
- data/lib/squared/workspace/support.rb +1 -1
- data/lib/squared/workspace.rb +4 -6
- metadata +3 -3
- 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,28 +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
|
-
attr_reader :name, :workspace, :path, :theme, :group, :parent, :dependfile,
|
|
84
|
-
:exception, :pipe, :verbose
|
|
85
|
-
attr_accessor :global, :project
|
|
116
|
+
attr_reader :name, :project, :workspace, :path, :theme, :group, :parent, :dependfile,
|
|
117
|
+
:exception, :pipe, :verbose, :global
|
|
86
118
|
|
|
87
119
|
def initialize(workspace, path, name, *, group: nil, first: {}, last: {}, error: {}, common: ARG[:COMMON],
|
|
88
120
|
**kwargs)
|
|
@@ -108,20 +140,20 @@ module Squared
|
|
|
108
140
|
else
|
|
109
141
|
val.nil? ? workspace.verbose : val
|
|
110
142
|
end
|
|
143
|
+
self.global = false
|
|
111
144
|
@output = []
|
|
112
145
|
@ref = []
|
|
113
146
|
@children = []
|
|
114
147
|
@events = hashobj.update({ first: first, last: last, error: error })
|
|
115
148
|
@as = hashobj
|
|
116
149
|
@desc = (@name.include?(':') ? @name.split(':').join(ARG[:SPACE]) : @name).freeze
|
|
117
|
-
@parent = nil
|
|
118
|
-
@global = false
|
|
119
150
|
@log = nil
|
|
120
151
|
@dev = nil
|
|
121
152
|
@prod = nil
|
|
122
153
|
@withargs = nil
|
|
123
154
|
@session = nil
|
|
124
155
|
@index = -1
|
|
156
|
+
parent_set kwargs[:parent]
|
|
125
157
|
run_set(kwargs[:run], kwargs[:env], opts: kwargs.fetch(:opts, true))
|
|
126
158
|
graph_set kwargs[:graph]
|
|
127
159
|
pass_set kwargs[:pass]
|
|
@@ -157,32 +189,24 @@ module Squared
|
|
|
157
189
|
|
|
158
190
|
data = @workspace.script_find(*@ref, @group)
|
|
159
191
|
if @output[0].nil?
|
|
160
|
-
if
|
|
192
|
+
if data[:script]
|
|
161
193
|
unless kwargs[:script] == false
|
|
162
|
-
|
|
163
|
-
script_set(scr, args: data.fetch(:args, kwargs[:args]), prod: kwargs[:prod])
|
|
194
|
+
script_set(data[:script], args: data.fetch(:args, kwargs[:args]), prod: kwargs[:prod], global: true)
|
|
164
195
|
end
|
|
165
|
-
elsif
|
|
166
|
-
|
|
167
|
-
run_set run
|
|
196
|
+
elsif data[:run]
|
|
197
|
+
run_set(data[:run], global: true)
|
|
168
198
|
end
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
script_set(scr, args: @script.fetch(:args, kwargs[:args]))
|
|
177
|
-
elsif (run = @script[:run])
|
|
178
|
-
@global = false
|
|
179
|
-
run_set run
|
|
180
|
-
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]
|
|
181
206
|
end
|
|
182
207
|
end
|
|
183
|
-
elsif data[:
|
|
184
|
-
|
|
185
|
-
run_set data[:run]
|
|
208
|
+
elsif data[:run] && data[:env][:run]
|
|
209
|
+
run_set(data[:run], global: true)
|
|
186
210
|
end
|
|
187
211
|
end
|
|
188
212
|
|
|
@@ -196,10 +220,11 @@ module Squared
|
|
|
196
220
|
return if @log
|
|
197
221
|
|
|
198
222
|
log = log.is_a?(Hash) ? log.dup : { file: log }
|
|
199
|
-
if (
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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
|
|
203
228
|
when 'y', 'year'
|
|
204
229
|
Date.today.year
|
|
205
230
|
when 'm', 'month'
|
|
@@ -209,19 +234,21 @@ module Squared
|
|
|
209
234
|
else
|
|
210
235
|
val.include?('%') ? Time.now.strftime(val) : Time.now.strftime('%FT%T%:z')
|
|
211
236
|
end]
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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
|
|
221
250
|
log[:progname] ||= @name
|
|
222
|
-
if (val = env('LOG_LEVEL', ignore: false))
|
|
223
|
-
log[:level] = val.match?(/\d/) ? log_sym(val.to_i) : val
|
|
224
|
-
end
|
|
251
|
+
log[:level] = val.match?(/\d/) ? log_sym(val.to_i) : val if (val = env('LOG_LEVEL', ignore: false))
|
|
225
252
|
log.delete(:file)
|
|
226
253
|
@log = [file, log]
|
|
227
254
|
end
|
|
@@ -229,7 +256,7 @@ module Squared
|
|
|
229
256
|
def initialize_env(dev: nil, prod: nil, **)
|
|
230
257
|
@dev = env_match('BUILD', dev, suffix: 'DEV', strict: true)
|
|
231
258
|
@prod = env_match('BUILD', prod, suffix: 'PROD', strict: true)
|
|
232
|
-
if (val = env('BUILD', suffix: 'ENV'))
|
|
259
|
+
if @output[2] != false && (val = env('BUILD', suffix: 'ENV'))
|
|
233
260
|
@output[2] = parse_json(val, hint: "BUILD_#{@envname}_ENV") || @output[2]
|
|
234
261
|
end
|
|
235
262
|
unless @output[0] == false || @output[0].is_a?(Array)
|
|
@@ -244,7 +271,6 @@ module Squared
|
|
|
244
271
|
@version = val if (val = env('BUILD', suffix: 'VERSION'))
|
|
245
272
|
return unless (val = env('BUILD', strict: true))
|
|
246
273
|
|
|
247
|
-
@global = false
|
|
248
274
|
if val == '0'
|
|
249
275
|
@output = [false]
|
|
250
276
|
elsif script?
|
|
@@ -326,6 +352,10 @@ module Squared
|
|
|
326
352
|
end
|
|
327
353
|
end
|
|
328
354
|
|
|
355
|
+
def global=(val)
|
|
356
|
+
@global = val unless val.nil?
|
|
357
|
+
end
|
|
358
|
+
|
|
329
359
|
def ref
|
|
330
360
|
Base.ref
|
|
331
361
|
end
|
|
@@ -353,17 +383,17 @@ module Squared
|
|
|
353
383
|
out, done = graph(args, out: [])
|
|
354
384
|
out.map! do |val|
|
|
355
385
|
n = done.index { |proj| val.match?(/ #{Regexp.escape(proj.name)}(?:@\d|\z)/) }
|
|
356
|
-
n ?
|
|
386
|
+
n ? val.subhint(n.succ) : val
|
|
357
387
|
end
|
|
358
388
|
emphasize(out, title: path, right: true, border: borderstyle, sub: [
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
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)
|
|
362
392
|
])
|
|
363
393
|
end
|
|
364
394
|
end
|
|
365
395
|
when 'unpack'
|
|
366
|
-
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))
|
|
367
397
|
params = %i[tag dir digest force]
|
|
368
398
|
params.unshift(:ext) if flag == :ext
|
|
369
399
|
task flag, params do |_, args|
|
|
@@ -371,21 +401,21 @@ module Squared
|
|
|
371
401
|
tag = param_guard(action, flag, args: args, key: :tag)
|
|
372
402
|
dir = param_guard(action, flag, args: args, key: :dir)
|
|
373
403
|
unless tag.match?(URI_SCHEME)
|
|
374
|
-
if
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
end
|
|
382
|
-
case (digest = args.digest)
|
|
383
|
-
when 'f', 'force'
|
|
384
|
-
digest = nil
|
|
385
|
-
force = true
|
|
386
|
-
else
|
|
387
|
-
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
|
|
388
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
|
|
389
419
|
unpack(basepath(dir), uri: tag, digest: digest, ext: ext, force: force)
|
|
390
420
|
end
|
|
391
421
|
when 'asdf'
|
|
@@ -393,7 +423,7 @@ module Squared
|
|
|
393
423
|
|
|
394
424
|
case flag
|
|
395
425
|
when :set
|
|
396
|
-
format_desc action, flag, 'version,
|
|
426
|
+
format_desc action, flag, 'version,dir?=u/home|p/arent'
|
|
397
427
|
task flag, [:version] do |_, args|
|
|
398
428
|
args = if (version = args.version)
|
|
399
429
|
args.extras
|
|
@@ -403,14 +433,14 @@ module Squared
|
|
|
403
433
|
.map(&:basename)
|
|
404
434
|
.sort { |a, b| b <=> a }
|
|
405
435
|
.push('latest', 'system'),
|
|
406
|
-
accept: [
|
|
407
|
-
values:
|
|
436
|
+
accept: [accept_y('Confirm?')],
|
|
437
|
+
values: 'Options', force: true)
|
|
408
438
|
OptionPartition.strip(opts)
|
|
409
439
|
end
|
|
410
440
|
asdf(flag, args, version: version)
|
|
411
441
|
end
|
|
412
442
|
else
|
|
413
|
-
format_desc(action, flag, flag == :exec
|
|
443
|
+
format_desc(action, flag, ('command' if flag == :exec))
|
|
414
444
|
task flag do |_, args|
|
|
415
445
|
args = args.to_a
|
|
416
446
|
args << readline('Enter command', force: true) if args.empty? && flag == :exec
|
|
@@ -429,7 +459,7 @@ module Squared
|
|
|
429
459
|
end
|
|
430
460
|
|
|
431
461
|
def with(**kwargs, &blk)
|
|
432
|
-
@withargs = kwargs.empty?
|
|
462
|
+
@withargs = (kwargs unless kwargs.empty?)
|
|
433
463
|
if block_given?
|
|
434
464
|
instance_eval(&blk)
|
|
435
465
|
@withargs = nil
|
|
@@ -450,7 +480,6 @@ module Squared
|
|
|
450
480
|
kwargs = hashdup(@withargs).update(kwargs) if @withargs
|
|
451
481
|
kwargs[:group] = group if group && !kwargs.key?(:group)
|
|
452
482
|
kwargs[:ref] = ref unless kwargs.key?(:ref)
|
|
453
|
-
parent = self
|
|
454
483
|
proj = nil
|
|
455
484
|
name = case name
|
|
456
485
|
when String, Symbol
|
|
@@ -458,8 +487,7 @@ module Squared
|
|
|
458
487
|
else
|
|
459
488
|
path.basename
|
|
460
489
|
end
|
|
461
|
-
workspace.add(path, name, **kwargs) do
|
|
462
|
-
__send__ :parent_set, parent
|
|
490
|
+
workspace.add(path, name, parent: self, **kwargs) do
|
|
463
491
|
proj = self
|
|
464
492
|
instance_eval(&blk) if block_given?
|
|
465
493
|
end
|
|
@@ -475,14 +503,14 @@ module Squared
|
|
|
475
503
|
|
|
476
504
|
def inject(obj, *args, **kwargs, &blk)
|
|
477
505
|
if enabled?
|
|
478
|
-
out = obj.link(self, *args, **kwargs, &blk)
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
elsif out.respond_to?(:build)
|
|
482
|
-
out.build
|
|
483
|
-
end
|
|
506
|
+
raise 'link not compatible' unless obj.respond_to?(:link) && (out = obj.link(self, *args, **kwargs, &blk))
|
|
507
|
+
|
|
508
|
+
out.build if out.respond_to?(:build)
|
|
484
509
|
end
|
|
485
510
|
self
|
|
511
|
+
rescue StandardError => e
|
|
512
|
+
print_error(e, subject: obj, hint: name)
|
|
513
|
+
self
|
|
486
514
|
end
|
|
487
515
|
|
|
488
516
|
def build(*args, sync: invoked_sync?('build'), from: :run, **)
|
|
@@ -490,8 +518,8 @@ module Squared
|
|
|
490
518
|
if args.empty?
|
|
491
519
|
return unless from == :run
|
|
492
520
|
|
|
493
|
-
banner =
|
|
494
|
-
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)
|
|
495
523
|
args = @output
|
|
496
524
|
end
|
|
497
525
|
if args.first.is_a?(Struct)
|
|
@@ -503,14 +531,8 @@ module Squared
|
|
|
503
531
|
cmd = []
|
|
504
532
|
var = {}
|
|
505
533
|
args.each do |val|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
instance_exec(*val[1..-1], &val.first)
|
|
509
|
-
next
|
|
510
|
-
when Method
|
|
511
|
-
val.first.call(*val[1..-1])
|
|
512
|
-
next
|
|
513
|
-
end
|
|
534
|
+
next instance_exec(*val[1..-1], &val.first) if val.first.is_a?(Proc)
|
|
535
|
+
|
|
514
536
|
a, b, c, d, e = val
|
|
515
537
|
case b
|
|
516
538
|
when Hash
|
|
@@ -520,7 +542,7 @@ module Squared
|
|
|
520
542
|
end
|
|
521
543
|
d = append_hash(d, target: []).join(' ') if d.is_a?(Hash)
|
|
522
544
|
if a
|
|
523
|
-
cmd << [
|
|
545
|
+
cmd << [a, d, b].compact.join(' ')
|
|
524
546
|
else
|
|
525
547
|
next unless respond_to?(:compose)
|
|
526
548
|
|
|
@@ -531,33 +553,33 @@ module Squared
|
|
|
531
553
|
cmd = cmd.join(' && ')
|
|
532
554
|
else
|
|
533
555
|
cmd, opts, var, flags, extra = args
|
|
534
|
-
|
|
535
|
-
|
|
556
|
+
end
|
|
557
|
+
if cmd
|
|
558
|
+
return run_b(cmd, sync: sync, from: from) if cmd.is_a?(Proc) || cmd.is_a?(Method)
|
|
536
559
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
else
|
|
551
|
-
cmd = [cmd, flags, opts].compact.join(' ') if opts || flags
|
|
552
|
-
end
|
|
560
|
+
cmd = as_get cmd, from
|
|
561
|
+
opts = compose(opts, script: false) if opts && respond_to?(:compose)
|
|
562
|
+
flags = append_hash(flags, target: []).join(' ') if flags.is_a?(Hash)
|
|
563
|
+
case opts
|
|
564
|
+
when Hash
|
|
565
|
+
cmd = Array(cmd).push(flags)
|
|
566
|
+
.concat(append_hash(opts, target: [], build: true))
|
|
567
|
+
.compact
|
|
568
|
+
.join(' ')
|
|
569
|
+
when Enumerable
|
|
570
|
+
cmd = Array(cmd).concat(opts.to_a)
|
|
571
|
+
cmd.map! { |val| "#{val} #{flags}" } if flags
|
|
572
|
+
cmd = cmd.join(' && ')
|
|
553
573
|
else
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
cmd = compose(as_get(opts, from), flags, script: true, args: extra, from: from)
|
|
557
|
-
from = :script if from == :run && script?
|
|
574
|
+
cmd = [cmd, flags, opts].compact.join(' ') if opts || flags
|
|
558
575
|
end
|
|
576
|
+
else
|
|
577
|
+
return unless (opts || extra) && respond_to?(:compose)
|
|
578
|
+
|
|
579
|
+
cmd = compose(as_get(opts, from), flags, script: true, args: extra, from: from)
|
|
580
|
+
from = :script if from == :run && script?
|
|
559
581
|
end
|
|
560
|
-
run(cmd, var, sync: sync,
|
|
582
|
+
run(cmd, var, sync: sync, banner: banner, from: from)
|
|
561
583
|
end
|
|
562
584
|
|
|
563
585
|
def depend(*, sync: invoked_sync?('depend'), **)
|
|
@@ -570,16 +592,16 @@ module Squared
|
|
|
570
592
|
next if @@graph[:_].include?(proj)
|
|
571
593
|
|
|
572
594
|
if (val = ENV["PREREQS_#{proj.instance_variable_get(:@envname)}"] || ENV["PREREQS_#{proj.ref.upcase}"])
|
|
573
|
-
split_escape(val)
|
|
595
|
+
split_escape(val) do |meth|
|
|
574
596
|
if proj.respond_to?(meth.to_sym)
|
|
575
597
|
begin
|
|
576
598
|
proj.__send__(meth, sync: sync)
|
|
599
|
+
next
|
|
577
600
|
rescue StandardError => e
|
|
578
601
|
on_error(e, :prereqs, exception: true)
|
|
579
602
|
end
|
|
580
|
-
else
|
|
581
|
-
print_error(name, "method: #{meth}", subject: 'prereqs', hint: 'undefined')
|
|
582
603
|
end
|
|
604
|
+
print_error(name, 'method not found', subject: 'prereqs', hint: meth)
|
|
583
605
|
end
|
|
584
606
|
elsif proj.build?
|
|
585
607
|
proj.build(sync: sync)
|
|
@@ -657,9 +679,9 @@ module Squared
|
|
|
657
679
|
end
|
|
658
680
|
|
|
659
681
|
def graph(start = [], tasks = nil, *, sync: invoked_sync?('graph'), pass: [], out: nil, **)
|
|
660
|
-
|
|
682
|
+
env('GRAPH', strict: true) do |val|
|
|
661
683
|
tasks ||= []
|
|
662
|
-
split_escape(val)
|
|
684
|
+
split_escape(val) do |task|
|
|
663
685
|
if ref?(task.to_sym) && (script = workspace.script_get(:graph, ref: task.to_sym))
|
|
664
686
|
tasks.concat(script[:graph])
|
|
665
687
|
else
|
|
@@ -667,7 +689,7 @@ module Squared
|
|
|
667
689
|
end
|
|
668
690
|
end
|
|
669
691
|
end
|
|
670
|
-
|
|
692
|
+
env('GRAPH', suffix: 'PASS') { |val| pass.concat(split_escape(val)) }
|
|
671
693
|
start, neg = start.partition { |name| !name.start_with?('-') }
|
|
672
694
|
data = graph_collect(self, start, pass: neg.map! { |name| name[1..-1] })
|
|
673
695
|
unless out
|
|
@@ -690,9 +712,9 @@ module Squared
|
|
|
690
712
|
if !target.exist?
|
|
691
713
|
target.mkpath
|
|
692
714
|
elsif !target.directory?
|
|
693
|
-
raise_error
|
|
715
|
+
raise_error Errno::EEXIST, target, hint: uri
|
|
694
716
|
elsif !file && !target.empty?
|
|
695
|
-
raise_error
|
|
717
|
+
raise_error Errno::EEXIST, target, hint: uri unless force || env('UNPACK_FORCE')
|
|
696
718
|
create = true
|
|
697
719
|
end
|
|
698
720
|
if digest
|
|
@@ -712,25 +734,27 @@ module Squared
|
|
|
712
734
|
when 128, 'sha512'
|
|
713
735
|
Digest::SHA512
|
|
714
736
|
else
|
|
715
|
-
raise_error "invalid checksum: #{digest}"
|
|
737
|
+
raise_error "invalid checksum: #{digest}", hint: uri
|
|
716
738
|
end
|
|
717
739
|
end
|
|
718
|
-
|
|
719
|
-
|
|
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
|
|
720
744
|
end
|
|
721
745
|
if file
|
|
722
746
|
ext ||= File.extname(file)[1..-1]
|
|
723
747
|
else
|
|
724
748
|
require 'open-uri'
|
|
725
749
|
data = nil
|
|
726
|
-
(uri = Array(uri)).each_with_index do |url,
|
|
750
|
+
(uri = Array(uri)).each_with_index do |url, i|
|
|
727
751
|
URI.open(url, headers) do |f|
|
|
728
752
|
data = f.read
|
|
729
753
|
if algo && algo.hexdigest(data) != digest
|
|
730
754
|
data = nil
|
|
731
|
-
raise_error
|
|
755
|
+
raise_error "invalid checksum: #{digest}", hint: url if i == uri.size.pred
|
|
732
756
|
end
|
|
733
|
-
next if ext &&
|
|
757
|
+
next if ext && i == 0
|
|
734
758
|
|
|
735
759
|
case f.content_type
|
|
736
760
|
when 'application/zip'
|
|
@@ -745,8 +769,8 @@ module Squared
|
|
|
745
769
|
end
|
|
746
770
|
break uri = url if data
|
|
747
771
|
end
|
|
748
|
-
unless data && (ext ||= URI.
|
|
749
|
-
raise_error("no content#{data ? ' type' : ''}", hint: uri)
|
|
772
|
+
unless data && (ext ||= URI.parse(uri).path[/\.(\w+)(?:\?|\z)/, 1])
|
|
773
|
+
raise_error(data ? TypeError : RuntimeError, "no content#{data ? ' type' : ''}", hint: uri)
|
|
750
774
|
end
|
|
751
775
|
end
|
|
752
776
|
ext = ext.downcase
|
|
@@ -755,13 +779,13 @@ module Squared
|
|
|
755
779
|
end
|
|
756
780
|
begin
|
|
757
781
|
unless file
|
|
758
|
-
if ext == 'gem'
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
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
|
|
765
789
|
file.write(data)
|
|
766
790
|
file.close
|
|
767
791
|
file = Pathname.new(file)
|
|
@@ -775,7 +799,7 @@ module Squared
|
|
|
775
799
|
case ext
|
|
776
800
|
when 'zip', 'aar'
|
|
777
801
|
session 'unzip', shell_quote(file), quote_option('d', target)
|
|
778
|
-
when 'tar',
|
|
802
|
+
when 'tar', /\A(?:t|tar\.)?[gx]z\z/
|
|
779
803
|
flags = +(verbose ? 'v' : '')
|
|
780
804
|
if ext.end_with?('gz')
|
|
781
805
|
flags += 'z'
|
|
@@ -818,29 +842,32 @@ module Squared
|
|
|
818
842
|
def asdf(flag, opts = [], version: nil)
|
|
819
843
|
return unless @asdf
|
|
820
844
|
|
|
821
|
-
cmd = session 'asdf', flag
|
|
845
|
+
cmd = flag == :update ? session('asdf', 'plugin update') : session('asdf', flag)
|
|
822
846
|
name = @asdf.first
|
|
823
|
-
legacy = @@asdf
|
|
847
|
+
legacy = @@asdf.version == 15
|
|
848
|
+
banner = true
|
|
824
849
|
case flag
|
|
825
850
|
when :set
|
|
826
|
-
u = has_value?(opts,
|
|
851
|
+
u = has_value?(opts, 'u', 'home')
|
|
827
852
|
cmd << if legacy
|
|
828
853
|
cmd.delete(flag)
|
|
829
854
|
u ? 'global' : 'local'
|
|
830
|
-
elsif has_value?(opts,
|
|
855
|
+
elsif has_value?(opts, 'p', 'parent')
|
|
831
856
|
'--parent'
|
|
832
857
|
elsif u
|
|
833
858
|
'--home'
|
|
834
859
|
end
|
|
835
860
|
cmd << name << version
|
|
836
861
|
when :exec
|
|
837
|
-
cmd << name unless opts.first.start_with?(/#{name}\b/)
|
|
838
862
|
cmd.merge(opts)
|
|
839
863
|
when :current
|
|
840
864
|
cmd << '--no-header' unless legacy
|
|
841
865
|
cmd << name
|
|
866
|
+
else
|
|
867
|
+
cmd << name
|
|
868
|
+
banner = flag == :update || flag == :reshim
|
|
842
869
|
end
|
|
843
|
-
|
|
870
|
+
success?(run(banner: banner, from: :"asdf:#{flag}"), flag == :set || flag == :reshim)
|
|
844
871
|
end
|
|
845
872
|
|
|
846
873
|
def first(key, *args, **kwargs, &blk)
|
|
@@ -880,28 +907,27 @@ module Squared
|
|
|
880
907
|
instance_variable_set :"@#{key}", [blk]
|
|
881
908
|
end
|
|
882
909
|
else
|
|
883
|
-
log&.warn "series: @#{key}
|
|
910
|
+
log&.warn "series: @#{key}".subhint('invalid')
|
|
884
911
|
end
|
|
885
912
|
self
|
|
886
913
|
end
|
|
887
914
|
|
|
888
|
-
def run(cmd = @session, var = nil, exception: self.exception, sync: true,
|
|
915
|
+
def run(cmd = @session, var = nil, exception: self.exception, sync: true, banner: true, from: nil, chdir: path,
|
|
889
916
|
interactive: nil, hint: nil, series: true, **)
|
|
890
|
-
unless cmd
|
|
891
|
-
|
|
892
|
-
return
|
|
893
|
-
end
|
|
917
|
+
return print_error('no command session started', subject: project, hint: from, pass: true) unless cmd
|
|
918
|
+
|
|
894
919
|
cmd = cmd.target if cmd.is_a?(OptionPartition)
|
|
895
|
-
if interactive && (!@session || !option('y'))
|
|
896
|
-
title, y = case interactive
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
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)
|
|
905
931
|
end
|
|
906
932
|
cmd = session_done cmd
|
|
907
933
|
log&.info cmd
|
|
@@ -911,7 +937,7 @@ module Squared
|
|
|
911
937
|
log&.warn "ENV discarded: #{var}" if var
|
|
912
938
|
task_invoke(cmd, exception: exception, warning: warning?)
|
|
913
939
|
else
|
|
914
|
-
print_item(format_banner(
|
|
940
|
+
print_item(format_banner(cmd, banner: banner, hint: hint), series: series) if sync
|
|
915
941
|
if var != false && (pre = runenv)
|
|
916
942
|
case pre
|
|
917
943
|
when Hash
|
|
@@ -934,12 +960,6 @@ module Squared
|
|
|
934
960
|
end
|
|
935
961
|
end
|
|
936
962
|
|
|
937
|
-
def scope(*args, **kwargs, &blk)
|
|
938
|
-
namespace name do
|
|
939
|
-
task(*args, **kwargs, &blk)
|
|
940
|
-
end
|
|
941
|
-
end
|
|
942
|
-
|
|
943
963
|
def variable_set(key, *args, **kwargs, &blk)
|
|
944
964
|
if block_given?
|
|
945
965
|
if blocks.include?(key)
|
|
@@ -949,14 +969,7 @@ module Squared
|
|
|
949
969
|
args = block_args args, &blk
|
|
950
970
|
end
|
|
951
971
|
if variables.include?(key) || blocks.include?(key)
|
|
952
|
-
val =
|
|
953
|
-
when 0
|
|
954
|
-
nil
|
|
955
|
-
when 1
|
|
956
|
-
args.first
|
|
957
|
-
else
|
|
958
|
-
args
|
|
959
|
-
end
|
|
972
|
+
val = args.size > 1 ? args : args.first
|
|
960
973
|
case key
|
|
961
974
|
when :index
|
|
962
975
|
index_set val
|
|
@@ -981,13 +994,12 @@ module Squared
|
|
|
981
994
|
when :env
|
|
982
995
|
run_set(output[0], *args, **kwargs)
|
|
983
996
|
when :dependfile
|
|
984
|
-
@
|
|
985
|
-
@dependfile = val.nil? ? nil : basepath(*args)
|
|
997
|
+
@dependfile = basepath(*args)
|
|
986
998
|
else
|
|
987
999
|
instance_variable_set(:"@#{key}", val)
|
|
988
1000
|
end
|
|
989
1001
|
else
|
|
990
|
-
log&.warn "variable_set: @#{key}
|
|
1002
|
+
log&.warn "variable_set: @#{key}".subhint('private')
|
|
991
1003
|
end
|
|
992
1004
|
self
|
|
993
1005
|
end
|
|
@@ -1010,6 +1022,10 @@ module Squared
|
|
|
1010
1022
|
@ref.include?(val)
|
|
1011
1023
|
end
|
|
1012
1024
|
|
|
1025
|
+
def exist?(*args)
|
|
1026
|
+
basepath(*args).exist?
|
|
1027
|
+
end
|
|
1028
|
+
|
|
1013
1029
|
def build?
|
|
1014
1030
|
!!@output[0] || script? || series?(@run)
|
|
1015
1031
|
end
|
|
@@ -1083,14 +1099,18 @@ module Squared
|
|
|
1083
1099
|
@dependindex ? @dependindex.succ : 0
|
|
1084
1100
|
end
|
|
1085
1101
|
|
|
1102
|
+
def dependname
|
|
1103
|
+
@dependname ||= dependfile&.basename.to_s
|
|
1104
|
+
end
|
|
1105
|
+
|
|
1086
1106
|
def log
|
|
1087
1107
|
return @log unless @log.is_a?(Array)
|
|
1088
1108
|
|
|
1089
|
-
@log = Logger.new(
|
|
1109
|
+
@log = Logger.new((@log.first if enabled?), **@log.last)
|
|
1090
1110
|
end
|
|
1091
1111
|
|
|
1092
|
-
def allref
|
|
1093
|
-
@ref.reverse_each
|
|
1112
|
+
def allref
|
|
1113
|
+
@ref.reverse_each
|
|
1094
1114
|
end
|
|
1095
1115
|
|
|
1096
1116
|
def basepath(*args)
|
|
@@ -1104,7 +1124,7 @@ module Squared
|
|
|
1104
1124
|
path.parent.ascend.each do |dir|
|
|
1105
1125
|
target = dir.join(*args)
|
|
1106
1126
|
return target if target.exist?
|
|
1107
|
-
break if (ascend
|
|
1127
|
+
break if (ascend && dir.join(ascend).exist?) || workspace.root == dir || parent&.path == dir
|
|
1108
1128
|
end
|
|
1109
1129
|
ret
|
|
1110
1130
|
end
|
|
@@ -1113,6 +1133,12 @@ module Squared
|
|
|
1113
1133
|
workspace.task_localname(name)
|
|
1114
1134
|
end
|
|
1115
1135
|
|
|
1136
|
+
def scriptname(from: :run)
|
|
1137
|
+
return unless (name = @output[1]) && respond_to?(:compose)
|
|
1138
|
+
|
|
1139
|
+
as_get name, from
|
|
1140
|
+
end
|
|
1141
|
+
|
|
1116
1142
|
def inspect
|
|
1117
1143
|
"#<#{self.class}: #{name} => #{self}>"
|
|
1118
1144
|
end
|
|
@@ -1131,12 +1157,21 @@ module Squared
|
|
|
1131
1157
|
log_console(*args, pipe: kwargs[:pipe] || pipe)
|
|
1132
1158
|
end
|
|
1133
1159
|
|
|
1134
|
-
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
|
|
1135
1166
|
on :first, from
|
|
1136
1167
|
begin
|
|
1137
|
-
cmd.
|
|
1168
|
+
cmd.each do |val|
|
|
1169
|
+
print_run val, banner
|
|
1170
|
+
run(val, var, sync: sync, banner: banner, **kwargs)
|
|
1171
|
+
end
|
|
1138
1172
|
rescue StandardError => e
|
|
1139
|
-
|
|
1173
|
+
ret = on :error, from, e
|
|
1174
|
+
raise unless ret == true
|
|
1140
1175
|
end
|
|
1141
1176
|
on :last, from
|
|
1142
1177
|
end
|
|
@@ -1150,7 +1185,12 @@ module Squared
|
|
|
1150
1185
|
when Proc
|
|
1151
1186
|
instance_eval(&obj)
|
|
1152
1187
|
when Method
|
|
1153
|
-
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)
|
|
1154
1194
|
else
|
|
1155
1195
|
if series?(obj)
|
|
1156
1196
|
obj.each(&:call)
|
|
@@ -1166,7 +1206,6 @@ module Squared
|
|
|
1166
1206
|
single: false, last: false, context: nil)
|
|
1167
1207
|
tag = ->(proj) { "#{proj.name}#{SEM_VER.match?(proj.version) ? "@#{proj.version}" : ''}" }
|
|
1168
1208
|
script = ->(proj) { workspace.script_get(:graph, group: proj.group, ref: proj.allref)&.fetch(:graph, nil) }
|
|
1169
|
-
check = ->(deps) { deps.reject { |val| done.include?(val) } }
|
|
1170
1209
|
dedupe = lambda do |name|
|
|
1171
1210
|
next [] unless (ret = data[name])
|
|
1172
1211
|
|
|
@@ -1177,12 +1216,11 @@ module Squared
|
|
|
1177
1216
|
end
|
|
1178
1217
|
ret
|
|
1179
1218
|
end
|
|
1180
|
-
start = target.name
|
|
1181
1219
|
if depth == 0
|
|
1182
|
-
items =
|
|
1220
|
+
items = dedupe.call(target.name) - done
|
|
1183
1221
|
single = items.size == 1
|
|
1184
1222
|
else
|
|
1185
|
-
items =
|
|
1223
|
+
items = data[target.name] - done
|
|
1186
1224
|
end
|
|
1187
1225
|
if out
|
|
1188
1226
|
a, b, c, d, e = ARG[:GRAPH]
|
|
@@ -1197,21 +1235,21 @@ module Squared
|
|
|
1197
1235
|
"#{last ? d : c}#{b * 3}#{e} #{f}"
|
|
1198
1236
|
end
|
|
1199
1237
|
else
|
|
1200
|
-
"#{single ? ' ' : a}#{' ' *
|
|
1238
|
+
"#{single ? ' ' : a}#{' ' * depth.pred}#{last ? d : c}#{b * 3}#{items.empty? ? b : e} #{f}"
|
|
1201
1239
|
end
|
|
1202
1240
|
end
|
|
1203
1241
|
items.each_with_index do |proj, i|
|
|
1204
1242
|
next if done.include?(proj)
|
|
1205
1243
|
|
|
1206
|
-
t = dedupe.call(proj.name)
|
|
1244
|
+
t = dedupe.call(name = proj.name)
|
|
1207
1245
|
j = if out
|
|
1208
|
-
if i == items.size
|
|
1246
|
+
if i == items.size.pred || (post = items[i.succ..-1] - done).empty?
|
|
1209
1247
|
true
|
|
1210
1248
|
elsif !t.empty? && depth > 0
|
|
1211
|
-
post
|
|
1249
|
+
(post - t).empty?
|
|
1212
1250
|
end
|
|
1213
1251
|
end
|
|
1214
|
-
unless
|
|
1252
|
+
unless target.name == name || (none = (t - done).empty?)
|
|
1215
1253
|
graph_branch(proj, data, tasks, out, sync: sync, pass: pass, done: done, depth: depth.succ,
|
|
1216
1254
|
single: single, last: j == true, context: target)
|
|
1217
1255
|
end
|
|
@@ -1219,28 +1257,28 @@ module Squared
|
|
|
1219
1257
|
(tasks || (subtasks = script.call(proj)) || (dev? ? %w[build copy] : %w[depend build])).each do |meth|
|
|
1220
1258
|
next if pass.include?(meth)
|
|
1221
1259
|
|
|
1222
|
-
if workspace.task_defined?(cmd = task_join(
|
|
1223
|
-
if ENV.key?(key = "BANNER_#{
|
|
1260
|
+
if workspace.task_defined?(cmd = task_join(name, meth))
|
|
1261
|
+
if ENV.key?(key = "BANNER_#{name.upcase}")
|
|
1224
1262
|
key = nil
|
|
1225
1263
|
else
|
|
1226
1264
|
ENV[key] = '0'
|
|
1227
1265
|
end
|
|
1228
1266
|
run(cmd, sync: false, banner: false)
|
|
1229
1267
|
ENV.delete(key) if key
|
|
1230
|
-
elsif proj.has?(meth, tasks || subtasks
|
|
1268
|
+
elsif proj.has?(meth, (workspace.baseref unless tasks || subtasks))
|
|
1231
1269
|
proj.__send__(meth.to_sym, sync: sync)
|
|
1232
1270
|
end
|
|
1233
1271
|
end
|
|
1234
1272
|
elsif none
|
|
1235
1273
|
a, b, c, d = ARG[:GRAPH]
|
|
1236
1274
|
out << if depth == 0
|
|
1237
|
-
"#{i == items.size
|
|
1275
|
+
"#{i == items.size.pred ? d : c}#{b * 4} #{tag.call(proj)}"
|
|
1238
1276
|
else
|
|
1239
1277
|
s = ''.dup
|
|
1240
1278
|
k = 0
|
|
1241
1279
|
final = data.keys.last
|
|
1242
1280
|
while k < depth
|
|
1243
|
-
indent = k > 0 ? ((last && !j) || (j && k == depth
|
|
1281
|
+
indent = k > 0 ? ((last && !j) || (j && k == depth.pred) || single) : j && last && depth == 1
|
|
1244
1282
|
s += "#{indent || (last && data[final].last == context) ? ' ' : a} "
|
|
1245
1283
|
k += 1
|
|
1246
1284
|
end
|
|
@@ -1258,22 +1296,19 @@ module Squared
|
|
|
1258
1296
|
next if pass.include?(val)
|
|
1259
1297
|
|
|
1260
1298
|
if (obj = workspace.find(name: val))
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
items = [obj]
|
|
1299
|
+
obj.enabled? ? [obj] : []
|
|
1264
1300
|
else
|
|
1265
|
-
|
|
1266
|
-
end
|
|
1267
|
-
items.each do |proj|
|
|
1301
|
+
workspace.find(group: val, ref: val.to_sym)
|
|
1302
|
+
end.each do |proj|
|
|
1268
1303
|
next if pass.include?(name = proj.name)
|
|
1269
1304
|
|
|
1270
1305
|
if proj.graph? && !data.key?(name) && !root.include?(name)
|
|
1271
1306
|
graph_collect(proj, data: data, pass: pass, root: root + [name, target.name])
|
|
1272
1307
|
end
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1308
|
+
unless (objs = data.fetch(name, [])).include?(target)
|
|
1309
|
+
deps << proj
|
|
1310
|
+
deps.concat(objs)
|
|
1311
|
+
end
|
|
1277
1312
|
end
|
|
1278
1313
|
end
|
|
1279
1314
|
deps.uniq!
|
|
@@ -1299,44 +1334,96 @@ module Squared
|
|
|
1299
1334
|
end
|
|
1300
1335
|
|
|
1301
1336
|
def env(key, default = nil, suffix: nil, equals: nil, ignore: nil, strict: false)
|
|
1302
|
-
|
|
1337
|
+
name = "#{key}_#{@envname}"
|
|
1303
1338
|
ret = if suffix
|
|
1304
|
-
ENV.fetch("#{
|
|
1339
|
+
ENV.fetch("#{name}_#{suffix}", '')
|
|
1305
1340
|
elsif strict
|
|
1306
|
-
ENV[
|
|
1341
|
+
ENV[name].to_s
|
|
1307
1342
|
else
|
|
1308
1343
|
ignore = ['0'].freeze if ignore.nil?
|
|
1309
|
-
ENV[
|
|
1344
|
+
ENV[name] || ENV.fetch(key, '')
|
|
1310
1345
|
end
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
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
|
|
1314
1352
|
end
|
|
1315
1353
|
|
|
1316
1354
|
def session(*cmd, prefix: cmd.first, main: true, path: true, options: true)
|
|
1317
|
-
prefix =
|
|
1355
|
+
prefix = prefix.to_s.stripext
|
|
1318
1356
|
if path && (val = shell_bin(prefix))
|
|
1319
1357
|
cmd[0] = shell_quote(val, force: false)
|
|
1320
1358
|
end
|
|
1321
1359
|
ret = JoinSet.new(cmd.flatten(1))
|
|
1322
|
-
if options
|
|
1323
|
-
|
|
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
|
|
1324
1368
|
end
|
|
1325
1369
|
main ? @session = ret : ret
|
|
1326
1370
|
end
|
|
1327
1371
|
|
|
1328
|
-
def session_delete(*args, target: @session)
|
|
1329
|
-
OptionPartition.delete(target, *args)
|
|
1330
|
-
end
|
|
1331
|
-
|
|
1332
1372
|
def session_output(*cmd, **kwargs)
|
|
1333
1373
|
session(*cmd, main: false, options: false, **kwargs)
|
|
1334
1374
|
end
|
|
1335
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
|
+
|
|
1336
1423
|
def session_done(cmd)
|
|
1337
|
-
return cmd unless cmd.respond_to?(:done)
|
|
1424
|
+
return cmd.to_s unless cmd.respond_to?(:done)
|
|
1338
1425
|
|
|
1339
|
-
raise_error
|
|
1426
|
+
raise_error 'no command added', hint: cmd.first unless cmd.size > 1
|
|
1340
1427
|
@session = nil if cmd == @session
|
|
1341
1428
|
cmd.done
|
|
1342
1429
|
end
|
|
@@ -1351,33 +1438,40 @@ module Squared
|
|
|
1351
1438
|
return unless prefix
|
|
1352
1439
|
|
|
1353
1440
|
args.each do |val|
|
|
1354
|
-
next unless (ret = env(env_key(stripext
|
|
1441
|
+
next unless (ret = env(env_key(prefix.to_s.stripext, val), **kwargs))
|
|
1355
1442
|
|
|
1356
1443
|
return block_given? ? yield(ret) : ret
|
|
1357
1444
|
end
|
|
1358
1445
|
nil
|
|
1359
1446
|
end
|
|
1360
1447
|
|
|
1361
|
-
def option_clear(opts, target: @session, **kwargs)
|
|
1448
|
+
def option_clear(opts, empty = true, target: @session, **kwargs)
|
|
1362
1449
|
return unless target
|
|
1363
1450
|
|
|
1364
1451
|
OptionPartition.clear(target, opts, styles: theme[:inline], **kwargs)
|
|
1452
|
+
opts.clear if empty
|
|
1453
|
+
nil
|
|
1365
1454
|
end
|
|
1366
1455
|
|
|
1367
|
-
def print_success
|
|
1456
|
+
def print_success
|
|
1368
1457
|
puts 'Success'
|
|
1369
1458
|
end
|
|
1370
1459
|
|
|
1371
1460
|
def print_error(*args, loglevel: Logger::WARN, **kwargs)
|
|
1372
|
-
|
|
1461
|
+
warn log_message(loglevel, *args, **kwargs) if warning?
|
|
1462
|
+
end
|
|
1373
1463
|
|
|
1374
|
-
|
|
1464
|
+
def print_run(cmd, banner = true, verbose: nil, **)
|
|
1465
|
+
return if banner || !stdout? || verbose == false
|
|
1466
|
+
|
|
1467
|
+
puts "\n> #{cmd}"
|
|
1468
|
+
printsucc
|
|
1375
1469
|
end
|
|
1376
1470
|
|
|
1377
1471
|
def print_item(*val, series: true)
|
|
1378
1472
|
puts unless printfirst?
|
|
1379
1473
|
printsucc if series
|
|
1380
|
-
puts val unless val.empty? || (val.size == 1 && val.first
|
|
1474
|
+
puts val unless val.empty? || (val.size == 1 && !val.first)
|
|
1381
1475
|
end
|
|
1382
1476
|
|
|
1383
1477
|
def print_banner(*lines, client: false, styles: theme[:banner], border: borderstyle, **)
|
|
@@ -1406,14 +1500,15 @@ module Squared
|
|
|
1406
1500
|
|
|
1407
1501
|
def print_footer(*lines, sub: nil, reverse: false, right: false, border: borderstyle, **)
|
|
1408
1502
|
n = line_width lines
|
|
1503
|
+
sub = as_a sub
|
|
1409
1504
|
lines.map! do |val|
|
|
1410
1505
|
s = right ? val.rjust(n) : val.ljust(n)
|
|
1411
|
-
sub
|
|
1506
|
+
sub.each { |h| s = sub_style(s, **h) }
|
|
1412
1507
|
s
|
|
1413
1508
|
end
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1509
|
+
[sub_style(ARG[:BORDER][1] * n, styles: border)].concat(lines)
|
|
1510
|
+
.tap { |ret| ret.reverse! if reverse }
|
|
1511
|
+
.join("\n")
|
|
1417
1512
|
end
|
|
1418
1513
|
|
|
1419
1514
|
def print_status(*args, from: nil, **kwargs)
|
|
@@ -1422,15 +1517,15 @@ module Squared
|
|
|
1422
1517
|
case from
|
|
1423
1518
|
when :outdated
|
|
1424
1519
|
out = print_footer("major #{args[0]} / minor #{args[1]} / patch #{args[2]}", right: true).split("\n")
|
|
1425
|
-
out[1] = sub_style(out[1],
|
|
1426
|
-
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]
|
|
1427
1523
|
puts out
|
|
1428
1524
|
when :completed
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
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]))
|
|
1434
1529
|
end
|
|
1435
1530
|
end
|
|
1436
1531
|
|
|
@@ -1440,7 +1535,7 @@ module Squared
|
|
|
1440
1535
|
workspace.format_desc([@desc, action, flag].compact, opts, **kwargs)
|
|
1441
1536
|
end
|
|
1442
1537
|
|
|
1443
|
-
def format_banner(cmd, banner: true)
|
|
1538
|
+
def format_banner(cmd, banner: true, hint: nil, strip: nil)
|
|
1444
1539
|
return unless banner && banner?
|
|
1445
1540
|
|
|
1446
1541
|
if (data = workspace.banner_get(*@ref, group: group))
|
|
@@ -1454,11 +1549,14 @@ module Squared
|
|
|
1454
1549
|
out = []
|
|
1455
1550
|
if data.command
|
|
1456
1551
|
if cmd =~ /\A(?:"((?:[^"]|(?<=\\)")+)"|'((?:[^']|(?<=\\)')+)'|(\S+))( |\z)/
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
cmd = cmd.sub(path, data.command == 0 ? name : name.upcase)
|
|
1552
|
+
arg = $3 || $2 || $1
|
|
1553
|
+
cmd = cmd.sub(arg, data.command == 0 ? arg.stripext : arg.stripext.upcase)
|
|
1460
1554
|
end
|
|
1461
|
-
|
|
1555
|
+
if strip || (strip.nil? && data.order.include?(:path))
|
|
1556
|
+
cmd = cmd.gsub(/(?:#{s = Regexp.escape(File.join(path, ''))}?(?=["'])|#{s})/, '')
|
|
1557
|
+
.gsub(/(?: -[^ ])? (?:""|'')/, '')
|
|
1558
|
+
end
|
|
1559
|
+
out << cmd.subhint(hint)
|
|
1462
1560
|
end
|
|
1463
1561
|
data.order.each do |val|
|
|
1464
1562
|
if val.is_a?(Array)
|
|
@@ -1486,7 +1584,7 @@ module Squared
|
|
|
1486
1584
|
end
|
|
1487
1585
|
end
|
|
1488
1586
|
|
|
1489
|
-
def format_list(items, cmd, type, grep: [], from: nil
|
|
1587
|
+
def format_list(items, cmd, type, grep: [], from: nil)
|
|
1490
1588
|
reg = grep.map { |val| Regexp.new(val) }
|
|
1491
1589
|
out = []
|
|
1492
1590
|
unless items.empty?
|
|
@@ -1494,29 +1592,29 @@ module Squared
|
|
|
1494
1592
|
items.each_with_index do |val, i|
|
|
1495
1593
|
next unless matchany?(val.first, reg)
|
|
1496
1594
|
|
|
1497
|
-
out << ('%*d. %s' % [pad, i.succ,
|
|
1595
|
+
out << ('%*d. %s' % [pad, i.succ, block_given? ? yield(val) : val.first])
|
|
1498
1596
|
end
|
|
1499
1597
|
end
|
|
1500
1598
|
sub = [headerstyle]
|
|
1501
|
-
if out.empty?
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
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
|
|
1520
1618
|
emphasize(out, title: task_join(name, cmd), border: borderstyle, sub: sub, footer: footer, right: true)
|
|
1521
1619
|
end
|
|
1522
1620
|
|
|
@@ -1524,14 +1622,13 @@ module Squared
|
|
|
1524
1622
|
"#{msg}#{!always && (!obj || obj == 0 || obj.to_s.empty?) ? '' : message(hint: message(title, obj.to_s))}"
|
|
1525
1623
|
end
|
|
1526
1624
|
|
|
1527
|
-
def append_repeat(flag, opts, target: @session
|
|
1528
|
-
opts.each { |val| target << shell_option(flag, val
|
|
1625
|
+
def append_repeat(flag, opts, target: @session)
|
|
1626
|
+
opts.each { |val| target << shell_option(flag, val) }
|
|
1529
1627
|
end
|
|
1530
1628
|
|
|
1531
1629
|
def append_hash(data, target: @session || [], build: false)
|
|
1532
1630
|
if build && (type = env('BUILD', suffix: 'TYPE') || ENV['BUILD_TYPE'])
|
|
1533
|
-
type = "__#{type}__"
|
|
1534
|
-
if (extra = data[type] || data[type.to_sym]).is_a?(Hash)
|
|
1631
|
+
if (extra = data[type = "__#{type}__"] || data[type.to_sym]).is_a?(Hash)
|
|
1535
1632
|
data = data.merge(extra)
|
|
1536
1633
|
else
|
|
1537
1634
|
extra = nil
|
|
@@ -1551,33 +1648,25 @@ module Squared
|
|
|
1551
1648
|
target << basic_option(key, val)
|
|
1552
1649
|
when FalseClass
|
|
1553
1650
|
target << shell_option(key).sub(/^--(?!no-)/, '--no-')
|
|
1554
|
-
when Pathname
|
|
1555
|
-
target << shell_option(key, val, escape: false)
|
|
1556
1651
|
else
|
|
1557
|
-
target << shell_option(key, val.is_a?(String)
|
|
1652
|
+
target << shell_option(key, (val if val.is_a?(String)))
|
|
1558
1653
|
end
|
|
1559
1654
|
end
|
|
1560
1655
|
target
|
|
1561
1656
|
end
|
|
1562
1657
|
|
|
1563
1658
|
def append_any(val, target: @session, build: false, delim: false)
|
|
1564
|
-
return unless val
|
|
1565
|
-
|
|
1566
1659
|
if delim && !target.include?('--')
|
|
1567
1660
|
target << '--'
|
|
1568
1661
|
else
|
|
1569
1662
|
delim = false
|
|
1570
1663
|
end
|
|
1571
|
-
val = shell_split
|
|
1664
|
+
val = shell_split val if val.is_a?(String)
|
|
1572
1665
|
case val
|
|
1573
1666
|
when Hash
|
|
1574
1667
|
append_hash(val, target: target, build: build)
|
|
1575
1668
|
when Enumerable
|
|
1576
|
-
|
|
1577
|
-
target.concat(val.to_a)
|
|
1578
|
-
else
|
|
1579
|
-
target.merge(val.to_a)
|
|
1580
|
-
end
|
|
1669
|
+
merge_list target, val
|
|
1581
1670
|
else
|
|
1582
1671
|
target.delete('--') if delim
|
|
1583
1672
|
nil
|
|
@@ -1598,7 +1687,7 @@ module Squared
|
|
|
1598
1687
|
next unless (val = option(opt, **kwargs))
|
|
1599
1688
|
|
|
1600
1689
|
return target << if flag
|
|
1601
|
-
shell_option(opt,
|
|
1690
|
+
shell_option(opt, (val if equals), quote: quote, escape: escape, force: force)
|
|
1602
1691
|
else
|
|
1603
1692
|
shell_quote val
|
|
1604
1693
|
end
|
|
@@ -1610,25 +1699,44 @@ module Squared
|
|
|
1610
1699
|
**kwargs)
|
|
1611
1700
|
return if list.empty?
|
|
1612
1701
|
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
next unless (val = option(flag, target: target, **kwargs))
|
|
1702
|
+
[].tap do |ret|
|
|
1703
|
+
list.flatten.each do |flag|
|
|
1704
|
+
next unless (val = option(flag, target: target, **kwargs))
|
|
1617
1705
|
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1706
|
+
if val == '0' && no
|
|
1707
|
+
flag = "no-#{flag}"
|
|
1708
|
+
val = nil
|
|
1709
|
+
end
|
|
1710
|
+
ret << shell_option(flag, (val if equals), escape: escape, quote: quote, force: force)
|
|
1621
1711
|
end
|
|
1622
|
-
|
|
1712
|
+
next if ret.empty?
|
|
1713
|
+
|
|
1714
|
+
merge_list target, ret
|
|
1623
1715
|
end
|
|
1624
|
-
ret.each { |val| target << val } unless ret.empty?
|
|
1625
|
-
ret
|
|
1626
1716
|
end
|
|
1627
1717
|
|
|
1628
1718
|
def append_nocolor(target: @session)
|
|
1629
1719
|
target << '--no-color' if !ARG[:COLOR] || stdin? || option('color', target: target, equals: '0')
|
|
1630
1720
|
end
|
|
1631
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
|
+
|
|
1632
1740
|
def merge_opts(base, data)
|
|
1633
1741
|
case data
|
|
1634
1742
|
when String
|
|
@@ -1669,27 +1777,31 @@ module Squared
|
|
|
1669
1777
|
end
|
|
1670
1778
|
end
|
|
1671
1779
|
|
|
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)
|
|
1789
|
+
end
|
|
1790
|
+
end
|
|
1791
|
+
|
|
1672
1792
|
def collect_hash(data, pass: [])
|
|
1673
1793
|
ret = []
|
|
1674
1794
|
data.each { |key, val| ret.concat(val) unless pass.include?(key) }
|
|
1675
1795
|
ret
|
|
1676
1796
|
end
|
|
1677
1797
|
|
|
1678
|
-
def replace_bin(val)
|
|
1679
|
-
a, b = val.split(' ', 2)
|
|
1680
|
-
return val if val.start_with?(/["']/) || a.include?(File::Separator)
|
|
1681
|
-
|
|
1682
|
-
[shell_bin(a), b].compact.join(' ')
|
|
1683
|
-
end
|
|
1684
|
-
|
|
1685
1798
|
def parse_json(val, kind: Hash, hint: nil)
|
|
1686
1799
|
ret = JSON.parse(val)
|
|
1687
|
-
raise_error
|
|
1800
|
+
raise_error 'invalid JSON'.subhint(kind.name), val, hint: hint if kind && !ret.is_a?(kind)
|
|
1801
|
+
ret
|
|
1688
1802
|
rescue StandardError => e
|
|
1689
1803
|
log&.warn e
|
|
1690
1804
|
print_error(e, subject: name)
|
|
1691
|
-
else
|
|
1692
|
-
ret
|
|
1693
1805
|
end
|
|
1694
1806
|
|
|
1695
1807
|
def param_guard(action, flag, args:, key: nil, pat: nil, values: nil)
|
|
@@ -1701,12 +1813,16 @@ module Squared
|
|
|
1701
1813
|
raise_error(action, "#{flag}[#{key}]", hint: val.nil? ? 'missing' : 'invalid')
|
|
1702
1814
|
elsif args.is_a?(Array) && args.empty?
|
|
1703
1815
|
@session = nil
|
|
1704
|
-
raise_error
|
|
1816
|
+
raise_error action, "#{flag}+", hint: 'empty'
|
|
1705
1817
|
end
|
|
1706
1818
|
args
|
|
1707
1819
|
end
|
|
1708
1820
|
|
|
1709
|
-
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)
|
|
1710
1826
|
a = sub_style(case rev
|
|
1711
1827
|
when 1
|
|
1712
1828
|
'MAJOR'
|
|
@@ -1718,16 +1834,17 @@ module Squared
|
|
|
1718
1834
|
b = sub_style(pkg.ljust(col1), styles: theme[:inline])
|
|
1719
1835
|
c = lock ? sub_style((cur || 'locked').rjust(7), styles: color(:red)) : cur&.rjust(7)
|
|
1720
1836
|
d = rev == 1 || lock ? 'N' : 'Y'
|
|
1721
|
-
confirm
|
|
1837
|
+
confirm("#{a}: #{b}#{c} #{sub_style(ver.rjust(col1 > 0 ? 10 : 0), styles: theme[:inline])} ", d, **kwargs)
|
|
1722
1838
|
end
|
|
1723
1839
|
|
|
1724
1840
|
def choice_index(msg, list, values: nil, accept: nil, series: false, trim: nil, column: nil, multiple: false,
|
|
1725
1841
|
force: true, **kwargs)
|
|
1726
|
-
puts
|
|
1727
|
-
|
|
1728
|
-
|
|
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
|
+
|
|
1729
1846
|
exit 1 if force
|
|
1730
|
-
return
|
|
1847
|
+
return nil
|
|
1731
1848
|
end
|
|
1732
1849
|
ret = multiple ? ret.map! { |val| val.sub(trim, '') } : ret.sub(trim, '') if trim
|
|
1733
1850
|
if column
|
|
@@ -1741,7 +1858,7 @@ module Squared
|
|
|
1741
1858
|
ret = Array(ret) if accept.any? { |val| val[1] == true }
|
|
1742
1859
|
loop do
|
|
1743
1860
|
item = accept.first
|
|
1744
|
-
c = confirm("#{item[0]}#{hint ? " [#{hint}]" : ''}", item[2] ? 'Y' : 'N'
|
|
1861
|
+
c = confirm("#{item[0]}#{hint ? " [#{hint}]" : ''}", item[2] ? 'Y' : 'N')
|
|
1745
1862
|
if item[1] == true
|
|
1746
1863
|
ret << c
|
|
1747
1864
|
elsif !c
|
|
@@ -1762,25 +1879,29 @@ module Squared
|
|
|
1762
1879
|
force = false
|
|
1763
1880
|
end
|
|
1764
1881
|
val = readline(val, force: force)
|
|
1765
|
-
ret << (val.empty?
|
|
1882
|
+
ret << (val unless val.empty?)
|
|
1766
1883
|
end
|
|
1767
1884
|
end
|
|
1768
1885
|
printsucc unless series
|
|
1769
1886
|
ret
|
|
1770
1887
|
end
|
|
1771
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
|
+
|
|
1772
1897
|
def command_args(args, min: 0, force: false, **kwargs)
|
|
1773
1898
|
return if args.size > min || option('i', 'interactive', **kwargs, equals: '0')
|
|
1774
1899
|
|
|
1775
1900
|
readline('Enter arguments', force: force)
|
|
1776
1901
|
end
|
|
1777
1902
|
|
|
1778
|
-
def block_args(
|
|
1779
|
-
|
|
1780
|
-
val
|
|
1781
|
-
else
|
|
1782
|
-
Array(ret)
|
|
1783
|
-
end
|
|
1903
|
+
def block_args(fallback = nil, &blk)
|
|
1904
|
+
(ret = instance_eval(&blk)).nil? ? fallback : Array(ret)
|
|
1784
1905
|
end
|
|
1785
1906
|
|
|
1786
1907
|
def runenv
|
|
@@ -1790,7 +1911,7 @@ module Squared
|
|
|
1790
1911
|
def command(*args)
|
|
1791
1912
|
return args.join(' && ') unless workspace.powershell?
|
|
1792
1913
|
|
|
1793
|
-
"
|
|
1914
|
+
"powershell.exe -Command #{shell_quote("& {#{args.join(' ; ')}}", option: false, double: true)}"
|
|
1794
1915
|
end
|
|
1795
1916
|
|
|
1796
1917
|
def relativepath(*list, all: false)
|
|
@@ -1813,12 +1934,10 @@ module Squared
|
|
|
1813
1934
|
|
|
1814
1935
|
def matchmap(list, prefix = nil)
|
|
1815
1936
|
list.map do |val|
|
|
1816
|
-
if val.is_a?(Regexp)
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
Regexp.new("#{prefix}#{val == '*' ? '.+' : val}")
|
|
1821
|
-
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}")
|
|
1822
1941
|
end
|
|
1823
1942
|
end
|
|
1824
1943
|
|
|
@@ -1835,7 +1954,8 @@ module Squared
|
|
|
1835
1954
|
end
|
|
1836
1955
|
|
|
1837
1956
|
def semscan(val, fill: true)
|
|
1838
|
-
val.scan(SEM_VER).first
|
|
1957
|
+
ret = val.scan(SEM_VER).first
|
|
1958
|
+
fill ? semver(ret) : ret
|
|
1839
1959
|
end
|
|
1840
1960
|
|
|
1841
1961
|
def semcmp(val, other)
|
|
@@ -1851,14 +1971,38 @@ module Squared
|
|
|
1851
1971
|
end
|
|
1852
1972
|
[c[0], c[2], c[4] || '0', d]
|
|
1853
1973
|
end
|
|
1854
|
-
a.each_with_index do |c,
|
|
1855
|
-
next if c == (d = b[
|
|
1974
|
+
a.each_with_index do |c, i|
|
|
1975
|
+
next if c == (d = b[i])
|
|
1856
1976
|
|
|
1857
1977
|
return c.to_i < d.to_i ? 1 : -1
|
|
1858
1978
|
end
|
|
1859
1979
|
0
|
|
1860
1980
|
end
|
|
1861
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
|
+
|
|
1862
2006
|
def semgte?(val, other)
|
|
1863
2007
|
semcmp(val, other) != 1
|
|
1864
2008
|
end
|
|
@@ -1868,7 +2012,7 @@ module Squared
|
|
|
1868
2012
|
end
|
|
1869
2013
|
|
|
1870
2014
|
def indexerror(val, list = nil)
|
|
1871
|
-
raise_error
|
|
2015
|
+
raise_error IndexError, "requested index #{val}", hint: list && "of #{list.size}"
|
|
1872
2016
|
end
|
|
1873
2017
|
|
|
1874
2018
|
def indexchar
|
|
@@ -1887,10 +2031,6 @@ module Squared
|
|
|
1887
2031
|
val.compact.flat_map { |s| color(s) }
|
|
1888
2032
|
end
|
|
1889
2033
|
|
|
1890
|
-
def epochtime
|
|
1891
|
-
Time.now.strftime('%s%L').to_i
|
|
1892
|
-
end
|
|
1893
|
-
|
|
1894
2034
|
def verbosetype
|
|
1895
2035
|
case verbose
|
|
1896
2036
|
when TrueClass
|
|
@@ -1922,7 +2062,7 @@ module Squared
|
|
|
1922
2062
|
end
|
|
1923
2063
|
end
|
|
1924
2064
|
|
|
1925
|
-
def on_error(err, from, exception: self.exception,
|
|
2065
|
+
def on_error(err, from, pass: false, exception: self.exception, dryrun: false)
|
|
1926
2066
|
log&.error err
|
|
1927
2067
|
unless dryrun
|
|
1928
2068
|
ret = on :error, from, err
|
|
@@ -1931,19 +2071,17 @@ module Squared
|
|
|
1931
2071
|
print_error(err, pass: pass) unless ret
|
|
1932
2072
|
end
|
|
1933
2073
|
|
|
1934
|
-
def pwd_set(pass: false, dryrun: false, from: nil)
|
|
1935
|
-
return yield if (path.to_s == Dir.pwd || pass == true) && (workspace.mri? || !workspace.windows?)
|
|
1936
|
-
|
|
2074
|
+
def pwd_set(pass: false, exception: self.exception, dryrun: false, from: nil)
|
|
1937
2075
|
pwd = Dir.pwd
|
|
1938
|
-
|
|
1939
|
-
|
|
2076
|
+
return yield if (path.to_s == pwd || pass == true) && (workspace.mri? || !workspace.windows?)
|
|
2077
|
+
|
|
2078
|
+
Dir.chdir path
|
|
2079
|
+
yield.tap { Dir.chdir pwd }
|
|
1940
2080
|
rescue StandardError => e
|
|
1941
|
-
on_error(e, from, dryrun: dryrun)
|
|
1942
|
-
ensure
|
|
1943
|
-
Dir.chdir(pwd) if pwd
|
|
2081
|
+
on_error(e, from, exception: exception, dryrun: dryrun)
|
|
1944
2082
|
end
|
|
1945
2083
|
|
|
1946
|
-
def run_set(cmd, val = nil, opts: nil, **)
|
|
2084
|
+
def run_set(cmd, val = nil, opts: nil, global: false, **)
|
|
1947
2085
|
noopt = @output[1] == false && !@output[0].nil?
|
|
1948
2086
|
noenv = @output[2] == false
|
|
1949
2087
|
parse = lambda do |data|
|
|
@@ -1962,6 +2100,7 @@ module Squared
|
|
|
1962
2100
|
ret[2] = data[:env] unless dise
|
|
1963
2101
|
ret
|
|
1964
2102
|
end
|
|
2103
|
+
self.global = global
|
|
1965
2104
|
case cmd
|
|
1966
2105
|
when Array
|
|
1967
2106
|
@output = if cmd.all? { |data| data.is_a?(Hash) }
|
|
@@ -1993,11 +2132,12 @@ module Squared
|
|
|
1993
2132
|
end
|
|
1994
2133
|
end
|
|
1995
2134
|
|
|
1996
|
-
def script_set(cmd, prod: nil, args: nil, **)
|
|
2135
|
+
def script_set(cmd, prod: nil, args: nil, global: false, **)
|
|
1997
2136
|
return if @output[1] == false && @output[0].nil?
|
|
1998
2137
|
|
|
2138
|
+
self.global = global
|
|
1999
2139
|
@output[0] = nil
|
|
2000
|
-
@output[1] = if
|
|
2140
|
+
@output[1] = if self.global && cmd.is_a?(Array)
|
|
2001
2141
|
cmd[prod == true ? 1 : 0]
|
|
2002
2142
|
else
|
|
2003
2143
|
cmd
|
|
@@ -2042,7 +2182,7 @@ module Squared
|
|
|
2042
2182
|
|
|
2043
2183
|
def asdf_set(val)
|
|
2044
2184
|
@asdf = if @@asdf && val
|
|
2045
|
-
dir = @@asdf
|
|
2185
|
+
dir = @@asdf.path.join('installs', val)
|
|
2046
2186
|
[val, dir] if dir.exist? && !dir.empty?
|
|
2047
2187
|
end
|
|
2048
2188
|
end
|
|
@@ -2058,9 +2198,12 @@ module Squared
|
|
|
2058
2198
|
end
|
|
2059
2199
|
|
|
2060
2200
|
def dependfile_set(list)
|
|
2061
|
-
@dependindex =
|
|
2062
|
-
|
|
2063
|
-
|
|
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
|
|
2064
2207
|
end
|
|
2065
2208
|
|
|
2066
2209
|
def as_get(val, from)
|
|
@@ -2102,12 +2245,10 @@ module Squared
|
|
|
2102
2245
|
end
|
|
2103
2246
|
|
|
2104
2247
|
def checkdir?(val)
|
|
2105
|
-
if val.directory? && !val.empty?
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
false
|
|
2110
|
-
end
|
|
2248
|
+
return true if val.directory? && !val.empty?
|
|
2249
|
+
|
|
2250
|
+
log&.warn "directory \"#{val}\"".subhint(val.directory? ? 'empty' : 'missing')
|
|
2251
|
+
false
|
|
2111
2252
|
end
|
|
2112
2253
|
|
|
2113
2254
|
def semmajor?(cur, want)
|
|
@@ -2120,7 +2261,7 @@ module Squared
|
|
|
2120
2261
|
|
|
2121
2262
|
def runnable?(val)
|
|
2122
2263
|
case val
|
|
2123
|
-
when String, Enumerable, Proc, Method
|
|
2264
|
+
when String, Enumerable, Proc, Method
|
|
2124
2265
|
true
|
|
2125
2266
|
else
|
|
2126
2267
|
false
|
|
@@ -2147,14 +2288,24 @@ module Squared
|
|
|
2147
2288
|
return true if val || from_sync?(ac = workspace.task_name(action))
|
|
2148
2289
|
return val if group && !(val = from_sync?(ac, group)).nil?
|
|
2149
2290
|
return val if (base = workspace.find_base(self)) && !(val = from_sync?(ac, base.ref)).nil?
|
|
2150
|
-
return false if workspace.series.chain?(
|
|
2151
|
-
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'))
|
|
2152
2293
|
|
|
2153
|
-
workspace.series.name_get(action)
|
|
2294
|
+
ret = workspace.series.name_get(action)
|
|
2295
|
+
ret != action && invoked_sync?(ret)
|
|
2154
2296
|
end
|
|
2155
2297
|
|
|
2156
|
-
def success?(
|
|
2157
|
-
|
|
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
|
|
2158
2309
|
end
|
|
2159
2310
|
|
|
2160
2311
|
def banner?
|
|
@@ -2181,10 +2332,16 @@ module Squared
|
|
|
2181
2332
|
workspace.warning
|
|
2182
2333
|
end
|
|
2183
2334
|
|
|
2184
|
-
def has_value?(
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2335
|
+
def has_value?(target, *args)
|
|
2336
|
+
args = args.first if args.size == 1 && args.first.is_a?(Enumerable)
|
|
2337
|
+
case target
|
|
2338
|
+
when Hash
|
|
2339
|
+
args.is_a?(Enumerable) ? args.any? { |obj| target.value?(obj) } : target.value?(args)
|
|
2340
|
+
when Enumerable
|
|
2341
|
+
args.is_a?(Enumerable) ? args.any? { |obj| target.include?(obj) } : target.include?(args)
|
|
2342
|
+
else
|
|
2343
|
+
false
|
|
2344
|
+
end
|
|
2188
2345
|
end
|
|
2189
2346
|
|
|
2190
2347
|
def variables
|
|
@@ -2195,28 +2352,16 @@ module Squared
|
|
|
2195
2352
|
BLK_SET
|
|
2196
2353
|
end
|
|
2197
2354
|
|
|
2198
|
-
def hashobj
|
|
2199
|
-
Workspace::Support.hashobj
|
|
2200
|
-
end
|
|
2201
|
-
|
|
2202
|
-
def hashlist
|
|
2203
|
-
Workspace::Support.hashlist
|
|
2204
|
-
end
|
|
2205
|
-
|
|
2206
|
-
def hashdup
|
|
2207
|
-
Workspace::Support.hashdup
|
|
2208
|
-
end
|
|
2209
|
-
|
|
2210
2355
|
def borderstyle
|
|
2211
2356
|
workspace.banner_get(*@ref, group: group)&.border || theme[:border]
|
|
2212
2357
|
end
|
|
2213
2358
|
|
|
2214
2359
|
def headerstyle
|
|
2215
|
-
|
|
2360
|
+
opt_style theme[:header], /^(\S+)(\s+)$/
|
|
2216
2361
|
end
|
|
2217
2362
|
|
|
2218
2363
|
def scriptargs
|
|
2219
|
-
{ 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 }
|
|
2220
2365
|
end
|
|
2221
2366
|
end
|
|
2222
2367
|
|