squared 0.5.20 → 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 -157
- 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 +57 -35
- 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 +538 -394
- data/lib/squared/workspace/project/docker.rb +393 -289
- data/lib/squared/workspace/project/git.rb +350 -339
- data/lib/squared/workspace/project/node.rb +499 -274
- data/lib/squared/workspace/project/python.rb +370 -241
- data/lib/squared/workspace/project/ruby.rb +683 -386
- 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,10 +1157,18 @@ 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
|
|
1140
1174
|
raise unless ret == true
|
|
@@ -1151,7 +1185,12 @@ module Squared
|
|
|
1151
1185
|
when Proc
|
|
1152
1186
|
instance_eval(&obj)
|
|
1153
1187
|
when Method
|
|
1154
|
-
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)
|
|
1155
1194
|
else
|
|
1156
1195
|
if series?(obj)
|
|
1157
1196
|
obj.each(&:call)
|
|
@@ -1167,7 +1206,6 @@ module Squared
|
|
|
1167
1206
|
single: false, last: false, context: nil)
|
|
1168
1207
|
tag = ->(proj) { "#{proj.name}#{SEM_VER.match?(proj.version) ? "@#{proj.version}" : ''}" }
|
|
1169
1208
|
script = ->(proj) { workspace.script_get(:graph, group: proj.group, ref: proj.allref)&.fetch(:graph, nil) }
|
|
1170
|
-
check = ->(deps) { deps.reject { |val| done.include?(val) } }
|
|
1171
1209
|
dedupe = lambda do |name|
|
|
1172
1210
|
next [] unless (ret = data[name])
|
|
1173
1211
|
|
|
@@ -1178,12 +1216,11 @@ module Squared
|
|
|
1178
1216
|
end
|
|
1179
1217
|
ret
|
|
1180
1218
|
end
|
|
1181
|
-
start = target.name
|
|
1182
1219
|
if depth == 0
|
|
1183
|
-
items =
|
|
1220
|
+
items = dedupe.call(target.name) - done
|
|
1184
1221
|
single = items.size == 1
|
|
1185
1222
|
else
|
|
1186
|
-
items =
|
|
1223
|
+
items = data[target.name] - done
|
|
1187
1224
|
end
|
|
1188
1225
|
if out
|
|
1189
1226
|
a, b, c, d, e = ARG[:GRAPH]
|
|
@@ -1198,21 +1235,21 @@ module Squared
|
|
|
1198
1235
|
"#{last ? d : c}#{b * 3}#{e} #{f}"
|
|
1199
1236
|
end
|
|
1200
1237
|
else
|
|
1201
|
-
"#{single ? ' ' : a}#{' ' *
|
|
1238
|
+
"#{single ? ' ' : a}#{' ' * depth.pred}#{last ? d : c}#{b * 3}#{items.empty? ? b : e} #{f}"
|
|
1202
1239
|
end
|
|
1203
1240
|
end
|
|
1204
1241
|
items.each_with_index do |proj, i|
|
|
1205
1242
|
next if done.include?(proj)
|
|
1206
1243
|
|
|
1207
|
-
t = dedupe.call(proj.name)
|
|
1244
|
+
t = dedupe.call(name = proj.name)
|
|
1208
1245
|
j = if out
|
|
1209
|
-
if i == items.size
|
|
1246
|
+
if i == items.size.pred || (post = items[i.succ..-1] - done).empty?
|
|
1210
1247
|
true
|
|
1211
1248
|
elsif !t.empty? && depth > 0
|
|
1212
|
-
post
|
|
1249
|
+
(post - t).empty?
|
|
1213
1250
|
end
|
|
1214
1251
|
end
|
|
1215
|
-
unless
|
|
1252
|
+
unless target.name == name || (none = (t - done).empty?)
|
|
1216
1253
|
graph_branch(proj, data, tasks, out, sync: sync, pass: pass, done: done, depth: depth.succ,
|
|
1217
1254
|
single: single, last: j == true, context: target)
|
|
1218
1255
|
end
|
|
@@ -1220,28 +1257,28 @@ module Squared
|
|
|
1220
1257
|
(tasks || (subtasks = script.call(proj)) || (dev? ? %w[build copy] : %w[depend build])).each do |meth|
|
|
1221
1258
|
next if pass.include?(meth)
|
|
1222
1259
|
|
|
1223
|
-
if workspace.task_defined?(cmd = task_join(
|
|
1224
|
-
if ENV.key?(key = "BANNER_#{
|
|
1260
|
+
if workspace.task_defined?(cmd = task_join(name, meth))
|
|
1261
|
+
if ENV.key?(key = "BANNER_#{name.upcase}")
|
|
1225
1262
|
key = nil
|
|
1226
1263
|
else
|
|
1227
1264
|
ENV[key] = '0'
|
|
1228
1265
|
end
|
|
1229
1266
|
run(cmd, sync: false, banner: false)
|
|
1230
1267
|
ENV.delete(key) if key
|
|
1231
|
-
elsif proj.has?(meth, tasks || subtasks
|
|
1268
|
+
elsif proj.has?(meth, (workspace.baseref unless tasks || subtasks))
|
|
1232
1269
|
proj.__send__(meth.to_sym, sync: sync)
|
|
1233
1270
|
end
|
|
1234
1271
|
end
|
|
1235
1272
|
elsif none
|
|
1236
1273
|
a, b, c, d = ARG[:GRAPH]
|
|
1237
1274
|
out << if depth == 0
|
|
1238
|
-
"#{i == items.size
|
|
1275
|
+
"#{i == items.size.pred ? d : c}#{b * 4} #{tag.call(proj)}"
|
|
1239
1276
|
else
|
|
1240
1277
|
s = ''.dup
|
|
1241
1278
|
k = 0
|
|
1242
1279
|
final = data.keys.last
|
|
1243
1280
|
while k < depth
|
|
1244
|
-
indent = k > 0 ? ((last && !j) || (j && k == depth
|
|
1281
|
+
indent = k > 0 ? ((last && !j) || (j && k == depth.pred) || single) : j && last && depth == 1
|
|
1245
1282
|
s += "#{indent || (last && data[final].last == context) ? ' ' : a} "
|
|
1246
1283
|
k += 1
|
|
1247
1284
|
end
|
|
@@ -1259,22 +1296,19 @@ module Squared
|
|
|
1259
1296
|
next if pass.include?(val)
|
|
1260
1297
|
|
|
1261
1298
|
if (obj = workspace.find(name: val))
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
items = [obj]
|
|
1299
|
+
obj.enabled? ? [obj] : []
|
|
1265
1300
|
else
|
|
1266
|
-
|
|
1267
|
-
end
|
|
1268
|
-
items.each do |proj|
|
|
1301
|
+
workspace.find(group: val, ref: val.to_sym)
|
|
1302
|
+
end.each do |proj|
|
|
1269
1303
|
next if pass.include?(name = proj.name)
|
|
1270
1304
|
|
|
1271
1305
|
if proj.graph? && !data.key?(name) && !root.include?(name)
|
|
1272
1306
|
graph_collect(proj, data: data, pass: pass, root: root + [name, target.name])
|
|
1273
1307
|
end
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1308
|
+
unless (objs = data.fetch(name, [])).include?(target)
|
|
1309
|
+
deps << proj
|
|
1310
|
+
deps.concat(objs)
|
|
1311
|
+
end
|
|
1278
1312
|
end
|
|
1279
1313
|
end
|
|
1280
1314
|
deps.uniq!
|
|
@@ -1300,44 +1334,96 @@ module Squared
|
|
|
1300
1334
|
end
|
|
1301
1335
|
|
|
1302
1336
|
def env(key, default = nil, suffix: nil, equals: nil, ignore: nil, strict: false)
|
|
1303
|
-
|
|
1337
|
+
name = "#{key}_#{@envname}"
|
|
1304
1338
|
ret = if suffix
|
|
1305
|
-
ENV.fetch("#{
|
|
1339
|
+
ENV.fetch("#{name}_#{suffix}", '')
|
|
1306
1340
|
elsif strict
|
|
1307
|
-
ENV[
|
|
1341
|
+
ENV[name].to_s
|
|
1308
1342
|
else
|
|
1309
1343
|
ignore = ['0'].freeze if ignore.nil?
|
|
1310
|
-
ENV[
|
|
1344
|
+
ENV[name] || ENV.fetch(key, '')
|
|
1311
1345
|
end
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
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
|
|
1315
1352
|
end
|
|
1316
1353
|
|
|
1317
1354
|
def session(*cmd, prefix: cmd.first, main: true, path: true, options: true)
|
|
1318
|
-
prefix =
|
|
1355
|
+
prefix = prefix.to_s.stripext
|
|
1319
1356
|
if path && (val = shell_bin(prefix))
|
|
1320
1357
|
cmd[0] = shell_quote(val, force: false)
|
|
1321
1358
|
end
|
|
1322
1359
|
ret = JoinSet.new(cmd.flatten(1))
|
|
1323
|
-
if options
|
|
1324
|
-
|
|
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
|
|
1325
1368
|
end
|
|
1326
1369
|
main ? @session = ret : ret
|
|
1327
1370
|
end
|
|
1328
1371
|
|
|
1329
|
-
def session_delete(*args, target: @session)
|
|
1330
|
-
OptionPartition.delete(target, *args)
|
|
1331
|
-
end
|
|
1332
|
-
|
|
1333
1372
|
def session_output(*cmd, **kwargs)
|
|
1334
1373
|
session(*cmd, main: false, options: false, **kwargs)
|
|
1335
1374
|
end
|
|
1336
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
|
+
|
|
1337
1423
|
def session_done(cmd)
|
|
1338
|
-
return cmd unless cmd.respond_to?(:done)
|
|
1424
|
+
return cmd.to_s unless cmd.respond_to?(:done)
|
|
1339
1425
|
|
|
1340
|
-
raise_error
|
|
1426
|
+
raise_error 'no command added', hint: cmd.first unless cmd.size > 1
|
|
1341
1427
|
@session = nil if cmd == @session
|
|
1342
1428
|
cmd.done
|
|
1343
1429
|
end
|
|
@@ -1352,33 +1438,40 @@ module Squared
|
|
|
1352
1438
|
return unless prefix
|
|
1353
1439
|
|
|
1354
1440
|
args.each do |val|
|
|
1355
|
-
next unless (ret = env(env_key(stripext
|
|
1441
|
+
next unless (ret = env(env_key(prefix.to_s.stripext, val), **kwargs))
|
|
1356
1442
|
|
|
1357
1443
|
return block_given? ? yield(ret) : ret
|
|
1358
1444
|
end
|
|
1359
1445
|
nil
|
|
1360
1446
|
end
|
|
1361
1447
|
|
|
1362
|
-
def option_clear(opts, target: @session, **kwargs)
|
|
1448
|
+
def option_clear(opts, empty = true, target: @session, **kwargs)
|
|
1363
1449
|
return unless target
|
|
1364
1450
|
|
|
1365
1451
|
OptionPartition.clear(target, opts, styles: theme[:inline], **kwargs)
|
|
1452
|
+
opts.clear if empty
|
|
1453
|
+
nil
|
|
1366
1454
|
end
|
|
1367
1455
|
|
|
1368
|
-
def print_success
|
|
1456
|
+
def print_success
|
|
1369
1457
|
puts 'Success'
|
|
1370
1458
|
end
|
|
1371
1459
|
|
|
1372
1460
|
def print_error(*args, loglevel: Logger::WARN, **kwargs)
|
|
1373
|
-
|
|
1461
|
+
warn log_message(loglevel, *args, **kwargs) if warning?
|
|
1462
|
+
end
|
|
1374
1463
|
|
|
1375
|
-
|
|
1464
|
+
def print_run(cmd, banner = true, verbose: nil, **)
|
|
1465
|
+
return if banner || !stdout? || verbose == false
|
|
1466
|
+
|
|
1467
|
+
puts "\n> #{cmd}"
|
|
1468
|
+
printsucc
|
|
1376
1469
|
end
|
|
1377
1470
|
|
|
1378
1471
|
def print_item(*val, series: true)
|
|
1379
1472
|
puts unless printfirst?
|
|
1380
1473
|
printsucc if series
|
|
1381
|
-
puts val unless val.empty? || (val.size == 1 && val.first
|
|
1474
|
+
puts val unless val.empty? || (val.size == 1 && !val.first)
|
|
1382
1475
|
end
|
|
1383
1476
|
|
|
1384
1477
|
def print_banner(*lines, client: false, styles: theme[:banner], border: borderstyle, **)
|
|
@@ -1407,14 +1500,15 @@ module Squared
|
|
|
1407
1500
|
|
|
1408
1501
|
def print_footer(*lines, sub: nil, reverse: false, right: false, border: borderstyle, **)
|
|
1409
1502
|
n = line_width lines
|
|
1503
|
+
sub = as_a sub
|
|
1410
1504
|
lines.map! do |val|
|
|
1411
1505
|
s = right ? val.rjust(n) : val.ljust(n)
|
|
1412
|
-
sub
|
|
1506
|
+
sub.each { |h| s = sub_style(s, **h) }
|
|
1413
1507
|
s
|
|
1414
1508
|
end
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1509
|
+
[sub_style(ARG[:BORDER][1] * n, styles: border)].concat(lines)
|
|
1510
|
+
.tap { |ret| ret.reverse! if reverse }
|
|
1511
|
+
.join("\n")
|
|
1418
1512
|
end
|
|
1419
1513
|
|
|
1420
1514
|
def print_status(*args, from: nil, **kwargs)
|
|
@@ -1423,15 +1517,15 @@ module Squared
|
|
|
1423
1517
|
case from
|
|
1424
1518
|
when :outdated
|
|
1425
1519
|
out = print_footer("major #{args[0]} / minor #{args[1]} / patch #{args[2]}", right: true).split("\n")
|
|
1426
|
-
out[1] = sub_style(out[1],
|
|
1427
|
-
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]
|
|
1428
1523
|
puts out
|
|
1429
1524
|
when :completed
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
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]))
|
|
1435
1529
|
end
|
|
1436
1530
|
end
|
|
1437
1531
|
|
|
@@ -1441,7 +1535,7 @@ module Squared
|
|
|
1441
1535
|
workspace.format_desc([@desc, action, flag].compact, opts, **kwargs)
|
|
1442
1536
|
end
|
|
1443
1537
|
|
|
1444
|
-
def format_banner(cmd, banner: true)
|
|
1538
|
+
def format_banner(cmd, banner: true, hint: nil, strip: nil)
|
|
1445
1539
|
return unless banner && banner?
|
|
1446
1540
|
|
|
1447
1541
|
if (data = workspace.banner_get(*@ref, group: group))
|
|
@@ -1455,11 +1549,14 @@ module Squared
|
|
|
1455
1549
|
out = []
|
|
1456
1550
|
if data.command
|
|
1457
1551
|
if cmd =~ /\A(?:"((?:[^"]|(?<=\\)")+)"|'((?:[^']|(?<=\\)')+)'|(\S+))( |\z)/
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
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)
|
|
1461
1554
|
end
|
|
1462
|
-
|
|
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)
|
|
1463
1560
|
end
|
|
1464
1561
|
data.order.each do |val|
|
|
1465
1562
|
if val.is_a?(Array)
|
|
@@ -1487,7 +1584,7 @@ module Squared
|
|
|
1487
1584
|
end
|
|
1488
1585
|
end
|
|
1489
1586
|
|
|
1490
|
-
def format_list(items, cmd, type, grep: [], from: nil
|
|
1587
|
+
def format_list(items, cmd, type, grep: [], from: nil)
|
|
1491
1588
|
reg = grep.map { |val| Regexp.new(val) }
|
|
1492
1589
|
out = []
|
|
1493
1590
|
unless items.empty?
|
|
@@ -1495,29 +1592,29 @@ module Squared
|
|
|
1495
1592
|
items.each_with_index do |val, i|
|
|
1496
1593
|
next unless matchany?(val.first, reg)
|
|
1497
1594
|
|
|
1498
|
-
out << ('%*d. %s' % [pad, i.succ,
|
|
1595
|
+
out << ('%*d. %s' % [pad, i.succ, block_given? ? yield(val) : val.first])
|
|
1499
1596
|
end
|
|
1500
1597
|
end
|
|
1501
1598
|
sub = [headerstyle]
|
|
1502
|
-
if out.empty?
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
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
|
|
1521
1618
|
emphasize(out, title: task_join(name, cmd), border: borderstyle, sub: sub, footer: footer, right: true)
|
|
1522
1619
|
end
|
|
1523
1620
|
|
|
@@ -1525,14 +1622,13 @@ module Squared
|
|
|
1525
1622
|
"#{msg}#{!always && (!obj || obj == 0 || obj.to_s.empty?) ? '' : message(hint: message(title, obj.to_s))}"
|
|
1526
1623
|
end
|
|
1527
1624
|
|
|
1528
|
-
def append_repeat(flag, opts, target: @session
|
|
1529
|
-
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) }
|
|
1530
1627
|
end
|
|
1531
1628
|
|
|
1532
1629
|
def append_hash(data, target: @session || [], build: false)
|
|
1533
1630
|
if build && (type = env('BUILD', suffix: 'TYPE') || ENV['BUILD_TYPE'])
|
|
1534
|
-
type = "__#{type}__"
|
|
1535
|
-
if (extra = data[type] || data[type.to_sym]).is_a?(Hash)
|
|
1631
|
+
if (extra = data[type = "__#{type}__"] || data[type.to_sym]).is_a?(Hash)
|
|
1536
1632
|
data = data.merge(extra)
|
|
1537
1633
|
else
|
|
1538
1634
|
extra = nil
|
|
@@ -1552,33 +1648,25 @@ module Squared
|
|
|
1552
1648
|
target << basic_option(key, val)
|
|
1553
1649
|
when FalseClass
|
|
1554
1650
|
target << shell_option(key).sub(/^--(?!no-)/, '--no-')
|
|
1555
|
-
when Pathname
|
|
1556
|
-
target << shell_option(key, val, escape: false)
|
|
1557
1651
|
else
|
|
1558
|
-
target << shell_option(key, val.is_a?(String)
|
|
1652
|
+
target << shell_option(key, (val if val.is_a?(String)))
|
|
1559
1653
|
end
|
|
1560
1654
|
end
|
|
1561
1655
|
target
|
|
1562
1656
|
end
|
|
1563
1657
|
|
|
1564
1658
|
def append_any(val, target: @session, build: false, delim: false)
|
|
1565
|
-
return unless val
|
|
1566
|
-
|
|
1567
1659
|
if delim && !target.include?('--')
|
|
1568
1660
|
target << '--'
|
|
1569
1661
|
else
|
|
1570
1662
|
delim = false
|
|
1571
1663
|
end
|
|
1572
|
-
val = shell_split
|
|
1664
|
+
val = shell_split val if val.is_a?(String)
|
|
1573
1665
|
case val
|
|
1574
1666
|
when Hash
|
|
1575
1667
|
append_hash(val, target: target, build: build)
|
|
1576
1668
|
when Enumerable
|
|
1577
|
-
|
|
1578
|
-
target.concat(val.to_a)
|
|
1579
|
-
else
|
|
1580
|
-
target.merge(val.to_a)
|
|
1581
|
-
end
|
|
1669
|
+
merge_list target, val
|
|
1582
1670
|
else
|
|
1583
1671
|
target.delete('--') if delim
|
|
1584
1672
|
nil
|
|
@@ -1599,7 +1687,7 @@ module Squared
|
|
|
1599
1687
|
next unless (val = option(opt, **kwargs))
|
|
1600
1688
|
|
|
1601
1689
|
return target << if flag
|
|
1602
|
-
shell_option(opt,
|
|
1690
|
+
shell_option(opt, (val if equals), quote: quote, escape: escape, force: force)
|
|
1603
1691
|
else
|
|
1604
1692
|
shell_quote val
|
|
1605
1693
|
end
|
|
@@ -1611,25 +1699,44 @@ module Squared
|
|
|
1611
1699
|
**kwargs)
|
|
1612
1700
|
return if list.empty?
|
|
1613
1701
|
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
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))
|
|
1618
1705
|
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
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)
|
|
1622
1711
|
end
|
|
1623
|
-
|
|
1712
|
+
next if ret.empty?
|
|
1713
|
+
|
|
1714
|
+
merge_list target, ret
|
|
1624
1715
|
end
|
|
1625
|
-
ret.each { |val| target << val } unless ret.empty?
|
|
1626
|
-
ret
|
|
1627
1716
|
end
|
|
1628
1717
|
|
|
1629
1718
|
def append_nocolor(target: @session)
|
|
1630
1719
|
target << '--no-color' if !ARG[:COLOR] || stdin? || option('color', target: target, equals: '0')
|
|
1631
1720
|
end
|
|
1632
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
|
+
|
|
1633
1740
|
def merge_opts(base, data)
|
|
1634
1741
|
case data
|
|
1635
1742
|
when String
|
|
@@ -1670,27 +1777,31 @@ module Squared
|
|
|
1670
1777
|
end
|
|
1671
1778
|
end
|
|
1672
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
|
+
|
|
1673
1792
|
def collect_hash(data, pass: [])
|
|
1674
1793
|
ret = []
|
|
1675
1794
|
data.each { |key, val| ret.concat(val) unless pass.include?(key) }
|
|
1676
1795
|
ret
|
|
1677
1796
|
end
|
|
1678
1797
|
|
|
1679
|
-
def replace_bin(val)
|
|
1680
|
-
a, b = val.split(' ', 2)
|
|
1681
|
-
return val if val.start_with?(/["']/) || a.include?(File::Separator)
|
|
1682
|
-
|
|
1683
|
-
[shell_bin(a), b].compact.join(' ')
|
|
1684
|
-
end
|
|
1685
|
-
|
|
1686
1798
|
def parse_json(val, kind: Hash, hint: nil)
|
|
1687
1799
|
ret = JSON.parse(val)
|
|
1688
|
-
raise_error
|
|
1800
|
+
raise_error 'invalid JSON'.subhint(kind.name), val, hint: hint if kind && !ret.is_a?(kind)
|
|
1801
|
+
ret
|
|
1689
1802
|
rescue StandardError => e
|
|
1690
1803
|
log&.warn e
|
|
1691
1804
|
print_error(e, subject: name)
|
|
1692
|
-
else
|
|
1693
|
-
ret
|
|
1694
1805
|
end
|
|
1695
1806
|
|
|
1696
1807
|
def param_guard(action, flag, args:, key: nil, pat: nil, values: nil)
|
|
@@ -1702,12 +1813,16 @@ module Squared
|
|
|
1702
1813
|
raise_error(action, "#{flag}[#{key}]", hint: val.nil? ? 'missing' : 'invalid')
|
|
1703
1814
|
elsif args.is_a?(Array) && args.empty?
|
|
1704
1815
|
@session = nil
|
|
1705
|
-
raise_error
|
|
1816
|
+
raise_error action, "#{flag}+", hint: 'empty'
|
|
1706
1817
|
end
|
|
1707
1818
|
args
|
|
1708
1819
|
end
|
|
1709
1820
|
|
|
1710
|
-
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)
|
|
1711
1826
|
a = sub_style(case rev
|
|
1712
1827
|
when 1
|
|
1713
1828
|
'MAJOR'
|
|
@@ -1719,16 +1834,17 @@ module Squared
|
|
|
1719
1834
|
b = sub_style(pkg.ljust(col1), styles: theme[:inline])
|
|
1720
1835
|
c = lock ? sub_style((cur || 'locked').rjust(7), styles: color(:red)) : cur&.rjust(7)
|
|
1721
1836
|
d = rev == 1 || lock ? 'N' : 'Y'
|
|
1722
|
-
confirm
|
|
1837
|
+
confirm("#{a}: #{b}#{c} #{sub_style(ver.rjust(col1 > 0 ? 10 : 0), styles: theme[:inline])} ", d, **kwargs)
|
|
1723
1838
|
end
|
|
1724
1839
|
|
|
1725
1840
|
def choice_index(msg, list, values: nil, accept: nil, series: false, trim: nil, column: nil, multiple: false,
|
|
1726
1841
|
force: true, **kwargs)
|
|
1727
|
-
puts
|
|
1728
|
-
|
|
1729
|
-
|
|
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
|
+
|
|
1730
1846
|
exit 1 if force
|
|
1731
|
-
return
|
|
1847
|
+
return nil
|
|
1732
1848
|
end
|
|
1733
1849
|
ret = multiple ? ret.map! { |val| val.sub(trim, '') } : ret.sub(trim, '') if trim
|
|
1734
1850
|
if column
|
|
@@ -1742,7 +1858,7 @@ module Squared
|
|
|
1742
1858
|
ret = Array(ret) if accept.any? { |val| val[1] == true }
|
|
1743
1859
|
loop do
|
|
1744
1860
|
item = accept.first
|
|
1745
|
-
c = confirm("#{item[0]}#{hint ? " [#{hint}]" : ''}", item[2] ? 'Y' : 'N'
|
|
1861
|
+
c = confirm("#{item[0]}#{hint ? " [#{hint}]" : ''}", item[2] ? 'Y' : 'N')
|
|
1746
1862
|
if item[1] == true
|
|
1747
1863
|
ret << c
|
|
1748
1864
|
elsif !c
|
|
@@ -1763,25 +1879,29 @@ module Squared
|
|
|
1763
1879
|
force = false
|
|
1764
1880
|
end
|
|
1765
1881
|
val = readline(val, force: force)
|
|
1766
|
-
ret << (val.empty?
|
|
1882
|
+
ret << (val unless val.empty?)
|
|
1767
1883
|
end
|
|
1768
1884
|
end
|
|
1769
1885
|
printsucc unless series
|
|
1770
1886
|
ret
|
|
1771
1887
|
end
|
|
1772
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
|
+
|
|
1773
1897
|
def command_args(args, min: 0, force: false, **kwargs)
|
|
1774
1898
|
return if args.size > min || option('i', 'interactive', **kwargs, equals: '0')
|
|
1775
1899
|
|
|
1776
1900
|
readline('Enter arguments', force: force)
|
|
1777
1901
|
end
|
|
1778
1902
|
|
|
1779
|
-
def block_args(
|
|
1780
|
-
|
|
1781
|
-
val
|
|
1782
|
-
else
|
|
1783
|
-
Array(ret)
|
|
1784
|
-
end
|
|
1903
|
+
def block_args(fallback = nil, &blk)
|
|
1904
|
+
(ret = instance_eval(&blk)).nil? ? fallback : Array(ret)
|
|
1785
1905
|
end
|
|
1786
1906
|
|
|
1787
1907
|
def runenv
|
|
@@ -1791,7 +1911,7 @@ module Squared
|
|
|
1791
1911
|
def command(*args)
|
|
1792
1912
|
return args.join(' && ') unless workspace.powershell?
|
|
1793
1913
|
|
|
1794
|
-
"
|
|
1914
|
+
"powershell.exe -Command #{shell_quote("& {#{args.join(' ; ')}}", option: false, double: true)}"
|
|
1795
1915
|
end
|
|
1796
1916
|
|
|
1797
1917
|
def relativepath(*list, all: false)
|
|
@@ -1814,12 +1934,10 @@ module Squared
|
|
|
1814
1934
|
|
|
1815
1935
|
def matchmap(list, prefix = nil)
|
|
1816
1936
|
list.map do |val|
|
|
1817
|
-
if val.is_a?(Regexp)
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
Regexp.new("#{prefix}#{val == '*' ? '.+' : val}")
|
|
1822
|
-
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}")
|
|
1823
1941
|
end
|
|
1824
1942
|
end
|
|
1825
1943
|
|
|
@@ -1836,7 +1954,8 @@ module Squared
|
|
|
1836
1954
|
end
|
|
1837
1955
|
|
|
1838
1956
|
def semscan(val, fill: true)
|
|
1839
|
-
val.scan(SEM_VER).first
|
|
1957
|
+
ret = val.scan(SEM_VER).first
|
|
1958
|
+
fill ? semver(ret) : ret
|
|
1840
1959
|
end
|
|
1841
1960
|
|
|
1842
1961
|
def semcmp(val, other)
|
|
@@ -1852,14 +1971,38 @@ module Squared
|
|
|
1852
1971
|
end
|
|
1853
1972
|
[c[0], c[2], c[4] || '0', d]
|
|
1854
1973
|
end
|
|
1855
|
-
a.each_with_index do |c,
|
|
1856
|
-
next if c == (d = b[
|
|
1974
|
+
a.each_with_index do |c, i|
|
|
1975
|
+
next if c == (d = b[i])
|
|
1857
1976
|
|
|
1858
1977
|
return c.to_i < d.to_i ? 1 : -1
|
|
1859
1978
|
end
|
|
1860
1979
|
0
|
|
1861
1980
|
end
|
|
1862
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
|
+
|
|
1863
2006
|
def semgte?(val, other)
|
|
1864
2007
|
semcmp(val, other) != 1
|
|
1865
2008
|
end
|
|
@@ -1869,7 +2012,7 @@ module Squared
|
|
|
1869
2012
|
end
|
|
1870
2013
|
|
|
1871
2014
|
def indexerror(val, list = nil)
|
|
1872
|
-
raise_error
|
|
2015
|
+
raise_error IndexError, "requested index #{val}", hint: list && "of #{list.size}"
|
|
1873
2016
|
end
|
|
1874
2017
|
|
|
1875
2018
|
def indexchar
|
|
@@ -1888,10 +2031,6 @@ module Squared
|
|
|
1888
2031
|
val.compact.flat_map { |s| color(s) }
|
|
1889
2032
|
end
|
|
1890
2033
|
|
|
1891
|
-
def epochtime
|
|
1892
|
-
Time.now.strftime('%s%L').to_i
|
|
1893
|
-
end
|
|
1894
|
-
|
|
1895
2034
|
def verbosetype
|
|
1896
2035
|
case verbose
|
|
1897
2036
|
when TrueClass
|
|
@@ -1923,7 +2062,7 @@ module Squared
|
|
|
1923
2062
|
end
|
|
1924
2063
|
end
|
|
1925
2064
|
|
|
1926
|
-
def on_error(err, from, exception: self.exception,
|
|
2065
|
+
def on_error(err, from, pass: false, exception: self.exception, dryrun: false)
|
|
1927
2066
|
log&.error err
|
|
1928
2067
|
unless dryrun
|
|
1929
2068
|
ret = on :error, from, err
|
|
@@ -1932,19 +2071,17 @@ module Squared
|
|
|
1932
2071
|
print_error(err, pass: pass) unless ret
|
|
1933
2072
|
end
|
|
1934
2073
|
|
|
1935
|
-
def pwd_set(pass: false, dryrun: false, from: nil)
|
|
1936
|
-
return yield if (path.to_s == Dir.pwd || pass == true) && (workspace.mri? || !workspace.windows?)
|
|
1937
|
-
|
|
2074
|
+
def pwd_set(pass: false, exception: self.exception, dryrun: false, from: nil)
|
|
1938
2075
|
pwd = Dir.pwd
|
|
1939
|
-
|
|
1940
|
-
|
|
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 }
|
|
1941
2080
|
rescue StandardError => e
|
|
1942
|
-
on_error(e, from, dryrun: dryrun)
|
|
1943
|
-
ensure
|
|
1944
|
-
Dir.chdir(pwd) if pwd
|
|
2081
|
+
on_error(e, from, exception: exception, dryrun: dryrun)
|
|
1945
2082
|
end
|
|
1946
2083
|
|
|
1947
|
-
def run_set(cmd, val = nil, opts: nil, **)
|
|
2084
|
+
def run_set(cmd, val = nil, opts: nil, global: false, **)
|
|
1948
2085
|
noopt = @output[1] == false && !@output[0].nil?
|
|
1949
2086
|
noenv = @output[2] == false
|
|
1950
2087
|
parse = lambda do |data|
|
|
@@ -1963,6 +2100,7 @@ module Squared
|
|
|
1963
2100
|
ret[2] = data[:env] unless dise
|
|
1964
2101
|
ret
|
|
1965
2102
|
end
|
|
2103
|
+
self.global = global
|
|
1966
2104
|
case cmd
|
|
1967
2105
|
when Array
|
|
1968
2106
|
@output = if cmd.all? { |data| data.is_a?(Hash) }
|
|
@@ -1994,11 +2132,12 @@ module Squared
|
|
|
1994
2132
|
end
|
|
1995
2133
|
end
|
|
1996
2134
|
|
|
1997
|
-
def script_set(cmd, prod: nil, args: nil, **)
|
|
2135
|
+
def script_set(cmd, prod: nil, args: nil, global: false, **)
|
|
1998
2136
|
return if @output[1] == false && @output[0].nil?
|
|
1999
2137
|
|
|
2138
|
+
self.global = global
|
|
2000
2139
|
@output[0] = nil
|
|
2001
|
-
@output[1] = if
|
|
2140
|
+
@output[1] = if self.global && cmd.is_a?(Array)
|
|
2002
2141
|
cmd[prod == true ? 1 : 0]
|
|
2003
2142
|
else
|
|
2004
2143
|
cmd
|
|
@@ -2043,7 +2182,7 @@ module Squared
|
|
|
2043
2182
|
|
|
2044
2183
|
def asdf_set(val)
|
|
2045
2184
|
@asdf = if @@asdf && val
|
|
2046
|
-
dir = @@asdf
|
|
2185
|
+
dir = @@asdf.path.join('installs', val)
|
|
2047
2186
|
[val, dir] if dir.exist? && !dir.empty?
|
|
2048
2187
|
end
|
|
2049
2188
|
end
|
|
@@ -2059,9 +2198,12 @@ module Squared
|
|
|
2059
2198
|
end
|
|
2060
2199
|
|
|
2061
2200
|
def dependfile_set(list)
|
|
2062
|
-
@dependindex =
|
|
2063
|
-
|
|
2064
|
-
|
|
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
|
|
2065
2207
|
end
|
|
2066
2208
|
|
|
2067
2209
|
def as_get(val, from)
|
|
@@ -2103,12 +2245,10 @@ module Squared
|
|
|
2103
2245
|
end
|
|
2104
2246
|
|
|
2105
2247
|
def checkdir?(val)
|
|
2106
|
-
if val.directory? && !val.empty?
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
false
|
|
2111
|
-
end
|
|
2248
|
+
return true if val.directory? && !val.empty?
|
|
2249
|
+
|
|
2250
|
+
log&.warn "directory \"#{val}\"".subhint(val.directory? ? 'empty' : 'missing')
|
|
2251
|
+
false
|
|
2112
2252
|
end
|
|
2113
2253
|
|
|
2114
2254
|
def semmajor?(cur, want)
|
|
@@ -2121,7 +2261,7 @@ module Squared
|
|
|
2121
2261
|
|
|
2122
2262
|
def runnable?(val)
|
|
2123
2263
|
case val
|
|
2124
|
-
when String, Enumerable, Proc, Method
|
|
2264
|
+
when String, Enumerable, Proc, Method
|
|
2125
2265
|
true
|
|
2126
2266
|
else
|
|
2127
2267
|
false
|
|
@@ -2148,14 +2288,24 @@ module Squared
|
|
|
2148
2288
|
return true if val || from_sync?(ac = workspace.task_name(action))
|
|
2149
2289
|
return val if group && !(val = from_sync?(ac, group)).nil?
|
|
2150
2290
|
return val if (base = workspace.find_base(self)) && !(val = from_sync?(ac, base.ref)).nil?
|
|
2151
|
-
return false if workspace.series.chain?(
|
|
2152
|
-
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'))
|
|
2153
2293
|
|
|
2154
|
-
workspace.series.name_get(action)
|
|
2294
|
+
ret = workspace.series.name_get(action)
|
|
2295
|
+
ret != action && invoked_sync?(ret)
|
|
2155
2296
|
end
|
|
2156
2297
|
|
|
2157
|
-
def success?(
|
|
2158
|
-
|
|
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
|
|
2159
2309
|
end
|
|
2160
2310
|
|
|
2161
2311
|
def banner?
|
|
@@ -2182,10 +2332,16 @@ module Squared
|
|
|
2182
2332
|
workspace.warning
|
|
2183
2333
|
end
|
|
2184
2334
|
|
|
2185
|
-
def has_value?(
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
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
|
|
2189
2345
|
end
|
|
2190
2346
|
|
|
2191
2347
|
def variables
|
|
@@ -2196,28 +2352,16 @@ module Squared
|
|
|
2196
2352
|
BLK_SET
|
|
2197
2353
|
end
|
|
2198
2354
|
|
|
2199
|
-
def hashobj
|
|
2200
|
-
Workspace::Support.hashobj
|
|
2201
|
-
end
|
|
2202
|
-
|
|
2203
|
-
def hashlist
|
|
2204
|
-
Workspace::Support.hashlist
|
|
2205
|
-
end
|
|
2206
|
-
|
|
2207
|
-
def hashdup
|
|
2208
|
-
Workspace::Support.hashdup
|
|
2209
|
-
end
|
|
2210
|
-
|
|
2211
2355
|
def borderstyle
|
|
2212
2356
|
workspace.banner_get(*@ref, group: group)&.border || theme[:border]
|
|
2213
2357
|
end
|
|
2214
2358
|
|
|
2215
2359
|
def headerstyle
|
|
2216
|
-
|
|
2360
|
+
opt_style theme[:header], /^(\S+)(\s+)$/
|
|
2217
2361
|
end
|
|
2218
2362
|
|
|
2219
2363
|
def scriptargs
|
|
2220
|
-
{ 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 }
|
|
2221
2365
|
end
|
|
2222
2366
|
end
|
|
2223
2367
|
|