squared 0.0.1 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -5
- data/README.ruby.md +51 -16
- data/lib/squared/common/class.rb +6 -0
- data/lib/squared/common/format.rb +80 -24
- data/lib/squared/common/shell.rb +9 -1
- data/lib/squared/common/system.rb +4 -2
- data/lib/squared/common/task.rb +1 -1
- data/lib/squared/common.rb +38 -16
- data/lib/squared/config.rb +139 -85
- data/lib/squared/repo/project/base.rb +185 -102
- data/lib/squared/repo/project/git.rb +140 -53
- data/lib/squared/repo/project/node.rb +206 -123
- data/lib/squared/repo/project/python.rb +48 -29
- data/lib/squared/repo/project/ruby.rb +77 -68
- data/lib/squared/repo/project.rb +0 -30
- data/lib/squared/repo/workspace.rb +196 -122
- data/lib/squared/repo.rb +3 -3
- data/lib/squared/version.rb +1 -1
- metadata +2 -2
@@ -16,6 +16,7 @@ module Squared
|
|
16
16
|
outdated: [],
|
17
17
|
refresh: [],
|
18
18
|
doc: [],
|
19
|
+
test: [],
|
19
20
|
clean: []
|
20
21
|
}
|
21
22
|
TASK_BASE = {}
|
@@ -42,20 +43,19 @@ module Squared
|
|
42
43
|
project_kind.find { |proj| proj.is_a?(path) } if path
|
43
44
|
end
|
44
45
|
|
46
|
+
def to_s
|
47
|
+
/[^:]+$/.match(super.to_s)[0]
|
48
|
+
end
|
49
|
+
|
45
50
|
attr_reader :project_kind
|
46
51
|
end
|
47
52
|
|
48
53
|
@project_kind = []
|
49
54
|
|
50
|
-
attr_reader :main, :root, :home, :series
|
51
|
-
attr_accessor :
|
52
|
-
|
53
|
-
def initialize(main)
|
54
|
-
prompt = lambda do |path|
|
55
|
-
return false unless path.directory?
|
55
|
+
attr_reader :main, :root, :home, :series, :theme
|
56
|
+
attr_accessor :manifest, :manifest_url, :exception, :pipe, :verbose, :warning
|
56
57
|
|
57
|
-
|
58
|
-
end
|
58
|
+
def initialize(main, *, common: true, **)
|
59
59
|
@main = main.to_s
|
60
60
|
@home = if (val = env('REPO_HOME'))
|
61
61
|
home = Pathname.new(val)
|
@@ -66,7 +66,7 @@ module Squared
|
|
66
66
|
elsif !@root.exist?
|
67
67
|
@root.mkpath
|
68
68
|
elsif !empty?(@root)
|
69
|
-
if
|
69
|
+
if repo_prompt(@root)
|
70
70
|
@override = true
|
71
71
|
else
|
72
72
|
@root = nil
|
@@ -81,7 +81,7 @@ module Squared
|
|
81
81
|
if !@root.exist?
|
82
82
|
@root.mkpath
|
83
83
|
elsif !empty?(@root)
|
84
|
-
raise ArgumentError, message('REPO_ROOT', val, hint: 'exist') unless
|
84
|
+
raise ArgumentError, message('REPO_ROOT', val, hint: 'exist') unless repo_prompt(@root)
|
85
85
|
|
86
86
|
@override = true
|
87
87
|
end
|
@@ -91,60 +91,39 @@ module Squared
|
|
91
91
|
end
|
92
92
|
@root ||= @home.parent
|
93
93
|
@series = TASK_NAME.dup
|
94
|
-
@
|
94
|
+
@theme = common ? __get__(:theme)[:workspace] : {}
|
95
95
|
@project = {}
|
96
|
+
@script = {
|
97
|
+
group: {},
|
98
|
+
ref: {},
|
99
|
+
build: nil,
|
100
|
+
dev: nil,
|
101
|
+
prod: nil
|
102
|
+
}
|
96
103
|
@exception = !env('PIPE_FAIL', ignore: '0').nil?
|
97
104
|
@pipe = !env('PIPE_OUT', ignore: '0').nil?
|
98
|
-
@verbose =
|
99
|
-
|
100
|
-
|
101
|
-
def repo(url, manifest = 'latest')
|
102
|
-
@manifest_url = url
|
103
|
-
@manifest = manifest
|
104
|
-
self
|
105
|
+
@verbose = !@pipe
|
106
|
+
@warning = !empty?(@root, init: false)
|
105
107
|
end
|
106
108
|
|
107
|
-
def
|
108
|
-
|
109
|
-
when 'verbose'
|
110
|
-
"#{script}:verbose"
|
111
|
-
when 'silent'
|
112
|
-
@verbose = false
|
113
|
-
script
|
114
|
-
else
|
115
|
-
val || script
|
116
|
-
end
|
117
|
-
@dev = bool_match(env('REPO_DEV'), kwargs[:dev])
|
118
|
-
@prod = bool_match(env('REPO_PROD'), kwargs[:prod])
|
119
|
-
self
|
120
|
-
end
|
109
|
+
def build(**kwargs)
|
110
|
+
return unless enabled?
|
121
111
|
|
122
|
-
|
123
|
-
|
124
|
-
ref = kwargs[:ref]
|
125
|
-
project = if !ref.is_a?(::Class)
|
126
|
-
Workspace.find(path: root_path(path), ref: ref)
|
127
|
-
elsif ref < Project::Base
|
128
|
-
ref
|
129
|
-
end
|
130
|
-
instance = (project || Project::Base).new(name, path, self, **kwargs)
|
131
|
-
@project[n = name.to_sym] = instance
|
132
|
-
get(:project)[n] = instance
|
133
|
-
self
|
134
|
-
end
|
112
|
+
default = kwargs[:default]
|
113
|
+
parallel = env('REPO_SYNC', ignore: '0') ? [] : (kwargs[:parallel] || []).map!(&:to_sym)
|
135
114
|
|
136
|
-
def build(default: nil, parallel: [])
|
137
115
|
group = {}
|
138
116
|
parent = {}
|
139
|
-
incl =
|
117
|
+
incl = []
|
140
118
|
@project.each do |name, proj|
|
141
119
|
next unless proj.enabled?
|
142
120
|
|
143
|
-
|
121
|
+
series.each do |key, items|
|
144
122
|
target = "#{name}:#{key}"
|
145
123
|
case key
|
146
|
-
when :build, :refresh, :depend, :outdated, :doc, :
|
147
|
-
|
124
|
+
when :build, :refresh, :depend, :copy, :outdated, :doc, :test, :clean
|
125
|
+
valid = proj.has?(key) || ::Rake::Task.task_defined?(target)
|
126
|
+
next unless valid || (key == :refresh && series[:build].include?(target = "#{name}:build"))
|
148
127
|
else
|
149
128
|
next unless task_defined?(proj, key)
|
150
129
|
end
|
@@ -156,19 +135,20 @@ module Squared
|
|
156
135
|
end
|
157
136
|
next unless (base = find_base(proj))
|
158
137
|
|
159
|
-
id = base.to_sym.to_s
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
(parent[:"#{key}:#{id}"] ||= []).push(target)
|
138
|
+
unless (id = base.to_sym.to_s) == proj.group
|
139
|
+
incl << id
|
140
|
+
(parent[:"#{key}:#{id}"] ||= []).push(target)
|
141
|
+
end
|
164
142
|
end
|
165
|
-
proj.populate
|
143
|
+
proj.populate(**kwargs)
|
166
144
|
end
|
167
|
-
|
168
|
-
|
169
|
-
if
|
145
|
+
series.merge!(parent) if incl.uniq.size > 1
|
146
|
+
series.merge!(group)
|
147
|
+
series[:refresh].clear if series[:refresh].all? { |target| target.end_with?(':build') }
|
148
|
+
|
149
|
+
if repo?
|
170
150
|
branch = env('REPO_MANIFEST') || read_manifest
|
171
|
-
target = branch ||
|
151
|
+
target = branch || manifest
|
172
152
|
stage = nil
|
173
153
|
failfast = true
|
174
154
|
cmd = []
|
@@ -217,7 +197,7 @@ module Squared
|
|
217
197
|
parse_opts.(args)
|
218
198
|
stage = :init
|
219
199
|
puts if newline
|
220
|
-
system("repo init -u #{
|
200
|
+
system("repo init -u #{manifest_url} -m #{args.manifest || target}.xml", chdir: root)
|
221
201
|
repo[:all].invoke
|
222
202
|
end
|
223
203
|
|
@@ -230,48 +210,36 @@ module Squared
|
|
230
210
|
cmd << '--fail-fast' if failfast
|
231
211
|
puts if newline && stage != :init
|
232
212
|
begin
|
233
|
-
shell("repo sync #{cmd.join(' ')}", chdir:
|
213
|
+
shell("repo sync #{cmd.join(' ')}", chdir: root, exception: failfast)
|
234
214
|
rescue StandardError => e
|
235
|
-
emphasize(e, title: "rake stash repo:#{stage ||
|
215
|
+
emphasize(e, title: "rake stash repo:#{stage || 'sync'}")
|
236
216
|
raise
|
237
217
|
end
|
238
218
|
end
|
239
219
|
end
|
240
220
|
end
|
241
|
-
return unless enabled?
|
242
221
|
|
243
|
-
|
244
|
-
output = dev? ? :refresh : :build
|
222
|
+
Workspace.project_kind.each { |obj| obj.populate(self, **kwargs) }
|
245
223
|
|
246
|
-
|
224
|
+
if !series[:build].empty?
|
225
|
+
init = [:depend, dev? && !series[:refresh].empty? ? :refresh : :build]
|
247
226
|
|
248
|
-
|
249
|
-
task :all, [:git] do |_, args|
|
250
|
-
sync = ->(key) { multi.include?(key) ? :"#{key}:sync" : key }
|
251
|
-
pull = case args.git
|
252
|
-
when 'rebase'
|
253
|
-
sync.(:rebase)
|
254
|
-
when 'stash'
|
255
|
-
invoke sync.(:stash)
|
256
|
-
sync.(:pull)
|
257
|
-
else
|
258
|
-
sync.(:pull)
|
259
|
-
end
|
260
|
-
invoke(pull, exception: @exception)
|
261
|
-
invoke(output, exception: @exception)
|
262
|
-
end
|
227
|
+
task default: default || init[1]
|
263
228
|
|
264
|
-
|
265
|
-
|
229
|
+
desc 'init'
|
230
|
+
task init: init
|
231
|
+
elsif default && !series[default].empty?
|
232
|
+
task default: default
|
233
|
+
end
|
266
234
|
|
267
|
-
|
235
|
+
series.each do |key, items|
|
268
236
|
next if items.empty?
|
269
237
|
|
270
|
-
unless (valid =
|
238
|
+
unless (valid = parallel.include?(key))
|
271
239
|
group = key.to_s
|
272
|
-
valid =
|
240
|
+
valid = parallel.include?(group.split(':').first.to_sym) if group.include?(':')
|
273
241
|
end
|
274
|
-
if valid
|
242
|
+
if valid && items.size > 1
|
275
243
|
desc "#{key} (thread)"
|
276
244
|
multitask key => items
|
277
245
|
|
@@ -282,50 +250,129 @@ module Squared
|
|
282
250
|
task key => items
|
283
251
|
end
|
284
252
|
end
|
253
|
+
|
254
|
+
yield self if block_given?
|
255
|
+
end
|
256
|
+
|
257
|
+
def repo(url, manifest = 'latest', run: nil, dev: nil, prod: nil)
|
258
|
+
@manifest_url = url
|
259
|
+
@manifest = manifest
|
260
|
+
script = case (val = env('REPO_BUILD'))
|
261
|
+
when 'verbose'
|
262
|
+
run ? "#{run}:verbose" : nil
|
263
|
+
when 'silent'
|
264
|
+
@verbose = false
|
265
|
+
@warning = false
|
266
|
+
run
|
267
|
+
else
|
268
|
+
val || run
|
269
|
+
end
|
270
|
+
case env('REPO_WARN')
|
271
|
+
when '0'
|
272
|
+
@warning = false
|
273
|
+
when '1'
|
274
|
+
@warning = true
|
275
|
+
end
|
276
|
+
script ? run(script, dev: bool_match(env('REPO_DEV'), dev), prod: bool_match(env('REPO_DEV'), prod)) : self
|
277
|
+
end
|
278
|
+
|
279
|
+
def run(script, group: nil, ref: nil, **kwargs)
|
280
|
+
if group || ref
|
281
|
+
script_command :run, script, group, ref
|
282
|
+
else
|
283
|
+
@script[:build] = script
|
284
|
+
@script[:dev] = kwargs[:dev]
|
285
|
+
@script[:prod] = kwargs[:prod]
|
286
|
+
self
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
def depend(script, group: nil, ref: nil)
|
291
|
+
script_command :depend, script, group, ref
|
292
|
+
end
|
293
|
+
|
294
|
+
def clean(script, group: nil, ref: nil)
|
295
|
+
script_command :clean, script, group, ref
|
296
|
+
end
|
297
|
+
|
298
|
+
def doc(script, group: nil, ref: nil)
|
299
|
+
script_command :doc, script, group, ref
|
300
|
+
end
|
301
|
+
|
302
|
+
def test(script, group: nil, ref: nil)
|
303
|
+
script_command :test, script, group, ref
|
285
304
|
end
|
286
305
|
|
287
|
-
def
|
288
|
-
|
306
|
+
def add(name, path = nil, **kwargs)
|
307
|
+
path = root_path((path || name).to_s)
|
308
|
+
ref = kwargs[:ref]
|
309
|
+
project = if !ref.is_a?(::Class)
|
310
|
+
Workspace.find(path: path, ref: ref)
|
311
|
+
elsif ref < Project::Base
|
312
|
+
ref
|
313
|
+
end
|
314
|
+
instance = (project || Project::Base).new(name, path, self, **kwargs)
|
315
|
+
@project[n = name.to_sym] = instance
|
316
|
+
__get__(:project)[n] = instance unless kwargs[:private]
|
289
317
|
self
|
290
318
|
end
|
291
319
|
|
292
|
-
def
|
293
|
-
|
320
|
+
def compose(name, &blk)
|
321
|
+
namespace(name, &blk)
|
294
322
|
self
|
295
323
|
end
|
296
324
|
|
297
|
-
def
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
325
|
+
def apply(&blk)
|
326
|
+
instance_eval(&blk)
|
327
|
+
self
|
328
|
+
end
|
329
|
+
|
330
|
+
def style(name, *args, target: nil, empty: false)
|
331
|
+
data = nil
|
332
|
+
if target
|
333
|
+
as_a(target).each_with_index do |val, i|
|
334
|
+
if i == 0
|
335
|
+
break unless (data = __get__(:theme)[val.to_sym])
|
336
|
+
else
|
337
|
+
data = data[val.to_sym] ||= {}
|
338
|
+
end
|
339
|
+
end
|
340
|
+
return unless data
|
303
341
|
end
|
342
|
+
apply_style(data || theme, name, *args, empty: empty)
|
304
343
|
self
|
305
344
|
end
|
306
345
|
|
346
|
+
def script(group: nil, ref: nil)
|
347
|
+
if group || ref
|
348
|
+
(group && @script[:group][group.to_sym]) || (ref && @script[:ref][ref.to_sym])
|
349
|
+
else
|
350
|
+
@script[:build]
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
307
354
|
def env(key, equals: nil, ignore: nil)
|
308
|
-
ret = ENV.fetch("#{key}_#{
|
355
|
+
ret = ENV.fetch("#{key}_#{main.gsub(/[^\w]/, '_').upcase}", ENV[key]).to_s
|
309
356
|
return ret == equals.to_s if equals
|
310
357
|
|
311
358
|
ret.empty? || as_a(ignore).any? { |val| ret == val.to_s } ? nil : ret
|
312
359
|
end
|
313
360
|
|
314
|
-
def read_manifest
|
361
|
+
def read_manifest(*)
|
315
362
|
require 'rexml/document'
|
316
363
|
file = root_path('.repo/manifest.xml')
|
317
364
|
return unless file.exist?
|
318
365
|
|
319
|
-
doc = REXML::Document.new(
|
366
|
+
doc = REXML::Document.new(file.read)
|
320
367
|
doc.elements['manifest/include'].attributes['name']&.sub('.xml', '')
|
321
368
|
end
|
322
369
|
|
323
370
|
def root_path(*args)
|
324
|
-
|
371
|
+
root.join(*args)
|
325
372
|
end
|
326
373
|
|
327
374
|
def home_path(*args)
|
328
|
-
|
375
|
+
home.join(*args)
|
329
376
|
end
|
330
377
|
|
331
378
|
def find_base(obj)
|
@@ -345,17 +392,20 @@ module Squared
|
|
345
392
|
end
|
346
393
|
end
|
347
394
|
|
348
|
-
def
|
349
|
-
|
350
|
-
|
395
|
+
def to_s
|
396
|
+
root.to_s
|
397
|
+
end
|
351
398
|
|
352
|
-
|
353
|
-
|
354
|
-
end
|
399
|
+
def inspect
|
400
|
+
"#<#{self.class}: #{main} => #{self}>"
|
355
401
|
end
|
356
402
|
|
357
403
|
def enabled?
|
358
|
-
|
404
|
+
repo? || @project.any? { |_, proj| proj.enabled? }
|
405
|
+
end
|
406
|
+
|
407
|
+
def repo?
|
408
|
+
!manifest_url.nil? && (empty?(root) || @override)
|
359
409
|
end
|
360
410
|
|
361
411
|
def multitask?
|
@@ -366,22 +416,27 @@ module Squared
|
|
366
416
|
end
|
367
417
|
end
|
368
418
|
|
419
|
+
def empty?(dir, init: true)
|
420
|
+
return true if dir.empty? || (init && dir.join('.repo').directory?)
|
421
|
+
return true if dir.children.size == 1 && dir.join(dir.children.first).to_s == __FILE__
|
422
|
+
|
423
|
+
dir == root && !env('REPO_ROOT').nil? && root.children.none? do |path|
|
424
|
+
path.directory? && !path.basename.to_s.start_with?('.') && path.to_s != home.to_s
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
369
428
|
def task_defined?(obj, key)
|
370
429
|
obj.is_a?(TASK_BASE[key])
|
371
430
|
end
|
372
431
|
|
373
|
-
def dev?(pat
|
374
|
-
with?(
|
432
|
+
def dev?(script: nil, pat: nil, global: nil)
|
433
|
+
with?(:dev, script: script, pat: pat, global: (pat.nil? && global.nil?) || global)
|
375
434
|
end
|
376
435
|
|
377
|
-
def prod?(pat
|
378
|
-
return false if @dev == true || !@prod
|
379
|
-
|
380
|
-
with?(pat, script: script, state: @prod)
|
381
|
-
end
|
436
|
+
def prod?(script: nil, pat: nil, global: false)
|
437
|
+
return false if global && (@script[:dev] == true || !@script[:prod])
|
382
438
|
|
383
|
-
|
384
|
-
@pipe
|
439
|
+
with?(:prod, script: script, pat: pat, global: global)
|
385
440
|
end
|
386
441
|
|
387
442
|
protected
|
@@ -414,11 +469,30 @@ module Squared
|
|
414
469
|
|
415
470
|
private
|
416
471
|
|
417
|
-
def
|
418
|
-
|
472
|
+
def script_command(task, val, group, ref)
|
473
|
+
if group
|
474
|
+
label = :group
|
475
|
+
items = as_a(group)
|
476
|
+
else
|
477
|
+
label = :ref
|
478
|
+
items = as_a(ref)
|
479
|
+
end
|
480
|
+
items.each { |name| (@script[label][name.to_sym] ||= {})[task] = val }
|
481
|
+
self
|
482
|
+
end
|
483
|
+
|
484
|
+
def repo_prompt(path)
|
485
|
+
return false unless path.directory?
|
486
|
+
|
487
|
+
confirm "#{log_title(:warn)} \"#{sub_style(path, :bold)}\" is not empty. Continue with installation? [y/N] "
|
488
|
+
end
|
489
|
+
|
490
|
+
def with?(state, script: nil, pat: nil, global: false)
|
491
|
+
pat = @script[state] if pat.nil? && global
|
419
492
|
return pat == true unless pat.is_a?(::Regexp)
|
493
|
+
return false if !script && !global
|
420
494
|
|
421
|
-
pat.match?(script || @script)
|
495
|
+
pat.match?(script || @script[:build])
|
422
496
|
end
|
423
497
|
end
|
424
498
|
end
|
data/lib/squared/repo.rb
CHANGED
@@ -9,7 +9,7 @@ module Squared
|
|
9
9
|
project id
|
10
10
|
else
|
11
11
|
(id = Pathname.new(id).realdirpath.to_s) rescue nil if id.is_a?(::String)
|
12
|
-
|
12
|
+
__get__(:project).find { |_, val| val.path.to_s == id.to_s }
|
13
13
|
end
|
14
14
|
end
|
15
15
|
ret.size == 1 ? ret.first : ret
|
@@ -19,7 +19,7 @@ module Squared
|
|
19
19
|
ret = project(name)
|
20
20
|
return ret if ret&.path&.directory?
|
21
21
|
|
22
|
-
raise NoMethodError,
|
22
|
+
raise NoMethodError, "project is not initialized (#{name})"
|
23
23
|
end
|
24
24
|
|
25
25
|
def project?(name)
|
@@ -29,7 +29,7 @@ module Squared
|
|
29
29
|
private
|
30
30
|
|
31
31
|
def project(name)
|
32
|
-
|
32
|
+
__get__(:project)[name.to_sym]
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
data/lib/squared/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: squared
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- An Pham
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-11-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|