squared 0.4.5 → 0.4.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d23d69be4457a4dfa43c961b405d27f834b915aa7c370b2733d2438dc5792b55
4
- data.tar.gz: d070c6ee2417ce81709a5fe6ea881e152d7839b6ef4030f8ab7539b2d7552f8f
3
+ metadata.gz: c948cc37c50fe20628bd7ca5f1c7d39125b571199f76688a7b58e34a08c8ce2d
4
+ data.tar.gz: 02abbb0dbf14cca7c0b5dc4ca6af5b08270e5d6a9bab95c23972bbc201b6fca9
5
5
  SHA512:
6
- metadata.gz: 5c4f6c187e2b5dd2f230e972919f48ed4badd124c7b73df86f28ec77c87027898480c3bf02044a5e3c986334214c82ec1eaeb15b52d8424eeafc720086652ee3
7
- data.tar.gz: 1ec9ca0ff06a048e13743759b82c3e070be6a23efcc2fce8b7d5cad82e49a65597538e78780b8fe88937a07cd055f26f7c54c4a2554926d04183707c0b0e79fe
6
+ metadata.gz: e5590666ce8061dc02a8d2f3c809ee2ccff87f3abe62bccc6d2510adf418a8ab41e323d75e6781b52aab091d8677ec7cd4e3c55b49177f2baf3a814920daad69
7
+ data.tar.gz: aeb0fd0ba9095f2a97de0977dab5a0f13da4e79ac6972fbda56ab9e022d07d44211bd552624e953aab158745145d054c620972f5f64829d97b58fb47a21e9517
data/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.4.6] - 2025-04-12
4
+
5
+ ### Added
6
+
7
+ - Python command venv action run was implemented.
8
+ - Program paths can be defined per session using ENV.
9
+ - Python style verbose is supported.
10
+
11
+ ### Changed
12
+
13
+ - Python dependtype lists setup.cfg before pyproject.toml.
14
+ - Pip install is editable by default.
15
+
16
+ ### Fixed
17
+
18
+ - Node copy task did not reset revbuild target flags.
19
+ - Python venv init did not locate user-defined program paths.
20
+ - Node update task did not reset revbuild target flags.
21
+
22
+ ## [0.3.8] - 2025-04-12
23
+
24
+ ### Fixed
25
+
26
+ - Project class did not parse verbose string values.
27
+
28
+ ## [0.2.8] - 2025-04-12
29
+
30
+ ### Fixed
31
+
32
+ - User-defined program paths were not sanitized for ENV.
33
+ - Project clean task used incompatible rmtree flag.
34
+ - Git branch unset-upstream used undefined variable.
35
+
3
36
  ## [0.4.5] - 2025-04-09
4
37
 
5
38
  ### Fixed
@@ -457,12 +490,14 @@
457
490
 
458
491
  - Changelog was created.
459
492
 
493
+ [0.4.6]: https://github.com/anpham6/squared/releases/tag/v0.4.6-ruby
460
494
  [0.4.5]: https://github.com/anpham6/squared/releases/tag/v0.4.5-ruby
461
495
  [0.4.4]: https://github.com/anpham6/squared/releases/tag/v0.4.4-ruby
462
496
  [0.4.3]: https://github.com/anpham6/squared/releases/tag/v0.4.3-ruby
463
497
  [0.4.2]: https://github.com/anpham6/squared/releases/tag/v0.4.2-ruby
464
498
  [0.4.1]: https://github.com/anpham6/squared/releases/tag/v0.4.1-ruby
465
499
  [0.4.0]: https://github.com/anpham6/squared/releases/tag/v0.4.0-ruby
500
+ [0.3.8]: https://github.com/anpham6/squared/releases/tag/v0.3.8-ruby
466
501
  [0.3.7]: https://github.com/anpham6/squared/releases/tag/v0.3.7-ruby
467
502
  [0.3.6]: https://github.com/anpham6/squared/releases/tag/v0.3.6-ruby
468
503
  [0.3.5]: https://github.com/anpham6/squared/releases/tag/v0.3.5-ruby
@@ -471,6 +506,7 @@
471
506
  [0.3.2]: https://github.com/anpham6/squared/releases/tag/v0.3.2-ruby
472
507
  [0.3.1]: https://github.com/anpham6/squared/releases/tag/v0.3.1-ruby
473
508
  [0.3.0]: https://github.com/anpham6/squared/releases/tag/v0.3.0-ruby
509
+ [0.2.8]: https://github.com/anpham6/squared/releases/tag/v0.2.8-ruby
474
510
  [0.2.7]: https://github.com/anpham6/squared/releases/tag/v0.2.7-ruby
475
511
  [0.2.6]: https://github.com/anpham6/squared/releases/tag/v0.2.6-ruby
476
512
  [0.2.5]: https://github.com/anpham6/squared/releases/tag/v0.2.5-ruby
data/README.ruby.md CHANGED
@@ -99,8 +99,8 @@ Workspace::Application
99
99
  # OR
100
100
  add(["publish/sqd-cli", "publish/sqd-serve"], true, exclude: [:base]) # rake squared:sqd-serve:build
101
101
  end
102
- .add("squared/sqd", exclude: :git, pass: [:node, "checkout", "bump"]) do # Skip initialize(:node) + squared:checkout:* + squared:bump:*
103
- variable_set :script, "build:sqd" # Override detection
102
+ .add("squared/sqd", exclude: :git, pass: [:node, "checkout", "bump"]) do # Skip initialize(:node) + squared:checkout:* + squared:bump:*
103
+ variable_set :script, "build:sqd" # Override detection
104
104
  variable_set :depend, false
105
105
  variable_set :clean, ["build/sqd/"]
106
106
  end
@@ -141,7 +141,7 @@ Workspace::Application
141
141
  run: "rake compile" # rake rb:pathname:build
142
142
  }
143
143
  })
