squared 0.4.13 → 0.4.14

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.
@@ -76,8 +76,8 @@ module Squared
76
76
  attr_reader :name, :project, :workspace, :path, :theme, :exception, :pipe, :verbose,
77
77
  :group, :parent, :dependfile
78
78
 
79
- def initialize(workspace, path, name, *, group: nil, archive: nil, first: {}, last: {}, error: {},
80
- common: ARG[:COMMON], **kwargs)
79
+ def initialize(workspace, path, name, *, group: nil, first: {}, last: {}, error: {}, common: ARG[:COMMON],
80
+ **kwargs)
81
81
  @path = path
82
82
  @workspace = workspace
83
83
  @name = name.to_s.freeze
@@ -90,14 +90,7 @@ module Squared
90
90
  @copy = kwargs[:copy]
91
91
  @clean = kwargs[:clean]
92
92
  @version = kwargs[:version]
93
- @archive = case archive
94
- when String, Array
95
- { uri: archive }
96
- when Hash
97
- archive
98
- end
99
93
  @release = kwargs[:release]
100
- @envname = @name.gsub(/[^\w]+/, '_').upcase.freeze
101
94
  @output = []
102
95
  @ref = []
103
96
  @children = []
@@ -106,6 +99,7 @@ module Squared
106
99
  last: last,
107
100
  error: error
108
101
  }
102
+ @envname = env_key(@name).freeze
109
103
  @desc = (@name.include?(':') ? @name.split(':').join(ARG[:SPACE]) : @name).freeze
110
104
  @parent = nil
111
105
  @global = false
@@ -114,10 +108,11 @@ module Squared
114
108
  exception_set kwargs[:exception]
115
109
  pipe_set kwargs[:pipe]
116
110
  verbose_set kwargs[:verbose]
117
- theme_set common
118
111
  graph_set kwargs[:graph]
119
112
  pass_set kwargs[:pass]
120
113
  exclude_set kwargs[:exclude]
114
+ archive_set kwargs[:archive]
115
+ theme_set common
121
116
  initialize_ref Base.ref
122
117
  end
123
118
 
@@ -205,7 +200,7 @@ module Squared
205
200
  file &&= @workspace.home.join(env('LOG_DIR', ''), file).realdirpath
206
201
  rescue StandardError => e
207
202
  file = nil
208
- warn log_message(Logger::WARN, e, pass: true) if warning?
203
+ warn log_message(Logger::WARN, e) if warning?
209
204
  end
210
205
  log[:progname] ||= @name
211
206
  if (val = env('LOG_LEVEL', ignore: false))
@@ -250,14 +245,14 @@ module Squared
250
245
  return 1 if a.include?(other)
251
246
 
252
247
  c, d = graph_deps other
253
- e = b.reject { |val| d.include?(val) }
254
- f = d.reject { |val| b.include?(val) }
248
+ e = b - d
249
+ f = d - b
255
250
  if parent == other.parent
256
251
  g = []
257
252
  h = []
258
253
  else
259
- g = a.reject { |val| c.include?(val) }
260
- h = c.reject { |val| a.include?(val) }
254
+ g = a - c
255
+ h = c - a
261
256
  end
262
257
  g << self
263
258
  h << other
@@ -420,7 +415,7 @@ module Squared
420
415
 
421
416
  out = obj.link(self, *args, **kwargs, &blk) if obj.respond_to?(:link)
422
417
  if !out
423
- warn log_message(Logger::WARN, 'link not compatible', subject: obj.to_s, hint: name, pass: true)
418
+ warn log_message(Logger::WARN, 'link not compatible', subject: obj.to_s, hint: name)
424
419
  elsif out.respond_to?(:build)
425
420
  out.build
426
421
  end
@@ -475,9 +470,9 @@ module Squared
475
470
  case opts
476
471
  when Hash
477
472
  opts = append_hash(opts, build: true)
478
- cmd = as_a(cmd).push(flags).concat(opts).compact.join(' ')
473
+ cmd = Array(cmd).push(flags).concat(opts).compact.join(' ')
479
474
  when Enumerable
480
- cmd = as_a(cmd).concat(opts.to_a)
475
+ cmd = Array(cmd).concat(opts.to_a)
481
476
  cmd.map! { |val| "#{val} #{flags}" } if flags
482
477
  cmd = cmd.join(' && ')
483
478
  else
@@ -513,9 +508,7 @@ module Squared
513
508
  next
514
509
  end
515
510
  end
516
- if warning?
517
- warn log_message(Logger::WARN, name, 'method not found', subject: 'prereqs', hint: meth, pass: true)
518
- end
511
+ warn log_message(Logger::WARN, name, 'method not found', subject: 'prereqs', hint: meth)
519
512
  end
