squared 0.4.8 → 0.4.9

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.
@@ -7,23 +7,23 @@ module Squared
7
7
  GEMFILE = %w[Gemfile Gemfile.lock gem.deps.rb Isolate].freeze
8
8
  DIR_RUBY = (GEMFILE + Rake::Application::DEFAULT_RAKEFILES + ['README.rdoc']).freeze
9
9
  OPT_RUBY = {
10
- ruby: %w[a c l n p s S w d|debug jit rjit v|verbose y|yydebug 0=im? backtrace-limit=i crash-report=q
11
- disable=q dump=q e=q enable=q encoding=b external-encoding=b Eex=m? F=qm i=m? internal-encoding=b
12
- I=pm parser=b r=bm W=bm? x=pm?].freeze,
10
+ ruby: %w[0=im? a c e=q E=bm F=qm i=bm? I=pm l n p r=bm s S w W=bm? x=pm? d|debug jit rjit v|verbose y|yydebug
11
+ backtrace-limit=i crash-report=q disable=q dump=q enable=q encoding=b external-encoding=b
12
+ internal-encoding=b parser=b].freeze,
13
13
  rake: %w[A|all B|build-all comments n|dry-run p|execute-print=q m|multitask P|prereqs q|quiet
14
14
  X|no-deprecation-warnings N|no-search G|no-system nosearch nosystem rules s|silent g|system
15
- v|verbose backtrace=b? D|describe=q? e|execute=q E|execute-continue=q I|libdir=p job-stats=b?
16
- j|jobs=i? R|rakelib=p rakelibdir=p r|require=b suppress-backtrace=q T|tasks=q? t|trace=b?
15
+ v|verbose backtrace=b? D|describe=q? e|execute=q E|execute-continue=q job-stats=b? j|jobs=i?
16
+ I|libdir=p R|rakelib=p rakelibdir=p r|require=b suppress-backtrace=q T|tasks=q? t|trace=b?
17
17
  W|where=q?].freeze,
18
- irb: %w[d f U w E=b I=p r=b W=m? autocomplete colorize echo echo-on-assignment extra-doc-dir inf-ruby-mode
19
- inspect multiline no-pager noautocomplete nocolorize noecho noinspect noecho-on-assignment
18
+ irb: %w[d f U w E=b I=p r=b W=im? autocomplete colorize echo echo-on-assignment extra-doc-dir inf-ruby-mode
19
+ inspect multiline no-pager noautocomplete nocolorize noecho noecho-on-assignment noinspect
20
20
  nomultiline noprompt noscript nosingleline noverbose regexp-completor sample-book-mode script
21
21
  simple-prompt single-irb singleline tracer truncate-echo-on-assignment type-completor verbose
22
22
  back-trace-limit=i context-mode=i prompt=b prompt-mode=b].freeze
23
23
  }.freeze
24
24
  OPT_BUNDLE = {
25
25
  common: %w[no-color V|verbose retry=i].freeze,
26
- install: %w[frozen no-cache no-prune system path=p binstubs=p? standalone=q? target-rbconfig=p trust-policy=b
26
+ install: %w[frozen no-cache no-prune system binstubs=p? path=p standalone=q? target-rbconfig=p trust-policy=b
27
27
  with=q without=q].freeze,
28
28
  install_base: %w[full-index quiet retry gemfile=p j|jobs=i].freeze,
29
29
  update: %w[conservative local pre redownload ruby strict bundler=b? g|group=q source=b].freeze,
@@ -42,18 +42,19 @@ module Squared
42
42
  target-rbconfig=p? P|trust-policy=b without=b].freeze,
43
43
  update: %w[system=b?].freeze,
44
44
  uninstall: %w[a D I x vendor n|bindir=p i|install-dir=p platform=b v|version=b].freeze,
45
- outdated: %w[b|both clear-sources l|local no-http-proxy r|remote B|bulk-threshold=i p|http-proxy=q?
46
- platform=q source=q].freeze,
47
- push: %w[no-http-proxy attestation=p host=q key=b otp=b p|http-proxy=q?].freeze,
45
+ outdated: %w[b|both clear-sources l|local no-http-proxy r|remote B|bulk-threshold=i p|http-proxy=q? platform=q
46
+ source=q].freeze,
47
+ push: %w[no-http-proxy attestation=p host=q p|http-proxy=q? key=b otp=b].freeze,
48
48
  build: %w[force strict o|output=p platform=q].freeze,
49
- exec: %w[conservative prerelease no-prerelease g|gem=v version=b].freeze,
50
- pristine: %w[all env-shebang extensions no-env-shebang no-extensions only-executables only-missing-extensions
51
- only-plugins n|bindir=p i|install-dir=p skip=b v|version=b].freeze,
49
+ exec: %w[conservative no-prerelease prerelease g|gem=v version=b].freeze,
50
+ pristine: %w[all only-executables only-missing-extensions only-plugins n|bindir=p i|install-dir=p skip=b
51
+ v|version=b].freeze,
52
52
  no: {
53
- install: %w[env-shebang force format-executable http-proxy lock minimal-deps post-install-message
54
- prerelease suggestions user-install wrappers].freeze,
53
+ install: %w[env-shebang force format-executable http-proxy lock minimal-deps post-install-message prerelease
54
+ suggestions user-install wrappers].freeze,
55
55
  uninstall: %w[abort-on-dependent all check-development executables force format-executable
56
- ignore-dependencies user-install].freeze
56
+ ignore-dependencies user-install].freeze,
57
+ pristine: %w[env-shebang extensions].freeze
57
58
  }.freeze
58
59
  }.freeze
