squared 0.4.32 → 0.4.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +37 -0
- data/lib/squared/common/prompt.rb +1 -1
- data/lib/squared/common/shell.rb +1 -0
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +5 -5
- data/lib/squared/workspace/project/base.rb +25 -5
- data/lib/squared/workspace/project/docker.rb +16 -17
- data/lib/squared/workspace/project/git.rb +5 -3
- data/lib/squared/workspace/project/node.rb +3 -1
- data/lib/squared/workspace/project/python.rb +47 -47
- data/lib/squared/workspace/project/ruby.rb +44 -31
- data/lib/squared/workspace/project/support/class.rb +20 -19
- data/lib/squared/workspace/repo.rb +3 -3
- data/lib/squared/workspace/series.rb +15 -7
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0d59b575971efdb7998b924fa5ca7815c4aeaeeaeecb756197fbc79b11433743
|
|
4
|
+
data.tar.gz: 9cb428fb205f51803c0b7576b71d78165a8987925f90c04462c266bd03ca48b9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5504784e072989e9e4a25ee08aa2f8bc5b9b73d4476aa9ad5d4633b08b2546847b9945de201f964b04a52124b2e75bc2f9341321348f429e2dc9ea0c4bae3fd8
|
|
7
|
+
data.tar.gz: 73786a35bd4255024f235090cc8b11883b95efa8903e2034b8f5d13353fb7a7756ed8d8d335f42756232d595a00bf10cdafb099c3065906617575e3cd035bebf
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.4.34] - 2025-12-26
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Project public base method scope for nested tasks was created.
|
|
8
|
+
- Ruby task copy can autodetect "env" using [GEM_HOME|GEM_ROOT].
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Python virtual environment did not install poetry during initialization.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- Workspace global banner never referenced the correct hash key.
|
|
17
|
+
- Python task depend without editable did not append context directory.
|
|
18
|
+
- Docker task build did not parse DOCKER_OPTIONS as command options.
|
|
19
|
+
- Project base method build did not call Method routines.
|
|
20
|
+
- Bundler autodetect did not check for valid gems directory.
|
|
21
|
+
- Ruby copy to version detection did not check for valid gemspec.
|
|
22
|
+
|
|
23
|
+
## [0.4.33] - 2025-12-07
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- Ruby attribute setter gemdir for copy method was created.
|
|
28
|
+
- Project inline run executables binary path are replaced with global alias.
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- Workspace class Series created non-existent keys when queried.
|
|
33
|
+
- Application class did not support changing base Project class.
|
|
34
|
+
- Git command rev action build did not check build? method.
|
|
35
|
+
- Python command build action python did not use outdir option.
|
|
36
|
+
|
|
3
37
|
## [0.4.32] - 2025-11-25
|
|
4
38
|
|
|
5
39
|
### Fixed
|
|
@@ -1130,6 +1164,9 @@
|
|
|
1130
1164
|
|
|
1131
1165
|
- Changelog was created.
|
|
1132
1166
|
|
|
1167
|
+
[0.4.34]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.34
|
|
1168
|
+
[0.4.33]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.33
|
|
1169
|
+
[0.4.32]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.32
|
|
1133
1170
|
[0.4.31]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.31
|
|
1134
1171
|
[0.4.30]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.30
|
|
1135
1172
|
[0.4.29]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.29
|
|
@@ -60,7 +60,7 @@ module Squared
|
|
|
60
60
|
while (ch = Readline.readline(msg))
|
|
61
61
|
unless (ch = ch.strip).empty?
|
|
62
62
|
if multiple
|
|
63
|
-
a = ch.split(
|
|
63
|
+
a = ch.split(',').map!(&:strip)
|
|
64
64
|
b = a.select { |s| valid.call(s) }.map!(&:to_i).sort
|
|
65
65
|
next unless a.size == b.size
|
|
66
66
|
return items ? b.map! { |i| items[i - 1] } : b unless multiple.is_a?(::Numeric) && multiple != b.size
|
data/lib/squared/common/shell.rb
CHANGED
|
@@ -110,6 +110,7 @@ module Squared
|
|
|
110
110
|
end
|
|
111
111
|
|
|
112
112
|
def shell_bin(name, env: true)
|
|
113
|
+
require_relative 'base'
|
|
113
114
|
key = name.to_s.upcase
|
|
114
115
|
key = File.basename(key, '.*') if Rake::Win32.windows?
|
|
115
116
|
shell_quote((env && ENV["PATH_#{key}"]) || PATH[key] || PATH[key.to_sym] || name,
|
data/lib/squared/version.rb
CHANGED
|
@@ -274,9 +274,9 @@ module Squared
|
|
|
274
274
|
|
|
275
275
|
def pass(name, group: @group, ref: @ref, &blk)
|
|
276
276
|
data = if group
|
|
277
|
-
@pass[:group][group]
|
|
277
|
+
@pass[:group][group.to_s]
|
|
278
278
|
elsif ref
|
|
279
|
-
@pass[:ref][ref]
|
|
279
|
+
@pass[:ref][ref.to_sym]
|
|
280
280
|
else
|
|
281
281
|
@pass[:global]
|
|
282
282
|
end
|
|
@@ -336,9 +336,9 @@ module Squared
|
|
|
336
336
|
end
|
|
337
337
|
proj = ((if !ref.is_a?(Class)
|
|
338
338
|
Application.find(ref, path: path)
|
|
339
|
-
elsif ref <
|
|
339
|
+
elsif ref < Application.impl_project
|
|
340
340
|
ref
|
|
341
|
-
end) || @kind[name]&.last ||
|
|
341
|
+
end) || @kind[name]&.last || Application.impl_project).new(self, path, name, **kwargs)
|
|
342
342
|
proj.__send__(:index_set, @project.size)
|
|
343
343
|
@project[name] = proj
|
|
344
344
|
__get__(:project)[name] = proj unless kwargs[:private]
|
|
@@ -573,7 +573,7 @@ module Squared
|
|
|
573
573
|
return ret if group && (ret = @banner[:group][group.to_sym])
|
|
574
574
|
|
|
575
575
|
ref.reverse_each { |val| return ret if (ret = @banner[:ref][val]) }
|
|
576
|
-
@banner[:ref][:
|
|
576
|
+
@banner[:ref][:_]
|
|
577
577
|
end
|
|
578
578
|
|
|
579
579
|
def enabled?
|
|
@@ -460,8 +460,14 @@ module Squared
|
|
|
460
460
|
cmd = []
|
|
461
461
|
var = {}
|
|
462
462
|
args.each do |val|
|
|
463
|
-
|
|
464
|
-
|
|
463
|
+
case val.first
|
|
464
|
+
when Proc
|
|
465
|
+
instance_exec(*val[1..-1], &val.first)
|
|
466
|
+
next
|
|
467
|
+
when Method
|
|
468
|
+
val.first.call(*val[1..-1])
|
|
469
|
+
next
|
|
470
|
+
end
|
|
465
471
|
a, b, c, d, e = val
|
|
466
472
|
case b
|
|
467
473
|
when Hash
|
|
@@ -471,7 +477,7 @@ module Squared
|
|
|
471
477
|
end
|
|
472
478
|
d = append_hash(d, target: []).join(' ') if d.is_a?(Hash)
|
|
473
479
|
if a
|
|
474
|
-
cmd << [a, d, b].compact.join(' ')
|
|
480
|
+
cmd << [replace_bin(a), d, b].compact.join(' ')
|
|
475
481
|
else
|
|
476
482
|
next unless respond_to?(:compose)
|
|
477
483
|
|
|
@@ -485,7 +491,7 @@ module Squared
|
|
|
485
491
|
if cmd
|
|
486
492
|
return run_b(cmd, sync: sync, from: from) if cmd.is_a?(Proc) || cmd.is_a?(Method)
|
|
487
493
|
|
|
488
|
-
cmd = as_get(cmd, from)
|
|
494
|
+
cmd = replace_bin as_get(cmd, from)
|
|
489
495
|
opts = compose(opts, script: false) if opts && respond_to?(:compose)
|
|
490
496
|
flags = append_hash(flags, target: []).join(' ') if flags.is_a?(Hash)
|
|
491
497
|
case opts
|
|
@@ -859,6 +865,12 @@ module Squared
|
|
|
859
865
|
end
|
|
860
866
|
end
|
|
861
867
|
|
|
868
|
+
def scope(*args, **kwargs, &blk)
|
|
869
|
+
namespace name do
|
|
870
|
+
task(*args, **kwargs, &blk)
|
|
871
|
+
end
|
|
872
|
+
end
|
|
873
|
+
|
|
862
874
|
def variable_set(key, *args, **kwargs, &blk)
|
|
863
875
|
if variables.include?(key) || blocks.include?(key)
|
|
864
876
|
val = case args.size
|
|
@@ -891,7 +903,8 @@ module Squared
|
|
|
891
903
|
when :env
|
|
892
904
|
run_set(output[0], *args, **kwargs)
|
|
893
905
|
when :dependfile
|
|
894
|
-
@
|
|
906
|
+
@dependindex = nil
|
|
907
|
+
@dependfile = val.nil? ? nil : basepath(*args)
|
|
895
908
|
else
|
|
896
909
|
if block_given?
|
|
897
910
|
if blocks.include?(key)
|
|
@@ -1595,6 +1608,13 @@ module Squared
|
|
|
1595
1608
|
ret
|
|
1596
1609
|
end
|
|
1597
1610
|
|
|
1611
|
+
def replace_bin(val)
|
|
1612
|
+
a, b = val.split(' ', 2)
|
|
1613
|
+
return val if val.start_with?(/["']/) || a.include?(File::Separator)
|
|
1614
|
+
|
|
1615
|
+
[shell_bin(a), b].compact.join(' ')
|
|
1616
|
+
end
|
|
1617
|
+
|
|
1598
1618
|
def parse_json(val, kind: Hash, hint: nil)
|
|
1599
1619
|
ret = JSON.parse(val)
|
|
1600
1620
|
raise_error("invalid JSON #{kind.name}", val, hint: hint) if kind && !ret.is_a?(kind)
|
|
@@ -13,7 +13,7 @@ module Squared
|
|
|
13
13
|
buildx: {
|
|
14
14
|
common: %w[builder=b D|debug],
|
|
15
15
|
build: %w[add-host=q annotation=q attest=q build-arg=qq build-context=qq cache-from=q cache-to=q
|
|
16
|
-
cgroup-parent=b iidfile=p label=q
|
|
16
|
+
cgroup-parent=b iidfile=p label=q network=b no-cache-filter=b o|output=q platform=q
|
|
17
17
|
q|quiet secret=qq shm-size=b ssh=qq t|tag=b target=b ulimit=q].freeze,
|
|
18
18
|
bake: %w[print list=q set=q].freeze,
|
|
19
19
|
shared: %w[check load no-cache pull push allow=q call=b? f|file=p metadata-file=p progress=b provenance=q
|
|
@@ -41,14 +41,14 @@ module Squared
|
|
|
41
41
|
device-read-bps=q device-read-iops=q device-write-bps=q device-write-iops=q
|
|
42
42
|
disable-content-trust=b? dns=q dns-option=q dns-search=q domainname=b entrypoint=q e|env=qq
|
|
43
43
|
env-file=p expose=q gpus=q group-add=b health-cmd=q health-interval=b health-retries=i
|
|
44
|
-
health-start-interval=q health-start-period=q health-timeout=q
|
|
45
|
-
ip=b ip6=q ipc=b isolation=b kernel-memory=b l|label=q label-file=q link=b
|
|
46
|
-
log-driver=b log-opt=q mac-address=q m|memory=b memory-reservation=b
|
|
47
|
-
memory-swappiness=n mount=qq name=b network=b network-alias=b oom-score-adj=b
|
|
48
|
-
|
|
49
|
-
stop-timeout=i storage-opt=q sysctl=q tmpfs=q ulimit=q u|user=b userns=b uts=b
|
|
50
|
-
volume-driver=b volumes-from=b w|workdir=q].freeze,
|
|
51
|
-
run: %w[d|detach detach-keys=q
|
|
44
|
+
health-start-interval=q health-start-period=q health-timeout=q hostname=q io-maxbandwidth=b
|
|
45
|
+
io-maxiops=b ip=b ip6=q ipc=b isolation=b kernel-memory=b l|label=q label-file=q link=b
|
|
46
|
+
link-local-ip=q log-driver=b log-opt=q mac-address=q m|memory=b memory-reservation=b
|
|
47
|
+
memory-swap=n memory-swappiness=n mount=qq name=b network=b network-alias=b oom-score-adj=b
|
|
48
|
+
pid=b pids-limit=n platform=q p|publish=q pull=b restart=b runtime=b security-opt=q shm-size=b
|
|
49
|
+
stop-signal=b stop-timeout=i storage-opt=q sysctl=q tmpfs=q ulimit=q u|user=b userns=b uts=b
|
|
50
|
+
v|volume=q volume-driver=b volumes-from=b w|workdir=q].freeze,
|
|
51
|
+
run: %w[d|detach detach-keys=q sig-proxy=b?].freeze,
|
|
52
52
|
update: %w[blkio-weight=i cpu-period=i cpu-quota=i cpu-rt-period=i cpu-rt-runtime=i c|cpu-shares=i cpus=f
|
|
53
53
|
cpuset-cpus=b cpuset-mems=b m|memory=b memory-reservation=b memory-swap=b pids-limit=n
|
|
54
54
|
restart=q].freeze,
|
|
@@ -64,9 +64,9 @@ module Squared
|
|
|
64
64
|
}.freeze,
|
|
65
65
|
image: {
|
|
66
66
|
list: %w[a|all q|quiet digests no-trunc tree f|filter=q format=q].freeze,
|
|
67
|
-
push: %w[a|all-tags disable-content-trust=b? platform=
|
|
68
|
-
rm: %w[f|force no-prune platform=
|
|
69
|
-
save: %w[o|output=p platform=
|
|
67
|
+
push: %w[a|all-tags disable-content-trust=b? platform=q q|quiet].freeze,
|
|
68
|
+
rm: %w[f|force no-prune platform=q].freeze,
|
|
69
|
+
save: %w[o|output=p platform=q].freeze
|
|
70
70
|
}.freeze,
|
|
71
71
|
network: {
|
|
72
72
|
connect: %w[alias=b driver-opt=q gw-priority=n ip=b ip6=q link=b link-local-ip=q].freeze,
|
|
@@ -262,21 +262,20 @@ module Squared
|
|
|
262
262
|
def compose(opts, flags = nil, script: false, args: nil, from: :run, **)
|
|
263
263
|
return opts if script == false
|
|
264
264
|
|
|
265
|
-
ret = docker_session
|
|
266
265
|
if from == :run
|
|
267
266
|
if bake?(n = filetype)
|
|
268
|
-
ret
|
|
267
|
+
ret = docker_session 'buildx bake'
|
|
269
268
|
append_file n
|
|
270
269
|
from = :bake
|
|
271
270
|
elsif compose?(n)
|
|
272
|
-
ret
|
|
271
|
+
ret = docker_session 'compose build'
|
|
273
272
|
append_file n
|
|
274
273
|
from = :compose
|
|
275
274
|
else
|
|
276
|
-
ret
|
|
275
|
+
ret = docker_session 'build'
|
|
277
276
|
end
|
|
278
277
|
else
|
|
279
|
-
ret
|
|
278
|
+
ret = docker_session from
|
|
280
279
|
end
|
|
281
280
|
case opts
|
|
282
281
|
when String
|
|
@@ -863,6 +863,8 @@ module Squared
|
|
|
863
863
|
rev_parse(flag, ref: ref, size: size)
|
|
864
864
|
end
|
|
865
865
|
when :build
|
|
866
|
+
next unless build?
|
|
867
|
+
|
|
866
868
|
format_desc action, flag, 'opts*'
|
|
867
869
|
task flag do |_, args|
|
|
868
870
|
revbuild flag, args.to_a
|
|
@@ -1114,7 +1116,7 @@ module Squared
|
|
|
1114
1116
|
end
|
|
1115
1117
|
end
|
|
1116
1118
|
out = choice_index('Choose a stash', git_spawn('stash list', stdout: false),
|
|
1117
|
-
values: values, column: /^[^@]+@\{(\d+)\}
|
|
1119
|
+
values: values, column: /^[^@]+@\{(\d+)\}/)
|
|
1118
1120
|
if values
|
|
1119
1121
|
op.merge(out.reverse)
|
|
1120
1122
|
else
|
|
@@ -1766,7 +1768,7 @@ module Squared
|
|
|
1766
1768
|
files << "#{sub_style(b, styles: color(:red))} #{a}"
|
|
1767
1769
|
end
|
|
1768
1770
|
unless files.empty?
|
|
1769
|
-
files = choice_index('Select files', files, multiple: true,
|
|
1771
|
+
files = choice_index('Select files', files, multiple: true, trim: /^\S+\s/,
|
|
1770
1772
|
accept: [['Add?', false, true]])
|
|
1771
1773
|
end
|
|
1772
1774
|
op.swap(list + files)
|
|
@@ -1833,7 +1835,7 @@ module Squared
|
|
|
1833
1835
|
return args ? [IO.popen(cmd), banner || '', from] : IO.popen(cmd)
|
|
1834
1836
|
elsif stdin? ? sync : stdout
|
|
1835
1837
|
print_item banner unless multiple
|
|
1836
|
-
ret = `#{cmd}
|
|
1838
|
+
ret = `#{cmd}`.chomp
|
|
1837
1839
|
if !ret.empty?
|
|
1838
1840
|
puts ret
|
|
1839
1841
|
elsif success?(!banner.nil?)
|
|
@@ -27,7 +27,8 @@ module Squared
|
|
|
27
27
|
use-running-store-server use-store-server child-concurrency=i hoist-pattern=q lockfile-dir=p
|
|
28
28
|
modules-dir=p network-concurrency=i package-import-method=b public-hoist-pattern=q
|
|
29
29
|
reporter=b].freeze,
|
|
30
|
-
install_base: %w[global-dir ignore-scripts offline prefer-offline store-dir=p
|
|
30
|
+
install_base: %w[dangerously-allow-all-builds global-dir ignore-scripts offline prefer-offline store-dir=p
|
|
31
|
+
virtual-store-dir=p].freeze,
|
|
31
32
|
install_no: %w[frozen-lockfile verify-store-integrity].freeze,
|
|
32
33
|
install_as: %w[D|dev no-optional P|prod].freeze,
|
|
33
34
|
update: %w[g|global i|interactive L|latest depth=i].freeze,
|
|
@@ -448,6 +449,7 @@ module Squared
|
|
|
448
449
|
split_escape(val).each { |opt| cmd << shell_option('public-hoist-pattern', opt) }
|
|
449
450
|
end
|
|
450
451
|
cmd << '--ignore-workspace' if env('NODE_WORKSPACES', equals: '0')
|
|
452
|
+
cmd << '--dangerously-allow-all-builds' if option('approve-builds')
|
|
451
453
|
append_nocolor
|
|
452
454
|
else
|
|
453
455
|
cmd = session 'npm', 'install'
|
|
@@ -30,15 +30,15 @@ module Squared
|
|
|
30
30
|
OPT_POETRY = {
|
|
31
31
|
common: %w[ansi no-ansi no-cache n|no-interaction no-plugins q|quiet v|verbose P|project=p].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=
|
|
34
|
-
u|username=
|
|
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
35
|
}.freeze
|
|
36
36
|
OPT_PDM = {
|
|
37
37
|
common: %w[I|ignore-python no-cache n|non-interactive].freeze,
|
|
38
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
39
|
k|skip=b].freeze,
|
|
40
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=
|
|
41
|
+
i|identity=b P|password=q p|project=p r|repository=q k|skip=b u|username=qq].freeze
|
|
42
42
|
}.freeze
|
|
43
43
|
OPT_HATCH = {
|
|
44
44
|
common: %w[color interactive no-color no-interactive cache-dir=p config=p data-dir=p e|env=b p|project=b
|
|
@@ -50,7 +50,7 @@ module Squared
|
|
|
50
50
|
OPT_TWINE = {
|
|
51
51
|
publish: %w[attestations disable-progress-bar non-interactive s|sign skip-existing verbose cert=p
|
|
52
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=
|
|
53
|
+
sign-with=b u|username=qq].freeze
|
|
54
54
|
}.freeze
|
|
55
55
|
private_constant :DEP_PYTHON, :DIR_PYTHON, :OPT_PYTHON, :OPT_PIP, :OPT_POETRY, :OPT_PDM, :OPT_HATCH, :OPT_TWINE
|
|
56
56
|
|
|
@@ -78,7 +78,7 @@ module Squared
|
|
|
78
78
|
|
|
79
79
|
attr_reader :venv, :editable
|
|
80
80
|
|
|
81
|
-
def initialize(*, editable: '.',
|
|
81
|
+
def initialize(*, editable: '.', **kwargs)
|
|
82
82
|
super
|
|
83
83
|
if @pass.include?(Python.ref)
|
|
84
84
|
initialize_ref Python.ref
|
|
@@ -307,10 +307,10 @@ module Squared
|
|
|
307
307
|
next unless build_backend == 'hatchling.build'
|
|
308
308
|
end
|
|
309
309
|
format_desc(action, flag, 'opts*', after: case flag
|
|
310
|
-
when :python then 'srcdir?'
|
|
311
310
|
when :poetry then 'output?'
|
|
312
311
|
when :pdm then 'dest?'
|
|
313
312
|
when :hatch then 'location?'
|
|
313
|
+
else 'outdir?'
|
|
314
314
|
end)
|
|
315
315
|
task flag do |_, args|
|
|
316
316
|
build! flag, args.to_a
|
|
@@ -343,6 +343,7 @@ module Squared
|
|
|
343
343
|
cmd << '--no-root' if option('no-root')
|
|
344
344
|
else
|
|
345
345
|
cmd = pip_session 'install'
|
|
346
|
+
cmd << '--upgrade-strategy=eager' if env('PYTHON_UPDATE')
|
|
346
347
|
if flag
|
|
347
348
|
case flag
|
|
348
349
|
when :user
|
|
@@ -478,9 +479,6 @@ module Squared
|
|
|
478
479
|
|
|
479
480
|
def build!(flag, opts = [])
|
|
480
481
|
case flag
|
|
481
|
-
when :python
|
|
482
|
-
cmd, opts = python_session('-m build', opts: opts)
|
|
483
|
-
list = OPT_PYTHON[:build]
|
|
484
482
|
when :poetry
|
|
485
483
|
cmd = poetry_session 'build'
|
|
486
484
|
list = OPT_POETRY[:build] + OPT_POETRY[:common]
|
|
@@ -490,37 +488,31 @@ module Squared
|
|
|
490
488
|
when :hatch
|
|
491
489
|
cmd, opts = hatch_session('build', opts: opts)
|
|
492
490
|
list = OPT_HATCH[:build]
|
|
491
|
+
else
|
|
492
|
+
cmd, opts = python_session('-m build', opts: opts)
|
|
493
|
+
list = OPT_PYTHON[:build]
|
|
493
494
|
end
|
|
494
|
-
srcdir = nil
|
|
495
495
|
op = OptionPartition.new(opts, list, cmd, project: self, single: singleopt(flag))
|
|
496
|
-
op.each do |opt|
|
|
497
|
-
if !srcdir && basepath(opt.chomp('*')).exist? && projectpath?(opt.chomp('*'))
|
|
498
|
-
srcdir = opt
|
|
499
|
-
else
|
|
500
|
-
op.found << opt
|
|
501
|
-
end
|
|
502
|
-
end
|
|
503
|
-
op.swap
|
|
504
496
|
case flag
|
|
505
|
-
when :poetry, :pdm
|
|
506
|
-
if srcdir
|
|
507
|
-
args = flag == :pdm ? ['d', 'dest'] : ['o', 'output']
|
|
508
|
-
if op.arg?(*args)
|
|
509
|
-
op.push(srcdir)
|
|
510
|
-
else
|
|
511
|
-
op << quote_option(args.last, basepath(srcdir))
|
|
512
|
-
end
|
|
513
|
-
srcdir = nil
|
|
514
|
-
end
|
|
515
497
|
when :hatch
|
|
516
|
-
if ENV['HATCH_BUILD_LOCATION']
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
498
|
+
if !ENV['HATCH_BUILD_LOCATION'] && (outdir ||= op.shift)
|
|
499
|
+
op.add_path(outdir)
|
|
500
|
+
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)
|
|
520
513
|
end
|
|
521
|
-
op << basic_option('p', project) unless ENV['HATCH_PROJECT'] || op.arg?('p', 'project')
|
|
522
514
|
end
|
|
523
|
-
op.
|
|
515
|
+
op.exist?(add: true, first: true) if srcdir
|
|
524
516
|
op.clear
|
|
525
517
|
run(from: :"#{flag}:build")
|
|
526
518
|
end
|
|
@@ -581,17 +573,21 @@ module Squared
|
|
|
581
573
|
def variable_set(key, *val, **)
|
|
582
574
|
case key
|
|
583
575
|
when :dependfile
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
@dependindex = index
|
|
587
|
-
@dependfile = req
|
|
576
|
+
if val.first.nil?
|
|
577
|
+
super
|
|
588
578
|
else
|
|
589
|
-
|
|
579
|
+
req = basepath(*val)
|
|
580
|
+
if (index = DEP_PYTHON.index(req.basename.to_s))
|
|
581
|
+
@dependindex = index
|
|
582
|
+
@dependfile = req
|
|
583
|
+
else
|
|
584
|
+
log.warn "variable_set: @#{key}=#{req} (not supported)"
|
|
585
|
+
end
|
|
590
586
|
end
|
|
591
587
|
when :editable
|
|
592
588
|
editable_set val.first
|
|
593
589
|
when :venv
|
|
594
|
-
|
|
590
|
+
@venv = val.empty? || val.first.nil? ? nil : basepath(*val)
|
|
595
591
|
else
|
|
596
592
|
super
|
|
597
593
|
end
|
|
@@ -612,10 +608,11 @@ module Squared
|
|
|
612
608
|
end
|
|
613
609
|
|
|
614
610
|
def python_session(*cmd, opts: nil)
|
|
615
|
-
|
|
611
|
+
pre = preopts(quiet: false)
|
|
612
|
+
return session('python', *pre, *cmd, path: venv.nil?) unless opts
|
|
616
613
|
|
|
617
614
|
op = OptionPartition.new(opts, OPT_PYTHON[:common], project: self, single: singleopt(:python))
|
|
618
|
-
ret = session('python', *op.to_a, *cmd, path: venv.nil?)
|
|
615
|
+
ret = session('python', *pre, *op.to_a, *cmd, path: venv.nil?)
|
|
619
616
|
[ret, op.extras]
|
|
620
617
|
end
|
|
621
618
|
|
|
@@ -638,8 +635,8 @@ module Squared
|
|
|
638
635
|
def create_session(*cmd, name:, common:, opts: nil)
|
|
639
636
|
return session(name, *preopts, *cmd, path: venv.nil?) unless opts
|
|
640
637
|
|
|
641
|
-
op = OptionPartition.new(opts, common, project: self, single: singleopt)
|
|
642
|
-
ret = session(name, *op.to_a, *cmd, path: venv.nil?)
|
|
638
|
+
op = OptionPartition.new(opts, common, project: self, single: singleopt(name.to_sym))
|
|
639
|
+
ret = session(name, *preopts, *op.to_a, *cmd, path: venv.nil?)
|
|
643
640
|
[ret, op.extras]
|
|
644
641
|
end
|
|
645
642
|
|
|
@@ -693,14 +690,16 @@ module Squared
|
|
|
693
690
|
OptionPartition.delete_key(target, 'e', 'editable')
|
|
694
691
|
case val
|
|
695
692
|
when '0', 'false'
|
|
696
|
-
return
|
|
693
|
+
return unless installable?
|
|
697
694
|
else
|
|
698
695
|
val = basepath val
|
|
699
696
|
end
|
|
700
|
-
elsif session_arg?('e', 'editable', target: target) || !
|
|
697
|
+
elsif session_arg?('e', 'editable', target: target) || !installable?
|
|
701
698
|
return
|
|
699
|
+
else
|
|
700
|
+
val = editable
|
|
702
701
|
end
|
|
703
|
-
target << quote_option('e', basepath(val))
|
|
702
|
+
target << (val ? quote_option('e', basepath(val)) : '.')
|
|
704
703
|
end
|
|
705
704
|
|
|
706
705
|
def append_global(target: @session)
|
|
@@ -876,6 +875,7 @@ module Squared
|
|
|
876
875
|
.clear(pass: false)
|
|
877
876
|
status = op.arg?(/\A-v+\z/)
|
|
878
877
|
run(op, env, exception: true, banner: banner)
|
|
878
|
+
install(:upgrade, ['poetry']) if poetry?
|
|
879
879
|
puts(dir.directory? ? "Success: #{dir}" : 'Failed') if banner && !status
|
|
880
880
|
end
|
|
881
881
|
|
|
@@ -24,10 +24,10 @@ module Squared
|
|
|
24
24
|
common: %w[no-color V|verbose r|retry=i].freeze,
|
|
25
25
|
install: %w[frozen no-cache no-prune system binstubs=p? path=p standalone=q? target-rbconfig=p trust-policy=b
|
|
26
26
|
with=q without=q].freeze,
|
|
27
|
-
install_base: %w[force full-index quiet redownload gemfile=p j|jobs=i].freeze,
|
|
27
|
+
install_base: %w[force full-index local quiet redownload gemfile=p j|jobs=i].freeze,
|
|
28
28
|
update: %w[all conservative local major minor patch pre ruby strict bundler=b? g|group=q source=b].freeze,
|
|
29
|
-
outdated: %w[filter-major filter-minor filter-patch groups local parseable pre
|
|
30
|
-
update-strict group=q source=b].freeze,
|
|
29
|
+
outdated: %w[filter-major filter-minor filter-patch filter-strict groups local parseable porcelain pre
|
|
30
|
+
only-explicit strict update-strict group=q source=b].freeze,
|
|
31
31
|
exec: %w[gemfile=p].freeze,
|
|
32
32
|
cache: %w[all all-platforms frozen no-all no-install no-prune quiet cache-path=p gemfile=p path=p].freeze,
|
|
33
33
|
check: %w[dry-run gemfile=p path=p].freeze
|
|
@@ -38,7 +38,7 @@ module Squared
|
|
|
38
38
|
install_base: %w[E f w b|both clear-sources conservative default development development-all explain
|
|
39
39
|
ignore-dependencies l|local N|no-document r|remote vendor n|bindir=p build-root=p
|
|
40
40
|
B|bulk-threshold=i document=b? g|file=p? p|http-proxy=q? i|install-dir=p platform=q
|
|
41
|
-
s|source=q target-rbconfig=p? P|trust-policy=b without=
|
|
41
|
+
s|source=q target-rbconfig=p? P|trust-policy=b without=q].freeze,
|
|
42
42
|
update: %w[system=b?].freeze,
|
|
43
43
|
uninstall: %w[a D I x vendor n|bindir=p i|install-dir=p platform=b v|version=q].freeze,
|
|
44
44
|
outdated: %w[b|both clear-sources l|local r|remote B|bulk-threshold=i p|http-proxy=q? platform=q
|
|
@@ -69,7 +69,7 @@ module Squared
|
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
def bannerargs
|
|
72
|
-
%i[dependfile gemname].freeze
|
|
72
|
+
%i[dependfile gemname gemdir].freeze
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
def config?(val)
|
|
@@ -93,6 +93,8 @@ module Squared
|
|
|
93
93
|
'irb' => nil
|
|
94
94
|
})
|
|
95
95
|
|
|
96
|
+
attr_reader :gemdir
|
|
97
|
+
|
|
96
98
|
def initialize(*, autodetect: false, gemspec: nil, **kwargs)
|
|
97
99
|
super
|
|
98
100
|
if @pass.include?(Ruby.ref)
|
|
@@ -126,6 +128,14 @@ module Squared
|
|
|
126
128
|
end
|
|
127
129
|
end
|
|
128
130
|
|
|
131
|
+
def gemdir=(val)
|
|
132
|
+
@gemdir = if val.is_a?(Pathname)
|
|
133
|
+
val
|
|
134
|
+
else
|
|
135
|
+
Pathname.new(val).realdirpath rescue nil
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
129
139
|
def ref
|
|
130
140
|
Ruby.ref
|
|
131
141
|
end
|
|
@@ -241,7 +251,7 @@ module Squared
|
|
|
241
251
|
else
|
|
242
252
|
a, b, c = choice_index('Select a file', Dir.glob(file || path.join('*.rb')),
|
|
243
253
|
values: (file ? [] : ['Options']).push('Arguments'),
|
|
244
|
-
|
|
254
|
+
series: true)
|
|
245
255
|
if file
|
|
246
256
|
file = a
|
|
247
257
|
b
|
|
@@ -287,7 +297,7 @@ module Squared
|
|
|
287
297
|
end
|
|
288
298
|
end
|
|
289
299
|
|
|
290
|
-
def copy(from: gemlib, into:
|
|
300
|
+
def copy(from: gemlib, into: gemdir, override: false, **kwargs)
|
|
291
301
|
return if @copy == false
|
|
292
302
|
|
|
293
303
|
glob = kwargs[:include]
|
|
@@ -716,7 +726,7 @@ module Squared
|
|
|
716
726
|
"#{spec.name}-#{spec.version}.gem"
|
|
717
727
|
else
|
|
718
728
|
gems = Dir.glob(basepath('*.gem')).map { |val| File.basename(val) }
|
|
719
|
-
choice_index
|
|
729
|
+
choice_index 'Select a file', gems
|
|
720
730
|
end)
|
|
721
731
|
else
|
|
722
732
|
file = op.shift
|
|
@@ -844,62 +854,63 @@ module Squared
|
|
|
844
854
|
|
|
845
855
|
def copy?
|
|
846
856
|
return true if @copy.is_a?(Hash) ? copy[:into] : super
|
|
847
|
-
return gemdir? if
|
|
857
|
+
return gemdir? if gemdir
|
|
848
858
|
|
|
849
859
|
if version
|
|
850
860
|
begin
|
|
851
861
|
case @autodetect
|
|
852
862
|
when 'rvm'
|
|
853
|
-
|
|
863
|
+
self.gemdir = pwd_set { `rvm info homes` }[/^\s+gem:\s+"(.+)"$/, 1]
|
|
854
864
|
when 'rbenv'
|
|
855
865
|
if pwd_set { `rbenv which ruby` } =~ %r{^(.+[\\/]versions[\\/](\d\.\d)\.[^\\/]+)[\\/]bin[\\/]ruby$}
|
|
856
|
-
|
|
866
|
+
self.gemdir = File.join($1, 'lib/ruby/gems', "#{$2}.0")
|
|
857
867
|
end
|
|
858
868
|
when 'asdf'
|
|
859
|
-
|
|
860
|
-
|
|
869
|
+
val = pwd_set { `asdf where ruby` }
|
|
870
|
+
self.gemdir = File.join(val, 'lib/ruby/gems', "#{$1}.0") if val =~ /(\d\.\d)\.[^.]+$/
|
|
871
|
+
when 'env'
|
|
872
|
+
ENV['GEM_HOME'] || ENV['GEM_ROOT']
|
|
861
873
|
when /bundler?/
|
|
862
|
-
|
|
874
|
+
path = pwd_set { `bundle env` }[/^\s+Gem Path\s+(.+)$/, 1]
|
|
875
|
+
self.gemdir = path.split(File::PATH_SEPARATOR).find { |val| Dir.exist?(val) }
|
|
863
876
|
end
|
|
864
877
|
rescue StandardError => e
|
|
865
878
|
log.debug e
|
|
866
|
-
else
|
|
867
|
-
@gemdir = Pathname.new(@gemdir) if @gemdir
|
|
868
879
|
end
|
|
869
880
|
return true if gemdir?
|
|
870
881
|
end
|
|
871
882
|
return false unless @autodetect
|
|
872
883
|
|
|
873
884
|
set = lambda do |val, path|
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
885
|
+
base = Pathname.new(path.strip)
|
|
886
|
+
return false unless base.join(gempath(val, 'specification')).exist?
|
|
887
|
+
|
|
888
|
+
log.warn "using version #{val} (given #{version})" if version && version != val
|
|
877
889
|
self.version = val
|
|
878
|
-
|
|
890
|
+
self.gemdir = base + gempath
|
|
879
891
|
end
|
|
880
892
|
if version
|
|
881
893
|
opt = gempwd
|
|
882
894
|
pwd_set(pass: !opt.nil?) do
|
|
883
895
|
out = `#{gem_output(opt, 'list --local -d', gemname)}`
|
|
884
|
-
if out =~ /#{Regexp.escape(gemname)}
|
|
896
|
+
if out =~ /#{Regexp.escape(gemname)}\s+\((.+)\)$/
|
|
885
897
|
split_escape($1)
|
|
886
898
|
.unshift(@version)
|
|
887
899
|
.uniq
|
|
888
900
|
.each do |val|
|
|
889
|
-
next unless out =~
|
|
901
|
+
next unless out =~ /(?:\(#{Regexp.escape(val)}[^)]*\)|Installed at):\s+(.+)$/
|
|
890
902
|
|
|
891
|
-
set.call(val, $1)
|
|
892
|
-
return gemdir? if @gemdir
|
|
903
|
+
return gemdir? if set.call(val, $1)
|
|
893
904
|
end
|
|
894
905
|
end
|
|
895
906
|
end
|
|
896
|
-
|
|
907
|
+
self.gemdir = Pathname.new(Gem.dir) + gempath
|
|
897
908
|
else
|
|
898
909
|
parse = lambda do |path|
|
|
899
910
|
next unless path
|
|
900
911
|
|
|
901
912
|
lib = Regexp.new(['', 'gems', "#{gemname}-([^#{File::SEPARATOR}]+)", ''].join(File::SEPARATOR))
|
|
902
|
-
if (ver = path[lib, 1]) && (val = path[/\A(.+)#{gempath(ver
|
|
913
|
+
if (ver = path[lib, 1]) && (val = path[/\A(.+)#{Regexp.escape(gempath(ver))}/, 1])
|
|
903
914
|
set.call(ver, val)
|
|
904
915
|
end
|
|
905
916
|
end
|
|
@@ -907,7 +918,7 @@ module Squared
|
|
|
907
918
|
target = RUBY_VERSION.start_with?('2.6') ? RubyVM : $LOAD_PATH
|
|
908
919
|
parse.call(target.resolve_feature_path(gemname)&.last)
|
|
909
920
|
end
|
|
910
|
-
if
|
|
921
|
+
if !gemdir && !pwd_set { parse.call(`#{bundle_output('show', gemname)}`) }
|
|
911
922
|
raise_error 'gems directory not found'
|
|
912
923
|
end
|
|
913
924
|
end
|
|
@@ -1042,14 +1053,16 @@ module Squared
|
|
|
1042
1053
|
end
|
|
1043
1054
|
end
|
|
1044
1055
|
|
|
1045
|
-
def gempath(val = version)
|
|
1046
|
-
File.join(
|
|
1056
|
+
def gempath(val = version, dir = 'gems')
|
|
1057
|
+
ret = File.join(dir, "#{gemname}-#{val}")
|
|
1058
|
+
ret += '.gemspec' if dir == 'specifications'
|
|
1059
|
+
ret
|
|
1047
1060
|
end
|
|
1048
1061
|
|
|
1049
1062
|
def gemdir?
|
|
1050
|
-
return false unless
|
|
1063
|
+
return false unless gemdir
|
|
1051
1064
|
|
|
1052
|
-
|
|
1065
|
+
gemdir.exist? && !gemdir.empty?
|
|
1053
1066
|
end
|
|
1054
1067
|
|
|
1055
1068
|
alias read_rakefile raketasks
|
|
@@ -114,7 +114,7 @@ module Squared
|
|
|
114
114
|
|
|
115
115
|
def matchopts(list, value = false)
|
|
116
116
|
a, b = Array(list).partition { |val| val.size == 1 || val.match?(OPT_SINGLE) }
|
|
117
|
-
return /\A#{shortopt(*a)}
|
|
117
|
+
return /\A#{shortopt(*a)}/ if b.empty?
|
|
118
118
|
return /\A#{longopt(*b, value)}/ if a.empty?
|
|
119
119
|
|
|
120
120
|
/\A(?:#{shortopt(*a)}|#{longopt(*b, value)})/
|
|
@@ -135,9 +135,9 @@ module Squared
|
|
|
135
135
|
|
|
136
136
|
def_delegators :@target, :+, :-, :<<, :any?, :none?, :include?, :add, :add?, :find, :find_all, :find_index,
|
|
137
137
|
:merge, :compact, :delete, :delete?, :delete_if, :grep, :grep_v, :inspect, :to_a, :to_s
|
|
138
|
-
def_delegators :@extras, :empty?, :each, :each_with_index, :
|
|
139
|
-
:
|
|
140
|
-
:
|
|
138
|
+
def_delegators :@extras, :empty?, :member?, :each, :each_with_index, :each_with_object, :partition, :dup,
|
|
139
|
+
:first, :last, :shift, :unshift, :pop, :push, :concat, :index, :join, :map, :map!, :detect,
|
|
140
|
+
:select, :select!, :reject, :size
|
|
141
141
|
|
|
142
142
|
def_delegator :@extras, :delete, :remove
|
|
143
143
|
def_delegator :@extras, :delete_at, :remove_at
|
|
@@ -309,6 +309,7 @@ module Squared
|
|
|
309
309
|
else
|
|
310
310
|
add val
|
|
311
311
|
end
|
|
312
|
+
found << val if args.empty?
|
|
312
313
|
end
|
|
313
314
|
self
|
|
314
315
|
end
|
|
@@ -405,26 +406,26 @@ module Squared
|
|
|
405
406
|
end
|
|
406
407
|
|
|
407
408
|
def splice(*exclude, quote: true, delim: true, path: false, pattern: false, &blk)
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
unless
|
|
409
|
+
temp, other = if block_given?
|
|
410
|
+
partition(&blk)
|
|
411
|
+
elsif exclude.first.is_a?(Symbol)
|
|
412
|
+
partition(&exclude.first)
|
|
413
|
+
else
|
|
414
|
+
partition do |val|
|
|
415
|
+
next false if pattern && OptionPartition.pattern?(val)
|
|
416
|
+
|
|
417
|
+
exclude.none? { |pat| val.match?(Regexp.new(pat)) }
|
|
418
|
+
end
|
|
419
|
+
end
|
|
420
|
+
unless temp.empty?
|
|
420
421
|
add '--' if delim
|
|
421
422
|
extras.clear
|
|
422
423
|
concat other
|
|
423
424
|
if path
|
|
424
|
-
|
|
425
|
+
temp.each { |val| add_path(val) }
|
|
425
426
|
else
|
|
426
|
-
|
|
427
|
-
merge
|
|
427
|
+
temp.map! { |val| shell_quote(val) } if quote
|
|
428
|
+
merge temp
|
|
428
429
|
end
|
|
429
430
|
end
|
|
430
431
|
self
|
|
@@ -228,10 +228,10 @@ module Squared
|
|
|
228
228
|
return false unless root.directory?
|
|
229
229
|
|
|
230
230
|
path = sub_style(root, styles: theme[:inline])
|
|
231
|
+
timeout = env('REPO_TIMEOUT').to_i
|
|
232
|
+
timeout = 15 unless timeout > 0
|
|
231
233
|
@repo_override = Common::Prompt.confirm(
|
|
232
|
-
"#{log_title(:warn)} \"#{path}\" is not empty. Continue with installation? [y/N] ",
|
|
233
|
-
'N',
|
|
234
|
-
timeout: env('REPO_TIMEOUT', 15, ignore: '0')
|
|
234
|
+
"#{log_title(:warn)} \"#{path}\" is not empty. Continue with installation? [y/N] ", 'N', timeout: timeout
|
|
235
235
|
)
|
|
236
236
|
end
|
|
237
237
|
|
|
@@ -31,15 +31,19 @@ module Squared
|
|
|
31
31
|
end
|
|
32
32
|
elsif (data = TASK_BATCH[obj])
|
|
33
33
|
args.each { |ref| data.delete(ref) }
|
|
34
|
-
|
|
34
|
+
if data.empty?
|
|
35
|
+
TASK_KEYS.delete(obj)
|
|
36
|
+
TASK_BATCH.delete(obj)
|
|
37
|
+
end
|
|
35
38
|
end
|
|
36
39
|
end
|
|
37
40
|
|
|
38
41
|
def alias(ref, obj)
|
|
39
42
|
if obj.is_a?(Hash)
|
|
40
43
|
obj.each { |key, val| TASK_ALIAS[key][ref] = val }
|
|
41
|
-
|
|
42
|
-
TASK_ALIAS[obj]
|
|
44
|
+
elsif TASK_ALIAS.key?(obj)
|
|
45
|
+
TASK_ALIAS[obj].delete(ref)
|
|
46
|
+
TASK_ALIAS.delete(obj) if TASK_ALIAS[obj].empty?
|
|
43
47
|
end
|
|
44
48
|
end
|
|
45
49
|
|
|
@@ -165,6 +169,8 @@ module Squared
|
|
|
165
169
|
end
|
|
166
170
|
|
|
167
171
|
def alias_get(key)
|
|
172
|
+
return unless TASK_ALIAS.key?(key)
|
|
173
|
+
|
|
168
174
|
TASK_ALIAS[key]
|
|
169
175
|
end
|
|
170
176
|
|
|
@@ -182,12 +188,14 @@ module Squared
|
|
|
182
188
|
end
|
|
183
189
|
|
|
184
190
|
def extend?(obj, key)
|
|
185
|
-
return false unless
|
|
191
|
+
return false unless TASK_EXTEND.key?(key)
|
|
186
192
|
|
|
187
193
|
meth = :"#{key}?"
|
|
188
194
|
ret = false
|
|
189
|
-
|
|
190
|
-
|
|
195
|
+
TASK_EXTEND[key].each do |kind|
|
|
196
|
+
next unless obj.is_a?(kind)
|
|
197
|
+
|
|
198
|
+
if kind.method_defined?(meth)
|
|
191
199
|
out = obj.__send__(meth)
|
|
192
200
|
return true if out == 1
|
|
193
201
|
return out if obj.ref?(kind.ref)
|
|
@@ -228,7 +236,7 @@ module Squared
|
|
|
228
236
|
end
|
|
229
237
|
|
|
230
238
|
def exclude?(key, empty = false)
|
|
231
|
-
@exclude.include?(key) || (empty && @data[key].empty?)
|
|
239
|
+
@exclude.include?(key) || (empty && (!@data.key?(key) || @data[key].empty?))
|
|
232
240
|
end
|
|
233
241
|
|
|
234
242
|
private
|