squared 0.0.12 → 0.1.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.
@@ -9,32 +9,31 @@ module Squared
9
9
  private_constant :OPT_PULL, :OPT_FETCH
10
10
 
11
11
  class << self
12
- include ::Rake::DSL
12
+ include Rake::DSL
13
13
 
14
14
  def populate(ws, **)
15
15
  return if ws.series[:pull].empty?
16
16
 
17
- name = ws.task_name('all')
18
- desc ws.task_name('all[git?=rebase|stash]', desc: true)
19
- task name, [:git] do |_, args|
20
- sync = lambda do |key|
21
- key = ws.task_name(key)
22
- ws.task_defined?(ret = ws.task_join(key, 'sync')) ? ret : key
17
+ namespace(name = ws.task_name('git')) do
18
+ all = ws.task_join(name, 'all')
19
+
20
+ desc ws.task_name("#{all}[git?=rebase|stash,depend?]", desc: true)
21
+ task 'all', [:git, :depend] do |_, args|
22
+ cmd = case args.git
23
+ when 'rebase'
24
+ [ws.task_sync('rebase')]
25
+ when 'stash'
26
+ [ws.task_sync('stash'), ws.task_sync('pull')]
27
+ else
28
+ [ws.task_sync('pull')]
29
+ end
30
+ cmd << ws.task_sync('depend') if args.depend && !ws.series[:depend].empty?
31
+ cmd << ws.task_sync('build')
32
+ Common::Utils.task_invoke(*cmd, **ws.invokeargs)
23
33
  end
24
- cmd = [case args.git
25
- when 'rebase'
26
- sync.('rebase')
27
- when 'stash'
28
- invoke(sync.('stash'), **ws.invokeargs)
29
- sync.('pull')
30
- else
31
- sync.('pull')
32
- end]
33
- cmd << ws.task_name('build')
34
- Common::Utils.task_invoke(*cmd, **ws.invokeargs)
34
+ ws.series.sync << all
35
+ ws.series.multiple << all
35
36
  end
36
- ws.series.sync << name
37
- ws.series.multiple << name
38
37
  end
39
38
 
40
39
  def tasks
@@ -63,7 +62,8 @@ module Squared
63
62
  refs: %i[heads tags].freeze,
64
63
  reset: %i[head soft mixed hard merge keep submodules].freeze,
65
64
  restore: %i[worktree staged overlay].freeze,
66
- rev: %i[commit branch].freeze
65
+ rev: %i[commit branch].freeze,
66
+ show: %i[oneline pretty format].freeze
67
67
  }.freeze
68
68
 
69
69
  def initialize(*, **)
@@ -200,6 +200,21 @@ module Squared
200
200
  reset(flag, ref: args.ref)
201
201
  end
202
202
  end
203
+ when :show
204
+ if flag == :oneline
205
+ desc format_desc(action, flag, 'object+')
206
+ task flag, [:object] do |_, args|
207
+ objs = guard_params(action, flag, args: args.to_a)
208
+ show(objs, pretty: 'oneline', abbrev: true)
209
+ end
210
+ else
211
+ desc format_desc(action, flag, 'format,object+')
212
+ task flag, [:format, :object] do |_, args|
213
+ format = guard_params(action, flag, args: args, key: :format)
214
+ objs = guard_params(action, flag, args: args.to_a[1..-1] || [])
215
+ show(objs, "#{flag}": format)
216
+ end
217
+ end
203
218
  end
204
219
  end
205
220
  end
@@ -220,7 +235,13 @@ module Squared
220
235
  cmd << '--commit'
221
236
  end
222
237
  append_pull opts, OPT_PULL, flag
223
- source(sync: sync, **threadargs)
238
+ sub = if verbose
239
+ [
240
+ { pat: /^(.+)(\|\s+\d+\s+)([^-]*)(-+)(.*)$/, styles: :red, index: 4 },
241
+ { pat: /^(.+)(\|\s+\d+\s+)(\++)(-*)(.*)$/, styles: :green, index: 3 }
242
+ ]
243
+ end
244
+ source(sync: sync, sub: sub, **threadargs)
224
245
  end
225
246
 
226
247
  def rebase
@@ -399,17 +420,17 @@ module Squared
399
420
  raise_error('commit', 'pathspec', hint: 'missing') if (files = projectmap(files)).empty?
400
421
  "-- #{files.join(' ')}"