144
- .with(:python) do # ref=Symbol | group=String
144
+ .with(:python, editable: false) do # ref=Symbol | group=String
145
145
  banner([:name, ": ", :version], "path") # chrome-docs: 0.1.0 | /workspaces/chrome-docs
146
146
  doc("make html") # rake rb:doc:python
147
147
  run(false) # rake rb:build:python (disabled)
@@ -470,8 +470,8 @@ All project executable programs can have their binary path set to a non-global a
470
470
 
471
471
  ```ruby
472
472
  Common::PATH.merge!({
473
- GIT: "/usr/bin/git",
474
- TAR: "/opt/archivers/tar",
473
+ GIT: "/usr/bin/git", # PATH_GIT=/usr/bin/git
474
+ TAR: "/opt/archivers/tar", # PATH_TAR=/opt/archivers/tar
475
475
  UNZIP: "/opt/archivers/unzip",
476
476
  GEM: "~/.rvm/gems/ruby-3.4.0/bin/gem",
477
477
  BUNDLE: "~/.rvm/gems/ruby-3.4.0/bin/bundle",
@@ -511,6 +511,9 @@ BUILD_${NAME}_VERSION=0.1.0 # publish + detection
511
511
 
512
512
  BANNER=0 # hide banner
513
513
  BANNER_${NAME}=0 #
514
+
515
+ REVBUILD_FORCE=1 # Rebuild all targets
516
+ REVBUILD_FORCE_${NAME}=1 # Rebuild project
514
517
  ```
515
518
 
516
519
  ### Graph
@@ -36,7 +36,7 @@ module Squared
36
36
  def shell_quote(val, option: true, force: true, double: false, override: false)
37
37
  val = val.to_s
38
38
  return val if !force && !val.include?(' ')
