squared 0.7.14 → 0.8.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.
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'json'
4
- require 'logger'
5
4
 
6
5
  require_relative 'support/class'
7
6
  require_relative 'support/utils'
@@ -10,6 +9,7 @@ module Squared
10
9
  module Workspace
11
10
  module Project
12
11
  class Base
12
+ include Enumerable
13
13
  include Comparable
14
14
  include Common::Format
15
15
  include System
@@ -343,7 +343,7 @@ module Squared
343
343
  tag ||= if @release
344
344
  "%s.#{ext}" % [@release.include?('??') ? @release.sub('??', tag) : @release + tag]
345
345
  else
346
- raise_error ArgumentError, "no base uri: #{tag}", hint: ext
346
+ raise ArgumentError, message('no base uri', tag, hint: ext)
347
347
  end
348
348
  end
349
349
  force = case (digest = args.digest)
@@ -471,10 +471,10 @@ module Squared
471
471
  cmd = args.each_with_object([]) do |val, out|
472
472
  case val.first
473
473
  when Proc
474
- instance_exec(*val[1..-1], &val.first)
474
+ instance_exec(*val.drop(1), &val.first)
475
475
  next
476
476
  when Method
477
- val.first.call(*val[1..-1])
477
+ val.first.call(*val.drop(1))
478
478
  next
479
479
  end
480
480
  a, b, c, d, e = val
@@ -542,7 +542,7 @@ module Squared
542
542
  on_error(e, exception: true)
543
543
  end
544
544
  else
545
- print_error('prereqs', "method: #{meth}", subject: name, hint: 'undefined')
545
+ print_error('prereqs', 'method', meth, subject: name, hint: 'undefined')
546
546
  end
547
547
  end
548
548
  elsif proj.build?
@@ -582,10 +582,10 @@ module Squared
582
582
  case @clean
583
583
  when Struct
584
584
  if (val = instance_eval(&@clean.block) || @clean.run)
585
- @clean = @clean.tap do
586
- @clean = val
587
- clean(*args, sync: sync, pass: true, **kwargs)
588
- end
585
+ cur = @clean
586
+ @clean = val
587
+ clean(*args, sync: sync, pass: true, **kwargs)
588
+ @clean = cur
589
589
  end
590
590
  when String
591
591
  run_s(@clean, sync: sync)
@@ -661,9 +661,10 @@ module Squared
661
661
  if !target.exist?
662
662
  target.mkpath
663
663
  elsif !target.directory?
664
- raise_error Errno::EEXIST, target, hint: uri
664
+ raise Errno::EEXIST, message(target, hint: uri)
665
665
  elsif !file && !target.empty?
666
- raise_error Errno::EEXIST, target, hint: uri unless force || env('UNPACK_FORCE')
666
+ raise Errno::EEXIST, message(target, hint: uri) unless force || env('UNPACK_FORCE')
667
+
667
668
  create = true
668
669
  end
669
670
  if digest
@@ -683,7 +684,7 @@ module Squared
683
684
  when 128, 'sha512'
684
685
  Digest::SHA512
685
686
  else
686
- raise_error "invalid checksum: #{digest}", hint: uri
687
+ raise message('invalid checksum', digest, hint: uri)
687
688
  end
688
689
  end
689
690
  env('HEADERS') do |val|
@@ -701,14 +702,14 @@ module Squared
701
702
  data = f.read
702
703
  if algo && algo.hexdigest(data) != digest
703
704
  data = nil
704
- raise_error "invalid checksum: #{digest}", hint: url if i == uri.size.pred
705
+ raise message('invalid checksum', digest, hint: url) if i == uri.size.pred
705
706
  end
706
707
  next if ext && i == 0
707
708
 
708
709
  case f.content_type
709
710
  when 'application/zip'
710
711
  ext = 'zip'
711
- when %r{application/(?:x-)?gzip}
712
+ when %r{application/(x-)?gzip}
712
713
  ext = 'tgz'
713
714
  when 'application/x-xz'
714
715
  ext = 'txz'
@@ -719,7 +720,7 @@ module Squared
719
720
  break uri = url if data
720
721
  end
721
722
  unless data && (ext ||= URI.decode_www_form_component(URI.parse(uri).path[/\.([\w%]+)(?:\?|\z)/, 1]))