59
60
  private_constant :GEMFILE, :DIR_RUBY, :OPT_RUBY, :OPT_BUNDLE, :OPT_GEM
@@ -101,7 +102,7 @@ module Squared
101
102
  end
102
103
  @autodetect = autodetect
103
104
  @dependindex = GEMFILE.index { |file| basepath(file).exist? }
104
- @dependfile = basepath(GEMFILE[@dependindex || 0])
105
+ @dependfile = @path + GEMFILE[@dependindex || 0]
105
106
  return if !@output[0].nil? || !@copy.nil? || @version || @autodetect || (file = rakefile).nil?
106
107
 
107
108
  begin
@@ -160,17 +161,19 @@ module Squared
160
161
  next unless (spec = basepath("#{project}.gemspec") || basepath("#{name}.gemspec"))
161
162
  next unless basepath('lib').join("#{gemname = stripext(spec)}.rb").exist?
162
163
 
163
- format_desc action, nil, 'opts*,args*'
164
+ format_desc action, nil, 'opts*,args*|:'
164
165
  task action do |_, args|
165
- irb gemname, args.to_a
166
+ args = args.to_a
167
+ if args.last == ':'
168
+ args.pop
169
+ load = readline('Enter file and arguments', force: false)
170
+ end
171
+ irb(gemname, args, load: load)
166
172
  end
167
173
  else
168
174
  format_desc(action, nil, OPT_BUNDLE[action.to_sym], after: case action
169
- when 'cache', 'check'
170
- nil
171
- else
172
- 'command+'
173
- end)
175
+ when 'cache', 'check' then nil
176
+ else 'command+' end)
174
177
  task action do |_, args|
175
178
  bundle(action, *args.to_a)
176
179
  end
@@ -187,7 +190,7 @@ module Squared
187
190
  when 'gem'
188
191
  case flag
189
192
  when :outdated
190
- format_desc action, flag, 'major|minor|patch|(i)nteractive?,opts*'
193
+ format_desc action, flag, 'major|minor|patch|interactive?,opts*'
191
194
  task flag, [:semver] do |_, args|
192
195
  case (filter = args.semver)
193
196
  when 'major', 'minor', 'patch', 'interactive', 'i'
@@ -207,8 +210,8 @@ module Squared
207
210
  else
208
211
  format_desc action, flag, "opts*,name+#{flag == :pristine ? '|name?@version' : ''}"