520
513
  elsif proj.build?
521
514
  proj.build(sync: sync)
@@ -659,7 +652,7 @@ module Squared
659
652
  headers = headers.is_a?(Hash) ? headers.merge(val) : val
660
653
  end
661
654
  data = nil
662
- (uri = as_a(uri)).each_with_index do |url, index|
655
+ (uri = Array(uri)).each_with_index do |url, index|
663
656
  fetch_uri(url, headers) do |f|
664
657
  data = f.read
665
658
  if algo && algo.hexdigest(data) != digest
@@ -697,7 +690,7 @@ module Squared
697
690
  file.write(data)
698
691
  file.close
699
692
  if create
700
- warn log_message(Logger::WARN, 'force remove', subject: name, hint: target, pass: true)
693
+ warn log_message(Logger::WARN, 'force remove', subject: name, hint: target)
701
694
  target.rmtree
702
695
  target.mkpath
703
696
  end
@@ -810,6 +803,8 @@ module Squared
810
803
  exclude_set val
811
804
  when :parent
812
805
  parent_set val
806
+ when :archive
807
+ archive_set val
813
808
  when :run
814
809
  run_set(*args, **kwargs)
815
810
  when :script
@@ -971,16 +966,28 @@ module Squared
971
966
  puts_oe(*args, pipe: pipe)
972
967
  end
973
968
 
974
- def run(cmd = @session, var = nil, exception: @exception, sync: true, from: nil, banner: true, chdir: path, **)
969
+ def run(cmd = @session, var = nil, exception: @exception, sync: true, from: nil, banner: true, chdir: path,
970
+ interactive: nil, **)
975
971
  unless cmd
976
- if warning?
977
- from &&= from.to_s
978
- warn log_message(Logger::WARN, from || 'unknown', subject: project, hint: 'no command given', pass: true)
979
- end
980
- return
972
+ from = from&.to_s || 'unknown'
973
+ return warn log_message(Logger::WARN, 'no command given', subject: project, hint: from, pass: true)
981
974
  end
975
+ i = interactive && !(@session && option('y'))
982
976
  cmd = cmd.target if cmd.is_a?(OptionPartition)
983
977
  cmd = session_done cmd
978
+ if i
979
+ title, y = case interactive
980
+ when Array
981
+ interactive
982
+ when String
983
+ [interactive, 'N']
984
+ else
985
+ ['Run', 'Y']
986
+ end
987
+ unless confirm("#{title}? [#{sub_style(cmd, styles: theme[:inline])}] #{y == 'Y' ? '[Y/n]' : '[y/N]'} ", y)
988
+ raise_error('user cancelled', hint: from)
989
+ end
990
+ end
984
991
  log&.info cmd
985
992
  on :first, from
986
993
  begin
@@ -1041,7 +1048,7 @@ module Squared
1041
1048
  elsif obj.is_a?(Array) && obj.any? { |val| !val.is_a?(String) }
1042
1049
  build(*obj, **kwargs)
1043
1050
  elsif obj
1044
- run_s(obj.is_a?(Enumerable) ? obj.to_a : obj, **kwargs)
1051
+ run_s(*Array(obj), **kwargs)
1045
1052
  end
1046
1053
  end
1047
1054
  end
@@ -1088,7 +1095,7 @@ module Squared
1088
1095
 
1089
1096
  t = dedupe.call(proj.name)
1090
1097
  j = if out
1091
- if i == items.size - 1 || check.call(post = items[i + 1..-1]).empty?
1098
+ if i == items.size - 1 || check.call(post = items[(i + 1)..-1]).empty?
1092
1099
  true
1093
1100
  elsif !t.empty? && depth > 0
1094
1101
  post.reject { |pr| t.include?(pr) }.empty?
@@ -1100,9 +1107,9 @@ module Squared
1100
1107
  end
1101
1108
  if !out
1102
1109
  if !tasks && (script = workspace.script_get(:graph, group: proj.group, ref: proj.allref))
1103
- group = script[:graph]
1110
+ tasks = script[:graph]
1104
1111
  end
1105
- (tasks || group || (dev? ? ['build', 'copy'] : ['depend', 'build'])).each do |meth|
1112
+ (tasks || (dev? ? ['build', 'copy'] : ['depend', 'build'])).each do |meth|
1106
1113
  next if pass.include?(meth)
1107
1114
 
1108
1115
  if workspace.task_defined?(cmd = task_join(proj.name, meth))
@@ -1113,7 +1120,7 @@ module Squared
1113
1120
  end
