squared 0.8.7 → 0.9.0.pre1

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.
@@ -4,27 +4,25 @@ module Squared
4
4
  module Workspace
5
5
  module Project
6
6
  class Python < Git
7
- DEP_PYTHON = %w[poetry.lock setup.cfg pyproject.toml setup.py requirements.txt].freeze
7
+ DEP_PYTHON = %w[poetry.lock pdm.lock pylock.toml setup.cfg pyproject.toml setup.py requirements.txt].freeze
8
8
  DIR_PYTHON = (DEP_PYTHON + %w[meson.build README.rst]).freeze
9
9
  OPT_PYTHON = {
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
11
- check-hash-based-pycs={always,default,never}].freeze,
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,
12
11
  build: %w[C=bm n|no-isolation s|sdist x|skip-dependency-check v|verbose w|wheel config-json=q config-setting=q
13
12
  installer=b o|outdir=p].freeze,
14
13
  venv: %w[clear copies symlinks system-site-packages upgrade upgrade-deps without-scm-ignore-files without-pip
15
14
  prompt=q].freeze,
16
15
  virtualenv: %w[always-copy clear copies download never-download no-download no-periodic-update no-pip no-seed
17
- no-setuptools no-vcs-ignore no-venv-redirect q|quiet read-only-app-data reset-app-data
18
- symlink-app-data symlinks system-site-packages with-traceback without-pip upgrade-embed-wheels
19
- venv-redirect v|verbose=+ activators={bash,batch,cshell,fish,nushell,powershell,python,xonsh}
20
- app-data=p creator=b discovery={builtin} extra-search-dir=p pip=b prompt=q p|python=q
21
- seeder={app-data,pip} setuptools=b try-first-with=q].freeze
16
+ no-setuptools no-vcs-ignore q|quiet 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
22
20
  }.freeze
23
21
  OPT_PIP = {
24
- common: %w[debug disable-pip-version-check isolated no-cache-dir no-color no-input no-proxy-env
25
- require-virtualenv q|quiet=+ v|verbose=+ cache-dir=p cert=p client-cert=p exists-action=b
26
- keyring-provider=b log=p proxy=q python=q resume-retries=i retries=i timeout=i trusted-host=b
27
- use-deprecated=b use-feature=b].freeze,
22
+ common: %w[debug disable-pip-version-check isolated no-cache-dir no-color no-input require-virtualenv
23
+ q|quiet=+ v|verbose=+ cache-dir=p cert=p client-cert=p exists-action=b keyring-provider=b log=p
24
+ proxy=q python=q resume-retries=i retries=i timeout=i trusted-host=b use-deprecated=b
25
+ use-feature=b].freeze,
28
26
  cache: %w[format=b].freeze,
29
27
  completion: %w[b|bash f|fish p|powershell z|zsh].freeze,
30
28
  config: %w[global user site editor=p].freeze,
@@ -37,12 +35,12 @@ module Squared
37
35
  no-warn-conflicts no-warn-script-location U|upgrade user prefix=p report=p root=p
38
36
  root-user-action=b t|target=p upgrade-strategy=b].freeze,
39
37
  install_a: %w[no-index pre prefer-binary all-releases=b extra-index-url=q f|find-links=q i|index-url=q
40
- no-binary=q only-binary=q only-final=b refresh-package=q uploaded-prior-to=q].freeze,
41
- install_b: %w[check-build-dependencies no-build-isolation no-clean no-deps no-require-hashes only-deps
42
- require-hashes use-pep517 build-constraint=p c|constraint=p group=q progress-bar=b
43
- r|requirement=p requirements-from-script=p src=p].freeze,
38
+ no-binary=q only-binary=q only-final=b].freeze,
39
+ install_b: %w[check-build-dependencies no-build-isolation no-clean no-deps require-hashes use-pep517
40
+ build-constraint=p c|constraint=p group=q progress-bar=b r|requirement=p
41
+ requirements-from-script=p src=p].freeze,
44
42
  install_c: %w[C|config-settings=q e|editable=v].freeze,
