squared 0.6.15 → 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 -131
- data/README.md +242 -205
- data/lib/squared/common/format.rb +7 -10
- data/lib/squared/common/prompt.rb +23 -24
- data/lib/squared/common/shell.rb +27 -35
- 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 +564 -472
- data/lib/squared/workspace/project/docker.rb +175 -167
- data/lib/squared/workspace/project/git.rb +213 -184
- data/lib/squared/workspace/project/node.rb +114 -143
- data/lib/squared/workspace/project/python.rb +248 -161
- data/lib/squared/workspace/project/ruby.rb +405 -294
- data/lib/squared/workspace/project/support/class.rb +13 -7
- data/lib/squared/workspace/project/support/optionpartition.rb +72 -57
- 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,28 +618,46 @@ 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
|
-
alias build_ build!
|
|
614
661
|
|
|
615
662
|
def publish(flag, opts = [], test: false)
|
|
616
663
|
list = case flag
|
|
@@ -656,12 +703,12 @@ module Squared
|
|
|
656
703
|
op.add_path
|
|
657
704
|
end
|
|
658
705
|
end
|
|
659
|
-
run(from:
|
|
706
|
+
run(from: symjoin(flag, 'publish'), interactive: ['Publish', 'N', project])
|
|
660
707
|
end
|
|
661
708
|
|
|
662
709
|
def python(*args, sync: true, banner: verbose?, with: nil, pass: PASS_PYTHON[:python], **kwargs)
|
|
663
710
|
op = OptionPartition.new(session_opts(with, args: args, kwargs: kwargs, pass: pass), OPT_PYTHON[:common],
|
|
664
|
-
session('python', path: venv
|
|
711
|
+
session('python', path: !venv?),
|
|
665
712
|
project: self, multiple: [/^-c/], single: singleopt(:python), args: true,
|
|
666
713
|
stdin: true)
|
|
667
714
|
op.concat(args)
|
|
@@ -677,7 +724,7 @@ module Squared
|
|
|
677
724
|
end
|
|
678
725
|
end
|
|
679
726
|
print_run(op, banner, **kwargs)
|
|
680
|
-
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)
|
|
681
728
|
end
|
|
682
729
|
|
|
683
730
|
def pip(flag, *args, sync: true, banner: verbose?, with: nil, pass: nil, **kwargs)
|
|
@@ -688,7 +735,7 @@ module Squared
|
|
|
688
735
|
when :freeze, :inspect, :list, :check, :completion, :debug
|
|
689
736
|
opts.concat(args)
|
|
690
737
|
end
|
|
691
|
-
op = append_pip(flag, opts,
|
|
738
|
+
op = append_pip(flag, opts, pipopts(flag), target: pip_session(flag))
|
|
692
739
|
case flag
|
|
693
740
|
when :install, :uninstall, :show, :index
|
|
694
741
|
op.concat(args)
|
|
@@ -711,9 +758,7 @@ module Squared
|
|
|
711
758
|
when :freeze
|
|
712
759
|
venv_init
|
|
713
760
|
op << '>'
|
|
714
|
-
|
|
715
|
-
op.remove(file) if file
|
|
716
|
-
op.add_quote(ret = basepath(file || DEP_PYTHON[4]))
|
|
761
|
+
op.add_quote(ret = basepath(op.detect { |val| op.exist?(val) } || DEP_PYTHON[4]))
|
|
717
762
|
.clear
|
|
718
763
|
when :cache
|
|
719
764
|
op.concat(args)
|
|
@@ -755,14 +800,24 @@ module Squared
|
|
|
755
800
|
op.clear
|
|
756
801
|
end
|
|
757
802
|
print_run(op, banner, **kwargs)
|
|
758
|
-
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))
|
|
759
804
|
.yield_self { |val| ret || val }
|
|
760
805
|
end
|
|
761
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
|
+
|
|
762
817
|
def variable_set(key, *args, **, &blk)
|
|
763
818
|
if block_given?
|
|
764
819
|
case key
|
|
765
|
-
when :dependfile, :
|
|
820
|
+
when :dependfile, :editable, :venv
|
|
766
821
|
args = block_args args, &blk
|
|
767
822
|
end
|
|
768
823
|
end
|
|
@@ -776,7 +831,7 @@ module Squared
|
|
|
776
831
|
@dependindex = index
|
|
777
832
|
@dependfile = val
|
|
778
833
|
else
|
|
779
|
-
log.warn "variable_set:
|
|
834
|
+
log.warn "variable_set: @dependfile=#{val}".subhint('not supported')
|
|
780
835
|
end
|
|
781
836
|
end
|
|
782
837
|
when :editable
|
|
@@ -796,60 +851,51 @@ module Squared
|
|
|
796
851
|
dependtype > 0 && !task_pass?('outdated')
|
|
797
852
|
end
|
|
798
853
|
|
|
854
|
+
def venv?
|
|
855
|
+
!venv.nil?
|
|
856
|
+
end
|
|
857
|
+
|
|
799
858
|
private
|
|
800
859
|
|
|
801
860
|
def pip_session(*cmd)
|
|
802
|
-
session('pip', *cmd, *preopts, path: venv
|
|
861
|
+
session('pip', *cmd, *preopts, path: !venv?)
|
|
803
862
|
end
|
|
804
863
|
|
|
805
864
|
def pip_output(*cmd)
|
|
806
|
-
session_output('pip', *cmd, *preopts, path: venv
|
|
865
|
+
session_output('pip', *cmd, *preopts, path: !venv?)
|
|
807
866
|
end
|
|
808
867
|
|
|
809
868
|
def python_session(*cmd, opts: nil)
|
|
810
|
-
|
|
811
|
-
return session('python', *pre, *cmd, path: venv.nil?) unless opts
|
|
812
|
-
|
|
813
|
-
op = OptionPartition.new(opts, OPT_PYTHON[:common], project: self, single: singleopt(:python))
|
|
814
|
-
[session('python', *pre, *op.to_a, *cmd, path: venv.nil?), op.extras]
|
|
815
|
-
end
|
|
816
|
-
|
|
817
|
-
def poetry_session(*cmd)
|
|
818
|
-
ret = session('poetry', *cmd, *preopts)
|
|
819
|
-
option('project', ignore: false) { |val| ret << quote_option('project', basepath(val)) }
|
|
820
|
-
ret
|
|
869
|
+
create_session('python', *cmd, common: OPT_PYTHON[:common], opts: opts, quiet: false)
|
|
821
870
|
end
|
|
822
871
|
|
|
823
872
|
def pdm_session(*cmd, opts: nil)
|
|
824
|
-
create_session(
|
|
873
|
+
create_session('pdm', *cmd, common: OPT_PDM[:common], opts: opts)
|
|
825
874
|
end
|
|
826
875
|
|
|
827
876
|
def hatch_session(*cmd, opts: nil)
|
|
828
|
-
|
|
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)
|
|
829
881
|
end
|
|
830
882
|
|
|
831
|
-
def
|
|
832
|
-
|
|
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
|
|
833
893
|
|
|
834
894
|
op = OptionPartition.new(opts, common, project: self, single: singleopt(name.to_sym))
|
|
835
|
-
[session(name, *
|
|
895
|
+
[session(name, *pre, *op.to_a, *cmd, path: !venv?), op.extras]
|
|
836
896
|
end
|
|
837
897
|
|
|
838
|
-
def append_pip(flag, opts, target: @session
|
|
839
|
-
list = OPT_PIP.fetch(from, []) + OPT_PIP[:common]
|
|
840
|
-
if pip_install?(flag) || from == :install
|
|
841
|
-
list.concat(OPT_PIP[:install_a])
|
|
842
|
-
list.concat(OPT_PIP[:install_b]) unless flag == :index
|
|
843
|
-
case flag
|
|
844
|
-
when :install, :editable, :upgrade
|
|
845
|
-
list.concat(OPT_PIP[:install_c] + OPT_PIP[:debug])
|
|
846
|
-
when :lock, :wheel
|
|
847
|
-
list.concat(OPT_PIP[:install_c])
|
|
848
|
-
when :download, :index
|
|
849
|
-
list.concat(OPT_PIP[:debug])
|
|
850
|
-
end
|
|
851
|
-
opts << 'no-build-isolation' if option('build-isolation', equals: '0')
|
|
852
|
-
end
|
|
898
|
+
def append_pip(flag, opts, list, target: @session)
|
|
853
899
|
op = OptionPartition.new(opts, list, target, project: self, single: singleopt)
|
|
854
900
|
append_global(target: target)
|
|
855
901
|
case flag
|
|
@@ -870,7 +916,7 @@ module Squared
|
|
|
870
916
|
end
|
|
871
917
|
op.swap
|
|
872
918
|
if edit
|
|
873
|
-
edit = basepath(edit) unless %r{\A[a-z]+(
|
|
919
|
+
edit = basepath(edit) unless %r{\A[a-z]+(\+[a-z]+)?://}i.match?(edit)
|
|
874
920
|
if flag == :editable
|
|
875
921
|
op.push(edit)
|
|
876
922
|
else
|
|
@@ -901,18 +947,16 @@ module Squared
|
|
|
901
947
|
end
|
|
902
948
|
|
|
903
949
|
def append_global(target: @session)
|
|
904
|
-
target
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
option('python', target: target) { |val| quote_option('python', basepath(val)) }
|
|
915
|
-
])
|
|
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)
|
|
916
960
|
append_nocolor(target: target)
|
|
917
961
|
end
|
|
918
962
|
|
|
@@ -923,14 +967,18 @@ module Squared
|
|
|
923
967
|
def read_pyproject(table, key = nil)
|
|
924
968
|
return [] unless (file = pyprojectfile)
|
|
925
969
|
|
|
926
|
-
|
|
970
|
+
ret = (@pyproject ||= {})[table]
|
|
971
|
+
unless ret
|
|
927
972
|
ret = []
|
|
973
|
+
found = false
|
|
928
974
|
start = /^\s*\[#{Regexp.escape(table)}\]\s*$/
|
|
929
975
|
ch = nil
|
|
930
|
-
found = false
|
|
931
976
|
File.foreach(file) do |line|
|
|
977
|
+
next if line.start_with?(/\s*#/)
|
|
978
|
+
|
|
932
979
|
if found
|
|
933
|
-
|
|
980
|
+
line.chomp!($1) if line =~ /(?<=[\d"'{}\[\]]|true|false)(\s*#.*)$/
|
|
981
|
+
break if line.match?(/^\s*\[(?:[\w.\-" ]+|".+"|'.+')\]\s*$/)
|
|
934
982
|
|
|
935
983
|
if ch
|
|
936
984
|
val = line.rstrip
|
|
@@ -946,9 +994,9 @@ module Squared
|
|
|
946
994
|
end
|
|
947
995
|
end
|
|
948
996
|
ret.last[1] += val
|
|
949
|
-
elsif
|
|
950
|
-
if (val =
|
|
951
|
-
case (ch =
|
|
997
|
+
elsif line.strip =~ /^(\S+)\s*=\s*([+-]?[\d.]+|true|false|("""|'''|["'\[{])(.*))$/
|
|
998
|
+
if (val = $4)
|
|
999
|
+
case (ch = $3)
|
|
952
1000
|
when '{', '['
|
|
953
1001
|
val = "#{ch}#{val}"
|
|
954
1002
|
ch = ch == '{' ? '}' : ']'
|
|
@@ -961,7 +1009,7 @@ module Squared
|
|
|
961
1009
|
end
|
|
962
1010
|
end
|
|
963
1011
|
else
|
|
964
|
-
val = case (ch =
|
|
1012
|
+
val = case (ch = $2)
|
|
965
1013
|
when 'true'
|
|
966
1014
|
true
|
|
967
1015
|
when 'false'
|
|
@@ -970,7 +1018,10 @@ module Squared
|
|
|
970
1018
|
ch.include?('.') ? ch.to_f : ch.to_i
|
|
971
1019
|
end
|
|
972
1020
|
end
|
|
973
|
-
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
|
|
974
1025
|
end
|
|
975
1026
|
else
|
|
976
1027
|
found = line.match?(start)
|
|
@@ -978,9 +1029,7 @@ module Squared
|
|
|
978
1029
|
end
|
|
979
1030
|
@pyproject[table] = ret
|
|
980
1031
|
end
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
ret
|
|
1032
|
+
key ? ret.find { |val| val.first == key }&.last : ret
|
|
984
1033
|
end
|
|
985
1034
|
|
|
986
1035
|
def pyprojectfile
|
|
@@ -992,9 +1041,9 @@ module Squared
|
|
|
992
1041
|
case flag
|
|
993
1042
|
when :python
|
|
994
1043
|
/\A(?:v+|q+|b+|V+|O+)\z/
|
|
995
|
-
when :pdm
|
|
1044
|
+
when :pdm, :poetry
|
|
996
1045
|
/\Av+\z/
|
|
997
|
-
when :twine
|
|
1046
|
+
when :twine, :meson
|
|
998
1047
|
nil
|
|
999
1048
|
else
|
|
1000
1049
|
/\A(?:v+|q+)\z/
|
|
@@ -1004,7 +1053,7 @@ module Squared
|
|
|
1004
1053
|
def preopts(quiet: true)
|
|
1005
1054
|
ret = []
|
|
1006
1055
|
case verbose
|
|
1007
|
-
when
|
|
1056
|
+
when false
|
|
1008
1057
|
ret << '--quiet' if quiet
|
|
1009
1058
|
when Numeric
|
|
1010
1059
|
ret << "-#{'v' * verbose}" if verbose > 0
|
|
@@ -1012,6 +1061,23 @@ module Squared
|
|
|
1012
1061
|
ret
|
|
1013
1062
|
end
|
|
1014
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
|
+
|
|
1015
1081
|
def variables
|
|
1016
1082
|
(super + %i[venv editable]).freeze
|
|
1017
1083
|
end
|
|
@@ -1040,11 +1106,16 @@ module Squared
|
|
|
1040
1106
|
end
|
|
1041
1107
|
|
|
1042
1108
|
def venv_set(val)
|
|
1109
|
+
@venv = nil
|
|
1043
1110
|
return unless val
|
|
1044
1111
|
|
|
1045
|
-
write = ->(level, hint) { log.add(level, "venv: #{@venv}".subhint(hint)) }
|
|
1112
|
+
write = ->(level, hint) { log.add(level, "#{virtualenv? ? 'virtualenv' : 'venv'}: #{@venv}".subhint(hint)) }
|
|
1046
1113
|
if val.is_a?(Array)
|
|
1047
1114
|
val, *opts = val
|
|
1115
|
+
if opts.first == 'virtualenv'
|
|
1116
|
+
@virtualenv = true
|
|
1117
|
+
opts.shift
|
|
1118
|
+
end
|
|
1048
1119
|
@venvopts = opts
|
|
1049
1120
|
end
|
|
1050
1121
|
@venv = basepath val
|
|
@@ -1064,25 +1135,35 @@ module Squared
|
|
|
1064
1135
|
def venv_init
|
|
1065
1136
|
return if !venv || (venvbin.directory? && !venvbin.empty?)
|
|
1066
1137
|
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
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?
|
|
1071
1143
|
end
|
|
1072
1144
|
|
|
1073
1145
|
def venv_create(dir, opts = [], env: nil, banner: banner?)
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
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/)
|
|
1079
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)
|
|
1080
1161
|
if poetry?
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
pip(:install, 'setuptools', 'wheel', banner: false)
|
|
1162
|
+
requires = read_pyproject 'tool.poetry', 'requires-poetry'
|
|
1163
|
+
args << "poetry#{requires}"
|
|
1084
1164
|
end
|
|
1085
|
-
|
|
1165
|
+
pip(:install, *args, banner: false) unless args.empty?
|
|
1166
|
+
success?(ret, banner, !status) { |ret| puts(ret && dir.directory? ? "Success: #{dir}" : 'Failed') }
|
|
1086
1167
|
end
|
|
1087
1168
|
|
|
1088
1169
|
def pip_install?(flag)
|
|
@@ -1099,6 +1180,8 @@ module Squared
|
|
|
1099
1180
|
build_backend == 'hatchling.build'
|
|
1100
1181
|
when :setuptools
|
|
1101
1182
|
build_backend == 'setuptools.build_meta'
|
|
1183
|
+
when :meson
|
|
1184
|
+
build_backend != 'mesonpy' && exist?('meson.build')
|
|
1102
1185
|
end
|
|
1103
1186
|
end
|
|
1104
1187
|
|
|
@@ -1114,6 +1197,10 @@ module Squared
|
|
|
1114
1197
|
dependtype == 1
|
|
1115
1198
|
end
|
|
1116
1199
|
|
|
1200
|
+
def virtualenv?
|
|
1201
|
+
@virtualenv ||= exist?('virtualenv.ini') || !ENV['VIRTUALENV_PYTHON'].nil?
|
|
1202
|
+
end
|
|
1203
|
+
|
|
1117
1204
|
def requirements?
|
|
1118
1205
|
dependtype == 5
|
|
1119
1206
|
end
|