squared 0.4.16 → 0.4.18

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.
@@ -94,7 +94,7 @@ module Squared
94
94
  PATH.freeze
95
95
  ARG.freeze
96
96
  VAR.each_value(&:freeze)
97
- VAR[:theme].each_value(&:freeze)
97
+ VAR[:theme].each_value { |val| val.freeze.each_value(&:freeze) }
98
98
  VAR.freeze
99
99
  end
100
100
 
@@ -141,11 +141,11 @@ module Squared
141
141
  def apply_style(data, key, args, empty: true)
142
142
  return if data.is_a?(::Symbol) && (data = __get__(:theme)[data]).nil?
143
143
 
144
- set = ->(k, v) { data[k] = check_style(v, empty: empty) }
144
+ set = ->(k, v) { data[k.to_sym] = check_style(v, empty: empty) }
145
145
  if key.is_a?(::Hash)
146
146
  key.each { |k, v| set.call(k, v || args) }
147
147
  else
148
- set.call(key.to_sym, args)
148
+ set.call(key, args)
149
149
  end
150
150
  end
151
151
 
@@ -194,7 +194,7 @@ module Squared
194
194
  end
195
195
  end
196
196
 
197
- def puts_oe(*args, pipe: 1)
197
+ def log_console(*args, pipe: 1)
198
198
  return if args.first == false && args.size == 1
199
199
 
200
200
  if pipe.is_a?(Pathname)
@@ -211,6 +211,8 @@ module Squared
211
211
  (pipe == 2 ? $stderr : $stdout).puts(*args)
212
212
  end
213
213
 
214
+ alias puts_oe log_console
215
+
214
216
  module_function
215
217
 
216
218
  def message(*args, hint: nil, empty: false, space: ARG[:SPACE])
@@ -42,7 +42,7 @@ module Squared
42
42
  list.each do |val|
43
43
  next if grep&.none? { |pat| pat.match?(line) }
44
44
 
45
- items << val.chomp
45
+ items << val.to_s.chomp
46
46
  puts "#{items.size.to_s.rjust(2)}. #{val}"
47
47
  end
48
48
  max = items.size
@@ -92,10 +92,16 @@ module Squared
92
92
  ret.join(join.is_a?(::String) ? join : ' ')
93
93
  end
94
94
 
95
- def fill_option(val, double: false)
95
+ def shell_bin(name, env: true)
96
+ key = name.upcase
97
+ shell_quote((env && ENV["PATH_#{key}"]) || PATH[key] || PATH[key.to_sym] || name,
98
+ option: false, force: false)
99
+ end
100
+
101
+ def fill_option(val, **kwargs)
96
102
  return "-#{val}" if val.match?(/\A(?:[a-z]\d*|\d)\z/i)
97
103
 
98
- shell_escape(val.start_with?('-') ? val : "--#{val}", double: double)
104
+ shell_escape(val.start_with?('-') ? val : "--#{val}", **kwargs)
99
105
  end
100
106
 
101
107
  def quote_option(flag, val, option: true, double: false, merge: false)
@@ -12,9 +12,9 @@ module Squared
12
12
  if RUBY_ENGINE == 'jruby' && Rake::Win32.windows?
13
13
  e = kwargs[:exception]
14
14
  if (dir = kwargs[:chdir]) && ((pwd = Dir.pwd) != dir)
15
- Dir.chdir(dir)
15
+ Dir.chdir dir
16
16
  ret = Kernel.send(name, *args)
17
- Dir.chdir(pwd)
17
+ Dir.chdir pwd
18
18
  else
19
19
  ret = Kernel.send(name, *args)
20
20
  end
@@ -24,7 +24,7 @@ module Squared
24
24
  else
25
25
  return Kernel.send(name, *args, **kwargs)
26
26
  end
27
- return ret if ret || !e
27
+ return ret unless e && !ret && name == :system
28
28
 
29
29
  raise $?.to_s
30
30
  end