45
- install_d: %w[ignore-requires-python].freeze,
43
+ install_d: %w[ignore-requires-python uploaded-prior-to=q].freeze,
46
44
  hash: %w[a|algorithm].freeze,
47
45
  list: %w[e|editable exclude-editable include-editable l|local not-required o|outdated u|uptodate user
48
46
  exclude=b format=b path=p].freeze,
@@ -60,8 +58,8 @@ module Squared
60
58
  u|username=qq].freeze
61
59
  }.freeze
62
60
  OPT_PDM = {
63
- common: %w[I|ignore-python no-cache n|non-interactive].freeze,
64
- build: %w[C=bm no-clean no-isolation no-sdist no-wheel q|quiet v|verbose=+ config-setting=q d|dest=p
61
+ common: %w[c|config I|ignore-python no-cache n|non-interactive].freeze,
62
+ build: %w[C=bm no-clean no-isolation no-sdist no-wheel q|quiet v|verbose=+ config-setting=qq d|dest=p
65
63
  p|project=p k|skip=b].freeze,
66
64
  publish: %w[no-build no-very-ssl q|quiet S|sign skip-existing v|verbose=+ ca-certs=p c|comment=q d|dest=p
67
65
  i|identity=b P|password=q p|project=p r|repository=q k|skip=b u|username=qq].freeze
@@ -79,20 +77,15 @@ module Squared
79
77
  sign-with=b u|username=qq].freeze
80
78
  }.freeze
81
79
  OPT_MESON = {
82
- build: %w[D=q clearcache debug errorlogs fatal-meson-warnings os2-emxomf pkgconfig.relocatable prefer-static
83
- python.allow-limited-api reconfigure stdsplit strip vsenv werror wipe auto-features=b
84
- backend={ninja,vs,vs2010,vs2012,vs2013,vs2015,vs2017,vs2019,vs2022,vs2026,xcode,none}
85
- bindir=q build.cmake-prefix-path=p build.pkg-config-path=p
86
- buildtype={plain,debug,debugoptimized,release,minsize,custom} cmake-prefix-path=p cross-file=p
87
- datadir=q default-library={shared,static,both} default-both-libraries={shared,static,auto}
88
- force-fallback-for=q genvslite={vs2022,vs2026} includedir=q infodir=q install-umask=b
89
- layout={mirror,flat} libdir=q libexecdir=q licensedir=q localedir=q localstatedir=q mandir=q
90
- namingscheme={platform,classic} native-file=p optimization={plain,0,g,1,2,3,s} pkg-config-path=p
91
- prefix=p python.build-config=p python.bytecompile=b python.platlibdir=p python.purelibdir=p
92
- python.install-env={auto,prefix,system,venv} sbindir=q sharedstatedir=q sysconfdir=q
93
- unity={on,off,subprojects} unity-size=i warnlevel={0,1,2,3,everything}
94
- wrap-mode={default,nofallback,nodownload,forcefallback,nopromote}].freeze,
95
- compile: %w[C=p clean v|verbose j|jobs=i l|load-average=b ninja-args=q vs-args=q xcode-args=q].freeze
80
+ build: %w[D=q clearcache debug errorlogs fatal-meson-warnings pkgconfig.relocatable prefer-static
81
+ python.allow-limited-api reconfigure stdsplit strip vsenv werror wipe auto-features=b backend=b
82
+ bindir=p build.cmake-prefix-path=p build.pkg-config-path=p buildtype=b cmake-prefix-path=p
83
+ cross-file=p datadir=p default-library=b default-both-libraries=b force-fallback-for=q genvslite=b
84
+ includedir=p infodir=p install-umask=b layout=b libdir=p libexecdir=p licensedir=p localedir=p
85
+ localstatedir=p mandir=p native-file=p optimization=b pkg-config-path=p prefix=p
86
+ python.bytecompile=i python.platlibdir=p python.purelibdir=p python.install-env=b sbindir=p
87
+ sharedstatedir=p sysconfdir=p unity=b unity-size=i warnlevel=b wrap-mode=b].freeze,
88
+ compile: %w[clean v|verbose j|jobs=i l|load-average=b ninja-args=q vs-args=q xcode-args=q].freeze
96
89
  }.freeze
