squared 0.7.8 → 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.
@@ -206,7 +206,7 @@ module Squared
206
206
 
207
207
  def read_keys(reader, type, file, keys, ext: [type], opts: {})
208
208
  if file && (mime = mimetype(file)) && basepath(file).exist?
209
- raise_error file, mime, hint: 'invalid' unless ext.include?(mime)
209
+ raise message(file, mime, hint: 'invalid') unless ext.include?(mime)
210
210
  else
211
211
  if ext.include?(mime)
212
212
  alt = file
@@ -218,12 +218,8 @@ module Squared
218
218
  file = Dir[alt].first
219
219
  else
220
220
  alt = main
221
- args = { hint: 'no keys' }
222
- end
223
- unless file
224
- args ||= { kind: Errno::ENOENT }
225
- raise_error(reader.name, "#{File.basename(alt, '.*')}.#{ext.first}", **args)
226
221
  end
222
+ raise Errno::ENOENT, message(reader.name, "#{File.basename(alt, '.*')}.#{ext.first}") unless file
227
223
  end
228
224
  log&.info "#{Viewer}(#{type}) => #{file} {#{keys.join(', ')}}"
229
225
  return puts File.read(file) if keys.last == '*'
@@ -273,11 +269,7 @@ module Squared
273
269
  val = Regexp.escape($!.message)