@@ -57,23 +57,24 @@ module Squared
57
57
  soft = 0
58
58
  subdir.each do |dir, files|
59
59
  if link
60
- items = files.dup
61
- files.clear
62
- items.each do |file|
63
- if file.exist?
64
- if file.symlink?
65
- next unless force
60
+ files.dup.tap do |items|
61
+ files.clear
62
+ items.each do |file|
63
+ if file.exist?
64
+ if file.symlink?
65
+ next unless force
66
+ else
67
+ files << file
68
+ next
69
+ end
70
+ end
71
+ if link == 'hard'
72
+ FileUtils.ln(file, dir, force: force, verbose: false)
66
73
  else
67
- files << file
68
- next
74
+ FileUtils.ln_s(file, dir, force: force, verbose: false)
69
75
  end
76
+ soft += 1
70
77
  end
71
- if link == 'hard'
72
- FileUtils.ln(file, dir, force: force, verbose: false)
73
- else
74
- FileUtils.ln_s(file, dir, force: force, verbose: false)
75
- end
76
- soft += 1
77
78
  end
78
79
  end
79
80
  next if files.empty?
@@ -94,10 +94,10 @@ module Squared
94
94
  def build
95
95
  return unless enabled?
96
96
 
97
- namespace(ns = task_name(name)) do
97
+ namespace task_name(name) do |ns|
98
98
  @mime.each do |type, items|
99
99
  items.each do |command, file, opts|
100
- next if Rake::Task.task_defined?("#{ns}:#{command}:#{type}")
100
+ next if Rake::Task.task_defined?("#{ns.scope.path}:#{command}:#{type}")
101
101
 
102
102
  namespace command do
103
103
  unless (data = @@mime_obj[type])
@@ -196,7 +196,7 @@ module Squared
196
196
  private
197
197
 
198
198
  def puts(*args)
199
- puts_oe(*args, pipe: pipe)
199
+ log_console(*args, pipe: pipe)
200
200
  end
201
201
 
202
202
  def log
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.4.16'
4
+ VERSION = '0.4.18'
5
5
  end
@@ -26,7 +26,7 @@ module Squared
26
26
  next unless base || obj < impl_project
27
27
 
28
28
  if base
29
- @impl_project = obj
29
+ self.impl_project = obj
30
30
  impl_series.base_set(obj)
31
31
  else
32
32
  kind_project.unshift(obj)
@@ -39,7 +39,7 @@ module Squared
39
39
  impl_series.alias(*args)
40
40
  end
41
41
  if (args = obj.bannerargs)
42
- @attr_banner.merge(args)
42
+ attr_banner.merge(args)
43
43
  end
44
44
  end
45
45
  end
@@ -95,9 +95,15 @@ module Squared
95
95
  @kind = Support.hashlist
96
96
  @extensions = []
97
97
  @envname = env_key(@main).freeze
98
- @pipe = env_pipe(pipe, (ARG[:OUT] && env(ARG[:OUT])) || 1, root: @home)
98
+ @pipe = $DEBUG ? 2 : env_pipe(pipe, (ARG[:OUT] && env(ARG[:OUT])) || 1, root: @home)
99
99
  @exception = env_bool exception
100
- @verbose = env_bool(verbose, verbose.nil? || verbose.is_a?(String) ? @pipe != 0 : verbose, index: true)
100
+ @verbose = if $VERBOSE.nil?
101
+ false
102
+ elsif verbose.nil?
103
+ @pipe != 0
104
+ else
105
+ env_bool(verbose, verbose.is_a?(String) ? @pipe != 0 : verbose, index: true)
106
+ end
101
107
  @warning = @verbose != false
102
108
  @closed = false
103
109
  if common
@@ -423,7 +429,7 @@ module Squared
423
429
  ret << proj if proj
424
430
  end
425
431
  end
426
- return (group || ref ? ret : ret[0]) unless block_given?
432
+ return (group || ref ? ret : ret.first) unless block_given?
427
433
 
