squared 0.0.10 → 0.0.12
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.ruby.md +98 -26
- data/lib/squared/app.rb +10 -0
- data/lib/squared/common/base.rb +12 -16
- data/lib/squared/common/class.rb +26 -1
- data/lib/squared/common/format.rb +79 -24
- data/lib/squared/common/prompt.rb +36 -0
- data/lib/squared/common/shell.rb +4 -3
- data/lib/squared/common/system.rb +15 -47
- data/lib/squared/common/utils.rb +51 -16
- data/lib/squared/common.rb +1 -4
- data/lib/squared/config.rb +48 -43
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +245 -125
- data/lib/squared/workspace/project/base.rb +448 -188
- data/lib/squared/workspace/project/git.rb +97 -113
- data/lib/squared/workspace/project/node.rb +217 -109
- data/lib/squared/workspace/project/python.rb +37 -34
- data/lib/squared/workspace/project/ruby.rb +137 -100
- data/lib/squared/workspace/project.rb +0 -3
- data/lib/squared/workspace/repo.rb +32 -18
- data/lib/squared/workspace/series.rb +82 -53
- data/lib/squared/workspace.rb +6 -5
- data/lib/squared.rb +1 -11
- metadata +4 -3
- data/lib/squared/common/task.rb +0 -24
@@ -3,8 +3,8 @@
|
|
3
3
|
module Squared
|
4
4
|
module Workspace
|
5
5
|
class Application
|
6
|
-
include Common
|
7
|
-
include
|
6
|
+
include Common::Format
|
7
|
+
include Utils
|
8
8
|
include ::Rake::DSL
|
9
9
|
|
10
10
|
SCRIPT_OBJ = {
|
@@ -20,54 +20,63 @@ module Squared
|
|
20
20
|
class << self
|
21
21
|
def implement(*objs)
|
22
22
|
objs.each do |obj|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
23
|
+
next unless obj < impl_project
|
24
|
+
|
25
|
+
kind_project.unshift(obj)
|
26
|
+
obj.tasks&.each { |task| impl_series.add(task, obj) }
|
27
|
+
if (args = obj.batchargs)
|
28
|
+
impl_series.batch(*args)
|
29
|
+
end
|
30
|
+
if (args = obj.aliasargs)
|
31
|
+
impl_series.alias(*args)
|
32
|
+
end
|
33
|
+
if (args = obj.bannerargs)
|
34
|
+
@attr_banner += args
|
28
35
|
end
|
29
36
|
end
|
30
37
|
end
|
31
38
|
|
32
39
|
def find(ref = nil, path: nil)
|
33
|
-
if ref && (ret =
|
40
|
+
if ref && (ret = kind_project.find { |proj| proj.ref == ref })
|
34
41
|
ret
|
35
42
|
elsif path
|
36
|
-
|
43
|
+
kind_project.find { |proj| proj.config?(path) }
|
37
44
|
end
|
38
45
|
end
|
39
46
|
|
47
|
+
def baseref
|
48
|
+
impl_project.ref
|
49
|
+
end
|
50
|
+
|
40
51
|
def to_s
|
41
|
-
super.
|
52
|
+
super.match(/[^:]+$/)[0]
|
42
53
|
end
|
43
54
|
|
44
|
-
attr_reader :
|
55
|
+
attr_reader :kind_project
|
56
|
+
attr_accessor :impl_series, :impl_project, :attr_banner
|
45
57
|
end
|
46
58
|
|
47
|
-
@
|
48
|
-
@impl_series = Workspace::Series
|
59
|
+
@kind_project = []
|
49
60
|
|
50
|
-
attr_reader :root, :home, :main, :prefix, :series, :
|
51
|
-
attr_accessor :exception, :pipe, :verbose, :warning
|
61
|
+
attr_reader :root, :home, :main, :prefix, :exception, :warning, :pipe, :verbose, :theme, :series, :closed
|
52
62
|
|
53
|
-
def initialize(home = Dir.pwd, *,
|
54
|
-
|
55
|
-
|
56
|
-
@home = (home = Pathname.new(home)).realdirpath
|
57
|
-
@main = (main || home.basename).to_s
|
63
|
+
def initialize(home = Dir.pwd, *, main: nil, prefix: nil,
|
64
|
+
verbose: ARG[:VERBOSE], common: ARG[:COMMON], pipe: ARG[:PIPE], exception: ARG[:FAIL], **)
|
65
|
+
@home = Pathname.new(home).realdirpath
|
58
66
|
@root = @home.parent
|
67
|
+
@main = (main || @home.basename).to_s.freeze
|
59
68
|
@prefix = prefix
|
60
69
|
@series = Application.impl_series.new(self)
|
61
70
|
@project = {}
|
62
71
|
@extensions = []
|
63
|
-
@pipe = env_pipe(pipe)
|
72
|
+
@pipe = env_pipe(pipe, (ARG[:OUT] && env(ARG[:OUT])) || 1, root: @home)
|
64
73
|
@exception = env_bool(exception)
|
65
|
-
@verbose = verbose.nil? ? @pipe
|
74
|
+
@verbose = env_bool(verbose, verbose.nil? || verbose.is_a?(::String) ? @pipe != 0 : verbose)
|
66
75
|
@warning = @verbose != false
|
67
|
-
@
|
76
|
+
@closed = false
|
68
77
|
if common
|
69
78
|
@theme = __get__(:theme)[:workspace]
|
70
|
-
|
79
|
+
ARG[:COLOR] = false if @pipe == 0 || @pipe.is_a?(::Pathname)
|
71
80
|
else
|
72
81
|
@theme = {}
|
73
82
|
end
|
@@ -81,46 +90,59 @@ module Squared
|
|
81
90
|
group: {},
|
82
91
|
ref: {}
|
83
92
|
}.freeze
|
93
|
+
initialize_session
|
84
94
|
end
|
85
95
|
|
86
|
-
def
|
87
|
-
|
88
|
-
return unless
|
96
|
+
def initialize_session
|
97
|
+
@envname = @main.gsub(/[^\w]+/, '_').upcase.freeze
|
98
|
+
return unless @pipe.is_a?(::Pathname)
|
99
|
+
|
100
|
+
bord = '#' * Project.line_width
|
101
|
+
puts bord, format('Session started on %s by %s', Time.now.to_s, @main), bord
|
102
|
+
end
|
89
103
|
|
104
|
+
def build(parallel: [], **kwargs)
|
105
|
+
return self unless enabled? && !@closed
|
106
|
+
|
107
|
+
kwargs[:parallel] = parallel.map(&:to_s)
|
90
108
|
@project.each_value do |proj|
|
91
109
|
next unless proj.enabled?
|
92
110
|
|
93
111
|
proj.populate(**kwargs)
|
94
|
-
series.
|
112
|
+
series.populate(proj)
|
95
113
|
end
|
96
114
|
|
97
|
-
Application.
|
115
|
+
Application.kind_project.each { |obj| obj.populate(self, **kwargs) }
|
98
116
|
@extensions.each { |ext| __send__(ext, **kwargs) }
|
99
117
|
|
100
|
-
series.
|
118
|
+
series.build(**kwargs)
|
101
119
|
__build__(**kwargs)
|
102
120
|
|
103
121
|
yield self if block_given?
|
122
|
+
@closed = true
|
123
|
+
self
|
104
124
|
end
|
105
125
|
|
106
|
-
def with(*val, &blk)
|
126
|
+
def with(*val, group: nil, **kwargs, &blk)
|
107
127
|
@group = nil
|
108
128
|
@ref = nil
|
129
|
+
@withargs = kwargs.empty? ? nil : kwargs
|
130
|
+
val = as_a(group || kwargs[:ref], flat: true, compact: true) if val.empty?
|
109
131
|
kind = val.first
|
110
132
|
val = kind if val.size == 1
|
111
133
|
case kind
|
112
134
|
when ::String
|
113
135
|
@group = val
|
114
|
-
if block_given?
|
115
|
-
instance_eval(&blk)
|
116
|
-
@group = nil
|
117
|
-
end
|
118
136
|
when ::Symbol
|
119
137
|
@ref = val
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
138
|
+
else
|
139
|
+
raise_error('group{Symbol} | ref{String}', hint: 'missing') if block_given?
|
140
|
+
end
|
141
|
+
if block_given?
|
142
|
+
instance_eval(&blk)
|
143
|
+
@group = nil
|
144
|
+
@ref = nil
|
145
|
+
@withargs = nil
|
124
146
|
end
|
125
147
|
self
|
126
148
|
end
|
@@ -133,6 +155,10 @@ module Squared
|
|
133
155
|
script_command :depend, script, group, ref
|
134
156
|
end
|
135
157
|
|
158
|
+
def graph(script, group: @group, ref: @ref)
|
159
|
+
script_command :graph, as_a(script, :to_s).freeze, group, ref
|
160
|
+
end
|
161
|
+
|
136
162
|
def clean(script, group: @group, ref: @ref)
|
137
163
|
script_command :clean, script, group, ref
|
138
164
|
end
|
@@ -153,48 +179,97 @@ module Squared
|
|
153
179
|
script_command :exclude, as_a(base, :to_sym).freeze, group, ref
|
154
180
|
end
|
155
181
|
|
156
|
-
def
|
182
|
+
def banner(*args, command: true, styles: nil, border: nil, group: @group, ref: @ref)
|
183
|
+
data = { command: command, order: [], styles: check_style(styles, empty: false), border: check_style(border) }
|
184
|
+
args.each do |meth|
|
185
|
+
if meth.is_a?(::Array)
|
186
|
+
found = false
|
187
|
+
meth = meth.select do |val|
|
188
|
+
case val
|
189
|
+
when ::Symbol
|
190
|
+
found = true
|
191
|
+
Application.attr_banner.include?(val)
|
192
|
+
when ::String
|
193
|
+
true
|
194
|
+
else
|
195
|
+
false
|
196
|
+
end
|
197
|
+
end
|
198
|
+
if !found
|
199
|
+
next
|
200
|
+
elsif meth.size == 1
|
201
|
+
meth = meth.first
|
202
|
+
end
|
203
|
+
elsif !Application.attr_banner.include?(meth = meth.to_sym)
|
204
|
+
next
|
205
|
+
end
|
206
|
+
data[:order] << meth
|
207
|
+
end
|
208
|
+
unless !command && data[:order].empty?
|
209
|
+
if group
|
210
|
+
label = :group
|
211
|
+
items = as_a(group)
|
212
|
+
else
|
213
|
+
label = :ref
|
214
|
+
items = ref ? as_a(ref) : %i[_]
|
215
|
+
end
|
216
|
+
items.each { |val| @banner[label][val.to_sym] = data }
|
217
|
+
end
|
218
|
+
self
|
219
|
+
end
|
220
|
+
|
221
|
+
def add(path, project = nil, **kwargs, &blk)
|
222
|
+
if @withargs
|
223
|
+
data = @withargs.dup
|
224
|
+
data.merge!(kwargs)
|
225
|
+
kwargs = data
|
226
|
+
end
|
157
227
|
ref = if kwargs.key?(:ref)
|
228
|
+
kwargs = kwargs.dup unless @withargs
|
158
229
|
kwargs.delete(:ref)
|
159
230
|
elsif @ref.is_a?(::Symbol)
|
160
231
|
@ref
|
161
232
|
end
|
162
|
-
|
163
|
-
|
164
|
-
|
233
|
+
if @group.is_a?(::String) && !kwargs.key?(:group)
|
234
|
+
kwargs = kwargs.dup unless @withargs
|
235
|
+
kwargs[:group] = @group
|
236
|
+
end
|
237
|
+
path = rootpath(path)
|
238
|
+
project = (project || path.basename).to_s
|
239
|
+
name = task_name(project)
|
240
|
+
index = 0
|
241
|
+
while @project[name]
|
242
|
+
index += 1
|
243
|
+
name = "#{project}-#{index}"
|
244
|
+
end
|
165
245
|
proj = ((if !ref.is_a?(::Class)
|
166
246
|
Application.find(ref, path: path)
|
167
247
|
elsif ref < Project::Base
|
168
248
|
ref
|
169
|
-
end) || Project::Base).new(
|
170
|
-
@project[name
|
249
|
+
end) || Project::Base).new(self, path, name, **kwargs)
|
250
|
+
@project[name] = proj
|
171
251
|
__get__(:project)[name] = proj unless kwargs[:private]
|
172
252
|
proj.instance_eval(&blk) if block_given?
|
173
253
|
self
|
174
254
|
end
|
175
255
|
|
176
|
-
def group(path,
|
177
|
-
|
178
|
-
next unless
|
256
|
+
def group(path, val, override: {}, **kwargs, &blk)
|
257
|
+
rootpath(path).children.map do |dir|
|
258
|
+
next unless dir.directory?
|
179
259
|
|
180
|
-
|
181
|
-
basename
|
182
|
-
while @project[basename]
|
183
|
-
index += 1
|
184
|
-
basename = :"#{basename}-#{index}"
|
185
|
-
end
|
186
|
-
[basename, dir, override[basename]]
|
260
|
+
basename = dir.basename.to_s
|
261
|
+
[dir, basename, override[basename.to_sym]]
|
187
262
|
end
|
188
|
-
.each do |
|
263
|
+
.each do |dir, basename, opts|
|
189
264
|
args = kwargs.dup
|
190
265
|
args.merge!(opts) if opts
|
191
|
-
add(
|
266
|
+
add(dir, basename, group: val, **args, &blk)
|
192
267
|
end
|
193
268
|
self
|
194
269
|
end
|
195
270
|
|
196
271
|
def compose(name, &blk)
|
197
|
-
namespace(task_name(name), &blk)
|
272
|
+
namespace(task_name(name), &blk) if block_given?
|
198
273
|
self
|
199
274
|
end
|
200
275
|
|
@@ -203,7 +278,7 @@ module Squared
|
|
203
278
|
self
|
204
279
|
end
|
205
280
|
|
206
|
-
def style(
|
281
|
+
def style(obj, *args, target: nil, empty: false)
|
207
282
|
data = nil
|
208
283
|
if target
|
209
284
|
as_a(target).each_with_index do |key, i|
|
@@ -214,79 +289,103 @@ module Squared
|
|
214
289
|
end
|
215
290
|
end
|
216
291
|
end
|
217
|
-
apply_style(data || theme,
|
292
|
+
apply_style(data || theme, obj, args, empty: empty) unless target && !data
|
218
293
|
self
|
219
294
|
end
|
220
295
|
|
221
|
-
def
|
222
|
-
|
223
|
-
|
224
|
-
|
296
|
+
def find(path = nil, name: nil)
|
297
|
+
path &&= rootpath(path)
|
298
|
+
name &&= name.to_s
|
299
|
+
ret = @project.find { |_, item| (path && item.path == path) || (name && item.name == name) }&.last
|
300
|
+
return ret unless block_given?
|
225
301
|
|
226
|
-
|
227
|
-
order.flatten.each do |val|
|
228
|
-
case (val = val.to_sym)
|
229
|
-
when :name, :project, :path, :ref, :group
|
230
|
-
data[:order] << val
|
231
|
-
end
|
232
|
-
end
|
233
|
-
if command || !data[:order].empty?
|
234
|
-
if group ||= @group
|
235
|
-
label = :group
|
236
|
-
items = as_a(group)
|
237
|
-
else
|
238
|
-
label = :ref
|
239
|
-
items = as_a(ref || @ref || :_)
|
240
|
-
end
|
241
|
-
items.each { |val| @banner[label][val.to_sym] = data }
|
242
|
-
end
|
302
|
+
yield ret if ret
|
243
303
|
self
|
244
304
|
end
|
245
305
|
|
246
|
-
def
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
args.reverse_each do |val|
|
251
|
-
next unless val && (ret = val.is_a?(::Symbol) ? @script[:ref!][val] : @script[:group!][val.to_sym])
|
306
|
+
def find_base(obj)
|
307
|
+
Application.kind_project.find { |proj| obj.instance_of?(proj) }
|
308
|
+
end
|
252
309
|
|
253
|
-
|
254
|
-
|
255
|
-
|
310
|
+
def task_name(val, desc: false)
|
311
|
+
ret = @prefix ? task_join(@prefix, val) : val.to_s
|
312
|
+
desc ? ret.split(':').join(ARG[:SPACE]) : ret
|
256
313
|
end
|
257
314
|
|
258
|
-
def
|
259
|
-
ret = (
|
260
|
-
return ret == equals.to_s unless equals.nil?
|
315
|
+
def task_namespace(val, first: false)
|
316
|
+
return nil unless (ret = val.to_s.split(':')).size > 1
|
261
317
|
|
262
|
-
|
318
|
+
first ? ret.first : task_join(*ret[0..-2])
|
263
319
|
end
|
264
320
|
|
265
|
-
def
|
266
|
-
|
267
|
-
|
321
|
+
def task_resolve(obj, key)
|
322
|
+
tasks = []
|
323
|
+
if (base = task_base?(key))
|
324
|
+
tasks << key if obj.has?(key, baseref)
|
325
|
+
elsif (batch = series.batch_get(key))
|
326
|
+
obj.allref.each do |ref|
|
327
|
+
next unless (data = batch[ref])
|
268
328
|
|
269
|
-
|
270
|
-
|
329
|
+
data.each do |val|
|
330
|
+
if (items = task_resolve(obj, val)).empty?
|
331
|
+
tasks.clear
|
332
|
+
break
|
333
|
+
end
|
334
|
+
tasks += items
|
335
|
+
end
|
336
|
+
return tasks unless tasks.empty?
|
337
|
+
end
|
338
|
+
elsif task_extend?(obj, key)
|
339
|
+
tasks << key
|
340
|
+
end
|
341
|
+
ret = []
|
342
|
+
if tasks.empty?
|
343
|
+
return [] if (base && !obj.ref?(baseref)) || !(data = series.alias_get(key))
|
344
|
+
|
345
|
+
obj.allref.each do |ref|
|
346
|
+
next unless (alt = data[ref])
|
347
|
+
|
348
|
+
ret = task_resolve(obj, alt)
|
349
|
+
break unless ret.empty?
|
350
|
+
end
|
351
|
+
else
|
352
|
+
tasks.each do |val|
|
353
|
+
target = task_join(obj.name, series.name_get(val))
|
354
|
+
return [] unless task_defined?(target)
|
355
|
+
|
356
|
+
ret << target
|
357
|
+
end
|
358
|
+
end
|
359
|
+
ret
|
271
360
|
end
|
272
361
|
|
273
|
-
def
|
274
|
-
|
362
|
+
def script_find(*args)
|
363
|
+
args.reverse_each do |val|
|
364
|
+
next unless val && (ret = val.is_a?(::Symbol) ? @script[:ref!][val] : @script[:group!][val.to_sym])
|
365
|
+
|
366
|
+
return ret
|
367
|
+
end
|
368
|
+
@script[:ref!][:_] || SCRIPT_OBJ
|
275
369
|
end
|
276
370
|
|
277
|
-
def
|
278
|
-
|
279
|
-
|
371
|
+
def script_get(group: nil, ref: nil)
|
372
|
+
if group
|
373
|
+
@script[:group][group.to_sym]
|
374
|
+
elsif ref
|
375
|
+
@script[:ref][ref]
|
376
|
+
end
|
280
377
|
end
|
281
378
|
|
282
|
-
def
|
283
|
-
|
379
|
+
def banner_get(*ref, group: nil)
|
380
|
+
ret = nil
|
381
|
+
return ret if group && (ret = @banner[:group][group.to_sym])
|
284
382
|
|
285
|
-
|
383
|
+
ref.reverse_each { |val| return ret if (ret = @banner[:ref][val]) }
|
384
|
+
@banner[:ref][:_]
|
286
385
|
end
|
287
386
|
|
288
387
|
def to_s
|
289
|
-
root.to_s
|
388
|
+
(home? ? home : root).to_s
|
290
389
|
end
|
291
390
|
|
292
391
|
def inspect
|
@@ -297,12 +396,20 @@ module Squared
|
|
297
396
|
!@extensions.empty? || @project.values.any?(&:enabled?)
|
298
397
|
end
|
299
398
|
|
399
|
+
def task_base?(key)
|
400
|
+
series.base?(key)
|
401
|
+
end
|
402
|
+
|
300
403
|
def task_extend?(obj, key)
|
301
404
|
series.extend?(obj, key)
|
302
405
|
end
|
303
406
|
|
304
|
-
def
|
305
|
-
|
407
|
+
def task_include?(obj, key, ref = nil)
|
408
|
+
task_base?(key) ? obj.has?(key, ref || baseref) : task_extend?(obj, key)
|
409
|
+
end
|
410
|
+
|
411
|
+
def task_defined?(*key)
|
412
|
+
::Rake::Task.task_defined?(key.size == 1 ? key.first : task_join(*key))
|
306
413
|
end
|
307
414
|
|
308
415
|
def dev?(**kwargs)
|
@@ -313,25 +420,38 @@ module Squared
|
|
313
420
|
script?(:prod, **kwargs)
|
314
421
|
end
|
315
422
|
|
316
|
-
|
423
|
+
def home?
|
424
|
+
!(proj = find(home)).nil? && proj.enabled?
|
425
|
+
end
|
317
426
|
|
318
|
-
def
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
427
|
+
def rootpath(*args)
|
428
|
+
root.join(*args)
|
429
|
+
end
|
430
|
+
|
431
|
+
def homepath(*args)
|
432
|
+
home.join(*args)
|
433
|
+
end
|
434
|
+
|
435
|
+
def baseref
|
436
|
+
Application.baseref
|
437
|
+
end
|
438
|
+
|
439
|
+
def invokeargs
|
440
|
+
{ exception: exception, warning: warning }
|
441
|
+
end
|
323
442
|
|
324
|
-
|
443
|
+
public :task_join
|
325
444
|
|
326
|
-
|
327
|
-
return unless series.some?(:depend) && !task_defined?(key = task_name('init'))
|
445
|
+
private
|
328
446
|
|
329
|
-
|
330
|
-
|
447
|
+
def __build__(default: nil, **)
|
448
|
+
if default && task_defined?(t = task_name(default)) && !task_defined?(n = ::Rake.application.default_task_name)
|
449
|
+
task n => t
|
450
|
+
end
|
331
451
|
end
|
332
452
|
|
333
453
|
def puts(*args)
|
334
|
-
|
454
|
+
puts_oe(*args, pipe: pipe)
|
335
455
|
end
|
336
456
|
|
337
457
|
def script_command(task, val, group, ref)
|
@@ -353,7 +473,7 @@ module Squared
|
|
353
473
|
elsif ref
|
354
474
|
as_a(ref).each { |val| @script[:ref!][val.to_sym] = data }
|
355
475
|
else
|
356
|
-
@script[:ref][:_] = data
|
476
|
+
@script[:ref!][:_] = data
|
357
477
|
end
|
358
478
|
end
|
359
479
|
|
@@ -361,8 +481,8 @@ module Squared
|
|
361
481
|
SCRIPT_OBJ.dup
|
362
482
|
end
|
363
483
|
|
364
|
-
def script?(state, target: nil, pat: nil, group: nil, ref:
|
365
|
-
data =
|
484
|
+
def script?(state, target: nil, pat: nil, group: nil, ref: baseref, global: false)
|
485
|
+
data = script_find(ref, group)
|
366
486
|
if global
|
367
487
|
target = data[:script] || data[:run] if target.nil?
|
368
488
|
pat = data[state] if pat.nil?
|