1114
1121
  run(cmd, sync: false, banner: false)
1115
1122
  ENV.delete(key) if key
1116
- elsif proj.has?(meth, tasks || group ? nil : workspace.baseref)
1123
+ elsif proj.has?(meth, tasks ? nil : workspace.baseref)
1117
1124
  proj.__send__(meth.to_sym, sync: sync)
1118
1125
  end
1119
1126
  end
@@ -1150,7 +1157,6 @@ module Squared
1150
1157
  else
1151
1158
  items = workspace.find(group: val, ref: val.to_sym)
1152
1159
  end
1153
-
1154
1160
  items.each do |proj|
1155
1161
  next if pass.include?(proj.name)
1156
1162
 
@@ -1195,7 +1201,7 @@ module Squared
1195
1201
  end
1196
1202
  return ret == equals.to_s unless equals.nil?
1197
1203
 
1198
- ret.empty? || (ignore && as_a(ignore).any? { |val| ret == val.to_s }) ? default : ret
1204
+ ret.empty? || (ignore && Array(ignore).any? { |val| ret == val.to_s }) ? default : ret
1199
1205
  end
1200
1206
 
1201
1207
  def session(*cmd, prefix: cmd.first, main: true, path: true, options: true)
@@ -1243,7 +1249,7 @@ module Squared
1243
1249
  def option(*args, target: @session, prefix: target&.first, **kwargs)
1244
1250
  if prefix
1245
1251
  args.each do |val|
1246
- ret = env("#{stripext(prefix)}_#{val.gsub(/\W/, '_')}".upcase, **kwargs)
1252
+ ret = env(env_key(stripext(prefix), val), **kwargs)
1247
1253
  return ret if ret
1248
1254
  end
1249
1255
  end
@@ -1307,6 +1313,18 @@ module Squared
1307
1313
  ret.join("\n")
1308
1314
  end
1309
1315
 
1316
+ def print_status(*args, from: nil)
1317
+ return if stdin?
1318
+
1319
+ case from
1320
+ when :outdated
1321
+ out = print_footer("major #{args[0]} / minor #{args[1]} / patch #{args[2]}", right: true).split("\n")
1322
+ out[1] = sub_style(out[1], pat: /^( +major )(\d+)(.+)$/, styles: theme[:major], index: 2)
1323
+ out[1] = sub_style(out[1], pat: /^(.+)(minor )(\d+)(.+)$/, styles: theme[:active], index: 3)
1324
+ puts out
1325
+ end
1326
+ end
1327
+
1310
1328
  def format_desc(action, flag, opts = nil, **kwargs)
1311
1329
  return unless TASK_METADATA
1312
1330
 
@@ -1380,7 +1398,7 @@ module Squared
1380
1398
  out << ''
1381
1399
  end
1382
1400
  if from
