squared 0.5.1 → 0.5.2
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 +42 -0
- data/lib/squared/common/prompt.rb +18 -6
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +19 -17
- data/lib/squared/workspace/project/base.rb +15 -10
- data/lib/squared/workspace/project/docker.rb +0 -1
- data/lib/squared/workspace/project/git.rb +17 -15
- data/lib/squared/workspace/project/python.rb +6 -3
- data/lib/squared/workspace/project/ruby.rb +8 -6
- data/lib/squared/workspace/series.rb +8 -8
- data/lib/squared/workspace.rb +8 -0
- 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: 9600e055e98f7c95c616af1a848044cb945f64597d986cad88392523a7ffb737
|
4
|
+
data.tar.gz: 255dc97b2d9738085a37fc336f43a6a835270d1ddcf28e9889712d077bc7f827
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 498761f07fcfe36010066c6e0e9c6487aaef3652214420c9d6012a61155980bc13475531416a4584641bd0a2ef909016e0f04d1224c991363050692c224f6798
|
7
|
+
data.tar.gz: 3addf62ff638f20117db50cd40a13149490401f9b97a04f19ef2a6d6e02133eea763595ee1df8239933cc68db7e6725caa29de1cb1356b4fec93a38565ccbf7e
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,42 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [0.5.2] - 2025-07-16
|
4
|
+
|
5
|
+
### Changed
|
6
|
+
|
7
|
+
- Common method choice can accept dashed ranges for selection lists.
|
8
|
+
|
9
|
+
## [0.4.15] - 2025-07-16
|
10
|
+
|
11
|
+
### Added
|
12
|
+
|
13
|
+
- Python command outdated option user was implemented.
|
14
|
+
- Git command commit action amend and amend-orig are interactive.
|
15
|
+
|
16
|
+
### Changed
|
17
|
+
|
18
|
+
- Ruby task copy does not guess Gem directory when version is used.
|
19
|
+
- Workspace hash-based data uses global method for key creation.
|
20
|
+
|
21
|
+
## [0.3.13] - 2025-07-16
|
22
|
+
|
23
|
+
### Fixed
|
24
|
+
|
25
|
+
- See `0.2.13`.
|
26
|
+
|
27
|
+
## [0.2.13] - 2025-07-16
|
28
|
+
|
29
|
+
### Fixed
|
30
|
+
|
31
|
+
- Project graph did not ignore circular references.
|
32
|
+
|
33
|
+
## [0.1.10] - 2025-07-16
|
34
|
+
|
35
|
+
### Fixed
|
36
|
+
|
37
|
+
- Module namespaces were not combined in the right order.
|
38
|
+
- Workspace group tasks were not registered.
|
39
|
+
|
3
40
|
## [0.5.1] - 2025-07-05
|
4
41
|
|
5
42
|
### Changed
|
@@ -837,8 +874,10 @@
|
|
837
874
|
|
838
875
|
- Changelog was created.
|
839
876
|
|
877
|
+
[0.5.2]: https://github.com/anpham6/squared/releases/tag/v0.5.2-ruby
|
840
878
|
[0.5.1]: https://github.com/anpham6/squared/releases/tag/v0.5.1-ruby
|
841
879
|
[0.5.0]: https://github.com/anpham6/squared/releases/tag/v0.5.0-ruby
|
880
|
+
[0.4.15]: https://github.com/anpham6/squared/releases/tag/v0.4.15-ruby
|
842
881
|
[0.4.14]: https://github.com/anpham6/squared/releases/tag/v0.4.14-ruby
|
843
882
|
[0.4.13]: https://github.com/anpham6/squared/releases/tag/v0.4.13-ruby
|
844
883
|
[0.4.12]: https://github.com/anpham6/squared/releases/tag/v0.4.12-ruby
|
@@ -854,6 +893,7 @@
|
|
854
893
|
[0.4.2]: https://github.com/anpham6/squared/releases/tag/v0.4.2-ruby
|
855
894
|
[0.4.1]: https://github.com/anpham6/squared/releases/tag/v0.4.1-ruby
|
856
895
|
[0.4.0]: https://github.com/anpham6/squared/releases/tag/v0.4.0-ruby
|
896
|
+
[0.3.13]: https://github.com/anpham6/squared/releases/tag/v0.3.13-ruby
|
857
897
|
[0.3.12]: https://github.com/anpham6/squared/releases/tag/v0.3.12-ruby
|
858
898
|
[0.3.11]: https://github.com/anpham6/squared/releases/tag/v0.3.11-ruby
|
859
899
|
[0.3.10]: https://github.com/anpham6/squared/releases/tag/v0.3.10-ruby
|
@@ -867,6 +907,7 @@
|
|
867
907
|
[0.3.2]: https://github.com/anpham6/squared/releases/tag/v0.3.2-ruby
|
868
908
|
[0.3.1]: https://github.com/anpham6/squared/releases/tag/v0.3.1-ruby
|
869
909
|
[0.3.0]: https://github.com/anpham6/squared/releases/tag/v0.3.0-ruby
|
910
|
+
[0.2.13]: https://github.com/anpham6/squared/releases/tag/v0.2.13-ruby
|
870
911
|
[0.2.12]: https://github.com/anpham6/squared/releases/tag/v0.2.12-ruby
|
871
912
|
[0.2.11]: https://github.com/anpham6/squared/releases/tag/v0.2.11-ruby
|
872
913
|
[0.2.10]: https://github.com/anpham6/squared/releases/tag/v0.2.10-ruby
|
@@ -880,6 +921,7 @@
|
|
880
921
|
[0.2.2]: https://github.com/anpham6/squared/releases/tag/v0.2.2-ruby
|
881
922
|
[0.2.1]: https://github.com/anpham6/squared/releases/tag/v0.2.1-ruby
|
882
923
|
[0.2.0]: https://github.com/anpham6/squared/releases/tag/v0.2.0-ruby
|
924
|
+
[0.1.10]: https://github.com/anpham6/squared/releases/tag/v0.1.10-ruby
|
883
925
|
[0.1.9]: https://github.com/anpham6/squared/releases/tag/v0.1.9-ruby
|
884
926
|
[0.1.8]: https://github.com/anpham6/squared/releases/tag/v0.1.8-ruby
|
885
927
|
[0.1.7]: https://github.com/anpham6/squared/releases/tag/v0.1.7-ruby
|
@@ -60,18 +60,30 @@ module Squared
|
|
60
60
|
end}] "
|
61
61
|
end
|
62
62
|
end
|
63
|
-
valid = ->(s) { s.match?(
|
63
|
+
valid = ->(s) { s.match?(/^\d+$/) && s.to_i.between?(min, max) }
|
64
64
|
Timeout.timeout(timeout) do
|
65
65
|
while (ch = Readline.readline(msg))
|
66
66
|
unless (ch = ch.strip).empty?
|
67
67
|
if multiple
|
68
68
|
a = ch.split(/\s*,\s*/)
|
69
|
-
b = a.
|
70
|
-
|
71
|
-
|
72
|
-
next if multiple.is_a?(::Numeric) && multiple != b.size
|
69
|
+
b = a.map do |s|
|
70
|
+
if s =~ /^(\d+)-(\d+)$/
|
71
|
+
next unless valid.call($1) && valid.call($2)
|
73
72
|
|
74
|
-
|
73
|
+
c = $1.to_i
|
74
|
+
d = $2.to_i
|
75
|
+
next (c..d).to_a if c < d
|
76
|
+
elsif valid.call(s)
|
77
|
+
s.to_i
|
78
|
+
end
|
79
|
+
end
|
80
|
+
unless b.include?(nil)
|
81
|
+
b.flatten!
|
82
|
+
b.uniq!
|
83
|
+
b.sort!
|
84
|
+
return b unless items
|
85
|
+
return b.map! { |i| items[i - 1] } unless multiple.is_a?(::Numeric) && multiple != b.size
|
86
|
+
end
|
75
87
|
elsif valid.call(ch)
|
76
88
|
return items ? items[ch.to_i - 1] : ch.to_i
|
77
89
|
end
|
data/lib/squared/version.rb
CHANGED
@@ -92,7 +92,7 @@ module Squared
|
|
92
92
|
@prefix = prefix
|
93
93
|
@series = Application.series_wrap(self)
|
94
94
|
@project = {}
|
95
|
-
@kind =
|
95
|
+
@kind = Workspace.hashlist
|
96
96
|
@extensions = []
|
97
97
|
@envname = env_key(@main).freeze
|
98
98
|
@pipe = env_pipe(pipe, (ARG[:OUT] && env(ARG[:OUT])) || 1, root: @home)
|
@@ -106,20 +106,20 @@ module Squared
|
|
106
106
|
else
|
107
107
|
@theme = {}
|
108
108
|
end
|
109
|
-
@chain =
|
109
|
+
@chain = Workspace.hashlist
|
110
110
|
@script = {
|
111
|
-
group:
|
112
|
-
ref:
|
111
|
+
group: Workspace.hashobj,
|
112
|
+
ref: Workspace.hashobj,
|
113
113
|
group!: {},
|
114
114
|
ref!: {}
|
115
115
|
}.freeze
|
116
116
|
@events = {
|
117
|
-
group:
|
118
|
-
ref:
|
117
|
+
group: Workspace.hashobj,
|
118
|
+
ref: Workspace.hashobj
|
119
119
|
}.freeze
|
120
120
|
@pass = {
|
121
|
-
group:
|
122
|
-
ref:
|
121
|
+
group: Workspace.hashobj,
|
122
|
+
ref: Workspace.hashobj,
|
123
123
|
global: {},
|
124
124
|
pattern: []
|
125
125
|
}.freeze
|
@@ -225,7 +225,7 @@ module Squared
|
|
225
225
|
end
|
226
226
|
end
|
227
227
|
data = Struct::ChainData.new(action, step, ns.call(with), ns.call(before), ns.call(after), sync)
|
228
|
-
|
228
|
+
@chain[task_name(task.to_s)] << data
|
229
229
|
self
|
230
230
|
end
|
231
231
|
|
@@ -267,9 +267,9 @@ module Squared
|
|
267
267
|
|
268
268
|
def pass(name, group: @group, ref: @ref, &blk)
|
269
269
|
data = if group
|
270
|
-
@pass[:group][group]
|
270
|
+
@pass[:group][group]
|
271
271
|
elsif ref
|
272
|
-
@pass[:ref][ref]
|
272
|
+
@pass[:ref][ref]
|
273
273
|
else
|
274
274
|
@pass[:global]
|
275
275
|
end
|
@@ -821,8 +821,8 @@ module Squared
|
|
821
821
|
items = as_a(ref, :to_sym)
|
822
822
|
end
|
823
823
|
items.each do |name|
|
824
|
-
|
825
|
-
|
824
|
+
@script[label][name][task] = val
|
825
|
+
@events[label][name][task] = on if on.is_a?(Hash)
|
826
826
|
end
|
827
827
|
self
|
828
828
|
end
|
@@ -839,15 +839,17 @@ module Squared
|
|
839
839
|
end
|
840
840
|
|
841
841
|
def data_get(*args, group: nil, ref: nil, target: nil)
|
842
|
-
target[:group]
|
843
|
-
|
842
|
+
if group && target[:group].key?(key = group.to_sym)
|
843
|
+
target[:group][key]
|
844
|
+
elsif ref.is_a?(Enumerable)
|
844
845
|
ref.each do |key|
|
845
|
-
next unless
|
846
|
+
next unless target[:ref].key?(key)
|
846
847
|
|
848
|
+
ret = target[:ref][key]
|
847
849
|
return ret if args.empty? || args.any? { |val| ret.key?(val) }
|
848
850
|
end
|
849
851
|
nil
|
850
|
-
elsif ref
|
852
|
+
elsif ref && target[:ref].key?(ref)
|
851
853
|
target[:ref][ref]
|
852
854
|
end
|
853
855
|
end
|
@@ -9,7 +9,6 @@ module Squared
|
|
9
9
|
module Workspace
|
10
10
|
module Project
|
11
11
|
class Base
|
12
|
-
include Comparable
|
13
12
|
include Common::Format
|
14
13
|
include System
|
15
14
|
include Shell
|
@@ -17,6 +16,7 @@ module Squared
|
|
17
16
|
include Utils
|
18
17
|
include Support
|
19
18
|
include Rake::DSL
|
19
|
+
include ::Comparable
|
20
20
|
|
21
21
|
VAR_SET = %i[parent global script index envname desc dependfile dependindex theme archive env dev prod graph
|
22
22
|
pass exclude].freeze
|
@@ -243,8 +243,13 @@ module Squared
|
|
243
243
|
end
|
244
244
|
end
|
245
245
|
|
246
|
+
def ==(other)
|
247
|
+
equal?(other)
|
248
|
+
end
|
249
|
+
|
246
250
|
def <=>(other)
|
247
|
-
return
|
251
|
+
return unless workspace == other.workspace
|
252
|
+
return 0 if equal?(other)
|
248
253
|
|
249
254
|
a, b = graph_deps
|
250
255
|
return 1 if a.include?(other)
|
@@ -272,13 +277,11 @@ module Squared
|
|
272
277
|
elsif f.any? { |val| e.include?(val) }
|
273
278
|
1
|
274
279
|
elsif @index >= 0 && (i = other.instance_variable_get(:@index)) >= 0
|
275
|
-
@index
|
276
|
-
else
|
277
|
-
0
|
280
|
+
@index <=> i
|
278
281
|
end
|
279
282
|
rescue StandardError => e
|
280
283
|
log&.debug e
|
281
|
-
|
284
|
+
nil
|
282
285
|
end
|
283
286
|
|
284
287
|
def ref
|
@@ -1142,7 +1145,7 @@ module Squared
|
|
1142
1145
|
done
|
1143
1146
|
end
|
1144
1147
|
|
1145
|
-
def graph_collect(target, start = [], data: {}, pass: [])
|
1148
|
+
def graph_collect(target, start = [], data: {}, pass: [], root: [])
|
1146
1149
|
deps = []
|
1147
1150
|
(start.empty? ? target.instance_variable_get(:@graph) : start)&.each do |val|
|
1148
1151
|
next if pass.include?(val)
|
@@ -1155,10 +1158,12 @@ module Squared
|
|
1155
1158
|
items = workspace.find(group: val, ref: val.to_sym)
|
1156
1159
|
end
|
1157
1160
|
items.each do |proj|
|
1158
|
-
next if pass.include?(proj.name)
|
1161
|
+
next if pass.include?(name = proj.name)
|
1159
1162
|
|
1160
|
-
|
1161
|
-
|
1163
|
+
if proj.graph? && !data.key?(name) && !root.include?(name)
|
1164
|
+
graph_collect(proj, data: data, pass: pass, root: root + [name, target.name])
|
1165
|
+
end
|
1166
|
+
next if (objs = data.fetch(name, [])).include?(target)
|
1162
1167
|
|
1163
1168
|
deps << proj
|
1164
1169
|
deps.concat(objs)
|
@@ -266,7 +266,6 @@ module Squared
|
|
266
266
|
when Enumerable
|
267
267
|
ret.merge(opts.to_a)
|
268
268
|
end
|
269
|
-
|
270
269
|
[args, flags].each_with_index do |target, index|
|
271
270
|
if (data = append_any(target, target: []))
|
272
271
|
ret.merge(data.map { |arg| index == 0 ? fill_option(arg) : quote_option('build-arg', arg) })
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Squared
|
4
4
|
module Workspace
|
5
5
|
module Git
|
6
|
-
GIT_REPO =
|
6
|
+
GIT_REPO = Workspace.hashobj
|
7
7
|
GIT_PROTO = %r{^(?:https?|ssh|git|file)://}i.freeze
|
8
8
|
private_constant :GIT_REPO, :GIT_PROTO
|
9
9
|
|
@@ -58,8 +58,8 @@ module Squared
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
key = task_name key
|
61
|
-
|
62
|
-
|
61
|
+
GIT_REPO[main][key] = [uri.to_s, opts]
|
62
|
+
@kind[key] << Project::Git
|
63
63
|
end
|
64
64
|
if cache == true
|
65
65
|
revbuild
|
@@ -399,12 +399,12 @@ module Squared
|
|
399
399
|
if flag == :fixup
|
400
400
|
ref, squash, pick = choice_commit(accept: [['Auto squash?', true]], reflog: false,
|
401
401
|
values: ['Pick [amend|reword]'])
|
402
|
-
pick
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
402
|
+
pick &&= case pick.downcase
|
403
|
+
when 'a', 'amend'
|
404
|
+
'amend'
|
405
|
+
when 'r', 'reword'
|
406
|
+
'reword'
|
407
|
+
end
|
408
408
|
if squash
|
409
409
|
found = false
|
410
410
|
git_spawn(git_output('log --format=%h'), stdout: false).each do |val|
|
@@ -416,12 +416,14 @@ module Squared
|
|
416
416
|
end
|
417
417
|
end
|
418
418
|
end
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
419
|
+
opts = []
|
420
|
+
refs = []
|
421
|
+
unless pick == 'reword'
|
422
|
+
if flag == :add
|
423
|
+
opts = param_guard(action, flag, args: args.to_a)
|
424
|
+
elsif (refs = args.to_a).empty?
|
425
|
+
refs = readline('Enter file patterns', force: true).shellsplit
|
426
|
+
end
|
425
427
|
end
|
426
428
|
commit(flag, opts, refs: refs, ref: ref, squash: squash, pick: pick)
|
427
429
|
end
|
@@ -280,7 +280,7 @@ module Squared
|
|
280
280
|
end
|
281
281
|
end
|
282
282
|
when 'outdated'
|
283
|
-
format_desc action, flag, 'eager?'
|
283
|
+
format_desc action, flag, 'eager?,user?'
|
284
284
|
task flag do |_, args|
|
285
285
|
outdated flag, args.to_a
|
286
286
|
end
|
@@ -431,7 +431,9 @@ module Squared
|
|
431
431
|
when :patch
|
432
432
|
patch
|
433
433
|
end
|
434
|
-
|
434
|
+
unless !pkg || pkg.empty?
|
435
|
+
install(:upgrade, pkg, strategy: opts.include?('eager') ? 'eager' : nil, user: opts.include?('user'))
|
436
|
+
end
|
435
437
|
elsif start == 0
|
436
438
|
puts 'No updates were found'
|
437
439
|
end
|
@@ -439,7 +441,7 @@ module Squared
|
|
439
441
|
on :last, :outdated
|
440
442
|
end
|
441
443
|
|
442
|
-
def install(flag, opts = [], strategy: nil)
|
444
|
+
def install(flag, opts = [], strategy: nil, user: nil)
|
443
445
|
cmd = pip_session 'install'
|
444
446
|
out = append_pip(flag, opts, from: :install)
|
445
447
|
case flag
|
@@ -449,6 +451,7 @@ module Squared
|
|
449
451
|
when :upgrade
|
450
452
|
raise_error('no packages listed', hint: flag) if out.empty?
|
451
453
|
cmd << '--upgrade'
|
454
|
+
cmd << '--user' if user
|
452
455
|
cmd << basic_option('upgrade-strategy', strategy) if strategy
|
453
456
|
append_value out
|
454
457
|
end
|
@@ -4,7 +4,7 @@ module Squared
|
|
4
4
|
module Workspace
|
5
5
|
module Project
|
6
6
|
class Ruby < Git
|
7
|
-
GEMFILE = %w[Gemfile Gemfile.lock gem.deps.rb Isolate].freeze
|
7
|
+
GEMFILE = %w[Gemfile Gemfile.lock gem.deps.rb gems.rb Isolate].freeze
|
8
8
|
DIR_RUBY = (GEMFILE + Rake::Application::DEFAULT_RAKEFILES + ['README.rdoc']).freeze
|
9
9
|
OPT_RUBY = {
|
10
10
|
ruby: %w[0=im? a c e=q E=bm F=qm i=bm? I=pm l n p r=bm s S w W=bm? x=pm? d|debug jit rjit v|verbose y|yydebug
|
@@ -856,12 +856,13 @@ module Squared
|
|
856
856
|
next unless out =~ /\(#{Regexp.escape(val)}(?:,[^)]+|\b)\):([^\n]+)/
|
857
857
|
|
858
858
|
set.call(val, $1)
|
859
|
-
|
859
|
+
return gemdir? if @gemdir
|
860
860
|
end
|
861
861
|
end
|
862
862
|
end
|
863
|
-
|
864
|
-
|
863
|
+
require 'rubygems'
|
864
|
+
@gemdir = Pathname.new(Gem.dir) + gempath
|
865
|
+
else
|
865
866
|
parse = lambda do |path|
|
866
867
|
next unless path
|
867
868
|
|
@@ -874,9 +875,10 @@ module Squared
|
|
874
875
|
target = RUBY_VERSION.start_with?('2.6') ? RubyVM : $LOAD_PATH
|
875
876
|
parse.call(target.resolve_feature_path(project)&.last)
|
876
877
|
end
|
877
|
-
pwd_set { parse.call(`#{bundle_output('show', project)}`) }
|
878
|
+
if !@gemdir && !pwd_set { parse.call(`#{bundle_output('show', project)}`) }
|
879
|
+
raise_error 'gems directory not found'
|
880
|
+
end
|
878
881
|
end
|
879
|
-
raise_error('parse failed', hint: @version || 'path') unless @gemdir
|
880
882
|
rescue StandardError => e
|
881
883
|
log.error e
|
882
884
|
@version = nil
|
@@ -10,16 +10,16 @@ module Squared
|
|
10
10
|
|
11
11
|
TASK_BASE = []
|
12
12
|
TASK_BATCH = {}
|
13
|
-
TASK_EXTEND =
|
13
|
+
TASK_EXTEND = Workspace.hashlist
|
14
14
|
TASK_KEYS = []
|
15
|
-
TASK_ALIAS =
|
15
|
+
TASK_ALIAS = Workspace.hashobj
|
16
16
|
TASK_NAME = {}
|
17
17
|
private_constant :TASK_BASE, :TASK_BATCH, :TASK_EXTEND, :TASK_KEYS, :TASK_ALIAS, :TASK_NAME
|
18
18
|
|
19
19
|
class << self
|
20
20
|
def add(task, obj)
|
21
21
|
key_set task
|
22
|
-
|
22
|
+
TASK_EXTEND[task] << obj
|
23
23
|
end
|
24
24
|
|
25
25
|
def batch(*args, obj)
|
@@ -37,7 +37,7 @@ module Squared
|
|
37
37
|
|
38
38
|
def alias(ref, obj)
|
39
39
|
if obj.is_a?(Hash)
|
40
|
-
obj.each { |key, val|
|
40
|
+
obj.each { |key, val| TASK_ALIAS[key][ref] = val }
|
41
41
|
else
|
42
42
|
TASK_ALIAS[obj]&.delete(ref)
|
43
43
|
end
|
@@ -79,8 +79,8 @@ module Squared
|
|
79
79
|
@chain = {}
|
80
80
|
@exclude = exclude.freeze
|
81
81
|
@session = {
|
82
|
-
group:
|
83
|
-
parent:
|
82
|
+
group: Workspace.hashlist,
|
83
|
+
parent: Workspace.hashlist,
|
84
84
|
id: []
|
85
85
|
}
|
86
86
|
@data = {}
|
@@ -95,7 +95,7 @@ module Squared
|
|
95
95
|
|
96
96
|
if (g = proj.group)
|
97
97
|
id << g
|
98
|
-
|
98
|
+
group[:"#{key}:#{g}"].concat(tasks)
|
99
99
|
else
|
100
100
|
items.concat(tasks)
|
101
101
|
end
|
@@ -106,7 +106,7 @@ module Squared
|
|
106
106
|
next unless (b = ws.find_base(proj)) && (n = b.ref.to_s) != g
|
107
107
|
|
108
108
|
id << n
|
109
|
-
|
109
|
+
parent[:"#{key}:#{n}"].concat(tasks)
|
110
110
|
end
|
111
111
|
end
|
112
112
|
|
data/lib/squared/workspace.rb
CHANGED