401
422
  end
402
- unless push?
403
- source('git branch -vv --list', io: true, banner: false).first.each do |val|
404
- origin = %r{^\* [^\[]+(?<= )\[([\w.-/]+?)/([\w.-]+)\] }.match(val)
405
- next unless origin
406
-
407
- @origin = origin[1]
408
- @branch = origin[2]
409
- break
410
- end
423
+ origin = nil
424
+ branch = nil
425
+ source('git fetch --no-tags --quiet', io: true, banner: false)
426
+ source('git branch -vv --list', io: true, banner: false).first.each do |val|
427
+ next unless (data = %r{^\* [^\[]+(?<= )\[([\w.-/]+?)/([\w.-]+)\] }.match(val))
428
+
429
+ origin = data[1]
430
+ branch = data[2]
431
+ break
411
432
  end
412
- raise_error('commit', 'work tree is not usable') unless push?
433
+ raise_error('commit', 'work tree is not usable') unless origin && branch
413
434
  cmd = git_session 'commit'
414
435
  cmd << '--dry-run' if option('dry-run')
415
436
  if amend
@@ -433,7 +454,7 @@ module Squared
433
454
  b << @origin << @branch
434
455
  puts if pass
435
456
  source a.join(' ')
436
- source
457
+ source cmd
437
458
  source b.join(' ')
438
459
  end
439
460
 
@@ -444,9 +465,31 @@ module Squared
444
465
  source(stdout: true)
445
466
  end
446
467
 
468
+ def show(objs, pretty: nil, format: nil, abbrev: nil)
469
+ cmd = git_session 'show'
470
+ case (flag = pretty&.downcase)
471
+ when 'oneline', 'short', 'medium', 'full', 'fuller', 'reference', 'email', 'raw'
472
+ cmd << "--pretty=#{flag}"
473
+ else
474
+ if pretty
475
+ cmd << "--pretty=#{shell_escape("tformat:#{pretty}", quote: true)}"
476
+ elsif format
477
+ cmd << "--format=#{shell_escape(format, quote: true)}"
478
+ end
479
+ end
480
+ if (abbrev ||= option('abbrev')) == true
481
+ cmd << '--abbrev-commit'
482
+ elsif abbrev.to_i > 0
483
+ cmd << "--abbrev=#{abbrev}"
484
+ end
485
+ append_value objs
486
+ source(exception: false)
487
+ end
488
+
447
489
  private
448
490
 
449
- def source(cmd = @session, exception: true, io: false, sync: true, stdout: false, stderr: false, banner: true)
491
+ def source(cmd = @session, exception: true, io: false, sync: true, stdout: false, stderr: false, banner: true,
492
+ sub: nil)
450
493
  cmd = session_done(cmd)
451
494
  log.info cmd
452
495
  banner = format_banner(cmd.gsub(File.join(path, ''), ''), banner: banner)
@@ -469,11 +512,12 @@ module Squared
469
512
  require 'open3'
470
513
  if stderr
471
514
  Open3.popen3(cmd) do |_, out, err|
472
- ret = write_lines(out, banner: banner, pass: true)
515
+ ret = write_lines(out, banner: banner, sub: sub, pass: true)
473
516
  if ret == 0
474
- write_lines(err, banner: banner)
517
+ ret = write_lines(err, banner: banner)
518
+ puts 'Success' if ret == 0 && banner && !stdin?
475
519
  else
476
- write_lines(err, loglevel: ::Logger::DEBUG)
520
+ write_lines(err, loglevel: Logger::DEBUG)
477
521
  end
478
522
  end
479
523
  else
@@ -484,15 +528,15 @@ module Squared
484
528
  log.error e
485
529
  raise if exception
486
530
 
487
- warn log_message(::Logger::WARN, e) if warning?
531
+ warn log_message(Logger::WARN, e) if warning?
488
532
  end
489
533
  end
490
534
 
491
535
  def write_lines(data, banner: nil, loglevel: nil, grep: nil, sub: nil, pass: false)
492
- grep = Regexp.new(grep == '*' ? '.+' : grep) if grep.is_a?(::String)
536
+ grep = Regexp.new(grep == '*' ? '.+' : grep) if grep.is_a?(String)
493
537
  sub = nil if stdin?
494
538
  ret = 0
495
- lines = []
539
+ out = []
496
540
  data.each do |line|
497
541
  next if grep && !line.match?(grep)
498
542
 
@@ -501,14 +545,14 @@ module Squared
501
545
  else
502
546
  sub&.each { |h| line = sub_style(line, **h) }
503
547
  if banner
504
- lines << line
548
+ out << line
505
549
  else
506
550
  puts line
507
551
  end
508
552
  end
509
553
  ret += 1
510
554
  end
511
- print_item banner, lines if banner && (ret > 0 || !pass)
555
+ print_item banner, out if banner && (ret > 0 || !pass)
512
556
  ret
513
557
  end
514
558
 
@@ -577,26 +621,18 @@ module Squared
577
621
  end
578
622
  end
579
623
 
580
- def append_option(list)
581
- list.each { |val| @session << "--#{val}" if option(val) }
582
- end
583
-
584
624
  def git_session(*cmd)
585
625
  session('git', *cmd)
586
626
  end
587
627
 
588
- def gitpath
589
- basepath('.git')
590
- end
591
-
592
- def push?
593
- !@origin.nil? && !@branch.nil?
594
- end
595
-
596
628
  def dry_run?
597
629
  @session.include?('--dry-run')
598
630
  end
599
631
 
632
+ def gitpath
633
+ basepath('.git')
634
+ end
635
+
600
636
  def threadargs
601
637
  { stderr: true, exception: exception || !workspace.series.multiple? }
602
638
  end
@@ -74,7 +74,7 @@ module Squared
74
74
  else
75
75
  cmd = guard_params(action, 'command', args: args.to_a)
76
76
  cmd.each do |val|
77
- if (data = indexdata(val))
77
+ if (data = indexitem(val))
78
78
  n, opts = data
79
79
  list = read_scripts
80
80
  if (item = list[n - 1])
@@ -117,52 +117,85 @@ module Squared
117
117
  end
118
118
  end
119
119
 
120
- def copy(from: 'build', glob: nil, into: 'node_modules', scope: nil, also: nil, override: false)
120
+ def copy(from: 'build', into: 'node_modules', workspace: false, include: nil, exclude: nil, scope: nil,
121
+ also: nil, create: nil, override: false)
121
122
  return if @copy == false
122
123
 
123
124
  if @copy && !override
124
125
  return super if runnable?(@copy)
125
126
 
126
127
  from = @copy[:from] if @copy.key?(:from)
127
- glob = @copy[:glob] if @copy.key?(:glob)
128
128
  into = @copy[:into] if @copy.key?(:into)
129
- scope = @copy[:scope] if @copy.key?(:scope)
130
- also = @copy[:also] if @copy.key?(:also)
129
+ workspace = @copy[:workspace] if @copy.key?(:workspace)
130
+ glob = @copy[:include]
131
+ pass = @copy[:exclude]
132
+ scope = @copy[:scope]
133
+ also = @copy[:also]
134
+ create = @copy[:create]
131
135
  end
132
- items = [path != workspace.home && workspace.home? ? workspace.home : nil]
136
+ items = []
137
+ items << @workspace.home if build? && path != @workspace.home && @workspace.home?
133
138
  items += as_a(also) if also
134
- items.each_with_index do |dir, i|
135
- if i == 0
136
- next unless dev? && build?
139
+ return if items.empty?
137
140
 
141
+ print_item unless @output[0] || !verbose || task_invoked?(/^copy(?::#{Node.ref}|$)/)
142
+ items.each do |dir|
143
+ case dir
144
+ when Pathname
138
145
  dest = dir
146
+ when String
147
+ dest = @workspace.rootpath(dir)
148
+ when Symbol
149
+ dest = @workspace.find(name: dir)&.path
150
+ log.warn message("copy project :#{dir}", hint: 'not found') unless dest
151
+ when Hash
152
+ glob = dir[:include]
153
+ pass = dir[:exclude]
154
+ from = dir[:from] if dir.key?(:from)
155
+ into = dir[:into] if dir.key?(:into)
156
+ scope = dir[:scope] if dir.key?(:scope)
157
+ dest = dir[:target]
158
+ create = dir[:create]
159
+ workspace = dir[:workspace]
160
+ dest = items.first unless dest && dest != true
161
+ when Project::Base
162
+ dest = dir.path
139
163
  else
140
- case dir
141
- when ::String
142
- dest = workspace.rootpath(dir)
143
- when ::Symbol
144
- dest = workspace.find(name: dir)&.path
145
- log.warn message("copy project :#{dir}", hint: 'not found') unless dest
146
- when ::Hash
147
- missing = ->(val) { log.warn message("copy attr :#{val}", hint: 'missing') }
148
- glob = dir[:glob]
149
- into = dir[:into] if dir.key?(:into)
150
- scope = dir[:scope]
151
- missing.('target') unless (dest = dir[:target])
152
- missing.('from') unless (from = dir[:from])
153
- when Project::Base
154
- dest = dir.path
155
- else
156
- raise_error("given: #{dir}", hint: 'unknown')
157
- end
164
+ raise_error("given: #{dir}", hint: 'unknown')
158
165
  end
159
166
  next unless from && dest&.directory?
160
167
 
161
168
  from = basepath(from)
162
- dest = dest.join(into, scope || project)
163
169
  glob = as_a(glob || '**/*')
164
- glob.each { |val| log.info "cp #{from.join(val)} #{dest}" }
165
- copy_d(from, dest, glob: glob, verbose: verbose)
170
+ target = []
171
+ if workspace
172
+ Dir.glob(from.join('*')).each do |path|
173
+ next unless (path = Pathname.new(path)).directory?
174
+
175
+ sub = if (proj = @workspace.find(path))
176
+ proj.packagename
177
+ elsif (file = path.join('package.json')).exist?
178
+ begin
179
+ doc = JSON.parse(file.read)
180
+ doc['name']
181
+ rescue StandardError => e
182
+ log.warn e
183
+ raise if exception
184
+ end
185
+ end
186
+ if sub
187
+ target << [path, dest.join(into, sub)]
188
+ else
189
+ log.debug message("package.json in \"#{path}\"", hint: 'not found')
190
+ end
191
+ end
192
+ else
193
+ target << [from, dest.join(into, scope || project)]
194
+ end
195
+ target.each do |src, to|
196
+ glob.each { |val| log.info "cp #{from.join(val)} #{to}" }
197
+ copy_d(src, to, glob: glob, create: create, pass: pass, verbose: verbose)
198
+ end
166
199
  end
167
200
  end
168
201
 
@@ -233,10 +266,10 @@ module Squared
233
266
  dryrun = opts.include?('dry-run')
234
267
  if pnpm? && read_packagemanager(version: '7.15')
235
268
  cmd = 'pnpm outdated'
236
- dryrun ||= !option('dry-run', prefix: 'pnpm').nil?
269
+ dryrun ||= dryrun?('pnpm')
237
270
  else
238
271
  cmd = 'npm outdated'
239
- dryrun ||= !option('dry-run', prefix: 'npm').nil?
272
+ dryrun ||= dryrun?('npm')
240
273
  end
241
274
  log.info cmd
242
275
  banner = format_banner("#{cmd}#{dryrun ? ' --dry-run' : ''}")
@@ -255,7 +288,7 @@ module Squared
255
288
  inter = opts.include?('interactive')
256
289
  unless data.empty?
257
290
  JSON.parse(data).each_pair do |key, val|
258
- val = val.find { |obj| obj['dependent'] == json['name'] } if val.is_a?(::Array)
291
+ val = val.find { |obj| obj['dependent'] == json['name'] } if val.is_a?(Array)
259
292
  next unless val && (file = dep1[key] || dep2[key]) && file != '*'
260
293
 
261
294
  latest = val['latest']
@@ -271,8 +304,8 @@ module Squared
271
304
  want = rev == :major && (ver = latest.match(SEM_VER)) && !ver[6] ? latest : val['wanted']
272
305
  next unless (val['current'] != want || file != want) && (want.match?(SEM_VER) || !file.match?(SEM_VER))
273
306
 
274
- f = semver(semscan(file))
275
- w = semver(semscan(want))
307
+ f = semscan(file)
308
+ w = semscan(want)
276
309
  a = f[0]
277
310
  b = f[2]
278
311
  c = w[0]
@@ -356,9 +389,9 @@ module Squared
356
389
  if dryrun || (modified == 0 && pending > 0)
357
390
  footer.(modified)
358
391
  elsif modified > 0
359
- File.write(dependfile, doc)
360
392
  modified = -1
361
393
  footer.()
394
+ File.write(dependfile, doc)
362
395
  commit(:add, ['package.json'], pass: true)
363
396
  install if opts.include?('prune')
364
397
  end
@@ -384,30 +417,10 @@ module Squared
384
417
  end
385
418
  end
386
419
 
387
- def compose(opts, flags = nil, script: false)
388
- return unless opts && script
389
-
390
- ret = session (if yarn?
391
- 'yarn'
392
- else
393
- pnpm? ? 'pnpm' : 'npm'
394
- end), 'run', flags
395
- append_loglevel
396
- case opts
397
- when ::Enumerable
398
- ret += opts.to_a
399
- when ::String
400
- ret << opts
401
- else
402
- raise_error("#{ret.first} script name", hint: opts.nil? ? 'missing' : 'invalid')
403
- end
404
- ret
405
- end
406
-
407
- def bump(flag)
420
+ def bump(flag = nil, sync: invoked_sync?('bump', flag))
408
421
  return unless (ver = version)
409
422
 
410
- seg = semscan(ver)
423
+ seg = semscan(ver, fill: false)
411
424
  case flag
412
425
  when :major
413
426
  if seg[0] != '0' || seg[2].nil?
@@ -421,45 +434,51 @@ module Squared
421
434
  else
422
435
  seg[2] = seg[2].succ
423
436
  end
424
- when :patch
437
+ else
425
438
  seg[4] &&= seg[4].succ
426
439
  end
427
- unless (out = seg.join) == ver
428
- begin
429
- doc = dependfile.read
430
- if doc.sub!(/"version"\s*:\s*"#{ver}"/, "\"version\": \"#{out}\"")
440
+ return if (out = seg.join) == ver
441
+
442
+ begin
443
+ doc = dependfile.read
444
+ if doc.sub!(/"version"\s*:\s*"#{ver}"/, "\"version\": \"#{out}\"")
445
+ unless dryrun?
431
446
  dependfile.write(doc)
432
447
  log.info "bump version #{ver} to #{out} (#{flag})"
433
- if verbose
434
- major = flag == :major
435
- emphasize("version: #{out}", title: name, border: borderstyle, sub: [
436
- headerstyle,
437
- { pat: /^(version:)( )(\S+)(.*)$/, styles: color(major ? :green : :yellow), index: 3 },
438
- { pat: /^(version:)(.*)$/, styles: theme[major ? :major : :active] }
439
- ])
440
- elsif stdin?
441
- puts out
442
- end
443
- else
444
- raise_error('not found', hint: 'version')
445
448
  end
446
- rescue StandardError => e
447
- log.debug e
448
- raise
449
+ if verbose
450
+ major = flag == :major
451
+ emphasize("version: #{out}", title: name, border: borderstyle, sub: [
452
+ headerstyle,
453
+ { pat: /^(version:)( )(\S+)(.*)$/, styles: color(major ? :green : :yellow), index: 3 },
454
+ { pat: /^(version:)(.*)$/, styles: theme[major ? :major : :active] }
455
+ ])
456
+ elsif stdin?
457
+ puts out
458
+ end
459
+ else
460
+ raise_error('not found', hint: 'version')
449
461
  end
462
+ rescue StandardError => e
463
+ log.debug e
464
+ raise if sync
450
465
  end
451
466
  end
452
467
 
453
- def version
454
- read_packagemanager
455
- @pm[:version]
456
- end
457
-
458
- def dependtype(prog)
459
- return @pm[prog] if @pm.key?(prog)
468
+ def compose(opts, flags = nil, script: false)
469
+ return unless opts && script
460
470
 
461
- meth = :"#{prog}?"
462
- respond_to?(meth) && __send__(meth) ? @pm[prog] : 0
471
+ ret = session dependbin, 'run', flags
472
+ append_loglevel
473
+ case opts
474
+ when Enumerable
475
+ ret += opts.to_a
476
+ when String
477
+ ret << opts
478
+ else
479
+ raise_error("#{ret.first} script name", hint: opts.nil? ? 'missing' : 'invalid')
480
+ end
481
+ ret
463
482
  end
464
483
 
465
484
  def depend?
@@ -467,7 +486,7 @@ module Squared
467
486
  end
468
487
 
469
488
  def copy?
470
- super || @copy.is_a?(::Hash)
489
+ super || @copy.is_a?(Hash)
471
490
  end
472
491
 
473
492
  def outdated?
@@ -475,8 +494,8 @@ module Squared
475
494
  end
476
495
 
477
496
  def yarn?
478
- (@pm[:yarn] ||= if basepath('yarn.lock', ascend: find_package).exist?
479
- if (rc = basepath('.yarnrc.yml', ascend: find_package)).exist?
497
+ (@pm[:yarn] ||= if basepath('yarn.lock', ascend: dependext).exist?
498
+ if (rc = basepath('.yarnrc.yml', ascend: dependext)).exist?
480
499
  begin
481
500
  require 'yaml'
482
501
  doc = YAML.load_file(rc)
@@ -495,10 +514,10 @@ module Squared
495
514
  end
496
515
 
497
516
  def pnpm?
498
- (@pm[:pnpm] ||= if basepath('pnpm-lock.yaml', ascend: find_package).exist?
517
+ (@pm[:pnpm] ||= if basepath('pnpm-lock.yaml', ascend: dependext).exist?
499
518
  begin
500
519
  require 'yaml'
501
- doc = YAML.load_file(basepath('node_modules/.modules.yaml', ascend: find_package))
520
+ doc = YAML.load_file(basepath('node_modules/.modules.yaml', ascend: dependext))
502
521
  @pm[:_] = doc['packageManager']
503
522
  case doc['nodeLinker']
504
523
  when 'hoisted'
@@ -521,24 +540,42 @@ module Squared
521
540
  basepath('pnpm-workspace.yaml').exist?
522
541
  else
523
542
  read_packagemanager
524
- @pm[:workspaces].is_a?(::Array)
543
+ @pm[:workspaces].is_a?(Array)
525
544
  end
526
545
  end
527
546
 
528
547
  def dev?
529
- !Node.prod? && super
548
+ super && (!Node.prod? || (@dev == true && !prod?))
530
549
  end
531
550
 
532
551
  def prod?
533
552
  @prod != false && (Node.prod? || super)
534
553
  end
535
554
 
555
+ def dependtype(prog)
556
+ return @pm[prog] if @pm.key?(prog)
557
+
558
+ meth = :"#{prog}?"
559
+ respond_to?(meth) && __send__(meth) ? @pm[prog] : 0
560
+ end
561
+
562
+ def version
563
+ read_packagemanager
564
+ @pm[:version]
565
+ end
566
+
567
+ def packagename
568
+ read_packagemanager
569
+ @pm[:name]
570
+ end
571
+
536
572
  private
537
573
 
538
574
  def read_packagemanager(version: nil)
539
575
  if @pm[:_].nil?
540
576
  doc = JSON.parse(dependfile.read)
541
577
  @pm[:_] = (val = doc['packageManager']) ? val[0..(val.index('+') || 0) - 1] : false
578
+ @pm[:name] = doc['name']
542
579
  @pm[:scripts] = doc['scripts']
543
580
  @pm[:version] = doc['version']
544
581
  @pm[:workspaces] = doc['workspaces']
@@ -560,7 +597,7 @@ module Squared
560
597
 
561
598
  def read_scripts
562
599
  read_packagemanager
563
- @pm[:scripts].is_a?(::Hash) ? @pm[:scripts].to_a : []
600
+ @pm[:scripts].is_a?(Hash) ? @pm[:scripts].to_a : []
564
601
  end
565
602
 
566
603
  def append_loglevel
@@ -605,12 +642,24 @@ module Squared
605
642
  'PATCH'
606
643
  end, styles: theme[:header])
607
644
  b = sub_style("#{pkg} #{ver}", styles: theme[:inline])
608
- c, d = rev == 1 || lock ? %w[y/N N] : %w[Y/n Y]
645
+ c, d = rev == 1 || lock ? ['y/N', 'N'] : ['Y/n', 'Y']
609
646
  e = lock ? " #{sub_style('(locked)', styles: color(:red))}" : ''
610
647
  Common::Prompt.confirm("Upgrade to #{a}? #{b}#{e} [#{c}] ", d, timeout: 60)
611
648
  end
612
649
 
613
- def find_package
650
+ def dryrun?(prefix = dependbin)
651
+ !option('dry-run', prefix: prefix).nil?
652
+ end
653
+
654
+ def dependbin
655
+ if yarn?
656
+ 'yarn'
657
+ else
658
+ pnpm? ? 'pnpm' : 'npm'
659
+ end
660
+ end
661
+
662
+ def dependext
614
663
  'package.json' if parent&.has?('outdated', Node.ref)
615
664
  end
616
665
  end