1383
- out << from
1401
+ out << (from = from.to_s)
1384
1402
  pat = /\A(#{Regexp.escape(from)})(.*)\z/
1385
1403
  end
1386
1404
  else
@@ -1549,7 +1567,7 @@ module Squared
1549
1567
  raise_error("invalid JSON #{kind.name}", val, hint: hint) if kind && !ret.is_a?(kind)
1550
1568
  rescue StandardError => e
1551
1569
  log&.warn e
1552
- warn log_message(Logger::WARN, e, subject: name, pass: true) if warning?
1570
+ warn log_message(Logger::WARN, e, subject: name) if warning?
1553
1571
  else
1554
1572
  ret
1555
1573
  end
@@ -1606,25 +1624,28 @@ module Squared
1606
1624
  end
1607
1625
  ret = multiple ? ret.map! { |val| val.sub(trim, '') } : ret.sub(trim, '') if trim
1608
1626
  if column
1609
- a, b = as_a column
1610
- ret = as_a(ret).map! { |val| val[a, b || 1] }
1627
+ a, b = Array(column)
1628
+ ret = Array(ret).map! { |val| val[a, b || 1] }
1611
1629
  ret = ret.first unless multiple
1612
1630
  end
1613
1631
  if accept
1614
- a = as_a(ret).map { |val| sub_style(val, styles: theme[:inline]) }.join(', ')
1615
- accept = as_a(accept).map { |val| as_a(val) }
1632
+ hint = Array(ret).map { |val| sub_style(val, styles: theme[:inline]) }.join(', ')
1633
+ accept = Array(accept).map { |val| Array(val) }
1616
1634
  if accept.any? { |val| val[1] == true }
1617
1635
  ret = [ret]
1618
1636
  multiple = -1
1619
1637
  end
1620
1638
  loop do
1621
- c = confirm("#{accept.first[0]}#{a ? " [#{a}]" : ''} [y/N] ", 'N', timeout: 60)
1622
- if accept.shift[1] == true
1639
+ item = accept.first
1640
+ d, e = item[2] ? ['Y', '[Y/n]'] : ['N', '[y/N]']
1641
+ c = confirm("#{item[0]}#{a ? " [#{a}]" : ''} #{e} ", d, timeout: 60)
1642
+ if item[1] == true
1623
1643
  ret << c
1624
1644
  elsif !c
1625
1645
  break
1626
1646
  end
1627
- a = nil
1647
+ hint = nil
1648
+ accept.shift
1628
1649
  break if accept.empty?
1629
1650
  end
1630
1651
  exit 1 unless accept.empty?
@@ -1655,7 +1676,7 @@ module Squared
1655
1676
  if (ret = instance_eval(&blk)).nil?
1656
1677
  val
1657
1678
  else
1658
- ret.is_a?(Array) ? ret : [ret]
1679
+ Array(ret)
1659
1680
  end
1660
1681
  end
1661
1682
 
@@ -1709,13 +1730,17 @@ module Squared
1709
1730
  end
1710
1731
 
1711
1732
  def indexitem(val)
1712
- [$1.to_i, $2 && $2[1..-1]] if val =~ /\A\^(\d+)(:.+)?\z/
1733
+ [$1.to_i, $2 && $2[1..-1]] if val =~ /\A[=^#{indexchar}](\d+)(:.+)?\z/
1713
1734
  end
1714
1735
 
1715
1736
  def indexerror(val, list = nil)
1716
1737
  raise_error("requested index #{val}", hint: list && "of #{list.size}")
1717
1738
  end
1718
1739
 
1740
+ def indexchar
1741
+ workspace.windows? ? '=' : '^'
1742
+ end
1743
+
1719
1744
  def printsucc
1720
1745
  @@print_order += 1
1721
1746
  end
@@ -1768,7 +1793,8 @@ module Squared
1768
1793
  pwd = Pathname.pwd
1769
1794
  if block_given?
1770
1795
  begin
1771
- if path == pwd || pass == true || (pass.is_a?(String) && semscan(pass).join <= RUBY_VERSION)
1796
+ pass = semscan(pass).join <= RUBY_VERSION if pass.is_a?(String)
1797
+ if (path == pwd || pass == true) && !workspace.jruby_win?
1772
1798
  ret = yield
1773
1799
  else
1774
1800
  Dir.chdir(path)
@@ -1888,19 +1914,9 @@ module Squared
1888
1914
  end
1889
1915
  end
1890
1916
 
1891
- def theme_set(common)
1892
- @theme = if !verbose
1893
- {}
1894
- elsif common
1895
- workspace.theme
1896
- else
1897
- __get__(:theme)[:project][to_sym] ||= {}
1898
- end
1899
- end
1900
-
1901
1917
  def graph_set(val)
1902
1918
  @graph = if val
1903
- as_a(val).map { |s| workspace.prefix ? workspace.task_name(s).to_sym : s.to_sym }.freeze
1919
+ Array(val).map { |s| workspace.prefix ? workspace.task_name(s).to_sym : s.to_sym }.freeze
1904
1920
  end
1905
1921
  end
1906
1922
 
@@ -1912,6 +1928,25 @@ module Squared
1912
1928
  @exclude = (val ? as_a(val, :to_sym) : []).freeze
1913
1929
  end
1914
1930
 
1931
+ def archive_set(val)
1932
+ @archive = case val
1933
+ when String, Array
1934
+ { uri: val }
1935
+ when Hash
1936
+ val
1937
+ end
1938
+ end
1939
+
1940
+ def theme_set(common)
1941
+ @theme = if !verbose
1942
+ {}
1943
+ elsif common
1944
+ workspace.theme
1945
+ else
1946
+ __get__(:theme)[:project][to_sym] ||= {}
1947
+ end
1948
+ end
1949
+
1915
1950
  def dependfile_set(list)
1916
1951
  @dependindex = list.index { |file| basepath(file).exist? }.tap do |index|
1917
1952
  @dependfile = @path + list[index || 0]
@@ -2011,6 +2046,10 @@ module Squared
2011
2046
  ARG[:BANNER] && !env('BANNER', equals: '0')
2012
2047
  end
2013
2048
 
2049
+ def pwd?
2050
+ path == Pathname.pwd
2051
+ end
2052
+
2014
2053
  def stdin?
2015
2054
  pipe == 0
2016
2055
  end
@@ -21,7 +21,8 @@ module Squared
21
21
  compose: {
22
22
  common: %w[all-resources compatibility dry-run ansi|b env-file=p f|file=p parallel=b profile=b progress=b
23
23
  project-directory=p p|project-name=e].freeze,
24
- build: %w[no-cache pull push with-dependencies q|quiet build-arg=qq builder=b m|memory=b ssh=qq].freeze,
24
+ build: %w[check no-cache pull push with-dependencies q|quiet build-arg=qq builder=b m|memory=b
25
+ ssh=qq].freeze,
25
26
  exec: %w[dry-run privileged d|detach e|env=qq index=i T|no-TTY=b? user=e w|workdir=q].freeze,
26
27
  run: %w[build dry-run no-deps quiet-pull remove-orphans rm P|service-ports use-aliases cap-add=b cap-drop=b
27
28
  d|detach entrypoint=q e|env=qq i|interactive=b? l|label=q name=b T|no-TTY=b? p|publish=e pull=b
@@ -159,7 +160,7 @@ module Squared
159
160
  compose! flag, args.to_a
160
161
  end
161
162
  when :exec, :run
162
- format_desc action, flag, "service,command#{flag == :exec ? '' : '?'},args*,opts*"
163
+ format_desc action, flag, "service,command#{flag == :exec ? '' : '?'}|:,args*,opts*"
163
164
  task flag, [:service] do |_, args|
164
165
  service = param_guard(action, flag, args: args, key: :service)
165
166
  compose!(flag, args.extras, service: service)
@@ -279,12 +280,12 @@ module Squared
279
280
  ret << quote_option('secret', @secrets, double: true)
280
281
  when Hash
281
282
  append = lambda do |type|
282
- as_a(@secrets[type]).each { |arg| ret << quote_option('secret', "type=#{type},#{arg}", double: true) }
283
+ Array(@secrets[type]).each { |arg| ret << quote_option('secret', "type=#{type},#{arg}", double: true) }
283
284
  end
284
285
  append.call(:file)
285
286
  append.call(:env)
286
287
  else
287
- as_a(@secrets).each { |arg| ret << quote_option('secret', arg) }
288
+ Array(@secrets).each { |arg| ret << quote_option('secret', arg) }
288
289
  end
289
290
  if (val = option('tag', ignore: false))
290
291
  append_tag val
@@ -312,7 +313,7 @@ module Squared
312
313
  when :bake
313
314
  unless op.empty?
314
315
  args = op.dup
315
- op.extras.clear
316
+ op.reset
316
317
  if Dir.exist?(args.last)
317
318
  if projectpath?(val = args.pop)
318
319
  context = val
@@ -359,7 +360,7 @@ module Squared
359
360
  both = run[:bind] + run[:tmpfs]
360
361
  diff = run[:bind].reject { |val| run[:tmpfs].include?(val) }
361
362
  delim = Regexp.new(",\\s*(?=#{both.join('|')})")
362
- as_a(@mounts).each do |val|
363
+ Array(@mounts).each do |val|
363
364
  args = []
364
365
  tmpfs = true
365
366
  val.split(delim).each do |opt|
@@ -565,7 +566,9 @@ module Squared
565
566
  end
566
567
 
567
568
  def append_command(flag, val, list, target: @session, from: nil)
568
- if (args = env('DOCKER_ARGS'))
569
+ if list.delete(':')
570
+ list << readline('Enter command [args]', force: true)
571
+ elsif (args = env('DOCKER_ARGS'))
569
572
  list << args
570
573
  end
571
574
  case flag
@@ -588,7 +591,7 @@ module Squared
588
591
  def append_file(type, target: @session)
589
592
  return unless type == 2 || type == 4 || @file.is_a?(Array)
590
593
 
591
- files = as_a(@file).map { |val| quote_option('file', path + val) }
594
+ files = Array(@file).map { |val| quote_option('file', path + val) }
592
595
  if target.is_a?(Set)
593
596
  target.merge(files)
594
597
  else
@@ -662,7 +665,7 @@ module Squared
662
665
  cols.each do |key|
663
666
  next if (key == 'Tag' && !dd) || (key == 'Size' && data[key] == '0B')
664
667
 
665
- puts "#{g + f} #{key}: #{as_a(data[key]).join(', ')}" unless data[key].to_s.empty?
668
+ puts "#{g + f} #{key}: #{Array(data[key]).join(', ')}" unless data[key].to_s.empty?
666
669
  end
667
670
  w = 9 + flag.to_s.size + 4 + ee.size
668
671
  puts g + sub_style(ARG[:BORDER][6] + (ARG[:BORDER][1] * w), styles: theme[:inline])