274
270
  key = key.sub(/(#{val})\.|\.(#{val})|(#{val})/) do
275
271
  s = "<#{$3 || $2 || $1}>"
276
- if $3
277
- s
278
- else
279
- $2 ? ".#{s}" : "#{s}."
280
- end
272
+ $3 ? s : $2 ? ".#{s}" : "#{s}."
281
273
  end
282
274
  out << [key, stdin? ? JSON.dump(nil) : 'undefined']
283
275
  else
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.7.8'
4
+ VERSION = '0.8.0'
5
5
  end
@@ -29,7 +29,7 @@ module Squared
29
29
  end
30
30
  end
31
31
 
32
- def find(ref = nil, path: nil)
32
+ def find(ref: nil, path: nil)
33
33
  if ref && (ret = kind_project.find { |proj| proj.ref == ref })
34
34
  ret
35
35
  elsif path
@@ -109,7 +109,7 @@ module Squared
109
109
  @kind = Support.hashlist
110
110
  @config = {}
111
111
  @extensions = Set.new
112
- @finalize = Set.new([:__chain__])
112
+ @finalize = Set.new(%i[__chain__ __join__])
113
113
  @envname = env_key(@main).freeze
114
114
  @closed = false
115
115
  @stage = Support.hashlist
@@ -127,6 +127,7 @@ module Squared
127
127
  @theme = common ? __get__(:theme)[:workspace] : {}
128
128
  @chain = Support.hashlist
129
129
  @script = Struct::SessionData.new
130
+ @join = Struct::SessionData.new
130
131
  @events = Struct::SessionData.new
131
132
  @pass = Struct::SessionData.new
132
133
  @banner = Struct::SessionData.new
@@ -226,7 +227,7 @@ module Squared
226
227
  when Symbol
227
228
  @ref = val
228
229
  else
229
- raise TypeError, "not a group/ref: #{kind || 'nil'}" if block_given?
230
+ raise TypeError, message('not a group/ref', hint: kind || 'nil') if block_given?
230
231
  end
231
232
  if block_given?
232
233
  instance_eval(&blk)
@@ -237,6 +238,15 @@ module Squared
237
238
  self
238
239
  end
239
240
 
241
+ def join(task, *cmd, invoke: nil, args: [], group: @group, ref: @ref, **kwargs, &blk)
242
+ unless block_given?
243
+ invoke ||= cmd.shift
244
+ args = cmd if (args = Array(args)).empty?
245
+ args.unshift(invoke)
246
+ end
247
+ script_command task.to_sym, args, group, ref, @join, kwargs, &blk
248
+ end
249
+
240
250
  def run(script = nil, group: @group, ref: @ref, on: nil, &blk)
241
251
  script_command :run, script, group, ref, on, &blk
242
252
  end
@@ -386,7 +396,7 @@ module Squared
386
396
  end
387
397
  unless ref.is_a?(Symbol) && (proj = @base.find { |item| item.ref == ref })
388
398
  proj = if !ref.is_a?(Class)
389
- require_project(ref) || Application.find(ref, path: path)
399
+ require_project(ref) || Application.find(ref: ref, path: path)
390
400
  elsif Application.extends(ref)
391
401
  ref
392
402
  end || @kind[name]&.last
@@ -569,10 +579,10 @@ module Squared
569
579
  def task_resolve(obj, key)
570
580
  tasks = []
571
581
  if (base = task_base?(key))
572
- tasks << key if obj.has?(key, baseref)
582
+ tasks << key if obj.has?(key, ref: baseref)
573
583
  elsif (batch = series.batch_get(key))
574
584
  obj.allref do |ref|
575
- next unless obj.has?(key, ref, missing: series.missing?(ref, key)) && (data = batch[ref])
585
+ next unless obj.has?(key, ref: ref, missing: series.missing?(ref, key)) && (data = batch[ref])
576
586
 
577
587
  data.each do |val|
578
588
  if (items = task_resolve(obj, val)).empty?
@@ -591,7 +601,7 @@ module Squared
591
601
  return [] if (base && !obj.ref?(baseref)) || !(data = series.alias_get(key))
592
602
 
593
603
  obj.allref do |ref|
594
- next unless obj.has?(key, ref) && (alt = data[ref])
604
+ next unless obj.has?(key, ref: ref) && (alt = data[ref])
595
605
 
596
606
  ret = task_resolve obj, alt
597
607
  break unless ret.empty?
@@ -691,10 +701,10 @@ module Squared
691
701
  series.extend?(obj, key)
692
702
  end
693
703
 
694
- def task_include?(obj, key, ref = nil)
704
+ def task_include?(obj, key, ref: nil)
695
705
  return false if series.exclude?(key)
696
706
 
697
- task_base?(key) ? obj.has?(key, ref || baseref) : task_extend?(obj, key)
707
+ task_base?(key) ? obj.has?(key, ref: ref || baseref) : task_extend?(obj, key)
698
708
  end
699
709
 
700
710
  def task_exclude?(key, obj = nil)
@@ -732,14 +742,6 @@ module Squared
732
742
  RUBY_ENGINE == 'ruby'
733
743
  end
734
744
 
735
- def jruby?
736
- RUBY_ENGINE == 'jruby'
737
- end
738
-
739
- def truffleruby?
740
- RUBY_ENGINE == 'truffleruby'
741
- end
742
-
743
745
  def docker?
744
746
  !Dir['/.dockerenv', '/docker-*.{sh,d}'].empty?
745
747
  end
@@ -773,7 +775,7 @@ module Squared
773
775
  end
774
776
 
775
777
  def invokeargs
776
- { exception: exception, warning: warning }
778
+ { exception: exception?, warning: warning }
777
779
  end
778
780
 
779
781
  def size
@@ -942,14 +944,75 @@ module Squared
942
944
  self.closed = 'chain:end'
943
945
  end
944
946
 
947
+ def __join__(*)
948
+ group = @join.group
949
+ ref = @join.ref
950
+ return if group.empty? && ref.empty?
951
+
952
+ self.closed = 'join:begin'
953
+ [group, ref].each do |with|
954
+ with.each do |target, data|
955
+ items = if with == group
956
+ target = target.to_s
957
+ store = @join.store[:group]
958
+ select { |proj| proj.group == target }
959
+ else
960
+ store = @join.store[:ref]
961
+ select { |proj| proj.ref == target }
962
+ end.sort
963
+ next if items.empty?
964
+
965
+ data.each do |name, args|
966
+ key = task_name(task_join(name, target))
967
+ sync = true
968
+ exception = exception?
969
+ if store && (kwargs = store["#{target}:#{name}"])
970
+ sync = kwargs[:sync] if kwargs.key?(:sync)
971
+ exception = kwargs[:exception] if kwargs.key?(:exception)
972
+ end
973
+ case args
974
+ when Struct
975
+ format_desc key
976
+ task key do
977
+ items.each do |proj|
978
+ if sync
979
+ proj.instance_eval(&args.block)
980
+ else
981
+ Rake.application.run_with_threads { proj.instance_eval(&args.block) }
982
+ end
983
+ rescue => e
984
+ raise if exception
985
+
986
+ warn log_message(Logger::ERROR, e, subject: proj.name, hint: key)
987
+ end
988
+ end
989
+ when Array
990
+ cmd = args.first
991
+ cmd = items.map { |proj| "#{proj.name}:#{cmd}" }
992
+ .select { |val| task_defined?(val) }
993
+ next if cmd.empty?
994
+
995
+ args = args.drop(1)
996
+ format_desc(args.empty? ? key : "#{key}[#{args.join(',')}]")
997
+ task key do
998
+ opts = ENV["#{target.upcase}_ARGS"]
999
+ task_invoke(*cmd, args: opts ? split_escape(opts) : args, sync: sync, exception: exception)
1000
+ end
1001
+ end
1002
+ end
1003
+ end
1004
+ end
1005
+ self.closed = 'join:end'
1006
+ end
1007
+
945
1008
  def puts(*args, **kwargs)
946
1009
  log_console(*args, pipe: kwargs[:pipe] || pipe)
947
1010
  end
948
1011
 
949
- def script_command(task, val, group, ref, on = nil, &blk)
1012
+ def script_command(task, val, group, ref, on = nil, store = nil, &blk)
950
1013
  if block_given?
951
1014
  val = Struct::RunData.new(val, blk)
952
- elsif !val
1015
+ elsif !val || (val.is_a?(Array) && val.empty?)
953
1016
  return self
954
1017
  end
955
1018
  if group
@@ -959,8 +1022,15 @@ module Squared
959
1022
  label = :ref
960
1023
  as_a(ref || :_, :to_sym)
961
1024
  end.each do |name|
962
- @script[label][name][task] = val
963
- @events[label][name][task] = on if on.is_a?(Hash)
1025
+ data = @script
1026
+ case on
1027
+ when Struct
1028
+ data = on
1029
+ when Hash
1030
+ @events[label][name][task] = on
1031
+ end
1032
+ data[label][name][task] = val
1033
+ (data.store[label] ||= {})["#{name}:#{task}"] = store if store
964
1034
  end
965
1035
  self
966
1036
  end
@@ -998,8 +1068,8 @@ module Squared
998
1068
  end
999
1069
 
1000
1070
  def data_get(*args, target:, group: nil, ref: nil)
1001
- if group && target[:group].key?(key = group.to_sym)
1002
- target[:group][key]
1071
+ if group && target[:group].key?(g = group.to_sym)
1072
+ target[:group][g]
1003
1073
  elsif ref.is_a?(Enumerable)
1004
1074
  ref.each do |key|
1005
1075
  next unless target[:ref].key?(key)
@@ -1053,6 +1123,10 @@ module Squared
1053
1123
  target && pat.is_a?(Regexp) ? Array(target).any?(pat) : pat == true
1054
1124
  end
1055
1125
 
1126
+ def exception?
1127
+ exception != false && exception != Logger::INFO
1128
+ end
1129
+
1056
1130
  def banner_include?(val)
1057
1131
  Application.attr_banner.include?(val) || @banner.items.include?(val)
1058
1132
  end
@@ -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(*)
@@ -1189,6 +1190,20 @@ module Squared
1189
1190
  keys.empty? ? ret : ret.dig(*keys)
1190
1191
  end
1191
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
+
1192
1207
  def inspect
1193
1208
  "#<#{self.class}: #{name} => #{self}>"
1194
1209
  end
@@ -1389,7 +1404,7 @@ module Squared
1389
1404
  elsif ws.task_defined?(val = task_join(name, meth)) || (meth.include?(':') && ws.task_defined?(val = meth))
1390
1405
  run(val, var, sync: sync, banner: banner, **kwargs)
1391
1406
  elsif from
1392
- print_error(from, "method: #{meth}", subject: name, hint: 'undefined')
1407
+ print_error(from, 'method', meth, subject: name, hint: 'undefined')
1393
1408
  end
1394
1409
  end
1395
1410
  end
@@ -1422,11 +1437,7 @@ module Squared
1422
1437
  when 0
1423
1438
  f
1424
1439
  when 1
1425
- if items.empty?
1426
- "#{d}#{b * 4} #{f}"
1427
- else
1428
- "#{last ? d : c}#{b * 3}#{e} #{f}"
1429
- end
1440
+ items.empty? ? "#{d}#{b * 4} #{f}" : "#{last ? d : c}#{b * 3}#{e} #{f}"
1430
1441
  else
1431
1442
  "#{single ? ' ' : a}#{' ' * depth.pred}#{last ? d : c}#{b * 3}#{items.empty? ? b : e} #{f}"
1432
1443
  end
@@ -1490,7 +1501,7 @@ module Squared
1490
1501
  end
1491
1502
  run(cmd, sync: false, banner: false)
1492
1503
  ENV.delete(key) if key
1493
- elsif proj.has?(meth, tasks || graph ? nil : workspace.baseref)
1504
+ elsif proj.has?(meth, ref: (workspace.baseref unless tasks || graph))
1494
1505
  proj.__send__(meth, sync: sync)
1495
1506
  end
1496
1507
  end
@@ -1572,7 +1583,7 @@ module Squared
1572
1583
  end
1573
1584
  cache = @timeout[:_]
1574
1585
  cache[1] ||= workspace.timeout_get(*@ref, group: group)
1575
- 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)/ }
1576
1587
  command = :"#{prefix}_#{$1}"
