squared 0.0.1 → 0.0.3
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/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
|