squared 0.5.18 → 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 -105
- data/README.md +101 -69
- data/lib/squared/common/base.rb +1 -22
- data/lib/squared/common/format.rb +40 -34
- data/lib/squared/common/prompt.rb +57 -34
- data/lib/squared/common/shell.rb +71 -55
- 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 +80 -81
- data/lib/squared/workspace/project/base.rb +534 -369
- data/lib/squared/workspace/project/docker.rb +376 -273
- data/lib/squared/workspace/project/git.rb +348 -335
- data/lib/squared/workspace/project/node.rb +499 -272
- data/lib/squared/workspace/project/python.rb +332 -203
- data/lib/squared/workspace/project/ruby.rb +664 -354
- data/lib/squared/workspace/project/support/class.rb +192 -188
- data/lib/squared/workspace/repo.rb +43 -41
- data/lib/squared/workspace/series.rb +6 -6
- 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
|
-
|
|
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)
|
|
@@ -525,33 +553,33 @@ module Squared
|
|
|
525
553
|
cmd = cmd.join(' && ')
|
|
526
554
|
else
|
|
527
555
|
cmd, opts, var, flags, extra = args
|
|
528
|
-
|
|
529
|
-
|
|
556
|
+
end
|
|
557
|
+
if cmd
|
|
558
|
+
return run_b(cmd, sync: sync, from: from) if cmd.is_a?(Proc) || cmd.is_a?(Method)
|
|
530
559
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
else
|
|
545
|
-
cmd = [cmd, flags, opts].compact.join(' ') if opts || flags
|
|
546
|
-
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(' && ')
|
|
547
573
|
else
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
cmd = compose(as_get(opts, from), flags, script: true, args: extra, from: from)
|
|
551
|
-
from = :script if from == :run && script?
|
|
574
|
+
cmd = [cmd, flags, opts].compact.join(' ') if opts || flags
|
|
552
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?
|
|
553
581
|
end
|
|
554
|
-
run(cmd, var, sync: sync,
|
|
582
|
+
run(cmd, var, sync: sync, banner: banner, from: from)
|
|
555
583
|
end
|
|
556
584
|
|
|
557
585
|
def depend(*, sync: invoked_sync?('depend'), **)
|
|
@@ -564,16 +592,16 @@ module Squared
|
|
|
564
592
|
next if @@graph[:_].include?(proj)
|
|
565
593
|
|
|
566
594
|
if (val = ENV["PREREQS_#{proj.instance_variable_get(:@envname)}"] || ENV["PREREQS_#{proj.ref.upcase}"])
|
|
567
|
-
split_escape(val)
|
|
595
|
+
split_escape(val) do |meth|
|
|
568
596
|
if proj.respond_to?(meth.to_sym)
|
|
569
597
|
begin
|
|
570
598
|
proj.__send__(meth, sync: sync)
|
|
599
|
+
next
|
|
571
600
|
rescue StandardError => e
|
|
572
601
|
on_error(e, :prereqs, exception: true)
|
|
573
602
|
end
|
|
574
|
-
else
|
|
575
|
-
print_error(name, "method: #{meth}", subject: 'prereqs', hint: 'undefined')
|
|
576
603
|
end
|
|
604
|
+
print_error(name, 'method not found', subject: 'prereqs', hint: meth)
|
|
577
605
|
end
|
|
578
606
|
elsif proj.build?
|
|
579
607
|
proj.build(sync: sync)
|
|
@@ -651,9 +679,9 @@ module Squared
|
|
|
651
679
|
end
|
|
652
680
|
|
|
653
681
|
def graph(start = [], tasks = nil, *, sync: invoked_sync?('graph'), pass: [], out: nil, **)
|
|
654
|
-
|
|
682
|
+
env('GRAPH', strict: true) do |val|
|
|
655
683
|
tasks ||= []
|
|
656
|
-
split_escape(val)
|
|
684
|
+
split_escape(val) do |task|
|
|
657
685
|
if ref?(task.to_sym) && (script = workspace.script_get(:graph, ref: task.to_sym))
|
|
658
686
|
tasks.concat(script[:graph])
|
|
659
687
|
else
|
|
@@ -661,7 +689,7 @@ module Squared
|
|
|
661
689
|
end
|
|
662
690
|
end
|
|
663
691
|
end
|
|
664
|
-
|
|
692
|
+
env('GRAPH', suffix: 'PASS') { |val| pass.concat(split_escape(val)) }
|
|
665
693
|
start, neg = start.partition { |name| !name.start_with?('-') }
|
|
666
694
|
data = graph_collect(self, start, pass: neg.map! { |name| name[1..-1] })
|
|
667
695
|
unless out
|
|
@@ -684,9 +712,9 @@ module Squared
|
|
|
684
712
|
if !target.exist?
|
|
685
713
|
target.mkpath
|
|
686
714
|
elsif !target.directory?
|
|
687
|
-
raise_error
|
|
715
|
+
raise_error Errno::EEXIST, target, hint: uri
|
|
688
716
|
elsif !file && !target.empty?
|
|
689
|
-
raise_error
|
|
717
|
+
raise_error Errno::EEXIST, target, hint: uri unless force || env('UNPACK_FORCE')
|
|
690
718
|
create = true
|
|
691
719
|
end
|
|
692
720
|
if digest
|
|
@@ -706,25 +734,27 @@ module Squared
|
|
|
706
734
|
when 128, 'sha512'
|
|
707
735
|
Digest::SHA512
|
|
708
736
|
else
|
|
709
|
-
raise_error "invalid checksum: #{digest}"
|
|
737
|
+
raise_error "invalid checksum: #{digest}", hint: uri
|
|
710
738
|
end
|
|
711
739
|
end
|
|
712
|
-
|
|
713
|
-
|
|
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
|
|
714
744
|
end
|
|
715
745
|
if file
|
|
716
746
|
ext ||= File.extname(file)[1..-1]
|
|
717
747
|
else
|
|
718
748
|
require 'open-uri'
|
|
719
749
|
data = nil
|
|
720
|
-
(uri = Array(uri)).each_with_index do |url,
|
|
750
|
+
(uri = Array(uri)).each_with_index do |url, i|
|
|
721
751
|
URI.open(url, headers) do |f|
|
|
722
752
|
data = f.read
|
|
723
753
|
if algo && algo.hexdigest(data) != digest
|
|
724
754
|
data = nil
|
|
725
|
-
raise_error
|
|
755
|
+
raise_error "invalid checksum: #{digest}", hint: url if i == uri.size.pred
|
|
726
756
|
end
|
|
727
|
-
next if ext &&
|
|
757
|
+
next if ext && i == 0
|
|
728
758
|
|
|
729
759
|
case f.content_type
|
|
730
760
|
when 'application/zip'
|
|
@@ -739,8 +769,8 @@ module Squared
|
|
|
739
769
|
end
|
|
740
770
|
break uri = url if data
|
|
741
771
|
end
|
|
742
|
-
unless data && (ext ||= URI.
|
|
743
|
-
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)
|
|
744
774
|
end
|
|
745
775
|
end
|
|
746
776
|
ext = ext.downcase
|
|
@@ -749,13 +779,13 @@ module Squared
|
|
|
749
779
|
end
|
|
750
780
|
begin
|
|
751
781
|
unless file
|
|
752
|
-
if ext == 'gem'
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
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
|
|
759
789
|
file.write(data)
|
|
760
790
|
file.close
|
|
761
791
|
file = Pathname.new(file)
|
|
@@ -769,7 +799,7 @@ module Squared
|
|
|
769
799
|
case ext
|
|
770
800
|
when 'zip', 'aar'
|
|
771
801
|
session 'unzip', shell_quote(file), quote_option('d', target)
|
|
772
|
-
when 'tar',
|
|
802
|
+
when 'tar', /\A(?:t|tar\.)?[gx]z\z/
|
|
773
803
|
flags = +(verbose ? 'v' : '')
|
|
774
804
|
if ext.end_with?('gz')
|
|
775
805
|
flags += 'z'
|
|
@@ -812,16 +842,17 @@ module Squared
|
|
|
812
842
|
def asdf(flag, opts = [], version: nil)
|
|
813
843
|
return unless @asdf
|
|
814
844
|
|
|
815
|
-
cmd = session 'asdf', flag
|
|
845
|
+
cmd = flag == :update ? session('asdf', 'plugin update') : session('asdf', flag)
|
|
816
846
|
name = @asdf.first
|
|
817
|
-
legacy = @@asdf
|
|
847
|
+
legacy = @@asdf.version == 15
|
|
848
|
+
banner = true
|
|
818
849
|
case flag
|
|
819
850
|
when :set
|
|
820
|
-
u = has_value?(opts,
|
|
851
|
+
u = has_value?(opts, 'u', 'home')
|
|
821
852
|
cmd << if legacy
|
|
822
853
|
cmd.delete(flag)
|
|
823
854
|
u ? 'global' : 'local'
|
|
824
|
-
elsif has_value?(opts,
|
|
855
|
+
elsif has_value?(opts, 'p', 'parent')
|
|
825
856
|
'--parent'
|
|
826
857
|
elsif u
|
|
827
858
|
'--home'
|
|
@@ -832,8 +863,11 @@ module Squared
|
|
|
832
863
|
when :current
|
|
833
864
|
cmd << '--no-header' unless legacy
|
|
834
865
|
cmd << name
|
|
866
|
+
else
|
|
867
|
+
cmd << name
|
|
868
|
+
banner = flag == :update || flag == :reshim
|
|
835
869
|
end
|
|
836
|
-
|
|
870
|
+
success?(run(banner: banner, from: :"asdf:#{flag}"), flag == :set || flag == :reshim)
|
|
837
871
|
end
|
|
838
872
|
|
|
839
873
|
def first(key, *args, **kwargs, &blk)
|
|
@@ -873,28 +907,27 @@ module Squared
|
|
|
873
907
|
instance_variable_set :"@#{key}", [blk]
|
|
874
908
|
end
|
|
875
909
|
else
|
|
876
|
-
log&.warn "series: @#{key}
|
|
910
|
+
log&.warn "series: @#{key}".subhint('invalid')
|
|
877
911
|
end
|
|
878
912
|
self
|
|
879
913
|
end
|
|
880
914
|
|
|
881
|
-
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,
|
|
882
916
|
interactive: nil, hint: nil, series: true, **)
|
|
883
|
-
unless cmd
|
|
884
|
-
|
|
885
|
-
return
|
|
886
|
-
end
|
|
917
|
+
return print_error('no command session started', subject: project, hint: from, pass: true) unless cmd
|
|
918
|
+
|
|
887
919
|
cmd = cmd.target if cmd.is_a?(OptionPartition)
|
|
888
|
-
if interactive && (!@session || !option('y'))
|
|
889
|
-
title, y = case interactive
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
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)
|
|
898
931
|
end
|
|
899
932
|
cmd = session_done cmd
|
|
900
933
|
log&.info cmd
|
|
@@ -904,7 +937,7 @@ module Squared
|
|
|
904
937
|
log&.warn "ENV discarded: #{var}" if var
|
|
905
938
|
task_invoke(cmd, exception: exception, warning: warning?)
|
|
906
939
|
else
|
|
907
|
-
print_item(format_banner(
|
|
940
|
+
print_item(format_banner(cmd, banner: banner, hint: hint), series: series) if sync
|
|
908
941
|
if var != false && (pre = runenv)
|
|
909
942
|
case pre
|
|
910
943
|
when Hash
|
|
@@ -936,14 +969,7 @@ module Squared
|
|
|
936
969
|
args = block_args args, &blk
|
|
937
970
|
end
|
|
938
971
|
if variables.include?(key) || blocks.include?(key)
|
|
939
|
-
val =
|
|
940
|
-
when 0
|
|
941
|
-
nil
|
|
942
|
-
when 1
|
|
943
|
-
args.first
|
|
944
|
-
else
|
|
945
|
-
args
|
|
946
|
-
end
|
|
972
|
+
val = args.size > 1 ? args : args.first
|
|
947
973
|
case key
|
|
948
974
|
when :index
|
|
949
975
|
index_set val
|
|
@@ -973,7 +999,7 @@ module Squared
|
|
|
973
999
|
instance_variable_set(:"@#{key}", val)
|
|
974
1000
|
end
|
|
975
1001
|
else
|
|
976
|
-
log&.warn "variable_set: @#{key}
|
|
1002
|
+
log&.warn "variable_set: @#{key}".subhint('private')
|
|
977
1003
|
end
|
|
978
1004
|
self
|
|
979
1005
|
end
|
|
@@ -996,6 +1022,10 @@ module Squared
|
|
|
996
1022
|
@ref.include?(val)
|
|
997
1023
|
end
|
|
998
1024
|
|
|
1025
|
+
def exist?(*args)
|
|
1026
|
+
basepath(*args).exist?
|
|
1027
|
+
end
|
|
1028
|
+
|
|
999
1029
|
def build?
|
|
1000
1030
|
!!@output[0] || script? || series?(@run)
|
|
1001
1031
|
end
|
|
@@ -1069,14 +1099,18 @@ module Squared
|
|
|
1069
1099
|
@dependindex ? @dependindex.succ : 0
|
|
1070
1100
|
end
|
|
1071
1101
|
|
|
1102
|
+
def dependname
|
|
1103
|
+
@dependname ||= dependfile&.basename.to_s
|
|
1104
|
+
end
|
|
1105
|
+
|
|
1072
1106
|
def log
|
|
1073
1107
|
return @log unless @log.is_a?(Array)
|
|
1074
1108
|
|
|
1075
|
-
@log = Logger.new(
|
|
1109
|
+
@log = Logger.new((@log.first if enabled?), **@log.last)
|
|
1076
1110
|
end
|
|
1077
1111
|
|
|
1078
|
-
def allref
|
|
1079
|
-
@ref.reverse_each
|
|
1112
|
+
def allref
|
|
1113
|
+
@ref.reverse_each
|
|
1080
1114
|
end
|
|
1081
1115
|
|
|
1082
1116
|
def basepath(*args)
|
|
@@ -1090,7 +1124,7 @@ module Squared
|
|
|
1090
1124
|
path.parent.ascend.each do |dir|
|
|
1091
1125
|
target = dir.join(*args)
|
|
1092
1126
|
return target if target.exist?
|
|
1093
|
-
break if (ascend
|
|
1127
|
+
break if (ascend && dir.join(ascend).exist?) || workspace.root == dir || parent&.path == dir
|
|
1094
1128
|
end
|
|
1095
1129
|
ret
|
|
1096
1130
|
end
|
|
@@ -1099,6 +1133,12 @@ module Squared
|
|
|
1099
1133
|
workspace.task_localname(name)
|
|
1100
1134
|
end
|
|
1101
1135
|
|
|
1136
|
+
def scriptname(from: :run)
|
|
1137
|
+
return unless (name = @output[1]) && respond_to?(:compose)
|
|
1138
|
+
|
|
1139
|
+
as_get name, from
|
|
1140
|
+
end
|
|
1141
|
+
|
|
1102
1142
|
def inspect
|
|
1103
1143
|
"#<#{self.class}: #{name} => #{self}>"
|
|
1104
1144
|
end
|
|
@@ -1117,10 +1157,18 @@ module Squared
|
|
|
1117
1157
|
log_console(*args, pipe: kwargs[:pipe] || pipe)
|
|
1118
1158
|
end
|
|
1119
1159
|
|
|
1120
|
-
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
|
|
1121
1166
|
on :first, from
|
|
1122
1167
|
begin
|
|
1123
|
-
cmd.
|
|
1168
|
+
cmd.each do |val|
|
|
1169
|
+
print_run val, banner
|
|
1170
|
+
run(val, var, sync: sync, banner: banner, **kwargs)
|
|
1171
|
+
end
|
|
1124
1172
|
rescue StandardError => e
|
|
1125
1173
|
ret = on :error, from, e
|
|
1126
1174
|
raise unless ret == true
|
|
@@ -1137,7 +1185,12 @@ module Squared
|
|
|
1137
1185
|
when Proc
|
|
1138
1186
|
instance_eval(&obj)
|
|
1139
1187
|
when Method
|
|
1140
|
-
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)
|
|
1141
1194
|
else
|
|
1142
1195
|
if series?(obj)
|
|
1143
1196
|
obj.each(&:call)
|
|
@@ -1153,7 +1206,6 @@ module Squared
|
|
|
1153
1206
|
single: false, last: false, context: nil)
|
|
1154
1207
|
tag = ->(proj) { "#{proj.name}#{SEM_VER.match?(proj.version) ? "@#{proj.version}" : ''}" }
|
|
1155
1208
|
script = ->(proj) { workspace.script_get(:graph, group: proj.group, ref: proj.allref)&.fetch(:graph, nil) }
|
|
1156
|
-
check = ->(deps) { deps.reject { |val| done.include?(val) } }
|
|
1157
1209
|
dedupe = lambda do |name|
|
|
1158
1210
|
next [] unless (ret = data[name])
|
|
1159
1211
|
|
|
@@ -1164,12 +1216,11 @@ module Squared
|
|
|
1164
1216
|
end
|
|
1165
1217
|
ret
|
|
1166
1218
|
end
|
|
1167
|
-
start = target.name
|
|
1168
1219
|
if depth == 0
|
|
1169
|
-
items =
|
|
1220
|
+
items = dedupe.call(target.name) - done
|
|
1170
1221
|
single = items.size == 1
|
|
1171
1222
|
else
|
|
1172
|
-
items =
|
|
1223
|
+
items = data[target.name] - done
|
|
1173
1224
|
end
|
|
1174
1225
|
if out
|
|
1175
1226
|
a, b, c, d, e = ARG[:GRAPH]
|
|
@@ -1184,21 +1235,21 @@ module Squared
|
|
|
1184
1235
|
"#{last ? d : c}#{b * 3}#{e} #{f}"
|
|
1185
1236
|
end
|
|
1186
1237
|
else
|
|
1187
|
-
"#{single ? ' ' : a}#{' ' *
|
|
1238
|
+
"#{single ? ' ' : a}#{' ' * depth.pred}#{last ? d : c}#{b * 3}#{items.empty? ? b : e} #{f}"
|
|
1188
1239
|
end
|
|
1189
1240
|
end
|
|
1190
1241
|
items.each_with_index do |proj, i|
|
|
1191
1242
|
next if done.include?(proj)
|
|
1192
1243
|
|
|
1193
|
-
t = dedupe.call(proj.name)
|
|
1244
|
+
t = dedupe.call(name = proj.name)
|
|
1194
1245
|
j = if out
|
|
1195
|
-
if i == items.size
|
|
1246
|
+
if i == items.size.pred || (post = items[i.succ..-1] - done).empty?
|
|
1196
1247
|
true
|
|
1197
1248
|
elsif !t.empty? && depth > 0
|
|
1198
|
-
post
|
|
1249
|
+
(post - t).empty?
|
|
1199
1250
|
end
|
|
1200
1251
|
end
|
|
1201
|
-
unless
|
|
1252
|
+
unless target.name == name || (none = (t - done).empty?)
|
|
1202
1253
|
graph_branch(proj, data, tasks, out, sync: sync, pass: pass, done: done, depth: depth.succ,
|
|
1203
1254
|
single: single, last: j == true, context: target)
|
|
1204
1255
|
end
|
|
@@ -1206,28 +1257,28 @@ module Squared
|
|
|
1206
1257
|
(tasks || (subtasks = script.call(proj)) || (dev? ? %w[build copy] : %w[depend build])).each do |meth|
|
|
1207
1258
|
next if pass.include?(meth)
|
|
1208
1259
|
|
|
1209
|
-
if workspace.task_defined?(cmd = task_join(
|
|
1210
|
-
if ENV.key?(key = "BANNER_#{
|
|
1260
|
+
if workspace.task_defined?(cmd = task_join(name, meth))
|
|
1261
|
+
if ENV.key?(key = "BANNER_#{name.upcase}")
|
|
1211
1262
|
key = nil
|
|
1212
1263
|
else
|
|
1213
1264
|
ENV[key] = '0'
|
|
1214
1265
|
end
|
|
1215
1266
|
run(cmd, sync: false, banner: false)
|
|
1216
1267
|
ENV.delete(key) if key
|
|
1217
|
-
elsif proj.has?(meth, tasks || subtasks
|
|
1268
|
+
elsif proj.has?(meth, (workspace.baseref unless tasks || subtasks))
|
|
1218
1269
|
proj.__send__(meth.to_sym, sync: sync)
|
|
1219
1270
|
end
|
|
1220
1271
|
end
|
|
1221
1272
|
elsif none
|
|
1222
1273
|
a, b, c, d = ARG[:GRAPH]
|
|
1223
1274
|
out << if depth == 0
|
|
1224
|
-
"#{i == items.size
|
|
1275
|
+
"#{i == items.size.pred ? d : c}#{b * 4} #{tag.call(proj)}"
|
|
1225
1276
|
else
|
|
1226
1277
|
s = ''.dup
|
|
1227
1278
|
k = 0
|
|
1228
1279
|
final = data.keys.last
|
|
1229
1280
|
while k < depth
|
|
1230
|
-
indent = k > 0 ? ((last && !j) || (j && k == depth
|
|
1281
|
+
indent = k > 0 ? ((last && !j) || (j && k == depth.pred) || single) : j && last && depth == 1
|
|
1231
1282
|
s += "#{indent || (last && data[final].last == context) ? ' ' : a} "
|
|
1232
1283
|
k += 1
|
|
1233
1284
|
end
|
|
@@ -1245,22 +1296,19 @@ module Squared
|
|
|
1245
1296
|
next if pass.include?(val)
|
|
1246
1297
|
|
|
1247
1298
|
if (obj = workspace.find(name: val))
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
items = [obj]
|
|
1299
|
+
obj.enabled? ? [obj] : []
|
|
1251
1300
|
else
|
|
1252
|
-
|
|
1253
|
-
end
|
|
1254
|
-
items.each do |proj|
|
|
1301
|
+
workspace.find(group: val, ref: val.to_sym)
|
|
1302
|
+
end.each do |proj|
|
|
1255
1303
|
next if pass.include?(name = proj.name)
|
|
1256
1304
|
|
|
1257
1305
|
if proj.graph? && !data.key?(name) && !root.include?(name)
|
|
1258
1306
|
graph_collect(proj, data: data, pass: pass, root: root + [name, target.name])
|
|
1259
1307
|
end
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1308
|
+
unless (objs = data.fetch(name, [])).include?(target)
|
|
1309
|
+
deps << proj
|
|
1310
|
+
deps.concat(objs)
|
|
1311
|
+
end
|
|
1264
1312
|
end
|
|
1265
1313
|
end
|
|
1266
1314
|
deps.uniq!
|
|
@@ -1286,44 +1334,96 @@ module Squared
|
|
|
1286
1334
|
end
|
|
1287
1335
|
|
|
1288
1336
|
def env(key, default = nil, suffix: nil, equals: nil, ignore: nil, strict: false)
|
|
1289
|
-
|
|
1337
|
+
name = "#{key}_#{@envname}"
|
|
1290
1338
|
ret = if suffix
|
|
1291
|
-
ENV.fetch("#{
|
|
1339
|
+
ENV.fetch("#{name}_#{suffix}", '')
|
|
1292
1340
|
elsif strict
|
|
1293
|
-
ENV[
|
|
1341
|
+
ENV[name].to_s
|
|
1294
1342
|
else
|
|
1295
1343
|
ignore = ['0'].freeze if ignore.nil?
|
|
1296
|
-
ENV[
|
|
1344
|
+
ENV[name] || ENV.fetch(key, '')
|
|
1297
1345
|
end
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
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
|
|
1301
1352
|
end
|
|
1302
1353
|
|
|
1303
1354
|
def session(*cmd, prefix: cmd.first, main: true, path: true, options: true)
|
|
1304
|
-
prefix =
|
|
1355
|
+
prefix = prefix.to_s.stripext
|
|
1305
1356
|
if path && (val = shell_bin(prefix))
|
|
1306
1357
|
cmd[0] = shell_quote(val, force: false)
|
|
1307
1358
|
end
|
|
1308
1359
|
ret = JoinSet.new(cmd.flatten(1))
|
|
1309
|
-
if options
|
|
1310
|
-
|
|
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
|
|
1311
1368
|
end
|
|
1312
1369
|
main ? @session = ret : ret
|
|
1313
1370
|
end
|
|
1314
1371
|
|
|
1315
|
-
def session_delete(*args, target: @session)
|
|
1316
|
-
OptionPartition.delete(target, *args)
|
|
1317
|
-
end
|
|
1318
|
-
|
|
1319
1372
|
def session_output(*cmd, **kwargs)
|
|
1320
1373
|
session(*cmd, main: false, options: false, **kwargs)
|
|
1321
1374
|
end
|
|
1322
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
|
+
|
|
1323
1423
|
def session_done(cmd)
|
|
1324
|
-
return cmd unless cmd.respond_to?(:done)
|
|
1424
|
+
return cmd.to_s unless cmd.respond_to?(:done)
|
|
1325
1425
|
|
|
1326
|
-
raise_error
|
|
1426
|
+
raise_error 'no command added', hint: cmd.first unless cmd.size > 1
|
|
1327
1427
|
@session = nil if cmd == @session
|
|
1328
1428
|
cmd.done
|
|
1329
1429
|
end
|
|
@@ -1338,33 +1438,40 @@ module Squared
|
|
|
1338
1438
|
return unless prefix
|
|
1339
1439
|
|
|
1340
1440
|
args.each do |val|
|
|
1341
|
-
next unless (ret = env(env_key(stripext
|
|
1441
|
+
next unless (ret = env(env_key(prefix.to_s.stripext, val), **kwargs))
|
|
1342
1442
|
|
|
1343
1443
|
return block_given? ? yield(ret) : ret
|
|
1344
1444
|
end
|
|
1345
1445
|
nil
|
|
1346
1446
|
end
|
|
1347
1447
|
|
|
1348
|
-
def option_clear(opts, target: @session, **kwargs)
|
|
1448
|
+
def option_clear(opts, empty = true, target: @session, **kwargs)
|
|
1349
1449
|
return unless target
|
|
1350
1450
|
|
|
1351
1451
|
OptionPartition.clear(target, opts, styles: theme[:inline], **kwargs)
|
|
1452
|
+
opts.clear if empty
|
|
1453
|
+
nil
|
|
1352
1454
|
end
|
|
1353
1455
|
|
|
1354
|
-
def print_success
|
|
1456
|
+
def print_success
|
|
1355
1457
|
puts 'Success'
|
|
1356
1458
|
end
|
|
1357
1459
|
|
|
1358
1460
|
def print_error(*args, loglevel: Logger::WARN, **kwargs)
|
|
1359
|
-
|
|
1461
|
+
warn log_message(loglevel, *args, **kwargs) if warning?
|
|
1462
|
+
end
|
|
1360
1463
|
|
|
1361
|
-
|
|
1464
|
+
def print_run(cmd, banner = true, verbose: nil, **)
|
|
1465
|
+
return if banner || !stdout? || verbose == false
|
|
1466
|
+
|
|
1467
|
+
puts "\n> #{cmd}"
|
|
1468
|
+
printsucc
|
|
1362
1469
|
end
|
|
1363
1470
|
|
|
1364
1471
|
def print_item(*val, series: true)
|
|
1365
1472
|
puts unless printfirst?
|
|
1366
1473
|
printsucc if series
|
|
1367
|
-
puts val unless val.empty? || (val.size == 1 && val.first
|
|
1474
|
+
puts val unless val.empty? || (val.size == 1 && !val.first)
|
|
1368
1475
|
end
|
|
1369
1476
|
|
|
1370
1477
|
def print_banner(*lines, client: false, styles: theme[:banner], border: borderstyle, **)
|
|
@@ -1393,14 +1500,15 @@ module Squared
|
|
|
1393
1500
|
|
|
1394
1501
|
def print_footer(*lines, sub: nil, reverse: false, right: false, border: borderstyle, **)
|
|
1395
1502
|
n = line_width lines
|
|
1503
|
+
sub = as_a sub
|
|
1396
1504
|
lines.map! do |val|
|
|
1397
1505
|
s = right ? val.rjust(n) : val.ljust(n)
|
|
1398
|
-
sub
|
|
1506
|
+
sub.each { |h| s = sub_style(s, **h) }
|
|
1399
1507
|
s
|
|
1400
1508
|
end
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1509
|
+
[sub_style(ARG[:BORDER][1] * n, styles: border)].concat(lines)
|
|
1510
|
+
.tap { |ret| ret.reverse! if reverse }
|
|
1511
|
+
.join("\n")
|
|
1404
1512
|
end
|
|
1405
1513
|
|
|
1406
1514
|
def print_status(*args, from: nil, **kwargs)
|
|
@@ -1409,15 +1517,15 @@ module Squared
|
|
|
1409
1517
|
case from
|
|
1410
1518
|
when :outdated
|
|
1411
1519
|
out = print_footer("major #{args[0]} / minor #{args[1]} / patch #{args[2]}", right: true).split("\n")
|
|
1412
|
-
out[1] = sub_style(out[1],
|
|
1413
|
-
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]
|
|
1414
1523
|
puts out
|
|
1415
1524
|
when :completed
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
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]))
|
|
1421
1529
|
end
|
|
1422
1530
|
end
|
|
1423
1531
|
|
|
@@ -1427,7 +1535,7 @@ module Squared
|
|
|
1427
1535
|
workspace.format_desc([@desc, action, flag].compact, opts, **kwargs)
|
|
1428
1536
|
end
|
|
1429
1537
|
|
|
1430
|
-
def format_banner(cmd, banner: true)
|
|
1538
|
+
def format_banner(cmd, banner: true, hint: nil, strip: nil)
|
|
1431
1539
|
return unless banner && banner?
|
|
1432
1540
|
|
|
1433
1541
|
if (data = workspace.banner_get(*@ref, group: group))
|
|
@@ -1441,11 +1549,14 @@ module Squared
|
|
|
1441
1549
|
out = []
|
|
1442
1550
|
if data.command
|
|
1443
1551
|
if cmd =~ /\A(?:"((?:[^"]|(?<=\\)")+)"|'((?:[^']|(?<=\\)')+)'|(\S+))( |\z)/
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
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)
|
|
1447
1554
|
end
|
|
1448
|
-
|
|
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)
|
|
1449
1560
|
end
|
|
1450
1561
|
data.order.each do |val|
|
|
1451
1562
|
if val.is_a?(Array)
|
|
@@ -1473,7 +1584,7 @@ module Squared
|
|
|
1473
1584
|
end
|
|
1474
1585
|
end
|
|
1475
1586
|
|
|
1476
|
-
def format_list(items, cmd, type, grep: [], from: nil
|
|
1587
|
+
def format_list(items, cmd, type, grep: [], from: nil)
|
|
1477
1588
|
reg = grep.map { |val| Regexp.new(val) }
|
|
1478
1589
|
out = []
|
|
1479
1590
|
unless items.empty?
|
|
@@ -1481,29 +1592,29 @@ module Squared
|
|
|
1481
1592
|
items.each_with_index do |val, i|
|
|
1482
1593
|
next unless matchany?(val.first, reg)
|
|
1483
1594
|
|
|
1484
|
-
out << ('%*d. %s' % [pad, i.succ,
|
|
1595
|
+
out << ('%*d. %s' % [pad, i.succ, block_given? ? yield(val) : val.first])
|
|
1485
1596
|
end
|
|
1486
1597
|
end
|
|
1487
1598
|
sub = [headerstyle]
|
|
1488
|
-
if out.empty?
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
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
|
|
1507
1618
|
emphasize(out, title: task_join(name, cmd), border: borderstyle, sub: sub, footer: footer, right: true)
|
|
1508
1619
|
end
|
|
1509
1620
|
|
|
@@ -1511,14 +1622,13 @@ module Squared
|
|
|
1511
1622
|
"#{msg}#{!always && (!obj || obj == 0 || obj.to_s.empty?) ? '' : message(hint: message(title, obj.to_s))}"
|
|
1512
1623
|
end
|
|
1513
1624
|
|
|
1514
|
-
def append_repeat(flag, opts, target: @session
|
|
1515
|
-
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) }
|
|
1516
1627
|
end
|
|
1517
1628
|
|
|
1518
1629
|
def append_hash(data, target: @session || [], build: false)
|
|
1519
1630
|
if build && (type = env('BUILD', suffix: 'TYPE') || ENV['BUILD_TYPE'])
|
|
1520
|
-
type = "__#{type}__"
|
|
1521
|
-
if (extra = data[type] || data[type.to_sym]).is_a?(Hash)
|
|
1631
|
+
if (extra = data[type = "__#{type}__"] || data[type.to_sym]).is_a?(Hash)
|
|
1522
1632
|
data = data.merge(extra)
|
|
1523
1633
|
else
|
|
1524
1634
|
extra = nil
|
|
@@ -1538,33 +1648,25 @@ module Squared
|
|
|
1538
1648
|
target << basic_option(key, val)
|
|
1539
1649
|
when FalseClass
|
|
1540
1650
|
target << shell_option(key).sub(/^--(?!no-)/, '--no-')
|
|
1541
|
-
when Pathname
|
|
1542
|
-
target << shell_option(key, val, escape: false)
|
|
1543
1651
|
else
|
|
1544
|
-
target << shell_option(key, val.is_a?(String)
|
|
1652
|
+
target << shell_option(key, (val if val.is_a?(String)))
|
|
1545
1653
|
end
|
|
1546
1654
|
end
|
|
1547
1655
|
target
|
|
1548
1656
|
end
|
|
1549
1657
|
|
|
1550
1658
|
def append_any(val, target: @session, build: false, delim: false)
|
|
1551
|
-
return unless val
|
|
1552
|
-
|
|
1553
1659
|
if delim && !target.include?('--')
|
|
1554
1660
|
target << '--'
|
|
1555
1661
|
else
|
|
1556
1662
|
delim = false
|
|
1557
1663
|
end
|
|
1558
|
-
val = shell_split
|
|
1664
|
+
val = shell_split val if val.is_a?(String)
|
|
1559
1665
|
case val
|
|
1560
1666
|
when Hash
|
|
1561
1667
|
append_hash(val, target: target, build: build)
|
|
1562
1668
|
when Enumerable
|
|
1563
|
-
|
|
1564
|
-
target.concat(val.to_a)
|
|
1565
|
-
else
|
|
1566
|
-
target.merge(val.to_a)
|
|
1567
|
-
end
|
|
1669
|
+
merge_list target, val
|
|
1568
1670
|
else
|
|
1569
1671
|
target.delete('--') if delim
|
|
1570
1672
|
nil
|
|
@@ -1585,7 +1687,7 @@ module Squared
|
|
|
1585
1687
|
next unless (val = option(opt, **kwargs))
|
|
1586
1688
|
|
|
1587
1689
|
return target << if flag
|
|
1588
|
-
shell_option(opt,
|
|
1690
|
+
shell_option(opt, (val if equals), quote: quote, escape: escape, force: force)
|
|
1589
1691
|
else
|
|
1590
1692
|
shell_quote val
|
|
1591
1693
|
end
|
|
@@ -1597,25 +1699,44 @@ module Squared
|
|
|
1597
1699
|
**kwargs)
|
|
1598
1700
|
return if list.empty?
|
|
1599
1701
|
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
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))
|
|
1604
1705
|
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
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)
|
|
1608
1711
|
end
|
|
1609
|
-
|
|
1712
|
+
next if ret.empty?
|
|
1713
|
+
|
|
1714
|
+
merge_list target, ret
|
|
1610
1715
|
end
|
|
1611
|
-
ret.each { |val| target << val } unless ret.empty?
|
|
1612
|
-
ret
|
|
1613
1716
|
end
|
|
1614
1717
|
|
|
1615
1718
|
def append_nocolor(target: @session)
|
|
1616
1719
|
target << '--no-color' if !ARG[:COLOR] || stdin? || option('color', target: target, equals: '0')
|
|
1617
1720
|
end
|
|
1618
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
|
+
|
|
1619
1740
|
def merge_opts(base, data)
|
|
1620
1741
|
case data
|
|
1621
1742
|
when String
|
|
@@ -1656,6 +1777,18 @@ module Squared
|
|
|
1656
1777
|
end
|
|
1657
1778
|
end
|
|
1658
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
|
+
|
|
1659
1792
|
def collect_hash(data, pass: [])
|
|
1660
1793
|
ret = []
|
|
1661
1794
|
data.each { |key, val| ret.concat(val) unless pass.include?(key) }
|
|
@@ -1664,12 +1797,11 @@ module Squared
|
|
|
1664
1797
|
|
|
1665
1798
|
def parse_json(val, kind: Hash, hint: nil)
|
|
1666
1799
|
ret = JSON.parse(val)
|
|
1667
|
-
raise_error
|
|
1800
|
+
raise_error 'invalid JSON'.subhint(kind.name), val, hint: hint if kind && !ret.is_a?(kind)
|
|
1801
|
+
ret
|
|
1668
1802
|
rescue StandardError => e
|
|
1669
1803
|
log&.warn e
|
|
1670
1804
|
print_error(e, subject: name)
|
|
1671
|
-
else
|
|
1672
|
-
ret
|
|
1673
1805
|
end
|
|
1674
1806
|
|
|
1675
1807
|
def param_guard(action, flag, args:, key: nil, pat: nil, values: nil)
|
|
@@ -1681,12 +1813,16 @@ module Squared
|
|
|
1681
1813
|
raise_error(action, "#{flag}[#{key}]", hint: val.nil? ? 'missing' : 'invalid')
|
|
1682
1814
|
elsif args.is_a?(Array) && args.empty?
|
|
1683
1815
|
@session = nil
|
|
1684
|
-
raise_error
|
|
1816
|
+
raise_error action, "#{flag}+", hint: 'empty'
|
|
1685
1817
|
end
|
|
1686
1818
|
args
|
|
1687
1819
|
end
|
|
1688
1820
|
|
|
1689
|
-
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)
|
|
1690
1826
|
a = sub_style(case rev
|
|
1691
1827
|
when 1
|
|
1692
1828
|
'MAJOR'
|
|
@@ -1698,16 +1834,17 @@ module Squared
|
|
|
1698
1834
|
b = sub_style(pkg.ljust(col1), styles: theme[:inline])
|
|
1699
1835
|
c = lock ? sub_style((cur || 'locked').rjust(7), styles: color(:red)) : cur&.rjust(7)
|
|
1700
1836
|
d = rev == 1 || lock ? 'N' : 'Y'
|
|
1701
|
-
confirm
|
|
1837
|
+
confirm("#{a}: #{b}#{c} #{sub_style(ver.rjust(col1 > 0 ? 10 : 0), styles: theme[:inline])} ", d, **kwargs)
|
|
1702
1838
|
end
|
|
1703
1839
|
|
|
1704
1840
|
def choice_index(msg, list, values: nil, accept: nil, series: false, trim: nil, column: nil, multiple: false,
|
|
1705
1841
|
force: true, **kwargs)
|
|
1706
|
-
puts
|
|
1707
|
-
|
|
1708
|
-
|
|
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
|
+
|
|
1709
1846
|
exit 1 if force
|
|
1710
|
-
return
|
|
1847
|
+
return nil
|
|
1711
1848
|
end
|
|
1712
1849
|
ret = multiple ? ret.map! { |val| val.sub(trim, '') } : ret.sub(trim, '') if trim
|
|
1713
1850
|
if column
|
|
@@ -1721,7 +1858,7 @@ module Squared
|
|
|
1721
1858
|
ret = Array(ret) if accept.any? { |val| val[1] == true }
|
|
1722
1859
|
loop do
|
|
1723
1860
|
item = accept.first
|
|
1724
|
-
c = confirm("#{item[0]}#{hint ? " [#{hint}]" : ''}", item[2] ? 'Y' : 'N'
|
|
1861
|
+
c = confirm("#{item[0]}#{hint ? " [#{hint}]" : ''}", item[2] ? 'Y' : 'N')
|
|
1725
1862
|
if item[1] == true
|
|
1726
1863
|
ret << c
|
|
1727
1864
|
elsif !c
|
|
@@ -1742,25 +1879,29 @@ module Squared
|
|
|
1742
1879
|
force = false
|
|
1743
1880
|
end
|
|
1744
1881
|
val = readline(val, force: force)
|
|
1745
|
-
ret << (val.empty?
|
|
1882
|
+
ret << (val unless val.empty?)
|
|
1746
1883
|
end
|
|
1747
1884
|
end
|
|
1748
1885
|
printsucc unless series
|
|
1749
1886
|
ret
|
|
1750
1887
|
end
|
|
1751
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
|
+
|
|
1752
1897
|
def command_args(args, min: 0, force: false, **kwargs)
|
|
1753
1898
|
return if args.size > min || option('i', 'interactive', **kwargs, equals: '0')
|
|
1754
1899
|
|
|
1755
1900
|
readline('Enter arguments', force: force)
|
|
1756
1901
|
end
|
|
1757
1902
|
|
|
1758
|
-
def block_args(
|
|
1759
|
-
|
|
1760
|
-
val
|
|
1761
|
-
else
|
|
1762
|
-
Array(ret)
|
|
1763
|
-
end
|
|
1903
|
+
def block_args(fallback = nil, &blk)
|
|
1904
|
+
(ret = instance_eval(&blk)).nil? ? fallback : Array(ret)
|
|
1764
1905
|
end
|
|
1765
1906
|
|
|
1766
1907
|
def runenv
|
|
@@ -1770,7 +1911,7 @@ module Squared
|
|
|
1770
1911
|
def command(*args)
|
|
1771
1912
|
return args.join(' && ') unless workspace.powershell?
|
|
1772
1913
|
|
|
1773
|
-
"
|
|
1914
|
+
"powershell.exe -Command #{shell_quote("& {#{args.join(' ; ')}}", option: false, double: true)}"
|
|
1774
1915
|
end
|
|
1775
1916
|
|
|
1776
1917
|
def relativepath(*list, all: false)
|
|
@@ -1793,12 +1934,10 @@ module Squared
|
|
|
1793
1934
|
|
|
1794
1935
|
def matchmap(list, prefix = nil)
|
|
1795
1936
|
list.map do |val|
|
|
1796
|
-
if val.is_a?(Regexp)
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
Regexp.new("#{prefix}#{val == '*' ? '.+' : val}")
|
|
1801
|
-
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}")
|
|
1802
1941
|
end
|
|
1803
1942
|
end
|
|
1804
1943
|
|
|
@@ -1815,7 +1954,8 @@ module Squared
|
|
|
1815
1954
|
end
|
|
1816
1955
|
|
|
1817
1956
|
def semscan(val, fill: true)
|
|
1818
|
-
val.scan(SEM_VER).first
|
|
1957
|
+
ret = val.scan(SEM_VER).first
|
|
1958
|
+
fill ? semver(ret) : ret
|
|
1819
1959
|
end
|
|
1820
1960
|
|
|
1821
1961
|
def semcmp(val, other)
|
|
@@ -1831,14 +1971,38 @@ module Squared
|
|
|
1831
1971
|
end
|
|
1832
1972
|
[c[0], c[2], c[4] || '0', d]
|
|
1833
1973
|
end
|
|
1834
|
-
a.each_with_index do |c,
|
|
1835
|
-
next if c == (d = b[
|
|
1974
|
+
a.each_with_index do |c, i|
|
|
1975
|
+
next if c == (d = b[i])
|
|
1836
1976
|
|
|
1837
1977
|
return c.to_i < d.to_i ? 1 : -1
|
|
1838
1978
|
end
|
|
1839
1979
|
0
|
|
1840
1980
|
end
|
|
1841
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
|
+
|
|
1842
2006
|
def semgte?(val, other)
|
|
1843
2007
|
semcmp(val, other) != 1
|
|
1844
2008
|
end
|
|
@@ -1848,7 +2012,7 @@ module Squared
|
|
|
1848
2012
|
end
|
|
1849
2013
|
|
|
1850
2014
|
def indexerror(val, list = nil)
|
|
1851
|
-
raise_error
|
|
2015
|
+
raise_error IndexError, "requested index #{val}", hint: list && "of #{list.size}"
|
|
1852
2016
|
end
|
|
1853
2017
|
|
|
1854
2018
|
def indexchar
|
|
@@ -1867,10 +2031,6 @@ module Squared
|
|
|
1867
2031
|
val.compact.flat_map { |s| color(s) }
|
|
1868
2032
|
end
|
|
1869
2033
|
|
|
1870
|
-
def epochtime
|
|
1871
|
-
Time.now.strftime('%s%L').to_i
|
|
1872
|
-
end
|
|
1873
|
-
|
|
1874
2034
|
def verbosetype
|
|
1875
2035
|
case verbose
|
|
1876
2036
|
when TrueClass
|
|
@@ -1902,7 +2062,7 @@ module Squared
|
|
|
1902
2062
|
end
|
|
1903
2063
|
end
|
|
1904
2064
|
|
|
1905
|
-
def on_error(err, from, exception: self.exception,
|
|
2065
|
+
def on_error(err, from, pass: false, exception: self.exception, dryrun: false)
|
|
1906
2066
|
log&.error err
|
|
1907
2067
|
unless dryrun
|
|
1908
2068
|
ret = on :error, from, err
|
|
@@ -1911,19 +2071,17 @@ module Squared
|
|
|
1911
2071
|
print_error(err, pass: pass) unless ret
|
|
1912
2072
|
end
|
|
1913
2073
|
|
|
1914
|
-
def pwd_set(pass: false, dryrun: false, from: nil)
|
|
1915
|
-
return yield if (path.to_s == Dir.pwd || pass == true) && (workspace.mri? || !workspace.windows?)
|
|
1916
|
-
|
|
2074
|
+
def pwd_set(pass: false, exception: self.exception, dryrun: false, from: nil)
|
|
1917
2075
|
pwd = Dir.pwd
|
|
1918
|
-
|
|
1919
|
-
|
|
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 }
|
|
1920
2080
|
rescue StandardError => e
|
|
1921
|
-
on_error(e, from, dryrun: dryrun)
|
|
1922
|
-
ensure
|
|
1923
|
-
Dir.chdir(pwd) if pwd
|
|
2081
|
+
on_error(e, from, exception: exception, dryrun: dryrun)
|
|
1924
2082
|
end
|
|
1925
2083
|
|
|
1926
|
-
def run_set(cmd, val = nil, opts: nil, **)
|
|
2084
|
+
def run_set(cmd, val = nil, opts: nil, global: false, **)
|
|
1927
2085
|
noopt = @output[1] == false && !@output[0].nil?
|
|
1928
2086
|
noenv = @output[2] == false
|
|
1929
2087
|
parse = lambda do |data|
|
|
@@ -1942,6 +2100,7 @@ module Squared
|
|
|
1942
2100
|
ret[2] = data[:env] unless dise
|
|
1943
2101
|
ret
|
|
1944
2102
|
end
|
|
2103
|
+
self.global = global
|
|
1945
2104
|
case cmd
|
|
1946
2105
|
when Array
|
|
1947
2106
|
@output = if cmd.all? { |data| data.is_a?(Hash) }
|
|
@@ -1973,11 +2132,12 @@ module Squared
|
|
|
1973
2132
|
end
|
|
1974
2133
|
end
|
|
1975
2134
|
|
|
1976
|
-
def script_set(cmd, prod: nil, args: nil, **)
|
|
2135
|
+
def script_set(cmd, prod: nil, args: nil, global: false, **)
|
|
1977
2136
|
return if @output[1] == false && @output[0].nil?
|
|
1978
2137
|
|
|
2138
|
+
self.global = global
|
|
1979
2139
|
@output[0] = nil
|
|
1980
|
-
@output[1] = if
|
|
2140
|
+
@output[1] = if self.global && cmd.is_a?(Array)
|
|
1981
2141
|
cmd[prod == true ? 1 : 0]
|
|
1982
2142
|
else
|
|
1983
2143
|
cmd
|
|
@@ -2022,7 +2182,7 @@ module Squared
|
|
|
2022
2182
|
|
|
2023
2183
|
def asdf_set(val)
|
|
2024
2184
|
@asdf = if @@asdf && val
|
|
2025
|
-
dir = @@asdf
|
|
2185
|
+
dir = @@asdf.path.join('installs', val)
|
|
2026
2186
|
[val, dir] if dir.exist? && !dir.empty?
|
|
2027
2187
|
end
|
|
2028
2188
|
end
|
|
@@ -2038,9 +2198,12 @@ module Squared
|
|
|
2038
2198
|
end
|
|
2039
2199
|
|
|
2040
2200
|
def dependfile_set(list)
|
|
2041
|
-
@dependindex =
|
|
2042
|
-
|
|
2043
|
-
|
|
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
|
|
2044
2207
|
end
|
|
2045
2208
|
|
|
2046
2209
|
def as_get(val, from)
|
|
@@ -2082,12 +2245,10 @@ module Squared
|
|
|
2082
2245
|
end
|
|
2083
2246
|
|
|
2084
2247
|
def checkdir?(val)
|
|
2085
|
-
if val.directory? && !val.empty?
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
false
|
|
2090
|
-
end
|
|
2248
|
+
return true if val.directory? && !val.empty?
|
|
2249
|
+
|
|
2250
|
+
log&.warn "directory \"#{val}\"".subhint(val.directory? ? 'empty' : 'missing')
|
|
2251
|
+
false
|
|
2091
2252
|
end
|
|
2092
2253
|
|
|
2093
2254
|
def semmajor?(cur, want)
|
|
@@ -2100,7 +2261,7 @@ module Squared
|
|
|
2100
2261
|
|
|
2101
2262
|
def runnable?(val)
|
|
2102
2263
|
case val
|
|
2103
|
-
when String, Enumerable, Proc, Method
|
|
2264
|
+
when String, Enumerable, Proc, Method
|
|
2104
2265
|
true
|
|
2105
2266
|
else
|
|
2106
2267
|
false
|
|
@@ -2127,14 +2288,24 @@ module Squared
|
|
|
2127
2288
|
return true if val || from_sync?(ac = workspace.task_name(action))
|
|
2128
2289
|
return val if group && !(val = from_sync?(ac, group)).nil?
|
|
2129
2290
|
return val if (base = workspace.find_base(self)) && !(val = from_sync?(ac, base.ref)).nil?
|
|
2130
|
-
return false if workspace.series.chain?(
|
|
2131
|
-
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'))
|
|
2132
2293
|
|
|
2133
|
-
workspace.series.name_get(action)
|
|
2294
|
+
ret = workspace.series.name_get(action)
|
|
2295
|
+
ret != action && invoked_sync?(ret)
|
|
2134
2296
|
end
|
|
2135
2297
|
|
|
2136
|
-
def success?(
|
|
2137
|
-
|
|
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
|
|
2138
2309
|
end
|
|
2139
2310
|
|
|
2140
2311
|
def banner?
|
|
@@ -2161,10 +2332,16 @@ module Squared
|
|
|
2161
2332
|
workspace.warning
|
|
2162
2333
|
end
|
|
2163
2334
|
|
|
2164
|
-
def has_value?(
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
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
|
|
2168
2345
|
end
|
|
2169
2346
|
|
|
2170
2347
|
def variables
|
|
@@ -2175,28 +2352,16 @@ module Squared
|
|
|
2175
2352
|
BLK_SET
|
|
2176
2353
|
end
|
|
2177
2354
|
|
|
2178
|
-
def hashobj
|
|
2179
|
-
Workspace::Support.hashobj
|
|
2180
|
-
end
|
|
2181
|
-
|
|
2182
|
-
def hashlist
|
|
2183
|
-
Workspace::Support.hashlist
|
|
2184
|
-
end
|
|
2185
|
-
|
|
2186
|
-
def hashdup
|
|
2187
|
-
Workspace::Support.hashdup
|
|
2188
|
-
end
|
|
2189
|
-
|
|
2190
2355
|
def borderstyle
|
|
2191
2356
|
workspace.banner_get(*@ref, group: group)&.border || theme[:border]
|
|
2192
2357
|
end
|
|
2193
2358
|
|
|
2194
2359
|
def headerstyle
|
|
2195
|
-
|
|
2360
|
+
opt_style theme[:header], /^(\S+)(\s+)$/
|
|
2196
2361
|
end
|
|
2197
2362
|
|
|
2198
2363
|
def scriptargs
|
|
2199
|
-
{ 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 }
|
|
2200
2365
|
end
|
|
2201
2366
|
end
|
|
2202
2367
|
|