97
90
  PASS_PYTHON = {
98
91
  python: %w[c v V].freeze,
@@ -138,7 +131,7 @@ module Squared
138
131
  initialize_build(Python.ref, **kwargs)
139
132
  initialize_env(**kwargs)
140
133
  end
141
- dependfile_set(DEP_PYTHON, default: 2)
134
+ dependfile_set(DEP_PYTHON, default: 4)
142
135
  serve_set kwargs[:serve]
143
136
  editable_set editable
144
137
  venv_set kwargs[:venv]
@@ -283,7 +276,7 @@ module Squared
283
276
  args = args.to_a
284
277
  if args.empty?
285
278
  args = readline('Enter command', force: true).split(' ', 2)
286
- elsif args.size == 1 && option('interactive', notequals: '0', prefix: 'python')
279
+ elsif args.size == 1 && option('interactive', notequals: '0', prefix: ref)
287
280
  args << readline('Enter arguments', force: false) unless args.first.include?(' ')
288
281
  end
289
282
  venv_init
@@ -304,7 +297,7 @@ module Squared
304
297
  install flag, ['upgrade', *args.to_a, 'pip']
305
298
  end
306
299
  when :freeze
307
- format_desc action, flag, "file?=#{DEP_PYTHON[4]},u/ninstall?,opts*"
300
+ format_desc action, flag, "file?=#{DEP_PYTHON[6]},u/ninstall?,opts*"
308
301
  task flag do |_, args|
309
302
  opts = args.to_a
310
303
  if has_value!(opts, 'u', 'uninstall')
@@ -353,18 +346,18 @@ module Squared
353
346
  case flag
354
347
  when :upgrade
355
348
  task flag, [:strategy] do |_, args|
356
- val = case args.strategy
357
- when 'eager'
358
- 'eager'
359
- when /^only-if/, /needed$/
360
- 'only-if-needed'
361
- end
362
- args = if val
363
- args.extras << "upgrade-strategy=#{val}"
364
- else
365
- args.to_a
366
- end
367
- install flag, args
349
+ install flag, (case args.strategy
350
+ when 'eager'
351
+ 'eager'
352
+ when /^only-if|needed$/
353
+ 'only-if-needed'
354
+ end.then do |val|
355
+ if val
356
+ args.extras << "upgrade-strategy=#{val}"
357
+ else
358
+ args.to_a
359
+ end
360
+ end)
368
361
  end
369
362
  when :requirement, :target
370
363
  task flag, [:path] do |_, args|
@@ -437,7 +430,17 @@ module Squared
437
430
  workspace.rev_clear(name, sync: sync)
438
431
  if !flag && poetry?
439
432
  cmd = poetry_session 'install -n'
433
+ if prod?
434
+ cmd << '--only=main'
435
+ else
436
+ option('with') { |val| cmd << basic_option('with', val) }
437
+ option('without') { |val| cmd << basic_option('without', val) }
438
+ end
440
439
  cmd << '--no-root' if option('no-root')
440
+ elsif !flag && pdm?
441
+ cmd = pdm_session 'install'
442
+ cmd << '--prod' if prod?
443
+ option('G', 'group') { |val| cmd << basic_option('G', val) }
441
444
  else
442
445
  cmd = pip_session 'install'
443
446
  cmd << '--upgrade-strategy=eager' if env('UPDATE') || env('PYTHON_UPDATE')
@@ -454,9 +457,13 @@ module Squared
454
457
  else
455
458
  append_global
456
459
  end
457
- if exist?(DEP_PYTHON[4]) && !session_arg?('r', 'requirement')
458
- cmd << basic_option('r', DEP_PYTHON[4])
459
- cmd << basic_option('c', 'constraints.txt') if exist?('constraints.txt')
460
+ unless session_arg?('r', 'requirement')
461
+ if exist?(DEP_PYTHON[2])
462
+ cmd << basic_option('r', DEP_PYTHON[2])
463
+ elsif exist?(DEP_PYTHON[6])
464
+ cmd << basic_option('r', DEP_PYTHON[6])
465
+ cmd << basic_option('c', 'constraints.txt') if exist?('constraints.txt')
466
+ end
460
467
  end
461
468
  append_editable
462
469
  end
@@ -576,8 +583,9 @@ module Squared
576
583
  end
577
584
  if found > 0
578
585
  items = if se
579
- choice('Select a package', items.map(&:first),
580
- multiple: true, force: false, index: true, border: true).map { |n| items[n.pred].last }
586
+ choice('Select a package', items.map(&:first), multiple: true, force: false, index: true,
587
+ border: true, **parse_select)
588
+ .map { |n| items[n.pred].last }
581
589
  elsif ia
582
590
  items.map(&:last)
583
591
  else
@@ -742,7 +750,7 @@ module Squared
742
750
  op = OptionPartition.new(session_opts(with, args: args, kwargs: kwargs, pass: pass), OPT_PYTHON[:common],
743
751
  session('python', path: !venv?),
744
752
  project: self, strict: strict?, multiple: [/^-c/], single: singleopt(:python),
745
- sep: ' ', args: true, stdin: true)
753
+ args: true, stdin: true)
746
754
  op.concat(args)