1577
1588
  cache[1][command] || @timeout[command]
1578
1589
  end || cache[1][prefix.to_sym] || @timeout[prefix.to_sym]
@@ -1638,8 +1649,8 @@ module Squared
1638
1649
 
1639
1650
  def session_done(cmd)
1640
1651
  return cmd.to_s unless cmd.respond_to?(:done)
1652
+ raise message('no command added', hint: cmd.first) unless cmd.size > 1
1641
1653
 
1642
- raise_error 'no command added', hint: cmd.first unless cmd.size > 1
1643
1654
  @session = nil if cmd.equal?(@session)
1644
1655
  cmd.done
1645
1656
  end
@@ -1672,7 +1683,7 @@ module Squared
1672
1683
  end
1673
1684
 
1674
1685
  def write_lines(data, grep: [], prefix: nil, sub: nil, banner: nil, loglevel: nil, pass: false, first: false)
1675
- grep = (matchmap(grep, prefix) unless grep.empty?)
1686
+ grep = (matchmap(grep, prefix: prefix) unless grep.empty?)
1676
1687
  sub = (as_a(sub) unless stdin?)
1677
1688
  ret = 0
1678
1689
  lines = data.each_with_object([]) do |line, out|
@@ -1808,13 +1819,13 @@ module Squared
1808
1819
  out = []