209
212
  task flag do |_, args|
210
- opts = param_guard(action, flag, args: args.to_a)
211
- gem! flag, opts
213
+ args = param_guard(action, flag, args: args.to_a)
214
+ gem! flag, args
212
215
  end
213
216
  end
214
217
  when 'ruby'
@@ -220,15 +223,10 @@ module Squared
220
223
  ruby(flag, args.to_a.drop(1), file: file)
221
224
  end
222
225
  when :script
223
- format_desc action, flag, 'command|RUBY_E,opts*,args*'
224
- task flag, [:e] do |_, args|
225
- if (command = ENV['RUBY_E'])
226
- opts = args.to_a
227
- else
228
- command = param_guard(action, flag, args: args, key: :e)
229
- opts = args.to_a.drop(1)
230
- end
231
- ruby(flag, opts, command: command)
226
+ format_desc action, flag, 'RUBY_E?,opts*,args*'
227
+ task flag do |_, args|
228
+ command = ENV['RUBY_E'] || readline('Enter script', force: true)
229
+ ruby(flag, args.to_a, command: command)
232
230
  end
233
231
  when :version
234
232
  format_desc action, flag
@@ -250,6 +248,7 @@ module Squared
250
248
  elsif outdated?
251
249
  workspace.rev_clear(name)
252
250
  cmd = bundle_session 'install'
251
+ cmd << '--without=development' if prod?
253
252
  if (n = option('jobs')).to_i > 0
254
253
  cmd << "-j#{n}"
255
254
  end
@@ -257,14 +256,18 @@ module Squared
257
256
  end
258
257
  end
259
258
 
260
- def copy(from: 'lib', include: nil, exclude: nil, into: @gemdir, override: false)
259
+ def copy(from: 'lib', into: @gemdir, override: false, **kwargs)
260
+ glob = kwargs[:include]
261
+ pass = kwargs[:exclude]
261
262
  if @copy && !override
262
263
  return super unless @copy.is_a?(Hash)
263
264
 
264
265
  from = @copy[:from] if @copy.key?(:from)
265
266
  glob = @copy[:include] if @copy.key?(:include)
266
- exclude = @copy[:exclude] if @copy.key?(:exclude)
267
+ pass = @copy[:exclude] if @copy.key?(:exclude)
267
268
  into = @copy[:into] if @copy.key?(:into)
269
+ elsif @copy == false
270
+ return
268
271
  end
269
272
  return unless into
270
273
 
@@ -273,12 +276,12 @@ module Squared
273
276
  print_item unless @output[0] || task_invoked?(/^copy(?::#{Ruby.ref}|$)/)
274
277
  glob = as_a(glob || '**/*')
275
278
  as_a(from).each_with_index do |val, i|
276
- a = basepath(val)
277
- b = dest.join(val)
278
- c = glob[i] || glob[0]
279
- log.info "cp #{a.join(c)} #{b}"
279
+ a = path + val
280
+ b = dest + val
281
+ c = glob[i] || glob.first
282
+ log.info "cp #{a + c} #{b}"
280
283
  begin
281
- copy_dir(a, b, c, pass: exclude, verbose: verbose)
284
+ copy_dir(a, b, c, pass: pass, verbose: verbose)
282
285
  rescue StandardError => e
283
286
  log.error e
284
287
  ret = on(:error, :copy, e)
@@ -310,8 +313,8 @@ module Squared
310
313
  data = line.scan(SEM_VER)
311
314
  next unless (cur = data.shift) && (lat = data.shift)
312
315
 
313
- semver(cur)
314
- semver(lat)
316
+ semver cur
317
+ semver lat
315
318
  c = cur.join
316
319
  l = lat.join
317
320
  styles = []
@@ -414,7 +417,7 @@ module Squared
414
417
  def update(flag, opts = [])
415
418
  bundle_session 'update', "--#{flag}"
416
419
  append_bundle(opts, OPT_BUNDLE[:install_base] + OPT_BUNDLE[:update] + OPT_BUNDLE[:common],
417
- append: flag == :all ? nil : /^\w+=/)
420
+ append: flag == :all ? nil : /\A\w+=/)
418
421
  run_rb(from: :update)
419
422
  end
420
423
 
@@ -423,7 +426,7 @@ module Squared
423
426
  when :file, :script
424
427
  op = OptionPartition.new(opts, OPT_RUBY[:ruby], ruby_session, project: self, args: true)
425
428
  if file
426
- op.extras.unshift(shell_quote(basepath(file)))
429
+ op.extras.unshift(shell_quote(path + file))
427
430
  elsif command
428
431
  op << quote_option('e', command, option: false)
429
432
  end
@@ -446,7 +449,7 @@ module Squared
446
449
  ].each do |val|