428
434
  ret.each(&blk)
429
435
  self
@@ -678,6 +684,10 @@ module Squared
678
684
  { exception: exception, warning: warning }
679
685
  end
680
686
 
687
+ def size
688
+ @project.size
689
+ end
690
+
681
691
  def to_s
682
692
  (home? ? home : root).to_s
683
693
  end
@@ -691,9 +701,14 @@ module Squared
691
701
  private
692
702
 
693
703
  def __build__(default: nil, **)
694
- return unless default && task_defined?(out = task_name(default))
695
-
696
- task Rake.application.default_task_name => out
704
+ unless task_defined?('squared:version')
705
+ task 'squared:version' do
706
+ puts Squared::VERSION
707
+ end
708
+ end
709
+ if default && task_defined?(out = task_name(default))
710
+ task Rake.application.default_task_name => out
711
+ end
697
712
  end
698
713
 
699
714
  def __chain__(*)
@@ -795,8 +810,8 @@ module Squared
795
810
  format_desc key
796
811
  task key do
797
812
  unless failed.empty? && group.empty?
798
- puts log_message(Logger::ERROR, *(failed + group.map { |val| val.action }.flatten),
799
- subject: 'failed placement', hint: false)
813
+ puts(log_message(Logger::ERROR, *(failed + group.map { |val| val.action }.flatten),
814
+ subject: 'failed placement', hint: false), pipe: 2)
800
815
  end
801
816
  cols = level.flatten(1).map(&:size).max
802
817
  level.each_with_index do |grp, n|
@@ -812,8 +827,8 @@ module Squared
812
827
  end
813
828
  end
814
829
 
815
- def puts(*args)
816
- puts_oe(*args, pipe: pipe)
830
+ def puts(*args, **kwargs)
831
+ log_console(*args, pipe: kwargs[:pipe] || pipe)
817
832
  end
818
833
 
819
834
  def script_command(task, val, group, ref, on, &blk)
@@ -21,8 +21,8 @@ module Squared
21
21
  VAR_SET = %i[parent global script index envname desc dependfile dependindex theme archive env dev prod graph
22
22
  pass only exclude].freeze
23
23
  BLK_SET = %i[run depend doc lint test copy clean].freeze
