squared 0.4.12 → 0.5.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 +56 -0
- data/README.md +4 -4
- data/README.ruby.md +19 -12
- data/lib/squared/common/base.rb +5 -3
- data/lib/squared/common/format.rb +1 -1
- data/lib/squared/common/prompt.rb +35 -39
- data/lib/squared/common/shell.rb +27 -22
- data/lib/squared/common/system.rb +36 -32
- data/lib/squared/common/utils.rb +0 -12
- data/lib/squared/common.rb +2 -1
- data/lib/squared/config.rb +12 -11
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +17 -21
- data/lib/squared/workspace/project/base.rb +363 -220
- data/lib/squared/workspace/project/docker.rb +110 -68
- data/lib/squared/workspace/project/git.rb +82 -74
- data/lib/squared/workspace/project/node.rb +63 -21
- data/lib/squared/workspace/project/python.rb +138 -103
- data/lib/squared/workspace/project/ruby.rb +60 -43
- data/lib/squared/workspace/project/support/class.rb +81 -6
- data/lib/squared/workspace/project.rb +0 -10
- data/lib/squared/workspace/repo.rb +5 -5
- data/lib/squared/workspace/series.rb +8 -8
- data/lib/squared/workspace/support/data.rb +1 -0
- data/lib/squared/workspace.rb +1 -1
- data/squared.gemspec +1 -1
- metadata +2 -3
- data/lib/squared/common/class.rb +0 -110
@@ -80,24 +80,19 @@ module Squared
|
|
80
80
|
initialize_build(Python.ref, **kwargs)
|
81
81
|
initialize_env(**kwargs)
|
82
82
|
end
|
83
|
-
|
84
|
-
@dependfile = @path + DEP_PYTHON[@dependindex || 0]
|
83
|
+
dependfile_set DEP_PYTHON
|
85
84
|
@verbose = verbose.size if verbose.is_a?(String) && verbose.match?(/\Av+\z/)
|
86
|
-
|
87
|
-
when '.', Pathname
|
88
|
-
editable
|
89
|
-
when String
|
90
|
-
Pathname.new(editable)
|
91
|
-
end
|
85
|
+
editable_set editable
|
92
86
|
venv_set venv if venv
|
93
87
|
end
|
94
88
|
|
95
89
|
subtasks({
|
96
|
-
'venv' => %i[
|
90
|
+
'venv' => %i[exec create remove show].freeze,
|
97
91
|
'pip' => %i[uninstall freeze].freeze,
|
98
92
|
'install' => %i[user force upgrade target editable].freeze,
|
99
93
|
'build' => %i[python poetry hatch].freeze,
|
100
|
-
'publish' => %i[poetry twine hatch].freeze
|
94
|
+
'publish' => %i[poetry twine hatch].freeze,
|
95
|
+
'exec' => nil
|
101
96
|
})
|
102
97
|
|
103
98
|
def ref
|
@@ -112,105 +107,130 @@ module Squared
|
|
112
107
|
Python.subtasks do |action, flags|
|
113
108
|
next if @pass.include?(action)
|
114
109
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
110
|
+
if flags.nil?
|
111
|
+
case action
|
112
|
+
when 'exec'
|
113
|
+
format_desc action, nil, 'command|:,args*'
|
114
|
+
task action do |_, args|
|
115
|
+
i = (args = args.to_a).delete(':')
|
116
|
+
cmd = if i && !workspace.windows?
|
117
|
+
readline('Enter script', force: true, multiline: ['##', ';'])
|
118
|
+
elsif i || args.empty?
|
119
|
+
readline('Enter command', force: true)
|
120
|
+
else
|
121
|
+
if (val = command_args(args, prefix: 'python'))
|
122
|
+
args << val
|
123
|
+
end
|
124
|
+
args.join(' ')
|
125
|
+
end
|
126
|
+
Kernel.exec(cmd, chdir: path)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
else
|
130
|
+
namespace action do
|
131
|
+
flags.each do |flag|
|
132
|
+
case action
|
133
|
+
when 'venv'
|
134
|
+
if flag == :create
|
135
|
+
format_desc action, flag, 'dir,opts*'
|
136
|
+
task flag, [:dir] do |_, args|
|
137
|
+
dir = path + param_guard(action, flag, args: args, key: :dir)
|
138
|
+
venv_create dir, args.extras
|
139
|
+
end
|
140
|
+
elsif venv
|
141
|
+
case flag
|
142
|
+
when :remove
|
143
|
+
next unless projectpath?(venv)
|
144
|
+
|
145
|
+
format_desc action, flag, 'c|create?,d|depend?'
|
146
|
+
task flag do |_, args|
|
147
|
+
rm_rf(venv, verbose: true)
|
148
|
+
venv_init if has_value?(%w[c create], args.to_a)
|
149
|
+
depend if has_value?(%w[d depend], args.to_a)
|
150
|
+
end
|
151
|
+
when :exec
|
152
|
+
format_desc action, flag, 'command,args*'
|
153
|
+
task flag do |_, args|
|
154
|
+
args = args.to_a
|
155
|
+
if args.empty?
|
156
|
+
args = readline('Enter command', force: true).split(' ', 2)
|
157
|
+
elsif args.size == 1 && !option('interactive', prefix: 'venv', equals: '0')
|
158
|
+
args << readline('Enter arguments', force: false)
|
159
|
+
end
|
160
|
+
venv_init
|
161
|
+
run args.join(' ')
|
162
|
+
end
|
163
|
+
when :show
|
164
|
+
format_desc action, flag
|
165
|
+
task flag do
|
166
|
+
puts venv
|
167
|
+
end
|
168
|
+
end
|
124
169
|
end
|
125
|
-
|
170
|
+
when 'pip'
|
126
171
|
case flag
|
127
|
-
when :
|
128
|
-
|
129
|
-
|
130
|
-
format_desc action, flag, 'c|create?,d|depend?'
|
172
|
+
when :freeze
|
173
|
+
format_desc action, flag, "file?=#{DEP_PYTHON[4]},opts*"
|
131
174
|
task flag do |_, args|
|
132
|
-
|
133
|
-
|
134
|
-
|
175
|
+
if (file = pip(flag, args.to_a)) && verbose
|
176
|
+
puts File.read(file)
|
177
|
+
end
|
135
178
|
end
|
136
|
-
when :
|
137
|
-
format_desc action, flag, '
|
179
|
+
when :uninstall
|
180
|
+
format_desc action, flag, 'package+,opts*'
|
138
181
|
task flag do |_, args|
|
139
|
-
|
140
|
-
args = readline('Enter command', force: true).split(' ', 2) if args.empty?
|
141
|
-
venv_init
|
142
|
-
run session(*args, path: false)
|
143
|
-
end
|
144
|
-
when :show
|
145
|
-
format_desc action, flag
|
146
|
-
task flag do
|
147
|
-
puts venv
|
182
|
+
pip flag, args.to_a
|
148
183
|
end
|
149
184
|
end
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
185
|
+
when 'install'
|
186
|
+
format_desc(action, flag, 'opts*', before: case flag
|
187
|
+
when :target then 'dir'
|
188
|
+
when :editable then 'path/url?'
|
189
|
+
when :upgrade then 'strategy?,package+'
|
190
|
+
end)
|
191
|
+
case flag
|
192
|
+
when :editable
|
193
|
+
task flag do |_, args|
|
194
|
+
install flag, args.to_a
|
158
195
|
end
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
task flag, [:strategy] do |_, args|
|
179
|
-
case (strategy = args.strategy)
|
180
|
-
when 'eager', 'only-if-needed'
|
181
|
-
args = args.extras
|
182
|
-
else
|
183
|
-
args = args.to_a
|
184
|
-
strategy = nil
|
196
|
+
when :upgrade
|
197
|
+
task flag, [:strategy] do |_, args|
|
198
|
+
case (strategy = args.strategy)
|
199
|
+
when 'eager', 'only-if-needed'
|
200
|
+
args = args.extras
|
201
|
+
else
|
202
|
+
args = args.to_a
|
203
|
+
strategy = nil
|
204
|
+
end
|
205
|
+
install(flag, args, strategy: strategy)
|
206
|
+
end
|
207
|
+
when :target
|
208
|
+
task flag, [:dir] do |_, args|
|
209
|
+
dir = param_guard(action, flag, args: args, key: :dir)
|
210
|
+
depend(flag, args.extras, target: dir)
|
211
|
+
end
|
212
|
+
else
|
213
|
+
task flag do |_, args|
|
214
|
+
depend flag, args.to_a
|
185
215
|
end
|
186
|
-
install(flag, args, strategy: strategy)
|
187
216
|
end
|
188
|
-
when
|
189
|
-
|
190
|
-
|
191
|
-
|
217
|
+
when 'build'
|
218
|
+
format_desc(action, flag, 'opts*', after: case flag
|
219
|
+
when :python then 'srcdir?'
|
220
|
+
when :hatch then 'location?'
|
221
|
+
end)
|
222
|
+
task flag do |_, args|
|
223
|
+
build! flag, args.to_a
|
192
224
|
end
|
193
|
-
|
225
|
+
when 'publish'
|
226
|
+
format_desc(action, flag, 'opts*', after: case flag
|
227
|
+
when :hatch then 'artifacts?'
|
228
|
+
when :twine then 'dist?'
|
229
|
+
end)
|
194
230
|
task flag do |_, args|
|
195
|
-
|
231
|
+
publish flag, args.to_a
|
196
232
|
end
|
197
233
|
end
|
198
|
-
when 'build'
|
199
|
-
format_desc(action, flag, 'opts*', after: case flag
|
200
|
-
when :python then 'srcdir?'
|
201
|
-
when :hatch then 'location?'
|
202
|
-
end)
|
203
|
-
task flag do |_, args|
|
204
|
-
build! flag, args.to_a
|
205
|
-
end
|
206
|
-
when 'publish'
|
207
|
-
format_desc(action, flag, 'opts*', after: case flag
|
208
|
-
when :hatch then 'artifacts?'
|
209
|
-
when :twine then 'dist?'
|
210
|
-
end)
|
211
|
-
task flag do |_, args|
|
212
|
-
publish flag, args.to_a
|
213
|
-
end
|
214
234
|
end
|
215
235
|
end
|
216
236
|
end
|
@@ -422,7 +442,13 @@ module Squared
|
|
422
442
|
ret
|
423
443
|
end
|
424
444
|
|
425
|
-
def variable_set(key, *val,
|
445
|
+
def variable_set(key, *val, **, &blk)
|
446
|
+
if block_given?
|
447
|
+
case key
|
448
|
+
when :dependfile, :venv, :editable
|
449
|
+
val = block_args val, &blk
|
450
|
+
end
|
451
|
+
end
|
426
452
|
case key
|
427
453
|
when :dependfile
|
428
454
|
req = basepath(*val)
|
@@ -432,7 +458,9 @@ module Squared
|
|
432
458
|
else
|
433
459
|
log.warn "variable_set: @#{key}=#{req} (not supported)"
|
434
460
|
end
|
435
|
-
when :
|
461
|
+
when :editable
|
462
|
+
editable_set val.first
|
463
|
+
when :venv
|
436
464
|
instance_variable_set(:"@#{key}", val.empty? ? nil : basepath(*val))
|
437
465
|
else
|
438
466
|
super
|
@@ -463,9 +491,7 @@ module Squared
|
|
463
491
|
|
464
492
|
def poetry_session(*cmd)
|
465
493
|
ret = session('poetry', *cmd, *preopts)
|
466
|
-
|
467
|
-
ret << quote_option('project', path + val)
|
468
|
-
end
|
494
|
+
option('project', ignore: false) { |val| ret << quote_option('project', path + val) }
|
469
495
|
ret
|
470
496
|
end
|
471
497
|
|
@@ -538,7 +564,7 @@ module Squared
|
|
538
564
|
end
|
539
565
|
|
540
566
|
def append_global(target: @session)
|
541
|
-
|
567
|
+
option('cache-dir', target: target) do |val|
|
542
568
|
target << case val
|
543
569
|
when '0', 'false'
|
544
570
|
'--no-cache-dir'
|
@@ -546,11 +572,20 @@ module Squared
|
|
546
572
|
quote_option('cache-dir', path + val)
|
547
573
|
end
|
548
574
|
end
|
549
|
-
|
550
|
-
|
575
|
+
option('proxy', target: target) { |val| target << shell_option('proxy', val) }
|
576
|
+
option('python', target: target) { |val| target << quote_option('python', path + val) }
|
551
577
|
append_nocolor(target: target)
|
552
578
|
end
|
553
579
|
|
580
|
+
def editable_set(val)
|
581
|
+
@editable = case val
|
582
|
+
when '.', Pathname
|
583
|
+
val
|
584
|
+
when String
|
585
|
+
Pathname.new(editable)
|
586
|
+
end
|
587
|
+
end
|
588
|
+
|
554
589
|
def singleopt(flag = nil)
|
555
590
|
case flag
|
556
591
|
when :python
|
@@ -100,9 +100,9 @@ module Squared
|
|
100
100
|
initialize_build(Ruby.ref, **kwargs)
|
101
101
|
initialize_env(**kwargs)
|
102
102
|
end
|
103
|
+
dependfile_set GEMFILE
|
103
104
|
@autodetect = autodetect
|
104
|
-
@
|
105
|
-
@dependfile = @path + GEMFILE[@dependindex || 0]
|
105
|
+
@rakelist = nil
|
106
106
|
return if !@output[0].nil? || !@copy.nil? || @version || @autodetect || (file = rakefile).nil?
|
107
107
|
|
108
108
|
begin
|
@@ -203,7 +203,7 @@ module Squared
|
|
203
203
|
gem!(flag, args, filter: filter)
|
204
204
|
end
|
205
205
|
when :build, :push, :exec
|
206
|
-
format_desc(action, flag, 'opts*', before: flag == :exec ? 'command
|
206
|
+
format_desc(action, flag, 'opts*', before: flag == :exec ? 'command,args*' : nil)
|
207
207
|
task flag do |_, args|
|
208
208
|
gem! flag, args.to_a
|
209
209
|
end
|
@@ -219,15 +219,20 @@ module Squared
|
|
219
219
|
when :file
|
220
220
|
format_desc action, flag, 'path,opts*,args*'
|
221
221
|
task flag, [:rb] do |_, args|
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
222
|
+
file = args.rb
|
223
|
+
args = args.to_a.drop(1)
|
224
|
+
unless file && !file.include?('*')
|
225
|
+
values = ['Arguments']
|
226
|
+
values.prepend('Options') unless file
|
227
|
+
file, opts, extra = choice_index('Select a file', Dir.glob(file || '*.rb', base: path),
|
228
|
+
values: values, force: true, series: !args.include?('v'))
|
229
|
+
if file
|
230
|
+
extra = opts
|
231
|
+
else
|
232
|
+
args.concat(OptionPartition.strip(opts))
|
233
|
+
end
|
229
234
|
end
|
230
|
-
ruby(flag, args, file: file)
|
235
|
+
ruby(flag, args, file: file, args: extra)
|
231
236
|
end
|
232
237
|
when :script
|
233
238
|
format_desc action, flag, 'opts*,args*'
|
@@ -306,7 +311,7 @@ module Squared
|
|
306
311
|
end
|
307
312
|
log.info cmd.to_s
|
308
313
|
on :first, :outdated
|
309
|
-
banner = format_banner
|
314
|
+
banner = format_banner cmd.to_s
|
310
315
|
print_item banner if sync
|
311
316
|
pwd_set(from: :outdated) do
|
312
317
|
start = 0
|
@@ -397,7 +402,7 @@ module Squared
|
|
397
402
|
end
|
398
403
|
if found > 0
|
399
404
|
begin
|
400
|
-
if major == 0 && dependfile.read =~ /\b(?:source\s+(["'])(
|
405
|
+
if major == 0 && dependfile.read =~ /\b(?:source\s+(["'])((?~\1))\1|remote:\s+(\S+))/
|
401
406
|
status = ($2 || $3).chomp('/')
|
402
407
|
right = true
|
403
408
|
end
|
@@ -423,22 +428,20 @@ module Squared
|
|
423
428
|
def update(flag, opts = [])
|
424
429
|
bundle_session 'update', "--#{flag}"
|
425
430
|
append_bundle(opts, OPT_BUNDLE[:install_base] + OPT_BUNDLE[:update] + OPT_BUNDLE[:common],
|
426
|
-
append: flag == :all ? nil : /\A
|
431
|
+
append: flag == :all ? nil : /\A[a-z\-]+=/)
|
427
432
|
run_rb(from: :update)
|
428
433
|
end
|
429
434
|
|
430
|
-
def ruby(flag, opts = [], file: nil, command: nil)
|
435
|
+
def ruby(flag, opts = [], file: nil, command: nil, args: nil)
|
431
436
|
case flag
|
432
437
|
when :file, :script
|
433
438
|
op = OptionPartition.new(opts, OPT_RUBY[:ruby], ruby_session, project: self, args: true)
|
434
439
|
if file
|
435
|
-
op.extras.
|
440
|
+
op.extras.prepend(shell_quote(path + file))
|
436
441
|
elsif command
|
437
442
|
op << quote_option('e', command, option: false)
|
438
443
|
end
|
439
|
-
if (args = ENV
|
440
|
-
op.extras << args
|
441
|
-
end
|
444
|
+
op.extras << args if (args = ENV.fetch('RUBY_ARGS', args))
|
442
445
|
op.append(delim: true, escape: false, quote: false) unless op.empty?
|
443
446
|
when :version
|
444
447
|
pwd_set do
|
@@ -461,8 +464,9 @@ module Squared
|
|
461
464
|
when 'rvm'
|
462
465
|
`rvm current`[/^\S+/, 0]
|
463
466
|
when 'rbenv'
|
464
|
-
|
465
|
-
|
467
|
+
`rbenv version-name`.yield_self do |name|
|
468
|
+
name.match?(SEM_VER) ? "ruby #{name}" : name
|
469
|
+
end
|
466
470
|
when 'chruby.sh'
|
467
471
|
chruby = session_output 'source', val
|
468
472
|
`#{chruby.with('ruby --version')}`
|
@@ -478,7 +482,7 @@ module Squared
|
|
478
482
|
when 'chruby.sh'
|
479
483
|
`#{chruby.with('chruby --version')}`.sub(':', '')
|
480
484
|
when 'install'
|
481
|
-
"asdf #{`asdf version`.
|
485
|
+
"asdf #{`asdf version`.delete_prefix('v')}"
|
482
486
|
else
|
483
487
|
`#{cmd} --version`
|
484
488
|
end)
|
@@ -603,7 +607,7 @@ module Squared
|
|
603
607
|
g = a.ljust(d)
|
604
608
|
pat = [/^([^.]+\.)([^.]+\..+)$/, /^([^.]+\.[^.]+\.)(.+)$/]
|
605
609
|
pre = b.start_with?('0.')
|
606
|
-
latest = [theme[:
|
610
|
+
latest = [theme[:latest]]
|
607
611
|
case item.last
|
608
612
|
when 1
|
609
613
|
case filter
|
@@ -637,8 +641,7 @@ module Squared
|
|
637
641
|
styles = %i[yellow]
|
638
642
|
pat = pat.last
|
639
643
|
end
|
640
|
-
b = b.rjust(e)
|
641
|
-
b = sub_style(b, *colormap(styles), pat: pat, index: 2)
|
644
|
+
b = sub_style(b.rjust(e), *colormap(styles), pat: pat, index: 2)
|
642
645
|
h = sub_style(c.rjust(f), styles: latest.flatten.compact, pat: pat, index: 2)
|
643
646
|
j += 1
|
644
647
|
if queue
|
@@ -656,15 +659,15 @@ module Squared
|
|
656
659
|
else
|
657
660
|
unless update.empty?
|
658
661
|
cmd = gem_output 'update', '-f'
|
659
|
-
|
662
|
+
option('document', prefix: 'gem', ignore: false) do |val|
|
660
663
|
cmd << case val
|
661
664
|
when '0', 'false'
|
662
665
|
'--no-document'
|
663
666
|
else
|
664
|
-
basic_option
|
667
|
+
basic_option 'document', val
|
665
668
|
end
|
666
669
|
end
|
667
|
-
|
670
|
+
option('user-install', prefix: 'gem', ignore: false) do |val|
|
668
671
|
cmd << case val
|
669
672
|
when '0', 'false'
|
670
673
|
'--no-user-install'
|
@@ -677,8 +680,13 @@ module Squared
|
|
677
680
|
end
|
678
681
|
unless stdin?
|
679
682
|
status = print_footer("major #{major} / minor #{minor} / patch #{patch}", right: true).split("\n")
|
680
|
-
status[1] =
|
681
|
-
|
683
|
+
status[1] = status[1]
|
684
|
+
.yield_self do |s|
|
685
|
+
sub_style(s, pat: /^( +major )(\d+)(.+)$/, styles: theme[:major], index: 2)
|
686
|
+
end
|
687
|
+
.yield_self do |s|
|
688
|
+
sub_style(s, pat: /^(.+)(minor )(\d+)(.+)$/, styles: theme[:active], index: 3)
|
689
|
+
end
|
682
690
|
puts status
|
683
691
|
end
|
684
692
|
end
|
@@ -692,12 +700,16 @@ module Squared
|
|
692
700
|
raise_error("unknown args: #{op.join(', ')}", hint: flag)
|
693
701
|
end
|
694
702
|
elsif flag == :build
|
695
|
-
spec = [path + "#{project}.gemspec", path + "#{name}.gemspec", *
|
703
|
+
spec = [path + "#{project}.gemspec", path + "#{name}.gemspec", *path.glob('*.gemspec')]
|
696
704
|
op << File.basename(spec) if (spec = spec.find { |file| File.exist?(file) })
|
697
705
|
end
|
698
706
|
when :exec
|
699
707
|
raise_error('missing command', hint: flag) if op.empty?
|
700
|
-
op << project
|
708
|
+
op << basic_option('gem', project) unless op.arg?('g', 'gem')
|
709
|
+
if (args = command_args(op.extras))
|
710
|
+
op.push(args)
|
711
|
+
end
|
712
|
+
op.append(delim: true, quote: false)
|
701
713
|
else
|
702
714
|
raise_error('missing gemname', hint: flag) if op.empty? && !op.arg?('system')
|
703
715
|
if flag == :pristine
|
@@ -733,8 +745,12 @@ module Squared
|
|
733
745
|
end
|
734
746
|
case flag
|
735
747
|
when 'exec', 'config'
|
736
|
-
|
737
|
-
|
748
|
+
if args.empty?
|
749
|
+
cmd << readline('Enter arguments', force: true)
|
750
|
+
else
|
751
|
+
args << command_args(args)
|
752
|
+
cmd.merge(args)
|
753
|
+
end
|
738
754
|
else
|
739
755
|
option_clear args
|
740
756
|
end
|
@@ -757,7 +773,7 @@ module Squared
|
|
757
773
|
def irb(name, opts = [], path: @path + 'lib', load: nil)
|
758
774
|
op = OptionPartition.new(opts, OPT_RUBY[:irb], session('irb'), project: self, first: [/\.rb$/])
|
759
775
|
r = as_a name
|
760
|
-
r.
|
776
|
+
r.prepend('bundler/setup') unless load
|
761
777
|
r.each { |val| op << shell_option('r', val, merge: true) }
|
762
778
|
as_a(path).each { |val| op << quote_option('I', val, merge: true) }
|
763
779
|
if load
|
@@ -811,14 +827,15 @@ module Squared
|
|
811
827
|
pwd_set(pass: !pwd.nil?) do
|
812
828
|
out = `#{gem_output(pwd, 'list --local -d', project)}`
|
813
829
|
if out =~ /#{Regexp.escape(project)} \(([^)]+)\)/
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
830
|
+
$1.split(/\s*,\s*/)
|
831
|
+
.prepend(@version)
|
832
|
+
.uniq
|
833
|
+
.each do |val|
|
834
|
+
next unless out =~ /\(#{Regexp.escape(val)}(?:,[^)]+|\b)\):([^\n]+)/
|
835
|
+
|
836
|
+
set.call(val, $1)
|
837
|
+
break
|
838
|
+
end
|
822
839
|
end
|
823
840
|
end
|
824
841
|
end
|