747
755
  if op.include?('-')
748
756
  op.exist?(add: true)
@@ -756,7 +764,7 @@ module Squared
756
764
  end
757
765
  end
758
766
  print_run(op, banner, **kwargs)
759
- run(sync: sync, banner: banner, exception: exception?(**kwargs), from: :python)
767
+ run(sync: sync, banner: banner, exception: kwargs.fetch(:exception, exception?), from: :python)
760
768
  end
761
769
 
762
770
  def pip(flag, *args, sync: true, banner: verbose?, with: nil, pass: nil, **kwargs)
@@ -793,7 +801,7 @@ module Squared
793
801
  ret = kwargs[:requirement] || begin
794
802
  file = op.detect { |val| op.exist?(val) }
795
803
  op.remove(file) if file
796
- basepath(file || DEP_PYTHON[4])
804
+ basepath(file || DEP_PYTHON[6])
797
805
  end
798
806
  op.add_quote(ret)
799
807
  .clear
@@ -838,8 +846,8 @@ module Squared
838
846
  op.clear
839
847
  end
840
848
  print_run(op, banner, **kwargs)
841
- run(sync: sync, banner: banner, exception: exception?(**kwargs), from: symjoin('pip', flag))
842
- .yield_self { |val| ret || val }
849
+ run(sync: sync, banner: banner, exception: kwargs.fetch(:exception, exception?), from: symjoin('pip', flag))
850
+ .then { |val| ret || val }
843
851
  end
844
852
 
845
853
  def serve(root, opts = [], bind: 'localhost', port: nil, **)
@@ -943,8 +951,7 @@ module Squared
943
951
  pre = preopts(quiet: quiet)
944
952
  return session(name, *pre, *cmd, path: !venv?) unless opts
945
953
 
946
- op = OptionPartition.new(opts, common, project: self, strict: strict?, sep: name == 'python' ? ' ' : '=',
947
- single: singleopt(name.to_sym))
954
+ op = OptionPartition.new(opts, common, project: self, strict: strict?, single: singleopt(name.to_sym))
948
955
  [session(name, *pre, *op.to_a, *cmd, path: !venv?), op.extras]
949
956
  end
950
957
 
@@ -1047,7 +1054,15 @@ module Squared
1047
1054
  end
1048
1055
  end
1049
1056
  ret.last[1] += val
