squared 0.6.4 → 0.6.6
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 +80 -0
- data/README.md +81 -27
- data/lib/squared/common/format.rb +8 -5
- data/lib/squared/common/shell.rb +7 -2
- data/lib/squared/config.rb +14 -12
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +16 -22
- data/lib/squared/workspace/project/base.rb +131 -83
- data/lib/squared/workspace/project/docker.rb +40 -44
- data/lib/squared/workspace/project/git.rb +64 -50
- data/lib/squared/workspace/project/node.rb +123 -105
- data/lib/squared/workspace/project/python.rb +119 -86
- data/lib/squared/workspace/project/ruby.rb +225 -113
- data/lib/squared/workspace/project/support/class.rb +26 -8
- data/lib/squared/workspace/project/support/optionpartition.rb +93 -42
- data/lib/squared/workspace/series.rb +3 -1
- data/lib/squared/workspace.rb +4 -3
- metadata +1 -1
|
@@ -7,9 +7,9 @@ module Squared
|
|
|
7
7
|
DEP_PYTHON = %w[poetry.lock setup.cfg pyproject.toml setup.py requirements.txt].freeze
|
|
8
8
|
DIR_PYTHON = (DEP_PYTHON + %w[README.rst]).freeze
|
|
9
9
|
OPT_PYTHON = {
|
|
10
|
-
common: %w[b=+ B d E h i I O P q=+ s S u v=+ x c=q m=b W=b X=q check-hash-based-pycs=b].freeze,
|
|
11
|
-
build: %w[n|no-isolation s|sdist x|skip-dependency-check v|verbose w|wheel
|
|
12
|
-
o|outdir=p].freeze,
|
|
10
|
+
common: %w[b=+ B d E h i I O P q=+ s S u v=+ V=+ x c=q m=b W=b X=q check-hash-based-pycs=b].freeze,
|
|
11
|
+
build: %w[C=bm n|no-isolation s|sdist x|skip-dependency-check v|verbose w|wheel config-json=q config-setting=q
|
|
12
|
+
installer=b o|outdir=p].freeze,
|
|
13
13
|
venv: %w[clear copies symlinks system-site-packages upgrade upgrade-deps without-scm-ignore-files without-pip
|
|
14
14
|
prompt=q].freeze
|
|
15
15
|
}.freeze
|
|
@@ -68,6 +68,7 @@ module Squared
|
|
|
68
68
|
sign-with=b u|username=q].freeze
|
|
69
69
|
}.freeze
|
|
70
70
|
PASS_PYTHON = {
|
|
71
|
+
python: %w[c v V].freeze,
|
|
71
72
|
pip: {
|
|
72
73
|
debug: %w[platform].freeze,
|
|
73
74
|
install: %w[C config-settings c constraint extra-index-url no-binary only-binary platform
|
|
@@ -178,7 +179,7 @@ module Squared
|
|
|
178
179
|
indexerror n, list
|
|
179
180
|
else
|
|
180
181
|
found |= 2
|
|
181
|
-
log.warn "run script #{n} of #{list.size}
|
|
182
|
+
log.warn "run script #{n} of #{list.size}".subhint('out of range')
|
|
182
183
|
end
|
|
183
184
|
else
|
|
184
185
|
case i
|
|
@@ -191,18 +192,18 @@ module Squared
|
|
|
191
192
|
else
|
|
192
193
|
raise_error "script: #{val}" if exception
|
|
193
194
|
found |= 2
|
|
194
|
-
log.warn "run script \"#{val}\"
|
|
195
|
+
log.warn "run script \"#{val}\"".subhint('not indexed')
|
|
195
196
|
end
|
|
196
197
|
end
|
|
197
198
|
end
|
|
198
199
|
end
|
|
199
200
|
break
|
|
200
201
|
end
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
202
|
+
next if found.anybits?(1)
|
|
203
|
+
|
|
204
|
+
puts log_message(found == 0 ? Logger::INFO : Logger.WARN,
|
|
205
|
+
"no scripts #{found == 0 ? 'found' : 'executed'}",
|
|
206
|
+
subject: name, hint: pyprojectfile)
|
|
206
207
|
end
|
|
207
208
|
when 'exec'
|
|
208
209
|
format_desc action, nil, ':|command,args*'
|
|
@@ -234,11 +235,12 @@ module Squared
|
|
|
234
235
|
when :remove
|
|
235
236
|
next unless projectpath?(venv)
|
|
236
237
|
|
|
237
|
-
format_desc action, flag, 'c/reate?,d/epend
|
|
238
|
+
format_desc action, flag, 'c/reate?,d/epend?,opts*'
|
|
238
239
|
task flag do |_, args|
|
|
240
|
+
args = args.to_a
|
|
239
241
|
rm_rf(venv, verbose: true)
|
|
240
|
-
venv_init if has_value
|
|
241
|
-
depend if has_value
|
|
242
|
+
venv_init if has_value!(args, 'c', 'create')
|
|
243
|
+
depend :force, args if has_value!(args, 'd', 'depend')
|
|
242
244
|
end
|
|
243
245
|
when :exec
|
|
244
246
|
format_desc action, flag, 'command,args*'
|
|
@@ -286,11 +288,11 @@ module Squared
|
|
|
286
288
|
pip(flag, opts: args.to_a, banner: true)
|
|
287
289
|
end
|
|
288
290
|
when :reinstall
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
291
|
+
next unless venv && projectpath?(venv)
|
|
292
|
+
|
|
293
|
+
format_desc action, flag
|
|
294
|
+
task flag do
|
|
295
|
+
ns['venv:remove'].invoke('depend')
|
|
294
296
|
end
|
|
295
297
|
end
|
|
296
298
|
when 'install'
|
|
@@ -309,7 +311,7 @@ module Squared
|
|
|
309
311
|
install flag, (case args.strategy
|
|
310
312
|
when 'eager'
|
|
311
313
|
'eager'
|
|
312
|
-
when
|
|
314
|
+
when /^only-if|needed$/
|
|
313
315
|
'only-if-needed'
|
|
314
316
|
end.yield_self do |val|
|
|
315
317
|
if val
|
|
@@ -330,7 +332,7 @@ module Squared
|
|
|
330
332
|
end
|
|
331
333
|
end
|
|
332
334
|
when 'outdated'
|
|
333
|
-
format_desc(action, flag, "eager?,no-deps?,#{shortname('h', 'i', 's', 'd')}",
|
|
335
|
+
format_desc(action, flag, "eager?,no-deps?,#{shortname('h', 'i', 's', 'u', 'd')}",
|
|
334
336
|
before: ('user?' unless venv))
|
|
335
337
|
task flag do |_, args|
|
|
336
338
|
outdated flag, args.to_a
|
|
@@ -408,18 +410,28 @@ module Squared
|
|
|
408
410
|
def outdated(flag = nil, opts = [], sync: invoked_sync?('outdated', flag))
|
|
409
411
|
cmd = pip_session 'list --outdated'
|
|
410
412
|
cmd << if flag
|
|
411
|
-
se = has_value!
|
|
413
|
+
se = has_value! opts, 's', 'select'
|
|
412
414
|
ia = has_value!(opts, 'i', 'interactive') && !se
|
|
415
|
+
up = has_value! opts, 'u', 'update'
|
|
413
416
|
hide = has_value! opts, 'h', 'hide'
|
|
414
417
|
dryrun = has_value! opts, 'd', 'dry-run'
|
|
415
418
|
if !sync || stdin?
|
|
416
419
|
se = false
|
|
417
420
|
ia = false
|
|
418
421
|
elsif se || ia
|
|
422
|
+
up = true
|
|
419
423
|
items = []
|
|
420
424
|
end
|
|
421
425
|
'--not-required' if opts.include?('no-deps')
|
|
422
426
|
else
|
|
427
|
+
if (up = option('u', 'update'))
|
|
428
|
+
flag = case up
|
|
429
|
+
when 'major', 'minor'
|
|
430
|
+
up.to_sym
|
|
431
|
+
else
|
|
432
|
+
:patch
|
|
433
|
+
end
|
|
434
|
+
end
|
|
423
435
|
'--not-required' unless option('not-required', equals: '0')
|
|
424
436
|
end
|
|
425
437
|
cmd << '--local' if option('l', 'local')
|
|
@@ -441,11 +453,10 @@ module Squared
|
|
|
441
453
|
buffer = []
|
|
442
454
|
out = ->(val) { sync ? puts(val) : buffer << val }
|
|
443
455
|
if workspace.windows?
|
|
444
|
-
(venv ? command(runenv, cmd) : `#{cmd}`).lines
|
|
456
|
+
(venv ? command(runenv, cmd) : `#{cmd}`).lines(chomp: true)
|
|
445
457
|
else
|
|
446
|
-
IO.popen(runenv || {}, cmd)
|
|
458
|
+
IO.popen(runenv || {}, cmd).readlines(chomp: true)
|
|
447
459
|
end.each do |line|
|
|
448
|
-
line.chomp!
|
|
449
460
|
next if line.match?(/^[ -]+$/)
|
|
450
461
|
|
|
451
462
|
if start > 0
|
|
@@ -506,34 +517,33 @@ module Squared
|
|
|
506
517
|
puts buffer
|
|
507
518
|
end
|
|
508
519
|
if found > 0
|
|
509
|
-
if se
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
+
items = if se
|
|
521
|
+
choice('Select a package', items.map(&:first),
|
|
522
|
+
multiple: true, force: false, index: true, border: true).map! { |n| items[n.pred].last }
|
|
523
|
+
elsif ia
|
|
524
|
+
items.map(&:last)
|
|
525
|
+
else
|
|
526
|
+
case flag
|
|
527
|
+
when :major
|
|
528
|
+
major + minor + patch
|
|
529
|
+
when :minor
|
|
530
|
+
minor + patch
|
|
531
|
+
else
|
|
532
|
+
patch
|
|
533
|
+
end
|
|
534
|
+
end
|
|
535
|
+
if up && !items.empty?
|
|
536
|
+
base = %w[eager no-deps]
|
|
537
|
+
base << 'user' unless venv
|
|
538
|
+
opts = (base & opts).map! { |val| val == 'eager' ? "upgrade-strategy=#{val}" : val }
|
|
539
|
+
if dryrun
|
|
540
|
+
opts.map! { |val| fill_option(val) }
|
|
541
|
+
print_run pip_output('install --upgrade', *opts, *items.quote!), false
|
|
520
542
|
else
|
|
521
|
-
|
|
543
|
+
install(:upgrade, opts, packages: items, banner: false)
|
|
522
544
|
end
|
|
523
|
-
end.tap do |packages|
|
|
524
|
-
unless packages.empty?
|
|
525
|
-
base = %w[eager no-deps]
|
|
526
|
-
base << 'user' unless venv
|
|
527
|
-
opts = (base & opts).map! { |val| val == 'eager' ? "upgrade-strategy=#{val}" : val }
|
|
528
|
-
if dryrun
|
|
529
|
-
opts.map! { |val| fill_option(val) }
|
|
530
|
-
print_run pip_output('install --upgrade', *opts, *packages.quote!), false
|
|
531
|
-
else
|
|
532
|
-
install(:upgrade, opts, packages: packages, banner: false)
|
|
533
|
-
end
|
|
534
|
-
end
|
|
535
|
-
print_status(major.size, minor.size, patch.size, from: :outdated)
|
|
536
545
|
end
|
|
546
|
+
print_status(major.size, minor.size, patch.size, from: :outdated)
|
|
537
547
|
elsif start == 0 || hide
|
|
538
548
|
puts 'No updates were found'
|
|
539
549
|
end
|
|
@@ -653,6 +663,27 @@ module Squared
|
|
|
653
663
|
run(from: :"#{flag}:publish", interactive: ['Publish', 'N', project])
|
|
654
664
|
end
|
|
655
665
|
|
|
666
|
+
def python(*args, sync: true, banner: verbose?, with: nil, pass: PASS_PYTHON[:python], **kwargs)
|
|
667
|
+
op = OptionPartition.new(session_opts(with, args: args, kwargs: kwargs, pass: pass), OPT_PYTHON[:common],
|
|
668
|
+
session('python', path: venv.nil?),
|
|
669
|
+
project: self, multiple: [/^-c/], single: singleopt(:python), args: true,
|
|
670
|
+
stdin: true)
|
|
671
|
+
op.concat(args)
|
|
672
|
+
if op.include?('-')
|
|
673
|
+
op.exist?(add: true)
|
|
674
|
+
else
|
|
675
|
+
op.append_any { |val| OptionPartition.parse_arg!('c', val) }
|
|
676
|
+
if op.arg?('c')
|
|
677
|
+
op.clear
|
|
678
|
+
else
|
|
679
|
+
op.exist?(add: true, first: true) unless op.arg?('m')
|
|
680
|
+
op.append(escape: kwargs.fetch(:escape, false), quote: kwargs.fetch(:quote, false))
|
|
681
|
+
end
|
|
682
|
+
end
|
|
683
|
+
print_run(op, banner, **kwargs)
|
|
684
|
+
run(sync: sync, banner: banner, exception: kwargs.fetch(:exception, exception), from: :python)
|
|
685
|
+
end
|
|
686
|
+
|
|
656
687
|
def pip(flag, *args, sync: true, banner: verbose?, with: nil, pass: nil, **kwargs)
|
|
657
688
|
flag = flag.to_sym
|
|
658
689
|
pass = PASS_PYTHON[:pip].fetch(pip_install?(flag) ? :install : flag, []) + %w[v verbose] if pass.nil?
|
|
@@ -726,29 +757,30 @@ module Squared
|
|
|
726
757
|
op.clear
|
|
727
758
|
end
|
|
728
759
|
print_run(op, banner, **kwargs)
|
|
729
|
-
run(sync: sync, banner: banner, from: :"pip:#{flag}")
|
|
760
|
+
run(sync: sync, banner: banner, exception: kwargs.fetch(:exception, exception), from: :"pip:#{flag}")
|
|
761
|
+
.yield_self { |val| ret || val }
|
|
730
762
|
end
|
|
731
763
|
|
|
732
|
-
def variable_set(key, *
|
|
764
|
+
def variable_set(key, *args, **, &blk)
|
|
733
765
|
if block_given?
|
|
734
766
|
case key
|
|
735
767
|
when :dependfile, :venv, :editable
|
|
736
|
-
|
|
768
|
+
args = block_args args, &blk
|
|
737
769
|
end
|
|
738
770
|
end
|
|
739
771
|
case key
|
|
740
772
|
when :dependfile
|
|
741
|
-
|
|
742
|
-
if (index = DEP_PYTHON.index(
|
|
773
|
+
val = basepath(*args)
|
|
774
|
+
if (index = DEP_PYTHON.index(val.basename.to_s))
|
|
743
775
|
@dependindex = index
|
|
744
|
-
@dependfile =
|
|
776
|
+
@dependfile = val
|
|
745
777
|
else
|
|
746
|
-
log.warn "variable_set: @#{key}=#{
|
|
778
|
+
log.warn "variable_set: @#{key}=#{val} (not supported)"
|
|
747
779
|
end
|
|
748
780
|
when :editable
|
|
749
|
-
editable_set
|
|
781
|
+
editable_set args.first
|
|
750
782
|
when :venv
|
|
751
|
-
instance_variable_set(:"@#{key}", (basepath(*
|
|
783
|
+
instance_variable_set(:"@#{key}", (basepath(*args) unless args.empty?))
|
|
752
784
|
else
|
|
753
785
|
super
|
|
754
786
|
end
|
|
@@ -775,14 +807,14 @@ module Squared
|
|
|
775
807
|
def python_session(*cmd, opts: nil)
|
|
776
808
|
return session('python', *preopts(quiet: false), *cmd, path: venv.nil?) unless opts
|
|
777
809
|
|
|
778
|
-
op = OptionPartition.new(opts, OPT_PYTHON[:common], project: self, single:
|
|
810
|
+
op = OptionPartition.new(opts, OPT_PYTHON[:common], project: self, single: singleopt(:python))
|
|
779
811
|
[session('python', *op.to_a, *cmd, path: venv.nil?), op.extras]
|
|
780
812
|
end
|
|
781
813
|
|
|
782
814
|
def poetry_session(*cmd)
|
|
783
|
-
session('poetry', *cmd, *preopts)
|
|
784
|
-
|
|
785
|
-
|
|
815
|
+
ret = session('poetry', *cmd, *preopts)
|
|
816
|
+
option('project', ignore: false) { |val| ret << quote_option('project', basepath(val)) }
|
|
817
|
+
ret
|
|
786
818
|
end
|
|
787
819
|
|
|
788
820
|
def pdm_session(*cmd, opts: nil)
|
|
@@ -849,7 +881,7 @@ module Squared
|
|
|
849
881
|
def append_editable(target: @session)
|
|
850
882
|
return if requirements? && editable == '.'
|
|
851
883
|
|
|
852
|
-
if (val = option('
|
|
884
|
+
if (val = option('e', 'editable', target: target, ignore: false))
|
|
853
885
|
OptionPartition.delete_key(target, 'e', 'editable')
|
|
854
886
|
case val
|
|
855
887
|
when '0', 'false'
|
|
@@ -873,7 +905,7 @@ module Squared
|
|
|
873
905
|
quote_option 'cache-dir', basepath(val)
|
|
874
906
|
end
|
|
875
907
|
end,
|
|
876
|
-
option('proxy', target: target) { |val|
|
|
908
|
+
option('proxy', target: target) { |val| quote_option('proxy', val) },
|
|
877
909
|
option('python', target: target) { |val| quote_option('python', basepath(val)) }
|
|
878
910
|
])
|
|
879
911
|
append_nocolor(target: target)
|
|
@@ -947,15 +979,14 @@ module Squared
|
|
|
947
979
|
end
|
|
948
980
|
|
|
949
981
|
def pyprojectfile
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
@pyprojectfile = (file = basepath(DEP_PYTHON[2])).exist? ? file : false
|
|
982
|
+
@pyprojectfile = basepath!(DEP_PYTHON[2]) || false if @pyprojectfile.nil?
|
|
983
|
+
@pyprojectfile || nil
|
|
953
984
|
end
|
|
954
985
|
|
|
955
986
|
def singleopt(flag = nil)
|
|
956
987
|
case flag
|
|
957
988
|
when :python
|
|
958
|
-
/\A(?:v+|q+|b+)\z/
|
|
989
|
+
/\A(?:v+|q+|b+|V+|O+)\z/
|
|
959
990
|
when :pdm
|
|
960
991
|
/\Av+\z/
|
|
961
992
|
when :twine
|
|
@@ -966,14 +997,14 @@ module Squared
|
|
|
966
997
|
end
|
|
967
998
|
|
|
968
999
|
def preopts(quiet: true)
|
|
969
|
-
[]
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
end
|
|
1000
|
+
ret = []
|
|
1001
|
+
case verbose
|
|
1002
|
+
when FalseClass
|
|
1003
|
+
ret << '--quiet' if quiet
|
|
1004
|
+
when Numeric
|
|
1005
|
+
ret << "-#{'v' * verbose}" if verbose > 0
|
|
976
1006
|
end
|
|
1007
|
+
ret
|
|
977
1008
|
end
|
|
978
1009
|
|
|
979
1010
|
def variables
|
|
@@ -1006,20 +1037,21 @@ module Squared
|
|
|
1006
1037
|
def venv_set(val)
|
|
1007
1038
|
return unless val
|
|
1008
1039
|
|
|
1040
|
+
write = ->(level, hint) { log.add(level, "venv: #{@venv}".subhint(hint)) }
|
|
1009
1041
|
if val.is_a?(Array)
|
|
1010
1042
|
val, *opts = val
|
|
1011
1043
|
@venvopts = opts
|
|
1012
1044
|
end
|
|
1013
|
-
@venv = basepath
|
|
1045
|
+
@venv = basepath val
|
|
1014
1046
|
if projectpath?(@venv)
|
|
1015
1047
|
if @venv.exist?
|
|
1016
|
-
|
|
1017
|
-
elsif
|
|
1048
|
+
write.call(Logger::DEBUG, 'found')
|
|
1049
|
+
elsif path.directory? && !path.empty?
|
|
1018
1050
|
@venv.mkpath
|
|
1019
|
-
|
|
1051
|
+
write.call(Logger::INFO, 'mkdir')
|
|
1020
1052
|
end
|
|
1021
1053
|
elsif !@venv.directory?
|
|
1022
|
-
|
|
1054
|
+
write.call(Logger::WARN, 'invalid')
|
|
1023
1055
|
@venv = nil
|
|
1024
1056
|
end
|
|
1025
1057
|
end
|
|
@@ -1027,20 +1059,21 @@ module Squared
|
|
|
1027
1059
|
def venv_init
|
|
1028
1060
|
return if !venv || (venvbin.directory? && !venvbin.empty?)
|
|
1029
1061
|
|
|
1030
|
-
puts log_message(venv, subject: 'venv', hint: 'init')
|
|
1062
|
+
puts log_message(venv, subject: 'venv', hint: 'init') unless silent?
|
|
1031
1063
|
opts = @venvopts&.map { |val| OptionPartition.strip(val) }&.flatten
|
|
1032
1064
|
venv_create(venv, opts || ["prompt=#{name}", 'upgrade-deps'], env: false, banner: false)
|
|
1033
|
-
puts log_message(venv, subject: 'venv', hint: 'created')
|
|
1065
|
+
puts log_message(venv, subject: 'venv', hint: 'created') unless silent?
|
|
1034
1066
|
end
|
|
1035
1067
|
|
|
1036
|
-
def venv_create(dir, opts = [], env: nil, banner:
|
|
1068
|
+
def venv_create(dir, opts = [], env: nil, banner: banner?)
|
|
1037
1069
|
cmd, opts = python_session('-m venv', opts: opts)
|
|
1038
1070
|
op = OptionPartition.new(opts, OPT_PYTHON[:venv], cmd, project: self)
|
|
1039
1071
|
status = op.append(dir, delim: true)
|
|
1040
1072
|
.clear(pass: false)
|
|
1041
1073
|
.arg?(/\A-v+\z/)
|
|
1042
|
-
run(op, env, exception: true, banner: banner)
|
|
1043
|
-
|
|
1074
|
+
success?(run(op, env, exception: true, banner: banner), banner, !status) do |ret|
|
|
1075
|
+
puts(ret && dir.directory? ? "Success: #{dir}" : 'Failed')
|
|
1076
|
+
end
|
|
1044
1077
|
end
|
|
1045
1078
|
|
|
1046
1079
|
def pip_install?(flag)
|
|
@@ -1061,7 +1094,7 @@ module Squared
|
|
|
1061
1094
|
end
|
|
1062
1095
|
|
|
1063
1096
|
def installable?
|
|
1064
|
-
setuptools? ||
|
|
1097
|
+
setuptools? || !!pyprojectfile
|
|
1065
1098
|
end
|
|
1066
1099
|
|
|
1067
1100
|
def setuptools?
|