722
- raise_error(data ? TypeError : RuntimeError, "no content#{' type' if data}", hint: uri)
723
+ raise(data ? TypeError : RuntimeError, message("no content#{' type' if data}", hint: uri))
723
724
  end
724
725
  end
725
726
  ext = ext.downcase
@@ -748,7 +749,7 @@ module Squared
748
749
  case ext
749
750
  when 'zip', 'aar'
750
751
  session 'unzip', shell_quote(file), quote_option('d', target)
751
- when 'tar', /\A(?:t|tar\.)?[gx]z\z/
752
+ when 'tar', /\A(t|tar\.)?[gx]z\z/
752
753
  flags = +(silent? ? '' : 'v')
753
754
  if ext.end_with?('gz')
754
755
  flags += 'z'
@@ -764,7 +765,7 @@ module Squared
764
765
  session 'gem', 'unpack', shell_quote(file), quote_option('target', target)
765
766
  depth = 0 unless val
766
767
  else
767
- raise_error("unsupported format: #{ext}", hint: uri || file)
768
+ raise message('unsupported format', ext, hint: uri || file)
768
769
  end
769
770
  run(sync: sync, banner: verbose, from: from)
770
771
  while depth > 0 && target.children.size == 1
@@ -1018,13 +1019,13 @@ module Squared
1018
1019
 
1019
1020
  alias apply variable_set
1020
1021
 
1021
- def enabled?(ref = nil, **)
1022
+ def enabled?(ref: nil, **)
1022
1023
  return false if ref && Array(ref).none? { |val| ref?(val) }
1023
1024
 
1024
1025
  (path.directory? && !path.empty?) || archive?
1025
1026
  end
1026
1027
 
1027
- def has?(meth, ref = nil, all: false, missing: false)
1028
+ def has?(meth, ref: nil, all: false, missing: false)
1028
1029
  return false if ref && !ref?(ref)
1029
1030
 
1030
1031
  pred = :"#{meth}?"
@@ -1105,8 +1106,8 @@ module Squared
1105
1106
  !@exclude.empty? && has_value?(@exclude, *refs)
1106
1107
  end
1107
1108
 
1108
- def task_include?(key, ref = nil)
1109
- workspace.task_include?(self, key, ref) && !@pass.include?(key.to_s)
1109
+ def task_include?(key, ref: nil)
1110
+ workspace.task_include?(self, key, ref: ref) && !@pass.include?(key.to_s)
1110
1111
  end
1111
1112
 
1112
1113
  def version(*)
@@ -1166,20 +1167,10 @@ module Squared
1166
1167
  ret = basepath(*args)
1167
1168
  return ret unless ascend && !ret.exist?
1168
1169
 
1169
- case ascend
1170
- when String, Pathname
1171
- root = Pathname.new(ascend).cleanpath
1172
- root = nil unless root.absolute? && root.directory?
1173
- end
1174
1170
  path.parent.ascend.each do |dir|
1175
1171
  target = dir.join(*args)
1176
1172
  return target if target.exist?
1177
-
1178
- if root
1179
- break if dir == root
1180
- elsif workspace.root == dir || parent&.path == dir || (ascend.is_a?(String) && dir.join(ascend).exist?)
1181
- break
1182
- end
1173
+ break if (ascend.is_a?(String) && dir.join(ascend).exist?) || workspace.root == dir || parent&.path == dir
1183
1174
  end
1184
1175
  ret
1185
1176
  end
@@ -1199,6 +1190,20 @@ module Squared
1199
1190
  keys.empty? ? ret : ret.dig(*keys)
1200
1191
  end
1201
1192
 
1193
+ def each(from: :run, ref: nil, accept: nil, &blk)
1194
+ from = from.to_s.split(':').last if from.is_a?(Symbol)
1195
+ items = ref ? children.select { |proj| proj.ref?(ref) } : children
1196
+ if items.empty?
1197
+ print_error("nothing to #{from}", subject: name)
1198
+ elsif accept && !confirm_basic("#{from.capitalize} workspace?", items.map(&:name).join(', '), accept,
1199
+ prefix: 'npm')
1200
+ items.clear
1201
+ end
1202
+ return items.to_enum unless block_given?
1203
+
1204
+ items.each(&blk)
1205
+ end
1206
+
1202
1207
  def inspect
