squared 0.9.0 → 0.9.2
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 +84 -1
- data/README.md +13 -6
- data/exe/sqd +264 -73
- data/lib/squared/common/base.rb +2 -0
- data/lib/squared/common/format.rb +1 -1
- data/lib/squared/common/prompt.rb +26 -8
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +5 -0
- data/lib/squared/workspace/project/base.rb +13 -11
- data/lib/squared/workspace/project/docker.rb +4 -4
- data/lib/squared/workspace/project/git.rb +4 -4
- data/lib/squared/workspace/project/node.rb +36 -23
- data/lib/squared/workspace/project/python.rb +123 -56
- data/lib/squared/workspace/project/ruby.rb +30 -20
- data/lib/squared/workspace/project/support/optionpartition.rb +20 -18
- metadata +2 -2
|
@@ -5,12 +5,30 @@ require 'timeout'
|
|
|
5
5
|
module Squared
|
|
6
6
|
module Common
|
|
7
7
|
module Prompt
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
class << self
|
|
9
|
+
def reline
|
|
10
|
+
require 'reline'
|
|
11
|
+
Reline
|
|
12
|
+
rescue LoadError
|
|
13
|
+
require 'readline'
|
|
14
|
+
Readline
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def multiline=(val)
|
|
18
|
+
raise NotImplementedError, 'multiline is available only with reline' unless multiline?
|
|
19
|
+
|
|
20
|
+
@multiline = case val
|
|
21
|
+
when '', '0', 'false' then nil
|
|
22
|
+
else
|
|
23
|
+
val.split(',').map(&:strip)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def multiline?
|
|
28
|
+
reline.respond_to?(:readmultiline)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
attr_reader :multiline
|
|
14
32
|
end
|
|
15
33
|
|
|
16
34
|
module_function
|
|
@@ -169,8 +187,8 @@ module Squared
|
|
|
169
187
|
end
|
|
170
188
|
end
|
|
171
189
|
|
|
172
|
-
def readline(msg, history = false, force: nil, multiline:
|
|
173
|
-
multiline = nil unless Prompt.
|
|
190
|
+
def readline(msg, history = false, force: nil, multiline: Prompt.multiline, &blk)
|
|
191
|
+
multiline = nil unless Prompt.multiline?
|
|
174
192
|
read = lambda do
|
|
175
193
|
if !multiline
|
|
176
194
|
Prompt.reline.readline(msg, history)
|
data/lib/squared/version.rb
CHANGED
|
@@ -167,6 +167,11 @@ module Squared
|
|
|
167
167
|
@series.ref_min = app[:series_ref_min] if app.key?(:series_ref_min)
|
|
168
168
|
kwargs[:pattern].concat(app[:build_pattern]) if app.key?(:build_pattern)
|
|
169
169
|
kwargs[:parallel].concat(app[:build_parallel]) if app.key?(:build_parallel)
|
|
170
|
+
kwargs[:parallel].reject! { |val| app[:build_parallel!].include?(val) } if app.key?(:build_parallel!)
|
|
171
|
+
app[:build_pattern!]&.each do |pat|
|
|
172
|
+
kwargs[:pattern].delete(pat)
|
|
173
|
+
kwargs[:parallel].reject! { |val| pat.match?(val) }
|
|
174
|
+
end
|
|
170
175
|
self.closed = 'begin'
|
|
171
176
|
pb = @stage.key?('project:begin')
|
|
172
177
|
pe = @stage.key?('project:end')
|
|
@@ -607,10 +607,10 @@ module Squared
|
|
|
607
607
|
@clean.each do |val|
|
|
608
608
|
src = basepath(val = val.to_s)
|
|
609
609
|
if src.directory? && val.match?(%r{[\\/]\z})
|
|
610
|
-
log&.
|
|
610
|
+
log&.info "rm -rf #{src}"
|
|
611
611
|
rm_rf(src, verbose: !silent?)
|
|
612
612
|
else
|
|
613
|
-
log&.
|
|
613
|
+
log&.info "rm #{src}"
|
|
614
614
|
(val.include?('*') ? Dir[src] : [src]).each do |file|
|
|
615
615
|
next unless File.file?(file)
|
|
616
616
|
|
|
@@ -864,7 +864,7 @@ module Squared
|
|
|
864
864
|
instance_variable_set :"@#{key}", [blk]
|
|
865
865
|
end
|
|
866
866
|
else
|
|
867
|
-
log&.
|
|
867
|
+
log&.debug "series: @#{key}".subhint('invalid')
|
|
868
868
|
end
|
|
869
869
|
self
|
|
870
870
|
end
|
|
@@ -876,7 +876,7 @@ module Squared
|
|
|
876
876
|
return
|
|
877
877
|
end
|
|
878
878
|
cmd = cmd.target if cmd.is_a?(OptionPartition)
|
|
879
|
-
if interactive && sync && !(@session && option('y'))
|
|
879
|
+
if interactive && sync && !(@session && option('y', 'yes'))
|
|
880
880
|
print_item(series: true)
|
|
881
881
|
msg, y, h = case interactive
|
|
882
882
|
when Array
|
|
@@ -1019,7 +1019,7 @@ module Squared
|
|
|
1019
1019
|
instance_variable_set(:"@#{key}", val)
|
|
1020
1020
|
end
|
|
1021
1021
|
else
|
|
1022
|
-
log&.
|
|
1022
|
+
log&.debug "variable_set: @#{key}".subhint('private')
|
|
1023
1023
|
end
|
|
1024
1024
|
self
|
|
1025
1025
|
end
|
|
@@ -1701,7 +1701,7 @@ module Squared
|
|
|
1701
1701
|
ret = case key.downcase
|
|
1702
1702
|
when 'force'
|
|
1703
1703
|
getarg.call(:FORCE)
|
|
1704
|
-
when 'y'
|
|
1704
|
+
when 'y', 'yes'
|
|
1705
1705
|
getarg.call(:YES)
|
|
1706
1706
|
end
|
|
1707
1707
|
return yield(ret) if !ret.nil? && block_given?
|
|
@@ -2161,7 +2161,7 @@ module Squared
|
|
|
2161
2161
|
end
|
|
2162
2162
|
|
|
2163
2163
|
def confirm_basic(msg, hint, accept = 'Y', style: :inline, target: @session, prefix: target&.first, **kwargs)
|
|
2164
|
-
return true if option('y', prefix: prefix)
|
|
2164
|
+
return true if option('y', 'yes', prefix: prefix)
|
|
2165
2165
|
|
|
2166
2166
|
confirm("#{msg} [#{sub_style(hint.to_s, style.is_a?(Symbol) ? theme[style] : style)}]", accept, **kwargs)
|
|
2167
2167
|
end
|
|
@@ -2726,10 +2726,12 @@ module Squared
|
|
|
2726
2726
|
end
|
|
2727
2727
|
|
|
2728
2728
|
def checkdir?(val)
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2729
|
+
if val.directory? && !val.empty?
|
|
2730
|
+
true
|
|
2731
|
+
else
|
|
2732
|
+
log&.warn "directory \"#{val}\"".subhint(val.directory? ? 'empty' : 'missing')
|
|
2733
|
+
false
|
|
2734
|
+
end
|
|
2733
2735
|
end
|
|
2734
2736
|
|
|
2735
2737
|
def printfirst?
|
|
@@ -422,7 +422,7 @@ module Squared
|
|
|
422
422
|
def clean(*, sync: invoked_sync?('clean'), **)
|
|
423
423
|
if runnable?(@clean)
|
|
424
424
|
super
|
|
425
|
-
elsif sync || option('y', prefix: 'docker')
|
|
425
|
+
elsif sync || option('y', 'yes', prefix: 'docker')
|
|
426
426
|
image :rm
|
|
427
427
|
end
|
|
428
428
|
end
|
|
@@ -731,7 +731,7 @@ module Squared
|
|
|
731
731
|
return
|
|
732
732
|
end
|
|
733
733
|
op << id
|
|
734
|
-
if option('y')
|
|
734
|
+
if option('y', 'yes')
|
|
735
735
|
exception = false
|
|
736
736
|
banner = false
|
|
737
737
|
end
|
|
@@ -966,7 +966,7 @@ module Squared
|
|
|
966
966
|
pwd_set(from: from) do
|
|
967
967
|
index = 1
|
|
968
968
|
all = option('all', prefix: 'docker')
|
|
969
|
-
y = from == :'image:rm' && option('y', prefix: 'docker')
|
|
969
|
+
y = from == :'image:rm' && option('y', 'yes', prefix: 'docker')
|
|
970
970
|
filter = env('DOCKER_FILTER', filter).to_s
|
|
971
971
|
pat = if OptionPartition.pattern?(filter)
|
|
972
972
|
Regexp.new(filter)
|
|
@@ -1013,7 +1013,7 @@ module Squared
|
|
|
1013
1013
|
end
|
|
1014
1014
|
pad = cols.map(&:size).max
|
|
1015
1015
|
cols.each { |key| puts "#{g + f} #{key.rjust(pad)}: #{Array(data[key]).join(', ')}" }
|
|
1016
|
-
w = 9 + flag.to_s.size +
|
|
1016
|
+
w = 9 + flag.to_s.size + ARG[:TAB] + ee.size
|
|
1017
1017
|
puts g + sub_style(ARG[:BORDER][6] + (ARG[:BORDER][1] * w), theme[:inline])
|
|
1018
1018
|
index += 1
|
|
1019
1019
|
next unless confirm("#{h + b}?", no ? 'N' : 'Y')
|
|
@@ -363,7 +363,7 @@ module Squared
|
|
|
363
363
|
subtasks({
|
|
364
364
|
'branch' => %i[create track delete move copy list all current].freeze,
|
|
365
365
|
'checkout' => %i[commit branch track detach path].freeze,
|
|
366
|
-
'commit' => %i[head add all amend amend-orig fixup].freeze,
|
|
366
|
+
'commit' => %i[head add all pathspec amend amend-orig fixup].freeze,
|
|
367
367
|
'clone' => %i[branch tag].freeze,
|
|
368
368
|
'diff' => %i[head branch files view between contain].freeze,
|
|
369
369
|
'range-diff' => %i[view between contain].freeze,
|
|
@@ -530,7 +530,7 @@ module Squared
|
|
|
530
530
|
if flag == :add
|
|
531
531
|
opts = param_guard(action, flag, args: args.to_a)
|
|
532
532
|
elsif (refs = args.to_a).empty?
|
|
533
|
-
refs = readline('Enter
|
|
533
|
+
refs = readline('Enter glob patterns', force: true).shellsplit
|
|
534
534
|
end
|
|
535
535
|
end
|
|
536
536
|
commit(flag, opts, refs: refs, ref: ref, squash: squash, pick: pick)
|
|
@@ -1773,7 +1773,7 @@ module Squared
|
|
|
1773
1773
|
pathspec = false if pick == 'reword'
|
|
1774
1774
|
end
|
|
1775
1775
|
if pathspec.nil?
|
|
1776
|
-
pathspec = if (flag == :fixup || amend) && refs.size == 1 && refs.first == '*'
|
|
1776
|
+
pathspec = if (flag == :pathspec || flag == :fixup || amend) && refs.size == 1 && refs.first == '*'
|
|
1777
1777
|
'--all'
|
|
1778
1778
|
elsif (refs = projectmap(refs)).empty?
|
|
1779
1779
|
raise 'no qualified pathspec'
|
|
@@ -1847,7 +1847,7 @@ module Squared
|
|
|
1847
1847
|
elsif stdout?
|
|
1848
1848
|
puts log_message('nothing to commit', subject: name, hint: flag)
|
|
1849
1849
|
end
|
|
1850
|
-
exit 1
|
|
1850
|
+
exit 1 unless pass.nil?
|
|
1851
1851
|
end
|
|
1852
1852
|
end
|
|
1853
1853
|
|
|
@@ -11,7 +11,7 @@ module Squared
|
|
|
11
11
|
install_a: %w[audit=! bin-links=! engine-strict=!? foreground-scripts=!? fund=! ignore-scripts=!?
|
|
12
12
|
install-links=!? package-lock=! strict-peer-deps=!? include=b install-strategy=b omit=b].freeze,
|
|
13
13
|
install_b: %w[no-save B|save-bundle D|save-dev O|save-optional save-peer P|save-prod g|global=!?
|
|
14
|
-
S|save=!?].freeze,
|
|
14
|
+
min-release-age=i min-release-age-exclude=q S|save=!?].freeze,
|
|
15
15
|
install_c: %w[allow-directory=b? allow-file=b? allow-git=b? allow-remote=b?].freeze,
|
|
16
16
|
run: %w[foreground-scripts=!? if-present=!? ignore-scripts=!? script-shell=p].freeze,
|
|
17
17
|
exec: %w[c|call=q package=b].freeze,
|
|
@@ -230,7 +230,7 @@ module Squared
|
|
|
230
230
|
elsif exception?
|
|
231
231
|
indexerror n, list
|
|
232
232
|
else
|
|
233
|
-
log.
|
|
233
|
+
log.debug "run script #{n} of #{list.size}".subhint('out of range')
|
|
234
234
|
next
|
|
235
235
|
end
|
|
236
236
|
else
|
|
@@ -330,26 +330,39 @@ module Squared
|
|
|
330
330
|
when 'package'
|
|
331
331
|
case flag
|
|
332
332
|
when :approve, :deny
|
|
333
|
-
format_desc
|
|
333
|
+
format_desc(action, flag, 'opts*', before: flag == :approve ? 'name*|:' : 'name*|:|::')
|
|
334
334
|
task flag do |_, args|
|
|
335
335
|
args = args.to_a
|
|
336
|
-
if choice!(args)
|
|
336
|
+
if choice!(args) || (flag == :deny && (all = choice!(args, char: '::')))
|
|
337
|
+
list = []
|
|
338
|
+
pad = 0
|
|
339
|
+
size = ->(s) { pad = [pad, s.size].max }
|
|
337
340
|
pwd_set do
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
341
|
+
json = JSON.parse(`#{npm_output('install-scripts ls --json')}`)
|
|
342
|
+
json&.fetch('allowScripts', [])&.each do |data|
|
|
343
|
+
line = data['changes']&.find { |item| item['change'] == 'pending' }
|
|
344
|
+
next unless line && line['key'] =~ /^(.+)@([^@]+)$/
|
|
345
|
+
|
|
346
|
+
size.call($1)
|
|
347
|
+
list << [$1, $2]
|
|
348
|
+
end
|
|
349
|
+
if all
|
|
350
|
+
current = read_package 'allowScripts'
|
|
351
|
+
current&.each_pair do |key, val|
|
|
352
|
+
next unless val
|
|
353
|
+
|
|
354
|
+
md = key.match(/^(.+?)(?:@([^@]+))?$/)
|
|
355
|
+
size.call(md[1])
|
|
356
|
+
list << [md[1], sub_style(md[2] || 'any', theme[:inline])]
|
|
357
|
+
end
|
|
350
358
|
end
|
|
351
|
-
args.concat(choice_index('Select packages', list, multiple: true, column: /^(\S+)/))
|
|
352
359
|
end
|
|
360
|
+
if list.empty?
|
|
361
|
+
puts log_message('no packages to review', subject: name, hint: "#{flag}-scripts")
|
|
362
|
+
exit
|
|
363
|
+
end
|
|
364
|
+
list.map! { |name, ver| name.ljust(pad + ARG[:TAB]) + ver }
|
|
365
|
+
args.concat(choice_index('Select packages', list, multiple: true, column: /^(\S+)/))
|
|
353
366
|
end
|
|
354
367
|
package flag, args
|
|
355
368
|
end
|
|
@@ -885,9 +898,9 @@ module Squared
|
|
|
885
898
|
end
|
|
886
899
|
print_item banner unless sync
|
|
887
900
|
if !found.empty?
|
|
888
|
-
col1 = width.call(found, 0) +
|
|
889
|
-
col2 = width.call(found, 1) +
|
|
890
|
-
col3 = pad.call(found, found.size).size + 2 + col1 + col2 + width.call(found, 2)
|
|
901
|
+
col1 = width.call(found, 0) + ARG[:TAB]
|
|
902
|
+
col2 = width.call(found, 1) + ARG[:TAB]
|
|
903
|
+
col3 = pad.call(found, found.size).size + (ARG[:TAB] / 2) + col1 + col2 + width.call(found, 2)
|
|
891
904
|
packages = []
|
|
892
905
|
pat = ->(a) { /("#{Regexp.escape(a[0])}"\s*:\s*)"([~^])#{'?' if a[4]}#{Regexp.escape(a[1])}"/ }
|
|
893
906
|
edit = lambda do |a, pkg, mod|
|
|
@@ -983,9 +996,9 @@ module Squared
|
|
|
983
996
|
end
|
|
984
997
|
end
|
|
985
998
|
elsif !avail.empty?
|
|
986
|
-
col1 = width.call(avail, 0) +
|
|
999
|
+
col1 = width.call(avail, 0) + ARG[:TAB]
|
|
987
1000
|
col2 = width.call(avail, 1)
|
|
988
|
-
col3 = width.call(avail, 2) +
|
|
1001
|
+
col3 = width.call(avail, 2) + ARG[:TAB]
|
|
989
1002
|
avail.each_with_index do |item, i|
|
|
990
1003
|
a, b, c, d = item
|
|
991
1004
|
a = a.ljust(col1)
|
|
@@ -1381,7 +1394,7 @@ module Squared
|
|
|
1381
1394
|
op.exist?(add: true)
|
|
1382
1395
|
end
|
|
1383
1396
|
end
|
|
1384
|
-
op.append(flags,
|
|
1397
|
+
op.append(flags, context: kwargs)
|
|
1385
1398
|
.clear
|
|
1386
1399
|
print_run(op, banner, **kwargs)
|
|
1387
1400
|
start = time_epoch if kwargs.fetch(:verbose, verbose? && !stdin?)
|
|
@@ -7,16 +7,18 @@ module Squared
|
|
|
7
7
|
DEP_PYTHON = %w[poetry.lock pdm.lock pylock.toml setup.cfg pyproject.toml setup.py requirements.txt].freeze
|
|
8
8
|
DIR_PYTHON = (DEP_PYTHON + %w[meson.build README.rst]).freeze
|
|
9
9
|
OPT_PYTHON = {
|
|
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
|
|
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
|
|
11
|
+
check-hash-based-pycs={always,default,never}].freeze,
|
|
11
12
|
build: %w[C=bm n|no-isolation s|sdist x|skip-dependency-check v|verbose w|wheel config-json=q config-setting=q
|
|
12
13
|
installer=b o|outdir=p].freeze,
|
|
13
14
|
venv: %w[clear copies symlinks system-site-packages upgrade upgrade-deps without-scm-ignore-files without-pip
|
|
14
15
|
prompt=q].freeze,
|
|
15
16
|
virtualenv: %w[always-copy clear copies download never-download no-download no-periodic-update no-pip no-seed
|
|
16
|
-
no-setuptools no-vcs-ignore q|quiet read-only-app-data reset-app-data
|
|
17
|
-
system-site-packages with-traceback without-pip upgrade-embed-wheels
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
no-setuptools no-vcs-ignore no-venv-redirect q|quiet read-only-app-data reset-app-data
|
|
18
|
+
symlink-app-data symlinks system-site-packages with-traceback without-pip upgrade-embed-wheels
|
|
19
|
+
venv-redirect v|verbose=+ activators={bash,batch,cshell,fish,nushell,powershell,python,xonsh}
|
|
20
|
+
app-data=p creator=b discovery={builtin} extra-search-dir=p pip=b prompt=q p|python=q
|
|
21
|
+
seeder={app-data,pip} setuptools=b try-first-with=q].freeze
|
|
20
22
|
}.freeze
|
|
21
23
|
OPT_PIP = {
|
|
22
24
|
common: %w[debug disable-pip-version-check isolated no-cache-dir no-color no-input no-proxy-env
|
|
@@ -49,6 +51,13 @@ module Squared
|
|
|
49
51
|
uninstall: %w[break-system-packages y|yes r|requirement=p root-user-action=b].freeze,
|
|
50
52
|
wheel: %w[no-verify w|wheel-dir=p].freeze
|
|
51
53
|
}.freeze
|
|
54
|
+
OPT_PY = {
|
|
55
|
+
common: %w[q|quiet=+ v|verbose=+ y|yes config=p].freeze,
|
|
56
|
+
exec: %w[3=/^\.\d+(\.\d+)?$/m? V=/^:./m?].freeze,
|
|
57
|
+
install: %w[by-id configure dry-run f|force refresh u|update d|download=p s|source=q t|target=p].freeze,
|
|
58
|
+
list: %w[1|one online only-managed format={table,json,jsonl,csv,exe,prefix,url,formats} s|source=q].freeze,
|
|
59
|
+
uninstall: %w[by-id cleanup purge].freeze
|
|
60
|
+
}.freeze
|
|
52
61
|
OPT_POETRY = {
|
|
53
62
|
common: %w[ansi no-ansi no-cache n|no-interaction no-plugins q|quiet v|verbose=+ P|project=p].freeze,
|
|
54
63
|
install: %w[all-extras all-groups compile dry-run no-directory no-root only-root E|extras=q only=q with=q
|
|
@@ -99,7 +108,8 @@ module Squared
|
|
|
99
108
|
install: %w[C config-settings c constraint extra-index-url no-binary only-binary platform
|
|
100
109
|
r requirement].freeze,
|
|
101
110
|
list: %w[exclude extra-index-url no-binary only-binary].freeze
|
|
102
|
-
}.freeze
|
|
111
|
+
}.freeze,
|
|
112
|
+
py: %w[q v quiet verbose].freeze
|
|
103
113
|
}.freeze
|
|
104
114
|
private_constant :DEP_PYTHON, :DIR_PYTHON, :OPT_PYTHON, :OPT_PIP, :OPT_POETRY, :OPT_PDM, :OPT_HATCH, :OPT_TWINE,
|
|
105
115
|
:PASS_PYTHON
|
|
@@ -149,6 +159,7 @@ module Squared
|
|
|
149
159
|
'outdated' => %i[major minor patch].freeze,
|
|
150
160
|
'build' => %i[poetry pdm hatch meson python].freeze,
|
|
151
161
|
'publish' => %i[twine poetry pdm hatch].freeze,
|
|
162
|
+
'py' => %i[exec install list uninstall].freeze,
|
|
152
163
|
'run' => nil,
|
|
153
164
|
'exec' => nil
|
|
154
165
|
})
|
|
@@ -210,7 +221,7 @@ module Squared
|
|
|
210
221
|
indexerror n, list
|
|
211
222
|
else
|
|
212
223
|
found |= 2
|
|
213
|
-
log.
|
|
224
|
+
log.debug "run script #{n} of #{list.size}".subhint('out of range')
|
|
214
225
|
end
|
|
215
226
|
else
|
|
216
227
|
case (i > 1 && poetry? ? 0 : i)
|
|
@@ -224,7 +235,7 @@ module Squared
|
|
|
224
235
|
raise message('script', val) if exception?
|
|
225
236
|
|
|
226
237
|
found |= 2
|
|
227
|
-
log.
|
|
238
|
+
log.debug "run script \"#{val}\"".subhint('not indexed')
|
|
228
239
|
end
|
|
229
240
|
end
|
|
230
241
|
end
|
|
@@ -242,7 +253,7 @@ module Squared
|
|
|
242
253
|
task action do |_, args|
|
|
243
254
|
args = args.to_a
|
|
244
255
|
cmd = if (i = args.delete(':')) && !windows?
|
|
245
|
-
readline('Enter script', force: true, multiline: %w[## ;])
|
|
256
|
+
readline('Enter script', force: true, multiline: Prompt.multiline || %w[## ;])
|
|
246
257
|
elsif i || args.empty?
|
|
247
258
|
readline('Enter command', force: true)
|
|
248
259
|
else
|
|
@@ -281,7 +292,7 @@ module Squared
|
|
|
281
292
|
args = args.to_a
|
|
282
293
|
if args.empty?
|
|
283
294
|
args = readline('Enter command', force: true).split(' ', 2)
|
|
284
|
-
elsif args.size == 1 && option('interactive', notequals: '0', prefix:
|
|
295
|
+
elsif args.size == 1 && option('interactive', notequals: '0', prefix: 'python')
|
|
285
296
|
args << readline('Enter arguments', force: false) unless args.first.include?(' ')
|
|
286
297
|
end
|
|
287
298
|
venv_init
|
|
@@ -351,18 +362,18 @@ module Squared
|
|
|
351
362
|
case flag
|
|
352
363
|
when :upgrade
|
|
353
364
|
task flag, [:strategy] do |_, args|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
365
|
+
val = case args.strategy
|
|
366
|
+
when 'eager'
|
|
367
|
+
'eager'
|
|
368
|
+
when /^only-if/, /needed$/
|
|
369
|
+
'only-if-needed'
|
|
370
|
+
end
|
|
371
|
+
args = if val
|
|
372
|
+
args.extras << "upgrade-strategy=#{val}"
|
|
373
|
+
else
|
|
374
|
+
args.to_a
|
|
375
|
+
end
|
|
376
|
+
install flag, args
|
|
366
377
|
end
|
|
367
378
|
when :requirement, :target
|
|
368
379
|
task flag, [:path] do |_, args|
|
|
@@ -419,6 +430,26 @@ module Squared
|
|
|
419
430
|
end)
|
|
420
431
|
end
|
|
421
432
|
break if be
|
|
433
|
+
when 'py'
|
|
434
|
+
break unless windows?
|
|
435
|
+
|
|
436
|
+
case flag
|
|
437
|
+
when :exec
|
|
438
|
+
format_desc action, flag, 'opts*'
|
|
439
|
+
task flag do |_, args|
|
|
440
|
+
opts = args.to_a
|
|
441
|
+
if (n = opts.index { |val| val.start_with?('3.') }) && (opts[n] =~ SEM_VER)
|
|
442
|
+
opts[n] = $3.to_i >= 5 ? "3=.#{$3}.#{$5 || '0'}" : '3'
|
|
443
|
+
end
|
|
444
|
+
command = ENV['PY_EXEC'] || readline('Enter command', force: true)
|
|
445
|
+
py(flag, command, opts: opts)
|
|
446
|
+
end
|
|
447
|
+
else
|
|
448
|
+
format_desc(action, flag, 'opts*', after: flag == :list ? 'filter*' : 'tag*')
|
|
449
|
+
task flag do |_, args|
|
|
450
|
+
py(flag, opts: args.to_a, banner: true)
|
|
451
|
+
end
|
|
452
|
+
end
|
|
422
453
|
end
|
|
423
454
|
end
|
|
424
455
|
end
|
|
@@ -751,10 +782,17 @@ module Squared
|
|
|
751
782
|
run(from: symjoin(flag, 'publish'), interactive: ['Publish', 'N', project])
|
|
752
783
|
end
|
|
753
784
|
|
|
754
|
-
def python(*args, sync: true, banner: verbose?, with: nil, pass: PASS_PYTHON[:python], **kwargs)
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
785
|
+
def python(*args, sync: true, banner: verbose?, with: nil, pass: PASS_PYTHON[:python], from: :python, **kwargs)
|
|
786
|
+
py = from == :py && windows?
|
|
787
|
+
list = OPT_PYTHON[:common]
|
|
788
|
+
if py
|
|
789
|
+
list += OPT_PY[:exec]
|
|
790
|
+
list.delete('V=+')
|
|
791
|
+
from = :'py:exec'
|
|
792
|
+
end
|
|
793
|
+
op = OptionPartition.new(session_opts(with, args: args, kwargs: kwargs, pass: pass), list,
|
|
794
|
+
py ? session('py', 'exec') : session('python', path: !venv?),
|
|
795
|
+
project: self, strict: strict?, auto: %w[help V|version], sep: ' ',
|
|
758
796
|
multiple: [/^-c/], single: singleopt(:python), args: true, stdin: true)
|
|
759
797
|
op.concat(args)
|
|
760
798
|
if op.include?('-')
|
|
@@ -765,11 +803,17 @@ module Squared
|
|
|
765
803
|
op.clear
|
|
766
804
|
else
|
|
767
805
|
op.exist?(add: true, first: true) unless op.arg?('m')
|
|
768
|
-
op.append(
|
|
806
|
+
op.append(context: kwargs)
|
|
769
807
|
end
|
|
770
808
|
end
|
|
809
|
+
var = kwargs[:env]
|
|
810
|
+
if var == true
|
|
811
|
+
var = nil
|
|
812
|
+
elsif py && var.nil?
|
|
813
|
+
var = false
|
|
814
|
+
end
|
|
771
815
|
print_run(op, banner, **kwargs) unless op.stdout
|
|
772
|
-
run(sync: sync, banner: op.style?(banner), exception: exception?(**kwargs), from:
|
|
816
|
+
run(op, var, sync: sync, banner: op.style?(banner), exception: exception?(**kwargs), from: from)
|
|
773
817
|
end
|
|
774
818
|
|
|
775
819
|
def pip(flag, *args, sync: true, banner: verbose?, with: nil, pass: nil, **kwargs)
|
|
@@ -855,6 +899,28 @@ module Squared
|
|
|
855
899
|
.then { |val| ret || val }
|
|
856
900
|
end
|
|
857
901
|
|
|
902
|
+
def py(flag, *args, sync: true, banner: verbose?, with: nil, pass: nil, **kwargs)
|
|
903
|
+
flag = flag.to_sym
|
|
904
|
+
if flag == :exec
|
|
905
|
+
pass = PASS_PYTHON[:python] if pass.nil?
|
|
906
|
+
python(*args, sync: sync, banner: banner, with: with, pass: pass, from: :py, **kwargs)
|
|
907
|
+
else
|
|
908
|
+
pass = PASS_PYTHON[:py] if pass.nil?
|
|
909
|
+
opts = session_opts(with, args: args, kwargs: kwargs, pass: pass)
|
|
910
|
+
list = OPT_PY[:common] + OPT_PY[flag]
|
|
911
|
+
op = OptionPartition.new(opts, list, session('py', flag), project: self, strict: strict?,
|
|
912
|
+
single: singleopt(:py))
|
|
913
|
+
case flag
|
|
914
|
+
when :install, :uninstall
|
|
915
|
+
raise ArgumentError, message('no tags listed', hint: flag) if op.empty?
|
|
916
|
+
end
|
|
917
|
+
op << '-y' if option('y', 'yes')
|
|
918
|
+
op.append
|
|
919
|
+
print_run(op, banner, **kwargs)
|
|
920
|
+
run(sync: sync, banner: banner, exception: exception?(**kwargs), from: symjoin('py', flag))
|
|
921
|
+
end
|
|
922
|
+
end
|
|
923
|
+
|
|
858
924
|
def serve(root, opts = [], bind: 'localhost', port: nil, **)
|
|
859
925
|
shell(python_session('-m http.server', port, basic_option('b', bind), opts: opts).first.done, chdir: root)
|
|
860
926
|
end
|
|
@@ -886,7 +952,7 @@ module Squared
|
|
|
886
952
|
@dependindex = index
|
|
887
953
|
@dependfile = val
|
|
888
954
|
else
|
|
889
|
-
log.
|
|
955
|
+
log.debug "variable_set: @dependfile=#{val}".subhint('not supported')
|
|
890
956
|
end
|
|
891
957
|
end
|
|
892
958
|
when :venv
|
|
@@ -956,7 +1022,8 @@ module Squared
|
|
|
956
1022
|
pre = preopts(quiet: quiet)
|
|
957
1023
|
return session(name, *pre, *cmd, path: !venv?) unless opts
|
|
958
1024
|
|
|
959
|
-
op = OptionPartition.new(opts, common, project: self, strict: strict?,
|
|
1025
|
+
op = OptionPartition.new(opts, common, project: self, strict: strict?, sep: name == 'python' ? ' ' : '=',
|
|
1026
|
+
single: singleopt(name.to_sym))
|
|
960
1027
|
[session(name, *pre, *op.to_a, *cmd, path: !venv?), op.extras]
|
|
961
1028
|
end
|
|
962
1029
|
|
|
@@ -1131,6 +1198,8 @@ module Squared
|
|
|
1131
1198
|
when :pdm, :poetry
|
|
1132
1199
|
/\Av+\z/
|
|
1133
1200
|
when :twine, :meson then nil
|
|
1201
|
+
when :py
|
|
1202
|
+
/\A(vv|qq)\z/
|
|
1134
1203
|
else
|
|
1135
1204
|
/\A(v+|q+)\z/
|
|
1136
1205
|
end
|
|
@@ -1235,6 +1304,7 @@ module Squared
|
|
|
1235
1304
|
status = true
|
|
1236
1305
|
:virtualenv
|
|
1237
1306
|
else
|
|
1307
|
+
status = !banner
|
|
1238
1308
|
:venv
|
|
1239
1309
|
end
|
|
1240
1310
|
cmd, opts = python_session('-m', flag, opts: opts)
|
|
@@ -1242,34 +1312,31 @@ module Squared
|
|
|
1242
1312
|
op.append(dir, delim: true)
|
|
1243
1313
|
.clear(pass: false)
|
|
1244
1314
|
status ||= op.arg?(/\A-v+\z/)
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
elsif pdm?
|
|
1262
|
-
cmd = pdm_session 'use -f'
|
|
1263
|
-
else
|
|
1264
|
-
puts "Success: #{dir}"
|
|
1265
|
-
return
|
|
1266
|
-
end
|
|
1267
|
-
cmd << shell_quote(dir)
|
|
1268
|
-
print_run cmd, silent?
|
|
1269
|
-
run(banner: false)
|
|
1315
|
+
if run(op, env, exception: true, banner: banner) && dir.directory?
|
|
1316
|
+
args = []
|
|
1317
|
+
requires = read_pyproject 'build-system', 'requires'
|
|
1318
|
+
args.concat(requires) if requires.is_a?(Array)
|
|
1319
|
+
if poetry?
|
|
1320
|
+
requires = read_pyproject 'tool.poetry', 'requires-poetry'
|
|
1321
|
+
args << "poetry#{requires}"
|
|
1322
|
+
elsif setuptools? && !virtualenv?
|
|
1323
|
+
args << 'setuptools' << 'wheel'
|
|
1324
|
+
end
|
|
1325
|
+
pip(:install, *args, banner: false) unless args.empty?
|
|
1326
|
+
if poetry?
|
|
1327
|
+
dir += (windows? ? 'Scripts/python.exe' : 'bin/python')
|
|
1328
|
+
poetry_session 'env use'
|
|
1329
|
+
elsif pdm?
|
|
1330
|
+
pdm_session 'use -f'
|
|
1270
1331
|
else
|
|
1271
|
-
puts
|
|
1332
|
+
puts "Success: #{dir}" unless status
|
|
1333
|
+
return
|
|
1272
1334
|
end
|
|
1335
|
+
cmd << shell_quote(dir)
|
|
1336
|
+
print_run cmd, silent?
|
|
1337
|
+
run(banner: false)
|
|
1338
|
+
elsif !status
|
|
1339
|
+
puts 'Failed'
|
|
1273
1340
|
end
|
|
1274
1341
|
end
|
|
1275
1342
|
|