squared 0.6.9 → 0.7.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 +74 -2
- data/README.md +239 -200
- data/lib/squared/common/format.rb +7 -10
- data/lib/squared/common/prompt.rb +23 -24
- data/lib/squared/common/shell.rb +16 -17
- data/lib/squared/common/system.rb +29 -20
- data/lib/squared/common/utils.rb +43 -54
- data/lib/squared/config.rb +17 -16
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +290 -175
- data/lib/squared/workspace/project/base.rb +542 -442
- data/lib/squared/workspace/project/docker.rb +151 -131
- data/lib/squared/workspace/project/git.rb +178 -144
- data/lib/squared/workspace/project/node.rb +89 -87
- data/lib/squared/workspace/project/python.rb +236 -139
- data/lib/squared/workspace/project/ruby.rb +395 -281
- data/lib/squared/workspace/project/support/class.rb +12 -6
- data/lib/squared/workspace/project/support/optionpartition.rb +58 -41
- data/lib/squared/workspace/project/support/utils.rb +68 -0
- data/lib/squared/workspace/project.rb +0 -7
- data/lib/squared/workspace/repo.rb +234 -169
- data/lib/squared/workspace/series.rb +91 -86
- data/lib/squared/workspace/support/base.rb +15 -1
- metadata +2 -1
|
@@ -4,6 +4,7 @@ require 'json'
|
|
|
4
4
|
require 'logger'
|
|
5
5
|
|
|
6
6
|
require_relative 'support/class'
|
|
7
|
+
require_relative 'support/utils'
|
|
7
8
|
|
|
8
9
|
module Squared
|
|
9
10
|
module Workspace
|
|
@@ -16,12 +17,13 @@ module Squared
|
|
|
16
17
|
include Prompt
|
|
17
18
|
include Utils
|
|
18
19
|
include Support
|
|
20
|
+
include Support::Utils
|
|
19
21
|
include Workspace::Support::Variables
|
|
20
22
|
include Rake::DSL
|
|
21
23
|
|
|
22
24
|
OPTIONS = Workspace::Support.hashobj
|
|
23
25
|
VAR_SET = %i[parent global script index envname desc dependfile dependname dependindex theme archive env graph
|
|
24
|
-
dev prod pass only exclude asdf].freeze
|
|
26
|
+
dev prod timeout pass only exclude asdf].freeze
|
|
25
27
|
BLK_SET = %i[run depend doc lint test copy clean].freeze
|
|
26
28
|
SEM_VER = /\b(\d+)(?:(\.)(\d+))?(?:(\.)(\d+))?[-.]?(\S+)?\b/.freeze
|
|
27
29
|
URI_SCHEME = %r{\A([a-z][a-z\d+-.]*)://[^@:\[\]\\^<>|\s]}i.freeze
|
|
@@ -99,33 +101,35 @@ module Squared
|
|
|
99
101
|
|
|
100
102
|
@@tasks = {}
|
|
101
103
|
@@graph = { _: [] }
|
|
102
|
-
@@asdf = Pathname.new("#{Dir.home}/.asdf").yield_self do |path|
|
|
104
|
+
@@asdf = Pathname.new(ENV['ASDF_DIR'] || "#{Dir.home}/.asdf").yield_self do |path|
|
|
103
105
|
version = if path.join('asdf.sh').exist?
|
|
104
106
|
15
|
|
105
107
|
elsif ENV['ASDF_DATA_DIR'] && (path = Pathname.new(ENV['ASDF_DATA_DIR'])).exist?
|
|
106
108
|
16
|
|
107
109
|
end
|
|
108
|
-
|
|
110
|
+
if version
|
|
111
|
+
config = ENV['ASDF_CONFIG_FILE'] || File.join(Dir.home, '.asdfrc')
|
|
112
|
+
Struct.new(:path, :version, :config).new(path, version, config)
|
|
113
|
+
end
|
|
109
114
|
end
|
|
110
115
|
@@print_order = 0
|
|
111
116
|
|
|
112
117
|
subtasks({
|
|
113
118
|
'graph' => %i[run print].freeze,
|
|
114
119
|
'unpack' => %i[zip gz tar ext],
|
|
115
|
-
'asdf' => %i[set exec current update latest where reshim]
|
|
120
|
+
'asdf' => %i[set exec env current update latest where reshim]
|
|
116
121
|
})
|
|
117
122
|
|
|
118
123
|
attr_reader :name, :workspace, :path, :theme, :group, :parent, :children, :dependfile,
|
|
119
|
-
:exception, :pipe, :verbose
|
|
124
|
+
:exception, :pipe, :verbose
|
|
120
125
|
attr_accessor :project
|
|
121
126
|
|
|
122
|
-
def initialize(workspace, path, name, *,
|
|
123
|
-
**kwargs)
|
|
127
|
+
def initialize(workspace, path, name, *, first: {}, last: {}, error: {}, common: ARG[:COMMON], **kwargs)
|
|
124
128
|
@path = path
|
|
125
129
|
@workspace = workspace
|
|
126
130
|
@name = name.to_s.freeze
|
|
127
131
|
@project = @path.basename.to_s.freeze
|
|
128
|
-
@group = group&.to_s.freeze
|
|
132
|
+
@group = kwargs[:group]&.to_s.freeze
|
|
129
133
|
@envname = env_key(@name).freeze
|
|
130
134
|
@depend = kwargs[:depend]
|
|
131
135
|
@doc = kwargs[:doc]
|
|
@@ -143,22 +147,28 @@ module Squared
|
|
|
143
147
|
else
|
|
144
148
|
val.nil? ? workspace.verbose : val
|
|
145
149
|
end
|
|
146
|
-
|
|
150
|
+
@global = 0
|
|
147
151
|
@output = []
|
|
148
152
|
@ref = []
|
|
149
153
|
@children = []
|
|
150
|
-
@events = hashobj.update({ first: first, last: last, error: error })
|
|
151
154
|
@as = hashobj
|
|
152
155
|
@desc = (@name.include?(':') ? @name.split(':').join(ARG[:SPACE]) : @name).freeze
|
|
156
|
+
@on = {
|
|
157
|
+
event: hashobj.update({ first: first, last: last, error: error }),
|
|
158
|
+
from: []
|
|
159
|
+
}
|
|
160
|
+
@timeout = { _: [{}.compare_by_identity, nil, 0] }
|
|
153
161
|
@log = nil
|
|
154
162
|
@dev = nil
|
|
155
163
|
@prod = nil
|
|
156
164
|
@withargs = nil
|
|
157
165
|
@session = nil
|
|
158
166
|
@index = -1
|
|
167
|
+
@initargs = kwargs.freeze
|
|
159
168
|
parent_set kwargs[:parent]
|
|
160
169
|
run_set(kwargs[:run], kwargs[:env], opts: kwargs.fetch(:opts, true))
|
|
161
170
|
graph_set kwargs[:graph]
|
|
171
|
+
timeout_set kwargs[:timeout]
|
|
162
172
|
pass_set kwargs[:pass]
|
|
163
173
|
only_set kwargs[:only]
|
|
164
174
|
exclude_set kwargs[:exclude]
|
|
@@ -168,117 +178,6 @@ module Squared
|
|
|
168
178
|
initialize_ref Base.ref
|
|
169
179
|
end
|
|
170
180
|
|
|
171
|
-
def initialize_ref(ref)
|
|
172
|
-
@ref << ref unless @exclude.include?(ref)
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
def initialize_build(ref, **kwargs)
|
|
176
|
-
initialize_ref ref
|
|
177
|
-
if (@script = @workspace.script_get(group: @group, ref: ref))
|
|
178
|
-
if @script[:log] && !kwargs.key?(:log)
|
|
179
|
-
kwargs[:log] = @script[:log]
|
|
180
|
-
@log = nil
|
|
181
|
-
end
|
|
182
|
-
@depend = @script[:depend] if @depend.nil?
|
|
183
|
-
@doc = @script[:doc] if @doc.nil?
|
|
184
|
-
@lint = @script[:lint] if @lint.nil?
|
|
185
|
-
@test = @script[:test] if @test.nil?
|
|
186
|
-
@clean = @script[:clean] if @clean.nil?
|
|
187
|
-
@exclude = @script[:exclude] if @exclude.empty? && @script.key?(:exclude)
|
|
188
|
-
end
|
|
189
|
-
initialize_events(ref, **kwargs)
|
|
190
|
-
initialize_logger(**kwargs)
|
|
191
|
-
return if @output[0] == false
|
|
192
|
-
|
|
193
|
-
data = @workspace.script_find(*@ref, @group)
|
|
194
|
-
if @output[0].nil?
|
|
195
|
-
if data[:script]
|
|
196
|
-
unless kwargs[:script] == false
|
|
197
|
-
script_set(data[:script], args: data.fetch(:args, kwargs[:args]), prod: kwargs[:prod], global: true)
|
|
198
|
-
end
|
|
199
|
-
elsif data[:run]
|
|
200
|
-
run_set(data[:run], global: true)
|
|
201
|
-
end
|
|
202
|
-
if kwargs[:script]
|
|
203
|
-
script_set(kwargs[:script], args: kwargs[:args]) unless data[:env][:script]
|
|
204
|
-
elsif @script
|
|
205
|
-
if @script[:script]
|
|
206
|
-
script_set(@script[:script], args: @script.fetch(:args, kwargs[:args])) unless data[:global][:script]
|
|
207
|
-
elsif @script[:run] && !data[:global][:run]
|
|
208
|
-
run_set @script[:run]
|
|
209
|
-
end
|
|
210
|
-
end
|
|
211
|
-
elsif data[:run] && data[:env][:run]
|
|
212
|
-
run_set(data[:run], global: true)
|
|
213
|
-
end
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
def initialize_events(ref, **)
|
|
217
|
-
return unless (events = @workspace.events_get(group: @group, ref: ref))
|
|
218
|
-
|
|
219
|
-
events.each { |task, data| data.each { |ev, blk| @events[ev][task] ||= [blk] } }
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
def initialize_logger(log: nil, **)
|
|
223
|
-
return if @log
|
|
224
|
-
|
|
225
|
-
log = log.is_a?(Hash) ? log.dup : { file: log }
|
|
226
|
-
file = if (val = env('LOG_FILE'))
|
|
227
|
-
Time.now.strftime(val)
|
|
228
|
-
elsif (val = env('LOG_AUTO'))
|
|
229
|
-
require 'date'
|
|
230
|
-
"#{@name}-%s.log" % [case val
|
|
231
|
-
when 'y', 'year'
|
|
232
|
-
Date.today.year
|
|
233
|
-
when 'm', 'month'
|
|
234
|
-
Date.today.strftime('%Y-%m')
|
|
235
|
-
when 'd', 'day', '1'
|
|
236
|
-
Date.today
|
|
237
|
-
else
|
|
238
|
-
val.include?('%') ? Time.now.strftime(val) : Time.now.strftime('%FT%T%:z')
|
|
239
|
-
end]
|
|
240
|
-
elsif (val = log[:file])
|
|
241
|
-
if val.is_a?(String)
|
|
242
|
-
Time.now.strftime(val)
|
|
243
|
-
else
|
|
244
|
-
require 'date'
|
|
245
|
-
"#{@name}-#{Date.today}.log"
|
|
246
|
-
end
|
|
247
|
-
end
|
|
248
|
-
.yield_self do |dir|
|
|
249
|
-
@workspace.home.join(env('LOG_DIR', ''), dir).realdirpath if dir
|
|
250
|
-
rescue StandardError => e
|
|
251
|
-
print_error e
|
|
252
|
-
end
|
|
253
|
-
log[:progname] ||= @name
|
|
254
|
-
env('LOG_LEVEL', ignore: false) { |val| log[:level] = val.start_with?(/\d/) ? log_sym(val.to_i) : val }
|
|
255
|
-
log.delete(:file)
|
|
256
|
-
@log = [file, log]
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
def initialize_env(dev: nil, prod: nil, **)
|
|
260
|
-
@dev = env_match('BUILD', dev, suffix: 'DEV', strict: true)
|
|
261
|
-
@prod = env_match('BUILD', prod, suffix: 'PROD', strict: true)
|
|
262
|
-
env('BUILD', suffix: 'ENV') { |val| @output[2] = val if (val = parse_json(val)) } unless @output[0] == false
|
|
263
|
-
unless @output[0] == false || @output[0].is_a?(Array)
|
|
264
|
-
env('BUILD', suffix: 'OPTS') do |val|
|
|
265
|
-
n = @output[0] ? 1 : 3
|
|
266
|
-
@output[n] = merge_opts(@output[n], shell_split(val))
|
|
267
|
-
end
|
|
268
|
-
env(ref.to_s.upcase, suffix: 'OPTS') { |val| @output[4] = merge_opts(@output[4], shell_split(val)) }
|
|
269
|
-
end
|
|
270
|
-
env('BUILD', suffix: 'VERSION') { |val| self.version = val }
|
|
271
|
-
env('BUILD', strict: true) do |val|
|
|
272
|
-
if val == '0'
|
|
273
|
-
@output = [false]
|
|
274
|
-
elsif script?
|
|
275
|
-
script_set val
|
|
276
|
-
else
|
|
277
|
-
run_set val
|
|
278
|
-
end
|
|
279
|
-
end
|
|
280
|
-
end
|
|
281
|
-
|
|
282
181
|
def ==(other)
|
|
283
182
|
equal?(other)
|
|
284
183
|
end
|
|
@@ -312,10 +211,10 @@ module Squared
|
|
|
312
211
|
-1
|
|
313
212
|
elsif f.any? { |val| e.include?(val) } # rubocop:disable Lint/DuplicateBranch
|
|
314
213
|
1
|
|
315
|
-
elsif @index >= 0 && (i = other.
|
|
214
|
+
elsif @index >= 0 && (i = other.index_get) >= 0
|
|
316
215
|
@index <=> i
|
|
317
216
|
end
|
|
318
|
-
rescue
|
|
217
|
+
rescue => e
|
|
319
218
|
log&.debug e
|
|
320
219
|
nil
|
|
321
220
|
end
|
|
@@ -326,7 +225,7 @@ module Squared
|
|
|
326
225
|
|
|
327
226
|
def exception=(val)
|
|
328
227
|
@exception = case val
|
|
329
|
-
when Numeric,
|
|
228
|
+
when Numeric, true, false
|
|
330
229
|
val
|
|
331
230
|
else
|
|
332
231
|
workspace.exception
|
|
@@ -344,7 +243,7 @@ module Squared
|
|
|
344
243
|
|
|
345
244
|
def verbose=(val)
|
|
346
245
|
@verbose = case val
|
|
347
|
-
when Numeric,
|
|
246
|
+
when Numeric, true, false
|
|
348
247
|
val
|
|
349
248
|
else
|
|
350
249
|
workspace.verbose
|
|
@@ -352,7 +251,17 @@ module Squared
|
|
|
352
251
|
end
|
|
353
252
|
|
|
354
253
|
def global=(val)
|
|
355
|
-
@global
|
|
254
|
+
return if @global == -1
|
|
255
|
+
|
|
256
|
+
@global = if val == 0
|
|
257
|
+
0
|
|
258
|
+
elsif val.nil?
|
|
259
|
+
-1
|
|
260
|
+
elsif val < 0
|
|
261
|
+
@global ^ val.abs
|
|
262
|
+
else
|
|
263
|
+
@global | val
|
|
264
|
+
end
|
|
356
265
|
end
|
|
357
266
|
|
|
358
267
|
def ref
|
|
@@ -375,7 +284,7 @@ module Squared
|
|
|
375
284
|
|
|
376
285
|
format_desc action, flag, '(-)project*'
|
|
377
286
|
task flag do |_, args|
|
|
378
|
-
args = args.to_a.reject { |val|
|
|
287
|
+
args = args.to_a.reject { |val| val == name }
|
|
379
288
|
if flag == :run
|
|
380
289
|
graph args
|
|
381
290
|
else
|
|
@@ -434,10 +343,12 @@ module Squared
|
|
|
434
343
|
asdf(flag, args, version: version)
|
|
435
344
|
end
|
|
436
345
|
else
|
|
437
|
-
format_desc(action, flag,
|
|
346
|
+
format_desc(action, flag, case flag when :exec, :env then 'command' end)
|
|
438
347
|
task flag do |_, args|
|
|
439
348
|
args = args.to_a
|
|
440
|
-
|
|
349
|
+
if args.empty? && (flag == :exec || flag == :env)
|
|
350
|
+
args << readline('Enter command', force: flag == :exec)
|
|
351
|
+
end
|
|
441
352
|
asdf flag, args
|
|
442
353
|
end
|
|
443
354
|
end
|
|
@@ -453,7 +364,7 @@ module Squared
|
|
|
453
364
|
end
|
|
454
365
|
|
|
455
366
|
def with(**kwargs, &blk)
|
|
456
|
-
@withargs =
|
|
367
|
+
@withargs = kwargs.empty? ? nil : kwargs
|
|
457
368
|
if block_given?
|
|
458
369
|
instance_eval(&blk)
|
|
459
370
|
@withargs = nil
|
|
@@ -474,18 +385,17 @@ module Squared
|
|
|
474
385
|
kwargs = hashdup(@withargs).update(kwargs) if @withargs
|
|
475
386
|
kwargs[:group] = group if group && !kwargs.key?(:group)
|
|
476
387
|
kwargs[:ref] = ref unless kwargs.key?(:ref)
|
|
477
|
-
proj = nil
|
|
478
388
|
name = case name
|
|
479
389
|
when String, Symbol
|
|
480
390
|
name.to_s
|
|
481
391
|
else
|
|
482
392
|
path.basename
|
|
483
393
|
end
|
|
394
|
+
target = children
|
|
484
395
|
workspace.add(path, name, parent: self, **kwargs) do
|
|
485
|
-
|
|
396
|
+
target << self
|
|
486
397
|
instance_eval(&blk) if block_given?
|
|
487
398
|
end
|
|
488
|
-
children << proj
|
|
489
399
|
end
|
|
490
400
|
self
|
|
491
401
|
end
|
|
@@ -502,8 +412,8 @@ module Squared
|
|
|
502
412
|
out.build if out.respond_to?(:build)
|
|
503
413
|
end
|
|
504
414
|
self
|
|
505
|
-
rescue
|
|
506
|
-
print_error(e, subject:
|
|
415
|
+
rescue => e
|
|
416
|
+
print_error(e, subject: name, hint: obj)
|
|
507
417
|
self
|
|
508
418
|
end
|
|
509
419
|
|
|
@@ -522,9 +432,8 @@ module Squared
|
|
|
522
432
|
return unless args.first
|
|
523
433
|
end
|
|
524
434
|
if args.all? { |val| val.is_a?(Array) }
|
|
525
|
-
cmd = []
|
|
526
435
|
var = {}
|
|
527
|
-
args.
|
|
436
|
+
cmd = args.each_with_object([]) do |val, out|
|
|
528
437
|
case val.first
|
|
529
438
|
when Proc
|
|
530
439
|
instance_exec(*val[1..-1], &val.first)
|
|
@@ -542,21 +451,20 @@ module Squared
|
|
|
542
451
|
end
|
|
543
452
|
d = append_hash(d, target: []).join(' ') if d.is_a?(Hash)
|
|
544
453
|
if a
|
|
545
|
-
|
|
454
|
+
out << [replace_bin(as_get(a, from, 1)), d, b].compact.join(' ')
|
|
546
455
|
else
|
|
547
456
|
next unless respond_to?(:compose)
|
|
548
457
|
|
|
549
|
-
|
|
458
|
+
out << a if (a = compose(as_get(b, from, 2), d, script: true, args: e, from: from))
|
|
550
459
|
end
|
|
551
460
|
var.update(c) if c.is_a?(Hash)
|
|
552
|
-
end
|
|
553
|
-
cmd = cmd.join(' && ')
|
|
461
|
+
end.join(' && ')
|
|
554
462
|
else
|
|
555
463
|
cmd, opts, var, flags, extra = args
|
|
556
464
|
if cmd
|
|
557
465
|
return run_b(cmd, sync: sync, from: from) if cmd.is_a?(Proc) || cmd.is_a?(Method)
|
|
558
466
|
|
|
559
|
-
cmd = replace_bin as_get(cmd, from)
|
|
467
|
+
cmd = replace_bin as_get(cmd, from, 1)
|
|
560
468
|
opts = compose(opts, script: false) if opts && respond_to?(:compose)
|
|
561
469
|
flags = append_hash(flags, target: []).join(' ') if flags.is_a?(Hash)
|
|
562
470
|
cmd = case opts
|
|
@@ -574,7 +482,7 @@ module Squared
|
|
|
574
482
|
else
|
|
575
483
|
return unless (opts || extra) && respond_to?(:compose)
|
|
576
484
|
|
|
577
|
-
cmd = compose(as_get(opts, from), flags, script: true, args: extra, from: from)
|
|
485
|
+
cmd = compose(as_get(opts, from, 2), flags, script: true, args: extra, from: from)
|
|
578
486
|
from = :script if from == :run && script?
|
|
579
487
|
end
|
|
580
488
|
end
|
|
@@ -590,16 +498,16 @@ module Squared
|
|
|
590
498
|
graph_deps.flatten(1).sort.each do |proj|
|
|
591
499
|
next if @@graph[:_].include?(proj)
|
|
592
500
|
|
|
593
|
-
if (val = ENV["PREREQS_#{proj.
|
|
501
|
+
if (val = ENV["PREREQS_#{proj.envname_get}"] || ENV["PREREQS_#{proj.ref.upcase}"])
|
|
594
502
|
split_escape(val) do |meth|
|
|
595
|
-
if proj.
|
|
503
|
+
if proj.has?(meth)
|
|
596
504
|
begin
|
|
597
505
|
proj.__send__(meth, sync: sync)
|
|
598
|
-
rescue
|
|
599
|
-
on_error(e,
|
|
506
|
+
rescue => e
|
|
507
|
+
on_error(e, exception: true)
|
|
600
508
|
end
|
|
601
509
|
else
|
|
602
|
-
print_error(
|
|
510
|
+
print_error('prereqs', "method: #{meth}", subject: name, hint: 'undefined')
|
|
603
511
|
end
|
|
604
512
|
end
|
|
605
513
|
elsif proj.build?
|
|
@@ -649,24 +557,24 @@ module Squared
|
|
|
649
557
|
when Hash
|
|
650
558
|
begin
|
|
651
559
|
@clean.each { |cmd, opts| build(cmd.to_s, opts, sync: sync) }
|
|
652
|
-
rescue
|
|
653
|
-
on_error
|
|
560
|
+
rescue => e
|
|
561
|
+
on_error(e, fatal: prod?)
|
|
654
562
|
end
|
|
655
563
|
else
|
|
656
564
|
if @clean.is_a?(Enumerable) && !series?(@clean)
|
|
657
565
|
@clean.each do |val|
|
|
658
|
-
|
|
659
|
-
if
|
|
660
|
-
log&.warn "rm -rf #{
|
|
661
|
-
rm_rf(
|
|
566
|
+
src = basepath(val = val.to_s)
|
|
567
|
+
if src.directory? && val.match?(%r{[\\/]\z})
|
|
568
|
+
log&.warn "rm -rf #{src}"
|
|
569
|
+
rm_rf(src, verbose: !silent?)
|
|
662
570
|
else
|
|
663
|
-
log&.warn "rm #{
|
|
664
|
-
(val.include?('*') ? Dir[
|
|
571
|
+
log&.warn "rm #{src}"
|
|
572
|
+
(val.include?('*') ? Dir[src] : [src]).each do |file|
|
|
665
573
|
next unless File.file?(file)
|
|
666
574
|
|
|
667
575
|
File.delete(file)
|
|
668
|
-
rescue
|
|
669
|
-
|
|
576
|
+
rescue => e
|
|
577
|
+
print_error(Logger::ERROR, e, subject: name)
|
|
670
578
|
end
|
|
671
579
|
end
|
|
672
580
|
end
|
|
@@ -690,22 +598,20 @@ module Squared
|
|
|
690
598
|
end
|
|
691
599
|
env('GRAPH', suffix: 'PASS') { |val| pass.concat(split_escape(val)) }
|
|
692
600
|
start, neg = start.partition { |name| !name.start_with?('-') }
|
|
693
|
-
data = graph_collect(self, start, pass: neg.map
|
|
601
|
+
data = graph_collect(self, start, pass: neg.map { |name| name[1..-1] })
|
|
694
602
|
unless out
|
|
695
603
|
data[name] << self
|
|
696
604
|
on :first, :graph
|
|
697
605
|
end
|
|
698
606
|
ret = graph_branch(self, data, tasks, out, sync: sync, pass: pass, order: order)
|
|
699
|
-
rescue
|
|
700
|
-
on_error(e, :
|
|
607
|
+
rescue => e
|
|
608
|
+
on_error(e, exception: true, dryrun: !out.nil?)
|
|
701
609
|
else
|
|
702
610
|
if out
|
|
703
611
|
if order
|
|
704
|
-
out.map
|
|
705
|
-
name = ret.find { |proj| val.match?(/ #{Regexp.escape(proj.name)}(
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
val.subhint(n.succ)
|
|
612
|
+
out.map do |val|
|
|
613
|
+
name = ret.find { |proj| val.match?(/ #{Regexp.escape(proj.name)}(@\d|\z)/) }&.name
|
|
614
|
+
(n = name && order[name]) ? val.subhint(n.succ) : val
|
|
709
615
|
end
|
|
710
616
|
else
|
|
711
617
|
[out, ret]
|
|
@@ -866,8 +772,8 @@ module Squared
|
|
|
866
772
|
'--home'
|
|
867
773
|
end
|
|
868
774
|
cmd << name << version
|
|
869
|
-
when :exec
|
|
870
|
-
cmd << name
|
|
775
|
+
when :env, :exec
|
|
776
|
+
cmd << name if flag == :env || !opts.first.start_with?(/#{name}\b/)
|
|
871
777
|
cmd.merge(opts)
|
|
872
778
|
when :current
|
|
873
779
|
cmd << '--no-header' unless legacy
|
|
@@ -876,7 +782,7 @@ module Squared
|
|
|
876
782
|
cmd << name
|
|
877
783
|
banner = false if flag == :latest || flag == :where
|
|
878
784
|
end
|
|
879
|
-
success?(run(banner: banner, from:
|
|
785
|
+
success?(run(banner: banner, from: symjoin('asdf', flag)), flag == :set || flag == :reshim)
|
|
880
786
|
end
|
|
881
787
|
|
|
882
788
|
def first(key, *args, **kwargs, &blk)
|
|
@@ -893,14 +799,18 @@ module Squared
|
|
|
893
799
|
|
|
894
800
|
def event(name, key, *args, override: false, **kwargs, &blk)
|
|
895
801
|
args.unshift(blk) if block_given?
|
|
896
|
-
ev = @
|
|
802
|
+
ev = @on[:event][name.to_sym]
|
|
897
803
|
(override ? ev[key.to_sym] = [] : ev[key.to_sym] ||= []) << [args, kwargs]
|
|
898
804
|
self
|
|
899
805
|
end
|
|
900
806
|
|
|
901
807
|
def as(cmd, script, to = nil)
|
|
902
808
|
data = @as[cmd.to_sym]
|
|
903
|
-
|
|
809
|
+
if script.is_a?(Enumerable)
|
|
810
|
+
script.each { |key, val| data[key.to_s] = val }
|
|
811
|
+
elsif to
|
|
812
|
+
data[script.to_s] = to
|
|
813
|
+
end
|
|
904
814
|
self
|
|
905
815
|
end
|
|
906
816
|
|
|
@@ -917,8 +827,8 @@ module Squared
|
|
|
917
827
|
self
|
|
918
828
|
end
|
|
919
829
|
|
|
920
|
-
def run(cmd = @session, var = nil, exception:
|
|
921
|
-
interactive: nil, hint: nil, series: false, **)
|
|
830
|
+
def run(cmd = @session, var = nil, exception: exception?, sync: true, banner: true, from: nil, chdir: path,
|
|
831
|
+
interactive: nil, hint: nil, series: false, timeout: nil, **)
|
|
922
832
|
unless cmd
|
|
923
833
|
print_error('no command session started', subject: project, hint: from, pass: true)
|
|
924
834
|
return
|
|
@@ -936,6 +846,7 @@ module Squared
|
|
|
936
846
|
msg = "#{msg} #{sub_style(h, theme[:active])}" if h
|
|
937
847
|
exit 1 unless confirm_basic("#{msg}?", cmd, y)
|
|
938
848
|
end
|
|
849
|
+
timeout = session_timeout cmd if timeout.nil?
|
|
939
850
|
cmd = session_done cmd
|
|
940
851
|
log&.info cmd
|
|
941
852
|
on :first, from
|
|
@@ -956,10 +867,13 @@ module Squared
|
|
|
956
867
|
end
|
|
957
868
|
end
|
|
958
869
|
args = var.is_a?(Hash) ? [var, cmd] : [cmd]
|
|
959
|
-
ret =
|
|
870
|
+
ret = shell_t(*args, chdir: chdir, exception: exception, timeout: timeout || 0)
|
|
960
871
|
end
|
|
961
|
-
rescue
|
|
962
|
-
|
|
872
|
+
rescue Timeout::Error => e
|
|
873
|
+
print_error(Logger::ERROR, cmd, subject: name, hint: e)
|
|
874
|
+
exit 1 unless exception?(Logger::DEBUG, Logger::INFO)
|
|
875
|
+
rescue => e
|
|
876
|
+
on_error(e, exception: true)
|
|
963
877
|
false
|
|
964
878
|
else
|
|
965
879
|
on :last, from
|
|
@@ -973,6 +887,51 @@ module Squared
|
|
|
973
887
|
end
|
|
974
888
|
end
|
|
975
889
|
|
|
890
|
+
def global(*args)
|
|
891
|
+
@global > 0 && @global.anybits?(case args.size
|
|
892
|
+
when 1
|
|
893
|
+
args.first
|
|
894
|
+
when 0
|
|
895
|
+
1 | 2
|
|
896
|
+
else
|
|
897
|
+
args.reduce(0) { |a, b| a | b }
|
|
898
|
+
end)
|
|
899
|
+
end
|
|
900
|
+
|
|
901
|
+
def global_set(name = nil, **kwargs)
|
|
902
|
+
return if (n = @global) == -1
|
|
903
|
+
|
|
904
|
+
@global = 0
|
|
905
|
+
data = scriptdata(name: name)
|
|
906
|
+
if n.anybits?(1 << 31)
|
|
907
|
+
@global = (n & (1 | 2)) | (1 << 31)
|
|
908
|
+
elsif @output[0] != false
|
|
909
|
+
kwargs.update(@initargs) if name
|
|
910
|
+
if @output[0].nil?
|
|
911
|
+
if data[:script]
|
|
912
|
+
unless kwargs[:script] == false
|
|
913
|
+
script_set(data[:script], args: data.fetch(:args, kwargs[:args]), prod: kwargs[:prod], global: true)
|
|
914
|
+
end
|
|
915
|
+
elsif data[:run]
|
|
916
|
+
run_set(data[:run], global: true)
|
|
917
|
+
end
|
|
918
|
+
if kwargs[:script]
|
|
919
|
+
script_set(kwargs[:script], args: kwargs[:args]) unless data[:env][:script]
|
|
920
|
+
elsif @script
|
|
921
|
+
if @script[:script]
|
|
922
|
+
script_set(@script[:script], args: @script.fetch(:args, kwargs[:args])) unless data[:global][:script]
|
|
923
|
+
elsif @script[:run] && !data[:global][:run]
|
|
924
|
+
run_set @script[:run]
|
|
925
|
+
end
|
|
926
|
+
end
|
|
927
|
+
elsif data[:run] && data[:env][:run]
|
|
928
|
+
run_set(data[:run], global: true)
|
|
929
|
+
end
|
|
930
|
+
end
|
|
931
|
+
self.global = 4 if data[:global][:doc] && doc?
|
|
932
|
+
self.global = 8 if data[:global][:test] && test?
|
|
933
|
+
end
|
|
934
|
+
|
|
976
935
|
def variable_set(key, *args, **kwargs, &blk)
|
|
977
936
|
if block_given?
|
|
978
937
|
if blocks.include?(key)
|
|
@@ -988,6 +947,8 @@ module Squared
|
|
|
988
947
|
index_set val
|
|
989
948
|
when :graph
|
|
990
949
|
graph_set val
|
|
950
|
+
when :timeout
|
|
951
|
+
timeout_set val
|
|
991
952
|
when :pass
|
|
992
953
|
pass_set val
|
|
993
954
|
when :only
|
|
@@ -1021,25 +982,26 @@ module Squared
|
|
|
1021
982
|
alias apply variable_set
|
|
1022
983
|
|
|
1023
984
|
def enabled?(ref = nil, **)
|
|
1024
|
-
return false if ref &&
|
|
985
|
+
return false if ref && Array(ref).none? { |val| ref?(val) }
|
|
1025
986
|
|
|
1026
987
|
(path.directory? && !path.empty?) || archive?
|
|
1027
988
|
end
|
|
1028
989
|
|
|
1029
|
-
def has?(meth, ref = nil)
|
|
990
|
+
def has?(meth, ref = nil, all: false, missing: false)
|
|
1030
991
|
return false if ref && !ref?(ref)
|
|
1031
992
|
|
|
1032
|
-
|
|
993
|
+
pred = :"#{meth}?"
|
|
994
|
+
respond_to?(pred, all) ? __send__(pred) : missing
|
|
1033
995
|
end
|
|
1034
996
|
|
|
1035
997
|
def ref?(val)
|
|
1036
998
|
@ref.include?(val)
|
|
1037
999
|
end
|
|
1038
1000
|
|
|
1039
|
-
def exist?(*args)
|
|
1040
|
-
return false if
|
|
1001
|
+
def exist?(*args, type: nil)
|
|
1002
|
+
return false if args.first.nil?
|
|
1041
1003
|
|
|
1042
|
-
basepath(*args).exist?
|
|
1004
|
+
type ? !basepath!(*args, type: type).nil? : basepath(*args).exist?
|
|
1043
1005
|
end
|
|
1044
1006
|
|
|
1045
1007
|
def build?
|
|
@@ -1064,10 +1026,9 @@ module Squared
|
|
|
1064
1026
|
|
|
1065
1027
|
def prereqs?
|
|
1066
1028
|
target = self
|
|
1067
|
-
|
|
1029
|
+
begin
|
|
1068
1030
|
return true if target.graph?
|
|
1069
|
-
|
|
1070
|
-
end
|
|
1031
|
+
end while (target = target.parent)
|
|
1071
1032
|
false
|
|
1072
1033
|
end
|
|
1073
1034
|
|
|
@@ -1104,7 +1065,7 @@ module Squared
|
|
|
1104
1065
|
end
|
|
1105
1066
|
|
|
1106
1067
|
def exclude?(*refs)
|
|
1107
|
-
!@exclude.empty? && has_value?(@exclude, refs
|
|
1068
|
+
!@exclude.empty? && has_value?(@exclude, *refs)
|
|
1108
1069
|
end
|
|
1109
1070
|
|
|
1110
1071
|
def task_include?(key, ref = nil)
|
|
@@ -1126,7 +1087,7 @@ module Squared
|
|
|
1126
1087
|
def log
|
|
1127
1088
|
return @log unless @log.is_a?(Array)
|
|
1128
1089
|
|
|
1129
|
-
@log = Logger.new(
|
|
1090
|
+
@log = Logger.new(enabled? ? @log.first : nil, **@log.last)
|
|
1130
1091
|
end
|
|
1131
1092
|
|
|
1132
1093
|
def allref(&blk)
|
|
@@ -1183,7 +1144,12 @@ module Squared
|
|
|
1183
1144
|
def scriptname(from: :run)
|
|
1184
1145
|
return unless (name = @output[1]) && respond_to?(:compose)
|
|
1185
1146
|
|
|
1186
|
-
as_get name, from
|
|
1147
|
+
as_get name, from, 2
|
|
1148
|
+
end
|
|
1149
|
+
|
|
1150
|
+
def scriptdata(*keys, name: nil)
|
|
1151
|
+
ret = @workspace.script_find(*@ref, @group, name: name)
|
|
1152
|
+
keys.empty? ? ret : ret.dig(*keys)
|
|
1187
1153
|
end
|
|
1188
1154
|
|
|
1189
1155
|
def inspect
|
|
@@ -1202,21 +1168,123 @@ module Squared
|
|
|
1202
1168
|
|
|
1203
1169
|
def script_get(*args, key: nil)
|
|
1204
1170
|
ret = workspace.script_get(*args, group: group, ref: allref)
|
|
1205
|
-
|
|
1171
|
+
ret && key ? ret.fetch(key, nil) : ret
|
|
1172
|
+
end
|
|
1173
|
+
|
|
1174
|
+
def index_get
|
|
1175
|
+
@index
|
|
1176
|
+
end
|
|
1177
|
+
|
|
1178
|
+
def envname_get
|
|
1179
|
+
@envname
|
|
1180
|
+
end
|
|
1206
1181
|
|
|
1207
|
-
|
|
1182
|
+
def graph_get
|
|
1183
|
+
@graph
|
|
1208
1184
|
end
|
|
1209
1185
|
|
|
1210
1186
|
private
|
|
1211
1187
|
|
|
1188
|
+
def initialize_ref(ref)
|
|
1189
|
+
@ref << ref unless @exclude.include?(ref)
|
|
1190
|
+
end
|
|
1191
|
+
|
|
1192
|
+
def initialize_build(ref, **kwargs)
|
|
1193
|
+
initialize_ref ref
|
|
1194
|
+
if (@script = @workspace.script_get(group: @group, ref: ref))
|
|
1195
|
+
if @script[:log] && !kwargs.key?(:log)
|
|
1196
|
+
kwargs[:log] = @script[:log]
|
|
1197
|
+
@log = nil
|
|
1198
|
+
end
|
|
1199
|
+
@depend = @script[:depend] if @depend.nil?
|
|
1200
|
+
@doc = @script[:doc] if @doc.nil?
|
|
1201
|
+
@lint = @script[:lint] if @lint.nil?
|
|
1202
|
+
@test = @script[:test] if @test.nil?
|
|
1203
|
+
@clean = @script[:clean] if @clean.nil?
|
|
1204
|
+
@exclude = @script[:exclude] if @exclude.empty? && @script.key?(:exclude)
|
|
1205
|
+
end
|
|
1206
|
+
@workspace.events_get(group: @group, ref: ref)&.each do |task, data|
|
|
1207
|
+
data.each { |ev, blk| @on[:event][ev][task] ||= [blk] }
|
|
1208
|
+
end
|
|
1209
|
+
initialize_logger kwargs[:log]
|
|
1210
|
+
global_set(script: kwargs[:script], args: kwargs[:args], prod: kwargs[:prod])
|
|
1211
|
+
end
|
|
1212
|
+
|
|
1213
|
+
def initialize_logger(log)
|
|
1214
|
+
return if @log
|
|
1215
|
+
|
|
1216
|
+
log = log.is_a?(Hash) ? log.dup : { file: log }
|
|
1217
|
+
file = if (val = env('LOG_FILE'))
|
|
1218
|
+
Time.now.strftime(val)
|
|
1219
|
+
elsif (val = env('LOG_AUTO'))
|
|
1220
|
+
require 'date'
|
|
1221
|
+
"#{@name}-%s.log" % [case val
|
|
1222
|
+
when 'y', 'year'
|
|
1223
|
+
Date.today.year
|
|
1224
|
+
when 'm', 'month'
|
|
1225
|
+
Date.today.strftime('%Y-%m')
|
|
1226
|
+
when 'd', 'day', '1'
|
|
1227
|
+
Date.today
|
|
1228
|
+
else
|
|
1229
|
+
val.include?('%') ? Time.now.strftime(val) : Time.now.strftime('%FT%T%:z')
|
|
1230
|
+
end]
|
|
1231
|
+
elsif (val = log[:file])
|
|
1232
|
+
if val.is_a?(String)
|
|
1233
|
+
Time.now.strftime(val)
|
|
1234
|
+
else
|
|
1235
|
+
require 'date'
|
|
1236
|
+
"#{@name}-#{Date.today}.log"
|
|
1237
|
+
end
|
|
1238
|
+
end
|
|
1239
|
+
.yield_self do |path|
|
|
1240
|
+
next unless path
|
|
1241
|
+
|
|
1242
|
+
@workspace.home.join(env('LOG_DIR', ''), path).realdirpath
|
|
1243
|
+
rescue => e
|
|
1244
|
+
print_error e
|
|
1245
|
+
end
|
|
1246
|
+
log[:progname] ||= @name
|
|
1247
|
+
env('LOG_LEVEL', ignore: false) { |val| log[:level] = val.start_with?(/\d/) ? log_sym(val.to_i) : val }
|
|
1248
|
+
log.delete(:file)
|
|
1249
|
+
@log = [file, log]
|
|
1250
|
+
end
|
|
1251
|
+
|
|
1252
|
+
def initialize_env(dev: nil, prod: nil, **)
|
|
1253
|
+
@dev = env_match('BUILD', dev, suffix: 'DEV', strict: true)
|
|
1254
|
+
@prod = env_match('BUILD', prod, suffix: 'PROD', strict: true)
|
|
1255
|
+
unless @output[0] == false
|
|
1256
|
+
env('BUILD', suffix: 'ENV') do |val|
|
|
1257
|
+
next unless (val = parse_json(val, kind: nil)).is_a?(Hash)
|
|
1258
|
+
|
|
1259
|
+
@output[2] = val
|
|
1260
|
+
end
|
|
1261
|
+
end
|
|
1262
|
+
unless @output[0] == false || @output[0].is_a?(Array)
|
|
1263
|
+
env('BUILD', suffix: 'OPTS') do |val|
|
|
1264
|
+
n = @output[0] ? 1 : 3
|
|
1265
|
+
@output[n] = merge_opts @output[n], shell_split(val)
|
|
1266
|
+
end
|
|
1267
|
+
env(ref.to_s.upcase, suffix: 'OPTS') { |val| @output[4] = merge_opts @output[4], shell_split(val) }
|
|
1268
|
+
end
|
|
1269
|
+
env('BUILD', suffix: 'VERSION') { |val| self.version = val }
|
|
1270
|
+
env('BUILD', strict: true) do |val|
|
|
1271
|
+
if val == '0'
|
|
1272
|
+
@output = [false]
|
|
1273
|
+
elsif script?
|
|
1274
|
+
script_set(val, global: 1 << 31)
|
|
1275
|
+
else
|
|
1276
|
+
run_set(val, global: 1 << 31)
|
|
1277
|
+
end
|
|
1278
|
+
end
|
|
1279
|
+
end
|
|
1280
|
+
|
|
1212
1281
|
def puts(*args, **kwargs)
|
|
1213
1282
|
log_console(*args, pipe: kwargs[:pipe] || pipe)
|
|
1214
1283
|
end
|
|
1215
1284
|
|
|
1216
1285
|
def run_s(*cmd, sync: true, banner: !silent?, from: nil, **kwargs)
|
|
1217
|
-
cmd.flatten!
|
|
1218
1286
|
case cmd.last
|
|
1219
|
-
when Hash,
|
|
1287
|
+
when Hash, true, false
|
|
1220
1288
|
var = cmd.pop
|
|
1221
1289
|
end
|
|
1222
1290
|
on :first, from
|
|
@@ -1225,8 +1293,8 @@ module Squared
|
|
|
1225
1293
|
print_run val, banner
|
|
1226
1294
|
run(val, var, sync: sync, banner: banner, **kwargs)
|
|
1227
1295
|
end
|
|
1228
|
-
rescue
|
|
1229
|
-
on_error(e,
|
|
1296
|
+
rescue => e
|
|
1297
|
+
on_error(e, exception: kwargs.fetch(:exception, exception?))
|
|
1230
1298
|
end
|
|
1231
1299
|
on :last, from
|
|
1232
1300
|
end
|
|
@@ -1240,11 +1308,8 @@ module Squared
|
|
|
1240
1308
|
when Proc
|
|
1241
1309
|
instance_eval(&obj)
|
|
1242
1310
|
when Method
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
else
|
|
1246
|
-
[]
|
|
1247
|
-
end
|
|
1311
|
+
n = obj.arity.abs
|
|
1312
|
+
args = n > 0 ? Array.new(n).tap { |data| data[0] = self } : []
|
|
1248
1313
|
obj.call(*args)
|
|
1249
1314
|
else
|
|
1250
1315
|
if series?(obj)
|
|
@@ -1257,8 +1322,25 @@ module Squared
|
|
|
1257
1322
|
end
|
|
1258
1323
|
end
|
|
1259
1324
|
|
|
1260
|
-
def
|
|
1261
|
-
|
|
1325
|
+
def run_e(cmd, stderr: false, banner: true, **kwargs)
|
|
1326
|
+
require 'open3'
|
|
1327
|
+
if stderr
|
|
1328
|
+
Open3.popen3(cmd) do |_, out, err|
|
|
1329
|
+
n = write_lines(out, banner: banner, pass: true, **kwargs)
|
|
1330
|
+
if n == 0
|
|
1331
|
+
n = write_lines(err, banner: banner)
|
|
1332
|
+
success?(n == 0, n == 0 && !banner.nil?)
|
|
1333
|
+
else
|
|
1334
|
+
write_lines(err, loglevel: Logger::DEBUG)
|
|
1335
|
+
end
|
|
1336
|
+
end
|
|
1337
|
+
else
|
|
1338
|
+
Open3.popen2e(cmd) { |_, out| write_lines(out, banner: banner, **kwargs) }
|
|
1339
|
+
end
|
|
1340
|
+
end
|
|
1341
|
+
|
|
1342
|
+
def graph_branch(target, data, tasks = nil, out = nil, sync: true, pass: [], done: [], depth: 0, single: false,
|
|
1343
|
+
last: false, order: nil, **kwargs)
|
|
1262
1344
|
tag = ->(proj) { "#{proj.name}#{"@#{proj.version}" if SEM_VER.match?(proj.version)}" }
|
|
1263
1345
|
uniq = lambda do |name|
|
|
1264
1346
|
return [] unless (ret = data[name])
|
|
@@ -1294,6 +1376,7 @@ module Squared
|
|
|
1294
1376
|
"#{single ? ' ' : a}#{' ' * depth.pred}#{last ? d : c}#{b * 3}#{items.empty? ? b : e} #{f}"
|
|
1295
1377
|
end
|
|
1296
1378
|
end
|
|
1379
|
+
ctx = { sync: sync, pass: pass, done: done, order: order, single: single, depth: depth.succ, context: target }
|
|
1297
1380
|
items.each_with_index do |proj, i|
|
|
1298
1381
|
next if done.include?(proj)
|
|
1299
1382
|
|
|
@@ -1306,8 +1389,7 @@ module Squared
|
|
|
1306
1389
|
end
|
|
1307
1390
|
end
|
|
1308
1391
|
unless target.name == name || (none = (t - done).empty?)
|
|
1309
|
-
graph_branch(proj, data, tasks, out,
|
|
1310
|
-
single: single, last: j == true, context: target)
|
|
1392
|
+
graph_branch(proj, data, tasks, out, last: j == true, **ctx)
|
|
1311
1393
|
end
|
|
1312
1394
|
if out
|
|
1313
1395
|
if none
|
|
@@ -1320,7 +1402,7 @@ module Squared
|
|
|
1320
1402
|
final = data.keys.last
|
|
1321
1403
|
while k < depth
|
|
1322
1404
|
indent = k > 0 ? ((last && !j) || (j && k == depth.pred) || single) : j && last && depth == 1
|
|
1323
|
-
s += "#{indent || (last && data[final].last == context) ? ' ' : a} "
|
|
1405
|
+
s += "#{indent || (last && data[final].last == kwargs[:context]) ? ' ' : a} "
|
|
1324
1406
|
k += 1
|
|
1325
1407
|
end
|
|
1326
1408
|
s += "#{j ? d : c}#{b * 3} #{tag.call(proj)}"
|
|
@@ -1346,14 +1428,14 @@ module Squared
|
|
|
1346
1428
|
next if pass.include?(meth)
|
|
1347
1429
|
|
|
1348
1430
|
if workspace.task_defined?(cmd = task_join(name, meth))
|
|
1349
|
-
if ENV.key?(key = "BANNER_#{
|
|
1431
|
+
if ENV.key?(key = "BANNER_#{envname_get}")
|
|
1350
1432
|
key = nil
|
|
1351
1433
|
else
|
|
1352
1434
|
ENV[key] = '0'
|
|
1353
1435
|
end
|
|
1354
1436
|
run(cmd, sync: false, banner: false)
|
|
1355
1437
|
ENV.delete(key) if key
|
|
1356
|
-
elsif proj.has?(meth,
|
|
1438
|
+
elsif proj.has?(meth, tasks || graph ? nil : workspace.baseref)
|
|
1357
1439
|
proj.__send__(meth.to_sym, sync: sync)
|
|
1358
1440
|
end
|
|
1359
1441
|
end
|
|
@@ -1364,8 +1446,7 @@ module Squared
|
|
|
1364
1446
|
end
|
|
1365
1447
|
|
|
1366
1448
|
def graph_collect(target, start = [], data: {}, pass: [], root: [])
|
|
1367
|
-
deps = []
|
|
1368
|
-
(start.empty? ? target.instance_variable_get(:@graph) : start)&.each do |val|
|
|
1449
|
+
deps = Array(start.empty? ? target.graph_get : start).each_with_object([]) do |val, out|
|
|
1369
1450
|
next if pass.include?(val)
|
|
1370
1451
|
|
|
1371
1452
|
if (obj = workspace.find(name: val))
|
|
@@ -1380,8 +1461,8 @@ module Squared
|
|
|
1380
1461
|
end
|
|
1381
1462
|
next if (objs = data.fetch(name, [])).include?(target)
|
|
1382
1463
|
|
|
1383
|
-
|
|
1384
|
-
|
|
1464
|
+
out << proj
|
|
1465
|
+
out.concat(objs)
|
|
1385
1466
|
end
|
|
1386
1467
|
end
|
|
1387
1468
|
deps.uniq!
|
|
@@ -1392,22 +1473,22 @@ module Squared
|
|
|
1392
1473
|
|
|
1393
1474
|
def graph_deps(target = self)
|
|
1394
1475
|
key = target.name
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
break unless (target = target.parent)
|
|
1476
|
+
@@graph[key] ||= begin
|
|
1477
|
+
base = []
|
|
1478
|
+
deps = []
|
|
1479
|
+
loop do
|
|
1480
|
+
deps.concat(graph_branch(target, graph_collect(target), []))
|
|
1481
|
+
break unless (target = target.parent)
|
|
1402
1482
|
|
|
1403
|
-
|
|
1483
|
+
base << target
|
|
1484
|
+
end
|
|
1485
|
+
deps.uniq!
|
|
1486
|
+
[base, deps]
|
|
1404
1487
|
end
|
|
1405
|
-
deps.uniq!
|
|
1406
|
-
@@graph[key] = [base, deps]
|
|
1407
1488
|
end
|
|
1408
1489
|
|
|
1409
|
-
def env(key, default = nil, suffix: nil,
|
|
1410
|
-
name = "#{key}_#{
|
|
1490
|
+
def env(key, default = nil, suffix: nil, strict: false, ignore: nil, **kwargs, &blk)
|
|
1491
|
+
name = "#{key}_#{envname_get}"
|
|
1411
1492
|
ret = if suffix
|
|
1412
1493
|
ENV.fetch("#{name}_#{suffix}", '')
|
|
1413
1494
|
elsif strict
|
|
@@ -1416,15 +1497,7 @@ module Squared
|
|
|
1416
1497
|
ignore = ['0'].freeze if ignore.nil?
|
|
1417
1498
|
ENV[name] || ENV.fetch(key, '')
|
|
1418
1499
|
end
|
|
1419
|
-
|
|
1420
|
-
ret = default if ret.empty? || (ignore && Array(ignore).any? { |val| ret == val.to_s })
|
|
1421
|
-
return ret if ret.nil?
|
|
1422
|
-
else
|
|
1423
|
-
ret = Array(equals).any? { |val| ret == val.to_s }
|
|
1424
|
-
end
|
|
1425
|
-
return yield ret if block_given?
|
|
1426
|
-
|
|
1427
|
-
ret
|
|
1500
|
+
env_yield(ret, default, ignore: ignore, **kwargs, &blk)
|
|
1428
1501
|
end
|
|
1429
1502
|
|
|
1430
1503
|
def session(*cmd, prefix: cmd.first, main: true, path: true, options: true)
|
|
@@ -1432,7 +1505,7 @@ module Squared
|
|
|
1432
1505
|
if path && (val = shell_bin(prefix))
|
|
1433
1506
|
cmd[0] = shell_quote(val, force: false)
|
|
1434
1507
|
end
|
|
1435
|
-
ret = JoinSet.new(cmd
|
|
1508
|
+
ret = JoinSet.new(cmd)
|
|
1436
1509
|
if options
|
|
1437
1510
|
env("#{prefix.upcase}_OPTIONS") do |val|
|
|
1438
1511
|
if val.start_with?('-')
|
|
@@ -1442,9 +1515,17 @@ module Squared
|
|
|
1442
1515
|
end
|
|
1443
1516
|
end
|
|
1444
1517
|
end
|
|
1445
|
-
|
|
1518
|
+
cache = @timeout[:_]
|
|
1519
|
+
cache[1] ||= workspace.timeout_get(*@ref, group: group)
|
|
1520
|
+
cache[0][ret] = if cmd[1..-1].find { |val| val =~ /\A([A-Za-z][\w-]*)(?<![-_])(?: |\z)/ }
|
|
1521
|
+
command = :"#{prefix}_#{$1}"
|
|
1522
|
+
cache[1][command] || @timeout[command]
|
|
1523
|
+
end || cache[1][prefix.to_sym] || @timeout[prefix.to_sym]
|
|
1524
|
+
main ? @session = ret : ret
|
|
1525
|
+
end
|
|
1446
1526
|
|
|
1447
|
-
|
|
1527
|
+
def session_timeout(cmd)
|
|
1528
|
+
@timeout[:_][0][cmd] || @timeout[:_][2]
|
|
1448
1529
|
end
|
|
1449
1530
|
|
|
1450
1531
|
def session_output(*cmd, **kwargs)
|
|
@@ -1468,18 +1549,18 @@ module Squared
|
|
|
1468
1549
|
end
|
|
1469
1550
|
|
|
1470
1551
|
def session_apply(val, args: nil, kwargs: nil, pass: [], keys: [:opts], exclude: [])
|
|
1471
|
-
a = []
|
|
1472
1552
|
b = {}
|
|
1473
|
-
Array(val).
|
|
1553
|
+
a = Array(val).each_with_object([]) do |c, out|
|
|
1474
1554
|
d, e, f = session_get c
|
|
1475
|
-
|
|
1555
|
+
f -= exclude
|
|
1556
|
+
unless f.empty?
|
|
1476
1557
|
h = []
|
|
1477
1558
|
i = {}
|
|
1478
|
-
session_apply(f.map
|
|
1479
|
-
|
|
1559
|
+
session_apply(f.map(&:to_s), args: h, kwargs: i, pass: pass, keys: keys, exclude: exclude.concat(f))
|
|
1560
|
+
out.concat(h)
|
|
1480
1561
|
append_keys(b, i, *keys)
|
|
1481
1562
|
end
|
|
1482
|
-
|
|
1563
|
+
out.concat(d)
|
|
1483
1564
|
append_keys(b, e, *keys)
|
|
1484
1565
|
end
|
|
1485
1566
|
if args
|
|
@@ -1512,23 +1593,48 @@ module Squared
|
|
|
1512
1593
|
OptionPartition.arg?(target, *args, **kwargs)
|
|
1513
1594
|
end
|
|
1514
1595
|
|
|
1515
|
-
def option(*args, target: @session, prefix: target&.first,
|
|
1596
|
+
def option(*args, target: @session, prefix: target&.first, path: false, escape: false, quote: false, pat: nil,
|
|
1597
|
+
**kwargs)
|
|
1516
1598
|
return unless prefix
|
|
1517
1599
|
|
|
1518
|
-
args.each do |
|
|
1519
|
-
next unless (ret = env(env_key(prefix.to_s.stripext,
|
|
1600
|
+
args.each do |key|
|
|
1601
|
+
next unless (ret = env(env_key(prefix.to_s.stripext, key), **kwargs)) && (!pat || ret.match?(pat))
|
|
1520
1602
|
|
|
1603
|
+
if path
|
|
1604
|
+
target << quote_option(key, basepath(ret))
|
|
1605
|
+
elsif quote
|
|
1606
|
+
target << quote_option(key, ret)
|
|
1607
|
+
elsif escape
|
|
1608
|
+
target << shell_option(key, ret)
|
|
1609
|
+
end
|
|
1521
1610
|
return block_given? ? yield(ret) : ret
|
|
1522
1611
|
end
|
|
1523
1612
|
nil
|
|
1524
1613
|
end
|
|
1525
1614
|
|
|
1526
|
-
def
|
|
1527
|
-
|
|
1615
|
+
def write_lines(data, grep: [], prefix: nil, sub: nil, banner: nil, loglevel: nil, pass: false, first: false)
|
|
1616
|
+
grep = grep.empty? ? nil : matchmap(grep, prefix)
|
|
1617
|
+
sub = stdin? ? nil : as_a(sub)
|
|
1618
|
+
ret = 0
|
|
1619
|
+
lines = data.each_with_object([]) do |line, out|
|
|
1620
|
+
next if grep&.none? { |pat| pat.match?(line) }
|
|
1621
|
+
next if block_given? && !(line = yield(line, ret))
|
|
1528
1622
|
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1623
|
+
if loglevel
|
|
1624
|
+
log&.add loglevel, line
|
|
1625
|
+
else
|
|
1626
|
+
sub&.each { |h| sub_style!(line, **h) }
|
|
1627
|
+
if banner
|
|
1628
|
+
out << line
|
|
1629
|
+
else
|
|
1630
|
+
puts line
|
|
1631
|
+
end
|
|
1632
|
+
end
|
|
1633
|
+
ret += 1
|
|
1634
|
+
break out if first
|
|
1635
|
+
end
|
|
1636
|
+
print_item banner, lines if banner && (ret > 0 || (!pass && !first))
|
|
1637
|
+
ret
|
|
1532
1638
|
end
|
|
1533
1639
|
|
|
1534
1640
|
def print_success
|
|
@@ -1538,7 +1644,18 @@ module Squared
|
|
|
1538
1644
|
def print_error(*args, loglevel: Logger::WARN, **kwargs)
|
|
1539
1645
|
return unless warning?
|
|
1540
1646
|
|
|
1541
|
-
|
|
1647
|
+
loglevel = args.shift if args.first.is_a?(Numeric) && args.first.between?(Logger::DEBUG, Logger::UNKNOWN)
|
|
1648
|
+
if loglevel >= Logger::WARN && exception?(Logger::ERROR, Logger::FATAL)
|
|
1649
|
+
$stderr.puts log_message([loglevel, Logger::Error].max, *args, **kwargs)
|
|
1650
|
+
if exception == Logger::ERROR
|
|
1651
|
+
ex = [args.first, kwargs[:subject], kwargs[:hint]].compact
|
|
1652
|
+
raise(ex.find { |val| val.class < Exception } || ex.first)
|
|
1653
|
+
else
|
|
1654
|
+
exit 1
|
|
1655
|
+
end
|
|
1656
|
+
else
|
|
1657
|
+
warn log_message(loglevel, *args, **kwargs)
|
|
1658
|
+
end
|
|
1542
1659
|
end
|
|
1543
1660
|
|
|
1544
1661
|
def print_run(cmd, banner = true, verbose: nil, **)
|
|
@@ -1554,19 +1671,19 @@ module Squared
|
|
|
1554
1671
|
puts val unless val.empty? || (val.size == 1 && !val.first)
|
|
1555
1672
|
end
|
|
1556
1673
|
|
|
1557
|
-
def print_banner(*lines, client: false, styles: theme[:banner], border: borderstyle
|
|
1674
|
+
def print_banner(*lines, client: false, styles: theme[:banner], border: borderstyle)
|
|
1558
1675
|
pad = 0
|
|
1559
1676
|
if styles
|
|
1560
1677
|
if styles.any? { |s| s.to_s.end_with?('!') }
|
|
1561
1678
|
pad = 1
|
|
1562
1679
|
elsif !client && styles.size <= 1
|
|
1563
|
-
styles
|
|
1680
|
+
styles += [:bold]
|
|
1564
1681
|
end
|
|
1565
1682
|
end
|
|
1566
1683
|
n = line_width lines
|
|
1567
1684
|
ch = ' ' * pad
|
|
1568
1685
|
index = -1
|
|
1569
|
-
lines.map
|
|
1686
|
+
ret = lines.map do |val|
|
|
1570
1687
|
index += 1
|
|
1571
1688
|
val = ch + val.ljust(n - (pad * 2)) + ch
|
|
1572
1689
|
if styles && (pad == 1 || index == 0)
|
|
@@ -1575,23 +1692,24 @@ module Squared
|
|
|
1575
1692
|
val
|
|
1576
1693
|
end
|
|
1577
1694
|
end
|
|
1578
|
-
|
|
1695
|
+
ret << sub_style(ARG[:BORDER][1] * n, border)
|
|
1696
|
+
ret.join("\n")
|
|
1579
1697
|
end
|
|
1580
1698
|
|
|
1581
|
-
def print_footer(*lines, sub: nil, reverse: false, right: false, border: borderstyle
|
|
1699
|
+
def print_footer(*lines, sub: nil, reverse: false, right: false, border: borderstyle)
|
|
1582
1700
|
n = line_width lines
|
|
1583
1701
|
sub = as_a sub
|
|
1584
|
-
lines.map
|
|
1702
|
+
ret = lines.map do |val|
|
|
1585
1703
|
s = right ? val.rjust(n) : val.ljust(n)
|
|
1586
1704
|
sub.each { |h| sub_style!(s, **h) }
|
|
1587
1705
|
s
|
|
1588
1706
|
end
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1707
|
+
ret.unshift(sub_style(ARG[:BORDER][1] * n, border))
|
|
1708
|
+
ret.reverse! if reverse
|
|
1709
|
+
ret.join("\n")
|
|
1592
1710
|
end
|
|
1593
1711
|
|
|
1594
|
-
def print_status(*args, from:
|
|
1712
|
+
def print_status(*args, from: :completed, **kwargs)
|
|
1595
1713
|
return if stdin? || silent?
|
|
1596
1714
|
|
|
1597
1715
|
case from
|
|
@@ -1617,7 +1735,7 @@ module Squared
|
|
|
1617
1735
|
workspace.format_desc([@desc, action, flag].compact, opts, **kwargs)
|
|
1618
1736
|
end
|
|
1619
1737
|
|
|
1620
|
-
def format_banner(cmd, banner: true, hint: nil, strip: nil)
|
|
1738
|
+
def format_banner(cmd, banner: true, hint: nil, strip: nil, quote: false)
|
|
1621
1739
|
return unless banner && banner?
|
|
1622
1740
|
|
|
1623
1741
|
if (data = workspace.banner_get(*@ref, group: group))
|
|
@@ -1625,7 +1743,7 @@ module Squared
|
|
|
1625
1743
|
|
|
1626
1744
|
client = true
|
|
1627
1745
|
else
|
|
1628
|
-
data = Struct::BannerData.new(true, [:
|
|
1746
|
+
data = Struct::BannerData.new(true, theme[:banner], theme[:border], [:path])
|
|
1629
1747
|
end
|
|
1630
1748
|
if verbose
|
|
1631
1749
|
out = []
|
|
@@ -1638,6 +1756,7 @@ module Squared
|
|
|
1638
1756
|
cmd = cmd.gsub(/(?:#{s = Regexp.escape(File.join(path, ''))}?(?=["'])|#{s})/, '')
|
|
1639
1757
|
.gsub(/(?: -[^ ])? (?:""|'')/, '')
|
|
1640
1758
|
end
|
|
1759
|
+
cmd.gsub!(/(?<= )(["'])([\w.-]+)\1(?= |\z)/, '\2') unless quote
|
|
1641
1760
|
out << cmd.subhint(hint)
|
|
1642
1761
|
end
|
|
1643
1762
|
data.order.each do |val|
|
|
@@ -1672,7 +1791,7 @@ module Squared
|
|
|
1672
1791
|
unless items.empty?
|
|
1673
1792
|
pad = items.size.to_s.size
|
|
1674
1793
|
items.each_with_index do |val, i|
|
|
1675
|
-
next unless matchany?(val.first
|
|
1794
|
+
next unless matchany?(reg, val.first)
|
|
1676
1795
|
|
|
1677
1796
|
out << ('%*d. %s' % [pad, i.succ, block_given? ? yield(val) : val.first])
|
|
1678
1797
|
end
|
|
@@ -1686,7 +1805,7 @@ module Squared
|
|
|
1686
1805
|
out << ''
|
|
1687
1806
|
end
|
|
1688
1807
|
if from
|
|
1689
|
-
out <<
|
|
1808
|
+
out << from
|
|
1690
1809
|
/\A(#{Regexp.escape(from)})(.*)\z/
|
|
1691
1810
|
end
|
|
1692
1811
|
else
|
|
@@ -1719,7 +1838,8 @@ module Squared
|
|
|
1719
1838
|
end
|
|
1720
1839
|
end
|
|
1721
1840
|
data.each do |key, val|
|
|
1722
|
-
|
|
1841
|
+
key = key.to_s
|
|
1842
|
+
next if key.start_with?('__')
|
|
1723
1843
|
|
|
1724
1844
|
if val.nil? || extra || session_arg?(key, target: target)
|
|
1725
1845
|
OptionPartition.delete_key(target, key)
|
|
@@ -1732,7 +1852,7 @@ module Squared
|
|
|
1732
1852
|
append_repeat(key, val, target: target)
|
|
1733
1853
|
when Numeric
|
|
1734
1854
|
target << basic_option(key, val)
|
|
1735
|
-
when
|
|
1855
|
+
when false
|
|
1736
1856
|
target << shell_option(key).sub(/^--(?!no-)/, '--no-')
|
|
1737
1857
|
when Pathname
|
|
1738
1858
|
target << shell_option(key, val, escape: false)
|
|
@@ -1769,9 +1889,7 @@ module Squared
|
|
|
1769
1889
|
|
|
1770
1890
|
def append_first(*list, target: @session, flag: true, equals: false, escape: true, quote: true, force: true,
|
|
1771
1891
|
**kwargs)
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
list.flatten.each do |opt|
|
|
1892
|
+
list.each do |opt|
|
|
1775
1893
|
next unless (val = option(opt, **kwargs))
|
|
1776
1894
|
|
|
1777
1895
|
return target << if flag
|
|
@@ -1785,30 +1903,25 @@ module Squared
|
|
|
1785
1903
|
|
|
1786
1904
|
def append_option(*list, target: @session, no: false, equals: false, escape: true, quote: true, force: true,
|
|
1787
1905
|
**kwargs)
|
|
1788
|
-
return if list.empty?
|
|
1789
|
-
|
|
1790
1906
|
kwargs[:ignore] = false if no && !kwargs.key?(:ignore)
|
|
1791
|
-
ret = []
|
|
1792
|
-
list.flatten.each do |flag|
|
|
1907
|
+
ret = list.each_with_object([]) do |flag, out|
|
|
1793
1908
|
next unless (val = option(flag, target: target, **kwargs))
|
|
1794
1909
|
|
|
1795
1910
|
if no && val == '0'
|
|
1796
1911
|
flag = "no-#{flag}"
|
|
1797
1912
|
val = nil
|
|
1798
1913
|
end
|
|
1799
|
-
|
|
1914
|
+
out << shell_option(flag, (val if equals), escape: escape, quote: quote, force: force)
|
|
1800
1915
|
end
|
|
1801
1916
|
merge_list target, ret unless ret.empty?
|
|
1802
|
-
ret
|
|
1803
1917
|
end
|
|
1804
1918
|
|
|
1805
|
-
def append_nocolor(target: @session)
|
|
1806
|
-
target <<
|
|
1919
|
+
def append_nocolor(flag = '--no-color', target: @session, **kwargs)
|
|
1920
|
+
target << flag if !ARG[:COLOR] || stdin? || option('color', target: target, equals: '0', **kwargs)
|
|
1807
1921
|
end
|
|
1808
1922
|
|
|
1809
1923
|
def append_keys(base, data, *keys)
|
|
1810
|
-
|
|
1811
|
-
keys.each do |key|
|
|
1924
|
+
ret = keys.each_with_object({}) do |key, out|
|
|
1812
1925
|
next unless data.key?(key)
|
|
1813
1926
|
|
|
1814
1927
|
out[key] = case (val = data[key])
|
|
@@ -1821,7 +1934,7 @@ module Squared
|
|
|
1821
1934
|
end
|
|
1822
1935
|
end
|
|
1823
1936
|
base.update(data)
|
|
1824
|
-
.update(
|
|
1937
|
+
.update(ret)
|
|
1825
1938
|
end
|
|
1826
1939
|
|
|
1827
1940
|
def merge_opts(base, data)
|
|
@@ -1864,22 +1977,9 @@ module Squared
|
|
|
1864
1977
|
end
|
|
1865
1978
|
end
|
|
1866
1979
|
|
|
1867
|
-
def merge_list(base, data)
|
|
1868
|
-
data = Array(data)
|
|
1869
|
-
case base
|
|
1870
|
-
when Array
|
|
1871
|
-
base.concat(data)
|
|
1872
|
-
when Set
|
|
1873
|
-
base.merge(data)
|
|
1874
|
-
else
|
|
1875
|
-
Array(base).concat(data)
|
|
1876
|
-
end
|
|
1877
|
-
end
|
|
1878
|
-
|
|
1879
1980
|
def collect_hash(data, pass: [])
|
|
1880
|
-
|
|
1881
|
-
data.
|
|
1882
|
-
ret
|
|
1981
|
+
data = data.reject { |key,| pass.include?(key) } unless pass.empty?
|
|
1982
|
+
data.values.flatten
|
|
1883
1983
|
end
|
|
1884
1984
|
|
|
1885
1985
|
def replace_bin(val)
|
|
@@ -1893,14 +1993,13 @@ module Squared
|
|
|
1893
1993
|
ret = JSON.parse(val)
|
|
1894
1994
|
raise_error 'invalid JSON'.subhint(kind.name), val, hint: hint if kind && !ret.is_a?(kind)
|
|
1895
1995
|
ret
|
|
1896
|
-
rescue
|
|
1897
|
-
|
|
1898
|
-
print_error(e, subject: name)
|
|
1996
|
+
rescue => e
|
|
1997
|
+
print_error(kind ? Logger::ERROR : Logger::INFO, e, subject: name)
|
|
1899
1998
|
end
|
|
1900
1999
|
|
|
1901
2000
|
def parse_env(key)
|
|
1902
2001
|
env(key) do |val|
|
|
1903
|
-
val.start_with?('-') ? shell_parse(val) : split_escape(val).map
|
|
2002
|
+
val.start_with?('-') ? shell_parse(val) : split_escape(val).map { |opt| fill_option(opt) }
|
|
1904
2003
|
end || []
|
|
1905
2004
|
end
|
|
1906
2005
|
|
|
@@ -1922,65 +2021,46 @@ module Squared
|
|
|
1922
2021
|
confirm("#{msg} [#{sub_style(target.to_s, style.is_a?(Symbol) ? theme[style] : style)}]", default, **kwargs)
|
|
1923
2022
|
end
|
|
1924
2023
|
|
|
1925
|
-
def confirm_outdated(pkg, ver, type, cur = nil, lock: false, col0: 0, col1: 0, col2: nil, col3: 0, col4: 0,
|
|
1926
|
-
**kwargs)
|
|
1927
|
-
h = sub_style(semrev(type).upcase, (type == 1 && theme[:major]) || theme[:header])
|
|
1928
|
-
case col0
|
|
1929
|
-
when 0
|
|
1930
|
-
col0 = "#{h}: "
|
|
1931
|
-
when Numeric
|
|
1932
|
-
puts h
|
|
1933
|
-
col0 = ' ' * col0
|
|
1934
|
-
else
|
|
1935
|
-
puts h
|
|
1936
|
-
end
|
|
1937
|
-
b = sub_style pkg.ljust(col1), theme[:inline]
|
|
1938
|
-
cur ||= 'locked' if lock
|
|
1939
|
-
c = if cur
|
|
1940
|
-
cur = cur.ljust(col2 || cur.size.succ)
|
|
1941
|
-
lock ? sub_style(cur, color(:red)) : cur
|
|
1942
|
-
end
|
|
1943
|
-
d = type == 1 || lock ? 'N' : 'Y'
|
|
1944
|
-
e = "#{col0}#{b}#{c}#{sub_style(col1 > 0 ? ver.ljust(col3) : ver.rjust(ver.size.succ), theme[:inline])}"
|
|
1945
|
-
confirm("#{e}#{col4 > 0 ? ' ' * [col4 - e.stripstyle.size - 1, 2].max : ' '}", d, **kwargs)
|
|
1946
|
-
end
|
|
1947
|
-
|
|
1948
2024
|
def confirm_semver(msg, type, style: (type == 1 && theme[:major]) || :inline, timeout: 0, **kwargs)
|
|
1949
|
-
|
|
2025
|
+
rev = case type
|
|
2026
|
+
when 1
|
|
2027
|
+
'major'
|
|
2028
|
+
when 2
|
|
2029
|
+
'minor'
|
|
2030
|
+
else
|
|
2031
|
+
'patch'
|
|
2032
|
+
end
|
|
2033
|
+
confirm_basic(msg, rev, type == 1 ? 'N' : 'Y', style: style, timeout: timeout, **kwargs)
|
|
1950
2034
|
end
|
|
1951
2035
|
|
|
1952
2036
|
def choice_index(msg, list, values: nil, accept: nil, series: false, trim: nil, column: nil, multiple: false,
|
|
1953
2037
|
force: true, **kwargs)
|
|
1954
2038
|
puts unless series || printfirst?
|
|
1955
|
-
ret = choice(msg, list, multiple: multiple, force: force, **kwargs)
|
|
1956
|
-
|
|
1957
|
-
|
|
2039
|
+
ret = choice(msg, list, multiple: multiple, force: force, **kwargs)
|
|
2040
|
+
unless ret && !ret.empty?
|
|
1958
2041
|
exit 1 if force
|
|
1959
|
-
return
|
|
2042
|
+
return
|
|
1960
2043
|
end
|
|
1961
|
-
ret = multiple ? ret.map
|
|
2044
|
+
ret = multiple ? ret.map { |val| val.sub(trim, '') } : ret.sub(trim, '') if trim
|
|
1962
2045
|
if column
|
|
1963
2046
|
a, b = Array(column)
|
|
1964
|
-
ret = Array(ret).map
|
|
2047
|
+
ret = Array(ret).map { |val| val[a, b || 1] }
|
|
1965
2048
|
ret = ret.first unless multiple
|
|
1966
2049
|
end
|
|
1967
2050
|
if accept
|
|
1968
2051
|
hint = Array(ret).map { |val| sub_style(val.to_s, theme[:inline]) }.join(', ')
|
|
1969
2052
|
accept = Array(accept).map { |val| Array(val) }
|
|
1970
2053
|
ret = Array(ret) if accept.any? { |val| val[1] == true }
|
|
1971
|
-
|
|
1972
|
-
item = accept.
|
|
2054
|
+
begin
|
|
2055
|
+
item = accept.shift
|
|
1973
2056
|
c = confirm("#{item[0]}#{" [#{hint}]" if hint}", item[2] ? 'Y' : 'N')
|
|
1974
2057
|
if item[1] == true
|
|
1975
2058
|
ret << c
|
|
1976
2059
|
elsif !c
|
|
1977
|
-
|
|
2060
|
+
exit 1
|
|
1978
2061
|
end
|
|
1979
2062
|
hint = nil
|
|
1980
|
-
|
|
1981
|
-
break if accept.empty?
|
|
1982
|
-
end
|
|
1983
|
-
exit 1 unless accept.empty?
|
|
2063
|
+
end until accept.empty?
|
|
1984
2064
|
end
|
|
1985
2065
|
if values
|
|
1986
2066
|
ret = Array(ret)
|
|
@@ -1991,7 +2071,7 @@ module Squared
|
|
|
1991
2071
|
force = false
|
|
1992
2072
|
end
|
|
1993
2073
|
val = readline(val, force: force)
|
|
1994
|
-
ret << (val
|
|
2074
|
+
ret << (val.empty? ? nil : val)
|
|
1995
2075
|
end
|
|
1996
2076
|
end
|
|
1997
2077
|
printsucc unless series
|
|
@@ -2009,10 +2089,11 @@ module Squared
|
|
|
2009
2089
|
def command_args(args, min: 0, force: false, **kwargs)
|
|
2010
2090
|
return if args.size > min || option('i', 'interactive', **kwargs, equals: '0')
|
|
2011
2091
|
|
|
2012
|
-
readline('Enter arguments', force: force)
|
|
2092
|
+
ret = readline('Enter arguments', force: force)
|
|
2093
|
+
args << ret unless ret.empty?
|
|
2013
2094
|
end
|
|
2014
2095
|
|
|
2015
|
-
def block_args(fallback =
|
|
2096
|
+
def block_args(fallback = [], &blk)
|
|
2016
2097
|
return fallback if (ret = instance_eval(&blk)).nil?
|
|
2017
2098
|
|
|
2018
2099
|
Array(ret)
|
|
@@ -2031,33 +2112,40 @@ module Squared
|
|
|
2031
2112
|
if workspace.powershell?
|
|
2032
2113
|
"#{shell_bin('powershell.exe')} -Command \"& {#{args.join(' ; ')}}\"#{out}"
|
|
2033
2114
|
else
|
|
2034
|
-
args.map
|
|
2115
|
+
args.map { |val| "#{val}#{out}" }.join(' && ')
|
|
2035
2116
|
end
|
|
2036
2117
|
end
|
|
2037
2118
|
|
|
2038
2119
|
def relativepath(*list, all: false)
|
|
2039
|
-
list.
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2120
|
+
list.map { |val| Pathname.new(val) }
|
|
2121
|
+
.select { |val| projectpath?(val) }
|
|
2122
|
+
.map do |val|
|
|
2123
|
+
ret = (val.absolute? ? val.relative_path_from(path) : val.cleanpath).to_s
|
|
2124
|
+
all && val.to_s.end_with?('/') ? "#{ret}/*" : ret
|
|
2125
|
+
end
|
|
2043
2126
|
end
|
|
2044
2127
|
|
|
2045
|
-
def projectmap(files, parent: false, pass: true)
|
|
2128
|
+
def projectmap(files, resolve: true, parent: false, pass: true)
|
|
2046
2129
|
unless parent
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2130
|
+
files = files.select { |val| projectpath?(val) }.tap do |list|
|
|
2131
|
+
next if pass || files.size == list.size
|
|
2132
|
+
|
|
2133
|
+
raise_error 'pathspec not within worktree'
|
|
2134
|
+
end
|
|
2135
|
+
end
|
|
2136
|
+
files.map do |val|
|
|
2137
|
+
if val == '.'
|
|
2138
|
+
'.'
|
|
2139
|
+
else
|
|
2140
|
+
val = basepath(val)
|
|
2141
|
+
val = val.relative_path_from(path) unless resolve
|
|
2142
|
+
shell_quote val
|
|
2143
|
+
end
|
|
2050
2144
|
end
|
|
2051
|
-
files.map { |val| val == '.' ? '.' : shell_quote(basepath(val)) }
|
|
2052
2145
|
end
|
|
2053
2146
|
|
|
2054
|
-
def
|
|
2055
|
-
|
|
2056
|
-
next val if val.is_a?(Regexp)
|
|
2057
|
-
|
|
2058
|
-
val = ".*#{val}" if prefix && !val.sub!(/\A(\^|\\A)/, '')
|
|
2059
|
-
Regexp.new("#{prefix}#{val == '*' ? '.+' : val}")
|
|
2060
|
-
end
|
|
2147
|
+
def symjoin(*args, char: ':')
|
|
2148
|
+
args.join(char).to_sym
|
|
2061
2149
|
end
|
|
2062
2150
|
|
|
2063
2151
|
def semver(val)
|
|
@@ -2082,10 +2170,10 @@ module Squared
|
|
|
2082
2170
|
return -1 if (b = other.scan(SEM_VER)).empty?
|
|
2083
2171
|
return 1 if (a = val.scan(SEM_VER)).empty?
|
|
2084
2172
|
|
|
2085
|
-
a, b = [a.first, b.first].map
|
|
2173
|
+
a, b = [a.first, b.first].map do |c|
|
|
2086
2174
|
d = begin
|
|
2087
2175
|
Integer(c[5]).to_s
|
|
2088
|
-
rescue
|
|
2176
|
+
rescue
|
|
2089
2177
|
c[5] ? '-1' : '0'
|
|
2090
2178
|
end
|
|
2091
2179
|
[c[0], c[2], c[4] || '0', d]
|
|
@@ -2123,24 +2211,13 @@ module Squared
|
|
|
2123
2211
|
end
|
|
2124
2212
|
|
|
2125
2213
|
def semtype(cur, lat)
|
|
2126
|
-
if semmajor?(cur, lat)
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
cur[2] == lat[2] ? 3 : 2
|
|
2130
|
-
end
|
|
2214
|
+
return 1 if semmajor?(cur, lat)
|
|
2215
|
+
|
|
2216
|
+
cur[2] == lat[2] ? 3 : 2
|
|
2131
2217
|
end
|
|
2132
2218
|
|
|
2133
|
-
def
|
|
2134
|
-
|
|
2135
|
-
when 1
|
|
2136
|
-
'major'
|
|
2137
|
-
when 2
|
|
2138
|
-
'minor'
|
|
2139
|
-
when 3
|
|
2140
|
-
'patch'
|
|
2141
|
-
else
|
|
2142
|
-
'unknown'
|
|
2143
|
-
end
|
|
2219
|
+
def semmajor?(cur, want)
|
|
2220
|
+
(cur[0] == '0' && want[0] == '0' ? cur[2] != want[2] : cur[0] != want[0]) && !want[5]
|
|
2144
2221
|
end
|
|
2145
2222
|
|
|
2146
2223
|
def semgte?(val, other = nil)
|
|
@@ -2166,7 +2243,7 @@ module Squared
|
|
|
2166
2243
|
def shortname(*args, suffix: '?', delim: ',', pass: false)
|
|
2167
2244
|
return unless TASK_METADATA || pass
|
|
2168
2245
|
|
|
2169
|
-
args.map
|
|
2246
|
+
args.map do |ch|
|
|
2170
2247
|
"#{ch}/#{case ch
|
|
2171
2248
|
when 'i'
|
|
2172
2249
|
'nteractive'
|
|
@@ -2192,7 +2269,7 @@ module Squared
|
|
|
2192
2269
|
end
|
|
2193
2270
|
|
|
2194
2271
|
def color(val)
|
|
2195
|
-
(ret = theme[val])
|
|
2272
|
+
(ret = Array(theme[val])).empty? ? [val] : ret
|
|
2196
2273
|
end
|
|
2197
2274
|
|
|
2198
2275
|
def colormap(val)
|
|
@@ -2201,7 +2278,7 @@ module Squared
|
|
|
2201
2278
|
|
|
2202
2279
|
def verbosetype
|
|
2203
2280
|
case verbose
|
|
2204
|
-
when
|
|
2281
|
+
when true
|
|
2205
2282
|
1
|
|
2206
2283
|
when Numeric
|
|
2207
2284
|
verbose.succ
|
|
@@ -2211,9 +2288,15 @@ module Squared
|
|
|
2211
2288
|
end
|
|
2212
2289
|
|
|
2213
2290
|
def on(event, from, *args, **kwargs)
|
|
2214
|
-
return unless from && @
|
|
2291
|
+
return unless from && @on[:event].key?(event)
|
|
2215
2292
|
|
|
2216
|
-
|
|
2293
|
+
case event
|
|
2294
|
+
when :first
|
|
2295
|
+
@on[:from] << from
|
|
2296
|
+
when :last
|
|
2297
|
+
return unless @on[:from].delete(from)
|
|
2298
|
+
end
|
|
2299
|
+
Array(@on[:event][event][from]).each do |obj|
|
|
2217
2300
|
target, opts = if obj.is_a?(Array) && obj[1].is_a?(Hash)
|
|
2218
2301
|
[obj[0], kwargs.empty? ? obj[1] : obj[1].merge(kwargs)]
|
|
2219
2302
|
else
|
|
@@ -2230,28 +2313,51 @@ module Squared
|
|
|
2230
2313
|
end
|
|
2231
2314
|
end
|
|
2232
2315
|
|
|
2233
|
-
def on_error(err, from
|
|
2316
|
+
def on_error(err, from = @on[:from].last, exception: exception?, fatal: true, dryrun: false, pass: false)
|
|
2234
2317
|
log&.error err
|
|
2235
|
-
unless
|
|
2236
|
-
|
|
2237
|
-
|
|
2318
|
+
unless from == false
|
|
2319
|
+
cancel = -> { @on[:from] = [false] if fatal && @on[:from].include?(from) }
|
|
2320
|
+
if dryrun
|
|
2321
|
+
cancel.call
|
|
2322
|
+
else
|
|
2323
|
+
ret = on :error, from, err
|
|
2324
|
+
unless ret == true
|
|
2325
|
+
cancel.call
|
|
2326
|
+
raise err if exception
|
|
2327
|
+
end
|
|
2328
|
+
end
|
|
2238
2329
|
end
|
|
2239
2330
|
print_error(err, pass: pass) unless ret
|
|
2240
2331
|
end
|
|
2241
2332
|
|
|
2242
|
-
def pwd_set(pass: false,
|
|
2243
|
-
return
|
|
2333
|
+
def pwd_set(cmd = nil, pass: false, timeout: nil, from: @on[:from].last, **kwargs, &blk)
|
|
2334
|
+
return if from == false
|
|
2244
2335
|
|
|
2245
|
-
|
|
2246
|
-
Dir.
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2336
|
+
require 'timeout'
|
|
2337
|
+
unless (path.to_s == Dir.pwd || pass == true) && (workspace.mri? || !workspace.windows?)
|
|
2338
|
+
pwd = Dir.pwd
|
|
2339
|
+
Dir.chdir(path)
|
|
2340
|
+
end
|
|
2341
|
+
timeout = session_timeout cmd if cmd && timeout.nil?
|
|
2342
|
+
if timeout.to_f > 0
|
|
2343
|
+
Timeout.timeout(timeout, &blk)
|
|
2344
|
+
else
|
|
2345
|
+
yield
|
|
2346
|
+
end
|
|
2347
|
+
rescue Timeout::Error => e
|
|
2348
|
+
if cmd
|
|
2349
|
+
print_error(Logger::ERROR, cmd, subject: name, hint: e)
|
|
2350
|
+
else
|
|
2351
|
+
print_error(Logger::ERROR, e, subject: name)
|
|
2352
|
+
end
|
|
2353
|
+
exit 1 unless exception?(Logger::DEBUG, Logger::INFO)
|
|
2354
|
+
rescue => e
|
|
2355
|
+
on_error(e, from, **kwargs)
|
|
2250
2356
|
ensure
|
|
2251
2357
|
Dir.chdir(pwd) if pwd
|
|
2252
2358
|
end
|
|
2253
2359
|
|
|
2254
|
-
def run_set(cmd, val = nil, opts: nil, global:
|
|
2360
|
+
def run_set(cmd, val = nil, opts: nil, global: nil, **)
|
|
2255
2361
|
noopt = @output[1] == false && !@output[0].nil?
|
|
2256
2362
|
noenv = @output[2] == false
|
|
2257
2363
|
parse = lambda do |data|
|
|
@@ -2270,7 +2376,14 @@ module Squared
|
|
|
2270
2376
|
ret[2] = data[:env] unless dise
|
|
2271
2377
|
ret
|
|
2272
2378
|
end
|
|
2273
|
-
|
|
2379
|
+
case global
|
|
2380
|
+
when true
|
|
2381
|
+
self.global = 1
|
|
2382
|
+
when false
|
|
2383
|
+
self.global = -1
|
|
2384
|
+
when Numeric
|
|
2385
|
+
self.global = 1 | global
|
|
2386
|
+
end
|
|
2274
2387
|
case cmd
|
|
2275
2388
|
when Hash
|
|
2276
2389
|
@output = parse.call(data)
|
|
@@ -2302,12 +2415,19 @@ module Squared
|
|
|
2302
2415
|
end
|
|
2303
2416
|
end
|
|
2304
2417
|
|
|
2305
|
-
def script_set(cmd, prod: nil, args: nil, global:
|
|
2418
|
+
def script_set(cmd, prod: nil, args: nil, global: nil, **)
|
|
2306
2419
|
return if @output[1] == false && @output[0].nil?
|
|
2307
2420
|
|
|
2308
|
-
|
|
2421
|
+
case global
|
|
2422
|
+
when true
|
|
2423
|
+
self.global = 2
|
|
2424
|
+
when false
|
|
2425
|
+
self.global = -2
|
|
2426
|
+
when Numeric
|
|
2427
|
+
self.global = 2 | global
|
|
2428
|
+
end
|
|
2309
2429
|
@output[0] = nil
|
|
2310
|
-
@output[1] = if
|
|
2430
|
+
@output[1] = if global && cmd.is_a?(Array)
|
|
2311
2431
|
cmd[prod == true ? 1 : 0]
|
|
2312
2432
|
else
|
|
2313
2433
|
cmd
|
|
@@ -2329,6 +2449,15 @@ module Squared
|
|
|
2329
2449
|
end
|
|
2330
2450
|
end
|
|
2331
2451
|
|
|
2452
|
+
def timeout_set(val)
|
|
2453
|
+
case val
|
|
2454
|
+
when Hash
|
|
2455
|
+
@timeout.update(val)
|
|
2456
|
+
when Numeric
|
|
2457
|
+
@timeout[:_][2] = val
|
|
2458
|
+
end
|
|
2459
|
+
end
|
|
2460
|
+
|
|
2332
2461
|
def pass_set(val)
|
|
2333
2462
|
@pass = Array(val).freeze
|
|
2334
2463
|
end
|
|
@@ -2376,8 +2505,8 @@ module Squared
|
|
|
2376
2505
|
end
|
|
2377
2506
|
end
|
|
2378
2507
|
|
|
2379
|
-
def as_get(val, from)
|
|
2380
|
-
(global && @as[from][val]) || val
|
|
2508
|
+
def as_get(val, from, *type)
|
|
2509
|
+
(global(*type) && @as[from][val]) || val
|
|
2381
2510
|
end
|
|
2382
2511
|
|
|
2383
2512
|
def unpack_get(*)
|
|
@@ -2400,7 +2529,7 @@ module Squared
|
|
|
2400
2529
|
next if (items = children.select { |item| item.task_include?(key) }).empty?
|
|
2401
2530
|
|
|
2402
2531
|
ws.task_desc(@desc, action, 'workspace')
|
|
2403
|
-
task task_join(action, 'workspace') => items.map
|
|
2532
|
+
task task_join(action, 'workspace') => items.map { |item| task_join(item.name, action) }
|
|
2404
2533
|
end
|
|
2405
2534
|
end
|
|
2406
2535
|
end
|
|
@@ -2409,10 +2538,6 @@ module Squared
|
|
|
2409
2538
|
@only ? !@only.include?(key) : @pass.include?(key)
|
|
2410
2539
|
end
|
|
2411
2540
|
|
|
2412
|
-
def matchany?(val, list, empty: true)
|
|
2413
|
-
list.empty? ? empty : list.any? { |pat| val.match?(pat) }
|
|
2414
|
-
end
|
|
2415
|
-
|
|
2416
2541
|
def projectpath?(val)
|
|
2417
2542
|
ret = Pathname.new(val).cleanpath
|
|
2418
2543
|
ret.absolute? ? ret.to_s.start_with?(File.join(path, '')) : !ret.to_s.start_with?(File.join('..', ''))
|
|
@@ -2425,10 +2550,6 @@ module Squared
|
|
|
2425
2550
|
false
|
|
2426
2551
|
end
|
|
2427
2552
|
|
|
2428
|
-
def semmajor?(cur, want)
|
|
2429
|
-
(cur[0] == '0' && want[0] == '0' ? cur[2] != want[2] : cur[0] != want[0]) && !want[5]
|
|
2430
|
-
end
|
|
2431
|
-
|
|
2432
2553
|
def printfirst?
|
|
2433
2554
|
@@print_order == 0
|
|
2434
2555
|
end
|
|
@@ -2470,26 +2591,24 @@ module Squared
|
|
|
2470
2591
|
end
|
|
2471
2592
|
|
|
2472
2593
|
def success?(run, *cond)
|
|
2473
|
-
case run
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
end.tap do |ret|
|
|
2481
|
-
next unless cond.none? { |val| val == false }
|
|
2482
|
-
|
|
2594
|
+
ret = case run
|
|
2595
|
+
when true, false
|
|
2596
|
+
run
|
|
2597
|
+
else
|
|
2598
|
+
$?.success?
|
|
2599
|
+
end
|
|
2600
|
+
if cond.none? { |val| val == false }
|
|
2483
2601
|
if block_given?
|
|
2484
2602
|
yield ret
|
|
2485
2603
|
elsif ret && stdout? && banner?
|
|
2486
2604
|
print_success
|
|
2487
2605
|
end
|
|
2488
2606
|
end
|
|
2607
|
+
ret
|
|
2489
2608
|
end
|
|
2490
2609
|
|
|
2491
2610
|
def banner?
|
|
2492
|
-
ARG[:BANNER] &&
|
|
2611
|
+
ARG[:BANNER] && env('BANNER', notequals: '0')
|
|
2493
2612
|
end
|
|
2494
2613
|
|
|
2495
2614
|
def pwd?
|
|
@@ -2516,29 +2635,9 @@ module Squared
|
|
|
2516
2635
|
workspace.warning
|
|
2517
2636
|
end
|
|
2518
2637
|
|
|
2519
|
-
def
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
args = args.first if args.size == 1 && args.first.is_a?(Enumerable)
|
|
2523
|
-
args.any? { |obj,| target.include?(obj) }
|
|
2524
|
-
end
|
|
2525
|
-
|
|
2526
|
-
def has_value!(target, *args, first: false)
|
|
2527
|
-
return unless target.is_a?(Enumerable)
|
|
2528
|
-
|
|
2529
|
-
args = args.first if args.size == 1 && args.first.is_a?(Enumerable)
|
|
2530
|
-
found = false
|
|
2531
|
-
args.each do |val|
|
|
2532
|
-
if target.respond_to?(:delete?)
|
|
2533
|
-
found = true if target.delete?(val)
|
|
2534
|
-
elsif target.respond_to?(:delete)
|
|
2535
|
-
found = true if target.delete(val)
|
|
2536
|
-
elsif target.include?(val)
|
|
2537
|
-
found = true
|
|
2538
|
-
end
|
|
2539
|
-
break if found && first
|
|
2540
|
-
end
|
|
2541
|
-
target if found
|
|
2638
|
+
def exception?(*level)
|
|
2639
|
+
ex = exception
|
|
2640
|
+
level.empty? ? ex != false && ex != Logger::INFO : ex.is_a?(Numeric) && level.include?(ex)
|
|
2542
2641
|
end
|
|
2543
2642
|
|
|
2544
2643
|
def variables
|
|
@@ -2558,12 +2657,13 @@ module Squared
|
|
|
2558
2657
|
end
|
|
2559
2658
|
|
|
2560
2659
|
def scriptargs
|
|
2561
|
-
|
|
2660
|
+
n = script? ? 1 : 0
|
|
2661
|
+
{ target: @output[n], type: n == 1 ? :script : :run, ref: ref, group: group, global: global(n.succ) }
|
|
2562
2662
|
end
|
|
2563
2663
|
end
|
|
2564
2664
|
|
|
2565
|
-
Application.implement
|
|
2566
|
-
Application.attr_banner
|
|
2665
|
+
Application.implement Base, base: 0
|
|
2666
|
+
Application.attr_banner.merge(%i[name project path ref group parent])
|
|
2567
2667
|
end
|
|
2568
2668
|
end
|
|
2569
2669
|
end
|