squared 0.6.13 → 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 +69 -85
- 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 +21 -22
- data/lib/squared/common/system.rb +29 -21
- 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 +292 -180
- data/lib/squared/workspace/project/base.rb +559 -467
- data/lib/squared/workspace/project/docker.rb +166 -159
- data/lib/squared/workspace/project/git.rb +202 -168
- data/lib/squared/workspace/project/node.rb +115 -127
- data/lib/squared/workspace/project/python.rb +248 -160
- data/lib/squared/workspace/project/ruby.rb +403 -292
- data/lib/squared/workspace/project/support/class.rb +13 -7
- data/lib/squared/workspace/project/support/optionpartition.rb +70 -55
- 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 +3 -2
|
@@ -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,19 +117,18 @@ 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)
|
|
115
130
|
end
|
|
116
|
-
dependfile_set
|
|
131
|
+
dependfile_set DEP_PYTHON
|
|
117
132
|
editable_set editable
|
|
118
133
|
venv_set kwargs[:venv]
|
|
119
134
|
end
|
|
@@ -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/
|
|
@@ -204,12 +223,12 @@ module Squared
|
|
|
204
223
|
end
|
|
205
224
|
next if found.anybits?(1)
|
|
206
225
|
|
|
207
|
-
puts log_message(found == 0 ? Logger::INFO : Logger
|
|
226
|
+
puts log_message(found == 0 ? Logger::INFO : Logger.WARN,
|
|
208
227
|
"no scripts #{found == 0 ? 'found' : 'executed'}",
|
|
209
228
|
subject: name, hint: pyprojectfile)
|
|
210
229
|
end
|
|
211
230
|
when 'exec'
|
|
212
|
-
format_desc action, nil, 'command
|
|
231
|
+
format_desc action, nil, ':|command,args*'
|
|
213
232
|
task action do |_, args|
|
|
214
233
|
args = args.to_a
|
|
215
234
|
cmd = if (i = args.delete(':')) && !workspace.windows?
|
|
@@ -217,9 +236,10 @@ 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
|
|
224
244
|
end
|
|
225
245
|
else
|
|
@@ -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)
|
|
@@ -710,9 +758,7 @@ module Squared
|
|
|
710
758
|
when :freeze
|
|
711
759
|
venv_init
|
|
712
760
|
op << '>'
|
|
713
|
-
|
|
714
|
-
op.remove(file) if file
|
|
715
|
-
op.add_quote(ret = basepath(file || DEP_PYTHON[4]))
|
|
761
|
+
op.add_quote(ret = basepath(op.detect { |val| op.exist?(val) } || DEP_PYTHON[4]))
|
|
716
762
|
.clear
|
|
717
763
|
when :cache
|
|
718
764
|
op.concat(args)
|
|
@@ -754,14 +800,24 @@ module Squared
|
|
|
754
800
|
op.clear
|
|
755
801
|
end
|
|
756
802
|
print_run(op, banner, **kwargs)
|
|
757
|
-
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))
|
|
758
804
|
.yield_self { |val| ret || val }
|
|
759
805
|
end
|
|
760
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
|
+
|
|
761
817
|
def variable_set(key, *args, **, &blk)
|
|
762
818
|
if block_given?
|
|
763
819
|
case key
|
|
764
|
-
when :dependfile, :
|
|
820
|
+
when :dependfile, :editable, :venv
|
|
765
821
|
args = block_args args, &blk
|
|
766
822
|
end
|
|
767
823
|
end
|
|
@@ -775,7 +831,7 @@ module Squared
|
|
|
775
831
|
@dependindex = index
|
|
776
832
|
@dependfile = val
|
|
777
833
|
else
|
|
778
|
-
log.warn "variable_set:
|
|
834
|
+
log.warn "variable_set: @dependfile=#{val}".subhint('not supported')
|
|
779
835
|
end
|
|
780
836
|
end
|
|
781
837
|
when :editable
|
|
@@ -795,60 +851,51 @@ module Squared
|
|
|
795
851
|
dependtype > 0 && !task_pass?('outdated')
|
|
796
852
|
end
|
|
797
853
|
|
|
854
|
+
def venv?
|
|
855
|
+
!venv.nil?
|
|
856
|
+
end
|
|
857
|
+
|
|
798
858
|
private
|
|
799
859
|
|
|
800
860
|
def pip_session(*cmd)
|
|
801
|
-
session('pip', *cmd, *preopts, path: venv
|
|
861
|
+
session('pip', *cmd, *preopts, path: !venv?)
|
|
802
862
|
end
|
|
803
863
|
|
|
804
864
|
def pip_output(*cmd)
|
|
805
|
-
session_output('pip', *cmd, *preopts, path: venv
|
|
865
|
+
session_output('pip', *cmd, *preopts, path: !venv?)
|
|
806
866
|
end
|
|
807
867
|
|
|
808
868
|
def python_session(*cmd, opts: nil)
|
|
809
|
-
|
|
810
|
-
return session('python', *pre, *cmd, path: venv.nil?) unless opts
|
|
811
|
-
|
|
812
|
-
op = OptionPartition.new(opts, OPT_PYTHON[:common], project: self, single: singleopt(:python))
|
|
813
|
-
[session('python', *pre, *op.to_a, *cmd, path: venv.nil?), op.extras]
|
|
814
|
-
end
|
|
815
|
-
|
|
816
|
-
def poetry_session(*cmd)
|
|
817
|
-
ret = session('poetry', *cmd, *preopts)
|
|
818
|
-
option('project', ignore: false) { |val| ret << quote_option('project', basepath(val)) }
|
|
819
|
-
ret
|
|
869
|
+
create_session('python', *cmd, common: OPT_PYTHON[:common], opts: opts, quiet: false)
|
|
820
870
|
end
|
|
821
871
|
|
|
822
872
|
def pdm_session(*cmd, opts: nil)
|
|
823
|
-
create_session(
|
|
873
|
+
create_session('pdm', *cmd, common: OPT_PDM[:common], opts: opts)
|
|
824
874
|
end
|
|
825
875
|
|
|
826
876
|
def hatch_session(*cmd, opts: nil)
|
|
827
|
-
|
|
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)
|
|
828
881
|
end
|
|
829
882
|
|
|
830
|
-
def
|
|
831
|
-
|
|
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
|
|
832
893
|
|
|
833
894
|
op = OptionPartition.new(opts, common, project: self, single: singleopt(name.to_sym))
|
|
834
|
-
[session(name, *
|
|
895
|
+
[session(name, *pre, *op.to_a, *cmd, path: !venv?), op.extras]
|
|
835
896
|
end
|
|
836
897
|
|
|
837
|
-
def append_pip(flag, opts, target: @session
|
|
838
|
-
list = OPT_PIP.fetch(from, []) + OPT_PIP[:common]
|
|
839
|
-
if pip_install?(flag) || from == :install
|
|
840
|
-
list.concat(OPT_PIP[:install_a])
|
|
841
|
-
list.concat(OPT_PIP[:install_b]) unless flag == :index
|
|
842
|
-
case flag
|
|
843
|
-
when :install, :editable, :upgrade
|
|
844
|
-
list.concat(OPT_PIP[:install_c] + OPT_PIP[:debug])
|
|
845
|
-
when :lock, :wheel
|
|
846
|
-
list.concat(OPT_PIP[:install_c])
|
|
847
|
-
when :download, :index
|
|
848
|
-
list.concat(OPT_PIP[:debug])
|
|
849
|
-
end
|
|
850
|
-
opts << 'no-build-isolation' if option('build-isolation', equals: '0')
|
|
851
|
-
end
|
|
898
|
+
def append_pip(flag, opts, list, target: @session)
|
|
852
899
|
op = OptionPartition.new(opts, list, target, project: self, single: singleopt)
|
|
853
900
|
append_global(target: target)
|
|
854
901
|
case flag
|
|
@@ -869,7 +916,7 @@ module Squared
|
|
|
869
916
|
end
|
|
870
917
|
op.swap
|
|
871
918
|
if edit
|
|
872
|
-
edit = basepath(edit) unless %r{\A[a-z]+(
|
|
919
|
+
edit = basepath(edit) unless %r{\A[a-z]+(\+[a-z]+)?://}i.match?(edit)
|
|
873
920
|
if flag == :editable
|
|
874
921
|
op.push(edit)
|
|
875
922
|
else
|
|
@@ -900,18 +947,16 @@ module Squared
|
|
|
900
947
|
end
|
|
901
948
|
|
|
902
949
|
def append_global(target: @session)
|
|
903
|
-
target
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
option('python', target: target) { |val| quote_option('python', basepath(val)) }
|
|
914
|
-
])
|
|
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)
|
|
915
960
|
append_nocolor(target: target)
|
|
916
961
|
end
|
|
917
962
|
|
|
@@ -922,14 +967,18 @@ module Squared
|
|
|
922
967
|
def read_pyproject(table, key = nil)
|
|
923
968
|
return [] unless (file = pyprojectfile)
|
|
924
969
|
|
|
925
|
-
|
|
970
|
+
ret = (@pyproject ||= {})[table]
|
|
971
|
+
unless ret
|
|
926
972
|
ret = []
|
|
973
|
+
found = false
|
|
927
974
|
start = /^\s*\[#{Regexp.escape(table)}\]\s*$/
|
|
928
975
|
ch = nil
|
|
929
|
-
found = false
|
|
930
976
|
File.foreach(file) do |line|
|
|
977
|
+
next if line.start_with?(/\s*#/)
|
|
978
|
+
|
|
931
979
|
if found
|
|
932
|
-
|
|
980
|
+
line.chomp!($1) if line =~ /(?<=[\d"'{}\[\]]|true|false)(\s*#.*)$/
|
|
981
|
+
break if line.match?(/^\s*\[(?:[\w.\-" ]+|".+"|'.+')\]\s*$/)
|
|
933
982
|
|
|
934
983
|
if ch
|
|
935
984
|
val = line.rstrip
|
|
@@ -945,9 +994,9 @@ module Squared
|
|
|
945
994
|
end
|
|
946
995
|
end
|
|
947
996
|
ret.last[1] += val
|
|
948
|
-
elsif
|
|
949
|
-
if (val =
|
|
950
|
-
case (ch =
|
|
997
|
+
elsif line.strip =~ /^(\S+)\s*=\s*([+-]?[\d.]+|true|false|("""|'''|["'\[{])(.*))$/
|
|
998
|
+
if (val = $4)
|
|
999
|
+
case (ch = $3)
|
|
951
1000
|
when '{', '['
|
|
952
1001
|
val = "#{ch}#{val}"
|
|
953
1002
|
ch = ch == '{' ? '}' : ']'
|
|
@@ -960,7 +1009,7 @@ module Squared
|
|
|
960
1009
|
end
|
|
961
1010
|
end
|
|
962
1011
|
else
|
|
963
|
-
val = case (ch =
|
|
1012
|
+
val = case (ch = $2)
|
|
964
1013
|
when 'true'
|
|
965
1014
|
true
|
|
966
1015
|
when 'false'
|
|
@@ -969,7 +1018,10 @@ module Squared
|
|
|
969
1018
|
ch.include?('.') ? ch.to_f : ch.to_i
|
|
970
1019
|
end
|
|
971
1020
|
end
|
|
972
|
-
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
|
|
973
1025
|
end
|
|
974
1026
|
else
|
|
975
1027
|
found = line.match?(start)
|
|
@@ -977,9 +1029,7 @@ module Squared
|
|
|
977
1029
|
end
|
|
978
1030
|
@pyproject[table] = ret
|
|
979
1031
|
end
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
ret
|
|
1032
|
+
key ? ret.find { |val| val.first == key }&.last : ret
|
|
983
1033
|
end
|
|
984
1034
|
|
|
985
1035
|
def pyprojectfile
|
|
@@ -991,9 +1041,9 @@ module Squared
|
|
|
991
1041
|
case flag
|
|
992
1042
|
when :python
|
|
993
1043
|
/\A(?:v+|q+|b+|V+|O+)\z/
|
|
994
|
-
when :pdm
|
|
1044
|
+
when :pdm, :poetry
|
|
995
1045
|
/\Av+\z/
|
|
996
|
-
when :twine
|
|
1046
|
+
when :twine, :meson
|
|
997
1047
|
nil
|
|
998
1048
|
else
|
|
999
1049
|
/\A(?:v+|q+)\z/
|
|
@@ -1003,7 +1053,7 @@ module Squared
|
|
|
1003
1053
|
def preopts(quiet: true)
|
|
1004
1054
|
ret = []
|
|
1005
1055
|
case verbose
|
|
1006
|
-
when
|
|
1056
|
+
when false
|
|
1007
1057
|
ret << '--quiet' if quiet
|
|
1008
1058
|
when Numeric
|
|
1009
1059
|
ret << "-#{'v' * verbose}" if verbose > 0
|
|
@@ -1011,6 +1061,23 @@ module Squared
|
|
|
1011
1061
|
ret
|
|
1012
1062
|
end
|
|
1013
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
|
+
|
|
1014
1081
|
def variables
|
|
1015
1082
|
(super + %i[venv editable]).freeze
|
|
1016
1083
|
end
|
|
@@ -1039,11 +1106,16 @@ module Squared
|
|
|
1039
1106
|
end
|
|
1040
1107
|
|
|
1041
1108
|
def venv_set(val)
|
|
1109
|
+
@venv = nil
|
|
1042
1110
|
return unless val
|
|
1043
1111
|
|
|
1044
|
-
write = ->(level, hint) { log.add(level, "venv: #{@venv}".subhint(hint)) }
|
|
1112
|
+
write = ->(level, hint) { log.add(level, "#{virtualenv? ? 'virtualenv' : 'venv'}: #{@venv}".subhint(hint)) }
|
|
1045
1113
|
if val.is_a?(Array)
|
|
1046
1114
|
val, *opts = val
|
|
1115
|
+
if opts.first == 'virtualenv'
|
|
1116
|
+
@virtualenv = true
|
|
1117
|
+
opts.shift
|
|
1118
|
+
end
|
|
1047
1119
|
@venvopts = opts
|
|
1048
1120
|
end
|
|
1049
1121
|
@venv = basepath val
|
|
@@ -1063,25 +1135,35 @@ module Squared
|
|
|
1063
1135
|
def venv_init
|
|
1064
1136
|
return if !venv || (venvbin.directory? && !venvbin.empty?)
|
|
1065
1137
|
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
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?
|
|
1070
1143
|
end
|
|
1071
1144
|
|
|
1072
1145
|
def venv_create(dir, opts = [], env: nil, banner: banner?)
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
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/)
|
|
1078
1157
|
ret = run(op, env, exception: true, banner: banner)
|
|
1158
|
+
args = []
|
|
1159
|
+
requires = read_pyproject 'build-system', 'requires'
|
|
1160
|
+
args.concat(requires) if requires.is_a?(Array)
|
|
1079
1161
|
if poetry?
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
pip(:install, 'setuptools', 'wheel', banner: false)
|
|
1162
|
+
requires = read_pyproject 'tool.poetry', 'requires-poetry'
|
|
1163
|
+
args << "poetry#{requires}"
|
|
1083
1164
|
end
|
|
1084
|
-
|
|
1165
|
+
pip(:install, *args, banner: false) unless args.empty?
|
|
1166
|
+
success?(ret, banner, !status) { |ret| puts(ret && dir.directory? ? "Success: #{dir}" : 'Failed') }
|
|
1085
1167
|
end
|
|
1086
1168
|
|
|
1087
1169
|
def pip_install?(flag)
|
|
@@ -1098,6 +1180,8 @@ module Squared
|
|
|
1098
1180
|
build_backend == 'hatchling.build'
|
|
1099
1181
|
when :setuptools
|
|
1100
1182
|
build_backend == 'setuptools.build_meta'
|
|
1183
|
+
when :meson
|
|
1184
|
+
build_backend != 'mesonpy' && exist?('meson.build')
|
|
1101
1185
|
end
|
|
1102
1186
|
end
|
|
1103
1187
|
|
|
@@ -1113,6 +1197,10 @@ module Squared
|
|
|
1113
1197
|
dependtype == 1
|
|
1114
1198
|
end
|
|
1115
1199
|
|
|
1200
|
+
def virtualenv?
|
|
1201
|
+
@virtualenv ||= exist?('virtualenv.ini') || !ENV['VIRTUALENV_PYTHON'].nil?
|
|
1202
|
+
end
|
|
1203
|
+
|
|
1116
1204
|
def requirements?
|
|
1117
1205
|
dependtype == 5
|
|
1118
1206
|
end
|