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.
@@ -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 (data = /\A(--?[^= ]+)((=|\s+)(["'])?(.+?)(["'])?)?\z/m.match(val = val.to_s))
13
- return val if !data[2] || (!data[4] && !data[5].match?(/\s/))
14
-
15
- join = ->(opt) { data[1] + data[3] + shell_quote(opt) }
16
- if data[4] == data[6]
17
- data[4] ? val : join.(data[5])
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
- join.(data[4] + data[5] + data[6])
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
- val.empty? ? '' : Shellwords.escape(val)
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
- val.join(join.is_a?(::String) ? join : ' ')
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, b = flag.size == 1 ? ['-', ' '] : ['--', '=']
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 fill_option(val)
61
- return "-#{val}" if val =~ /\A[a-z](?:\d*)\z/i
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
- shell_escape(val.start_with?('-') ? val : "--#{val}")
64
- end
78
+ ret = ret.map { |opt| shell_escape(opt, quote: quote) } if escape
79
+ return ret unless join
65
80
 
66
- def quote_option(flag, val)
67
- shell_option(flag, val, escape: false)
81
+ ret.join(join.is_a?(::String) ? join : ' ')
68
82
  end
69
83
 
70
- def basic_option(flag, val)
71
- shell_option(flag, val, escape: false, force: false)
72
- end
84
+ def fill_option(val, double: false)
85
+ return "-#{val}" if val.match?(/^[a-z]\d*$/i)
73
86
 
74
- def single_quote(val)
75
- val.gsub("'", "'\\\\''")
87
+ shell_escape(val.start_with?('-') ? val : "--#{val}", double: double)
76
88
  end
77
89
 
78
- def double_quote(val)
79
- val.gsub(/(?<!\\)"/, '\\"')
90
+ def quote_option(flag, val, double: false)
91
+ shell_option(flag, val, escape: false, double: double)
80
92
  end
81
93
 
82
- def split_escape(val, char: ',')
83
- val.split(/\s*(?<!\\)#{char}\s*/)
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
@@ -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 =~ val : val == 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.between?(0, 2)
144
+ return key if key >= 0 && key <= 2
92
145
  end
93
146
  default
94
147
  end
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.3.10'
4
+ VERSION = '0.4.0'
5
5
  end
@@ -173,7 +173,7 @@ module Squared
173
173
  when Symbol
174
174
  @ref = val
175
175
  else
176
- raise_error('group{Symbol} | ref{String}', hint: 'missing') if block_given?
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|\^)/ =~ key || /(\\z|\$)\z/ =~ key
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)}:/, '') : val.to_s
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
- if (index = data.size) > 0
419
- data.to_a.reverse_each { |group| out.sub!("%#{index -= 1}", group) }
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, key|
424
- next unless (data = pat.match(val))
422
+ @describe[:replace].each do |pat, tmpl|
423
+ next unless val =~ pat
425
424
 
426
- val = replace.(data, key.dup)
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 (data = pat.match(val))
433
+ next unless val =~ pat
435
434
 
436
- val = replace.(data, key.dup)
435
+ val = replace.($~, key.dup)
437
436
  found = true
438
437
  break
439
438
  end
440
439
  end
441
- args = Shell.split_escape(val, char: ':').map! { |s| s.gsub('\\:', ':') } if found
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 =~ item : key == item }
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 =~ pat } : pat == true
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