squared 0.8.4 → 0.9.0.pre1

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.
@@ -102,7 +102,7 @@ module Squared
102
102
 
103
103
  @@tasks = {}
104
104
  @@graph = { _: [] }
105
- @@asdf = Pathname.new(ENV['ASDF_DIR'] || "#{Dir.home}/.asdf").yield_self do |path|
105
+ @@asdf = Pathname.new(ENV['ASDF_DIR'] || "#{Dir.home}/.asdf").then do |path|
106
106
  version = if path.join('asdf.sh').exist?
107
107
  15
108
108
  elsif ENV['ASDF_DATA_DIR'] && (path = Pathname.new(ENV['ASDF_DATA_DIR'])).exist?
@@ -640,7 +640,7 @@ module Squared
640
640
  end
641
641
  env('GRAPH', suffix: 'PASS') { |val| pass.concat(split_escape(val)) }
642
642
  start, neg = start.partition { |name| !name.start_with?('-') }
643
- data = graph_collect(self, start, pass: neg.map { |name| name[1..-1] })
643
+ data = graph_collect(self, start, pass: neg.map { |name| name[1..] })
644
644
  unless out
645
645
  data[name] << self
646
646
  on :first, :graph
@@ -700,7 +700,7 @@ module Squared
700
700
  headers = headers.is_a?(Hash) ? headers.merge(data) : data
701
701
  end
702
702
  if file
703
- ext ||= File.extname(file)[1..-1]
703
+ ext ||= File.extname(file)[1..]
704
704
  else
705
705
  require 'open-uri'
706
706
  data = nil
@@ -824,7 +824,7 @@ module Squared
824
824
  cmd << name
825
825
  banner = false if flag == :latest || flag == :where
826
826
  end
827
- success?(run(banner: banner, from: symjoin('asdf', flag)), banner, flag == :set || flag == :reshim)
827
+ success?(run(banner: banner, from: symjoin('asdf', flag)), banner, %i[set reshim].include?(flag))
828
828
  end
829
829
 
830
830
  def first(key, *args, **kwargs, &blk)
@@ -876,7 +876,7 @@ module Squared
876
876
  return
877
877
  end
878
878
  cmd = cmd.target if cmd.is_a?(OptionPartition)
879
- if interactive && sync && (!@session || !option('y'))
879
+ if interactive && sync && !(@session && option('y'))
880
880
  print_item(series: true)
881
881
  msg, y, h = case interactive
882
882
  when Array
@@ -913,7 +913,7 @@ module Squared
913
913
  ret = shell_t(*args, name: send, chdir: chdir, exception: exception, timeout: timeout || 0)
914
914
  end
915
915
  rescue Timeout::Error => e
916
- print_error(Logger::ERROR, cmd, subject: name, hint: e)
916
+ print_error(Logger::ERROR, e, subject: name, hint: cmd)
917
917
  exit 1 unless exception?(Logger::DEBUG, Logger::INFO)
918
918
  rescue => e
919
919
  on_error(e, exception: true)
@@ -924,9 +924,9 @@ module Squared
924
924
  end
925
925
  end
926
926
 
927
- def scope(*args, **kwargs, &blk)
927
+ def scope(...)
928
928
  namespace name do
929
- task(*args, **kwargs, &blk)
929
+ task(...)
930
930
  end
931
931
  end
932
932
 
@@ -1288,26 +1288,25 @@ module Squared
1288
1288
  file = if (val = env('LOG_FILE'))
1289
1289
  Time.now.strftime(val)
1290
1290
  elsif (val = env('LOG_AUTO'))
1291
- require 'date'
1291
+ d = Time.now
1292
1292
  "#{@name}-%s.log" % [case val
1293
1293
  when 'y', 'year'
1294
- Date.today.year
1294
+ d.year
1295
1295
  when 'm', 'month'
1296
- Date.today.strftime('%Y-%m')
1296
+ d.strftime('%Y-%m')
1297
1297
  when 'd', 'day', '1'
1298
- Date.today
1298
+ d.strftime('%Y-%m-%d')
1299
1299
  else
1300
- val.include?('%') ? Time.now.strftime(val) : Time.now.strftime('%FT%T%:z')
1300
+ val.include?('%') ? d.strftime(val) : d.strftime('%FT%T%:z')
1301
1301
  end]