1050
- elsif line.strip =~ /^(\S+)\s*=\s*([+-]?[\d.]+|true|false|("""|'''|["'\[{])(.*))$/
1057
+ elsif line.strip =~ /^(\S+)\s*=\s*
1058
+ (
1059
+ [+-]?(?:[\d._]+(?:[eE].+)?|0x[\dA-Fa-f]+|0[ob]\d+|nan|inf)
1060
+ |true|false
1061
+ |\d{4}-\d{2}-\d{2}.*
1062
+ |\d{2}:\d{2}.*
1063
+ |("""|'''|["'\[{])(.*)
1064
+ )$/x
1065
+ name = $1
1051
1066
  if (val = $4)
1052
1067
  case (ch = $3)
1053
1068
  when '{', '['
@@ -1067,11 +1082,21 @@ module Squared
1067
1082
  true
1068
1083
  when 'false'
1069
1084
  false
1085
+ when /^\d{4}-/
1086
+ Time.parse(ch)
1087
+ when /^\d{2}:/
1088
+ Time.strptime(ch, '%T')
1089
+ when /nan$/
1090
+ Float::NAN
1091
+ when /inf$/
1092
+ Float::INFINITY * (ch[0] == '-' ? -1 : 1)
1093
+ when /^[+-]?0[xob]/
1094
+ eval ch
1070
1095
  else
1071
1096
  ch.include?('.') ? ch.to_f : ch.to_i
1072
1097
  end
1073
1098
  end
1074
- ret << [$1, val]
1099
+ ret << [name, val]
1075
1100
  end
1076
1101
  if !ch && (val = ret.last[1]).is_a?(String) && (val.match?(/\A\{.+\}\z/m) || val.match?(/\A\[.+\]\z/m))
1077
1102
  ret.last[1] = JSON.parse(val) rescue nil
@@ -1090,19 +1115,19 @@ module Squared
1090
1115
  end
1091
1116
 
1092
1117
  def pyprojectfile
1093
- @pyprojectfile = basepath!(DEP_PYTHON[2]) || false if @pyprojectfile.nil?
1118
+ @pyprojectfile = basepath!(DEP_PYTHON[4]) || false if @pyprojectfile.nil?
1094
1119
  @pyprojectfile || nil
1095
1120
  end
1096
1121
 
1097
1122
  def singleopt(flag = nil)
1098
1123
  case flag
1099
1124
  when :python
1100
- /\A(v+|q+|b+|V+|O+)\z/
1125
+ /\A(?:v+|q+|b+|V+|O+)\z/
1101
1126
  when :pdm, :poetry
1102
1127
  /\Av+\z/
1103
1128
  when :twine, :meson then nil
1104
1129
  else
1105
- /\A(v+|q+)\z/
1130
+ /\A(?:v+|q+)\z/
1106
1131
  end
1107
1132
  end
1108
1133
 
@@ -1120,18 +1145,19 @@ module Squared
1120
1145
  def pipopts(flag)
1121
1146
  ret = OPT_PIP.fetch(flag, []) + OPT_PIP[:common]
1122
1147
  if pip_install?(flag)
1123
- ret.concat(OPT_PIP[:install_a], OPT_PIP[:install_d])
1148
+ ret.concat(OPT_PIP[:install_a])
1124
1149
  ret.concat(OPT_PIP[:install_b]) unless flag == :index
1150
+ ret.concat(OPT_PIP[:install_d])
1125
1151
  case flag
1126
1152
  when :install
1127
- ret.concat(OPT_PIP[:install_c], OPT_PIP[:debug])
1153
+ ret.concat(OPT_PIP[:install_c] + OPT_PIP[:debug])
1128
1154
  when :lock, :wheel
1129
1155
  ret.concat(OPT_PIP[:install_c])
1130
1156
  when :download, :index
1131
1157
  ret.concat(OPT_PIP[:debug])
1132
1158
  end
1133
1159
  elsif flag == :list
1134
- ret.concat(OPT_PIP[:install_a], OPT_PIP[:install_d])
1160
+ ret.concat(OPT_PIP[:install_a])
1135
1161
  end
1136
1162
  ret
1137
1163
  end
@@ -1146,7 +1172,7 @@ module Squared
1146
1172
  if windows?
1147
1173
  shell_quote(venvbin.join(powershell? ? 'Activate.ps1' : 'activate.bat'), option: false)
1148
1174
  else
1149
- { 'VIRTUAL_ENV' => venv.to_s, 'PATH' => "#{venvbin}:#{ENV['PATH']}" }
1175
+ { 'VIRTUAL_ENV' => venv.to_s, 'PATH' => task_join(venvbin, ENV['PATH']) }
1150
1176
  end
1151
1177
  end
1152
1178
 
@@ -1205,7 +1231,6 @@ module Squared
1205
1231
  status = true
1206
1232
  :virtualenv
1207
1233
  else
1208
- status = !banner
1209
1234
  :venv
1210
1235
  end
1211
1236
  cmd, opts = python_session('-m', flag, opts: opts)
@@ -1213,31 +1238,34 @@ module Squared
1213
1238
  op.append(dir, delim: true)
1214
1239
  .clear(pass: false)
1215
1240
  status ||= op.arg?(/\A-v+\z/)
1216
- if run(op, env, exception: true, banner: banner) && dir.directory?
1217
- args = []
1218
- requires = read_pyproject 'build-system', 'requires'
1219
- args.concat(requires) if requires.is_a?(Array)
1220
- if poetry?
1221
- requires = read_pyproject 'tool.poetry', 'requires-poetry'
1222
- args << "poetry#{requires}"
1223
- elsif setuptools? && !virtualenv?
1224
- args << 'setuptools' << 'wheel'
1225
- end
1226
- pip(:install, *args, banner: false) unless args.empty?
1227
- if poetry?
1228
- dir += (windows? ? 'Scripts/python.exe' : 'bin/python')
1229
- poetry_session 'env use'
1230
- elsif pdm?
1231
- pdm_session 'use -f'
1241
+ ret = run(op, env, exception: true, banner: banner)
1242
+ args = []
1243
+ requires = read_pyproject 'build-system', 'requires'
1244
+ args.concat(requires) if requires.is_a?(Array)
1245
+ if poetry?
1246
+ requires = read_pyproject 'tool.poetry', 'requires-poetry'
1247
+ args << "poetry#{requires}"
1248
+ elsif setuptools? && !virtualenv?
1249
+ args << 'setuptools' << 'wheel'
1250
+ end
1251
+ pip(:install, *args, banner: false) unless args.empty?
1252
+ success?(ret, banner, !status) do |out|
1253
+ if out && dir.directory?
1254
+ if poetry?
1255
+ dir += (windows? ? 'Scripts/python.exe' : 'bin/python')
1256
+ cmd = poetry_session 'env use'
1257
+ elsif pdm?
1258
+ cmd = pdm_session 'use -f'
1259
+ else
1260
+ puts "Success: #{dir}"
1261
+ return
1262
+ end
1263
+ cmd << shell_quote(dir)
1264
+ print_run cmd, silent?
1265
+ run(banner: false)
1232
1266
  else
1233
- puts "Success: #{dir}" unless status
1234
- return
1267
+ puts 'Failed'
1235
1268
  end
1236
- cmd << shell_quote(dir)
1237
- print_run cmd, silent?
1238
- run(banner: false)
1239
- elsif !status
1240
- puts 'Failed'
1241
1269
  end
1242
1270
  end
1243
1271
 
@@ -1271,13 +1299,17 @@ module Squared
1271
1299
  end
1272
1300
 
1273
1301
  def setuptools?
1274
- dependtype == 2 || dependtype == 4
1302
+ dependtype == 4 || dependtype == 6
1275
1303
  end
1276
1304
 
1277
1305
  def poetry?
1278
1306
  dependtype == 1
1279
1307
  end
1280
1308
 
1309
+ def pdm?
1310
+ dependtype == 2
1311
+ end
1312
+
1281
1313
  def twine?
1282
1314
  venv_package?('twine')
1283
1315
  end
@@ -1287,7 +1319,7 @@ module Squared
1287
1319
  end
1288
1320
 
1289
1321
  def requirements?
1290
- dependtype == 5
1322
+ dependtype == 7
1291
1323
  end
1292
1324
  end
1293
1325