squared 0.3.10 → 0.4.0
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 +44 -103
- data/README.md +13 -2
- data/README.ruby.md +169 -89
- data/lib/squared/app.rb +1 -0
- data/lib/squared/common/base.rb +6 -1
- data/lib/squared/common/class.rb +1 -1
- data/lib/squared/common/format.rb +31 -19
- data/lib/squared/common/prompt.rb +3 -3
- data/lib/squared/common/shell.rb +53 -41
- data/lib/squared/common/utils.rb +55 -2
- data/lib/squared/config.rb +1 -1
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +18 -15
- data/lib/squared/workspace/project/base.rb +458 -170
- data/lib/squared/workspace/project/docker.rb +572 -0
- data/lib/squared/workspace/project/git.rb +471 -230
- data/lib/squared/workspace/project/node.rb +51 -51
- data/lib/squared/workspace/project/python.rb +130 -41
- data/lib/squared/workspace/project/ruby.rb +47 -58
- data/lib/squared/workspace/project.rb +7 -1
- data/lib/squared/workspace/repo.rb +11 -4
- data/lib/squared/workspace/series.rb +1 -1
- metadata +3 -2
data/lib/squared/common/shell.rb
CHANGED
@@ -8,79 +8,91 @@ module Squared
|
|
8
8
|
module Shell
|
9
9
|
module_function
|
10
10
|
|
11
|
-
def shell_escape(val, quote: false, force: false)
|
12
|
-
if (
|
13
|
-
return val if !
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
11
|
+
def shell_escape(val, quote: false, force: false, double: false, override: false)
|
12
|
+
if (r = /\A(--?)([^= ]+)((=|\s+)(["'])?(.+?)(["'])?)?\z/m.match(val = val.to_s))
|
13
|
+
return val if !r[3] || (!r[5] && r[6].match?(/\s/))
|
14
|
+
|
15
|
+
combine = lambda do |opt|
|
16
|
+
if r[2] =~ /^(["'])(.+)\1$/
|
17
|
+
double = $1 == '"'
|
18
|
+
r[2] = $2
|
19
|
+
override = true
|
20
|
+
end
|
21
|
+
r[1] + r[2] + r[4] + shell_quote(opt, double: double, force: force, override: override)
|
22
|
+
end
|
23
|
+
if r[5] == r[7]
|
24
|
+
r[5] ? val : combine.(r[6])
|
18
25
|
else
|
19
|
-
|
26
|
+
force = true
|
27
|
+
combine.(r[5] + r[6] + r[7])
|
20
28
|
end
|
21
29
|
elsif Rake::Win32.windows?
|
22
|
-
quote ? shell_quote(val, force: force) : val
|
30
|
+
quote ? shell_quote(val, double: double, force: force) : val
|
23
31
|
else
|
24
|
-
|
32
|
+
Shellwords.escape(val)
|
25
33
|
end
|
26
34
|
end
|
27
35
|
|
28
|
-
def shell_quote(val, force: true)
|
36
|
+
def shell_quote(val, option: true, force: true, double: false, override: false)
|
29
37
|
val = val.to_s
|
30
|
-
return val if !force && !val.include?(' ')
|
31
|
-
return val if option && val =~ /(?:^|\S=|[^=]\s+|#{Rake::Win32.windows? ? '[\\\/]' : '\/'})(["']).+\1\z/m
|
32
|
-
|
33
|
-
Rake::Win32.windows? || ARG[:QUOTE] == '"' ? "\"#{double_quote(val)}\"" : "'#{single_quote(val)}'"
|
34
|
-
end
|
35
|
-
|
36
|
-
def shell_split(val, escape: true, quote: false, join: nil)
|
37
|
-
val = Shellwords.split(val)
|
38
|
-
val = val.map { |opt| shell_escape(opt, quote: quote) } if escape
|
39
|
-
return val unless join
|
38
|
+
return val if (!force && !val.include?(' ')) || (option && val.match?(/(?:^|\S=|[^=]\s+)(["']).+\1\z/m))
|
40
39
|
|
41
|
-
|
40
|
+
if double || Rake::Win32.windows? || (ARG[:QUOTE] == '"' && !override)
|
41
|
+
"\"#{val.gsub(/(?<!\\)"/, '\\"')}\""
|
42
|
+
else
|
43
|
+
"'#{val.gsub("'", "'\\\\''")}'"
|
44
|
+
end
|
42
45
|
end
|
43
46
|
|
44
|
-
def shell_option(flag, val = nil, escape: true, quote: true, force: true
|
47
|
+
def shell_option(flag, val = nil, escape: true, quote: true, force: true, double: false, override: false,
|
48
|
+
merge: false)
|
45
49
|
flag = flag.to_s
|
50
|
+
if flag =~ /^(["'])(.+)\1$/
|
51
|
+
double = $1 == '"'
|
52
|
+
flag = $2
|
53
|
+
escape = false
|
54
|
+
override = true
|
55
|
+
end
|
46
56
|
if flag[0] == '-'
|
47
57
|
b = flag[1] == '-' ? '=' : ' '
|
58
|
+
elsif flag.size == 1
|
59
|
+
a = '-'
|
60
|
+
b = merge ? '' : ' '
|
48
61
|
else
|
49
|
-
a
|
62
|
+
a = '--'
|
63
|
+
b = '='
|
50
64
|
end
|
51
65
|
"#{a}#{flag}#{if val
|
52
66
|
"#{b}#{if escape
|
53
|
-
shell_escape(val, quote: quote)
|
67
|
+
shell_escape(val, quote: quote, double: double, override: override)
|
54
68
|
else
|
55
|
-
quote ? shell_quote(val, force: force) : val
|
69
|
+
quote ? shell_quote(val, force: force, double: double, override: override) : val
|
56
70
|
end}"
|
57
71
|
end}"
|
58
72
|
end
|
59
73
|
|
60
|
-
def
|
61
|
-
|
74
|
+
def shell_split(val, escape: true, quote: false, join: nil)
|
75
|
+
ret = Shellwords.split(val)
|
76
|
+
return ret if join == false
|
62
77
|
|
63
|
-
|
64
|
-
|
78
|
+
ret = ret.map { |opt| shell_escape(opt, quote: quote) } if escape
|
79
|
+
return ret unless join
|
65
80
|
|
66
|
-
|
67
|
-
shell_option(flag, val, escape: false)
|
81
|
+
ret.join(join.is_a?(::String) ? join : ' ')
|
68
82
|
end
|
69
83
|
|
70
|
-
def
|
71
|
-
|
72
|
-
end
|
84
|
+
def fill_option(val, double: false)
|
85
|
+
return "-#{val}" if val.match?(/^[a-z]\d*$/i)
|
73
86
|
|
74
|
-
|
75
|
-
val.gsub("'", "'\\\\''")
|
87
|
+
shell_escape(val.start_with?('-') ? val : "--#{val}", double: double)
|
76
88
|
end
|
77
89
|
|
78
|
-
def
|
79
|
-
|
90
|
+
def quote_option(flag, val, double: false)
|
91
|
+
shell_option(flag, val, escape: false, double: double)
|
80
92
|
end
|
81
93
|
|
82
|
-
def
|
83
|
-
val
|
94
|
+
def basic_option(flag, val, merge: false)
|
95
|
+
shell_option(flag, val, escape: false, force: false, merge: merge)
|
84
96
|
end
|
85
97
|
end
|
86
98
|
end
|
data/lib/squared/common/utils.rb
CHANGED
@@ -8,6 +8,10 @@ module Squared
|
|
8
8
|
module Utils
|
9
9
|
module_function
|
10
10
|
|
11
|
+
def split_escape(val, char: ',')
|
12
|
+
val.split(/\s*(?<!\\)#{char}\s*/o)
|
13
|
+
end
|
14
|
+
|
11
15
|
def task_invoke(*cmd, args: [], exception: true, warning: true)
|
12
16
|
cmd.each { |name| Rake::Task[name].invoke(*args) }
|
13
17
|
rescue StandardError => e
|
@@ -31,8 +35,57 @@ module Squared
|
|
31
35
|
Rake::Task.tasks.any? do |obj|
|
32
36
|
next unless obj.already_invoked
|
33
37
|
|
34
|
-
args.any? { |val| val.is_a?(::Regexp) ? obj.name
|
38
|
+
args.any? { |val| val.is_a?(::Regexp) ? obj.name.match?(val) : val == obj.name }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def time_format(epoch, clock: false, pass: [])
|
43
|
+
ss = 1000
|
44
|
+
mm = 60 * ss
|
45
|
+
hh = 60 * mm
|
46
|
+
dd = 24 * hh
|
47
|
+
hm = pass.include?('s')
|
48
|
+
time = []
|
49
|
+
if !clock && (d = epoch / dd) > 0
|
50
|
+
time << "#{d}d"
|
51
|
+
epoch -= d * dd
|
52
|
+
end
|
53
|
+
if (h = epoch / hh) > 0
|
54
|
+
time << (clock ? h.to_s : "#{h}h")
|
55
|
+
epoch -= h * hh
|
35
56
|
end
|
57
|
+
if (m = epoch / mm) > 0
|
58
|
+
time << (clock ? m.to_s.rjust(2, '0') : "#{m}m")
|
59
|
+
epoch -= m * mm
|
60
|
+
elsif clock
|
61
|
+
time << '00'
|
62
|
+
end
|
63
|
+
unless hm
|
64
|
+
if (s = epoch / ss) > 0
|
65
|
+
time << (clock ? s.to_s.rjust(2, '0') : "#{s}s")
|
66
|
+
epoch -= s * ss
|
67
|
+
elsif clock
|
68
|
+
time << '00'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
if clock
|
72
|
+
time.join(':')
|
73
|
+
else
|
74
|
+
time << "#{epoch}ms" unless hm || pass.include?('ms')
|
75
|
+
time.join(' ')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def time_offset(val = nil)
|
80
|
+
val = DateTime.parse(val) if val.is_a?(::String)
|
81
|
+
cur = DateTime.now
|
82
|
+
ret = 0
|
83
|
+
if (r = /^([+-])(\d+):(\d+):(\d+)$/.match((val || cur).strftime('%::z')))
|
84
|
+
ret += (r[1] == '+' ? -1 : 1) * ((r[2].to_i * 60 * 60) + (r[3].to_i * 60) + r[4].to_i) * 1000
|
85
|
+
end
|
86
|
+
return ret unless val
|
87
|
+
|
88
|
+
(cur.strftime('%Q').to_i + time_offset) - (val.strftime('%Q').to_i + ret)
|
36
89
|
end
|
37
90
|
|
38
91
|
def env(key, default = nil, suffix: nil, strict: false, equals: nil, ignore: nil)
|
@@ -88,7 +141,7 @@ module Squared
|
|
88
141
|
return ret.to_i
|
89
142
|
end
|
90
143
|
when ::Numeric
|
91
|
-
return key if key
|
144
|
+
return key if key >= 0 && key <= 2
|
92
145
|
end
|
93
146
|
default
|
94
147
|
end
|
data/lib/squared/config.rb
CHANGED
@@ -90,7 +90,7 @@ module Squared
|
|
90
90
|
@required = true
|
91
91
|
project ? [project, 'not found'] : ['name', 'missing']
|
92
92
|
end
|
93
|
-
warn log_message(Logger::WARN, msg, subject: self.class, hint: hint)
|
93
|
+
warn log_message(Logger::WARN, msg, subject: self.class, hint: hint, pass: true)
|
94
94
|
end
|
95
95
|
|
96
96
|
def build
|
data/lib/squared/version.rb
CHANGED
@@ -173,7 +173,7 @@ module Squared
|
|
173
173
|
when Symbol
|
174
174
|
@ref = val
|
175
175
|
else
|
176
|
-
raise_error
|
176
|
+
raise_error 'missing group or ref' if block_given?
|
177
177
|
end
|
178
178
|
if block_given?
|
179
179
|
instance_eval(&blk)
|
@@ -350,14 +350,14 @@ module Squared
|
|
350
350
|
end
|
351
351
|
|
352
352
|
def describe(data)
|
353
|
-
@describe
|
353
|
+
@describe = {
|
354
354
|
alias: {},
|
355
355
|
replace: [],
|
356
356
|
pattern: {}
|
357
357
|
}
|
358
358
|
data.each do |key, val|
|
359
359
|
key = key.to_s
|
360
|
-
if /\A(\\A|\^)/
|
360
|
+
if key.match?(/\A(\\A|\^)/) || key.match?(/(\\z|\$)\z/)
|
361
361
|
@describe[:replace] << [Regexp.new(key), val]
|
362
362
|
else
|
363
363
|
@describe[val.is_a?(Regexp) ? :pattern : :alias][key.to_s] = val
|
@@ -404,7 +404,7 @@ module Squared
|
|
404
404
|
end
|
405
405
|
|
406
406
|
def task_localname(val)
|
407
|
-
prefix && val.is_a?(String) ? val.sub(/\A#{Regexp.escape(prefix)}
|
407
|
+
prefix && val.is_a?(String) ? val.sub(/\A#{Regexp.escape(prefix)}:/o, '') : val.to_s
|
408
408
|
end
|
409
409
|
|
410
410
|
def task_desc(*args, **kwargs)
|
@@ -415,15 +415,14 @@ module Squared
|
|
415
415
|
val = name || task_join(*args)
|
416
416
|
found = false
|
417
417
|
replace = lambda do |data, out|
|
418
|
-
|
419
|
-
|
420
|
-
end
|
418
|
+
index = data.size
|
419
|
+
data.to_a.reverse_each { |group| out.sub!("%#{index -= 1}", group) }
|
421
420
|
out
|
422
421
|
end
|
423
|
-
@describe[:replace].each do |pat,
|
424
|
-
next unless
|
422
|
+
@describe[:replace].each do |pat, tmpl|
|
423
|
+
next unless val =~ pat
|
425
424
|
|
426
|
-
val = replace.(
|
425
|
+
val = replace.($~, tmpl.dup)
|
427
426
|
found = true
|
428
427
|
end
|
429
428
|
if (out = @describe[:alias][val])
|
@@ -431,14 +430,14 @@ module Squared
|
|
431
430
|
found = true
|
432
431
|
else
|
433
432
|
@describe[:pattern].each do |key, pat|
|
434
|
-
next unless
|
433
|
+
next unless val =~ pat
|
435
434
|
|
436
|
-
val = replace.(
|
435
|
+
val = replace.($~, key.dup)
|
437
436
|
found = true
|
438
437
|
break
|
439
438
|
end
|
440
439
|
end
|
441
|
-
args =
|
440
|
+
args = split_escape(val, char: ':').map! { |s| s.gsub('\\:', ':') } if found
|
442
441
|
end
|
443
442
|
desc message(*args, **kwargs)
|
444
443
|
end
|
@@ -564,7 +563,7 @@ module Squared
|
|
564
563
|
|
565
564
|
key = task_join(task_localname(obj.name), key)
|
566
565
|
end
|
567
|
-
@pass[:pattern].any? { |item| item.is_a?(Regexp) ? key
|
566
|
+
@pass[:pattern].any? { |item| item.is_a?(Regexp) ? key.to_s.match?(item) : key == item }
|
568
567
|
end
|
569
568
|
|
570
569
|
def task_defined?(*key)
|
@@ -587,6 +586,10 @@ module Squared
|
|
587
586
|
Rake::Win32.windows?
|
588
587
|
end
|
589
588
|
|
589
|
+
def docker?
|
590
|
+
File.exist?('/.dockerenv')
|
591
|
+
end
|
592
|
+
|
590
593
|
def rootpath(*args)
|
591
594
|
root.join(*args)
|
592
595
|
end
|
@@ -693,7 +696,7 @@ module Squared
|
|
693
696
|
end
|
694
697
|
return false if state == :prod && data[:dev] == true && data[:global]
|
695
698
|
|
696
|
-
target && pat.is_a?(Regexp) ? as_a(target).any? { |val| val
|
699
|
+
target && pat.is_a?(Regexp) ? as_a(target).any? { |val| val.match?(pat) } : pat == true
|
697
700
|
end
|
698
701
|
|
699
702
|
def scriptobj
|