squared 0.4.38 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,8 +7,8 @@ module Squared
7
7
  DEP_PYTHON = %w[poetry.lock setup.cfg pyproject.toml setup.py requirements.txt].freeze
8
8
  DIR_PYTHON = (DEP_PYTHON + %w[README.rst]).freeze
9
9
  OPT_PYTHON = {
10
- common: %w[b B d E h i I O P q s S u v x c=q m=b W=b X=q check-hash-based-pycs=b].freeze,
11
- build: %w[C=bm n|no-isolation s|sdist x|skip-dependency-check v|verbose w|wheel config-setting=q installer=b
10
+ common: %w[b B d E h i I O OO P q s S u v x c=q m=b W=b X=q check-hash-based-pycs=b].freeze,
11
+ build: %w[n|no-isolation s|sdist v|verbose w|wheel x|skip-dependency-check C|config-setting=q installer=b
12
12
  o|outdir=p].freeze,
13
13
  venv: %w[clear copies symlinks system-site-packages upgrade upgrade-deps without-scm-ignore-files without-pip
14
14
  prompt=q].freeze
@@ -28,17 +28,10 @@ module Squared
28
28
  freeze: %w[all exclude-editable l|local user exclude=b path=p r|requirement=p].freeze
29
29
  }.freeze
30
30
  OPT_POETRY = {
31
- common: %w[ansi no-ansi no-cache n|no-interaction no-plugins q|quiet v|verbose P|project=p].freeze,
31
+ common: %w[ansi no-ansi no-cache n|no-interaction no-plugins P|project=p q|quiet v|verbose].freeze,
32
32
  build: %w[clean config-settings=qq f|format=b o|output=p].freeze,
33
- publish: %w[build dry-run skip-existing cert=p client-cert=p dist-dir=p p|password=q r|repository=b
34
- u|username=qq].freeze
35
- }.freeze
36
- OPT_PDM = {
37
- common: %w[I|ignore-python no-cache n|non-interactive].freeze,
38
- build: %w[C=bm no-clean no-isolation no-sdist no-wheel quiet verbose config-setting=q d|dest=p p|project=p
39
- k|skip=b].freeze,
40
- publish: %w[no-build no-very-ssl quiet S|sign skip-existing verbose ca-certs=p c|comment=q d|dest=p
41
- i|identity=b P|password=q p|project=p r|repository=q k|skip=b u|username=qq].freeze
33
+ publish: %w[build dry-run client-cert=p cert=p dist-dir=p p|password=b r|repository=b skip-existing
34
+ u|username=b].freeze
42
35
  }.freeze
43
36
  OPT_HATCH = {
44
37
  common: %w[color interactive no-color no-interactive cache-dir=p config=p data-dir=p e|env=b p|project=b
@@ -48,11 +41,11 @@ module Squared
48
41
  p|publisher=b r|repo=b u|user=q].freeze
49
42
  }.freeze
50
43
  OPT_TWINE = {
51
- publish: %w[attestations disable-progress-bar non-interactive s|sign skip-existing verbose cert=p
52
- client-cert=p c|comment=q config-file=p i|identity=b p|password=q r|repository=b repository-url=q
53
- sign-with=b u|username=qq].freeze
44
+ publish: %w[attestations disable-progress-bar non-interactive skip-existing verbose s|sign c|comment=q
45
+ config-file=p cert=p client-cert=p i|identity=b p|password=q r|repository=b repository-url=q
46
+ sign-with=b u|username=q].freeze
54
47
  }.freeze
55
- private_constant :DEP_PYTHON, :DIR_PYTHON, :OPT_PYTHON, :OPT_PIP, :OPT_POETRY, :OPT_PDM, :OPT_HATCH, :OPT_TWINE
48
+ private_constant :DEP_PYTHON, :DIR_PYTHON, :OPT_PYTHON, :OPT_PIP, :OPT_POETRY, :OPT_HATCH, :OPT_TWINE
56
49
 
57
50
  class << self
58
51
  def populate(*); end
@@ -78,7 +71,7 @@ module Squared
78
71
 
79
72
  attr_reader :venv, :editable
80
73
 
81
- def initialize(*, editable: '.', **kwargs)
74
+ def initialize(*, venv: nil, editable: '.', verbose: nil, **kwargs)
82
75
  super
83
76
  if @pass.include?(Python.ref)
84
77
  initialize_ref Python.ref
@@ -87,101 +80,35 @@ module Squared
87
80
  initialize_build(Python.ref, **kwargs)
88
81
  initialize_env(**kwargs)
89
82
  end
90
- dependfile_set(DEP_PYTHON, default: 2)
83
+ dependfile_set DEP_PYTHON
84
+ @verbose = verbose.size if verbose.is_a?(String) && verbose.match?(/\Av+\z/)
91
85
  editable_set editable
92
- venv_set kwargs[:venv]
86
+ venv_set venv if venv
93
87
  end
94
88
 
95
89
  subtasks({
96
90
  'venv' => %i[exec create remove show].freeze,
97
- 'pip' => %i[upgrade uninstall freeze].freeze,
91
+ 'pip' => %i[uninstall freeze].freeze,
98
92
  'install' => %i[user force upgrade target editable].freeze,
99
- 'outdated' => %i[major minor patch].freeze,
100
- 'build' => %i[python poetry pdm hatch].freeze,
101
- 'publish' => %i[poetry pdm hatch twine].freeze,
102
- 'run' => nil,
93
+ 'build' => %i[python poetry hatch].freeze,
94
+ 'publish' => %i[poetry twine hatch].freeze,
103
95
  'exec' => nil
104
96
  })
105
97
 
106
- def verbose=(val)
107
- case val
108
- when /\Av+\z/
109
- @verbose = val.size
110
- else
111
- super
112
- end
113
- end
114
-
115
98
  def ref
116
99
  Python.ref
117
100
  end
118
101
 
119
102
  def populate(*, **)
120
103
  super
121
- return unless (outdated? && ref?(Python.ref)) || @only
104
+ return unless outdated? && ref?(Python.ref)
122
105
 
123
106
  namespace name do
124
107
  Python.subtasks do |action, flags|
125
- next if task_pass?(action)
108
+ next if @pass.include?(action)
126
109
 
127
110
  if flags.nil?
128
111
  case action
129
- when 'run'
130
- next unless pyprojectfile
131
-
132
- format_desc action, nil, "script+|#{indexchar}index+|#,pattern*"
133
- task action, [:command] do |_, args|
134
- found = 0
135
- %w[tool.poetry.scripts tool.pdm.scripts project.scripts].each_with_index do |table, index|
136
- next if (list = read_pyproject(table)).empty?
137
-
138
- if args.command == '#'
139
- format_list(list, "run[#{indexchar}N]", 'scripts', grep: args.extras, from: pyprojectfile)
140
- found |= 1
141
- else
142
- args.to_a.each do |val|
143
- if (n, = indexitem(val))
144
- if (script, = list[n - 1])
145
- case index
146
- when 0
147
- script = session_output 'poetry', 'run', script
148
- when 1
149
- script = pdm_session 'run', script
150
- else
151
- venv_init
152
- end
153
- found |= 1
154
- run(script, from: :run)
155
- elsif exception
156
- indexerror n, list
157
- else
158
- found |= 2
159
- log.warn "run script #{n} of #{list.size} (out of range)"
160
- end
161
- else
162
- case index
163
- when 0
164
- found |= 1
165
- run(session_output('poetry', 'run', val), from: :run)
166
- when 1
167
- found |= 1
168
- run(pdm_session('run', val), from: :run)
169
- else
170
- raise_error "script: #{val}" if exception
171
- found |= 2
172
- log.warn "run script \"#{val}\" (not indexed)"
173
- end
174
- end
175
- end
176
- end
177
- break
178
- end
179
- next if found.anybits?(1)
180
-
181
- puts log_message(found == 0 ? Logger::INFO : Logger::WARN,
182
- "no scripts #{found == 0 ? 'found' : 'executed'}",
183
- subject: name, hint: pyprojectfile)
184
- end
185
112
  when 'exec'
186
113
  format_desc action, nil, 'command|:,args*'
187
114
  task action do |_, args|
@@ -191,12 +118,12 @@ module Squared
191
118
  elsif i || args.empty?
192
119
  readline('Enter command', force: true)
193
120
  else
194
- if (val = command_args(args, min: 1, prefix: 'python'))
121
+ if (val = command_args(args, prefix: 'python'))
195
122
  args << val
196
123
  end
197
124
  args.join(' ')
198
125
  end
199
- run(cmd, send: :exec, banner: false)
126
+ Kernel.exec(cmd, chdir: path)
200
127
  end
201
128
  end
202
129
  else
@@ -207,7 +134,7 @@ module Squared
207
134
  if flag == :create
208
135
  format_desc action, flag, 'dir,opts*'
209
136
  task flag, [:dir] do |_, args|
210
- dir = basepath param_guard(action, flag, args: args, key: :dir)
137
+ dir = path + param_guard(action, flag, args: args, key: :dir)
211
138
  venv_create dir, args.extras
212
139
  end
213
140
  elsif venv
@@ -228,7 +155,7 @@ module Squared
228
155
  if args.empty?
229
156
  args = readline('Enter command', force: true).split(' ', 2)
230
157
  elsif args.size == 1 && !option('interactive', prefix: 'venv', equals: '0')
231
- args << readline('Enter arguments', force: false) unless args.first.include?(' ')
158
+ args << readline('Enter arguments', force: false)
232
159
  end
233
160
  venv_init
234
161
  run args.join(' ')
@@ -242,11 +169,6 @@ module Squared
242
169
  end
243
170
  when 'pip'
244
171
  case flag
245
- when :upgrade
246
- format_desc action, flag, 'opts*'
247
- task flag do |_, args|
248
- install flag, ['upgrade', *args.to_a, 'pip']
249
- end
250
172
  when :freeze
251
173
  format_desc action, flag, "file?=#{DEP_PYTHON[4]},opts*"
252
174
  task flag do |_, args|
@@ -292,30 +214,14 @@ module Squared
292
214
  depend flag, args.to_a
293
215
  end
294
216
  end
295
- when 'outdated'
296
- format_desc action, flag, 'eager?,user?'
297
- task flag do |_, args|
298
- outdated flag, args.to_a
299
- end
300
217
  when 'build'
301
- case flag
302
- when :poetry
303
- next unless build_backend == 'poetry.core.masonry.api'
304
- when :pdm
305
- next unless build_backend == 'pdm.backend'
306
- when :hatch
307
- next unless build_backend == 'hatchling.build'
308
- end
309
218
  format_desc(action, flag, 'opts*', after: case flag
310
- when :poetry then 'output?'
311
- when :pdm then 'dest?'
219
+ when :python then 'srcdir?'
312
220
  when :hatch then 'location?'
313
- else 'outdir?'
314
221
  end)
315
222
  task flag do |_, args|
316
223
  build! flag, args.to_a
317
224
  end
318
- break unless flag == :python
319
225
  when 'publish'
320
226
  format_desc(action, flag, 'opts*', after: case flag
321
227
  when :hatch then 'artifacts?'
@@ -338,18 +244,17 @@ module Squared
338
244
  elsif outdated?
339
245
  venv_init
340
246
  workspace.rev_clear(name, sync: sync)
341
- if !flag && poetry?
342
- cmd = poetry_session 'install -n'
247
+ if !flag && dependtype == 1
248
+ cmd = poetry_session 'install', '-n'
343
249
  cmd << '--no-root' if option('no-root')
344
250
  else
345
251
  cmd = pip_session 'install'
346
- cmd << '--upgrade-strategy=eager' if env('PYTHON_UPDATE')
347
252
  if flag
348
253
  case flag
349
254
  when :user
350
255
  cmd << '--user'
351
256
  when :target
352
- cmd << quote_option('target', basepath(target))
257
+ cmd << quote_option('target', path + target)
353
258
  when :force
354
259
  cmd << '--force-reinstall'
355
260
  end
@@ -364,8 +269,8 @@ module Squared
364
269
  end
365
270
  end
366
271
 
367
- def outdated(flag = nil, opts = [], sync: invoked_sync?('outdated', flag))
368
- cmd = pip_session 'list --outdated'
272
+ def outdated(*, sync: invoked_sync?('outdated'))
273
+ cmd = pip_session 'list', '--outdated'
369
274
  append_global
370
275
  cmd = session_done cmd
371
276
  log.info cmd
@@ -374,39 +279,28 @@ module Squared
374
279
  print_item banner if sync
375
280
  start = 0
376
281
  found = 0
377
- major = []
378
- minor = []
379
- patch = []
282
+ major = 0
380
283
  pwd_set(from: :outdated) do
381
284
  buffer = []
382
285
  out = ->(val) { sync ? puts(val) : buffer << val }
383
- if workspace.windows?
384
- (venv ? command(runenv, cmd) : `#{cmd}`).lines
385
- else
386
- IO.popen(runenv || {}, cmd)
387
- end.each do |line|
388
- next if line.match?(/^[ -]+$/)
286
+ IO.popen(runenv || {}, cmd).each do |line|
287
+ next if line.match?(/^[\s-]+$/)
389
288
 
390
289
  if start > 0
391
290
  unless stdin?
392
- cur, lat = line.scan(SEM_VER)
393
- next unless cur && lat
291
+ data = line.scan(SEM_VER)
292
+ next unless (cur = data.shift) && (lat = data.shift)
394
293
 
395
294
  latest = lat.join
396
295
  current = cur.join
397
296
  semver cur
398
297
  semver lat
399
- name = line.split(' ', 2).first
400
- type = if semmajor?(cur, lat)
401
- major << name
402
- 2
403
- elsif cur[2] == lat[2]
404
- patch << name
405
- 0
406
- else
407
- minor << name
408
- 1
409
- end
298
+ if semmajor?(cur, lat)
299
+ type = 2
300
+ major += 1
301
+ else
302
+ type = cur[2] == lat[2] ? 0 : 1
303
+ end
410
304
  if type == 0
411
305
  styles = color(:yellow)
412
306
  else
@@ -440,18 +334,7 @@ module Squared
440
334
  puts buffer
441
335
  end
442
336
  if found > 0
443
- print_status(major.size, minor.size, patch.size, from: :outdated)
444
- pkg = case flag
445
- when :major
446
- major + minor + patch
447
- when :minor
448
- minor + patch
449
- when :patch
450
- patch
451
- end
452
- unless !pkg || pkg.empty?
453
- install(:upgrade, pkg, strategy: opts.include?('eager') ? 'eager' : nil, user: opts.include?('user'))
454
- end
337
+ puts print_footer empty_status('Updates are available', 'major', major)
455
338
  elsif start == 0
456
339
  puts 'No updates were found'
457
340
  end
@@ -459,7 +342,7 @@ module Squared
459
342
  on :last, :outdated
460
343
  end
461
344
 
462
- def install(flag, opts = [], strategy: nil, user: nil)
345
+ def install(flag, opts = [], strategy: nil)
463
346
  cmd = pip_session 'install'
464
347
  out = append_pip(flag, opts, from: :install)
465
348
  case flag
@@ -469,89 +352,77 @@ module Squared
469
352
  when :upgrade
470
353
  raise_error('no packages listed', hint: flag) if out.empty?
471
354
  cmd << '--upgrade'
472
- cmd << '--user' if user
473
355
  cmd << basic_option('upgrade-strategy', strategy) if strategy
474
356
  append_value out
475
- python_session('-m pip', *cmd.to_a.drop(1)) if workspace.windows?
476
357
  end
477
358
  run(from: :install)
478
359
  end
479
360
 
480
361
  def build!(flag, opts = [])
481
362
  case flag
363
+ when :python
364
+ cmd, opts = python_session('-m build', opts: opts)
365
+ list = OPT_PYTHON[:build]
482
366
  when :poetry
483
367
  cmd = poetry_session 'build'
484
368
  list = OPT_POETRY[:build] + OPT_POETRY[:common]
485
- when :pdm
486
- cmd, opts = pdm_session('build', opts: opts)
487
- list = OPT_PDM[:build]
488
369
  when :hatch
489
370
  cmd, opts = hatch_session('build', opts: opts)
490
371
  list = OPT_HATCH[:build]
491
- else
492
- cmd, opts = python_session('-m build', opts: opts)
493
- list = OPT_PYTHON[:build]
494
372
  end
373
+ srcdir = nil
495
374
  op = OptionPartition.new(opts, list, cmd, project: self, single: singleopt(flag))
375
+ op.each do |opt|
376
+ if !srcdir && basepath(opt).exist? && projectpath?(opt)
377
+ srcdir = opt
378
+ else
379
+ op.found << opt
380
+ end
381
+ end
382
+ op.swap
496
383
  case flag
497
- when :hatch
498
- if !ENV['HATCH_BUILD_LOCATION'] && (outdir ||= op.shift)
499
- op.add_path(outdir)
384
+ when :poetry
385
+ if srcdir
386
+ if op.arg?('o', 'output')
387
+ op.extras << srcdir
388
+ else
389
+ op << quote_option('output', path + srcdir)
390
+ end
391
+ srcdir = nil
500
392
  end
501
- else
502
- unless op.empty?
503
- args = case flag
504
- when :poetry
505
- %w[o output]
506
- when :pdm
507
- %w[d dest]
508
- else
509
- srcdir = true
510
- %w[o outdir]
511
- end
512
- op << quote_option(args.last, basepath(op.shift)) unless op.arg?(*args)
393
+ when :hatch
394
+ if ENV['HATCH_BUILD_LOCATION']
395
+ srcdir = nil
396
+ else
397
+ srcdir ||= path
513
398
  end
399
+ op << basic_option('p', project) unless ENV['HATCH_PROJECT'] || op.arg?('p', 'project')
514
400
  end
515
- op.exist?(add: true, first: true) if srcdir
401
+ op << shell_quote(path + srcdir) if srcdir
516
402
  op.clear
517
403
  run(from: :"#{flag}:build")
518
404
  end
519
- alias build_ build!
520
405
 
521
406
  def publish(flag, opts = [])
522
407
  case flag
523
408
  when :poetry
524
409
  poetry_session 'publish'
525
410
  list = OPT_POETRY[:publish] + OPT_POETRY[:common]
526
- when :pdm
527
- opts = pdm_session('publish', opts: opts).last
528
- list = OPT_PDM[:publish]
529
- when :hatch
530
- opts = hatch_session('publish', opts: opts).last
531
- list = OPT_HATCH[:publish]
532
411
  when :twine
533
412
  session 'twine', 'upload'
534
413
  list = OPT_TWINE[:publish]
414
+ when :hatch
415
+ opts = hatch_session('publish', opts: opts).last
416
+ list = OPT_HATCH[:publish]
535
417
  end
536
418
  op = OptionPartition.new(opts, list, @session, project: self, single: singleopt(flag))
537
- dist = lambda do
538
- basepath('dist').tap do |dir|
539
- raise_error('no source files found', hint: dir) unless dir.directory? && !dir.empty?
540
- end
419
+ if op.empty?
420
+ dist = path + 'dist'
421
+ raise_error('no source files found', hint: dist) unless dist.directory? && !dist.empty?
422
+ op.extras << "#{dist}/*" unless flag == :poetry
541
423
  end
542
- case flag
543
- when :hatch, :twine
544
- if op.empty?
545
- op.push("#{dist.call}/*")
546
- else
547
- op.map! { |val| basepath(val) }
548
- end
549
- op.append
550
- else
551
- dist.call unless op.arg?(*(flag == :poetry ? ['dist-dir'] : ['d', 'dest']))
552
- op.clear(pass: false)
553
- end
554
- run(from: :"#{flag}:publish", interactive: "Publish #{sub_style(project, styles: theme[:active])}")
424
+ op.append
425
+ run(from: :"#{flag}:publish")
555
426
  end
556
427
 
557
428
  def pip(flag, opts = [])
@@ -559,7 +430,7 @@ module Squared
559
430
  out = append_pip(nil, opts, from: flag)
560
431
  case flag
561
432
  when :uninstall
562
- raise_error('no packages listed', hint: flag) if out.empty?
433
+ raise_error('no packages listed', hint: 'uninstall') if out.empty?
563
434
  cmd.merge(out)
564
435
  when :freeze
565
436
  venv_init
@@ -571,24 +442,26 @@ module Squared
571
442
  ret
572
443
  end
573
444
 
574
- def variable_set(key, *val, **)
445
+ def variable_set(key, *val, **, &blk)
446
+ if block_given?
447
+ case key
448
+ when :dependfile, :venv, :editable
449
+ val = block_args val, &blk
450
+ end
451
+ end
575
452
  case key
576
453
  when :dependfile
577
- if val.first.nil?
578
- super
454
+ req = basepath(*val)
455
+ if (index = DEP_PYTHON.index(req.basename.to_s))
456
+ @dependindex = index
457
+ @dependfile = req
579
458
  else
580
- req = basepath(*val)
581
- if (index = DEP_PYTHON.index(req.basename.to_s))
582
- @dependindex = index
583
- @dependfile = req
584
- else
585
- log.warn "variable_set: @#{key}=#{req} (not supported)"
586
- end
459
+ log.warn "variable_set: @#{key}=#{req} (not supported)"
587
460
  end
588
461
  when :editable
589
462
  editable_set val.first
590
463
  when :venv
591
- @venv = val.empty? || val.first.nil? ? nil : basepath(*val)
464
+ instance_variable_set(:"@#{key}", val.empty? ? nil : basepath(*val))
592
465
  else
593
466
  super
594
467
  end
@@ -599,7 +472,7 @@ module Squared
599
472
  end
600
473
 
601
474
  def outdated?
602
- dependtype > 0 && !task_pass?('outdated')
475
+ dependtype > 0
603
476
  end
604
477
 
605
478
  private
@@ -609,40 +482,29 @@ module Squared
609
482
  end
610
483
 
611
484
  def python_session(*cmd, opts: nil)
612
- pre = preopts(quiet: false)
613
- return session('python', *pre, *cmd, path: venv.nil?) unless opts
485
+ return session('python', *preopts(quiet: false), *cmd, path: venv.nil?) unless opts
614
486
 
615
- op = OptionPartition.new(opts, OPT_PYTHON[:common], project: self, single: singleopt(:python))
616
- ret = session('python', *pre, *op.to_a, *cmd, path: venv.nil?)
487
+ op = OptionPartition.new(opts, OPT_PYTHON[:common], project: self, single: /\Av+\z/)
488
+ ret = session('python', *op.to_a, *cmd, path: venv.nil?)
617
489
  [ret, op.extras]
618
490
  end
619
491
 
620
492
  def poetry_session(*cmd)
621
493
  ret = session('poetry', *cmd, *preopts)
622
- if (val = option('project', ignore: false))
623
- ret << quote_option('project', basepath(val))
624
- end
494
+ option('project', ignore: false) { |val| ret << quote_option('project', path + val) }
625
495
  ret
626
496
  end
627
497
 
628
- def pdm_session(*cmd, opts: nil)
629
- create_session(*cmd, name: 'pdm', common: OPT_PDM[:common], opts: opts)
630
- end
631
-
632
498
  def hatch_session(*cmd, opts: nil)
633
- create_session(*cmd, name: 'hatch', common: OPT_HATCH[:common], opts: opts)
634
- end
635
-
636
- def create_session(*cmd, name:, common:, opts: nil)
637
- return session(name, *preopts, *cmd, path: venv.nil?) unless opts
499
+ return session('hatch', *preopts, *cmd, path: venv.nil?) unless opts
638
500
 
639
- op = OptionPartition.new(opts, common, project: self, single: singleopt(name.to_sym))
640
- ret = session(name, *preopts, *op.to_a, *cmd, path: venv.nil?)
501
+ op = OptionPartition.new(opts, OPT_HATCH[:common], project: self, single: singleopt)
502
+ ret = session('hatch', *op.to_a, *cmd, path: venv.nil?)
641
503
  [ret, op.extras]
642
504
  end
643
505
 
644
506
  def append_pip(flag, opts, target: @session, from: nil)
645
- unless from && !opts.empty?
507
+ if !from || opts.empty?
646
508
  append_global(target: target)
647
509
  return []
648
510
  end
@@ -665,11 +527,11 @@ module Squared
665
527
  end
666
528
  op.swap
667
529
  if edit
668
- edit = basepath(edit) unless %r{\A[a-z]+(?:\+[a-z]+)?://}i.match?(edit)
530
+ edit = path + edit unless %r{^[a-z]+(?:\+[a-z]+)?://}i.match?(edit)
669
531
  if flag == :editable
670
- op.push(edit)
532
+ op.extras << edit
671
533
  else
672
- op << quote_option('e', edit)
534
+ target << quote_option('e', edit)
673
535
  end
674
536
  end
675
537
  case flag
@@ -680,120 +542,54 @@ module Squared
680
542
  []
681
543
  end
682
544
  else
683
- op.extras
545
+ opts
684
546
  end
685
547
  end
686
548
 
687
549
  def append_editable(target: @session)
688
- return if requirements? && editable == '.'
550
+ return if requirements?
689
551
 
690
552
  if (val = option('editable', 'e', target: target, ignore: false))
691
- OptionPartition.delete_key(target, 'e', 'editable')
553
+ session_delete('e', 'editable', target: target)
692
554
  case val
693
555
  when '0', 'false'
694
- return unless installable?
556
+ return
695
557
  else
696
- val = basepath val
558
+ val = path + val
697
559
  end
698
- elsif session_arg?('e', 'editable', target: target) || !installable?
560
+ elsif session_arg?('e', 'editable', target: target) || !(val = editable)
699
561
  return
700
- else
701
- val = editable
702
562
  end
703
- target << (val ? quote_option('e', basepath(val)) : '.')
563
+ target << quote_option('e', val)
704
564
  end
705
565
 
706
566
  def append_global(target: @session)
707
- if (val = option('cache-dir', target: target))
567
+ option('cache-dir', target: target) do |val|
708
568
  target << case val
709
569
  when '0', 'false'
710
570
  '--no-cache-dir'
711
571
  else
712
- quote_option('cache-dir', basepath(val))
572
+ quote_option('cache-dir', path + val)
713
573
  end
714
574
  end
715
- target << quote_option('proxy', val) if (val = option('proxy', target: target))
716
- target << quote_option('python', basepath(val)) if (val = option('python', target: target))
575
+ option('proxy', target: target) { |val| target << shell_option('proxy', val) }
576
+ option('python', target: target) { |val| target << quote_option('python', path + val) }
717
577
  append_nocolor(target: target)
718
578
  end
719
579
 
720
- def build_backend
721
- @build_backend ||= read_pyproject('build-system', 'build-backend') || ''
722
- end
723
-
724
- def read_pyproject(table, key = nil)
725
- return [] unless (file = pyprojectfile)
726
-
727
- unless (ret = (@pyproject ||= {})[table])
728
- ret = []
729
- start = /^\s*\[#{Regexp.escape(table)}\]\s*$/
730
- ch = nil
731
- found = false
732
- File.foreach(file) do |line|
733
- if found
734
- break if line.match?(/^\s*\[[\w.-]+\]\s*$/)
735
-
736
- if ch
737
- val = line.rstrip
738
- case ch
739
- when '}', ']'
740
- ch = nil if val.end_with?(ch)
741
- val = "\n#{val}"
742
- else
743
- if val.chomp!(ch)
744
- ch = nil
745
- else
746
- val = line
747
- end
748
- end
749
- ret.last[1] += val
750
- elsif (data = line.match(/^\s*(\S+)\s*=\s*([+-]?[\d.]+|true|false|("""|'''|["'\[{])(.*?))\s*$/))
751
- if (val = data[4])
752
- case (ch = data[3])
753
- when '{', '['
754
- val = "#{ch}#{val}"
755
- ch = ch == '{' ? '}' : ']'
756
- ch = nil if val.end_with?(ch)
757
- else
758
- if val.chomp!(ch)
759
- ch = nil
760
- elsif ch.size == 1
761
- next
580
+ def editable_set(val)
581
+ @editable = case val
582
+ when '.', Pathname
583
+ val
584
+ when String
585
+ Pathname.new(editable)
762
586
  end
763
- end
764
- else
765
- val = case (val = data[2])
766
- when 'true'
767
- true
768
- when 'false'
769
- false
770
- else
771
- val.include?('.') ? val.to_f : val.to_i
772
- end
773
- end
774
- ret << [data[1], val]
775
- end
776
- else
777
- found = line.match?(start)
778
- end
779
- end
780
- @pyproject[table] = ret
781
- end
782
- return ret.find { |val| val.first == key }&.last if key
783
-
784
- ret
785
- end
786
-
787
- def pyprojectfile
788
- return unless (ret = basepath(DEP_PYTHON[2])).exist?
789
-
790
- ret
791
587
  end
792
588
 
793
589
  def singleopt(flag = nil)
794
590
  case flag
795
591
  when :python
796
- /\A(?:v+|q+|b+|V+|O+)\z/
592
+ /\A(?:v+|q+|b+)\z/
797
593
  when :twine
798
594
  nil
799
595
  else
@@ -830,23 +626,13 @@ module Squared
830
626
  @venv&.join(workspace.windows? ? 'Scripts' : 'bin')
831
627
  end
832
628
 
833
- def editable_set(val)
834
- @editable = case val
835
- when '.', Pathname
836
- val
837
- when String
838
- Pathname.new(val) unless val.empty?
839
- end
840
- end
841
-
842
629
  def venv_set(val)
843
- return unless val
844
-
845
630
  if val.is_a?(Array)
846
631
  val, *opts = val
847
632
  @venvopts = opts
848
633
  end
849
- @venv = basepath(val)
634
+ @venv = Pathname.new(val)
635
+ @venv = @path + @venv unless @venv.absolute?
850
636
  if projectpath?(@venv)
851
637
  if @venv.exist?
852
638
  log.debug "venv found: #{@venv}"
@@ -864,8 +650,8 @@ module Squared
864
650
  return if !venv || (venvbin.directory? && !venvbin.empty?)
865
651
 
866
652
  puts log_message(Logger::INFO, venv, subject: 'venv', hint: 'init')
867
- opts = @venvopts&.map { |val| OptionPartition.strip(val) }&.flatten
868
- venv_create(venv, opts || ["prompt=#{name}", 'upgrade-deps'], env: false, banner: false)
653
+ @venvopts &&= @venvopts.map { |val| OptionPartition.strip(val) }.flatten
654
+ venv_create(venv, @venvopts || ["prompt=#{name}", 'upgrade-deps'], env: false, banner: false)
869
655
  puts log_message(Logger::INFO, venv, subject: 'venv', hint: 'created')
870
656
  end
871
657
 
@@ -874,28 +660,11 @@ module Squared
874
660
  op = OptionPartition.new(opts, OPT_PYTHON[:venv], cmd, project: self)
875
661
  op.append(dir, delim: true)
876
662
  .clear(pass: false)
877
- status = op.arg?(/\A-v+\z/)
663
+ status = op.arg?(/\A-v+\z/, 'verbose')
878
664
  run(op, env, exception: true, banner: banner)
879
- if poetry?
880
- install(:upgrade, ['poetry'])
881
- elsif setuptools?
882
- install(:upgrade, ['setuptools', 'wheel'])
883
- end
884
665
  puts(dir.directory? ? "Success: #{dir}" : 'Failed') if banner && !status
885
666
  end
886
667
 
887
- def installable?
888
- setuptools? || !!pyprojectfile
889
- end
890
-
891
- def setuptools?
892
- dependtype == 2 || dependtype == 4
893
- end
894
-
895
- def poetry?
896
- dependtype == 1
897
- end
898
-
899
668
  def requirements?
900
669
  dependtype == 5
901
670
  end