squared 0.4.7 → 0.4.9
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 +106 -1
- data/README.ruby.md +57 -28
- data/lib/squared/common/base.rb +1 -0
- data/lib/squared/common/class.rb +19 -1
- data/lib/squared/common/format.rb +35 -38
- data/lib/squared/common/prompt.rb +66 -3
- data/lib/squared/common/shell.rb +30 -19
- data/lib/squared/common/system.rb +3 -3
- data/lib/squared/common/utils.rb +11 -10
- data/lib/squared/config.rb +4 -5
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +46 -34
- data/lib/squared/workspace/project/base.rb +191 -70
- data/lib/squared/workspace/project/docker.rb +79 -40
- data/lib/squared/workspace/project/git.rb +742 -392
- data/lib/squared/workspace/project/node.rb +35 -51
- data/lib/squared/workspace/project/python.rb +42 -48
- data/lib/squared/workspace/project/ruby.rb +316 -100
- data/lib/squared/workspace/project/support/class.rb +37 -19
- data/lib/squared/workspace/repo.rb +10 -12
- data/lib/squared/workspace/series.rb +11 -7
- data/lib/squared/workspace.rb +2 -9
- metadata +3 -3
@@ -16,10 +16,10 @@ module Squared
|
|
16
16
|
include Prompt
|
17
17
|
|
18
18
|
def append(target, *args, delim: false, escape: false, quote: true)
|
19
|
-
return if args.empty?
|
19
|
+
return if (ret = args.flatten).empty?
|
20
20
|
|
21
21
|
target << '--' if delim && !target.include?('--')
|
22
|
-
ret
|
22
|
+
ret.map! { |val| escape ? shell_escape(val, quote: quote) : shell_quote(val) } if escape || quote
|
23
23
|
if target.is_a?(Set)
|
24
24
|
target.merge(ret)
|
25
25
|
else
|
@@ -35,18 +35,25 @@ module Squared
|
|
35
35
|
kwargs[:hint] ||= 'unrecognized'
|
36
36
|
append(target, opts, delim: true) if kwargs.delete(:append)
|
37
37
|
warn log_message(Logger::WARN, opts.join(', '), pass: true, **kwargs)
|
38
|
-
return if pass || confirm("Run? [#{sub_style(target, styles: styles)}] [y/N] ", 'N'
|
38
|
+
return if pass || confirm("Run? [#{sub_style(target, styles: styles)}] [y/N] ", 'N')
|
39
39
|
|
40
40
|
raise_error 'user cancelled'
|
41
41
|
end
|
42
42
|
|
43
|
+
def strip(val)
|
44
|
+
return [] unless val
|
45
|
+
|
46
|
+
val = shell_split(val) if val.is_a?(String)
|
47
|
+
val.map { |s| s.sub(/\A-([a-z\d])(.+)\z/mi, '\1=\2').sub(/\A--?/, '') }.reject(&:empty?)
|
48
|
+
end
|
49
|
+
|
43
50
|
def arg?(target, *args, value: false)
|
44
51
|
r, s = args.partition { |val| val.is_a?(Regexp) }
|
45
52
|
unless s.empty?
|
46
53
|
s.map! { |val| Regexp.escape(shell_option(val)) }
|
47
54
|
r << /\A(?:#{s.join('|')})#{value ? '[ =].' : '(?: |=|\z)'}/
|
48
55
|
end
|
49
|
-
target.any? { |opt| r.any? { |val| opt
|
56
|
+
target.any? { |opt| r.any? { |val| opt&.match?(val) } }
|
50
57
|
end
|
51
58
|
end
|
52
59
|
|
@@ -66,7 +73,7 @@ module Squared
|
|
66
73
|
parse(list, opts, **kwargs, &blk)
|
67
74
|
end
|
68
75
|
|
69
|
-
def parse(list, opts = extras, no: nil, single: nil, args: false, first:
|
76
|
+
def parse(list, opts = extras, no: nil, single: nil, args: false, first: nil, &blk)
|
70
77
|
@extras = []
|
71
78
|
@values = []
|
72
79
|
bare = []
|
@@ -79,8 +86,8 @@ module Squared
|
|
79
86
|
i = []
|
80
87
|
f = []
|
81
88
|
si = []
|
82
|
-
list.
|
83
|
-
x, y = val.split('|')
|
89
|
+
list.flat_map do |val|
|
90
|
+
x, y = val.split('|', 2)
|
84
91
|
if y
|
85
92
|
if (n = val.index('='))
|
86
93
|
x += val[n..-1]
|
@@ -90,7 +97,6 @@ module Squared
|
|
90
97
|
x
|
91
98
|
end
|
92
99
|
end
|
93
|
-
.flatten
|
94
100
|
.each do |val|
|
95
101
|
if (n = val.index('='))
|
96
102
|
flag = val[0, n]
|
@@ -117,6 +123,7 @@ module Squared
|
|
117
123
|
else
|
118
124
|
next
|
119
125
|
end
|
126
|
+
m << flag if val[n + 2] == 'm'
|
120
127
|
bare << flag if val.end_with?('?')
|
121
128
|
else
|
122
129
|
bare << val
|
@@ -124,6 +131,12 @@ module Squared
|
|
124
131
|
end
|
125
132
|
no = (no || []).map { |val| (n = val.index('=')) ? val[0, n] : val }
|
126
133
|
bare.concat(no)
|
134
|
+
numtype = [
|
135
|
+
[i, /\A\d+\z/],
|
136
|
+
[f, /\A\d*(?:\.\d+)?\z/],
|
137
|
+
[si, /\A-?\d+\z/]
|
138
|
+
].freeze
|
139
|
+
numcheck = ->(k, v) { numtype.any? { |flag, pat| flag.include?(k) && pat.match?(v) } }
|
127
140
|
skip = false
|
128
141
|
opts.each do |opt|
|
129
142
|
next @extras << opt if skip
|
@@ -138,17 +151,17 @@ module Squared
|
|
138
151
|
if opt =~ /\A([^=]+)=(.+)\z/
|
139
152
|
key = $1
|
140
153
|
val = $2
|
141
|
-
|
154
|
+
merge = m.include?(key)
|
142
155
|
if e.include?(key)
|
143
|
-
target << shell_option(key, val)
|
156
|
+
target << shell_option(key, val, merge: merge)
|
144
157
|
elsif q.include?(key)
|
145
|
-
target << quote_option(key, val, double: qq.include?(key))
|
158
|
+
target << quote_option(key, val, double: qq.include?(key), merge: merge)
|
146
159
|
elsif p.include?(key) && path
|
147
|
-
target << quote_option(key, path
|
148
|
-
elsif
|
160
|
+
target << quote_option(key, path + val, merge: merge)
|
161
|
+
elsif b.include?(key) || numcheck.call(key, val)
|
162
|
+
target << basic_option(key, val, merge: merge)
|
163
|
+
elsif merge
|
149
164
|
target << basic_option(key, val, merge: true)
|
150
|
-
elsif b.include?(key) || match.(i, /^\d+$/) || match.(f, /^\d*(?:\.\d+)?$/) || match.(si, /^-?\d+$/)
|
151
|
-
target << basic_option(key, val)
|
152
165
|
else
|
153
166
|
@extras << opt
|
154
167
|
end
|
@@ -157,10 +170,10 @@ module Squared
|
|
157
170
|
@extras << opt
|
158
171
|
skip = true if args
|
159
172
|
end
|
160
|
-
skip = true if first
|
173
|
+
skip = true if first&.any? { |s| s.is_a?(Regexp) ? opt.match?(s) : !opt.include?(s) }
|
161
174
|
end
|
162
175
|
end
|
163
|
-
@values = @values.empty? ? /\A\s+\z/ : /\A(#{@values.join('|')})=(.+)\z/
|
176
|
+
@values = @values.empty? ? /\A\s+\z/ : /\A(#{@values.join('|')})=(.+)\z/m
|
164
177
|
@extras.each_with_index(&blk) if block_given?
|
165
178
|
self
|
166
179
|
end
|
@@ -179,9 +192,14 @@ module Squared
|
|
179
192
|
self
|
180
193
|
end
|
181
194
|
|
182
|
-
def clear(opts = nil, **kwargs)
|
183
|
-
opts ||= (kwargs[:errors] ? errors : extras)
|
195
|
+
def clear(opts = nil, errors: false, **kwargs)
|
184
196
|
styles = project.theme[:inline] if project
|
197
|
+
if !opts
|
198
|
+
opts = errors ? @errors : @extras
|
199
|
+
elsif errors
|
200
|
+
OptionPartition.clear(target, @errors, styles: styles, **kwargs)
|
201
|
+
@errors.clear
|
202
|
+
end
|
185
203
|
OptionPartition.clear(target, opts.reject { |val| found.include?(val) }, styles: styles, **kwargs)
|
186
204
|
opts.clear
|
187
205
|
self
|
@@ -3,12 +3,10 @@
|
|
3
3
|
module Squared
|
4
4
|
module Workspace
|
5
5
|
module Repo
|
6
|
-
include Common::Format
|
7
|
-
|
8
6
|
class << self
|
9
7
|
def read_manifest(path)
|
10
8
|
require 'rexml/document'
|
11
|
-
return unless (file = path
|
9
|
+
return unless (file = path + '.repo/manifest.xml').exist?
|
12
10
|
|
13
11
|
doc = REXML::Document.new(file.read)
|
14
12
|
doc.elements['manifest/include'].attributes['name']&.sub('.xml', '')
|
@@ -41,12 +39,12 @@ module Squared
|
|
41
39
|
raise_error("path does not exist: #{val}", hint: 'REPO_ROOT') unless repo_confirm
|
42
40
|
end
|
43
41
|
@root.join(main).realdirpath
|
44
|
-
elsif repo_install?(parent: true) && (!@home.exist? || @root
|
42
|
+
elsif repo_install?(parent: true) && (!@home.exist? || @root + main == @home)
|
45
43
|
@home
|
46
44
|
elsif repo_install?(@home)
|
47
|
-
@home
|
45
|
+
@home + main
|
48
46
|
else
|
49
|
-
(path = pwd) == @home || !repo_install?(path) ? @home : path
|
47
|
+
(path = pwd) == @home || !repo_install?(path) ? @home : path + main
|
50
48
|
end
|
51
49
|
@root = @home.parent
|
52
50
|
@manifest_url = url
|
@@ -149,9 +147,9 @@ module Squared
|
|
149
147
|
end
|
150
148
|
end
|
151
149
|
|
152
|
-
desc.('all[{0}]')
|
150
|
+
desc.call('all[{0}]')
|
153
151
|
task 'all', [:opts] do |_, args|
|
154
|
-
parse_opts.(args)
|
152
|
+
parse_opts.call(args)
|
155
153
|
stage ||= 'all'
|
156
154
|
repo['sync'].invoke
|
157
155
|
next if env('REPO_DRYRUN', equals: '2')
|
@@ -174,21 +172,21 @@ module Squared
|
|
174
172
|
end
|
175
173
|
end
|
176
174
|
|
177
|
-
desc.("init[manifest?=#{target},{0}]", target)
|
175
|
+
desc.call("init[manifest?=#{target},{0}]", target)
|
178
176
|
task 'init', [:manifest, :opts] do |_, args|
|
179
|
-
parse_opts.(args)
|
177
|
+
parse_opts.call(args)
|
180
178
|
stage = 'init'
|
181
179
|
puts if newline
|
182
180
|
system("repo init -u #{env('REPO_URL') || manifest_url} -m #{args.manifest || target}.xml", chdir: root)
|
183
181
|
repo['all'].invoke
|
184
182
|
end
|
185
183
|
|
186
|
-
desc.('sync[{0}]')
|
184
|
+
desc.call('sync[{0}]')
|
187
185
|
task 'sync', [:opts] do |_, args|
|
188
186
|
unless branch || stage == 'init'
|
189
187
|
raise_error('repo not initialized', hint: task_name('repo:init'), kind: LoadError)
|
190
188
|
end
|
191
|
-
parse_opts.(args)
|
189
|
+
parse_opts.call(args)
|
192
190
|
cmd << "-j#{ENV.fetch('REPO_JOBS', Rake::CpuCounter.count)}"
|
193
191
|
cmd << '--fail-fast' if failfast
|
194
192
|
puts if newline && stage != 'init'
|
@@ -71,11 +71,12 @@ module Squared
|
|
71
71
|
def_delegators :@data, :[], :each, :each_key, :keys, :fetch, :to_a, :to_s, :inspect, :merge!, :key?
|
72
72
|
def_delegators :@workspace, :task_desc, :task_name, :task_namespace, :task_join, :format_desc
|
73
73
|
|
74
|
-
def initialize(workspace)
|
74
|
+
def initialize(workspace, exclude: [])
|
75
75
|
@workspace = workspace
|
76
76
|
@sync = []
|
77
77
|
@multiple = []
|
78
78
|
@parallel = []
|
79
|
+
@exclude = exclude.freeze
|
79
80
|
@session = {
|
80
81
|
group: {},
|
81
82
|
parent: {},
|
@@ -89,7 +90,7 @@ module Squared
|
|
89
90
|
group, parent, id = @session.values
|
90
91
|
ws = proj.workspace
|
91
92
|
@data.each do |key, items|
|
92
|
-
next if (tasks = ws.task_resolve(proj, key)).empty?
|
93
|
+
next if exclude?(key) || (tasks = ws.task_resolve(proj, key)).empty?
|
93
94
|
|
94
95
|
if (g = proj.group)
|
95
96
|
id << g
|
@@ -113,13 +114,13 @@ module Squared
|
|
113
114
|
@data.merge!(@session[:parent]) if @session[:id].uniq.size > 1
|
114
115
|
@data.merge!(@session[:group])
|
115
116
|
@data.each do |key, items|
|
116
|
-
next if
|
117
|
+
next if exclude?(key, true) || @workspace.task_exclude?(t = name_get(key))
|
117
118
|
|
118
|
-
key = task_name
|
119
|
+
key = task_name t
|
119
120
|
val = format_desc(key, out: true)
|
120
121
|
if items.size > 1
|
121
122
|
@multiple << key
|
122
|
-
if parallel.include?(t) || pattern.any? { |pat| t.match?(pat) } || subcheck.(t)
|
123
|
+
if parallel.include?(t) || pattern.any? { |pat| t.match?(pat) } || subcheck.call(t)
|
123
124
|
task_desc("#{val} (thread)", name: key)
|
124
125
|
multitask key => items
|
125
126
|
@parallel << key
|
@@ -167,14 +168,13 @@ module Squared
|
|
167
168
|
return false unless (items = TASK_EXTEND[key]) && !(items = items.select { |kind| obj.is_a?(kind) }).empty?
|
168
169
|
|
169
170
|
meth = :"#{key}?"
|
170
|
-
allref = obj.allref.to_a
|
171
171
|
ret = false
|
172
172
|
items.each do |kind|
|
173
173
|
if kind.instance_methods.include?(meth)
|
174
174
|
out = obj.__send__(meth)
|
175
175
|
return true if out == 1
|
176
176
|
return out if obj.ref?(kind.ref)
|
177
|
-
elsif
|
177
|
+
elsif obj.ref?(kind.ref)
|
178
178
|
ret = true
|
179
179
|
end
|
180
180
|
end
|
@@ -199,6 +199,10 @@ module Squared
|
|
199
199
|
already_invoked?(parallel, val)
|
200
200
|
end
|
201
201
|
|
202
|
+
def exclude?(key, empty = false)
|
203
|
+
@exclude.include?(key) || (empty && @data[key].empty?)
|
204
|
+
end
|
205
|
+
|
202
206
|
private
|
203
207
|
|
204
208
|
def already_invoked?(list, val)
|
data/lib/squared/workspace.rb
CHANGED
@@ -10,15 +10,14 @@ module Squared
|
|
10
10
|
if id.is_a?(Symbol)
|
11
11
|
project id
|
12
12
|
else
|
13
|
-
|
14
|
-
__get__(:project).find { |_, val| val.path.to_s == id.to_s }
|
13
|
+
__get__(:project).find { |_, val| File.expand_path(val.path) == File.expand_path(id) }
|
15
14
|
end
|
16
15
|
end
|
17
16
|
ret.size == 1 ? ret.first : ret
|
18
17
|
end
|
19
18
|
|
20
19
|
def expect(name)
|
21
|
-
ret = project
|
20
|
+
ret = project name
|
22
21
|
return ret if ret&.path&.directory?
|
23
22
|
|
24
23
|
raise NoMethodError, "project is not initialized (#{name})"
|
@@ -33,12 +32,6 @@ module Squared
|
|
33
32
|
def project(name)
|
34
33
|
__get__(:project)[name.to_s]
|
35
34
|
end
|
36
|
-
|
37
|
-
def dirpath(val, absolute: true)
|
38
|
-
Pathname.new(val).realdirpath
|
39
|
-
rescue StandardError
|
40
|
-
absolute ? Pathname.pwd.join(val) : Pathname.new(val)
|
41
|
-
end
|
42
35
|
end
|
43
36
|
end
|
44
37
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: squared
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- An Pham
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 2025-04-28 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: rake
|
@@ -123,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
125
|
requirements: []
|
126
|
-
rubygems_version: 3.6.
|
126
|
+
rubygems_version: 3.6.2
|
127
127
|
specification_version: 4
|
128
128
|
summary: Rake task generator for managing multi-language workspaces.
|
129
129
|
test_files: []
|