24
- SEM_VER = /\b(\d+)(?:(\.)(\d+))?(?:(\.)(\d+)(\S+)?)?\b/.freeze
25
- URI_SCHEME = %r{^([a-z][a-z\d+-.]*)://[^@:\[\]\\^<>|\s]}i.freeze
24
+ SEM_VER = /\b(\d+)(?:(\.)(\d+))?(?:(\.)(\d+))?[-.]?(\S+)?\b/.freeze
25
+ URI_SCHEME = %r{\A([a-z][a-z\d+-.]*)://[^@:\[\]\\^<>|\s]}i.freeze
26
26
  TASK_METADATA = Rake::TaskManager.record_task_metadata
27
27
  private_constant :VAR_SET, :BLK_SET, :SEM_VER, :URI_SCHEME, :TASK_METADATA
28
28
 
@@ -208,7 +208,7 @@ module Squared
208
208
  def initialize_env(dev: nil, prod: nil, **)
209
209
  @dev = env_match('BUILD', dev, suffix: 'DEV', strict: true)
210
210
  @prod = env_match('BUILD', prod, suffix: 'PROD', strict: true)
211
- if @output[2] != false && (val = env('BUILD', suffix: 'ENV'))
211
+ unless @output[2] == false || !(val = env('BUILD', suffix: 'ENV'))
212
212
  @output[2] = parse_json(val, hint: "BUILD_#{@envname}_ENV") || @output[2]
213
213
  end
214
214
  unless @output[0] == false || @output[0].is_a?(Array)
@@ -313,7 +313,7 @@ module Squared
313
313
  flags.each do |flag|
314
314
  case action
315
315
  when 'graph'
316
- next unless graph?
316
+ break unless graph?
317
317
 
318
318
  format_desc action, flag, '(-)project*'
319
319
  task flag do |_, args|
@@ -455,13 +455,13 @@ module Squared
455
455
  if args.first.is_a?(Struct)
456
456
  f, blk = args.first.to_a
457
457
  args[0] = instance_eval(&blk) || f
458
- return unless args[0]
458
+ return unless args.first
459
459
  end
460
460
  if args.all? { |val| val.is_a?(Array) }
461
461
  cmd = []
462
462
  var = {}
463
463
  args.each do |val|
464
- next instance_exec(*val[1..-1], &val[0]) if val.first.is_a?(Proc)
464
+ next instance_exec(*val[1..-1], &val.first) if val.first.is_a?(Proc)
465
465
 
466
466
  a, b, c, d, e = val
467
467
  case b
@@ -662,7 +662,7 @@ module Squared
662
662
  when 128, 'sha512'
663
663
  Digest::SHA512
664
664
  else
665
- raise_error("invalid checksum: #{digest}", hint: name)
665
+ raise_error "invalid checksum: #{digest}"
666
666
  end
667
667
  end
668
668
  if (val = env('HEADERS')) && (val = parse_json(val, hint: "HEADERS_#{@envname}"))
@@ -948,7 +948,7 @@ module Squared
948
948
  def log
949
949
  return @log unless @log.is_a?(Array)
950
950
 
951
- @log = Logger.new(enabled? ? @log[0] : nil, **@log[1])
951
+ @log = Logger.new(enabled? ? @log.first : nil, **@log.last)
952
952
  end
953
953
 
954
954
  def allref
@@ -989,20 +989,18 @@ module Squared
989
989
 
990
990
  private
991
991
 
992
- def puts(*args)
993
- puts_oe(*args, pipe: pipe)
992
+ def puts(*args, **kwargs)
993
+ log_console(*args, pipe: kwargs[:pipe] || pipe)
994
994
  end
995
995
 
996
996
  def run(cmd = @session, var = nil, exception: self.exception, sync: true, from: nil, banner: true, chdir: path,
997
- interactive: nil, **)
997
+ interactive: nil, hint: nil, **)
998
998
  unless cmd
999
999
  warn log_message(Logger::WARN, 'no command given', subject: project, hint: from || 'unknown', pass: true)
1000
1000
  return
1001
1001
  end
1002
- i = interactive && !(@session && option('y'))
1003
1002
  cmd = cmd.target if cmd.is_a?(OptionPartition)
1004
- cmd = session_done cmd
1005
- if i
1003
+ if interactive && (!@session || !option('y'))
1006
1004
  title, y = case interactive
1007
1005
  when Array
1008
1006
  interactive
@@ -1011,10 +1009,10 @@ module Squared
1011
1009
  else
1012
1010
  ['Run', 'Y']
1013
1011
  end
1014
- unless confirm("#{title}? [#{sub_style(cmd, styles: theme[:inline])}] #{y == 'Y' ? '[Y/n]' : '[y/N]'} ", y)
1015
- exit 1
1016
- end
1012
+ yn = y == 'Y' ? 'Y/n' : 'y/N'
1013
+ exit 1 unless confirm("#{title}? [#{sub_style(cmd.to_s, styles: theme[:inline])}] [#{yn}] ", y)
1017
1014
  end
1015
+ cmd = session_done cmd
1018
1016
  log&.info cmd
1019
1017
  on :first, from
1020
1018
  begin
@@ -1022,7 +1020,7 @@ module Squared
1022
1020
  log&.warn "ENV discarded: #{var}" if var
1023
1021
  task_invoke(cmd, exception: exception, warning: warning?)
1024
1022
  else
1025
- print_item format_banner(cmd, banner: banner) if sync
1023
+ print_item format_banner(hint ? "#{cmd} (#{hint})" : cmd, banner: banner) if sync
1026
1024
  if var != false && (pre = runenv)
1027
1025
  case pre
1028
1026
  when Hash
@@ -1231,12 +1229,12 @@ module Squared
1231
1229
  end
1232
1230
 
1233
1231
  def session(*cmd, prefix: cmd.first, main: true, path: true, options: true)
1234
- prefix = stripext(prefix.to_s).upcase
1235
- if path && (val = ENV["PATH_#{prefix}"] || PATH[prefix] || PATH[prefix.to_sym])
1232
+ prefix = stripext prefix.to_s
1233
+ if path && (val = shell_bin(prefix))
1236
1234
  cmd[0] = shell_quote(val, force: false)
1237
1235
  end
1238
1236
  ret = JoinSet.new(cmd.flatten(1))
1239
- if options && (val = env("#{prefix}_OPTIONS"))
1237
+ if options && (val = env("#{prefix.upcase}_OPTIONS"))
1240
1238
  split_escape(val).each { |opt| ret.last(fill_option(opt), /\A(--?[^ =]+)[ =].+\z/m) }
1241
1239
  end
1242
1240
  main ? @session = ret : ret
@@ -1261,7 +1259,7 @@ module Squared
1261
1259
  def session_done(cmd)
1262
1260
  return cmd unless cmd.respond_to?(:done)
1263
1261
 
1264
- raise_error('no args added', hint: cmd.first || name) unless cmd.size > 1
1262
+ raise_error('no args added', hint: cmd.first) unless cmd.size > 1
1265
1263
  @session = nil if cmd == @session
1266
1264
  cmd.done
1267
1265
  end
@@ -1420,9 +1418,9 @@ module Squared
1420
1418
  unless items.empty?
1421
1419
  pad = items.size.to_s.size
1422
1420
  items.each_with_index do |val, i|
1423
- next unless reg.empty? || reg.any? { |pat| val[0].match?(pat) }
1421
+ next unless matchany?(val.first, reg)
1424
1422
 
1425
- out << "#{i.succ.to_s.rjust(pad)}. #{each ? each.call(val) : val[0]}"
1423
+ out << "#{i.succ.to_s.rjust(pad)}. #{each ? each.call(val) : val.first}"
1426
1424
  end
1427
1425
  end
1428
1426
  sub = [headerstyle]
@@ -1744,6 +1742,17 @@ module Squared
1744
1742
  files.map { |val| val == '.' ? '.' : shell_quote(path + val) }
1745
1743
  end
1746
1744
 
1745
+ def matchmap(list, prefix = nil)
1746
+ list.map do |val|
1747
+ if val.is_a?(Regexp)
1748
+ val
1749
+ else
1750
+ val = ".*#{val}" if prefix && !val.sub!(/\A(\^|\\A)/, '')
1751
+ Regexp.new("#{prefix}#{val == '*' ? '.+' : val}")
1752
+ end
1753
+ end
1754
+ end
1755
+
1747
1756
  def semver(val)
1748
1757
  return val if val[3]
1749
1758
 
@@ -1762,12 +1771,20 @@ module Squared
1762
1771
  end
1763
1772
 
1764
1773
  def semcmp(val, other)
1765
- a, b = [val, other].map! { |ver| ver.match(SEM_VER) }
1766
- return 1 unless a
1767
- return -1 unless b
1768
- return 0 if a[0] == b[0]
1774
+ return 0 if val == other
1769
1775
 
1770
- a, b = [a, b].map! { |c| [c[1], c[3], c[5] || '0'] }
1776
+ a, b = [val, other].map! { |ver| ver.scan(SEM_VER) }
1777
+ return -1 if b.empty?
1778
+ return 1 if a.empty?
1779
+
1780
+ a, b = [a.first, b.first].map! do |c|
1781
+ begin
1782
+ d = Integer(c[5]).to_s
1783
+ rescue StandardError
1784
+ d = c[5] ? '-1' : '0'
1785
+ end
1786
+ [c[0], c[2], c[4] || '0', d]
1787
+ end
1771
1788
  a.each_with_index do |c, index|
1772
1789
  next if c == (d = b[index])
1773
1790
 
@@ -1776,6 +1793,10 @@ module Squared
1776
1793
  0
1777
1794
  end
1778
1795
 
1796
+ def semgte?(val, other)
1797
+ semcmp(val, other) != 1
1798
+ end
1799
+
1779
1800
  def indexitem(val)
1780
1801
  [$1.to_i, $2 && $2[1..-1]] if val =~ /\A[=^#{indexchar}](\d+)(:.+)?\z/
1781
1802
  end
@@ -1819,7 +1840,7 @@ module Squared
1819
1840
  def on(event, from, *args, **kwargs)
1820
1841
  return unless from && @events.key?(event)
1821
1842
 
1822
- @events[event][from]&.each do |obj|
1843
+ Array(@events[event][from]).each do |obj|
1823
1844
  target, opts = if obj.is_a?(Array) && obj[1].is_a?(Hash)
1824
1845
  [obj[0], kwargs.empty? ? obj[1] : obj[1].merge(kwargs)]
1825
1846
  else
@@ -1849,13 +1870,12 @@ module Squared
1849
1870
  pwd = Pathname.pwd
1850
1871
  if block_given?
1851
1872
  begin
1852
- pass = semscan(pass).join <= RUBY_VERSION if pass.is_a?(String)
1853
1873
  if (path == pwd || pass == true) && (workspace.mri? || !workspace.windows?)
1854
1874
  ret = yield
1855
1875
  else
1856
- Dir.chdir(path)
1876
+ Dir.chdir path
1857
1877
  ret = yield
1858
- Dir.chdir(pwd)
1878
+ Dir.chdir pwd
1859
1879
  end
1860
1880
  rescue StandardError => e
1861
1881
  on_error(e, from, dryrun: dryrun)
@@ -1878,8 +1898,8 @@ module Squared
1878
1898
  end
1879
1899
 
1880
1900
  def run_set(cmd, val = nil, opts: nil, **)
1881
- diso = @output[1] == false && !@output[0].nil?
1882
- dise = @output[2] == false
1901
+ noopt = @output[1] == false && !@output[0].nil?
1902
+ noenv = @output[2] == false
1883
1903
  parse = lambda do |data|
1884
1904
  ret = []
1885
1905
  if data[:command]
@@ -1899,8 +1919,8 @@ module Squared
1899
1919
  case cmd
1900
1920
  when Array
1901
1921
  @output = if cmd.all? { |data| data.is_a?(Hash) }
1902
- diso = false
1903
- dise = false
1922
+ noopt = false
1923
+ noenv = false
1904
1924
  cmd.map { |data| parse.call(data) }
1905
1925
  else
1906
1926
  cmd.dup
@@ -1911,14 +1931,14 @@ module Squared
1911
1931
  else
1912
1932
  @output[0] = cmd
1913
1933
  end
1914
- unless diso
1934
+ unless noopt
1915
1935
  if opts == false
1916
1936
  @output[1] = false
1917
1937
  elsif opts && opts != true
1918
1938
  @output[1] = opts
1919
1939
  end
1920
1940
  end
1921
- return if dise
1941
+ return if noenv
1922
1942
 
1923
1943
  if val.is_a?(Hash)
1924
1944
  @output[2] = val
@@ -2021,6 +2041,10 @@ module Squared
2021
2041
  @only ? !@only.include?(key) : @pass.include?(key)
2022
2042
  end
2023
2043
 
2044
+ def matchany?(val, list, empty: true)
2045
+ list.empty? ? empty : list.any? { |pat| val.match?(pat) }
2046
+ end
2047
+
2024
2048
  def projectpath?(val)
2025
2049
  val = Pathname.new(val).cleanpath
2026
2050
  val.absolute? ? val.to_s.start_with?(File.join(path, '')) : !val.to_s.start_with?(File.join('..', ''))