1203
1208
  "#<#{self.class}: #{name} => #{self}>"
1204
1209
  end
@@ -1399,7 +1404,7 @@ module Squared
1399
1404
  elsif ws.task_defined?(val = task_join(name, meth)) || (meth.include?(':') && ws.task_defined?(val = meth))
1400
1405
  run(val, var, sync: sync, banner: banner, **kwargs)
1401
1406
  elsif from
1402
- print_error(from, "method: #{meth}", subject: name, hint: 'undefined')
1407
+ print_error(from, 'method', meth, subject: name, hint: 'undefined')
1403
1408
  end
1404
1409
  end
1405
1410
  end
@@ -1432,11 +1437,7 @@ module Squared
1432
1437
  when 0
1433
1438
  f
1434
1439
  when 1
1435
- if items.empty?
1436
- "#{d}#{b * 4} #{f}"
1437
- else
1438
- "#{last ? d : c}#{b * 3}#{e} #{f}"
1439
- end
1440
+ items.empty? ? "#{d}#{b * 4} #{f}" : "#{last ? d : c}#{b * 3}#{e} #{f}"
1440
1441
  else
1441
1442
  "#{single ? ' ' : a}#{' ' * depth.pred}#{last ? d : c}#{b * 3}#{items.empty? ? b : e} #{f}"
1442
1443
  end
@@ -1500,7 +1501,7 @@ module Squared
1500
1501
  end
1501
1502
  run(cmd, sync: false, banner: false)
1502
1503
  ENV.delete(key) if key
1503
- elsif proj.has?(meth, tasks || graph ? nil : workspace.baseref)
1504
+ elsif proj.has?(meth, ref: (workspace.baseref unless tasks || graph))
1504
1505
  proj.__send__(meth, sync: sync)
1505
1506
  end
1506
1507
  end
@@ -1555,7 +1556,7 @@ module Squared
1555
1556
  def env(key, default = nil, suffix: nil, strict: false, ignore: nil, **kwargs, &blk)
1556
1557
  name = "#{key}_#{envname_get}"
1557
1558
  ret = if suffix
1558
- ENV["#{name}_#{suffix}"] || (ignore == false && ENV["#{key}_#{suffix}"]) || ''
1559
+ ENV.fetch("#{name}_#{suffix}", '')
1559
1560
  elsif strict
1560
1561
  ENV[name].to_s
1561
1562
  else
@@ -1582,7 +1583,7 @@ module Squared
1582
1583
  end
1583
1584
  cache = @timeout[:_]
1584
1585
  cache[1] ||= workspace.timeout_get(*@ref, group: group)
1585
- cache[0][ret] = if cmd[1..-1].find { |val| val =~ /\A([A-Za-z][\w-]*)(?<![-_])(?: |\z)/ }
1586
+ cache[0][ret] = if cmd.drop(1).find { |val| val =~ /\A([A-Za-z][\w-]*)(?<![-_])(?: |\z)/ }
1586
1587
  command = :"#{prefix}_#{$1}"
1587
1588
  cache[1][command] || @timeout[command]
1588
1589
  end || cache[1][prefix.to_sym] || @timeout[prefix.to_sym]
@@ -1648,8 +1649,8 @@ module Squared
1648
1649
 
1649
1650
  def session_done(cmd)
1650
1651
  return cmd.to_s unless cmd.respond_to?(:done)
1652
+ raise message('no command added', hint: cmd.first) unless cmd.size > 1
1651
1653
 
1652
- raise_error 'no command added', hint: cmd.first unless cmd.size > 1
1653
1654
  @session = nil if cmd.equal?(@session)
1654
1655
  cmd.done
1655
1656
  end
@@ -1682,7 +1683,7 @@ module Squared
1682
1683
  end
1683
1684
 
1684
1685
  def write_lines(data, grep: [], prefix: nil, sub: nil, banner: nil, loglevel: nil, pass: false, first: false)
1685
- grep = (matchmap(grep, prefix) unless grep.empty?)
1686
+ grep = (matchmap(grep, prefix: prefix) unless grep.empty?)
1686
1687
  sub = (as_a(sub) unless stdin?)