39
- return val if option && val.match?(/(?:^|\S=|[^=]\s+|#{Rake::Win32.windows? ? '[\\\/]' : '\/'})(["']).+\1\z/m)
39
+ return val if option && val.match?(/(?:\A|\S=|[^=]\s+|#{Rake::Win32.windows? ? '[\\\/]' : '\/'})(["']).+\1\z/m)
40
40
 
41
41
  if double || Rake::Win32.windows? || (ARG[:QUOTE] == '"' && !override)
42
42
  "\"#{val.gsub(/(?<!\\)"/, '\\"')}\""
@@ -76,7 +76,7 @@ module Squared
76
76
  ret = Shellwords.split(val)
77
77
  return ret if join == false
78
78
 
79
- ret = ret.map { |opt| shell_escape(opt, quote: quote) } if escape
79
+ ret.map! { |opt| shell_escape(opt, quote: quote) } if escape
80
80
  return ret unless join
81
81
 
82
82
  ret.join(join.is_a?(::String) ? join : ' ')
@@ -18,7 +18,7 @@ module Squared
18
18
 
19
19
  last = val[i + 1..-1].strip
20
20
  quote = ''
21
- if last =~ /^(["'])(.+)\1$/
21
+ if last =~ /\A(["'])(.+)\1\z/
22
22
  last = $2
23
23
  quote = $1
24
24
  end
@@ -188,7 +188,7 @@ module Squared
188
188
  def to_s
189
189
  realpath if target?
190
190
 
191
- @mime.keys.map { |ext| "#{main}.#{ext}" }.join(',')
191
+ @mime.keys.map! { |ext| "#{main}.#{ext}" }.join(',')
192
192
  end
193
193
 
194
194
  def inspect
@@ -291,9 +291,9 @@ module Squared
291
291
  pad = [pad, key.size].max
292
292
  end
293
293
  if stdin?
294
- puts out.map(&:last).join("\n")
294
+ puts out.map!(&:last).join("\n")
295
295
  else
296
- out.map { |item| "#{item[0].ljust(pad)} : #{item[1]}" }
296
+ out.map! { |item| "#{item[0].ljust(pad)} : #{item[1]}" }
297
297
  end
298
298
  end
299
299
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.4.5'
4
+ VERSION = '0.4.6'
5
5
  end
@@ -310,17 +310,17 @@ module Squared
310
310
  end
311
311
 
312
312
  def group(path, val, override: {}, **kwargs, &blk)
313
- rootpath(path).children.map do |dir|
313
+ rootpath(path).children.map! do |dir|
314
314
  next unless dir.directory?
315
315
 
316
316
  basename = dir.basename.to_s
317
317
  [dir, basename, override[basename.to_sym]]
318
318
  end
319
- .each do |dir, basename, opts|
320
- args = kwargs.dup
321
- args.merge!(opts) if opts
322
- add(dir, basename, group: val, **args, &blk)
323
- end
319
+ .each do |dir, basename, opts|
320
+ args = kwargs.dup
321
+ args.merge!(opts) if opts
322
+ add(dir, basename, group: val, **args, &blk)
323
+ end
324
324
  self
325
325
  end
326
326
 
@@ -70,7 +70,7 @@ module Squared
70
70
  :group, :parent, :dependfile
71
71
 
72
72
  def initialize(workspace, path, name, *, group: nil, graph: nil, pass: nil, exclude: nil, release: nil,
73
- archive: nil, first: {}, last: {}, error: {}, common: ARG[:COMMON], **kwargs)
73
+ archive: nil, verbose: nil, first: {}, last: {}, error: {}, common: ARG[:COMMON], **kwargs)
74
74
  @path = path
75
75
  @workspace = workspace
76
76
  @name = name.to_s.freeze
@@ -97,7 +97,7 @@ module Squared
97
97
  when nil
98
98
  workspace.verbose
99
99
  when String
100
- env_pipe(verbose, workspace.verbose, strict: true, index: true)
100
+ env_bool(verbose, workspace.verbose, strict: true, index: true)
101
101
  else
102
102
  verbose
103
103
  end
@@ -395,7 +395,7 @@ module Squared
395
395
 
396
396
  run_b(@run, sync: sync, from: from) if series?(@run)
397
397
  args = @output
398
- banner = verbose == 1 if task_invoked?('build', 'build:sync', 'default')
398
+ banner = verbosity > 0 if task_invoked?('build', 'build:sync', 'default')
399
399
  end
400
400
  if args.all? { |val| val.is_a?(Array) }
401
401
  cmd = []
@@ -493,7 +493,7 @@ module Squared
493
493
  path = basepath(val)
494
494
  if path.directory? && val.match?(%r{[\\/]$})
495
495
  log&.warn "rm -rf #{path}"
496
- path.rmtree(verbose: verbose)
496
+ FileUtils.rm_rf(path, verbose: verbose)
497
497
  else
498
498
  log&.warn "rm #{path}"
499
499
  (val.include?('*') ? Dir[path] : [path]).each do |file|
@@ -527,7 +527,7 @@ module Squared
527
527
  end
528
528
  pass += split_escape(val) if (val = env('GRAPH', suffix: 'PASS'))
529
529
  start, neg = start.partition { |name| !name.start_with?('-') }
530
- data = graph_collect(self, start, pass: neg.map { |name| name[1..-1] })
530
+ data = graph_collect(self, start, pass: neg.map! { |name| name[1..-1] })
531
531
  unless out
532
532
  data[name] << self
533
533
  on :first, :graph
@@ -1067,7 +1067,7 @@ module Squared
1067
1067
 
1068
1068
  def session(*cmd, prefix: cmd.first, main: true, path: true, options: true)
1069
1069
  prefix = prefix.to_s.upcase
1070
- if path && (val = PATH[prefix] || PATH[prefix.to_sym])
1070
+ if path && (val = ENV["PATH_#{prefix}"] || PATH[prefix] || PATH[prefix.to_sym])
1071
1071
  cmd[0] = shell_quote(val, force: false)
1072
1072
  end
1073
1073
  ret = JoinSet.new(cmd.flatten(1))
@@ -1103,6 +1103,7 @@ module Squared
1103
1103
 
1104
1104
  def option(*args, prefix: @session&.first, **kwargs)
1105
1105
  if prefix
1106
+ prefix = File.basename(prefix, File.extname(prefix))
1106
1107
  args.each do |val|
1107
1108
  ret = env("#{prefix}_#{val.gsub(/\W/, '_')}".upcase, **kwargs)
1108
1109
  return ret if ret
@@ -1124,7 +1125,7 @@ module Squared
1124
1125
  i = []
1125
1126
  f = []
1126
1127
  si = []
1127
- list = list.map do |val|
1128
+ list.map do |val|
1128
1129
  x, y = val.split('|')
1129
1130
  if y
1130
1131
  if (n = val.index('='))
@@ -1135,7 +1136,8 @@ module Squared
1135
1136
  x
1136
1137
  end
1137
1138
  end
1138
- list.flatten.each do |val|
1139
+ .flatten
1140
+ .each do |val|
1139
1141
  if (n = val.index('='))
1140
1142
  flag = val[0, n]
1141
1143
  case val[n + 1]
@@ -1235,7 +1237,7 @@ module Squared
1235
1237
  n = Project.max_width(lines)
1236
1238
  ch = ' ' * pad
1237
1239
  index = -1
1238
- out = lines.map do |val|
1240
+ lines.map! do |val|
1239
1241
  index += 1
1240
1242
  val = ch + val.ljust(n - (pad * 2)) + ch
1241
1243
  if styles && (pad == 1 || index == 0)
@@ -1244,8 +1246,7 @@ module Squared
1244
1246
  val
1245
1247
  end
1246
1248
  end
1247
- out << sub_style(ARG[:BORDER][1] * n, styles: border)
1248
- out.join("\n")
1249
+ (lines << sub_style(ARG[:BORDER][1] * n, styles: border)).join("\n")
1249
1250
  end
1250
1251
 
1251
1252
  def print_footer(*lines, sub: nil, reverse: false, right: false, **kwargs)
@@ -1414,10 +1415,10 @@ module Squared
1414
1415
  return if (list = list.flatten).empty?
1415
1416
 
1416
1417
  target << '--' if delim && !target.include?('--')
1417
- list.map do |val|
1418
- item = escape ? shell_escape(val, quote: quote) : shell_quote(val)
1419
- target << item
1420
- item
1418
+ list.map! do |val|
1419
+ ret = escape ? shell_escape(val, quote: quote) : shell_quote(val)
1420
+ target << ret
1421
+ ret
1421
1422
  end
1422
1423
  end
1423
1424
 
@@ -1542,7 +1543,7 @@ module Squared
1542
1543
  return [] if files.empty?
1543
1544
 
1544
1545
  pat = /^#{Regexp.escape(File.join(path, ''))}/
1545
- files.flatten.map { |val| Pathname.new(val) }.select { |val| projectpath?(val) }.map do |val|
1546
+ files.flatten.map! { |val| Pathname.new(val) }.select { |val| projectpath?(val) }.map! do |val|
1546
1547
  val = val.absolute? ? val.to_s.sub(pat, '') : val.to_s
1547
1548
  val = val[2..-1] if val.start_with?('./')
1548
1549
  val = "#{val}*" if all && val.end_with?('/')
@@ -1592,7 +1593,7 @@ module Squared
1592
1593
  end
1593
1594
 
1594
1595
  def colormap(val)
1595
- val.compact.map { |s| color(s) }.flatten
1596
+ val.compact.map! { |s| color(s) }.flatten
1596
1597
  end
1597
1598
 
1598
1599
  def epochtime
@@ -1740,7 +1741,7 @@ module Squared
1740
1741
  next if (items = @children.select { |item| item.task_include?(key) }).empty?
1741
1742
 
1742
1743
  ws.task_desc(@desc, action, 'workspace')
1743
- task task_join(action, 'workspace') => items.map { |item| task_join(item.name, action) }
1744
+ task task_join(action, 'workspace') => items.map! { |item| task_join(item.name, action) }
1744
1745
  end
1745
1746
  end
1746
1747
  end
@@ -270,7 +270,7 @@ module Squared
270
270
  append_context
271
271
  when :bake, :compose
272
272
  if (val = option(from == :bake ? 'target' : 'service', ignore: false))
273
- ret.merge(split_escape(val).map { |s| shell_escape(s) })
273
+ ret.merge(split_escape(val).map! { |s| shell_escape(s) })
274
274
  end
275
275
  end
276
276
  ret
@@ -411,7 +411,7 @@ module Squared
411
411
  when :rm
412
412
  status = %w[created exited dead]
413
413
  end
414
- ps = docker_output('ps -a', *status.map { |s| "--filter=\"status=#{s}\"" })
414
+ ps = docker_output('ps -a', *status.map! { |s| "--filter='status=#{s}'" })
415
415
  list_image(flag, ps, no: no, hint: "status: #{status.join(', ')}", from: from) do |img|
416
416
  run(cmd.temp(img), from: from)
417
417
  end
@@ -452,7 +452,7 @@ module Squared
452
452
  out.each { |val| run(cmd.temp(val), sync: sync, from: from) }
453
453
  return
454
454
  else
455
- list_image(flag, docker_output('image', 'ls -a'), from: from) do |val|
455
+ list_image(flag, docker_output('image ls -a'), from: from) do |val|
456
456
  image(:rm, opts, sync: sync, id: val)
457
457
  end
458
458
  return
@@ -660,7 +660,7 @@ module Squared
660
660
  end
661
661
 
662
662
  def tagname(val)
663
- val = val.split(':').map { |s| charname(s.sub(/^\W+/, '')) }
663
+ val = val.split(':').map! { |s| charname(s.sub(/^\W+/, '')) }
664
664
  ret = val.join(':')
665
665
  ret = val.first if val.size > 1 && ret.size > 128
666
666
  ret[0..127]
@@ -116,6 +116,9 @@ module Squared
116
116
  end
117
117
 
118
118
  def rev_clear(name)
119
+ if Dir.exist?(name) && (proj = find(name))
120
+ name = proj.name
121
+ end
119
122
  rev_write if rev_entry(name, 'revision', val: '', create: false)
120
123
  end
121
124
 
@@ -519,7 +522,7 @@ module Squared
519
522
  end
520
523
  when :delete
521
524
  format_desc action, flag, '(^~)name+'
522
- task flag, [:name] do |_, args|
525
+ task flag do |_, args|
523
526
  refs = param_guard(action, flag, args: args.to_a)
524
527
  branch(flag, refs: refs)
525
528
  end
@@ -686,12 +689,12 @@ module Squared
686
689
  end
687
690
 
688
691
  def depend(*, **)
689
- workspace.rev_clear name
692
+ workspace.rev_clear(name)
690
693
  super
691
694
  end
692
695
 
693
696
  def clean(*, **)
694
- workspace.rev_clear name
697
+ workspace.rev_clear(name)
695
698
  super
696
699
  end
697
700
 
@@ -751,10 +754,10 @@ module Squared
751
754
 
752
755
  def fetch(flag = nil, opts = [], sync: invoked_sync?('fetch', flag), remote: nil)
753
756
  cmd, opts = git_session('fetch', opts: opts)
754
- cmd << '--all' if !remote && !opts.include?('multiple') && option('all')
755
- cmd << '--verbose' if verbose && !opts.include?('quiet')
756
757
  append_pull(opts, collect_hash(OPT_GIT[:fetch]), no: collect_hash(OPT_GIT[:no][:fetch]),
757
758
  remote: remote, flag: flag)
759
+ cmd << '--all' if !remote && !session_arg?('multiple') && option('all')
760
+ cmd << '--verbose' if verbose && !session_arg('quiet')
758
761
  source(sync: sync, **threadargs)
759
762
  end
760
763
 
@@ -872,7 +875,7 @@ module Squared
872
875
  args << basic_option('ignore-submodules', flag) if (flag = option('ignore-submodules', prefix: 'git'))
873
876
  args << basic_option('ignored', flag) if (flag = option('ignored', prefix: 'git'))
874
877
  end
875
- if (cur = workspace.rev_entry(name)) && cur['revision'] == sha
878
+ if (cur = workspace.rev_entry(name)) && cur['revision'] == sha && !env('REVBUILD_FORCE')
876
879
  files = status_digest(*args, **kwargs)
877
880
  if cur['files'].size == files.size && cur['files'].find { |key, val| files[key] != val }.nil?
878
881
  if verbose
@@ -1151,7 +1154,7 @@ module Squared
1151
1154
  return unless ref
1152
1155
 
1153
1156
  if ref.start_with?('^')
1154
- cmd << '--unset-upstream' << shell_escape(arg[1..-1])
1157
+ cmd << '--unset-upstream' << shell_escape(ref[1..-1])
1155
1158
  target = nil
1156
1159
  stdout = true
1157
1160
  else
@@ -1240,11 +1243,10 @@ module Squared
1240
1243
  case flag
1241
1244
  when :textconv
1242
1245
  cmd << '--textconv'
1243
- files = files.map { |val| Dir[val] }
1244
- .flatten
1245
- .select { |val| projectpath?(val) }
1246
- .map { |val| shell_quote("HEAD:#{val}") }
1247
- append_value files
1246
+ append_value(files.map { |val| Dir[val] }
1247
+ .flatten
1248
+ .select { |val| projectpath?(val) }
1249
+ .map! { |val| shell_quote("HEAD:#{val}") })
1248
1250
  source(banner: false)
1249
1251
  return
1250
1252
  when :oneline
@@ -1290,7 +1292,7 @@ module Squared
1290
1292
  args = option_sanitize(opts, OPT_GIT[:rev_parse][flag]).first
1291
1293
  append_value(args, escape: session_arg?('sq-quote'))
1292
1294
  end
1293
- source(banner: verbose == 1)
1295
+ source(banner: verbosity > 0)
1294
1296
  end
1295
1297
 
1296
1298
  def ls_remote(flag, opts = [], remote: nil)
@@ -1520,8 +1522,8 @@ module Squared
1520
1522
  end
1521
1523
  target.delete('--all')
1522
1524
  elsif target.include?('--multiple')
1523
- target.merge(out.map { |opt| shell_escape(opt, quote: true) })
1524
- out.clear
1525
+ target.merge(out.map! { |opt| shell_escape(opt, quote: true) })
1526
+ return
1525
1527
  end
1526
1528
  option_clear(out, target: target, subject: flag.to_s) if flag
1527
1529
  end
@@ -1604,6 +1606,17 @@ module Squared
1604
1606
  target.include?('--quiet') || (target.include?('-q') && target.first == 'git')
1605
1607
  end
1606
1608
 
1609
+ def verbosity
1610
+ case verbose
1611
+ when true
1612
+ 0
1613
+ when Numeric
1614
+ verbose
1615
+ else
1616
+ -1
1617
+ end
1618
+ end
1619
+
1607
1620
  def gitpath
1608
1621
  basepath '.git'
1609
1622
  end
@@ -238,7 +238,10 @@ module Squared
238
238
  return
239
239
  end
240
240
  items = []
241
- items << @workspace.home if build? && path != @workspace.home && @workspace.home?
241
+ if build? && path != @workspace.home && @workspace.home?
242
+ items << @workspace.home
243
+ @workspace.rev_clear(@workspace.find(@workspace.home).name)
244
+ end
242
245
  items += as_a(also) if also
243
246
  return if items.empty?
244
247
 
@@ -248,11 +251,18 @@ module Squared
248
251
  case dir
249
252
  when Pathname
250
253
  dest = dir
254
+ @workspace.rev_clear(dest)
251
255
  when String
252
256
  dest = @workspace.rootpath(dir)
257
+ @workspace.rev_clear(dest)
253
258
  when Symbol
254
- dest = @workspace.find(name: dir)&.path
255
- log.warn message("copy project :#{dir}", hint: 'not found') unless dest
259
+ if (proj = @workspace.find(name: dir))
260
+ @workspace.rev_clear(proj.name)
261
+ dest = proj.path
262
+ else
263
+ log.warn message("copy project :#{dir}", hint: 'not found')
264
+ dest = nil
265
+ end
256
266
  when Hash
257
267
  from = dir[:from] if dir.key?(:from)
258
268
  into = dir[:into] if dir.key?(:into)
@@ -265,8 +275,10 @@ module Squared
265
275
  glob = dir[:include]
266
276
  pass = dir[:exclude]
267
277
  dest = items.first unless dest && dest != true
278
+ @workspace.rev_clear(dest) unless dest == true
268
279
  when Project::Base
269
280
  dest = dir.path
281
+ @workspace.rev_clear(dir.name)
270
282
  else
271
283
  raise_error "copy given: #{dir}"
272
284
  end
@@ -318,7 +330,7 @@ module Squared
318
330
  if @depend && !flag
319
331
  super
320
332
  elsif outdated?
321
- workspace.rev_clear name
333
+ workspace.rev_clear(name)
322
334
  return update if !flag && env('NODE_UPDATE')
323
335
 
324
336
  if (yarn = dependtype(:yarn)) > 0
@@ -579,6 +591,7 @@ module Squared
579
591
  end
580
592
 
581
593
  def package(flag, opts = [])
594
+ workspace.rev_clear(name)
582
595
  if (yarn = dependtype(:yarn)) > 0
583
596
  cmd = session 'yarn', if flag == :update
584
597
  flag = yarn == 1 ? 'upgrade' : 'up'
@@ -4,9 +4,8 @@ module Squared
4
4
  module Workspace
5
5
  module Project
6
6
  class Python < Git
7
- REQUIREMENTS = %w[requirements.txt poetry.lock pyproject.toml setup.cfg].freeze
8
- SETUPTOOLS = %w[setup.py pyproject.toml].freeze
9
- DIR_PYTHON = (REQUIREMENTS + SETUPTOOLS).freeze
7
+ DEP_PYTHON = %w[poetry.lock setup.cfg pyproject.toml setup.py requirements.txt].freeze
8
+ DIR_PYTHON = (DEP_PYTHON + %w[README.rst]).freeze
10
9
  OPT_PYTHON = {
11
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,
12
11
  build: %w[n|no-isolation s|sdist v|verbose w|wheel x|skip-dependency-check C|config-setting=q installer=b
@@ -21,7 +20,7 @@ module Squared
21
20
  install: %w[break-system-packages check-build-dependencies compile dry-run force-reinstall I|ignore-installed
22
21
  ignore-requires-python no-build-isolation no-clean no-compile no-deps no-index no-warn-conflicts
23
22
  no-warn-script-location pre prefer-binary require-hashes U|upgrade use-pep517 user abi=b
24
- config-settings=q c|constraint=p e|editable=b? extra-index-url=q f|find-links=q global-option=q
23
+ config-settings=q c|constraint=p extra-index-url=q f|find-links=q global-option=q
25
24
  implementation=b i|index-url=q no-binary=q only-binary=q platform=q prefix=p progress-bar=b
26
25
  python-version=q report=p r|requirement=p root=p root-user-action=b src=p t|target=p
27
26
  upgrade-strategy=b].freeze,
@@ -46,8 +45,7 @@ module Squared
46
45
  config-file=p cert=p client-cert=p i|identity=b p|password=q r|repository=b repository-url=q
47
46
  sign-with=b u|username=q].freeze
48
47
  }.freeze
49
- private_constant :REQUIREMENTS, :SETUPTOOLS, :DIR_PYTHON, :OPT_PYTHON, :OPT_PIP, :OPT_POETRY, :OPT_HATCH,
50
- :OPT_TWINE
48
+ private_constant :DEP_PYTHON, :DIR_PYTHON, :OPT_PYTHON, :OPT_PIP, :OPT_POETRY, :OPT_HATCH, :OPT_TWINE
51
49
 
52
50
  class << self
53
51
  def populate(*); end
@@ -71,9 +69,9 @@ module Squared
71
69
  end
72
70
  end
73
71
 
74
- attr_reader :venv
72
+ attr_reader :venv, :editable
75
73
 
76
- def initialize(*, venv: nil, **kwargs)
74
+ def initialize(*, venv: nil, editable: '.', verbose: nil, **kwargs)
77
75
  super
78
76
  if @pass.include?(Python.ref)
79
77
  initialize_ref Python.ref
@@ -82,13 +80,20 @@ module Squared
82
80
  initialize_build(Python.ref, **kwargs)
83
81
  initialize_env(**kwargs)
84
82
  end
85
- @dependindex = REQUIREMENTS.index { |file| basepath(file).exist? }
86
- @dependfile = basepath(REQUIREMENTS[@dependindex || 0])
83
+ @dependindex = DEP_PYTHON.index { |file| basepath(file).exist? }
84
+ @dependfile = basepath(DEP_PYTHON[@dependindex || 0])
85
+ @verbose = $1.size if verbose.is_a?(String) && verbose =~ /^(v+)$/
86
+ @editable = case editable
87
+ when '.', Pathname
88
+ editable
89
+ when String
90
+ Pathname.new(editable)
91
+ end
87
92
  venv_set venv if venv
88
93
  end
89
94
 
90
95
  subtasks({
91
- 'venv' => %i[create remove show].freeze,
96
+ 'venv' => %i[run create remove show].freeze,
92
97
  'pip' => %i[uninstall freeze].freeze,
93
98
  'install' => %i[user force upgrade target editable].freeze,
94
99
  'build' => %i[python poetry hatch].freeze,
@@ -114,10 +119,10 @@ module Squared
114
119
  if flag == :create
115
120
  format_desc action, flag, 'dir,opts*'
116
121
  task flag, [:dir] do |_, args|
117
- dir = param_guard(action, flag, args: args, key: :dir)
122
+ dir = basepath(param_guard(action, flag, args: args, key: :dir))
118
123
  opts = python_session('-m venv', opts: args.extras).last
119
124
  opts = option_sanitize(opts, OPT_PYTHON[:venv]).first
120
- append_value(dir = basepath(dir), delim: true)
125
+ append_value(dir, delim: true)
121
126
  option_clear(opts, pass: false)
122
127
  run(exception: true)
123
128
  puts(dir.directory? ? "Success: #{dir}" : 'Failed')
@@ -129,10 +134,17 @@ module Squared
129
134
 
130
135
  format_desc action, flag, 'c|reate?,d|epend?'
131
136
  task flag do |_, args|
132
- venv.rmtree(verbose: true)
137
+ FileUtils.rm_rf(venv, verbose: true)
133
138
  venv_init if has_value?(%w[c create], args.to_a)
134
139
  depend if has_value?(%w[d depend], args.to_a)
135
140
  end
141
+ when :run
142
+ format_desc action, flag, 'args+'
143
+ task flag do |_, args|
144
+ args = param_guard(action, flag, args: args.to_a)
145
+ venv_init
146
+ run session(*args, path: false)
147
+ end
136
148
  when :show
137
149
  format_desc action, flag
138
150
  task flag do
@@ -143,7 +155,7 @@ module Squared
143
155
  when 'pip'
144
156
  case flag
145
157
  when :freeze
146
- format_desc action, flag, 'file?=requirements.txt,opts*'
158
+ format_desc action, flag, "file?=#{DEP_PYTHON[4]},opts*"
147
159
  task flag do |_, args|
148
160
  if (file = pip(flag, args.to_a)) && verbose
149
161
  puts File.read(file)
@@ -162,7 +174,7 @@ module Squared
162
174
  when :editable
163
175
  'path/url?'
164
176
  when :upgrade
165
- 'eager?,package+'
177
+ 'strategy?,package+'
166
178
  end)
167
179
  case flag
168
180
  when :editable
@@ -222,10 +234,9 @@ module Squared
222
234
  super
223
235
  elsif outdated?
224
236
  venv_init
225
- workspace.rev_clear name
226
- if !flag && dependtype == 2
227
- cmd = session 'poetry', 'install', '-n'
228
- cmd << '--no-ansi' unless verbose
237
+ workspace.rev_clear(name)
238
+ if !flag && dependtype == 1
239
+ cmd = poetry_session 'install', '-n'
229
240
  cmd << '--no-root' if option('no-root')
230
241
  else
231
242
  cmd = pip_session 'install'
@@ -240,16 +251,10 @@ module Squared
240
251
  end
241
252
  append_pip(flag, opts, from: :install)
242
253
  else
243
- if (val = option('editable', 'e'))
244
- cmd << quote_option('e', editable(val))
245
- end
246
254
  append_global
247
255
  end
248
- if dependtype == 1 && !session_arg?('e', 'editable')
249
- cmd << '-r requirements.txt' unless session_arg?('r', 'requirement')
250
- elsif !session_arg?('e', 'editable', value: true)
251
- cmd << '.'
252
- end
256
+ cmd << "-r #{DEP_PYTHON[4]}" if basepath(DEP_PYTHON[4]).exist? && !session_arg?('r', 'requirement')
257
+ append_editable
253
258
  end
254
259
  run(from: :depend, sync: sync)
255
260
  end
@@ -333,7 +338,7 @@ module Squared
333
338
  out = append_pip(flag, opts, from: :install)
334
339
  case flag
335
340
  when :editable
336
- cmd << quote_option('e', out.shift || '.')
341
+ cmd << quote_option('e', out.pop || editable || '.')
337
342
  option_clear out
338
343
  when :upgrade
339
344
  cmd << '--upgrade'
@@ -351,7 +356,7 @@ module Squared
351
356
  cmd, opts = python_session('-m build', opts: opts)
352
357
  list = OPT_PYTHON[:build]
353
358
  when :poetry
354
- cmd = session 'poetry', 'build'
359
+ cmd = poetry_session 'build'
355
360
  list = OPT_POETRY[:build] + OPT_POETRY[:common]
356
361
  when :hatch
357
362
  cmd, opts = hatch_session('build', opts: opts)
@@ -388,13 +393,12 @@ module Squared
388
393
  end
389
394
 
390
395
  def publish(flag, opts = [])
391
- cmd = session flag
392
396
  case flag
393
397
  when :poetry
394
- cmd << 'publish'
398
+ poetry_session 'publish'
395
399
  list = OPT_POETRY[:publish] + OPT_POETRY[:common]
396
400
  when :twine
397
- cmd << 'upload'
401
+ session 'twine', 'upload'
398
402
  list = OPT_TWINE[:publish]
399
403
  when :hatch
400
404
  opts = hatch_session('publish', opts: opts).last
@@ -403,7 +407,7 @@ module Squared
403
407
  out = option_sanitize(opts, list, single: flag == :twine ? nil : /^(?:v+|q+)$/).first
404
408
  if out.empty?
405
409
  dist = basepath.join('dist')
406
- raise_error('no source files given', hint: dist) unless dist.directory? && !dist.empty?
410
+ raise_error('no source files found', hint: dist) unless dist.directory? && !dist.empty?
407
411
  out << "#{dist}/*" unless flag == :poetry
408
412
  end
409
413
  append_value out
@@ -415,11 +419,11 @@ module Squared
415
419
  out = append_pip(nil, opts, from: flag)
416
420
  case flag
417
421
  when :uninstall
418
- raise_error('no packages given', subject: name, hint: 'uninstall') if out.empty?
422
+ raise_error('no packages listed', subject: name, hint: 'uninstall') if out.empty?
419
423
  cmd.merge(out)
420
424
  when :freeze
421
425
  venv_init
422
- ret = basepath(out.shift || 'requirements.txt')
426
+ ret = basepath(out.shift || DEP_PYTHON[4])
423
427
  cmd << '>' << shell_quote(ret)
424
428
  option_clear out
425
429
  end
@@ -431,14 +435,14 @@ module Squared
431
435
  case key
432
436
  when :dependfile
433
437
  req = basepath(*val)
434
- if (index = REQUIREMENTS.index(req.basename.to_s))
438
+ if (index = DEP_PYTHON.index(req.basename.to_s))
435
439
  @dependindex = index
436
440
  @dependfile = req
437
441
  else
438
442
  log.warn "variable_set: @#{key}=#{req} (not supported)"
439
443
  end
440
- when :venv
441
- @venv = val.empty? ? nil : basepath(*val)
444
+ when :venv, :editable
445
+ instance_variable_set(:"@#{key}", val.empty? ? nil : basepath(*val))
442
446
  else
443
447
  super
444
448
  end
@@ -455,11 +459,11 @@ module Squared
455
459
  private
456
460
 
457
461
  def pip_session(*cmd)
458
- session('pip', *cmd, path: venv.nil?)
462
+ session('pip', *cmd, *preopts, path: venv.nil?)
459
463
  end
460
464
 
461
465
  def python_session(*cmd, opts: nil)
462
- return session('python', *cmd, path: venv.nil?) unless opts
466
+ return session('python', *preopts(quiet: false), *cmd, path: venv.nil?) unless opts
463
467
 
464
468
  out = []
465
469
  opts = option_sanitize(opts, OPT_PYTHON[:common], target: out, single: /^v+$/).first
@@ -467,8 +471,16 @@ module Squared
467
471
  [ret, opts]
468
472
  end
469
473
 
474
+ def poetry_session(*cmd)
475
+ ret = session('poetry', *cmd, *preopts)
476
+ if (val = option('project', ignore: false))
477
+ ret << quote_option('project', basepath(val))
478
+ end
479
+ ret
480
+ end
481
+
470
482
  def hatch_session(*cmd, opts: nil)
471
- return session('hatch', *cmd, path: venv.nil?) unless opts
483
+ return session('hatch', *preopts, *cmd, path: venv.nil?) unless opts
472
484
 
473
485
  out = []
474
486
  opts = option_sanitize(opts, OPT_HATCH[:common], target: out, single: /^(?:v+|q+)$/).first
@@ -490,6 +502,7 @@ module Squared
490
502
  if opt =~ pat
491
503
  case $1
492
504
  when 'e', 'editable'
505
+ out << edit if edit && flag == :editable
493
506
  edit = $2
494
507
  end
495
508
  elsif flag == :editable && !edit
@@ -499,7 +512,7 @@ module Squared
499
512
  end
500
513
  end
501
514
  if edit
502
- edit = editable(edit)
515
+ edit = basepath(edit) unless %r{^[a-z]+(?:\+[a-z]+)?://}i.match?(edit)
503
516
  if flag == :editable
504
517
  out << edit
505
518
  else
@@ -518,6 +531,23 @@ module Squared
518
531
  end
519
532
  end
520
533
 
534
+ def append_editable
535
+ return if requirements?
536
+
537
+ if (val = option('editable', 'e', ignore: false))
538
+ session_delete('e', 'editable')
539
+ case val
540
+ when '0', 'false'
541
+ return
542
+ else
543
+ val = basepath(val)
544
+ end
545
+ elsif session_arg?('e', 'editable') || !(val = editable)
546
+ return
547
+ end
548
+ @session << quote_option('e', val)
549
+ end
550
+
521
551
  def append_global(target: @session)
522
552
  if (val = option('cache-dir'))
523
553
  target << case val
@@ -532,12 +562,19 @@ module Squared
532
562
  append_nocolor(target: target)
533
563
  end
534
564
 
535
- def editable(val)
536
- %r{^[a-z]+(?:\+[a-z]+)?://}i.match?(val) ? val : basepath(val)
565
+ def preopts(quiet: true)
566
+ ret = []
567
+ case verbose
568
+ when false
569
+ ret << '--quiet' if quiet
570
+ when Numeric
571
+ ret << "-#{'v' * verbose}" if verbose > 0
572
+ end
573
+ ret
537
574
  end
538
575
 
539
576
  def variables
540
- (super + %i[venv]).freeze
577
+ (super + %i[venv editable]).freeze
541
578
  end
542
579
 
543
580
  def runenv
@@ -551,7 +588,7 @@ module Squared
551
588
  end
552
589
 
553
590
  def venvbin
554
- @venv.join(workspace.windows? ? 'Scripts' : 'bin')
591
+ @venv&.join(workspace.windows? ? 'Scripts' : 'bin')
555
592
  end
556
593
 
557
594
  def venv_set(val)
@@ -574,10 +611,14 @@ module Squared
574
611
  return if !venv || (venvbin.directory? && !venvbin.empty?)
575
612
 
576
613
  puts log_message(Logger::INFO, venv, subject: 'venv', hint: 'init')
577
- cmd = python_session '-m venv', shell_option('prompt', name), '--upgrade-deps', shell_quote(venv)
614
+ cmd = session 'python', '-m venv', shell_option('prompt', name), '--upgrade-deps', shell_quote(venv)
578
615
  run(cmd, false, exception: true, banner: false)
579
616
  puts log_message(Logger::INFO, venv, subject: 'venv', hint: 'created')
580
617
  end
618
+
619
+ def requirements?
620
+ dependtype == 5
621
+ end
581
622
  end
582
623
 
583
624
  Application.implement Python
@@ -99,7 +99,7 @@ module Squared
99
99
  File.foreach(file) do |line|
100
100
  next unless line.match?(%r{\brequire\s+(["'])bundler/gem_tasks\1})
101
101
 
102
- cmd = bundle_output('exec', 'rake').to_s
102
+ cmd = bundle_output('exec rake').to_s
103
103
  @output[0] = "#{cmd} build"
104
104
  @copy = "#{cmd} install"
105
105
  @clean = "#{cmd} clean" if @clean.nil?
@@ -201,7 +201,7 @@ module Squared
201
201
  if @depend
202
202
  super
203
203
  elsif outdated?
204
- workspace.rev_clear name
204
+ workspace.rev_clear(name)
205
205
  cmd = bundle_session 'install'
206
206
  if (n = option('jobs')).to_i > 0
207
207
  cmd << "-j#{n}"
@@ -375,10 +375,7 @@ module Squared
375
375
  cmd = gem_session
376
376
  case flag
377
377
  when :outdated
378
- if (pwd = gempwd)
379
- cmd << pwd
380
- end
381
- cmd << 'outdated'
378
+ cmd << gempwd << 'outdated'
382
379
  when :push
383
380
  cmd << 'push' << project
384
381
  when :'user-install'
@@ -395,6 +392,7 @@ module Squared
395
392
  when :pristine
396
393
  first = true
397
394
  end
395
+ cmd.merge(preopts)
398
396
  opts, pat = option_sanitize(opts, list, no: no, first: first)
399
397
  out = []
400
398
  err = []
@@ -538,7 +536,7 @@ module Squared
538
536
  end
539
537
  case flag
540
538
  when 'exec', 'config'
541
- raise_error('no command given', hint: flag) if args.empty?
539
+ raise_error('no command args', hint: flag) if args.empty?
542
540
  cmd.merge(args)
543
541
  else
544
542
  option_clear args
@@ -590,7 +588,7 @@ module Squared
590
588
  if @version
591
589
  pwd = gempwd
592
590
  pwd_set(pass: !pwd.nil?) do
593
- out = `#{gem_output(pwd, 'list', '--local', '-d', project)}`
591
+ out = `#{gem_output(pwd, 'list --local -d', project)}`
594
592
  if out =~ /#{Regexp.escape(project)} \(([^)]+)\)/
595
593
  ver = $1.split(/\s*,\s*/)
596
594
  ver.unshift(@version).uniq!
@@ -653,18 +651,21 @@ module Squared
653
651
 
654
652
  def gem_session(*cmd, **kwargs)
655
653
  ret = session('gem', *cmd, **kwargs)
656
- ret << '--no-verbose' unless verbose
657
- ret
654
+ return ret if cmd.empty?
655
+
656
+ ret.merge(preopts)
658
657
  end
659
658
 
660
659
  def bundle_session(*cmd, **kwargs)
661
660
  ret = session('bundle', *cmd, **kwargs)
661
+ return ret if cmd.empty?
662
+
662
663
  append_nocolor
663
- ret
664
+ ret.merge(preopts)
664
665
  end
665
666
 
666
667
  def rake_session(*cmd, **kwargs)
667
- session('rake', *cmd, **kwargs)
668
+ session('rake', *preopts, *cmd, **kwargs)
668
669
  end
669
670
 
670
671
  def gem_output(*cmd, **kwargs)
@@ -694,6 +695,10 @@ module Squared
694
695
  @rakelist = ret
695
696
  end
696
697
 
698
+ def preopts
699
+ verbosity > 0 && !session_arg?('quiet') ? ['--verbose'] : []
700
+ end
701
+
697
702
  def gemdir?
698
703
  @gemdir.exist? && !@gemdir.empty?
699
704
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: squared
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.4.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - An Pham