squared 0.4.14 → 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 +14 -58
- data/README.md +4 -4
- data/README.ruby.md +15 -12
- data/lib/squared/common/base.rb +7 -8
- data/lib/squared/common/format.rb +3 -9
- data/lib/squared/common/prompt.rb +36 -40
- data/lib/squared/common/shell.rb +13 -8
- data/lib/squared/common/system.rb +45 -48
- data/lib/squared/common/utils.rb +3 -19
- data/lib/squared/common.rb +2 -1
- data/lib/squared/config.rb +16 -16
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +27 -40
- data/lib/squared/workspace/project/base.rb +128 -196
- data/lib/squared/workspace/project/docker.rb +37 -38
- data/lib/squared/workspace/project/git.rb +113 -139
- data/lib/squared/workspace/project/node.rb +64 -49
- data/lib/squared/workspace/project/python.rb +57 -251
- data/lib/squared/workspace/project/ruby.rb +119 -139
- data/lib/squared/workspace/project/support/class.rb +73 -34
- data/lib/squared/workspace/project.rb +0 -10
- data/lib/squared/workspace/repo.rb +6 -7
- data/lib/squared/workspace/series.rb +8 -8
- data/lib/squared/workspace/support/data.rb +3 -2
- data/lib/squared/workspace.rb +1 -1
- data/squared.gemspec +1 -1
- metadata +2 -3
- data/lib/squared/common/class.rb +0 -110
@@ -8,7 +8,7 @@ module Squared
|
|
8
8
|
DIR_PYTHON = (DEP_PYTHON + %w[README.rst]).freeze
|
9
9
|
OPT_PYTHON = {
|
10
10
|
common: %w[b B d E h i I O OO 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
|
11
|
+
build: %w[n|no-isolation s|sdist v|verbose w|wheel x|skip-dependency-check C|config-setting=q installer=b
|
12
12
|
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
|
@@ -28,18 +28,11 @@ module Squared
|
|
28
28
|
freeze: %w[all exclude-editable l|local user exclude=b path=p r|requirement=p].freeze
|
29
29
|
}.freeze
|
30
30
|
OPT_POETRY = {
|
31
|
-
common: %w[ansi no-ansi no-cache n|no-interaction no-plugins q|quiet v|verbose
|
31
|
+
common: %w[ansi no-ansi no-cache n|no-interaction no-plugins P|project=p q|quiet v|verbose].freeze,
|
32
32
|
build: %w[clean config-settings=qq f|format=b o|output=p].freeze,
|
33
|
-
publish: %w[build dry-run
|
33
|
+
publish: %w[build dry-run client-cert=p cert=p dist-dir=p p|password=b r|repository=b skip-existing
|
34
34
|
u|username=b].freeze
|
35
35
|
}.freeze
|
36
|
-
OPT_PDM = {
|
37
|
-
common: %w[I|ignore-python no-cache n|non-interactive].freeze,
|
38
|
-
build: %w[C=bm no-clean no-isolation no-sdist no-wheel quiet verbose config-setting=q d|dest=p p|project=p
|
39
|
-
k|skip=b].freeze,
|
40
|
-
publish: %w[no-build no-very-ssl quiet S|sign skip-existing verbose ca-certs=p c|comment=q d|dest=p identity=b
|
41
|
-
p|password=q p|project=p r|repository=q k|skip=b u|username=b].freeze
|
42
|
-
}.freeze
|
43
36
|
OPT_HATCH = {
|
44
37
|
common: %w[color interactive no-color no-interactive cache-dir=p config=p data-dir=p e|env=b p|project=b
|
45
38
|
q|quiet v|verbose].freeze,
|
@@ -48,11 +41,11 @@ module Squared
|
|
48
41
|
p|publisher=b r|repo=b u|user=q].freeze
|
49
42
|
}.freeze
|
50
43
|
OPT_TWINE = {
|
51
|
-
publish: %w[attestations disable-progress-bar non-interactive
|
52
|
-
|
44
|
+
publish: %w[attestations disable-progress-bar non-interactive skip-existing verbose s|sign c|comment=q
|
45
|
+
config-file=p cert=p client-cert=p i|identity=b p|password=q r|repository=b repository-url=q
|
53
46
|
sign-with=b u|username=q].freeze
|
54
47
|
}.freeze
|
55
|
-
private_constant :DEP_PYTHON, :DIR_PYTHON, :OPT_PYTHON, :OPT_PIP, :OPT_POETRY, :
|
48
|
+
private_constant :DEP_PYTHON, :DIR_PYTHON, :OPT_PYTHON, :OPT_PIP, :OPT_POETRY, :OPT_HATCH, :OPT_TWINE
|
56
49
|
|
57
50
|
class << self
|
58
51
|
def populate(*); end
|
@@ -78,7 +71,7 @@ module Squared
|
|
78
71
|
|
79
72
|
attr_reader :venv, :editable
|
80
73
|
|
81
|
-
def initialize(*, editable: '.', verbose: nil, **kwargs)
|
74
|
+
def initialize(*, venv: nil, editable: '.', verbose: nil, **kwargs)
|
82
75
|
super
|
83
76
|
if @pass.include?(Python.ref)
|
84
77
|
initialize_ref Python.ref
|
@@ -87,20 +80,18 @@ module Squared
|
|
87
80
|
initialize_build(Python.ref, **kwargs)
|
88
81
|
initialize_env(**kwargs)
|
89
82
|
end
|
90
|
-
@verbose = verbose.size if verbose.is_a?(String) && verbose.match?(/\Av+\z/)
|
91
83
|
dependfile_set DEP_PYTHON
|
84
|
+
@verbose = verbose.size if verbose.is_a?(String) && verbose.match?(/\Av+\z/)
|
92
85
|
editable_set editable
|
93
|
-
venv_set
|
86
|
+
venv_set venv if venv
|
94
87
|
end
|
95
88
|
|
96
89
|
subtasks({
|
97
90
|
'venv' => %i[exec create remove show].freeze,
|
98
91
|
'pip' => %i[uninstall freeze].freeze,
|
99
92
|
'install' => %i[user force upgrade target editable].freeze,
|
100
|
-
'
|
101
|
-
'
|
102
|
-
'publish' => %i[poetry pdm hatch twine].freeze,
|
103
|
-
'run' => nil,
|
93
|
+
'build' => %i[python poetry hatch].freeze,
|
94
|
+
'publish' => %i[poetry twine hatch].freeze,
|
104
95
|
'exec' => nil
|
105
96
|
})
|
106
97
|
|
@@ -118,62 +109,6 @@ module Squared
|
|
118
109
|
|
119
110
|
if flags.nil?
|
120
111
|
case action
|
121
|
-
when 'run'
|
122
|
-
next unless pyprojectfile
|
123
|
-
|
124
|
-
format_desc action, nil, "script+|#{indexchar}index+|#,pattern*"
|
125
|
-
task action, [:command] do |_, args|
|
126
|
-
found = 0
|
127
|
-
['tool.poetry.scripts', 'tool.pdm.scripts', 'project.scripts'].each_with_index do |table, index|
|
128
|
-
next if (list = read_pyproject(table)).empty?
|
129
|
-
|
130
|
-
if args.command == '#'
|
131
|
-
format_list(list, "run[#{indexchar}N]", 'scripts', grep: args.extras, from: pyprojectfile)
|
132
|
-
found |= 1
|
133
|
-
else
|
134
|
-
args.to_a.each do |val|
|
135
|
-
if (n, = indexitem(val))
|
136
|
-
if (script, = list[n - 1])
|
137
|
-
case index
|
138
|
-
when 0
|
139
|
-
script = session_output 'poetry', 'run', script
|
140
|
-
when 1
|
141
|
-
script = pdm_session 'run', script
|
142
|
-
else
|
143
|
-
venv_init
|
144
|
-
end
|
145
|
-
found |= 1
|
146
|
-
run(script, from: :run)
|
147
|
-
elsif exception
|
148
|
-
indexerror n, list
|
149
|
-
else
|
150
|
-
found |= 2
|
151
|
-
log.warn "run script #{n} of #{list.size} (out of range)"
|
152
|
-
end
|
153
|
-
else
|
154
|
-
case index
|
155
|
-
when 0
|
156
|
-
found |= 1
|
157
|
-
run(session_output('poetry', 'run', val), from: :run)
|
158
|
-
when 1
|
159
|
-
found |= 1
|
160
|
-
run(pdm_session('run', val), from: :run)
|
161
|
-
else
|
162
|
-
raise_error("script: #{val}", hint: 'unknown') if exception
|
163
|
-
found |= 2
|
164
|
-
log.warn "run script \"#{val}\" (not indexed)"
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end
|
169
|
-
break
|
170
|
-
end
|
171
|
-
unless found.anybits?(1)
|
172
|
-
puts log_message(found == 0 ? Logger::INFO : Logger.WARN,
|
173
|
-
"no scripts #{found == 0 ? 'found' : 'executed'}",
|
174
|
-
subject: name, hint: pyprojectfile)
|
175
|
-
end
|
176
|
-
end
|
177
112
|
when 'exec'
|
178
113
|
format_desc action, nil, 'command|:,args*'
|
179
114
|
task action do |_, args|
|
@@ -188,7 +123,7 @@ module Squared
|
|
188
123
|
end
|
189
124
|
args.join(' ')
|
190
125
|
end
|
191
|
-
|
126
|
+
Kernel.exec(cmd, chdir: path)
|
192
127
|
end
|
193
128
|
end
|
194
129
|
else
|
@@ -279,30 +214,14 @@ module Squared
|
|
279
214
|
depend flag, args.to_a
|
280
215
|
end
|
281
216
|
end
|
282
|
-
when 'outdated'
|
283
|
-
format_desc action, flag, 'eager?'
|
284
|
-
task flag do |_, args|
|
285
|
-
outdated flag, args.to_a
|
286
|
-
end
|
287
217
|
when 'build'
|
288
|
-
case flag
|
289
|
-
when :poetry
|
290
|
-
next unless build_backend == 'poetry.core.masonry.api'
|
291
|
-
when :pdm
|
292
|
-
next unless build_backend == 'pdm.backend'
|
293
|
-
when :hatch
|
294
|
-
next unless build_backend == 'hatchling.build'
|
295
|
-
end
|
296
218
|
format_desc(action, flag, 'opts*', after: case flag
|
297
219
|
when :python then 'srcdir?'
|
298
|
-
when :poetry then 'output?'
|
299
|
-
when :pdm then 'dest?'
|
300
220
|
when :hatch then 'location?'
|
301
221
|
end)
|
302
222
|
task flag do |_, args|
|
303
223
|
build! flag, args.to_a
|
304
224
|
end
|
305
|
-
break unless flag == :python
|
306
225
|
when 'publish'
|
307
226
|
format_desc(action, flag, 'opts*', after: case flag
|
308
227
|
when :hatch then 'artifacts?'
|
@@ -350,7 +269,7 @@ module Squared
|
|
350
269
|
end
|
351
270
|
end
|
352
271
|
|
353
|
-
def outdated(
|
272
|
+
def outdated(*, sync: invoked_sync?('outdated'))
|
354
273
|
cmd = pip_session 'list', '--outdated'
|
355
274
|
append_global
|
356
275
|
cmd = session_done cmd
|
@@ -360,35 +279,28 @@ module Squared
|
|
360
279
|
print_item banner if sync
|
361
280
|
start = 0
|
362
281
|
found = 0
|
363
|
-
major =
|
364
|
-
minor = []
|
365
|
-
patch = []
|
282
|
+
major = 0
|
366
283
|
pwd_set(from: :outdated) do
|
367
284
|
buffer = []
|
368
285
|
out = ->(val) { sync ? puts(val) : buffer << val }
|
369
286
|
IO.popen(runenv || {}, cmd).each do |line|
|
370
|
-
next if line.match?(/^[
|
287
|
+
next if line.match?(/^[\s-]+$/)
|
371
288
|
|
372
289
|
if start > 0
|
373
290
|
unless stdin?
|
374
|
-
|
375
|
-
next unless cur && lat
|
291
|
+
data = line.scan(SEM_VER)
|
292
|
+
next unless (cur = data.shift) && (lat = data.shift)
|
376
293
|
|
377
294
|
latest = lat.join
|
378
295
|
current = cur.join
|
379
296
|
semver cur
|
380
297
|
semver lat
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
0
|
388
|
-
else
|
389
|
-
minor << name
|
390
|
-
1
|
391
|
-
end
|
298
|
+
if semmajor?(cur, lat)
|
299
|
+
type = 2
|
300
|
+
major += 1
|
301
|
+
else
|
302
|
+
type = cur[2] == lat[2] ? 0 : 1
|
303
|
+
end
|
392
304
|
if type == 0
|
393
305
|
styles = color(:yellow)
|
394
306
|
else
|
@@ -422,16 +334,7 @@ module Squared
|
|
422
334
|
puts buffer
|
423
335
|
end
|
424
336
|
if found > 0
|
425
|
-
|
426
|
-
pkg = case flag
|
427
|
-
when :major
|
428
|
-
major + minor + patch
|
429
|
-
when :minor
|
430
|
-
minor + patch
|
431
|
-
when :patch
|
432
|
-
patch
|
433
|
-
end
|
434
|
-
install(:upgrade, pkg, strategy: opts.include?('eager') ? 'eager' : nil) unless !pkg || pkg.empty?
|
337
|
+
puts print_footer empty_status('Updates are available', 'major', major)
|
435
338
|
elsif start == 0
|
436
339
|
puts 'No updates were found'
|
437
340
|
end
|
@@ -463,9 +366,6 @@ module Squared
|
|
463
366
|
when :poetry
|
464
367
|
cmd = poetry_session 'build'
|
465
368
|
list = OPT_POETRY[:build] + OPT_POETRY[:common]
|
466
|
-
when :pdm
|
467
|
-
cmd, opts = pdm_session('build', opts: opts)
|
468
|
-
list = OPT_PDM[:build]
|
469
369
|
when :hatch
|
470
370
|
cmd, opts = hatch_session('build', opts: opts)
|
471
371
|
list = OPT_HATCH[:build]
|
@@ -473,7 +373,7 @@ module Squared
|
|
473
373
|
srcdir = nil
|
474
374
|
op = OptionPartition.new(opts, list, cmd, project: self, single: singleopt(flag))
|
475
375
|
op.each do |opt|
|
476
|
-
if !srcdir && basepath(opt
|
376
|
+
if !srcdir && basepath(opt).exist? && projectpath?(opt)
|
477
377
|
srcdir = opt
|
478
378
|
else
|
479
379
|
op.found << opt
|
@@ -481,13 +381,12 @@ module Squared
|
|
481
381
|
end
|
482
382
|
op.swap
|
483
383
|
case flag
|
484
|
-
when :poetry
|
384
|
+
when :poetry
|
485
385
|
if srcdir
|
486
|
-
|
487
|
-
if op.arg?(*args)
|
386
|
+
if op.arg?('o', 'output')
|
488
387
|
op.extras << srcdir
|
489
388
|
else
|
490
|
-
op << quote_option(
|
389
|
+
op << quote_option('output', path + srcdir)
|
491
390
|
end
|
492
391
|
srcdir = nil
|
493
392
|
end
|
@@ -509,35 +408,21 @@ module Squared
|
|
509
408
|
when :poetry
|
510
409
|
poetry_session 'publish'
|
511
410
|
list = OPT_POETRY[:publish] + OPT_POETRY[:common]
|
512
|
-
when :pdm
|
513
|
-
opts = pdm_session('publish', opts: opts).last
|
514
|
-
list = OPT_PDM[:publish]
|
515
|
-
when :hatch
|
516
|
-
opts = hatch_session('publish', opts: opts).last
|
517
|
-
list = OPT_HATCH[:publish]
|
518
411
|
when :twine
|
519
412
|
session 'twine', 'upload'
|
520
413
|
list = OPT_TWINE[:publish]
|
414
|
+
when :hatch
|
415
|
+
opts = hatch_session('publish', opts: opts).last
|
416
|
+
list = OPT_HATCH[:publish]
|
521
417
|
end
|
522
418
|
op = OptionPartition.new(opts, list, @session, project: self, single: singleopt(flag))
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
419
|
+
if op.empty?
|
420
|
+
dist = path + 'dist'
|
421
|
+
raise_error('no source files found', hint: dist) unless dist.directory? && !dist.empty?
|
422
|
+
op.extras << "#{dist}/*" unless flag == :poetry
|
527
423
|
end
|
528
|
-
|
529
|
-
|
530
|
-
if op.empty?
|
531
|
-
op.extras << "#{dist.call}/*"
|
532
|
-
else
|
533
|
-
op.map! { |val| path + val }
|
534
|
-
end
|
535
|
-
op.append
|
536
|
-
else
|
537
|
-
dist.call unless op.arg?(*(flag == :poetry ? ['dist-dir'] : ['d', 'dest']))
|
538
|
-
op.clear(pass: false)
|
539
|
-
end
|
540
|
-
run(from: :"#{flag}:publish", interactive: "Publish #{sub_style(project, styles: theme[:active])}")
|
424
|
+
op.append
|
425
|
+
run(from: :"#{flag}:publish")
|
541
426
|
end
|
542
427
|
|
543
428
|
def pip(flag, opts = [])
|
@@ -557,7 +442,13 @@ module Squared
|
|
557
442
|
ret
|
558
443
|
end
|
559
444
|
|
560
|
-
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
|
561
452
|
case key
|
562
453
|
when :dependfile
|
563
454
|
req = basepath(*val)
|
@@ -600,25 +491,15 @@ module Squared
|
|
600
491
|
|
601
492
|
def poetry_session(*cmd)
|
602
493
|
ret = session('poetry', *cmd, *preopts)
|
603
|
-
|
604
|
-
ret << quote_option('project', path + val)
|
605
|
-
end
|
494
|
+
option('project', ignore: false) { |val| ret << quote_option('project', path + val) }
|
606
495
|
ret
|
607
496
|
end
|
608
497
|
|
609
|
-
def pdm_session(*cmd, opts: nil)
|
610
|
-
create_session(*cmd, name: 'pdm', common: OPT_PDM[:common], opts: opts)
|
611
|
-
end
|
612
|
-
|
613
498
|
def hatch_session(*cmd, opts: nil)
|
614
|
-
|
615
|
-
end
|
499
|
+
return session('hatch', *preopts, *cmd, path: venv.nil?) unless opts
|
616
500
|
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
op = OptionPartition.new(opts, common, project: self, single: singleopt)
|
621
|
-
ret = session(name, *op.to_a, *cmd, path: venv.nil?)
|
501
|
+
op = OptionPartition.new(opts, OPT_HATCH[:common], project: self, single: singleopt)
|
502
|
+
ret = session('hatch', *op.to_a, *cmd, path: venv.nil?)
|
622
503
|
[ret, op.extras]
|
623
504
|
end
|
624
505
|
|
@@ -683,7 +564,7 @@ module Squared
|
|
683
564
|
end
|
684
565
|
|
685
566
|
def append_global(target: @session)
|
686
|
-
|
567
|
+
option('cache-dir', target: target) do |val|
|
687
568
|
target << case val
|
688
569
|
when '0', 'false'
|
689
570
|
'--no-cache-dir'
|
@@ -691,82 +572,18 @@ module Squared
|
|
691
572
|
quote_option('cache-dir', path + val)
|
692
573
|
end
|
693
574
|
end
|
694
|
-
|
695
|
-
|
575
|
+
option('proxy', target: target) { |val| target << shell_option('proxy', val) }
|
576
|
+
option('python', target: target) { |val| target << quote_option('python', path + val) }
|
696
577
|
append_nocolor(target: target)
|
697
578
|
end
|
698
579
|
|
699
|
-
def
|
700
|
-
@
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
unless (ret = (@pyproject ||= {})[table])
|
707
|
-
ret = []
|
708
|
-
start = /^\s*\[#{Regexp.escape(table)}\]\s*$/
|
709
|
-
ch = nil
|
710
|
-
found = false
|
711
|
-
File.foreach(file) do |line|
|
712
|
-
if found
|
713
|
-
break if line.match?(/^\s*\[[\w.-]+\]\s*$/)
|
714
|
-
|
715
|
-
if ch
|
716
|
-
val = line.rstrip
|
717
|
-
case ch
|
718
|
-
when '}', ']'
|
719
|
-
ch = nil if val.end_with?(ch)
|
720
|
-
val = "\n#{val}"
|
721
|
-
else
|
722
|
-
if val.chomp!(ch)
|
723
|
-
ch = nil
|
724
|
-
else
|
725
|
-
val = line
|
726
|
-
end
|
727
|
-
end
|
728
|
-
ret.last[1] += val
|
729
|
-
elsif (data = line.match(/^\s*(\S+)\s*=\s*([+-]?[\d.]+|true|false|("""|'''|["'\[{])(.*?))\s*$/))
|
730
|
-
if (val = data[4])
|
731
|
-
case (ch = data[3])
|
732
|
-
when '{', '['
|
733
|
-
val = "#{ch}#{val}"
|
734
|
-
ch = ch == '{' ? '}' : ']'
|
735
|
-
ch = nil if val.end_with?(ch)
|
736
|
-
else
|
737
|
-
if val.chomp!(ch)
|
738
|
-
ch = nil
|
739
|
-
elsif ch.size == 1
|
740
|
-
next
|
580
|
+
def editable_set(val)
|
581
|
+
@editable = case val
|
582
|
+
when '.', Pathname
|
583
|
+
val
|
584
|
+
when String
|
585
|
+
Pathname.new(editable)
|
741
586
|
end
|
742
|
-
end
|
743
|
-
else
|
744
|
-
val = case (val = data[2])
|
745
|
-
when 'true'
|
746
|
-
true
|
747
|
-
when 'false'
|
748
|
-
false
|
749
|
-
else
|
750
|
-
val.include?('.') ? val.to_f : val.to_i
|
751
|
-
end
|
752
|
-
end
|
753
|
-
ret << [data[1], val]
|
754
|
-
end
|
755
|
-
else
|
756
|
-
found = line.match?(start)
|
757
|
-
end
|
758
|
-
end
|
759
|
-
@pyproject[table] = ret
|
760
|
-
end
|
761
|
-
return ret.find { |val| val[0] == key }&.last if key
|
762
|
-
|
763
|
-
ret
|
764
|
-
end
|
765
|
-
|
766
|
-
def pyprojectfile
|
767
|
-
return unless (ret = basepath(DEP_PYTHON[2])).exist?
|
768
|
-
|
769
|
-
ret
|
770
587
|
end
|
771
588
|
|
772
589
|
def singleopt(flag = nil)
|
@@ -809,18 +626,7 @@ module Squared
|
|
809
626
|
@venv&.join(workspace.windows? ? 'Scripts' : 'bin')
|
810
627
|
end
|
811
628
|
|
812
|
-
def editable_set(val)
|
813
|
-
@editable = case val
|
814
|
-
when '.', Pathname
|
815
|
-
val
|
816
|
-
when String
|
817
|
-
Pathname.new(editable)
|
818
|
-
end
|
819
|
-
end
|
820
|
-
|
821
629
|
def venv_set(val)
|
822
|
-
return unless val
|
823
|
-
|
824
630
|
if val.is_a?(Array)
|
825
631
|
val, *opts = val
|
826
632
|
@venvopts = opts
|