1302
1302
  elsif (val = log[:file])
1303
1303
  if val.is_a?(String)
1304
1304
  Time.now.strftime(val)
1305
1305
  else
1306
- require 'date'
1307
- "#{@name}-#{Date.today}.log"
1306
+ "#{@name}-#{Time.now.strftime('%Y-%m-%d')}.log"
1308
1307
  end
1309
1308
  end
1310
- .yield_self do |path|
1309
+ .then do |path|
1311
1310
  next unless path
1312
1311
 
1313
1312
  @workspace.home.join(env('LOG_DIR', ''), path).realdirpath
@@ -1466,7 +1465,7 @@ module Squared
1466
1465
 
1467
1466
  t = uniq.call(name = proj.name)
1468
1467
  j = if out
1469
- if i == items.size.pred || (post = items[i.succ..-1] - done).empty?
1468
+ if i == items.size.pred || (post = items[i.succ..] - done).empty?
1470
1469
  true
1471
1470
  elsif !t.empty? && depth > 0
1472
1471
  (post - t).empty?
@@ -1572,14 +1571,18 @@ module Squared
1572
1571
  end
1573
1572
 
1574
1573
  def env(key, default = nil, suffix: nil, strict: false, ignore: nil, **kwargs, &blk)
1575
- name = "#{key}_#{envname_get}"
1574
+ name = suffix == false ? key : "#{key}_#{envname_get}"
1576
1575
  ret = if suffix
1577
1576
  ENV["#{name}_#{suffix}"] || (ignore == false && ENV["#{key}_#{suffix}"]) || ''
1578
1577
  elsif strict
1579
1578
  ENV[name].to_s
1580
1579
  else
1581
1580
  ignore = ['0'].freeze if ignore.nil?
1582
- ENV[name] || ENV.fetch(key, '')
1581
+ if key =~ /^(.+)_(FORCE|YES|Y)$/ && !(ret = __arg__($2 == 'Y' ? 'YES' : $2, $1)).nil?
1582
+ ret
1583
+ else
1584
+ ENV[name] || ENV.fetch(key, '')
1585
+ end
1583
1586
  end
1584
1587
  env_yield(ret, default, ignore: ignore, **kwargs, &blk)
1585
1588
  end
@@ -1683,19 +1686,38 @@ module Squared
1683
1686
  **kwargs)
1684
1687
  return unless prefix
1685
1688
 
1689
+ getarg = ->(key) { ARG[key][s = prefix.downcase] || ARG[key][s.to_sym] }
1686
1690
  args.each do |key|
1687
- next unless (ret = env(env_key(prefix.to_s.stripext, key), **kwargs)) && (!pat || ret.match?(pat))
1688
-
1689
- if target
1690
- if path
1691
- target << quote_option(key, basepath(ret))
1692
- elsif quote
1693
- target << quote_option(key, ret)
1694
- elsif escape
1695
- target << shell_option(key, ret)
1691
+ ret = case key.downcase
1692
+ when 'force'
1693
+ getarg.call(:FORCE)
1694
+ when 'y'
1695
+ getarg.call(:YES)
1696
+ end
1697
+ return yield(ret) if !ret.nil? && block_given?
1698
+
1699
+ case ret.to_s
1700
+ when '0'
1701
+ next
1702
+ when 'true'
1703
+ return true
1704
+ when 'false'
1705
+ return false
1706
+ else
1707
+ ret ||= env(env_key(prefix.to_s.stripext, key), **kwargs)
1708
+ next unless ret && (!pat || ret.match?(pat))
1709
+
1710
+ if target
1711
+ if path
1712
+ target << quote_option(key, basepath(ret))
1713
+ elsif quote
1714
+ target << quote_option(key, ret)
1715
+ elsif escape
1716
+ target << shell_option(key, ret)
1717
+ end
1696
1718
  end