1687
1688
  ret = 0
1688
1689
  lines = data.each_with_object([]) do |line, out|
@@ -1702,18 +1703,12 @@ module Squared
1702
1703
  ret += 1
1703
1704
  break out if first
1704
1705
  end
1705
- if banner && (ret > 0 || (!pass && !first))
1706
- if banner.empty?
1707
- print_item(*lines)
1708
- else
1709
- print_item(banner, *lines)
1710
- end
1711
- end
1706
+ print_item banner, lines if banner && (ret > 0 || (!pass && !first))
1712
1707
  ret
1713
1708
  end
1714
1709
 
1715
1710
  def print_success
1716
- puts ARG[:SUCCESS]
1711
+ puts 'Success'
1717
1712
  end
1718
1713
 
1719
1714
  def print_error(*args, loglevel: Logger::WARN, **kwargs)
@@ -1734,7 +1729,7 @@ module Squared
1734
1729
  end
1735
1730
 
1736
1731
  def print_run(cmd, banner = true, verbose: nil, **)
1737
- return if banner || !stdout? || verbose == false || env('BANNER', equals: %w[0 false])
1732
+ return if banner || !stdout? || verbose == false || env('BANNER', equals: '0')
1738
1733
 
1739
1734
  puts "\n> #{cmd}"
1740
1735
  printsucc
@@ -1743,7 +1738,7 @@ module Squared
1743
1738
  def print_item(*val, series: false)
1744
1739
  puts unless printfirst?
1745
1740
  printsucc unless series
1746
- puts val unless val.empty? || (val.size == 1 && (!val.first || val.first.empty?))
1741
+ puts val unless val.empty? || (val.size == 1 && !val.first)
1747
1742
  end
1748
1743
 
1749
1744
  def print_banner(*lines, client: false, styles: theme[:banner], border: borderstyle)
@@ -1824,13 +1819,13 @@ module Squared
1824
1819
  out = []
1825
1820
  if data.command
1826
1821
  if command
1827
- if cmd =~ /\A(?:"((?:[^"]|(?<=\\)")+)"|'((?:[^']|(?<=\\)')+)'|(\S+))( |\z)/
1822
+ if cmd =~ /\A(?:"((?:[^"]|(?<=\\)")+)"|'((?:[^']|(?<=\\)')+)'|(\S+))(?: |\z)/
1828
1823
  arg = $3 || $2 || $1
1829
1824
  cmd = cmd.sub(arg, data.command == 0 ? arg.stripext : arg.stripext.upcase)
1830
1825
  end
1831
1826
  if strip || (strip.nil? && data.order.include?(:path))
