squared 0.0.1 → 0.0.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/README.md +5 -5
- data/README.ruby.md +51 -16
- data/lib/squared/common/class.rb +6 -0
- data/lib/squared/common/format.rb +63 -23
- data/lib/squared/common/shell.rb +9 -1
- data/lib/squared/common/system.rb +4 -0
- data/lib/squared/common.rb +22 -15
- data/lib/squared/config.rb +37 -25
- data/lib/squared/repo/project/base.rb +166 -94
- data/lib/squared/repo/project/git.rb +138 -51
- data/lib/squared/repo/project/node.rb +207 -123
- data/lib/squared/repo/project/python.rb +48 -29
- data/lib/squared/repo/project/ruby.rb +71 -62
- data/lib/squared/repo/project.rb +0 -30
- data/lib/squared/repo/workspace.rb +165 -117
- data/lib/squared/repo.rb +2 -2
- data/lib/squared/version.rb +1 -1
- metadata +2 -2
@@ -1,29 +1,34 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'forwardable'
|
4
|
+
require 'date'
|
4
5
|
|
5
6
|
module Squared
|
6
7
|
module Repo
|
7
8
|
module Project
|
8
9
|
class Base
|
9
|
-
include Common
|
10
|
+
include Common::System
|
10
11
|
include Shell
|
11
|
-
include System
|
12
12
|
include Task
|
13
13
|
include ::Rake::DSL
|
14
14
|
extend Forwardable
|
15
15
|
|
16
16
|
class << self
|
17
|
+
include Common::Task
|
18
|
+
include ::Rake::DSL
|
19
|
+
|
17
20
|
def tasks
|
18
21
|
[].freeze
|
19
22
|
end
|
20
23
|
|
24
|
+
def populate(*); end
|
25
|
+
|
21
26
|
def to_s
|
22
|
-
|
27
|
+
/[^:]+$/.match(super.to_s)[0]
|
23
28
|
end
|
24
29
|
|
25
30
|
def to_sym
|
26
|
-
|
31
|
+
to_s.downcase.to_sym
|
27
32
|
end
|
28
33
|
end
|
29
34
|
|
@@ -34,60 +39,86 @@ module Squared
|
|
34
39
|
|
35
40
|
protected :logger
|
36
41
|
|
37
|
-
def_delegators :logger, :log,
|
42
|
+
def_delegators :logger, :log, :<<, :debug, :info, :warn, :error, :fatal, :unknown
|
38
43
|
|
39
44
|
def initialize(name, project, workspace, **kwargs)
|
40
45
|
@name = name.to_s
|
41
46
|
@path = workspace.root_path(project.to_s)
|
42
47
|
@project = @path.basename.to_s
|
43
48
|
@workspace = workspace
|
49
|
+
@group = kwargs[:group]&.to_s
|
44
50
|
@depend = kwargs[:depend]
|
45
51
|
@doc = kwargs[:doc]
|
46
|
-
@
|
47
|
-
|
48
|
-
opts = env('BUILD', strict: true)
|
49
|
-
raise ArgumentError, message("BUILD_#{name.to_s.upcase}", opts) if opts && run.is_a?(::Array)
|
50
|
-
|
51
|
-
@output = [run, opts]
|
52
|
+
@test = kwargs[:test]
|
53
|
+
@output = [kwargs[:run], nil]
|
52
54
|
@copy = kwargs[:copy]
|
53
55
|
@clean = kwargs[:clean]
|
54
56
|
log = kwargs[:log]
|
55
57
|
log = { file: log } unless log.is_a?(::Hash)
|
56
58
|
if (logfile = env('LOG_FILE')).nil? && (auto = env('LOG_AUTO'))
|
57
|
-
require 'date'
|
58
59
|
logfile = case auto
|
59
60
|
when 'y', 'year'
|
60
|
-
"#{name}-#{Date.today.year}.log"
|
61
|
+
"#{@name}-#{Date.today.year}.log"
|
61
62
|
when 'm', 'month'
|
62
|
-
"#{name}-#{Date.today.strftime('%Y-%m')}.log"
|
63
|
+
"#{@name}-#{Date.today.strftime('%Y-%m')}.log"
|
63
64
|
when 'd', 'day', '1'
|
64
|
-
"#{name}-#{Date.today}.log"
|
65
|
-
else
|
66
|
-
log[:file]
|
65
|
+
"#{@name}-#{Date.today}.log"
|
67
66
|
end
|
68
|
-
else
|
69
|
-
logfile = log[:file]
|
70
67
|
end
|
71
|
-
if
|
72
|
-
logfile
|
68
|
+
if logfile ||= log[:file]
|
69
|
+
logfile = Date.today.strftime(logfile)
|
70
|
+
logfile = (dir = env('LOG_DIR')) ? Pathname.new(dir).join(logfile) : Pathname.new(logfile)
|
71
|
+
begin
|
72
|
+
logfile.realdirpath
|
73
|
+
rescue StandardError => e
|
74
|
+
logfile = nil
|
75
|
+
Warning.warn e
|
76
|
+
end
|
73
77
|
end
|
74
|
-
@logger = Logger.new(logfile, level: env('LOG_LEVEL') || log[:level] || Logger::INFO)
|
75
|
-
|
76
|
-
|
78
|
+
@logger = Logger.new(logfile, progname: @name, level: env('LOG_LEVEL') || log[:level] || Logger::INFO)
|
79
|
+
end
|
80
|
+
|
81
|
+
def initialize_build(ref, **kwargs)
|
82
|
+
initialize_script(ref)
|
83
|
+
if (val = env('BUILD', strict: true))
|
84
|
+
@output[0] = val
|
85
|
+
elsif @script && @output[0] != false
|
86
|
+
@output[0] ||= @script[:run]
|
87
|
+
end
|
88
|
+
if env('BUILD', suffix: 'DEV', equals: '0')
|
89
|
+
@dev = false
|
90
|
+
else
|
91
|
+
@dev = kwargs.delete(:dev)
|
92
|
+
if env('BUILD', suffix: 'DEV')
|
93
|
+
@dev = true
|
94
|
+
elsif @dev.nil?
|
95
|
+
@dev = workspace.dev?
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def initialize_script(ref)
|
101
|
+
return unless (script = workspace.script(group: group, ref: ref))
|
102
|
+
|
103
|
+
@depend = script[:depend] if @depend.nil?
|
104
|
+
@doc = script[:doc] if @doc.nil?
|
105
|
+
@test = script[:test] if @test.nil?
|
106
|
+
@clean = script[:clean] if @clean.nil?
|
107
|
+
@script = script
|
77
108
|
end
|
78
109
|
|
79
110
|
def populate(*)
|
80
|
-
namespace
|
81
|
-
|
111
|
+
namespace name do
|
112
|
+
workspace.series.each_key do |key|
|
82
113
|
case key
|
83
|
-
when :build, :refresh, :depend, :outdated, :doc, :copy, :clean
|
114
|
+
when :build, :refresh, :depend, :outdated, :doc, :test, :copy, :clean
|
84
115
|
next unless has?(key)
|
85
116
|
else
|
86
|
-
next unless
|
117
|
+
next unless workspace.task_defined?(self, key)
|
87
118
|
end
|
88
|
-
desc message(
|
119
|
+
desc message(name, key)
|
89
120
|
task key do
|
90
|
-
|
121
|
+
__send__(key)
|
91
122
|
end
|
92
123
|
end
|
93
124
|
end
|
@@ -114,12 +145,12 @@ module Squared
|
|
114
145
|
cmd = compose(opts)
|
115
146
|
banner = env('REPO_BUILD') == 'verbose'
|
116
147
|
end
|
117
|
-
run(cmd, exception:
|
148
|
+
run(cmd, exception: workspace.exception, banner: banner)
|
118
149
|
end
|
119
150
|
|
120
151
|
def refresh(*)
|
121
152
|
build
|
122
|
-
key = "#{
|
153
|
+
key = "#{name}:copy"
|
123
154
|
if ::Rake::Task.task_defined?(key)
|
124
155
|
invoke key
|
125
156
|
else
|
@@ -128,36 +159,43 @@ module Squared
|
|
128
159
|
end
|
129
160
|
|
130
161
|
def depend(*)
|
131
|
-
run(@depend, exception:
|
162
|
+
run(@depend, exception: workspace.exception) if @depend
|
132
163
|
end
|
133
164
|
|
134
165
|
def doc
|
135
166
|
build @doc if @doc
|
136
167
|
end
|
137
168
|
|
169
|
+
def test
|
170
|
+
build @test if @test
|
171
|
+
end
|
172
|
+
|
138
173
|
def copy(*)
|
139
174
|
run_s @copy
|
140
175
|
end
|
141
176
|
|
142
177
|
def clean
|
143
|
-
return
|
144
|
-
|
145
|
-
@clean&.each do |path|
|
146
|
-
path = path.to_s
|
147
|
-
if %r{[\\/]$}.match?(path)
|
148
|
-
dir = Pathname.new(path)
|
149
|
-
dir = base_path(dir) unless dir.absolute?
|
150
|
-
next unless dir.directory?
|
178
|
+
return unless @clean
|
151
179
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
180
|
+
if @clean.is_a?(::String)
|
181
|
+
run_s @clean
|
182
|
+
else
|
183
|
+
@clean.each do |val|
|
184
|
+
if (val = val.to_s).match?(%r{[\\/]$})
|
185
|
+
dir = Pathname.new(val)
|
186
|
+
dir = base_path(dir) unless dir.absolute?
|
187
|
+
next unless dir.directory?
|
188
|
+
|
189
|
+
warn "rm -rf #{dir}"
|
190
|
+
dir.rmtree(verbose: true)
|
191
|
+
else
|
192
|
+
files = val.include?('*') ? Dir[base_path(val)] : [base_path(val)]
|
193
|
+
files.each do |file|
|
194
|
+
begin
|
195
|
+
File.delete(file) if File.file?(file)
|
196
|
+
rescue StandardError => e
|
197
|
+
warn e
|
198
|
+
end
|
161
199
|
end
|
162
200
|
end
|
163
201
|
end
|
@@ -165,45 +203,51 @@ module Squared
|
|
165
203
|
end
|
166
204
|
|
167
205
|
def styles
|
168
|
-
|
206
|
+
workspace.styles
|
169
207
|
end
|
170
208
|
|
171
209
|
def base_path(*args)
|
172
|
-
|
210
|
+
path.join(*args)
|
211
|
+
end
|
212
|
+
|
213
|
+
def inspect
|
214
|
+
"#<#{self.class}: #{name} => #{self}>"
|
173
215
|
end
|
174
216
|
|
175
217
|
def to_s
|
176
|
-
|
218
|
+
path.to_s
|
177
219
|
end
|
178
220
|
|
179
221
|
def to_sym
|
180
|
-
|
222
|
+
name.to_sym
|
181
223
|
end
|
182
224
|
|
183
225
|
def enabled?
|
184
|
-
|
226
|
+
path.directory? && !path.empty?
|
185
227
|
end
|
186
228
|
|
187
229
|
def has?(method)
|
188
|
-
respond_to?(m = :"#{method}?") &&
|
230
|
+
respond_to?(m = :"#{method}?") && __send__(m)
|
189
231
|
end
|
190
232
|
|
191
233
|
def build?
|
192
|
-
|
193
|
-
|
194
|
-
!doc? || !@output[0].nil?
|
234
|
+
!!@output[0]
|
195
235
|
end
|
196
236
|
|
197
237
|
def refresh?
|
198
|
-
build?
|
238
|
+
build? && (copy? || ::Rake::Task.task_defined?("#{name}:copy"))
|
199
239
|
end
|
200
240
|
|
201
241
|
def depend?
|
202
|
-
|
242
|
+
!!@depend
|
203
243
|
end
|
204
244
|
|
205
245
|
def doc?
|
206
|
-
|
246
|
+
!!@doc
|
247
|
+
end
|
248
|
+
|
249
|
+
def test?
|
250
|
+
!!@test
|
207
251
|
end
|
208
252
|
|
209
253
|
def copy?
|
@@ -211,11 +255,7 @@ module Squared
|
|
211
255
|
end
|
212
256
|
|
213
257
|
def clean?
|
214
|
-
|
215
|
-
end
|
216
|
-
|
217
|
-
def verbose?
|
218
|
-
@workspace.verbose && !pipe?
|
258
|
+
!!@clean
|
219
259
|
end
|
220
260
|
|
221
261
|
protected
|
@@ -227,7 +267,7 @@ module Squared
|
|
227
267
|
info cmd
|
228
268
|
print_item format_banner(cmd, banner: banner)
|
229
269
|
begin
|
230
|
-
shell(cmd, chdir:
|
270
|
+
shell(cmd, chdir: path, exception: exception)
|
231
271
|
rescue StandardError => e
|
232
272
|
error e
|
233
273
|
raise
|
@@ -235,37 +275,33 @@ module Squared
|
|
235
275
|
end
|
236
276
|
|
237
277
|
def run_s(cmd)
|
238
|
-
run(cmd, exception:
|
278
|
+
run(cmd, exception: workspace.exception, banner: verbose?) if cmd.is_a?(::String)
|
239
279
|
end
|
240
280
|
|
241
281
|
def env(key, suffix: nil, equals: nil, strict: false)
|
242
|
-
|
282
|
+
alt = "#{key}_#{name.upcase}"
|
243
283
|
ret = if suffix
|
244
|
-
ENV.fetch(([
|
284
|
+
ENV.fetch(([alt] + as_a(suffix)).join('_'), '')
|
245
285
|
else
|
246
|
-
ENV.fetch(
|
286
|
+
ENV.fetch(alt, strict ? '' : ENV[key]).to_s
|
247
287
|
end
|
248
|
-
|
249
|
-
|
250
|
-
|
288
|
+
if !equals.nil?
|
289
|
+
ret == equals.to_s
|
290
|
+
elsif !ret.empty? && ret != '0'
|
291
|
+
ret
|
292
|
+
end
|
251
293
|
end
|
252
294
|
|
253
295
|
def session(*cmd, options: nil)
|
254
296
|
if (val = ENV["#{(options || cmd.first).upcase}_OPTIONS"])
|
255
|
-
split_escape(val).each
|
256
|
-
cmd << (if opt.start_with?('-')
|
257
|
-
shell_escape(opt).sub('\\=', '=')
|
258
|
-
else
|
259
|
-
opt.size == 1 || /^[a-z]\d+$/i.match?(opt) ? "-#{opt}" : "--#{opt}"
|
260
|
-
end)
|
261
|
-
end
|
297
|
+
split_escape(val).each { |opt| cmd << fill_option(opt) }
|
262
298
|
end
|
263
299
|
@session = JoinSet.new(cmd)
|
264
300
|
end
|
265
301
|
|
266
302
|
def close_session(cmd)
|
267
303
|
return cmd unless cmd.respond_to?(:done)
|
268
|
-
raise ArgumentError, message('none were provided', hint:
|
304
|
+
raise ArgumentError, message('none were provided', hint: name) if cmd.empty?
|
269
305
|
|
270
306
|
@session = nil if cmd == @session
|
271
307
|
cmd.done
|
@@ -277,9 +313,35 @@ module Squared
|
|
277
313
|
puts val unless val.empty? || (val.size == 1 && val.first.nil?)
|
278
314
|
end
|
279
315
|
|
316
|
+
def print_banner(*lines, styles: nil, pad: 0, first: false)
|
317
|
+
n = max_width(lines)
|
318
|
+
ch = ' ' * pad
|
319
|
+
index = -1
|
320
|
+
out = lines.map do |val|
|
321
|
+
index += 1
|
322
|
+
val = ch + val.ljust(n - (pad * 2)) + ch
|
323
|
+
if styles && (!first || index == 0)
|
324
|
+
sub_style(val, *styles)
|
325
|
+
else
|
326
|
+
val
|
327
|
+
end
|
328
|
+
end
|
329
|
+
out << ('-' * n)
|
330
|
+
out.join("\n")
|
331
|
+
end
|
332
|
+
|
333
|
+
def print_footer(*lines)
|
334
|
+
n = max_width(lines)
|
335
|
+
['-' * n, *lines.map { |val| val.ljust(n) }].join("\n")
|
336
|
+
end
|
337
|
+
|
280
338
|
def format_desc(action, flag, opts = nil, req: 'opts*')
|
281
339
|
opts = "#{req}=#{opts.join(',')}" if opts.is_a?(::Array)
|
282
|
-
|
340
|
+
if !flag
|
341
|
+
flag = action
|
342
|
+
action = ''
|
343
|
+
end
|
344
|
+
message(name, action, opts ? "#{flag}[#{opts}]" : flag)
|
283
345
|
end
|
284
346
|
|
285
347
|
def format_banner(cmd, banner: true, multitask: false)
|
@@ -294,9 +356,9 @@ module Squared
|
|
294
356
|
args = [:bold] + args
|
295
357
|
end
|
296
358
|
end
|
297
|
-
|
298
|
-
elsif multitask &&
|
299
|
-
"## #{
|
359
|
+
print_banner(cmd.sub(/^\S+/, &:upcase), path.to_s, styles: args, pad: pad, first: pad == 0)
|
360
|
+
elsif multitask && workspace.multitask?
|
361
|
+
"## #{path} ##"
|
300
362
|
end
|
301
363
|
end
|
302
364
|
|
@@ -310,7 +372,7 @@ module Squared
|
|
310
372
|
|
311
373
|
def guard_params(action, flag, args: nil, key: nil, pat: nil)
|
312
374
|
if args && key
|
313
|
-
return unless (val = args[key]).nil? || (pat && !
|
375
|
+
return unless (val = args[key]).nil? || (pat && !val.match?(pat))
|
314
376
|
|
315
377
|
@session = nil
|
316
378
|
raise ArgumentError, message(action, "#{flag}[#{key}]", hint: val.nil? ? 'missing' : 'invalid')
|
@@ -326,12 +388,16 @@ module Squared
|
|
326
388
|
raise ArgumentError, message('parameter', flag, hint: 'missing')
|
327
389
|
end
|
328
390
|
|
391
|
+
def verbose?
|
392
|
+
workspace.verbose
|
393
|
+
end
|
394
|
+
|
329
395
|
def pipe?
|
330
|
-
|
396
|
+
workspace.pipe
|
331
397
|
end
|
332
398
|
|
333
399
|
def invoked_sync?(action)
|
334
|
-
return true if invoked?(
|
400
|
+
return true if invoked?(sync = "#{action}:sync")
|
335
401
|
|
336
402
|
missing = ->(val) { ::Rake::Task.tasks.none? { |item| item.name == val } }
|
337
403
|
check = lambda do |val|
|
@@ -341,15 +407,21 @@ module Squared
|
|
341
407
|
true
|
342
408
|
end
|
343
409
|
end
|
344
|
-
if
|
345
|
-
ret = check.("#{action}:#{
|
410
|
+
if group
|
411
|
+
ret = check.("#{action}:#{group}")
|
346
412
|
return ret unless ret.nil?
|
347
413
|
end
|
348
|
-
if (base =
|
414
|
+
if (base = workspace.find_base(self))
|
349
415
|
ret = check.("#{action}:#{base.to_sym}")
|
350
416
|
return ret unless ret.nil?
|
351
417
|
end
|
352
|
-
invoked?("#{
|
418
|
+
invoked?("#{name}:#{action}") && (!invoked?(action) || missing.(sync))
|
419
|
+
end
|
420
|
+
|
421
|
+
private
|
422
|
+
|
423
|
+
def max_width(lines)
|
424
|
+
[lines.max_by(&:size).size, Project.line_width].max
|
353
425
|
end
|
354
426
|
end
|
355
427
|
end
|