1719
+ return block_given? ? yield(ret) : ret
1697
1720
  end
1698
- return block_given? ? yield(ret) : ret
1699
1721
  end
1700
1722
  nil
1701
1723
  end
@@ -1808,6 +1830,8 @@ module Squared
1808
1830
 
1809
1831
  case from
1810
1832
  when :outdated
1833
+ return if ENV['BANNER'] == 'false'
1834
+
1811
1835
  out = print_footer("major #{args[0]} / minor #{args[1]} / patch #{args[2]}", right: true).split("\n")
1812
1836
  sub_style!(out[1], **opt_style(theme[:major], /^( +major )(\d+)(.+)$/, 2))
1813
1837
  sub_style!(out[1], **opt_style(theme[:active], /^(.+)(minor )(\d+)(.+)$/, 3))
@@ -2030,27 +2054,27 @@ module Squared
2030
2054
  val
2031
2055
  end
2032
2056
  end
2033
- base.update(data)
2034
- .update(ret)
2057
+ base.update(data, ret)
2035
2058
  end
2036
2059
 
2037
2060
  def merge_opts(base, data)
2061
+ s = '%s %s'
2038
2062
  case data
2039
2063
  when String
2040
2064
  case base
2041
2065
  when String
2042
- "#{base} #{data}"
2066
+ s % [base, data]
2043
2067
  when Hash
2044
- "#{append_hash(base, target: []).join(' ')} #{data}"
2068
+ s % [append_hash(base, target: []).join(' '), data]
2045
2069
  when Enumerable
2046
- "#{base.to_a.join(' ')} #{data}"
2070
+ s % [base.to_a.join(' '), data]
2047
2071
  else
2048
2072
  data
2049
2073
  end
2050
2074
  when Hash
2051
2075
  case base
2052
2076
  when String
2053
- "#{base} #{append_hash(data, target: []).join(' ')}"
2077
+ s % [base, append_hash(data, target: []).join(' ')]
2054
2078
  when Hash
2055
2079
  base.merge(data)
2056
2080
  when Enumerable
@@ -2061,9 +2085,9 @@ module Squared
2061
2085
  when Enumerable
2062
2086
  case base
2063
2087
  when String
2064
- "#{base} #{data.to_a.join(' ')}"
2088
+ s % [base, data.to_a.join(' ')]
2065
2089
  when Hash
2066
- "#{append_hash(base, target: []).join(' ')} #{data.to_a.join(' ')}"
2090
+ s % [append_hash(base, target: []).join(' '), data.to_a.join(' ')]
2067
2091
  when Enumerable
2068
2092
  Set.new(base.to_a + data.to_a).to_a
2069
2093
  else
@@ -2097,6 +2121,17 @@ module Squared
2097
2121
  end || []
2098
2122
  end
2099
2123
 
2124
+ def parse_select(kwargs = {})
2125
+ pa, ch = ENV.fetch('SELECT', '0:0').split(':').map(&:to_i)
2126
+ if pa > 0
2127
+ kwargs[:page] = pa
2128
+ elsif !kwargs.key?(:page)
2129
+ kwargs[:page] = ARG[:PAGE]
2130
+ end
2131
+ kwargs[:max] = ch if ch > 0
2132
+ kwargs
2133
+ end
2134
+
2100
2135
  def param_guard(action, flag, args:, key: nil, pat: nil, values: nil)
2101
2136
  if args && key
2102
2137
  val = args.fetch(key, nil)
@@ -2130,9 +2165,9 @@ module Squared
2130
2165
  end
2131
2166
 
2132
2167
  def choice_index(msg, list, values: nil, accept: nil, series: false, trim: nil, column: nil, multiple: false,
2133
- force: true, **kwargs)
2168
+ force: true, pipe: self.pipe, **kwargs)
2134
2169
  puts unless series || printfirst?
