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