squared 0.6.7 → 0.6.8

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: 73203f27b80dac94c1a96127b27afeb60d939e27adc578724264c9db26380ac0
4
- data.tar.gz: 308784d8e94aefcb5b2da4b75e6614bb94e6d1a5d66fc4754d7e72072655e588
3
+ metadata.gz: f3fd4d34940e2ce81d6aff4d5bb9ccd827c8c11f755808778c0f266fc53fbf00
4
+ data.tar.gz: 4a030838743ef95041fe4cd53a6a4491f9d5a5f89cca6dc1283c04429644cdc1
5
5
  SHA512:
6
- metadata.gz: 1f477ca8a24e892a052a2375283fbbf08af5cfc4714eaadba8c9465d59ad20e5d9bc6ae6cd624ff09780d62831cf2355918f01a851bbe09c52861d45479b1b6b
7
- data.tar.gz: 289b353519bd3d5d7b13eb6f190428c74d9f4975e176094e65ba052a1febf28b2d719210efae09768cf0c3729d03b944bfd2344bde2025705cf2b0627d6bdfeb
6
+ metadata.gz: d4e1ddf573b20ea122f1b03d0c7d14ac23542d09aac252ae5eda2185a13a1e42fc32302b82896a6ca07ec6dfcf58dfed81dc3e009f2f7b8c2b8f4ba10fddfe5c
7
+ data.tar.gz: 97bda796bfed20453137241f0f6cd98362d877fccc4674e1a1a0e615f1059ea8067d28a9f1d31e4a96b60c7fbb4011bb58ee05877e47ae3be0c41aea855bc872
data/CHANGELOG.md CHANGED
@@ -1,5 +1,46 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.6.8] - 2025-12-26
4
+
5
+ ### Added
6
+
7
+ - Ruby attribute project is extracted from Gemspec.
8
+
9
+ ### Changed
10
+
11
+ - Project base task unpack no longer hard codes any extensions.
12
+
13
+ ### Fixed
14
+
15
+ - Gem command outdated did not set bindir with update command.
16
+ - Bundler ultimately never ended up learning how to spell JIT.
17
+
18
+ ## [0.5.20] - 2025-12-26
19
+
20
+ ### Fixed
21
+
22
+ - Bundle config get method did not always discard newline.
23
+
24
+ ## [0.4.34] - 2025-12-26
25
+
26
+ ### Added
27
+
28
+ - Project public base method scope for nested tasks was created.
29
+ - Ruby task copy can autodetect "env" using [GEM_HOME|GEM_ROOT].
30
+
31
+ ### Changed
32
+
33
+ - Python virtual environment did not install poetry during initialization.
34
+
35
+ ### Fixed
36
+
37
+ - Workspace global banner never referenced the correct hash key.
38
+ - Python task depend without editable did not append context directory.
39
+ - Docker task build did not parse DOCKER_OPTIONS as command options.
40
+ - Project base method build did not call Method routines.
41
+ - Bundler autodetect did not check for valid gems directory.
42
+ - Ruby copy to version detection did not check for valid gemspec.
43
+
3
44
  ## [0.6.7] - 2025-12-07
4
45
 
5
46
  ### Added
@@ -1524,6 +1565,7 @@
1524
1565
 
1525
1566
  - Changelog was created.
1526
1567
 
1568
+ [0.6.8]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.8
1527
1569
  [0.6.7]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.7
1528
1570
  [0.6.6]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.6
1529
1571
  [0.6.5]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.5
