squared 0.8.3 → 0.8.5
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 +112 -6
- data/README.md +8 -9
- data/lib/squared/common/base.rb +1 -0
- data/lib/squared/common/format.rb +2 -1
- data/lib/squared/common/host.rb +39 -0
- data/lib/squared/common/prompt.rb +4 -3
- data/lib/squared/common/shell.rb +13 -12
- data/lib/squared/common/utils.rb +7 -4
- data/lib/squared/common.rb +1 -0
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +5 -27
- data/lib/squared/workspace/project/base.rb +41 -17
- data/lib/squared/workspace/project/docker.rb +215 -147
- data/lib/squared/workspace/project/git.rb +125 -113
- data/lib/squared/workspace/project/node.rb +69 -36
- data/lib/squared/workspace/project/python.rb +13 -9
- data/lib/squared/workspace/project/ruby.rb +13 -12
- data/lib/squared/workspace/project/support/optionpartition.rb +108 -53
- data/lib/squared/workspace/repo.rb +3 -2
- data/lib/squared/workspace/series.rb +2 -2
- metadata +3 -2
|
@@ -18,6 +18,7 @@ module Squared
|
|
|
18
18
|
pack: %w[ignore-scripts=!? json=!? pack-destination=p].freeze,
|
|
19
19
|
rebuild: %w[bin-links=! foreground-scripts=!? global=!? ignore-scripts=!? install-links=!?].freeze,
|
|
20
20
|
'approve-scripts': %w[a|all allow-scripts-pending allow-scripts-pin=!? no-allow-scripts-pin json].freeze,
|
|
21
|
+
'deny-scripts': %w[a|all json].freeze,
|
|
21
22
|
no: {
|
|
22
23
|
install: %w[audit bin-links fund package-lock].freeze
|
|
23
24
|
}.freeze
|
|
@@ -254,7 +255,8 @@ module Squared
|
|
|
254
255
|
when 'exec'
|
|
255
256
|
format_desc action, nil, 'pkg/cmd,opts*,args*'
|
|
256
257
|
task action, [:package] do |_, args|
|
|
257
|
-
|
|
258
|
+
package = args.package
|
|
259
|
+
if package
|
|
258
260
|
args = args.extras
|
|
259
261
|
cmd = if pnpm?
|
|
260
262
|
pre = ->(ch) { "-#{ch}" if args.delete(ch) }
|
|
@@ -267,9 +269,10 @@ module Squared
|
|
|
267
269
|
op = OptionPartition.new(args, list, cmd, project: self, strict: strict?)
|
|
268
270
|
if op.empty?
|
|
269
271
|
op << package
|
|
270
|
-
|
|
272
|
+
s = readline('Enter arguments', force: false)
|
|
273
|
+
if s
|
|
271
274
|
op.delim unless pnpm?
|
|
272
|
-
op <<
|
|
275
|
+
op << s
|
|
273
276
|
end
|
|
274
277
|
else
|
|
275
278
|
op.delim unless pnpm?
|
|
@@ -281,20 +284,21 @@ module Squared
|
|
|
281
284
|
run(from: :exec)
|
|
282
285
|
end
|
|
283
286
|
when 'nvm'
|
|
284
|
-
next unless ENV['NVM_DIR'] && !
|
|
287
|
+
next unless ENV['NVM_DIR'] && !windows?
|
|
285
288
|
|
|
286
289
|
format_desc action, nil, 'version?,args*'
|
|
287
290
|
task action, [:version] do |_, args|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
+
version = args.version
|
|
292
|
+
args = args.extras
|
|
293
|
+
append = ->(s) { shell_quote(File.join(ENV['NVM_DIR'], s)) }
|
|
294
|
+
unless version
|
|
295
|
+
cmd = ". #{append.call('nvm.sh')} && nvm list --no-colors --no-alias"
|
|
291
296
|
version = pwd_set(from: :nvm) do
|
|
292
297
|
choice_index('Select a version', IO.popen(cmd).map { |line| line[/\s(v\S+)/, 1] }, series: true)
|
|
293
298
|
end
|
|
294
299
|
end
|
|
295
|
-
args = args.extras
|
|
296
300
|
args << readline('Enter command', force: true) if args.empty?
|
|
297
|
-
args.unshift(
|
|
301
|
+
args.unshift(append.call('nvm-exec'))
|
|
298
302
|
run(args.join(' '), { 'NODE_VERSION' => version }, banner: false, from: :nvm)
|
|
299
303
|
end
|
|
300
304
|
when 'bump'
|
|
@@ -325,20 +329,48 @@ module Squared
|
|
|
325
329
|
outdated flag, args.to_a
|
|
326
330
|
end
|
|
327
331
|
when 'package'
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
332
|
+
case flag
|
|
333
|
+
when :approve, :deny
|
|
334
|
+
format_desc action, flag, 'name*|:,opts*'
|
|
335
|
+
task flag do |_, args|
|
|
336
|
+
args = args.to_a
|
|
337
|
+
if choice!(args)
|
|
338
|
+
pwd_set do
|
|
339
|
+
pad = 0
|
|
340
|
+
list = IO.popen(npm_output('approve-scripts --allow-scripts-pending').to_s)
|
|
341
|
+
.each_with_object([]) do |line, out|
|
|
342
|
+
next unless line =~ /^\s+([a-z\d@][^@]*)@(\S+)/
|
|
343
|
+
|
|
344
|
+
pad = [pad, $1.size].max
|
|
345
|
+
out << [$1, $2]
|
|
346
|
+
end
|
|
347
|
+
.map { |name, ver| name.ljust(pad + 4) + ver }
|
|
348
|
+
if list.empty?
|
|
349
|
+
puts log_message('no packages to review', subject: name, hint: "#{flag}-scripts")
|
|
350
|
+
exit 0
|
|
351
|
+
end
|
|
352
|
+
args.concat(choice_index('Select packages', list, multiple: true, column: /^(\S+)/))
|
|
353
|
+
end
|
|
354
|
+
end
|
|
355
|
+
package flag, args
|
|
356
|
+
end
|
|
357
|
+
else
|
|
358
|
+
format_desc(action, flag, 'opts*', before: case flag
|
|
359
|
+
when :dedupe, :rebuild then nil
|
|
360
|
+
when :reinstall then 'f/orce?'
|
|
361
|
+
else 'name*'
|
|
362
|
+
end)
|
|
363
|
+
task flag do |_, args|
|
|
364
|
+
package flag, args.to_a
|
|
365
|
+
end
|
|
335
366
|
end
|
|
336
367
|
when 'publish'
|
|
337
368
|
if flag == :verify
|
|
338
369
|
format_desc action, flag, 'version?,ext*'
|
|
339
370
|
task flag, [:version] do |_, args|
|
|
371
|
+
version = args.version
|
|
340
372
|
ext = args.extras
|
|
341
|
-
if
|
|
373
|
+
if version&.match?(/^\.?[a-z]+$/i)
|
|
342
374
|
ext.unshift(version)
|
|
343
375
|
version = nil
|
|
344
376
|
end
|
|
@@ -362,7 +394,7 @@ module Squared
|
|
|
362
394
|
elsif has_value!(args, 'p', 'public')
|
|
363
395
|
'public'
|
|
364
396
|
end
|
|
365
|
-
dryrun = has_value!
|
|
397
|
+
dryrun = has_value! args, 'd', 'dry-run'
|
|
366
398
|
end
|
|
367
399
|
case flag
|
|
368
400
|
when :stage
|
|
@@ -379,7 +411,7 @@ module Squared
|
|
|
379
411
|
[ver, tag, item['id'], item['actor']]
|
|
380
412
|
end
|
|
381
413
|
if data.empty?
|
|
382
|
-
print_error('no staged releases',
|
|
414
|
+
print_error(Logger::INFO, 'no staged releases', subject: npmname)
|
|
383
415
|
exit 1
|
|
384
416
|
end
|
|
385
417
|
data.each do |item|
|
|
@@ -424,7 +456,7 @@ module Squared
|
|
|
424
456
|
@tsfile
|
|
425
457
|
end
|
|
426
458
|
end
|
|
427
|
-
watch = has_value!
|
|
459
|
+
watch = has_value! args, 'w', 'watch'
|
|
428
460
|
tsc(*args, banner: true, project: project, build: flag == :build, watch: !watch.nil?)
|
|
429
461
|
end
|
|
430
462
|
end
|
|
@@ -630,7 +662,7 @@ module Squared
|
|
|
630
662
|
end
|
|
631
663
|
if nolockfile?(prefix: 'yarn')
|
|
632
664
|
cmd << '--no-lockfile'
|
|
633
|
-
elsif option('ci')
|
|
665
|
+
elsif option('ci') || (ci? && exist?('yarn.lock'))
|
|
634
666
|
if yarn == 1
|
|
635
667
|
cmd << '--frozen-lockfile'
|
|
636
668
|
elsif !flag
|
|
@@ -666,13 +698,14 @@ module Squared
|
|
|
666
698
|
'--force'
|
|
667
699
|
elsif nolockfile?(prefix: 'pnpm')
|
|
668
700
|
'--no-lockfile'
|
|
669
|
-
elsif option('ci')
|
|
701
|
+
elsif option('ci') || (ci? && exist?('pnpm-lock.yaml'))
|
|
670
702
|
'--frozen-lockfile'
|
|
671
703
|
end
|
|
672
704
|
cmd << '--ignore-scripts' if option('ignore-scripts')
|
|
673
705
|
cmd << '--dangerously-allow-all-builds' if option('approve-builds')
|
|
674
706
|
else
|
|
675
|
-
|
|
707
|
+
ci = option('ci', prefix: 'npm') || (ci? && exist?('package-lock.json'))
|
|
708
|
+
cmd = session('npm', ci ? 'ci' : 'install')
|
|
676
709
|
option('approve-scripts') do |val|
|
|
677
710
|
cmd = npm_output 'approve-scripts'
|
|
678
711
|
cmd << case val
|
|
@@ -841,7 +874,7 @@ module Squared
|
|
|
841
874
|
pending = 0
|
|
842
875
|
modified = 0
|
|
843
876
|
width = ->(a, i) { a.map { |aa| aa[i] }.max_by(&:size).size }
|
|
844
|
-
pad = ->(
|
|
877
|
+
pad = ->(a, n) { n.succ.to_s.rjust([a.size.to_s.size, 2].max) }
|
|
845
878
|
footer = lambda do |val, size|
|
|
846
879
|
return unless verbose
|
|
847
880
|
|
|
@@ -857,7 +890,7 @@ module Squared
|
|
|
857
890
|
if !found.empty?
|
|
858
891
|
col1 = width.call(found, 0) + 4
|
|
859
892
|
col2 = width.call(found, 1) + 4
|
|
860
|
-
col3 = pad.call(found
|
|
893
|
+
col3 = pad.call(found, found.size).size + 2 + col1 + col2 + width.call(found, 2)
|
|
861
894
|
packages = []
|
|
862
895
|
pat = ->(a) { /("#{Regexp.escape(a[0])}"\s*:\s*)"([~^])#{'?' if a[4]}#{Regexp.escape(a[1])}"/ }
|
|
863
896
|
edit = lambda do |a, pkg, mod|
|
|
@@ -879,21 +912,21 @@ module Squared
|
|
|
879
912
|
end
|
|
880
913
|
a = a.ljust(col1)
|
|
881
914
|
b = b.ljust(col2)
|
|
882
|
-
sub_style
|
|
915
|
+
b = sub_style b, theme[:current] if theme[:current] && !stdin?
|
|
883
916
|
if cur == -1
|
|
884
917
|
c = 'SKIP'
|
|
885
918
|
elsif modified == cur
|
|
886
919
|
c = 'FAIL'
|
|
887
920
|
elsif !stdin?
|
|
888
921
|
if d == 1
|
|
889
|
-
sub_style
|
|
890
|
-
sub_style
|
|
922
|
+
a = sub_style a, theme[:major]
|
|
923
|
+
c = sub_style c, :bold, color(:green)
|
|
891
924
|
else
|
|
892
|
-
sub_style
|
|
925
|
+
c = sub_style(c, **opt_style(color(d == 3 ? :green : :yellow), SEM_VER, d))
|
|
893
926
|
end
|
|
894
927
|
g = item
|
|
895
928
|
end
|
|
896
|
-
s = "#{pad.call(
|
|
929
|
+
s = "#{pad.call(found, i)}. #{a}#{b}#{c}"
|
|
897
930
|
if se
|
|
898
931
|
items << [s, g]
|
|
899
932
|
next
|
|
@@ -962,11 +995,11 @@ module Squared
|
|
|
962
995
|
b = sub_style b.ljust(col2), color(d ? :red : :yellow)
|
|
963
996
|
c = c.ljust(col3)
|
|
964
997
|
unless d
|
|
965
|
-
sub_style
|
|
966
|
-
sub_style
|
|
998
|
+
a = sub_style a, theme[:active]
|
|
999
|
+
c = sub_style c, color(:green)
|
|
967
1000
|
pending += 1
|
|
968
1001
|
end
|
|
969
|
-
puts "#{pad.call(
|
|
1002
|
+
puts "#{pad.call(avail, i)}. #{(a + c + b).subhint(d ? 'locked' : 'latest')}"
|
|
970
1003
|
end
|
|
971
1004
|
footer.call(0, avail.size)
|
|
972
1005
|
else
|
|
@@ -1589,10 +1622,10 @@ module Squared
|
|
|
1589
1622
|
modules.rmtree
|
|
1590
1623
|
rescue Timeout::Error => e
|
|
1591
1624
|
puts
|
|
1592
|
-
print_error(e, hint: modules, pass: true)
|
|
1625
|
+
print_error(e, subject: name, hint: modules, pass: true)
|
|
1593
1626
|
exit 1
|
|
1594
1627
|
rescue => e
|
|
1595
|
-
print_error(e, pass: true)
|
|
1628
|
+
print_error(e, subject: name, pass: true)
|
|
1596
1629
|
false
|
|
1597
1630
|
else
|
|
1598
1631
|
true
|
|
@@ -1639,7 +1672,7 @@ module Squared
|
|
|
1639
1672
|
end
|
|
1640
1673
|
|
|
1641
1674
|
def quotepath(name, val)
|
|
1642
|
-
if $2.include?(File::SEPARATOR) || (
|
|
1675
|
+
if $2.include?(File::SEPARATOR) || (windows? && val.match?(%r{[\\/]}))
|
|
1643
1676
|
quote_option name, basepath(val)
|
|
1644
1677
|
else
|
|
1645
1678
|
shell_option name, val
|
|
@@ -236,7 +236,7 @@ module Squared
|
|
|
236
236
|
format_desc action, nil, 'command|:,args*'
|
|
237
237
|
task action do |_, args|
|
|
238
238
|
args = args.to_a
|
|
239
|
-
cmd = if (i = args.delete(':')) && !
|
|
239
|
+
cmd = if (i = args.delete(':')) && !windows?
|
|
240
240
|
readline('Enter script', force: true, multiline: %w[## ;])
|
|
241
241
|
elsif i || args.empty?
|
|
242
242
|
readline('Enter command', force: true)
|
|
@@ -502,7 +502,7 @@ module Squared
|
|
|
502
502
|
patch = []
|
|
503
503
|
buffer = []
|
|
504
504
|
out = ->(val) { sync ? puts(val) : buffer << val }
|
|
505
|
-
if
|
|
505
|
+
if windows?
|
|
506
506
|
(venv ? command(runenv, cmd) : `#{cmd}`).lines(chomp: true)
|
|
507
507
|
else
|
|
508
508
|
IO.popen(runenv || {}, cmd).readlines(chomp: true)
|
|
@@ -617,7 +617,7 @@ module Squared
|
|
|
617
617
|
|
|
618
618
|
op << "--#{flag}"
|
|
619
619
|
op.append
|
|
620
|
-
python_session('-m pip', *op.to_a.drop(1)) if
|
|
620
|
+
python_session('-m pip', *op.to_a.drop(1)) if windows?
|
|
621
621
|
end
|
|
622
622
|
end
|
|
623
623
|
run(banner: banner, from: :install)
|
|
@@ -1009,7 +1009,7 @@ module Squared
|
|
|
1009
1009
|
@build_backend ||= read_pyproject('build-system', 'build-backend') || ''
|
|
1010
1010
|
end
|
|
1011
1011
|
|
|
1012
|
-
def read_pyproject(table,
|
|
1012
|
+
def read_pyproject(table, *keys)
|
|
1013
1013
|
return [] unless (file = pyprojectfile)
|
|
1014
1014
|
|
|
1015
1015
|
ret = (@pyproject ||= {})[table]
|
|
@@ -1074,7 +1074,11 @@ module Squared
|
|
|
1074
1074
|
end
|
|
1075
1075
|
@pyproject[table] = ret
|
|
1076
1076
|
end
|
|
1077
|
-
|
|
1077
|
+
unless keys.empty?
|
|
1078
|
+
ret.select! { |key,| keys.include?(key) }
|
|
1079
|
+
return ret.first&.last if keys.size == 1
|
|
1080
|
+
end
|
|
1081
|
+
ret
|
|
1078
1082
|
end
|
|
1079
1083
|
|
|
1080
1084
|
def pyprojectfile
|
|
@@ -1132,15 +1136,15 @@ module Squared
|
|
|
1132
1136
|
def runenv
|
|
1133
1137
|
return unless venv
|
|
1134
1138
|
|
|
1135
|
-
if
|
|
1136
|
-
shell_quote(venvbin.join(
|
|
1139
|
+
if windows?
|
|
1140
|
+
shell_quote(venvbin.join(powershell? ? 'Activate.ps1' : 'activate.bat'), option: false)
|
|
1137
1141
|
else
|
|
1138
1142
|
{ 'VIRTUAL_ENV' => venv.to_s, 'PATH' => "#{venvbin}:#{ENV['PATH']}" }
|
|
1139
1143
|
end
|
|
1140
1144
|
end
|
|
1141
1145
|
|
|
1142
1146
|
def venvbin
|
|
1143
|
-
@venv&.join(
|
|
1147
|
+
@venv&.join(windows? ? 'Scripts' : 'bin')
|
|
1144
1148
|
end
|
|
1145
1149
|
|
|
1146
1150
|
def editable_set(val)
|
|
@@ -1215,7 +1219,7 @@ module Squared
|
|
|
1215
1219
|
success?(ret, banner, !status) do |out|
|
|
1216
1220
|
if out && dir.directory?
|
|
1217
1221
|
if poetry?
|
|
1218
|
-
dir += (
|
|
1222
|
+
dir += (windows? ? 'Scripts/python.exe' : 'bin/python')
|
|
1219
1223
|
cmd = poetry_session 'env use'
|
|
1220
1224
|
else
|
|
1221
1225
|
puts "Success: #{dir}"
|
|
@@ -541,8 +541,9 @@ module Squared
|
|
|
541
541
|
when :file
|
|
542
542
|
format_desc action, flag, 'path,opts*,args*'
|
|
543
543
|
task flag, [:rb] do |_, args|
|
|
544
|
+
file = args.rb
|
|
544
545
|
opts = args.extras
|
|
545
|
-
args = Array(if
|
|
546
|
+
args = Array(if file && !file.include?('*')
|
|
546
547
|
ENV['RUBY_ARGS']
|
|
547
548
|
else
|
|
548
549
|
a, b, c = choice_index('Select a file', Dir.glob(file || '*.rb', base: path),
|
|
@@ -564,7 +565,7 @@ module Squared
|
|
|
564
565
|
task flag do |_, args|
|
|
565
566
|
args = args.to_a
|
|
566
567
|
multiline = case args.first
|
|
567
|
-
when ';',
|
|
568
|
+
when ';', /^#+$/
|
|
568
569
|
args.shift
|
|
569
570
|
else
|
|
570
571
|
%w[## ;]
|
|
@@ -650,7 +651,7 @@ module Squared
|
|
|
650
651
|
ver = nil
|
|
651
652
|
`ruby --version`
|
|
652
653
|
end)
|
|
653
|
-
unless
|
|
654
|
+
unless windows?
|
|
654
655
|
if vm
|
|
655
656
|
out << trim.call(case vm
|
|
656
657
|
when 'chruby'
|
|
@@ -843,11 +844,11 @@ module Squared
|
|
|
843
844
|
def outdated(flag = nil, opts = [], sync: invoked_sync?('outdated', flag))
|
|
844
845
|
cmd = bundle_output 'outdated'
|
|
845
846
|
if flag
|
|
846
|
-
se = has_value!
|
|
847
|
+
se = has_value! opts, 's', 'select'
|
|
847
848
|
ia = has_value!(opts, 'i', 'interactive') && !se
|
|
848
|
-
up = has_value!
|
|
849
|
+
up = has_value! opts, 'u', 'update'
|
|
849
850
|
opts << 'only-explicit' if has_value!(opts, 'e', 'explicit')
|
|
850
|
-
dryrun = has_value!
|
|
851
|
+
dryrun = has_value! opts, 'd', 'dry-run'
|
|
851
852
|
if !sync || stdin?
|
|
852
853
|
se = false
|
|
853
854
|
ia = false
|
|
@@ -1581,12 +1582,12 @@ module Squared
|
|
|
1581
1582
|
def rdbg(*args, banner: verbose?, with: nil, pass: PASS_RUBY[:rdbg], **kwargs)
|
|
1582
1583
|
opts = session_opts(with, args: args, kwargs: kwargs, pass: pass)
|
|
1583
1584
|
cmd = session 'rdbg'
|
|
1584
|
-
args.each_with_index do |val,
|
|
1585
|
+
args.each_with_index do |val, i|
|
|
1585
1586
|
break if val == '--'
|
|
1586
1587
|
next unless exist?(val, type: 'f')
|
|
1587
1588
|
|
|
1588
|
-
args[
|
|
1589
|
-
cmd.merge(args.slice!(0,
|
|
1589
|
+
args[i] = shell_quote basepath(val)
|
|
1590
|
+
cmd.merge(args.slice!(0, i.succ))
|
|
1590
1591
|
break
|
|
1591
1592
|
end
|
|
1592
1593
|
op = OptionPartition.new(opts, OPT_RUBY[:rdbg], cmd, project: self, strict: strict?, first: [/\.rb$/])
|
|
@@ -1671,7 +1672,7 @@ module Squared
|
|
|
1671
1672
|
def serve(root, *, bind: nil, port: 3000, **kwargs)
|
|
1672
1673
|
require 'webrick'
|
|
1673
1674
|
rescue LoadError => e
|
|
1674
|
-
print_error(e, pass: true)
|
|
1675
|
+
print_error(e, subject: name, hint: 'webrick', pass: true)
|
|
1675
1676
|
else
|
|
1676
1677
|
config = kwargs.merge({ DocumentRoot: root })
|
|
1677
1678
|
config[:BindAddress] = bind if bind
|
|
@@ -1685,11 +1686,11 @@ module Squared
|
|
|
1685
1686
|
|
|
1686
1687
|
def vmname(bin: false)
|
|
1687
1688
|
order = { 'rbenv' => -1, 'rvm' => -1, 'chruby' => -1, 'asdf' => -1, 'mise' => -1 }
|
|
1688
|
-
ENV.fetch('PATH', '').split(':').each_with_index do |val,
|
|
1689
|
+
ENV.fetch('PATH', '').split(':').each_with_index do |val, i|
|
|
1689
1690
|
order.each_key do |key|
|
|
1690
1691
|
next unless val.match?(%r{[/.]#{key}/})
|
|
1691
1692
|
|
|
1692
|
-
order[key] =
|
|
1693
|
+
order[key] = i
|
|
1693
1694
|
break
|
|
1694
1695
|
end
|
|
1695
1696
|
end
|