squared 0.6.10 → 0.7.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 +67 -14
- data/README.md +242 -204
- data/lib/squared/common/format.rb +7 -10
- data/lib/squared/common/prompt.rb +23 -24
- data/lib/squared/common/shell.rb +16 -17
- data/lib/squared/common/system.rb +29 -20
- data/lib/squared/common/utils.rb +43 -54
- data/lib/squared/config.rb +17 -16
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +290 -175
- data/lib/squared/workspace/project/base.rb +544 -446
- data/lib/squared/workspace/project/docker.rb +162 -155
- data/lib/squared/workspace/project/git.rb +180 -147
- data/lib/squared/workspace/project/node.rb +91 -89
- data/lib/squared/workspace/project/python.rb +245 -151
- data/lib/squared/workspace/project/ruby.rb +403 -291
- data/lib/squared/workspace/project/support/class.rb +12 -6
- data/lib/squared/workspace/project/support/optionpartition.rb +58 -41
- data/lib/squared/workspace/project/support/utils.rb +68 -0
- data/lib/squared/workspace/project.rb +0 -7
- data/lib/squared/workspace/repo.rb +234 -169
- data/lib/squared/workspace/series.rb +91 -86
- data/lib/squared/workspace/support/base.rb +15 -1
- metadata +2 -1
|
@@ -5,13 +5,18 @@ module Squared
|
|
|
5
5
|
module Project
|
|
6
6
|
class Python < Git
|
|
7
7
|
DEP_PYTHON = %w[poetry.lock setup.cfg pyproject.toml setup.py requirements.txt].freeze
|
|
8
|
-
DIR_PYTHON = (DEP_PYTHON + %w[README.rst]).freeze
|
|
8
|
+
DIR_PYTHON = (DEP_PYTHON + %w[meson.build README.rst]).freeze
|
|
9
9
|
OPT_PYTHON = {
|
|
10
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
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
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
|
-
prompt=q].freeze
|
|
14
|
+
prompt=q].freeze,
|
|
15
|
+
virtualenv: %w[always-copy clear copies download q|quiet never-download no-download no-periodic-update no-pip
|
|
16
|
+
no-seed no-setuptools no-vcs-ignore read-only-app-data reset-app-data symlink-app-data symlinks
|
|
17
|
+
system-site-packages with-traceback without-pip upgrade-embed-wheels v|verbose=+ activators=q
|
|
18
|
+
app-data=p creator=b discovery=b extra-search-dir=p pip=b prompt=q p|python=q seeder=b
|
|
19
|
+
setuptools=b try-first-with=q].freeze
|
|
15
20
|
}.freeze
|
|
16
21
|
OPT_PIP = {
|
|
17
22
|
common: %w[debug disable-pip-version-check isolated no-cache-dir no-color no-input require-virtualenv
|
|
@@ -29,23 +34,23 @@ module Squared
|
|
|
29
34
|
install: %w[break-system-packages compile dry-run force-reinstall I|ignore-installed no-compile
|
|
30
35
|
no-warn-conflicts no-warn-script-location U|upgrade user prefix=p report=p root=p
|
|
31
36
|
root-user-action=b t|target=p upgrade-strategy=b].freeze,
|
|
32
|
-
install_a: %w[ignore-requires-python no-index pre
|
|
33
|
-
|
|
34
|
-
install_b: %w[build-constraint check-build-dependencies no-build-isolation no-clean no-deps
|
|
35
|
-
require-hashes use-pep517 c|constraint=p group=q progress-bar=b r|requirement=p
|
|
36
|
-
requirements-from-script=p src=p].freeze,
|
|
37
|
+
install_a: %w[ignore-requires-python no-index pre extra-index-url=q f|find-links=q i|index-url=q no-binary=q
|
|
38
|
+
only-binary=q].freeze,
|
|
39
|
+
install_b: %w[build-constraint check-build-dependencies no-build-isolation no-clean no-deps prefer-binary
|
|
40
|
+
require-hashes use-pep517 c|constraint=p group=q progress-bar=b r|requirement=p src=p].freeze,
|
|
37
41
|
install_c: %w[C|config-settings=q e|editable=v].freeze,
|
|
38
42
|
hash: %w[a|algorithm].freeze,
|
|
39
|
-
list: %w[e|editable exclude-editable include-editable l|local no-index not-required o|outdated pre
|
|
40
|
-
|
|
41
|
-
i|index-url=q no-binary=q only-binary=q only-final=b path=p].freeze,
|
|
43
|
+
list: %w[e|editable exclude-editable include-editable l|local no-index not-required o|outdated pre u|uptodate
|
|
44
|
+
user exclude=b extra-index-url=q format=b f|find-links=q i|index-url=q path=p].freeze,
|
|
42
45
|
lock: %w[o|output=p].freeze,
|
|
43
46
|
show: %w[f|files].freeze,
|
|
44
47
|
uninstall: %w[break-system-packages y|yes r|requirement=p root-user-action=b].freeze,
|
|
45
48
|
wheel: %w[no-verify w|wheel-dir=p].freeze
|
|
46
49
|
}.freeze
|
|
47
50
|
OPT_POETRY = {
|
|
48
|
-
common: %w[ansi no-ansi no-cache n|no-interaction no-plugins q|quiet
|
|
51
|
+
common: %w[ansi no-ansi no-cache n|no-interaction no-plugins q|quiet v|verbose=+ P|project=p].freeze,
|
|
52
|
+
install: %w[all-extras all-groups compile dry-run no-directory no-root only-root E|extras=q only=q with=q
|
|
53
|
+
without=q].freeze,
|
|
49
54
|
build: %w[clean config-settings=qq f|format=b o|output=p].freeze,
|
|
50
55
|
publish: %w[build dry-run skip-existing cert=p client-cert=p dist-dir=p p|password=q r|repository=q
|
|
51
56
|
u|username=qq].freeze
|
|
@@ -69,13 +74,24 @@ module Squared
|
|
|
69
74
|
client-cert=p c|comment=q config-file=p i|identity=b p|password=q r|repository=b repository-url=q
|
|
70
75
|
sign-with=b u|username=qq].freeze
|
|
71
76
|
}.freeze
|
|
77
|
+
OPT_MESON = {
|
|
78
|
+
build: %w[D=q clearcache debug errorlogs fatal-meson-warnings pkgconfig.relocatable prefer-static
|
|
79
|
+
python.allow-limited-api reconfigure stdsplit strip vsenv werror wipe auto-features=b backend=b
|
|
80
|
+
bindir=p build.cmake-prefix-path=p build.pkg-config-path=p buildtype=b cmake-prefix-path=p
|
|
81
|
+
cross-file=p datadir=p default-library=b default-both-libraries=b force-fallback-for=q genvslite=b
|
|
82
|
+
includedir=p infodir=p install-umask=b layout=b libdir=p libexecdir=p licensedir=p localedir=p
|
|
83
|
+
localstatedir=p mandir=p native-file=p optimization=b pkg-config-path=p prefix=p
|
|
84
|
+
python.bytecompile=i python.platlibdir=p python.purelibdir=p python.install-env=b sbindir=p
|
|
85
|
+
sharedstatedir=p sysconfdir=p unity=b unity-size=i warnlevel=b wrap-mode=b].freeze,
|
|
86
|
+
compile: %w[clean v|verbose j|jobs=i l|load-average=b ninja-args=q vs-args=q xcode-args=q].freeze
|
|
87
|
+
}.freeze
|
|
72
88
|
PASS_PYTHON = {
|
|
73
89
|
python: %w[c v V].freeze,
|
|
74
90
|
pip: {
|
|
75
91
|
debug: %w[platform].freeze,
|
|
76
92
|
install: %w[C config-settings c constraint extra-index-url no-binary only-binary platform
|
|
77
93
|
r requirement].freeze,
|
|
78
|
-
list: %w[exclude extra-index-url
|
|
94
|
+
list: %w[exclude extra-index-url].freeze
|
|
79
95
|
}.freeze
|
|
80
96
|
}.freeze
|
|
81
97
|
private_constant :DEP_PYTHON, :DIR_PYTHON, :OPT_PYTHON, :OPT_PIP, :OPT_POETRY, :OPT_PDM, :OPT_HATCH, :OPT_TWINE,
|
|
@@ -87,7 +103,7 @@ module Squared
|
|
|
87
103
|
end
|
|
88
104
|
|
|
89
105
|
def bannerargs
|
|
90
|
-
%i[dependfile venv].freeze
|
|
106
|
+
%i[version dependfile venv].freeze
|
|
91
107
|
end
|
|
92
108
|
|
|
93
109
|
def venv?
|
|
@@ -101,14 +117,13 @@ module Squared
|
|
|
101
117
|
end
|
|
102
118
|
end
|
|
103
119
|
|
|
104
|
-
attr_reader :venv
|
|
105
|
-
attr_accessor :editable
|
|
120
|
+
attr_reader :venv, :editable
|
|
106
121
|
|
|
107
122
|
def initialize(*, editable: '.', asdf: 'python', **kwargs)
|
|
108
123
|
super
|
|
109
124
|
if @pass.include?(Python.ref)
|
|
110
125
|
initialize_ref Python.ref
|
|
111
|
-
initialize_logger
|
|
126
|
+
initialize_logger kwargs[:log]
|
|
112
127
|
else
|
|
113
128
|
initialize_build(Python.ref, **kwargs)
|
|
114
129
|
initialize_env(**kwargs)
|
|
@@ -121,14 +136,18 @@ module Squared
|
|
|
121
136
|
subtasks({
|
|
122
137
|
'venv' => %i[exec create remove show].freeze,
|
|
123
138
|
'pip' => %i[upgrade uninstall wheel reinstall freeze].freeze,
|
|
124
|
-
'install' => %i[
|
|
139
|
+
'install' => %i[requirement target upgrade editable poetry].freeze,
|
|
125
140
|
'outdated' => %i[major minor patch].freeze,
|
|
126
|
-
'build' => %i[poetry pdm hatch python].freeze,
|
|
141
|
+
'build' => %i[poetry pdm hatch meson python].freeze,
|
|
127
142
|
'publish' => %i[poetry pdm hatch twine].freeze,
|
|
128
143
|
'run' => nil,
|
|
129
144
|
'exec' => nil
|
|
130
145
|
})
|
|
131
146
|
|
|
147
|
+
def project=(val)
|
|
148
|
+
@project = val.dup
|
|
149
|
+
end
|
|
150
|
+
|
|
132
151
|
def verbose=(val)
|
|
133
152
|
case val
|
|
134
153
|
when /\Av+\z/
|
|
@@ -217,7 +236,8 @@ module Squared
|
|
|
217
236
|
elsif i || args.empty?
|
|
218
237
|
readline('Enter command', force: true)
|
|
219
238
|
else
|
|
220
|
-
|
|
239
|
+
command_args(args, min: 1, prefix: 'python')
|
|
240
|
+
args.join(' ')
|
|
221
241
|
end
|
|
222
242
|
shell(cmd, name: :exec, chdir: path)
|
|
223
243
|
end
|
|
@@ -251,8 +271,8 @@ module Squared
|
|
|
251
271
|
args = args.to_a
|
|
252
272
|
if args.empty?
|
|
253
273
|
args = readline('Enter command', force: true).split(' ', 2)
|
|
254
|
-
elsif args.size == 1 &&
|
|
255
|
-
args << readline('Enter arguments', force: false)
|
|
274
|
+
elsif args.size == 1 && option('interactive', notequals: '0', prefix: ref)
|
|
275
|
+
args << readline('Enter arguments', force: false)
|
|
256
276
|
end
|
|
257
277
|
venv_init
|
|
258
278
|
run args.join(' ')
|
|
@@ -274,9 +294,9 @@ module Squared
|
|
|
274
294
|
when :freeze
|
|
275
295
|
format_desc action, flag, "file?=#{DEP_PYTHON[4]},opts*"
|
|
276
296
|
task flag do |_, args|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
297
|
+
next unless (file = pip(flag, opts: args.to_a, banner: true)) && !silent?
|
|
298
|
+
|
|
299
|
+
puts File.read(file)
|
|
280
300
|
end
|
|
281
301
|
when :uninstall
|
|
282
302
|
format_desc action, flag, 'package+,opts*'
|
|
@@ -300,15 +320,12 @@ module Squared
|
|
|
300
320
|
end
|
|
301
321
|
when 'install'
|
|
302
322
|
format_desc(action, flag, 'opts*', before: case flag
|
|
303
|
-
when :
|
|
304
|
-
when :
|
|
305
|
-
when :
|
|
323
|
+
when :editable then 'path/url?'
|
|
324
|
+
when :upgrade then 'strategy?,package+'
|
|
325
|
+
when :requirement, :target then 'path'
|
|
326
|
+
else 'package+'
|
|
306
327
|
end)
|
|
307
328
|
case flag
|
|
308
|
-
when :editable
|
|
309
|
-
task flag do |_, args|
|
|
310
|
-
install flag, args.to_a
|
|
311
|
-
end
|
|
312
329
|
when :upgrade
|
|
313
330
|
task flag, [:strategy] do |_, args|
|
|
314
331
|
install flag, (case args.strategy
|
|
@@ -324,14 +341,16 @@ module Squared
|
|
|
324
341
|
end
|
|
325
342
|
end)
|
|
326
343
|
end
|
|
327
|
-
when :target
|
|
328
|
-
task flag, [:
|
|
329
|
-
|
|
330
|
-
depend(flag, args.extras, target:
|
|
344
|
+
when :requirement, :target
|
|
345
|
+
task flag, [:path] do |_, args|
|
|
346
|
+
path = param_guard(action, flag, args: args, key: :path)
|
|
347
|
+
depend(flag, args.extras, target: path)
|
|
331
348
|
end
|
|
332
349
|
else
|
|
350
|
+
next if flag == :poetry && !poetry?
|
|
351
|
+
|
|
333
352
|
task flag do |_, args|
|
|
334
|
-
|
|
353
|
+
install flag, args.to_a
|
|
335
354
|
end
|
|
336
355
|
end
|
|
337
356
|
when 'outdated'
|
|
@@ -389,22 +408,24 @@ module Squared
|
|
|
389
408
|
cmd << '--no-root' if option('no-root')
|
|
390
409
|
else
|
|
391
410
|
cmd = pip_session 'install'
|
|
392
|
-
cmd << '--upgrade-strategy=eager' if env('PYTHON_UPDATE')
|
|
411
|
+
cmd << '--upgrade-strategy=eager' if env('UPDATE') || env('PYTHON_UPDATE')
|
|
412
|
+
cmd << '--no-build-isolation' if option('build-isolation', equals: '0')
|
|
393
413
|
if flag
|
|
394
|
-
case flag
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
end
|
|
402
|
-
op = append_pip(flag, opts, from: :install)
|
|
414
|
+
cmd << case flag
|
|
415
|
+
when :requirement, :target
|
|
416
|
+
quote_option(flag, basepath(target))
|
|
417
|
+
else
|
|
418
|
+
shell_option(flag)
|
|
419
|
+
end
|
|
420
|
+
op = append_pip flag, opts, pipopts(:install)
|
|
403
421
|
op.clear
|
|
404
422
|
else
|
|
405
423
|
append_global
|
|
406
424
|
end
|
|
407
|
-
|
|
425
|
+
if exist?(DEP_PYTHON[4]) && !session_arg?('r', 'requirement')
|
|
426
|
+
cmd << basic_option('r', DEP_PYTHON[4])
|
|
427
|
+
cmd << basic_option('c', 'constraints.txt') if exist?('constraints.txt')
|
|
428
|
+
end
|
|
408
429
|
append_editable
|
|
409
430
|
end
|
|
410
431
|
run(sync: sync, from: :depend)
|
|
@@ -436,7 +457,7 @@ module Squared
|
|
|
436
457
|
:patch
|
|
437
458
|
end
|
|
438
459
|
end
|
|
439
|
-
'--not-required'
|
|
460
|
+
'--not-required' if option('not-required', notequals: '0') && !env('PYTHON_DEFAULT')
|
|
440
461
|
end
|
|
441
462
|
cmd << '--local' if option('l', 'local')
|
|
442
463
|
append_global
|
|
@@ -446,7 +467,7 @@ module Squared
|
|
|
446
467
|
on :first, :outdated
|
|
447
468
|
banner = format_banner cmd
|
|
448
469
|
print_item banner if sync
|
|
449
|
-
pwd_set(
|
|
470
|
+
pwd_set(cmd, dryrun: dryrun) do
|
|
450
471
|
tc = theme[:current]
|
|
451
472
|
start = 0
|
|
452
473
|
found = 0
|
|
@@ -460,7 +481,8 @@ module Squared
|
|
|
460
481
|
(venv ? command(runenv, cmd) : `#{cmd}`).lines(chomp: true)
|
|
461
482
|
else
|
|
462
483
|
IO.popen(runenv || {}, cmd).readlines(chomp: true)
|
|
463
|
-
end
|
|
484
|
+
end
|
|
485
|
+
.each do |line|
|
|
464
486
|
next if line.match?(/^[ -]+$/)
|
|
465
487
|
|
|
466
488
|
if start > 0
|
|
@@ -523,7 +545,7 @@ module Squared
|
|
|
523
545
|
if found > 0
|
|
524
546
|
items = if se
|
|
525
547
|
choice('Select a package', items.map(&:first),
|
|
526
|
-
multiple: true, force: false, index: true, border: true).map
|
|
548
|
+
multiple: true, force: false, index: true, border: true).map { |n| items[n.pred].last }
|
|
527
549
|
elsif ia
|
|
528
550
|
items.map(&:last)
|
|
529
551
|
else
|
|
@@ -539,10 +561,9 @@ module Squared
|
|
|
539
561
|
if up && !items.empty?
|
|
540
562
|
base = %w[eager no-deps]
|
|
541
563
|
base << 'user' unless venv
|
|
542
|
-
opts = (base & opts).map
|
|
564
|
+
opts = (base & opts).map { |val| val == 'eager' ? "upgrade-strategy=#{val}" : val }
|
|
543
565
|
if dryrun
|
|
544
|
-
opts.map
|
|
545
|
-
print_run pip_output('install --upgrade', *opts, *items.quote!), false
|
|
566
|
+
print_run pip_output('install --upgrade', *opts.map { |val| fill_option(val) }, *items.quote!), false
|
|
546
567
|
else
|
|
547
568
|
install(:upgrade, opts, packages: items, banner: false)
|
|
548
569
|
end
|
|
@@ -555,8 +576,13 @@ module Squared
|
|
|
555
576
|
on :last, :outdated
|
|
556
577
|
end
|
|
557
578
|
|
|
558
|
-
def install(flag, opts = [], packages: [], banner:
|
|
559
|
-
|
|
579
|
+
def install(flag, opts = [], packages: [], banner: !silent?)
|
|
580
|
+
if flag == :poetry
|
|
581
|
+
OptionPartition.new(opts, OPT_POETRY[:install] + OPT_POETRY[:common], poetry_session('install'),
|
|
582
|
+
project: self, single: singleopt(flag))
|
|
583
|
+
else
|
|
584
|
+
op = append_pip(flag, opts, pipopts(:install), target: pip_session('install'))
|
|
585
|
+
end
|
|
560
586
|
case flag
|
|
561
587
|
when :editable
|
|
562
588
|
op << quote_option('e', op.pop || editable || '.')
|
|
@@ -571,7 +597,7 @@ module Squared
|
|
|
571
597
|
run(banner: banner, from: :install)
|
|
572
598
|
end
|
|
573
599
|
|
|
574
|
-
def build!(flag, opts = [])
|
|
600
|
+
def build!(flag, opts = [], outdir: nil, srcdir: nil)
|
|
575
601
|
list = case flag
|
|
576
602
|
when :poetry
|
|
577
603
|
cmd = poetry_session 'build'
|
|
@@ -582,6 +608,9 @@ module Squared
|
|
|
582
608
|
when :hatch
|
|
583
609
|
cmd, opts = hatch_session('build', opts: opts)
|
|
584
610
|
OPT_HATCH[:build]
|
|
611
|
+
when :meson
|
|
612
|
+
cmd = session 'meson', 'setup'
|
|
613
|
+
OPT_MESON[:build]
|
|
585
614
|
else
|
|
586
615
|
cmd, opts = python_session('-m build', opts: opts)
|
|
587
616
|
OPT_PYTHON[:build]
|
|
@@ -589,26 +618,45 @@ module Squared
|
|
|
589
618
|
op = OptionPartition.new(opts, list, cmd, project: self, single: singleopt(flag))
|
|
590
619
|
case flag
|
|
591
620
|
when :hatch
|
|
592
|
-
if !ENV['HATCH_BUILD_LOCATION'] && (outdir ||= op.shift)
|
|
621
|
+
op.add_path(outdir) if !ENV['HATCH_BUILD_LOCATION'] && (outdir ||= op.shift)
|
|
622
|
+
srcdir = false
|
|
623
|
+
when :meson
|
|
624
|
+
if outdir
|
|
593
625
|
op.add_path(outdir)
|
|
626
|
+
else
|
|
627
|
+
outdir = op.first
|
|
628
|
+
op.add_first(path: true, expect: 'outdir not specified')
|
|
594
629
|
end
|
|
595
630
|
else
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
631
|
+
args = case flag
|
|
632
|
+
when :poetry
|
|
633
|
+
srcdir = false
|
|
634
|
+
%w[o output]
|
|
635
|
+
when :pdm
|
|
636
|
+
srcdir = false
|
|
637
|
+
%w[d dest]
|
|
638
|
+
else
|
|
639
|
+
%w[o outdir]
|
|
640
|
+
end
|
|
641
|
+
outdir = op.shift unless op.arg?(*args)
|
|
642
|
+
op << quote_option(args.last, basepath(outdir)) if outdir
|
|
643
|
+
end
|
|
644
|
+
unless srcdir == false
|
|
645
|
+
if srcdir
|
|
646
|
+
op.add_path(srcdir)
|
|
647
|
+
else
|
|
648
|
+
op.exist?(add: true, first: true)
|
|
607
649
|
end
|
|
608
650
|
end
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
651
|
+
from = symjoin flag, 'build'
|
|
652
|
+
if flag == :meson
|
|
653
|
+
cmd = session_output 'meson', 'compile', quote_option('C', basepath(outdir))
|
|
654
|
+
OptionPartition.new(op.extras, OPT_MESON[:compile], cmd, project: self).append unless op.empty?
|
|
655
|
+
run_s(op, cmd.done, from: from)
|
|
656
|
+
else
|
|
657
|
+
op.clear
|
|
658
|
+
run(from: from)
|
|
659
|
+
end
|
|
612
660
|
end
|
|
613
661
|
|
|
614
662
|
def publish(flag, opts = [], test: false)
|
|
@@ -655,12 +703,12 @@ module Squared
|
|
|
655
703
|
op.add_path
|
|
656
704
|
end
|
|
657
705
|
end
|
|
658
|
-
run(from:
|
|
706
|
+
run(from: symjoin(flag, 'publish'), interactive: ['Publish', 'N', project])
|
|
659
707
|
end
|
|
660
708
|
|
|
661
709
|
def python(*args, sync: true, banner: verbose?, with: nil, pass: PASS_PYTHON[:python], **kwargs)
|
|
662
710
|
op = OptionPartition.new(session_opts(with, args: args, kwargs: kwargs, pass: pass), OPT_PYTHON[:common],
|
|
663
|
-
session('python', path: venv
|
|
711
|
+
session('python', path: !venv?),
|
|
664
712
|
project: self, multiple: [/^-c/], single: singleopt(:python), args: true,
|
|
665
713
|
stdin: true)
|
|
666
714
|
op.concat(args)
|
|
@@ -676,7 +724,7 @@ module Squared
|
|
|
676
724
|
end
|
|
677
725
|
end
|
|
678
726
|
print_run(op, banner, **kwargs)
|
|
679
|
-
run(sync: sync, banner: banner, exception: kwargs.fetch(:exception, exception), from: :python)
|
|
727
|
+
run(sync: sync, banner: banner, exception: kwargs.fetch(:exception, exception?), from: :python)
|
|
680
728
|
end
|
|
681
729
|
|
|
682
730
|
def pip(flag, *args, sync: true, banner: verbose?, with: nil, pass: nil, **kwargs)
|
|
@@ -687,7 +735,7 @@ module Squared
|
|
|
687
735
|
when :freeze, :inspect, :list, :check, :completion, :debug
|
|
688
736
|
opts.concat(args)
|
|
689
737
|
end
|
|
690
|
-
op = append_pip(flag, opts,
|
|
738
|
+
op = append_pip(flag, opts, pipopts(flag), target: pip_session(flag))
|
|
691
739
|
case flag
|
|
692
740
|
when :install, :uninstall, :show, :index
|
|
693
741
|
op.concat(args)
|
|
@@ -752,14 +800,24 @@ module Squared
|
|
|
752
800
|
op.clear
|
|
753
801
|
end
|
|
754
802
|
print_run(op, banner, **kwargs)
|
|
755
|
-
run(sync: sync, banner: banner, exception: kwargs.fetch(:exception, exception), from:
|
|
803
|
+
run(sync: sync, banner: banner, exception: kwargs.fetch(:exception, exception?), from: symjoin('pip', flag))
|
|
756
804
|
.yield_self { |val| ret || val }
|
|
757
805
|
end
|
|
758
806
|
|
|
807
|
+
def project
|
|
808
|
+
return @project unless @project.frozen?
|
|
809
|
+
|
|
810
|
+
@project = (read_pyproject('project', 'name') || @project).dup
|
|
811
|
+
end
|
|
812
|
+
|
|
813
|
+
def version
|
|
814
|
+
@version ||= read_pyproject('project', 'version')
|
|
815
|
+
end
|
|
816
|
+
|
|
759
817
|
def variable_set(key, *args, **, &blk)
|
|
760
818
|
if block_given?
|
|
761
819
|
case key
|
|
762
|
-
when :dependfile, :
|
|
820
|
+
when :dependfile, :editable, :venv
|
|
763
821
|
args = block_args args, &blk
|
|
764
822
|
end
|
|
765
823
|
end
|
|
@@ -773,7 +831,7 @@ module Squared
|
|
|
773
831
|
@dependindex = index
|
|
774
832
|
@dependfile = val
|
|
775
833
|
else
|
|
776
|
-
log.warn "variable_set:
|
|
834
|
+
log.warn "variable_set: @dependfile=#{val}".subhint('not supported')
|
|
777
835
|
end
|
|
778
836
|
end
|
|
779
837
|
when :editable
|
|
@@ -793,60 +851,51 @@ module Squared
|
|
|
793
851
|
dependtype > 0 && !task_pass?('outdated')
|
|
794
852
|
end
|
|
795
853
|
|
|
854
|
+
def venv?
|
|
855
|
+
!venv.nil?
|
|
856
|
+
end
|
|
857
|
+
|
|
796
858
|
private
|
|
797
859
|
|
|
798
860
|
def pip_session(*cmd)
|
|
799
|
-
session('pip', *cmd, *preopts, path: venv
|
|
861
|
+
session('pip', *cmd, *preopts, path: !venv?)
|
|
800
862
|
end
|
|
801
863
|
|
|
802
864
|
def pip_output(*cmd)
|
|
803
|
-
session_output('pip', *cmd, *preopts, path: venv
|
|
865
|
+
session_output('pip', *cmd, *preopts, path: !venv?)
|
|
804
866
|
end
|
|
805
867
|
|
|
806
868
|
def python_session(*cmd, opts: nil)
|
|
807
|
-
|
|
808
|
-
return session('python', *pre, *cmd, path: venv.nil?) unless opts
|
|
809
|
-
|
|
810
|
-
op = OptionPartition.new(opts, OPT_PYTHON[:common], project: self, single: singleopt(:python))
|
|
811
|
-
[session('python', *pre, *op.to_a, *cmd, path: venv.nil?), op.extras]
|
|
812
|
-
end
|
|
813
|
-
|
|
814
|
-
def poetry_session(*cmd)
|
|
815
|
-
ret = session('poetry', *cmd, *preopts)
|
|
816
|
-
option('project', ignore: false) { |val| ret << quote_option('project', basepath(val)) }
|
|
817
|
-
ret
|
|
869
|
+
create_session('python', *cmd, common: OPT_PYTHON[:common], opts: opts, quiet: false)
|
|
818
870
|
end
|
|
819
871
|
|
|
820
872
|
def pdm_session(*cmd, opts: nil)
|
|
821
|
-
create_session(
|
|
873
|
+
create_session('pdm', *cmd, common: OPT_PDM[:common], opts: opts)
|
|
822
874
|
end
|
|
823
875
|
|
|
824
876
|
def hatch_session(*cmd, opts: nil)
|
|
825
|
-
|
|
877
|
+
if (target = append_nocolor('no-color', target: [], prefix: 'hatch'))
|
|
878
|
+
(opts ||= []).concat(target)
|
|
879
|
+
end
|
|
880
|
+
create_session('hatch', *cmd, common: OPT_HATCH[:common], opts: opts)
|
|
826
881
|
end
|
|
827
882
|
|
|
828
|
-
def
|
|
829
|
-
|
|
883
|
+
def poetry_session(*cmd)
|
|
884
|
+
ret = session('poetry', *cmd, *preopts)
|
|
885
|
+
option('project', ignore: false, path: true)
|
|
886
|
+
append_nocolor '--no-ansi'
|
|
887
|
+
ret
|
|
888
|
+
end
|
|
889
|
+
|
|
890
|
+
def create_session(name, *cmd, common:, opts: nil, quiet: true)
|
|
891
|
+
pre = preopts(quiet: quiet)
|
|
892
|
+
return session(name, *pre, *cmd, path: !venv?) unless opts
|
|
830
893
|
|
|
831
894
|
op = OptionPartition.new(opts, common, project: self, single: singleopt(name.to_sym))
|
|
832
|
-
[session(name, *
|
|
895
|
+
[session(name, *pre, *op.to_a, *cmd, path: !venv?), op.extras]
|
|
833
896
|
end
|
|
834
897
|
|
|
835
|
-
def append_pip(flag, opts, target: @session
|
|
836
|
-
list = OPT_PIP.fetch(from, []) + OPT_PIP[:common]
|
|
837
|
-
if pip_install?(flag) || from == :install
|
|
838
|
-
list.concat(OPT_PIP[:install_a])
|
|
839
|
-
list.concat(OPT_PIP[:install_b]) unless flag == :index
|
|
840
|
-
case flag
|
|
841
|
-
when :install, :editable, :upgrade
|
|
842
|
-
list.concat(OPT_PIP[:install_c] + OPT_PIP[:debug])
|
|
843
|
-
when :lock, :wheel
|
|
844
|
-
list.concat(OPT_PIP[:install_c])
|
|
845
|
-
when :download, :index
|
|
846
|
-
list.concat(OPT_PIP[:debug])
|
|
847
|
-
end
|
|
848
|
-
opts << 'no-build-isolation' if option('build-isolation', equals: '0')
|
|
849
|
-
end
|
|
898
|
+
def append_pip(flag, opts, list, target: @session)
|
|
850
899
|
op = OptionPartition.new(opts, list, target, project: self, single: singleopt)
|
|
851
900
|
append_global(target: target)
|
|
852
901
|
case flag
|
|
@@ -867,7 +916,7 @@ module Squared
|
|
|
867
916
|
end
|
|
868
917
|
op.swap
|
|
869
918
|
if edit
|
|
870
|
-
edit = basepath(edit) unless %r{\A[a-z]+(
|
|
919
|
+
edit = basepath(edit) unless %r{\A[a-z]+(\+[a-z]+)?://}i.match?(edit)
|
|
871
920
|
if flag == :editable
|
|
872
921
|
op.push(edit)
|
|
873
922
|
else
|
|
@@ -898,18 +947,16 @@ module Squared
|
|
|
898
947
|
end
|
|
899
948
|
|
|
900
949
|
def append_global(target: @session)
|
|
901
|
-
target
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
option('python', target: target) { |val| quote_option('python', basepath(val)) }
|
|
912
|
-
])
|
|
950
|
+
option('cache-dir', target: target) do |val|
|
|
951
|
+
target << case val
|
|
952
|
+
when '0', 'false'
|
|
953
|
+
'--no-cache-dir'
|
|
954
|
+
else
|
|
955
|
+
quote_option('cache-dir', basepath(val))
|
|
956
|
+
end
|
|
957
|
+
end
|
|
958
|
+
option('proxy', target: target, quote: true)
|
|
959
|
+
option('python', target: target, path: true)
|
|
913
960
|
append_nocolor(target: target)
|
|
914
961
|
end
|
|
915
962
|
|
|
@@ -920,14 +967,18 @@ module Squared
|
|
|
920
967
|
def read_pyproject(table, key = nil)
|
|
921
968
|
return [] unless (file = pyprojectfile)
|
|
922
969
|
|
|
923
|
-
|
|
970
|
+
ret = (@pyproject ||= {})[table]
|
|
971
|
+
unless ret
|
|
924
972
|
ret = []
|
|
973
|
+
found = false
|
|
925
974
|
start = /^\s*\[#{Regexp.escape(table)}\]\s*$/
|
|
926
975
|
ch = nil
|
|
927
|
-
found = false
|
|
928
976
|
File.foreach(file) do |line|
|
|
977
|
+
next if line.start_with?(/\s*#/)
|
|
978
|
+
|
|
929
979
|
if found
|
|
930
|
-
|
|
980
|
+
line.chomp!($1) if line =~ /(?<=[\d"'{}\[\]]|true|false)(\s*#.*)$/
|
|
981
|
+
break if line.match?(/^\s*\[(?:[\w.\-" ]+|".+"|'.+')\]\s*$/)
|
|
931
982
|
|
|
932
983
|
if ch
|
|
933
984
|
val = line.rstrip
|
|
@@ -943,9 +994,9 @@ module Squared
|
|
|
943
994
|
end
|
|
944
995
|
end
|
|
945
996
|
ret.last[1] += val
|
|
946
|
-
elsif
|
|
947
|
-
if (val =
|
|
948
|
-
case (ch =
|
|
997
|
+
elsif line.strip =~ /^(\S+)\s*=\s*([+-]?[\d.]+|true|false|("""|'''|["'\[{])(.*))$/
|
|
998
|
+
if (val = $4)
|
|
999
|
+
case (ch = $3)
|
|
949
1000
|
when '{', '['
|
|
950
1001
|
val = "#{ch}#{val}"
|
|
951
1002
|
ch = ch == '{' ? '}' : ']'
|
|
@@ -958,7 +1009,7 @@ module Squared
|
|
|
958
1009
|
end
|
|
959
1010
|
end
|
|
960
1011
|
else
|
|
961
|
-
val = case (ch =
|
|
1012
|
+
val = case (ch = $2)
|
|
962
1013
|
when 'true'
|
|
963
1014
|
true
|
|
964
1015
|
when 'false'
|
|
@@ -967,7 +1018,10 @@ module Squared
|
|
|
967
1018
|
ch.include?('.') ? ch.to_f : ch.to_i
|
|
968
1019
|
end
|
|
969
1020
|
end
|
|
970
|
-
ret << [
|
|
1021
|
+
ret << [$1, val]
|
|
1022
|
+
end
|
|
1023
|
+
if !ch && (val = ret.last[1]).is_a?(String) && (val.match?(/\A\{.+\}\z/m) || val.match?(/\A\[.+\]\z/m))
|
|
1024
|
+
ret.last[1] = JSON.parse(val) rescue nil
|
|
971
1025
|
end
|
|
972
1026
|
else
|
|
973
1027
|
found = line.match?(start)
|
|
@@ -975,9 +1029,7 @@ module Squared
|
|
|
975
1029
|
end
|
|
976
1030
|
@pyproject[table] = ret
|
|
977
1031
|
end
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
ret
|
|
1032
|
+
key ? ret.find { |val| val.first == key }&.last : ret
|
|
981
1033
|
end
|
|
982
1034
|
|
|
983
1035
|
def pyprojectfile
|
|
@@ -989,9 +1041,9 @@ module Squared
|
|
|
989
1041
|
case flag
|
|
990
1042
|
when :python
|
|
991
1043
|
/\A(?:v+|q+|b+|V+|O+)\z/
|
|
992
|
-
when :pdm
|
|
1044
|
+
when :pdm, :poetry
|
|
993
1045
|
/\Av+\z/
|
|
994
|
-
when :twine
|
|
1046
|
+
when :twine, :meson
|
|
995
1047
|
nil
|
|
996
1048
|
else
|
|
997
1049
|
/\A(?:v+|q+)\z/
|
|
@@ -1001,7 +1053,7 @@ module Squared
|
|
|
1001
1053
|
def preopts(quiet: true)
|
|
1002
1054
|
ret = []
|
|
1003
1055
|
case verbose
|
|
1004
|
-
when
|
|
1056
|
+
when false
|
|
1005
1057
|
ret << '--quiet' if quiet
|
|
1006
1058
|
when Numeric
|
|
1007
1059
|
ret << "-#{'v' * verbose}" if verbose > 0
|
|
@@ -1009,6 +1061,23 @@ module Squared
|
|
|
1009
1061
|
ret
|
|
1010
1062
|
end
|
|
1011
1063
|
|
|
1064
|
+
def pipopts(flag)
|
|
1065
|
+
ret = OPT_PIP.fetch(flag, []) + OPT_PIP[:common]
|
|
1066
|
+
if pip_install?(flag)
|
|
1067
|
+
ret.concat(OPT_PIP[:install_a])
|
|
1068
|
+
ret.concat(OPT_PIP[:install_b]) unless flag == :index
|
|
1069
|
+
case flag
|
|
1070
|
+
when :install
|
|
1071
|
+
ret.concat(OPT_PIP[:install_c] + OPT_PIP[:debug])
|
|
1072
|
+
when :lock, :wheel
|
|
1073
|
+
ret.concat(OPT_PIP[:install_c])
|
|
1074
|
+
when :download, :index
|
|
1075
|
+
ret.concat(OPT_PIP[:debug])
|
|
1076
|
+
end
|
|
1077
|
+
end
|
|
1078
|
+
ret
|
|
1079
|
+
end
|
|
1080
|
+
|
|
1012
1081
|
def variables
|
|
1013
1082
|
(super + %i[venv editable]).freeze
|
|
1014
1083
|
end
|
|
@@ -1037,11 +1106,16 @@ module Squared
|
|
|
1037
1106
|
end
|
|
1038
1107
|
|
|
1039
1108
|
def venv_set(val)
|
|
1109
|
+
@venv = nil
|
|
1040
1110
|
return unless val
|
|
1041
1111
|
|
|
1042
|
-
write = ->(level, hint) { log.add(level, "venv: #{@venv}".subhint(hint)) }
|
|
1112
|
+
write = ->(level, hint) { log.add(level, "#{virtualenv? ? 'virtualenv' : 'venv'}: #{@venv}".subhint(hint)) }
|
|
1043
1113
|
if val.is_a?(Array)
|
|
1044
1114
|
val, *opts = val
|
|
1115
|
+
if opts.first == 'virtualenv'
|
|
1116
|
+
@virtualenv = true
|
|
1117
|
+
opts.shift
|
|
1118
|
+
end
|
|
1045
1119
|
@venvopts = opts
|
|
1046
1120
|
end
|
|
1047
1121
|
@venv = basepath val
|
|
@@ -1061,21 +1135,35 @@ module Squared
|
|
|
1061
1135
|
def venv_init
|
|
1062
1136
|
return if !venv || (venvbin.directory? && !venvbin.empty?)
|
|
1063
1137
|
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1138
|
+
subject = virtualenv? ? 'virtualenv' : 'venv'
|
|
1139
|
+
puts log_message(venv, subject: subject, hint: 'init') unless silent?
|
|
1140
|
+
opts = @venvopts ? @venvopts.map { |val| OptionPartition.strip(val) }.flatten : [basic_option('prompt', name)]
|
|
1141
|
+
venv_create(venv, opts, env: false, banner: false)
|
|
1142
|
+
puts log_message(venv, subject: subject, hint: 'created') unless silent?
|
|
1068
1143
|
end
|
|
1069
1144
|
|
|
1070
1145
|
def venv_create(dir, opts = [], env: nil, banner: banner?)
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1146
|
+
flag = if virtualenv?
|
|
1147
|
+
status = true
|
|
1148
|
+
:virtualenv
|
|
1149
|
+
else
|
|
1150
|
+
:venv
|
|
1151
|
+
end
|
|
1152
|
+
cmd, opts = python_session('-m', flag, opts: opts)
|
|
1153
|
+
op = OptionPartition.new(opts, OPT_PYTHON[flag], cmd, project: self)
|
|
1154
|
+
op.append(dir, delim: true)
|
|
1155
|
+
.clear(pass: false)
|
|
1156
|
+
status ||= op.arg?(/\A-v+\z/)
|
|
1076
1157
|
ret = run(op, env, exception: true, banner: banner)
|
|
1077
|
-
|
|
1078
|
-
|
|
1158
|
+
args = []
|
|
1159
|
+
requires = read_pyproject 'build-system', 'requires'
|
|
1160
|
+
args.concat(requires) if requires.is_a?(Array)
|
|
1161
|
+
if poetry?
|
|
1162
|
+
requires = read_pyproject 'tool.poetry', 'requires-poetry'
|
|
1163
|
+
args << "poetry#{requires}"
|
|
1164
|
+
end
|
|
1165
|
+
pip(:install, *args, banner: false) unless args.empty?
|
|
1166
|
+
success?(ret, banner, !status) { |ret| puts(ret && dir.directory? ? "Success: #{dir}" : 'Failed') }
|
|
1079
1167
|
end
|
|
1080
1168
|
|
|
1081
1169
|
def pip_install?(flag)
|
|
@@ -1092,6 +1180,8 @@ module Squared
|
|
|
1092
1180
|
build_backend == 'hatchling.build'
|
|
1093
1181
|
when :setuptools
|
|
1094
1182
|
build_backend == 'setuptools.build_meta'
|
|
1183
|
+
when :meson
|
|
1184
|
+
build_backend != 'mesonpy' && exist?('meson.build')
|
|
1095
1185
|
end
|
|
1096
1186
|
end
|
|
1097
1187
|
|
|
@@ -1107,6 +1197,10 @@ module Squared
|
|
|
1107
1197
|
dependtype == 1
|
|
1108
1198
|
end
|
|
1109
1199
|
|
|
1200
|
+
def virtualenv?
|
|
1201
|
+
@virtualenv ||= exist?('virtualenv.ini') || !ENV['VIRTUALENV_PYTHON'].nil?
|
|
1202
|
+
end
|
|
1203
|
+
|
|
1110
1204
|
def requirements?
|
|
1111
1205
|
dependtype == 5
|
|
1112
1206
|
end
|