@@ -1532,6 +1574,7 @@
1532
1574
  [0.6.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.2
1533
1575
  [0.6.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.1
1534
1576
  [0.6.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.0
1577
+ [0.5.20]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.20
1535
1578
  [0.5.19]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.19
1536
1579
  [0.5.18]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.18
1537
1580
  [0.5.17]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.17
@@ -1552,6 +1595,7 @@
1552
1595
  [0.5.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.2-ruby
1553
1596
  [0.5.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.1-ruby
1554
1597
  [0.5.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.0-ruby
1598
+ [0.4.34]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.34
1555
1599
  [0.4.33]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.33
1556
1600
  [0.4.32]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.32
1557
1601
  [0.4.31]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.31
data/README.md CHANGED
@@ -75,7 +75,7 @@ Workspace::Application
75
75
  .add("e-mc", "emc", copy: { from: "publish", scope: "@e-mc", also: [:pir, "squared-express/"] }, ref: :node) # Node
76
76
  .add("pi-r", "pir", copy: { from: "publish", scope: "@pi-r" }, clean: ["publish/**/*.js", "tmp/"]) # Trailing slash required for directories
77
77
  .add("pi-r2", "pir2", copy: { from: :npm, also: %i[squared express], files: ["LICENSE", ["README.md.ruby", "README.md"]] }) # Uses dist files from NPM package spec
78
- .add("squared", init: 'pnpm', script: ["build:stage1", "build:stage2"], group: "app") do # Use pnpm/yarn/berry for depend + Copy target (main)
78
+ .add("squared", init: "pnpm", script: ["build:stage1", "build:stage2"], group: "app") do # Use pnpm/yarn/berry for depend + Copy target (main)
79
79
  # Repo (global)
80
80
  as(:run, "build:dev", "dev") # npm run build:dev -> npm run dev
81
81
  as(:run, { "build:dev": "dev", "build:prod": "prod" })
@@ -165,7 +165,7 @@ Workspace::Application
165
165
  .each(&:join)
166
166
  }
167
167
  apply :lint, proc {
168
- bundle("exec", "-A --cache=true", with: "lint", verbose: true) # bundle exec --gemfile='/squared/Gemfile' rubocop --parallel -A --cache=true
168
+ bundle("exec", "-A --cache=true", with: "lint", verbose: true) # bundle exec --gemfile="/squared/Gemfile" rubocop --parallel -A --cache=true
169
169
  }
170
170
  end
171
171
  .with(:python, editable: false) do # ref=Symbol | group=String
@@ -567,7 +567,7 @@ Commands which use commit hashes are parsed using a ":" prefix as to not be conf
567
567
 
568
568
  ```sh
569
569
  rake squared:log:view[:af012345] # git log af012345
570
- rake squared:log:view[H1,HEAD^5,all,lib,./H12345] # git log --all @~1 @^5 -- 'lib' 'H12345'
570
+ rake squared:log:view[H1,HEAD^5,all,lib,./H12345] # git log --all @~1 @^5 -- "lib" "H12345"
571
571
  ```
572
572
 
573
573
  ## Environment
@@ -723,7 +723,7 @@ DOCKER_ALL=1 # list every image/container
723
723
  DOCKER_Y=1 # confirm all
724
724
 
725
725
  BUILD_SQUARED_OPTS="NODE_TAG=24 RUBY_VERSION=3.4.0" DOCKER_SQUARED_OPTS="--no-cache --label=v1" rake squared:build
726
- docker build --no-cache --label=v1 --build-arg='NODE_TAG=24' --build-arg='RUBY_VERSION=3.4.0' .
726
+ docker build --no-cache --label=v1 --build-arg="NODE_TAG=24" --build-arg="RUBY_VERSION=3.4.0" .
727
727
  ```
728
728
 
729
729
  | Command | Flag | ENV |
@@ -839,7 +839,8 @@ Features can be enabled through ENV when calling global tasks such as through *C
839
839
  | depend package | * | PACAKGE_LOCK|LOCKFILE=0 NO_LOCKFILE=1 Y |
840
840
  | npm pnpm | depend package | CPU=s OS=s LIBC=s |
841
841
  | npm | package | SAVE IGNORE_SCRIPTS STRICT_PEER_DEPS |
842
- | pnpm | depend | ALLOW_BUILD=s PUBLIC_HOIST_PATTERN=s |
842
+ | pnpm | depend | PUBLIC_HOIST_PATTERN=s APPROVE_BUILDS |
843
+ | pnpm | depend:add | ALLOW_BUILD=s |
843
844
  | yarn | depend package | IGNORE_ENGINES=0 |
844
845
 
845
846
  #### Python
@@ -89,7 +89,8 @@ module Squared
89
89
  k = if ch == '*'
90
90
  (min..max).to_a
91
91
  else
92
- ch.split(/\s*,\s*/).map! do |s|
92
+ ch.split(',').map! do |s|
93
+ s.strip!
93
94
  if s =~ /^(\d+)-(\d+)$/
94
95
  next unless between.call($1) && between.call($2)
95
96
 
@@ -150,6 +150,7 @@ module Squared
150
150
  end
151
151
 
152
152
  def shell_bin(name, env: true)
153
+ require_relative 'base'
153
154
  key = name.to_s.upcase
154
155
  key = File.basename(key, '.*') if Rake::Win32.windows?
155
156
  shell_quote((env && ENV["PATH_#{key}"]) || PATH[key] || PATH[key.to_sym] || name,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.6.7'
4
+ VERSION = '0.6.8'
5
5
  end
@@ -298,9 +298,9 @@ module Squared
298
298
 
299
299
  def pass(name, group: @group, ref: @ref, &blk)
300
300
  data = if group
301
- @pass[:group][group]
301
+ @pass[:group][group.to_s]
302
302
  elsif ref
303
- @pass[:ref][ref]
303
+ @pass[:ref][ref.to_sym]
304
304
  else
305
305
  @pass[:global]
306
306
  end
@@ -606,7 +606,7 @@ module Squared
606
606
  return ret if group && (ret = @banner[:group][group.to_sym])
607
607
 
608
608
  ref.reverse_each { |val| return ret if (ret = @banner[:ref][val]) }
609
- @banner[:ref][:'']
609
+ @banner[:ref][:_]
610
610
  end
611
611
 
612
612
  def enabled?
@@ -396,13 +396,12 @@ module Squared
396
396
  tag = param_guard(action, flag, args: args, key: :tag)
397
397
  dir = param_guard(action, flag, args: args, key: :dir)
398
398
  unless tag.match?(URI_SCHEME)
399
- tag = if ext == 'gem'
400
- "https://rubygems.org/downloads/#{File.basename(tag, '.gem')}.gem"
401
- elsif @release
402
- "%s.#{ext}" % [@release.include?('??') ? @release.sub('??', tag) : @release + tag]
403
- else
404
- raise_error ArgumentError, "no base uri: #{tag}", hint: ext
405
- end
399
+ tag = unpack_get tag, ext
400
+ tag ||= if @release
401
+ "%s.#{ext}" % [@release.include?('??') ? @release.sub('??', tag) : @release + tag]
402
+ else
403
+ raise_error ArgumentError, "no base uri: #{tag}", hint: ext
404
+ end
406
405
  end
407
406
  force = case (digest = args.digest)
408
407
  when 'f', 'force'
@@ -526,8 +525,14 @@ module Squared
526
525
  cmd = []
527
526
  var = {}
528
527
  args.each do |val|
529
- next instance_exec(*val[1..-1], &val.first) if val.first.is_a?(Proc)
530
-
528
+ case val.first
529
+ when Proc
530
+ instance_exec(*val[1..-1], &val.first)
531
+ next
532
+ when Method
533
+ val.first.call(*val[1..-1])
534
+ next
535
+ end
531
536
  a, b, c, d, e = val
532
537
  case b
533
538
  when Hash
@@ -862,6 +867,7 @@ module Squared
862
867
  end
863
868
  cmd << name << version
864
869
  when :exec
870
+ cmd << name unless opts.first.start_with?(/#{name}\b/)
865
871
  cmd.merge(opts)
866
872
  when :current
867
873
  cmd << '--no-header' unless legacy
@@ -961,6 +967,12 @@ module Squared
961
967
  end
962
968
  end
963
969
 
970
+ def scope(*args, **kwargs, &blk)
971
+ namespace name do
972
+ task(*args, **kwargs, &blk)
973
+ end
974
+ end
975
+
964
976
  def variable_set(key, *args, **kwargs, &blk)
965
977
  if block_given?
966
978
  if blocks.include?(key)
@@ -995,7 +1007,8 @@ module Squared
995
1007
  when :env
996
1008
  run_set(output[0], *args, **kwargs)
997
1009
  when :dependfile
998
- @dependfile = basepath(*args)
1010
+ @dependindex = nil
1011
+ @dependfile = val.nil? ? nil : basepath(*args)
999
1012
  else
1000
1013
  instance_variable_set(:"@#{key}", val)
1001
1014
  end
@@ -2008,7 +2021,9 @@ module Squared
2008
2021
 
2009
2022
  def command(*args, verbose: true)
2010
2023
  out = unless verbose
2011
- [">#{File::NULL}", '2>&1'].tap { |a| a.reverse if File::NULL == 'NUL' }.unshift('').join(' ')
2024
+ cmd = [">#{File::NULL}", '2>&1']
2025
+ cmd.reverse! if File::NULL == 'NUL'
2026
+ cmd.unshift('').join(' ')
2012
2027
  end
2013
2028
  if workspace.powershell?
2014
2029
  "#{shell_bin('powershell.exe')} -Command \"& {#{args.join(' ; ')}}\"#{out}"
@@ -2362,6 +2377,10 @@ module Squared
2362
2377
  (global && @as[from][val]) || val
2363
2378
  end
2364
2379
 
2380
+ def unpack_get(*)
2381
+ nil
2382
+ end
2383
+
2365
2384
  def task_build(keys)
2366
2385
  namespace name do
2367
2386
  ws = workspace
@@ -323,21 +323,20 @@ module Squared
323
323
  def compose(opts, flags = nil, script: false, args: nil, from: :run, **)
324
324
  return opts unless script
325
325
 
326
- ret = docker_session
327
326
  if from == :run
328
327
  if bake?(n = filetype)
329
- ret << 'buildx bake'
328
+ ret = docker_session 'buildx bake'
330
329
  append_file n
331
330
  from = :bake
332
331
  elsif compose?(n)
333
- ret << 'compose build'
332
+ ret = docker_session 'compose build'
334
333
  append_file n
335
334
  from = :compose
336
335
  else
337
- ret << 'build'
336
+ ret = docker_session 'build'
338
337
  end
339
338
  else
340
- ret << from
339
+ ret = docker_session from
341
340
  end
342
341
  case opts
343
342
  when String
@@ -1910,8 +1910,8 @@ module Squared
1910
1910
  return args ? [IO.popen(cmd), banner || '', from] : IO.popen(cmd)
1911
1911
  elsif stdin? ? sync : stdout
1912
1912
  print_item banner unless multiple
1913
- ret = `#{cmd}`
1914
- raise(ret.chomp.empty? ? $?.to_s : ret) unless $?.success?
1913
+ ret = `#{cmd}`.chomp
1914
+ raise(ret.empty? ? $?.to_s : ret) unless $?.success?
1915
1915
 
1916
1916
  if ret.empty?
1917
1917
  success?(nil, !banner.nil?)
@@ -31,7 +31,8 @@ module Squared
31
31
  use-running-store-server use-store-server child-concurrency=i hoist-pattern=q lockfile-dir=p
32
32
  modules-dir=p network-concurrency=i package-import-method=b public-hoist-pattern=q
33
33
  reporter=b].freeze,
34
- install_a: %w[global-dir ignore-scripts offline prefer-offline store-dir=p virtual-store-dir=p].freeze,
34
+ install_a: %w[dangerously-allow-all-builds global-dir ignore-scripts offline prefer-offline store-dir=p
35
+ virtual-store-dir=p].freeze,
35
36
  install_b: %w[D|dev no-optional P|prod].freeze,
36
37
  add: %w[allow-build config g|global save-catalog D|save-dev O|save-optional save-peer P|save-prod
37
38
  save-catalog-name=b].freeze,
@@ -577,6 +578,7 @@ module Squared
577
578
  '--frozen-lockfile'
578
579
  end
579
580
  cmd << '--ignore-scripts' if option('ignore-scripts')
581
+ cmd << '--dangerously-allow-all-builds' if option('approve-builds')
580
582
  else
581
583
  cmd = session 'npm'
582
584
  cmd << (ci = option('ci') ? 'ci' : 'install')
@@ -45,15 +45,15 @@ module Squared
45
45
  OPT_POETRY = {
46
46
  common: %w[ansi no-ansi no-cache n|no-interaction no-plugins q|quiet=+ v|verbose=+ P|project=p].freeze,
47
47
  build: %w[clean config-settings=qq f|format=b o|output=p].freeze,
48
- publish: %w[build dry-run skip-existing cert=p client-cert=p dist-dir=p p|password=b r|repository=q
49
- u|username=b].freeze
48
+ publish: %w[build dry-run skip-existing cert=p client-cert=p dist-dir=p p|password=q r|repository=q
49
+ u|username=qq].freeze
50
50
  }.freeze
51
51
  OPT_PDM = {
52
52
  common: %w[I|ignore-python no-cache n|non-interactive].freeze,
53
53
  build: %w[C=bm no-clean no-isolation no-sdist no-wheel q|quiet v|verbose=+ config-setting=q d|dest=p
54
54
  p|project=p k|skip=b].freeze,
55
55
  publish: %w[no-build no-very-ssl q|quiet S|sign skip-existing v|verbose=+ ca-certs=p c|comment=q d|dest=p
56
- i|identity=b P|password=q p|project=p r|repository=q k|skip=b u|username=b].freeze
56
+ i|identity=b P|password=q p|project=p r|repository=q k|skip=b u|username=qq].freeze
57
57
  }.freeze
58
58
  OPT_HATCH = {
59
59
  common: %w[color interactive no-color no-interactive cache-dir=p config=p data-dir=p e|env=b p|project=b
@@ -65,7 +65,7 @@ module Squared
65
65
  OPT_TWINE = {
66
66
  publish: %w[attestations disable-progress-bar non-interactive s|sign skip-existing verbose cert=p
67
67
  client-cert=p c|comment=q config-file=p i|identity=b p|password=q r|repository=b repository-url=q
68
- sign-with=b u|username=q].freeze
68
+ sign-with=b u|username=qq].freeze
69
69
  }.freeze
70
70
  PASS_PYTHON = {
71
71
  python: %w[c v V].freeze,
@@ -386,6 +386,7 @@ module Squared
386
386
  cmd << '--no-root' if option('no-root')
387
387
  else
388
388
  cmd = pip_session 'install'
389
+ cmd << '--upgrade-strategy=eager' if env('PYTHON_UPDATE')
389
390
  if flag
390
391
  case flag
391
392
  when :user
@@ -588,7 +589,6 @@ module Squared
588
589
  if !ENV['HATCH_BUILD_LOCATION'] && (outdir ||= op.shift)
589
590
  op.add_path(outdir)
590
591
  end
591
- op << basic_option('p', project) unless ENV['HATCH_PROJECT'] || op.arg?('p', 'project')
592
592
  else
593
593
  unless op.empty?
594
594
  args = case flag
@@ -762,17 +762,21 @@ module Squared
762
762
  end
763
763
  case key
764
764
  when :dependfile
765
- val = basepath(*args)
766
- if (index = DEP_PYTHON.index(val.basename.to_s))
767
- @dependindex = index
768
- @dependfile = val
765
+ if args.first.nil?
766
+ super
769
767
  else
770
- log.warn "variable_set: @#{key}=#{val} (not supported)"
768
+ val = basepath(*args)
769
+ if (index = DEP_PYTHON.index(val.basename.to_s))
770
+ @dependindex = index
771
+ @dependfile = val
772
+ else
773
+ log.warn "variable_set: @#{key}=#{val} (not supported)"
774
+ end
771
775
  end
772
776
  when :editable
773
777
  editable_set args.first
774
778
  when :venv
775
- instance_variable_set(:"@#{key}", (basepath(*args) unless args.empty?))
779
+ @venv = args.empty? || args.first.nil? ? nil : basepath(*args)
776
780
  else
777
781
  super
778
782
  end
@@ -797,10 +801,11 @@ module Squared
797
801
  end
798
802
 
799
803
  def python_session(*cmd, opts: nil)
800
- return session('python', *preopts(quiet: false), *cmd, path: venv.nil?) unless opts
804
+ pre = preopts(quiet: false)
805
+ return session('python', *pre, *cmd, path: venv.nil?) unless opts
801
806
 
802
807
  op = OptionPartition.new(opts, OPT_PYTHON[:common], project: self, single: singleopt(:python))
803
- [session('python', *op.to_a, *cmd, path: venv.nil?), op.extras]
808
+ [session('python', *pre, *op.to_a, *cmd, path: venv.nil?), op.extras]
804
809
  end
805
810
 
806
811
  def poetry_session(*cmd)
@@ -820,8 +825,8 @@ module Squared
820
825
  def create_session(*cmd, name:, common:, opts: nil)
821
826
  return session(name, *preopts, *cmd, path: venv.nil?) unless opts
822
827
 
823
- op = OptionPartition.new(opts, common, project: self, single: singleopt)
824
- [session(name, *op.to_a, *cmd, path: venv.nil?), op.extras]
828
+ op = OptionPartition.new(opts, common, project: self, single: singleopt(name.to_sym))
829
+ [session(name, *preopts, *op.to_a, *cmd, path: venv.nil?), op.extras]
825
830
  end
826
831
 
827
832
  def append_pip(flag, opts, target: @session, from: nil)
@@ -877,14 +882,16 @@ module Squared
877
882
  OptionPartition.delete_key(target, 'e', 'editable')
878
883
  case val
879
884
  when '0', 'false'
880
- return
885
+ return unless installable?
881
886
  else
882
887
  val = basepath val
883
888
  end
884
- elsif session_arg?('e', 'editable', target: target) || !(val = editable)
889
+ elsif session_arg?('e', 'editable', target: target) || !installable?
885
890
  return
891
+ else
892
+ val = editable
886
893
  end
887
- target << quote_option('e', basepath(val))
894
+ target << (val ? quote_option('e', basepath(val)) : '.')
888
895
  end
889
896
 
890
897
  def append_global(target: @session)
@@ -1063,9 +1070,9 @@ module Squared
1063
1070
  status = op.append(dir, delim: true)
1064
1071
  .clear(pass: false)
1065
1072
  .arg?(/\A-v+\z/)
1066
- success?(run(op, env, exception: true, banner: banner), banner, !status) do |ret|
1067
- puts(ret && dir.directory? ? "Success: #{dir}" : 'Failed')
1068
- end
1073
+ ret = run(op, env, exception: true, banner: banner)
1074
+ pip(:install, 'poetry', banner: false) if poetry?
1075
+ success?(ret, banner, !status) { |out| puts(out && dir.directory? ? "Success: #{dir}" : 'Failed') }
1069
1076
  end
1070
1077
 
1071
1078
  def pip_install?(flag)
@@ -223,6 +223,10 @@ module Squared
223
223
  end
224
224
  end
225
225
 
226
+ def project=(val)
227
+ @project = val.dup
228
+ end
229
+
226
230
  def gemdir=(val)
227
231
  @gemdir = if val.is_a?(Pathname)
228
232
  val
@@ -1064,28 +1068,27 @@ module Squared
1064
1068
  multiple: true, force: false, index: true, border: true).map! { |n| items[n.pred].last }
1065
1069
  end
1066
1070
  unless Array(update).empty?
1067
- cmd = gem_output 'update -f'
1071
+ opts = ['f']
1068
1072
  option('document', prefix: 'gem', ignore: false) do |val|
1069
- cmd << case val
1070
- when '0', 'false'
1071
- '--no-document'
1072
- else
1073
- basic_option 'document', val
1074
- end
1073
+ opts << case val
1074
+ when '0', 'false'
1075
+ 'no-document'
1076
+ else
1077
+ "document=#{val}"
1078
+ end
1075
1079
  end
1076
1080
  option('user-install', prefix: 'gem', ignore: false) do |val|
1077
- cmd << case val
1078
- when '0', 'false'
1079
- '--no-user-install'
1080
- else
1081
- '--user-install'
1082
- end
1081
+ opts << case val
1082
+ when '0', 'false'
1083
+ 'no-user-install'
1084
+ else
1085
+ 'user-install'
1086
+ end
1083
1087
  end
1084
- cmd.merge(update.quote!)
1085
1088
  if filter[:dryrun]
1086
- print_run cmd, false
1089
+ print_run gem_output('update -f', *update.quote!), false
1087
1090
  else
1088
- run(cmd, sync: sync, banner: false, from: :'gem:update')
1091
+ gem(:update, *update, opts: opts)
1089
1092
  end
1090
1093
  end
1091
1094
  print_status(*major, from: :outdated)
@@ -1154,6 +1157,9 @@ module Squared
1154
1157
  end
1155
1158
  op.append(quote: false)
1156
1159
  when :update
1160
+ if !op.arg?('n', 'bindir') && (bin = config_get('bin')) && Dir.exist?(bin)
1161
+ op << quote_option('bindir', bin)
1162
+ end
1157
1163
  if op.arg?('system')
1158
1164
  op.add_first(quote: false) { |val| val if val.match?(SEM_VER) }
1159
1165
  else
@@ -1280,7 +1286,7 @@ module Squared
1280
1286
  else
1281
1287
  flag
1282
1288
  end),
1283
- cmd, proect: self, no: OPT_BUNDLE[:no][flag], args: flag == :exec)
1289
+ cmd, project: self, no: OPT_BUNDLE[:no][flag], args: flag == :exec)
1284
1290
  op.concat(args) unless pre
1285
1291
  output = false
1286
1292
  invalid = ->(a) { raise_error ArgumentError, "unrecognized args: #{a.join(', ')}", hint: flag }
@@ -1337,7 +1343,7 @@ module Squared
1337
1343
  op.clear
1338
1344
  end
1339
1345
  when :exec
1340
- if op.empty? || (op.delete(':') && op.append(quote: false))
1346
+ if op.empty? || (op.remove(':') && op.append(quote: false))
1341
1347
  op << readline('Enter arguments', force: true)
1342
1348
  else
1343
1349
  op.append(quote: false)
@@ -1466,6 +1472,12 @@ module Squared
1466
1472
  @gemname ||= ((spec = gemspec) ? spec.name : project)
1467
1473
  end
1468
1474
 
1475
+ def project
1476
+ return @project unless @project.frozen?
1477
+
1478
+ @project = ((spec = gemspec) ? spec.name : @project).dup
1479
+ end
1480
+
1469
1481
  def depend?
1470
1482
  @depend != false && (!@depend.nil? || outdated?)
1471
1483
  end
@@ -1487,8 +1499,12 @@ module Squared
1487
1499
  pwd_set { `asdf where ruby` }.yield_self do |val|
1488
1500
  val =~ /(\d\.\d)\.[^.]+$/ && File.join(val, 'lib/ruby/gems', "#{$1}.0")
1489
1501
  end
1502
+ when 'env'
1503
+ ENV['GEM_HOME'] || ENV['GEM_ROOT']
1490
1504
  when /bundler?/
1491
- pwd_set { `bundle env` }[/^\s+Gem Path\s+([^#{File::PATH_SEPARATOR}]+)/, 1]
1505
+ pwd_set { `bundle env` }[/^\s+Gem Path\s+(.+)$/, 1].split(File::PATH_SEPARATOR).find do |val|
1506
+ Dir.exist?(val)
1507
+ end
1492
1508
  end.tap { |val| self.gemdir = val if val }
1493
1509
  rescue StandardError => e
1494
1510
  log.debug e
@@ -1498,12 +1514,11 @@ module Squared
1498
1514
  return false unless @autodetect
1499
1515
 
1500
1516
  set = lambda do |val, path|
1501
- dir = Pathname.new(path.strip) + gempath
1502
- return false unless dir.writable?
1517
+ base = Pathname.new(path.strip)
1518
+ dir = base + gempath
1519
+ return false unless dir.writable? && base.join(gempath(val, 'specification')).exist?
1503
1520
 
1504
- if (ver = version) && ver != val
1505
- log.warn "using version #{val}".subhint("given #{ver}")
1506
- end
1521
+ log.warn "using version #{val}".subhint("given #{version}") if version && version != val
1507
1522
  self.version = val
1508
1523
  self.gemdir = dir
1509
1524
  end
@@ -1511,16 +1526,15 @@ module Squared
1511
1526
  opt = gempwd
1512
1527
  pwd_set(pass: !opt.nil?) do
1513
1528
  out = `#{gem_output(opt, 'list --local -d', gemname)}`
1514
- next unless out =~ /#{Regexp.escape(gemname)} \(([^)]+)\)/
1529
+ next unless out =~ /#{Regexp.escape(gemname)}\s+\((.+)\)$/
1515
1530
 
1516
1531
  split_escape($1)
1517
1532
  .unshift(version)
1518
1533
  .uniq
1519
1534
  .each do |val|
1520
- next unless out =~ /\(#{Regexp.escape(val)}[^)]*\):([^\n]+)/
1535
+ next unless out =~ /(?:\(#{Regexp.escape(val)}[^)]*\)|Installed at):\s+(.+)$/
1521
1536
 
1522
- set.call(val, $1)
1523
- return gemdir? if gemdir
1537
+ return gemdir? if set.call(val, $1)
1524
1538
  end
1525
1539
  end
1526
1540
  self.gemdir = Pathname.new(Gem.dir) + gempath
@@ -1600,19 +1614,19 @@ module Squared
1600
1614
  end
1601
1615
 
1602
1616
  def config_get(key)
1603
- ret = if pwd_set { `#{bundle_output('config get --parseable', key)}` } =~ /\A([^=]+)=(.*)\z/ && $1 == key
1604
- $2.chomp
1605
- end
1606
- case ret
1617
+ out = pwd_set { `#{bundle_output('config get --parseable', key)}`.chomp }
1618
+ return unless out =~ /\A([^=]+)=(.*)\z/ && $1 == key
1619
+
1620
+ case (out = $2)
1607
1621
  when 'true'
1608
1622
  true
1609
1623
  when '', '[]'
1610
1624
  nil
1611
1625
  else
1612
- if ret =~ /\A\[:(.+)\]\z/
1613
- $1.split(', :').map! { |val| ((val.delete_prefix!('"') && val.delete_suffix!('"')) || val).to_sym }
1626
+ if out =~ /\A\[:(.+)\]\z/
1627
+ $1.split(', :').map { |val| ((val.delete_prefix!('"') && val.delete_suffix!('"')) || val).to_sym }
1614
1628
  else
1615
- ret || false
1629
+ out || false
1616
1630
  end
1617
1631
  end
1618
1632
  end
@@ -1621,6 +1635,12 @@ module Squared
1621
1635
  run(bundle_output('config', ('--global' if global), 'set', key, *val), banner: false, series: true)
1622
1636
  end
1623
1637
 
1638
+ def unpack_get(tag, ext)
1639
+ return super unless ext == 'gem'
1640
+
1641
+ "https://rubygems.org/downloads/#{File.basename(tag, '.gem')}.gem"
1642
+ end
1643
+
1624
1644
  def preopts
1625
1645
  verbose? ? ['--verbose'] : []
1626
1646
  end
@@ -1698,9 +1718,9 @@ module Squared
1698
1718
 
1699
1719
  def gemfile
1700
1720
  if @gemfile.nil?
1701
- @gemfile = [project, name].map! { |val| basepath("#{val}.gemspec") }
1702
- .concat(path.glob('*.gemspec'))
1703
- .find(&:exist?) || false
1721
+ @gemfile = [@project, name].map { |val| basepath("#{val}.gemspec") }
1722
+ .concat(path.glob('*.gemspec'))
1723
+ .find(&:exist?) || false
1704
1724
  end
1705
1725
  @gemfile || nil
1706
1726
  end
@@ -1714,8 +1734,10 @@ module Squared
1714
1734
  end
1715
1735
  end
1716
1736
 
1717
- def gempath(val = version)
1718
- File.join('gems', "#{gemname}-#{val}")
1737
+ def gempath(val = version, dir = 'gems')
1738
+ ret = File.join(dir, "#{gemname}-#{val}")
1739
+ ret += '.gemspec' if dir == 'specifications'
1740
+ ret
1719
1741
  end
1720
1742
 
1721
1743
  def gemdir?
@@ -173,9 +173,9 @@ module Squared
173
173
 
174
174
  def_delegators :@target, :+, :-, :<<, :any?, :none?, :include?, :add, :add?, :find, :find_all, :find_index,
175
175
  :merge, :compact, :delete, :delete?, :delete_if, :grep, :grep_v, :inspect, :to_a, :to_s
176
- def_delegators :@extras, :empty?, :each, :each_with_index, :partition, :dup, :first, :shift, :unshift,
177
- :pop, :push, :concat, :index, :join, :detect, :map, :map!, :select, :select!, :slice, :slice!,
178
- :reject, :size
176
+ def_delegators :@extras, :empty?, :member?, :each, :each_with_index, :each_with_object, :partition, :dup,
177
+ :first, :shift, :unshift, :pop, :push, :concat, :index, :join, :detect, :map, :map!, :select,
178
+ :select!, :reject, :slice, :slice!, :size
179
179
 
180
180
  def_delegator :@extras, :delete, :remove
181
181
  def_delegator :@extras, :delete_at, :remove_at
@@ -243,9 +243,8 @@ module Squared
243
243
  true
244
244
  else
245
245
  Common::Prompt.confirm(
246
- "#{log_title(:warn)} \"#{path}\" is not empty. Continue with installation?",
247
- 'N',
248
- force: true, timeout: env('REPO_TIMEOUT', 15, ignore: '0')
246
+ "#{log_title(:warn)} \"#{path}\" is not empty. Continue with installation?", 'N',
247
+ force: true, timeout: env('REPO_TIMEOUT').to_i.yield_self { |n| n > 0 ? n : 15 }
249
248
  )
250
249
  end
251
250
  end
@@ -32,7 +32,10 @@ module Squared
32
32
  end
33
33
  elsif (data = TASK_BATCH[obj])
34
34
  args.each { |ref| data.delete(ref) }
35
- TASK_KEYS.delete(obj) if data.empty?
35
+ if data.empty?
36
+ TASK_KEYS.delete(obj)
37
+ TASK_BATCH.delete(obj)
38
+ end
36
39
  end
37
40
  end
38
41
 
@@ -41,6 +44,7 @@ module Squared
41
44
  obj.each { |key, val| TASK_ALIAS[key][ref] = val }
42
45
  elsif TASK_ALIAS.key?(obj)
43
46
  TASK_ALIAS[obj].delete(ref)
47
+ TASK_ALIAS.delete(obj) if TASK_ALIAS[obj].empty?
44
48
  end
45
49
  end
46
50
 
@@ -243,7 +247,7 @@ module Squared
243
247
  end
244
248
 
245
249
  def exclude?(key, empty = false)
246
- @exclude.include?(key) || (empty && self[key].empty?)
250
+ @exclude.include?(key) || (empty && (!key?(key) || self[key].empty?))
247
251
  end
248
252
 
249
253
  private
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.6.7
4
+ version: 0.6.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - An Pham