447
450
  next unless val.empty? || File.exist?(val.sub('$HOME', Dir.home))
448
451
 
449
- trim = ->(s) { s[/^\D+\d+\.\d+(?:\.\S+)?/, 0].sub(/^([a-z]+)-/i, '\1 ') }
452
+ trim = ->(s) { s[/\A\D+\d+\.\d+(?:\.\S+)?/, 0].sub(/\A([a-z]+)-/i, '\1 ') }
450
453
  ver = '.ruby-version'
451
454
  out << trim.call(case (cmd = File.basename(val))
452
455
  when 'rvm'
@@ -490,7 +493,7 @@ module Squared
490
493
  end
491
494
  if ver
492
495
  path.ascend do |ent|
493
- next unless (ent = ent.join(ver)).exist?
496
+ next unless (ent += ver).exist?
494
497
 
495
498
  hint = File.read(ent).lines(chomp: true).reject(&:empty?).join(', ') rescue nil
496
499
  out << message("found #{ent}", hint: hint)
@@ -522,21 +525,17 @@ module Squared
522
525
  case flag
523
526
  when :install, :update
524
527
  list.concat(OPT_GEM[:install_base])
525
- no = OPT_GEM[:no][:install]
526
- first = true
527
- when :uninstall
528
- no = OPT_GEM[:no][:uninstall]
529
- first = true
530
- when :pristine
531
- first = true
528
+ first = ['=']
529
+ when :uninstall, :pristine
530
+ first = ['=']
532
531
  end
533
532
  cmd.merge(preopts)
534
- op = OptionPartition.new(opts, list, cmd, project: self, no: no, first: first)
533
+ op = OptionPartition.new(opts, list, cmd, project: self, no: OPT_GEM[:no][flag], first: first)
535
534
  op.each do |opt|
536
535
  if opt =~ op.values
537
536
  case $1
538
537
  when 'g', 'gem'
539
- op << (flag == :exec ? shell_option($1, $2) : quote_option($1, basepath($2)))
538
+ op << (flag == :exec ? shell_option($1, $2) : quote_option($1, path + $2))
540
539
  end
541
540
  elsif opt.include?('=') && !%i[outdated build push exec].include?(flag)
542
541
  op.errors << opt
@@ -559,8 +558,8 @@ module Squared
559
558
  items = [[%w[Gem Current Latest], nil]]
560
559
  IO.popen(cmd.done).each do |line|
561
560
  if line =~ /^(\S+) \((\S+) < ([^)]+)\)$/