1832
- cmd = cmd.gsub(/(?:#{s = Regexp.escape(File.join(path, ''))}?(?=["'])|#{s})/, '')
1833
- .gsub(/(?: -[^ ])? (?:""|'')/, '')
1827
+ s = Regexp.escape(File.join(path, ''))
1828
+ cmd = cmd.gsub(/(#{s}?(?=["'])|#{s})/, '').gsub(/( -[^ ])? (""|'')/, '')
1834
1829
  end
1835
1830
  cmd = cmd.gsub(/(?<= )(["'])([\w.-]+)\1(?= |\z)/, '\2') unless quote
1836
1831
  end
@@ -1882,7 +1877,7 @@ module Squared
1882
1877
  out << ''
1883
1878
  end
1884
1879
  if from
1885
- out << (from = from.to_s)
1880
+ out << from
1886
1881
  /\A(#{Regexp.escape(from)})(.*)\z/
1887
1882
  end
1888
1883
  else
@@ -1907,7 +1902,7 @@ module Squared
1907
1902
  end
1908
1903
 
1909
1904
  def append_hash(data, target: @session || [], build: false)
1910
- if build && (type = env('BUILD', suffix: 'TYPE', ignore: false))
1905
+ if build && (type = env('BUILD', suffix: 'TYPE') || ENV['BUILD_TYPE'])
1911
1906
  if (extra = data[type = "__#{type}__"] || data[type.to_sym]).is_a?(Hash)
1912
1907
  data = data.merge(extra)
1913
1908
  else
@@ -2054,11 +2049,6 @@ module Squared
2054
2049
  end
2055
2050
  end
2056
2051
 
2057
- def collect_hash(data, pass: [])
2058
- data = data.reject { |key,| pass.include?(key) } unless pass.empty?
2059
- data.values.flatten
2060
- end
2061
-
2062
2052
  def replace_bin(val)
2063
2053
  a, b = val.split(' ', 2)
2064
2054
  return val if val.start_with?(/["']/) || a.include?(File::Separator)
@@ -2068,7 +2058,7 @@ module Squared
2068
2058
 
2069
2059
  def parse_json(val, kind: Hash, key: nil, hint: nil, &blk)
2070
2060
  ret = JSON.parse(val)
2071
- raise_error 'invalid JSON'.subhint(kind.name), val, hint: hint if kind && !ret.is_a?(kind)
2061
+ raise message('invalid JSON', kind.name, hint: hint) if kind && !ret.is_a?(kind)
2072
2062
  return ret unless key
2073
2063
 
2074
2064
  block_given? ? ret.fetch(key, &blk) : ret[key]
@@ -2088,18 +2078,18 @@ module Squared
2088
2078
  return val unless val.nil? || (pat && !val.match?(pat)) || (values && !values.include?(val))
2089
2079
 
2090
2080
  @session = nil
2091
- raise_error(action, "#{flag}[#{key}]", hint: val.nil? ? 'missing' : 'invalid')
2081
+ raise message(action, "#{flag}[#{key}]", hint: val.nil? ? 'missing' : 'invalid')
2092
2082
  elsif args.is_a?(Array) && args.empty?
2093
2083
  @session = nil
2094
- raise_error action, "#{flag}+", hint: 'empty'
2084
+ raise message(action, "#{flag}+", hint: 'empty')
2095
2085
  end
2096
2086
  args
2097
2087
  end
2098
2088
 
2099
- def confirm_basic(msg, hint, default = 'Y', style: :inline, target: @session, prefix: target&.first, **kwargs)
2100
- return true if option('y', prefix: prefix)
2089
+ def confirm_basic(msg, hint, accept = 'Y', style: :inline, target: @session, prefix: nil, **kwargs)
2090
+ return true if prefix ? option('y', prefix: prefix) : target && option('y', target: target)
2101
2091
 
2102
- confirm("#{msg} [#{sub_style(hint.to_s, style.is_a?(Symbol) ? theme[style] : style)}]", default, **kwargs)
2092
+ confirm("#{msg} [#{sub_style(hint.to_s, style.is_a?(Symbol) ? theme[style] : style)}]", accept, **kwargs)
2103
2093
  end
2104
2094
 
2105
2095
  def confirm_semver(msg, type, style: (type == 1 && theme[:major]) || :inline, timeout: 0, **kwargs)
@@ -2131,10 +2121,7 @@ module Squared
2131
2121
  if accept
2132
2122
  hint = Array(ret).map { |val| sub_style(val.to_s, theme[:inline]) }.join(', ')
2133
2123
  accept = Array(accept).map { |val| Array(val) }
2134
- if accept.any? { |val| val[1] == true }
2135
- ret = [ret]
2136
- multiple = -1
2137
- end
2124
+ ret = Array(ret) if accept.any? { |val| val[1] == true }
2138
2125
  begin
2139
2126
  item = accept.shift
2140
2127
  c = confirm("#{item[0]}#{" [#{hint}]" if hint}", item[2] ? 'Y' : 'N')
@@ -2147,7 +2134,7 @@ module Squared
2147
2134
  end until accept.empty?
2148
2135
  end
2149
2136
  if values
2150
- ret = [ret] unless accept && multiple == -1
2137
+ ret = Array(ret)
2151
2138
  Array(values).each do |val|
2152
2139
  if val.is_a?(Array)
2153
2140
  val, force = val
@@ -2162,12 +2149,8 @@ module Squared
2162
2149
  ret
2163
2150
  end
2164
2151
 
2165
- def accept_b(val, yes = false)
2166
- [val, true, yes]
2167
- end
2168
-
2169
- def accept_y(val, bool = false)
2170
- [val, bool, true]
2152
+ def accept_b(val, ret: true, yes: false)
2153
+ [val, ret, yes]
2171
2154
  end
2172
2155
 
2173
2156
  def command_args(args, min: 0, force: false, **kwargs)
@@ -2228,10 +2211,6 @@ module Squared
2228
2211
  end
2229
2212
  end
2230
2213
 
2231
- def symjoin(*args, char: ':')
2232
- args.join(char).to_sym
2233
- end
2234
-
2235
2214
  def semver(val)
2236
2215
  return val if val[3]
2237
2216
 
@@ -2273,7 +2252,7 @@ module Squared
2273
2252
  def sembump(val, flag = :patch, join: true)
2274
2253
  ret = semscan(val, fill: false)
2275
2254
  case flag
2276
- when :major
2255
+ when :major, :premajor
2277
2256
  ret[2] = if ret[0] != '0' || ret[2].nil?
2278
2257
  ret[0] = ret[0].succ
2279
2258
  '0'
@@ -2281,16 +2260,29 @@ module Squared
2281
2260
  ret[2].succ
2282
2261
  end
2283
2262
  ret[4] = '0'
2284
- when :minor
2263
+ when :minor, :preminor
2285
2264
  if ret[0] == '0'
2286
2265
  ret[4] &&= ret[4].succ
2287
2266
  else
2288
2267
  ret[2] = ret[2].succ
2289
2268
  ret[4] &&= '0'
2290
2269
  end
2291
- when :patch
2270
+ when :patch, :prepatch
2292
2271
  ret[4] &&= ret[4].succ
2293
2272
  end
2273
+ case flag
2274
+ when :premajor, :preminor, :prepatch
2275
+ ret[5] ||= '-'
2276
+ ret[6] = '0'
2277
+ when :prerelease
2278
+ if !ret[6]
2279
+ ret[5] = '-'
2280
+ ret[6] = '0'
2281
+ elsif ret[6].match?(/^\d+$/)
2282
+ ret[5] ||= '-'
2283
+ ret[6] = ret[6].succ
2284
+ end
2285
+ end
2294
2286
  join ? ret.join : ret
2295
2287
  end
2296
2288
 
@@ -2317,7 +2309,7 @@ module Squared
2317
2309
  end
2318
2310
 
2319
2311
  def indexerror(val, list = nil)
2320
- raise_error IndexError, "requested index #{val}", hint: ("of #{list.size}" if list)
2312
+ raise IndexError, message("requested index #{val}", hint: ("of #{list.size}" if list))
2321
2313
  end
2322
2314
 
2323
2315
  def indexchar
@@ -2705,16 +2697,7 @@ module Squared
2705
2697
  end
2706
2698
 
2707
2699
  def banner?
2708
- case (val = env('BANNER', ignore: false))
2709
- when '0', 'false'
2710
- false
2711
- else
2712
- !val.nil? || ARG[:BANNER]
2713
- end
2714
- end
2715
-
2716
- def dryrun?(*, target: @session, prefix: target&.first)
2717
- Array(target).include?('--dry-run') || !option('dry-run', target: target, prefix: prefix).nil?
2700
+ ARG[:BANNER] && env('BANNER', notequals: '0')
2718
2701
  end
2719
2702
 
2720
2703
  def pwd?
@@ -2742,17 +2725,14 @@ module Squared
2742
2725
  end
2743
2726
 
2744
2727
  def exception?(*level)
2745
- ex = exception
2746
- level.empty? ? ex != false && ex != Logger::INFO : ex.is_a?(Numeric) && level.include?(ex)
2728
+ ret = exception
2729
+ return ret unless ret.is_a?(Numeric)
2730
+
2731
+ level.empty? ? ret != Logger::INFO : level.include?(ret)
2747
2732
  end
2748
2733
 
2749
2734
  def strict?
2750
- case (val = env('STRICT', ignore: false))
2751
- when '0', 'false'
2752
- false
2753
- else
2754
- !val.nil? || ARG[:STRICT] || exception?(Logger::FATAL)
2755
- end
2735
+ (ARG[:STRICT] || exception?(Logger::FATAL)) && env('STRICT', notequals: '0')
2756
2736
  end
2757
2737
 
2758
2738
  def serve?