1809
1820
  if data.command
1810
1821
  if command
1811
- if cmd =~ /\A(?:"((?:[^"]|(?<=\\)")+)"|'((?:[^']|(?<=\\)')+)'|(\S+))( |\z)/
1822
+ if cmd =~ /\A(?:"((?:[^"]|(?<=\\)")+)"|'((?:[^']|(?<=\\)')+)'|(\S+))(?: |\z)/
1812
1823
  arg = $3 || $2 || $1
1813
1824
  cmd = cmd.sub(arg, data.command == 0 ? arg.stripext : arg.stripext.upcase)
1814
1825
  end
1815
1826
  if strip || (strip.nil? && data.order.include?(:path))
1816
- cmd = cmd.gsub(/(?:#{s = Regexp.escape(File.join(path, ''))}?(?=["'])|#{s})/, '')
1817
- .gsub(/(?: -[^ ])? (?:""|'')/, '')
1827
+ s = Regexp.escape(File.join(path, ''))
1828
+ cmd = cmd.gsub(/(#{s}?(?=["'])|#{s})/, '').gsub(/( -[^ ])? (""|'')/, '')
1818
1829
  end
1819
1830
  cmd = cmd.gsub(/(?<= )(["'])([\w.-]+)\1(?= |\z)/, '\2') unless quote
1820
1831
  end
@@ -2038,11 +2049,6 @@ module Squared
2038
2049
  end
2039
2050
  end
2040
2051
 
2041
- def collect_hash(data, pass: [])
2042
- data = data.reject { |key,| pass.include?(key) } unless pass.empty?
2043
- data.values.flatten
2044
- end
2045
-
2046
2052
  def replace_bin(val)
2047
2053
  a, b = val.split(' ', 2)
2048
2054
  return val if val.start_with?(/["']/) || a.include?(File::Separator)
@@ -2052,7 +2058,7 @@ module Squared
2052
2058
 
2053
2059
  def parse_json(val, kind: Hash, key: nil, hint: nil, &blk)
2054
2060
  ret = JSON.parse(val)
2055
- 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)
2056
2062
  return ret unless key
2057
2063
 
2058
2064
  block_given? ? ret.fetch(key, &blk) : ret[key]
@@ -2072,18 +2078,18 @@ module Squared
2072
2078
  return val unless val.nil? || (pat && !val.match?(pat)) || (values && !values.include?(val))
2073
2079
 
2074
2080
  @session = nil
2075
- raise_error(action, "#{flag}[#{key}]", hint: val.nil? ? 'missing' : 'invalid')
2081
+ raise message(action, "#{flag}[#{key}]", hint: val.nil? ? 'missing' : 'invalid')
2076
2082
  elsif args.is_a?(Array) && args.empty?
2077
2083
  @session = nil
2078
- raise_error action, "#{flag}+", hint: 'empty'
2084
+ raise message(action, "#{flag}+", hint: 'empty')
2079
2085
  end
2080
2086
  args
2081
2087
  end
2082
2088
 
2083
- def confirm_basic(msg, hint, default = 'Y', style: :inline, target: @session, prefix: nil, **kwargs)
2089
+ def confirm_basic(msg, hint, accept = 'Y', style: :inline, target: @session, prefix: nil, **kwargs)
2084
2090
  return true if prefix ? option('y', prefix: prefix) : target && option('y', target: target)
2085
2091
 
2086
- 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)
2087
2093
  end
2088
2094
 
2089
2095
  def confirm_semver(msg, type, style: (type == 1 && theme[:major]) || :inline, timeout: 0, **kwargs)
@@ -2143,12 +2149,8 @@ module Squared
2143
2149
  ret
2144
2150
  end
2145
2151
 
2146
- def accept_b(val, yes = false)
2147
- [val, true, yes]
2148
- end
2149
-
2150
- def accept_y(val, bool = false)
2151
- [val, bool, true]
2152
+ def accept_b(val, ret: true, yes: false)
2153
+ [val, ret, yes]
2152
2154
  end
2153
2155
 
2154
2156
  def command_args(args, min: 0, force: false, **kwargs)
@@ -2209,10 +2211,6 @@ module Squared
2209
2211
  end
2210
2212
  end
2211
2213
 
2212
- def symjoin(*args, char: ':')
2213
- args.join(char).to_sym
2214
- end
2215
-
2216
2214
  def semver(val)
2217
2215
  return val if val[3]
2218
2216
 
@@ -2254,7 +2252,7 @@ module Squared
2254
2252
  def sembump(val, flag = :patch, join: true)
2255
2253
  ret = semscan(val, fill: false)
2256
2254
  case flag
2257
- when :major
2255
+ when :major, :premajor
2258
2256
  ret[2] = if ret[0] != '0' || ret[2].nil?
2259
2257
  ret[0] = ret[0].succ
2260
2258
  '0'
@@ -2262,16 +2260,29 @@ module Squared
2262
2260
  ret[2].succ
2263
2261
  end
2264
2262
  ret[4] = '0'
2265
- when :minor
2263
+ when :minor, :preminor
2266
2264
  if ret[0] == '0'
2267
2265
  ret[4] &&= ret[4].succ
2268
2266
  else
2269
2267
  ret[2] = ret[2].succ
2270
2268
  ret[4] &&= '0'
2271
2269
  end
2272
- when :patch
2270
+ when :patch, :prepatch
2273
2271
  ret[4] &&= ret[4].succ
2274
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
2275
2286
  join ? ret.join : ret
2276
2287
  end
2277
2288
 
@@ -2298,7 +2309,7 @@ module Squared
2298
2309
  end
2299
2310
 
2300
2311
  def indexerror(val, list = nil)
2301
- 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))
2302
2313
  end
2303
2314
 
2304
2315
  def indexchar
@@ -2714,8 +2725,10 @@ module Squared
2714
2725
  end
2715
2726
 
2716
2727
  def exception?(*level)
2717
- ex = exception
2718
- 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)
2719
2732
  end
2720
2733
 
2721
2734
  def strict?