562
- cur = semscan($2)
563
- lat = semscan($3)
561
+ cur = semscan $2
562
+ lat = semscan $3
564
563
  items << [$~.to_a.drop(1), if semmajor?(cur, lat)
565
564
  1
566
565
  else
@@ -570,20 +569,19 @@ module Squared
570
569
  puts line
571
570
  end
572
571
  end
573
- if items.size == 1
574
- puts 'No updates were found'
575
- else
572
+ if items.size > 1
576
573
  pad = [items.size.to_s.size + 1, 3].max
577
574
  d = 0
578
575
  e = 0
579
576
  f = 0
577
+ j = 0
578
+ queue = nil
580
579
  items.each do |item|
581
580
  a, b, c = item.first
582
581
  d = a.size if a.size > d
583
582
  e = b.size if b.size > e
584
583
  f = c.size if c.size > f
585
584
  end
586
- j = 0
587
585
  items.each_with_index do |item, i|
588
586
  next if i == 0 && stdin?
589
587
 
@@ -594,11 +592,10 @@ module Squared
594
592
  2.times do
595
593
  line = sub_style(line, pat: /^(.+)(?<!\dm)(#{a}|#{c})(.*)$/, styles: theme[:header], index: 2)
596
594
  end
597
- puts line
598
- puts sub_style(ARG[:BORDER][1] * n, styles: borderstyle)
595
+ queue = [line, sub_style(ARG[:BORDER][1] * n, styles: borderstyle)]
599
596
  else
600
597
  g = a.ljust(d)
601
- pat = [/\A([^.]+\.)([^.]+\..+)\z/, /\A([^.]+\.[^.]+\.)(.+)\z/]
598
+ pat = [/^([^.]+\.)([^.]+\..+)$/, /^([^.]+\.[^.]+\.)(.+)$/]
602
599
  pre = b.start_with?('0.')
603
600
  latest = [theme[:current]]
604
601
  case item.last
@@ -638,50 +635,58 @@ module Squared
638
635
  b = sub_style(b, *colormap(styles), pat: pat, index: 2)
639
636
  h = sub_style(c.rjust(f), styles: latest.flatten.compact, pat: pat, index: 2)
640
637
  j += 1
638
+ if queue
639
+ puts queue
640
+ queue = nil
641
+ end
641
642
  puts "#{"#{j}.".rjust(pad)} #{g} #{b} #{h}"
642
643
  update << a if filter == 'interactive' && confirm_outdated(a, c, item.last)
643
644
  end
644
645
  end
645
646
  end
646
647
  end
647
- unless update.empty?
648
- cmd = gem_output 'update', '-f'
649
- if (val = option('document', prefix: 'gem', ignore: false))
650
- cmd << case val
651
- when '0', 'false'
652
- '--no-document'
653
- else
654
- basic_option('document', val)
655
- end
648
+ if major + minor + patch == 0
649
+ puts 'No updates were found'
650
+ else
651
+ unless update.empty?
652
+ cmd = gem_output 'update', '-f'
653
+ if (val = option('document', prefix: 'gem', ignore: false))
654
+ cmd << case val
655
+ when '0', 'false'
656
+ '--no-document'
657
+ else
658
+ basic_option('document', val)
659
+ end
660
+ end
661
+ if (val = option('user-install', prefix: 'gem', ignore: false))
662
+ cmd << case val
663
+ when '0', 'false'
664
+ '--no-user-install'
665
+ else
666
+ '--user-install'
667
+ end
668
+ end
669
+ cmd.merge(update)
670
+ run(cmd, banner: false, from: :'gem:update')
656
671
  end
657
- if (val = option('user-install', prefix: 'gem', ignore: false))
658
- cmd << case val
659
- when '0', 'false'
660
- '--no-user-install'
661
- else
662
- '--user-install'
663
- end
672
+ unless stdin?
673
+ status = print_footer("major #{major} / minor #{minor} / patch #{patch}", right: true).split("\n")
674
+ status[1] = sub_style(status[1], pat: /^( +major )(\d+)(.+)$/, styles: theme[:major], index: 2)
675
+ status[1] = sub_style(status[1], pat: /^(.+)(minor )(\d+)(.+)$/, styles: theme[:active], index: 3)
676
+ puts status
664
677
  end
665
- cmd.merge(update)
666
- run(cmd, banner: false, from: :'gem:update')
667
- end
668
- unless stdin?
669
- status = print_footer("major #{major} / minor #{minor} / patch #{patch}", right: true).split("\n")
670
- status[1] = sub_style(status[1], pat: /^( +major )(\d+)(.+)$/, styles: theme[:major], index: 2)
671
- status[1] = sub_style(status[1], pat: /^(.+)(minor )(\d+)(.+)$/, styles: theme[:active], index: 3)
672
- puts status
673
678
  end
674
679
  on :last, from
675
680
  return
676
681
  when :build, :push
677
682
  if !op.empty?
678
683
  if flag == :build && op.size == 1
679
- op << shell_quote(basepath(op.first))
684
+ op << shell_quote(path + op.first)
680
685
  else
681
686
  raise_error("unknown args: #{op.join(', ')}", hint: flag)
682
687
  end
683
688
  elsif flag == :build
684
- spec = [basepath("#{project}.gemspec"), basepath("#{name}.gemspec"), *Dir.glob(basepath('*.gemspec'))]
689
+ spec = [path + "#{project}.gemspec", path + "#{name}.gemspec", *Dir.glob(path + '*.gemspec')]
685
690
  op << File.basename(spec) if (spec = spec.find { |file| File.exist?(file) })
686
691
  end
687
692
  when :exec
@@ -692,7 +697,7 @@ module Squared
692
697
  if flag == :pristine
693
698
  if op.arg?('all')
694
699
  append_repeat 'skip', op.extras
695
- op.clear
700
+ op.extras.clear
696
701
  elsif (n = op.first.index('@'))
697
702
  name = op.shift
698
703
  if n == 0
@@ -743,11 +748,16 @@ module Squared
743
748
  run_s(args, banner: false, from: :rake)
744
749
  end
745
750
 
746
- def irb(name, opts = [], path: basepath('lib'))
747
- op = OptionPartition.new(opts, OPT_RUBY[:irb], session('irb'), project: self, first: true)
748
- as_a(name).each { |val| op << shell_option('r', val) }
749
- as_a(path).each { |val| op << quote_option('I', val) }
750
- op.merge(op.extras)
751
+ def irb(name, opts = [], path: @path + 'lib', load: nil)
752
+ op = OptionPartition.new(opts, OPT_RUBY[:irb], session('irb'), project: self, first: [/\.rb$/])
753
+ as_a(name).each { |val| op << shell_option('r', val, merge: true) }
754
+ as_a(path).each { |val| op << quote_option('I', val, merge: true) }
755
+ if load
756
+ op << '--' << load
757
+ op.clear
758
+ else
759
+ op.append(delim: true)
760
+ end
751
761
  run(banner: false)
752
762
  end
753
763
 
@@ -759,8 +769,26 @@ module Squared
759
769
  return true if super || (@copy.is_a?(Hash) && copy.fetch(:into, nil))
760
770
  return gemdir? if @gemdir
761
771
 
762
- if @version && (home = ENV['GEM_HOME'])
763
- @gemdir = Pathname.new(home).join(gempath)
772
+ if @version
773
+ begin
774
+ case @autodetect
775
+ when 'rvm'
776
+ @gemdir = pwd_set { `rvm info homes` }[/^\s+gem:\s+"(.+)"$/, 1]
777
+ when 'rbenv'
778
+ if pwd_set { `rbenv which ruby` } =~ %r{^(.+[\\/]versions[\\/](\d\.\d)\.[^\\/]+)[\\/]bin[\\/]ruby$}
779
+ @gemdir = File.join($1, 'lib/ruby/gems', "#{$2}.0")
780
+ end
781
+ when 'asdf'
782
+ @gemdir = pwd_set { `asdf where ruby` }
783
+ @gemdir = @gemdir =~ /(\d\.\d)\.[^.]+$/ && File.join(@gemdir, 'lib/ruby/gems', "#{$1}.0")
784
+ when /bundler?/
785
+ @gemdir = pwd_set { `bundle env` }[/^\s+Gem Home\s+(.+)$/, 1]
786
+ end
787
+ rescue StandardError => e
788
+ log.debug e
789
+ else
790
+ @gemdir = Pathname.new(@gemdir) if @gemdir
791
+ end
764
792
  return true if gemdir?
765
793
  end
766
794
  return false unless @autodetect
@@ -768,7 +796,7 @@ module Squared
768
796
  set = lambda do |val, path|
769
797
  log.warn "using version #{val} (given #{@version})" if @version && @version != val
770
798
  @version = val
771
- @gemdir = Pathname.new(path.strip).join(gempath)
799
+ @gemdir = Pathname.new(path.strip) + gempath
772
800
  end
773
801
  if @version
774
802
  pwd = gempwd
@@ -899,7 +927,7 @@ module Squared
899
927
  end
900
928
 
901
929
  def gemdir?
902
- @gemdir.exist? && !@gemdir.empty?
930
+ !@gemdir.nil? && @gemdir.exist? && !@gemdir.empty?
903
931
  end
904
932
 
905
933
  def variables
@@ -909,7 +937,7 @@ module Squared
909
937
  def rakefile
910
938
  return unless (file = Rake::Application::DEFAULT_RAKEFILES.find { |val| basepath(val).exist? })
911
939
 
912
- basepath file
940
+ path + file
913
941
  end
914
942
 
915
943
  def rakepwd
@@ -35,18 +35,25 @@ module Squared
35
35
  kwargs[:hint] ||= 'unrecognized'
36
36
  append(target, opts, delim: true) if kwargs.delete(:append)
37
37
  warn log_message(Logger::WARN, opts.join(', '), pass: true, **kwargs)
38
- return if pass || confirm("Run? [#{sub_style(target, styles: styles)}] [y/N] ", 'N', timeout: 30)
38
+ return if pass || confirm("Run? [#{sub_style(target, styles: styles)}] [y/N] ", 'N')
39
39
 
40
40
  raise_error 'user cancelled'
41
41
  end
42
42
 
43
+ def strip(val)
44
+ return [] unless val
45
+
46
+ val = shell_split(val) if val.is_a?(String)
47
+ val.map { |s| s.sub(/\A-([a-z\d])(.+)\z/mi, '\1=\2').sub(/\A--?/, '') }.reject(&:empty?)
48
+ end
49
+
43
50
  def arg?(target, *args, value: false)
44
51
  r, s = args.partition { |val| val.is_a?(Regexp) }
45
52
  unless s.empty?
46
53
  s.map! { |val| Regexp.escape(shell_option(val)) }
47
54
  r << /\A(?:#{s.join('|')})#{value ? '[ =].' : '(?: |=|\z)'}/
48
55
  end
49
- target.any? { |opt| r.any? { |val| opt.match?(val) } }
56
+ target.any? { |opt| r.any? { |val| opt&.match?(val) } }
50
57
  end
51
58
  end
52
59
 
@@ -66,7 +73,7 @@ module Squared
66
73
  parse(list, opts, **kwargs, &blk)
67
74
  end
68
75
 
69
- def parse(list, opts = extras, no: nil, single: nil, args: false, first: false, pass: ['='], &blk)
76
+ def parse(list, opts = extras, no: nil, single: nil, args: false, first: nil, &blk)
70
77
  @extras = []
71
78
  @values = []
72
79
  bare = []
@@ -79,8 +86,8 @@ module Squared
79
86
  i = []
80
87
  f = []
81
88
  si = []
82
- list.map do |val|
83
- x, y = val.split('|')
89
+ list.flat_map do |val|
90
+ x, y = val.split('|', 2)
84
91
  if y
85
92
  if (n = val.index('='))
86
93
  x += val[n..-1]
@@ -90,7 +97,6 @@ module Squared
90
97
  x
91
98
  end
92
99
  end
93
- .flatten
94
100
  .each do |val|
95
101
  if (n = val.index('='))
96
102
  flag = val[0, n]
@@ -125,6 +131,12 @@ module Squared
125
131
  end
126
132
  no = (no || []).map { |val| (n = val.index('=')) ? val[0, n] : val }
127
133
  bare.concat(no)
134
+ numtype = [
135
+ [i, /\A\d+\z/],
136
+ [f, /\A\d*(?:\.\d+)?\z/],
137
+ [si, /\A-?\d+\z/]
138
+ ].freeze
139
+ numcheck = ->(k, v) { numtype.any? { |flag, pat| flag.include?(k) && pat.match?(v) } }
128
140
  skip = false
129
141
  opts.each do |opt|
130
142
  next @extras << opt if skip
@@ -140,14 +152,13 @@ module Squared
140
152
  key = $1
141
153
  val = $2
142
154
  merge = m.include?(key)
143
- r = ->(flag, pat) { flag.include?(key) && pat.match?(val) }
144
155
  if e.include?(key)
145
156
  target << shell_option(key, val, merge: merge)
146
157
  elsif q.include?(key)
147
158
  target << quote_option(key, val, double: qq.include?(key), merge: merge)
148
159
  elsif p.include?(key) && path
149
- target << quote_option(key, path.join(val), merge: merge)
150
- elsif b.include?(key) || r.call(i, /^\d+$/) || r.call(f, /^\d*(?:\.\d+)?$/) || r.call(si, /^-?\d+$/)
160
+ target << quote_option(key, path + val, merge: merge)
161
+ elsif b.include?(key) || numcheck.call(key, val)
151
162
  target << basic_option(key, val, merge: merge)
152
163
  elsif merge
153
164
  target << basic_option(key, val, merge: true)
@@ -159,10 +170,10 @@ module Squared
159
170
  @extras << opt
160
171
  skip = true if args
161
172
  end
162
- skip = true if first && pass.none? { |s| opt.include?(s) }
173
+ skip = true if first&.any? { |s| s.is_a?(Regexp) ? opt.match?(s) : !opt.include?(s) }
163
174
  end
164
175
  end
165
- @values = @values.empty? ? /\A\s+\z/ : /\A(#{@values.join('|')})=(.+)\z/
176
+ @values = @values.empty? ? /\A\s+\z/ : /\A(#{@values.join('|')})=(.+)\z/m
166
177
  @extras.each_with_index(&blk) if block_given?
167
178
  self
168
179
  end
@@ -181,9 +192,14 @@ module Squared
181
192
  self
182
193
  end
183
194
 
184
- def clear(opts = nil, **kwargs)
185
- opts ||= (kwargs[:errors] ? errors : extras)
195
+ def clear(opts = nil, errors: false, **kwargs)
186
196
  styles = project.theme[:inline] if project
197
+ if !opts
198
+ opts = errors ? @errors : @extras
199
+ elsif errors
200
+ OptionPartition.clear(target, @errors, styles: styles, **kwargs)
201
+ @errors.clear
202
+ end
187
203
  OptionPartition.clear(target, opts.reject { |val| found.include?(val) }, styles: styles, **kwargs)
188
204
  opts.clear
189
205
  self
@@ -6,7 +6,7 @@ module Squared
6
6
  class << self
7
7
  def read_manifest(path)
8
8
  require 'rexml/document'
9
- return unless (file = path.join('.repo/manifest.xml')).exist?
9
+ return unless (file = path + '.repo/manifest.xml').exist?
10
10
 
11
11
  doc = REXML::Document.new(file.read)
12
12
  doc.elements['manifest/include'].attributes['name']&.sub('.xml', '')
@@ -39,12 +39,12 @@ module Squared
39
39
  raise_error("path does not exist: #{val}", hint: 'REPO_ROOT') unless repo_confirm
40
40
  end
41
41
  @root.join(main).realdirpath
42
- elsif repo_install?(parent: true) && (!@home.exist? || @root.join(main) == @home)
42
+ elsif repo_install?(parent: true) && (!@home.exist? || @root + main == @home)
43
43
  @home
44
44
  elsif repo_install?(@home)
45
- @home.join(main)
45
+ @home + main
46
46
  else
47
- (path = pwd) == @home || !repo_install?(path) ? @home : path.join(main)
47
+ (path = pwd) == @home || !repo_install?(path) ? @home : path + main
48
48
  end
49
49
  @root = @home.parent
50
50
  @manifest_url = url