2135
- ret = choice(msg, list, multiple: multiple, force: force, **kwargs)
2170
+ ret = choice(msg, list, multiple: multiple, force: force, pipe: pipe, **parse_select(kwargs))
2136
2171
  unless ret && !ret.empty?
2137
2172
  exit 1 if force
2138
2173
  return
@@ -2216,12 +2251,12 @@ module Squared
2216
2251
  end
2217
2252
 
2218
2253
  def relativepath(*list, all: false)
2219
- list.map { |val| Pathname.new(val) }
2220
- .select { |val| projectpath?(val) }
2221
- .map do |val|
2222
- ret = (val.absolute? ? val.relative_path_from(path) : val.cleanpath).to_s
2223
- all && val.to_s.end_with?('/') ? "#{ret}/*" : ret
2224
- end
2254
+ list.filter_map do |val|
2255
+ next unless projectpath?(file = Pathname.new(val))
2256
+
2257
+ out = (file.absolute? ? file.relative_path_from(path) : file.cleanpath).to_s
2258
+ all && file.to_s.end_with?('/') ? "#{out}/*" : out
2259
+ end
2225
2260
  end
2226
2261
 
2227
2262
  def projectmap(files, resolve: true, parent: false, pass: true)
@@ -2324,6 +2359,19 @@ module Squared
2324
2359
  cur[2] == lat[2] ? 3 : 2
2325
2360
  end
2326
2361
 
2362
+ def semapp(name, *args, minor: true, patch: true, pre: false, env: false)
2363
+ if args.empty?
2364
+ args << '--version'
2365
+ else
2366
+ args.map! { |s| shell_quote(s, force: false) }
2367
+ end
2368
+ n = minor ? patch ? pre ? -1 : 4 : 2 : 0
2369
+ IO.popen([shell_bin(name, env: env), *args], chdir: path, &:read).scan(SEM_VER).first
2370
+ &.slice(0..n)&.join or raise
2371
+ rescue
2372
+ '0.0.0'
2373
+ end
2374
+
2327
2375
  def semmajor?(cur, want)
2328
2376
  (cur[0] == '0' && want[0] == '0' ? cur[2] != want[2] : cur[0] != want[0]) && !want[6]
2329
2377
  end
@@ -2337,7 +2385,7 @@ module Squared
2337
2385
  end
2338
2386
 
2339
2387
  def indexitem(val)
2340
- [$1.to_i, $2 && $2[1..-1]] if val =~ /\A[=^#{indexchar}](\d+)(:.+)?\z/
2388
+ [$1.to_i, $2 && $2[1..]] if val =~ /\A[=^#{indexchar}](\d+)(:.+)?\z/
2341
2389
  end
2342
2390
 
2343
2391
  def indexerror(val, list = nil)
@@ -2441,7 +2489,6 @@ module Squared
2441
2489
  def pwd_set(cmd = nil, pass: false, timeout: nil, from: @on[:from].last, **kwargs, &blk)
2442
2490
  return if from == false
2443
2491
 
2444
- require 'timeout'
2445
2492
  unless (path.to_s == Dir.pwd || pass) && (mri? || !windows?)
2446
2493
  pwd = Dir.pwd
2447
2494
  Dir.chdir(path)
@@ -2738,7 +2785,15 @@ module Squared
2738
2785
  end
2739
2786
 
2740
2787
  def dryrun?(target: @session, prefix: target&.first, **)
2741
- Array(target).include?('--dry-run') || !option('dry-run', target: target, prefix: prefix).nil?
2788
+ val = ENV['DRY_RUN'] if (val = option('dry-run', target: target, prefix: prefix)).nil?
2789
+ case val.to_s
2790
+ when '0' then nil
2791
+ when 'false'
2792
+ return false
2793
+ else
2794
+ return true if val
2795
+ end
2796
+ Array(target).include?('--dry-run')
2742
2797
  end
2743
2798
 
2744
2799
  def pwd?