squared 0.0.1 → 0.0.2

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.
@@ -6,25 +6,44 @@ module Squared
6
6
  class Git < Base
7
7
  include Common::Format
8
8
 
9
+ REF = :git
10
+ private_constant :REF
11
+
9
12
  class << self
10
- def tasks
11
- %i[pull rebase fetch stash status].freeze
13
+ def populate(workspace, parallel: [], **)
14
+ return if workspace.series[:pull].empty?
15
+
16
+ desc 'all[git?=rebase|stash]'
17
+ task :all, [:git] do |_, args|
18
+ sync = ->(key) { parallel.include?(key) ? :"#{key}:sync" : key }
19
+ pull = case args.git
20
+ when 'rebase'
21
+ sync.(:rebase)
22
+ when 'stash'
23
+ invoke sync.(:stash)
24
+ sync.(:pull)
25
+ else
26
+ sync.(:pull)
27
+ end
28
+ invoke(pull, exception: workspace.exception)
29
+ invoke(workspace.dev? ? :refresh : :build, exception: workspace.exception)
30
+ end
12
31
  end
13
32
 
14
- def to_sym
15
- :git
33
+ def tasks
34
+ %i[pull rebase fetch stash status].freeze
16
35
  end
17
36
 
18
- def is_a?(path)
19
- if path.is_a?(::String) || path.is_a?(::Pathname)
20
- Pathname.new(path).join('.git').directory?
37
+ def is_a?(val)
38
+ if val.is_a?(::Pathname) || (val.is_a?(::String) && (val = Pathname.new(val)))
39
+ val.join('.git').directory?
21
40
  else
22
41
  super
23
42
  end
24
43
  end
25
44
  end
26
45
 
27
- @@tasks[:git] = {
46
+ @@tasks[REF] = {
28
47
  checkout: %i[branch detach force merge],
29
48
  commit: %i[add amend amend-orig all no-all],
30
49
  diff: %i[head cached branch],
@@ -33,16 +52,17 @@ module Squared
33
52
  pull: %i[rebase no-rebase commit no-commit submodules],
34
53
  stash: %i[push pop apply list clear],
35
54
  refs: %i[heads tags],
36
- reset: %i[hard mixed soft],
55
+ reset: %i[head soft mixed hard merge keep submodules],
56
+ restore: %i[worktree staged overlay],
37
57
  rev: %i[commit branch]
38
58
  }.freeze
39
59
 
40
60
  def populate(*)
41
61
  super
42
- return unless vardir.exist?
62
+ return unless gitdir.exist?
43
63
 
44
- namespace @name do
45
- @@tasks[:git].each do |action, flags|
64
+ namespace name do
65
+ @@tasks[REF].each do |action, flags|
46
66
  namespace action do
47
67
  flags.each do |flag|
48
68
  case action
@@ -58,7 +78,7 @@ module Squared
58
78
  opts = collect_args(args, :opts)
59
79
  fetch(flag, opts: opts)
60
80
  end
61
- when :commit
81
+ when :commit, :restore
62
82
  if flag == :all
63
83
  desc format_desc(action, flag, 'message?')
64
84
  task flag, [:message] do |_, args|
@@ -68,7 +88,7 @@ module Squared
68
88
  desc format_desc(action, flag, 'pathspec+')
69
89
  task flag, [:pathspec] do |_, args|
70
90
  guard_params(action, flag, args: args, key: :pathspec)
71
- commit(flag, collect_args(args, :pathspec))
91
+ __send__(action, flag, collect_args(args, :pathspec))
72
92
  end
73
93
  end
74
94
  when :stash
@@ -91,7 +111,7 @@ module Squared
91
111
  when :refs, :files
92
112
  desc format_desc(action, flag, 'grep?=pattern')
93
113
  task flag, [:grep] do |_, args|
94
- send(action, flag, grep: args.fetch(:grep, nil))
114
+ __send__(action, flag, grep: args.fetch(:grep, nil))
95
115
  end
96
116
  when :diff
97
117
  case flag
@@ -151,10 +171,17 @@ module Squared
151
171
  end
152
172
  end
153
173
  when :reset
154
- desc format_desc(action, flag, 'commit')
155
- task flag, [:commit] do |_, args|
156
- guard_params(action, flag, args: args, key: :commit)
157
- reset(flag, commit: args.commit)
174
+ if flag == :head
175
+ desc format_desc(action, flag, 'ref?=HEAD,pathspec+')
176
+ task flag, [:ref, :pathspec] do |_, args|
177
+ guard_params(action, flag, args: args, key: :pathspec)
178
+ reset(:head, collect_args(args, :pathspec), ref: args.ref)
179
+ end
180
+ else
181
+ desc format_desc(action, flag, 'ref?=HEAD')
182
+ task flag, [:ref] do |_, args|
183
+ reset(flag, ref: args.ref)
184
+ end
158
185
  end
159
186
  end
160
187
  end
@@ -175,14 +202,14 @@ module Squared
175
202
  elsif flag == :commit || option('commit')
176
203
  cmd << '--commit'
177
204
  end
178
- cmd << '--recurse-submodules' if flag == :submodules || option('recurse-submodules')
205
+ append_submodules flag
179
206
  opts.each do |val|
180
207
  case val
181
208
  when 'all', 'tags', 'prune', 'ff-only', 'autostash', 'dry-run'
182
209
  cmd << "--#{val}"
183
210
  end
184
211
  end
185
- source(sync: sync, stderr: true, exception: !@workspace.multitask?)
212
+ source(sync: sync, stderr: true, exception: !workspace.multitask?)
186
213
  end
187
214
 
188
215
  def rebase
@@ -192,7 +219,7 @@ module Squared
192
219
  def fetch(flag = nil, opts: [])
193
220
  cmd = git_session 'fetch'
194
221
  cmd << '--all' if flag == :all || option('all')
195
- cmd << '--recurse-submodules' if flag == :submodules || option('recurse-submodules')
222
+ append_submodules flag
196
223
  opts.each do |val|
197
224
  case val
198
225
  when 'tags', 'prune', 'prune-tags', 'dry-run'
@@ -201,7 +228,7 @@ module Squared
201
228
  cmd << "--depth=#{$1}" if /^depth=(\d+)$/.match(val)
202
229
  end
203
230
  end
204
- source(sync: invoked_sync?('fetch', flag), stderr: true, exception: !@workspace.multitask?)
231
+ source(sync: invoked_sync?('fetch', flag), stderr: true, exception: !workspace.multitask?)
205
232
  end
206
233
 
207
234
  def stash(flag = :push, files = [], commit: nil)
@@ -215,7 +242,7 @@ module Squared
215
242
  append_message option('message')
216
243
  append_pathspec files
217
244
  end
218
- source(sync: invoked_sync?('stash', flag), exception: @workspace.exception)
245
+ source(sync: invoked_sync?('stash', flag), exception: workspace.exception)
219
246
  end
220
247
 
221
248
  def status
@@ -249,8 +276,24 @@ module Squared
249
276
  list_result(ret, 'files', action: 'modified')
250
277
  end
251
278
 
252
- def reset(flag, commit: nil)
253
- source "git reset --#{flag} #{commit}"
279
+ def reset(flag, files = [], ref: nil)
280
+ cmd = git_session 'reset'
281
+ if flag == :head
282
+ append_commit ref
283
+ append_pathspec files
284
+ else
285
+ case flag
286
+ when :hard, :soft, :merge, :keep
287
+ cmd << "--#{flag}"
288
+ when :submodules
289
+ append_submodules flag
290
+ else
291
+ cmd << '--mixed'
292
+ cmd << '--no-refresh' if option('refresh', equals: '0')
293
+ end
294
+ append_commit ref
295
+ end
296
+ source
254
297
  end
255
298
 
256
299
  def checkout(flag, files = [], branch: nil, create: nil, commit: nil, detach: nil)
@@ -272,14 +315,8 @@ module Squared
272
315
  cmd << commit if commit
273
316
  else
274
317
  cmd << "--#{flag}"
275
- if option('ours')
276
- cmd << '--ours'
277
- elsif option('theirs')
278
- cmd << '--theirs'
279
- end
280
- if (val = option('tree-ish'))
281
- cmd << val
282
- end
318
+ append_ours
319
+ append_head
283
320
  append_pathspec files
284
321
  end
285
322
  source
@@ -291,7 +328,8 @@ module Squared
291
328
  else
292
329
  (n = size.to_i) > 0 ? "--short=#{[n, 5].max}" : '--verify'
293
330
  end
294
- git_session 'rev-parse', opt, ref || 'HEAD'
331
+ git_session 'rev-parse', opt
332
+ append_commit ref
295
333
  source
296
334
  end
297
335
 
@@ -395,19 +433,35 @@ module Squared
395
433
  source b.join(' ')
396
434
  end
397
435
 
436
+ def restore(flag, files)
437
+ cmd = git_session 'restore'
438
+ case flag
439
+ when :worktree, :staged, :overlay
440
+ cmd << "--#{flag}"
441
+ end
442
+ append_ours
443
+ append_pathspec(files, expect: true)
444
+ source(stdout: true)
445
+ end
446
+
398
447
  protected
399
448
 
400
449
  def source(cmd = @session, exception: true, banner: true, io: false, sync: true, stdout: false, stderr: false)
401
450
  cmd = close_session(cmd)
402
451
  info cmd
403
452
  begin
404
- banner = format_banner(cmd.gsub(trailing_slash(@path), ''), banner: banner, multitask: true)
405
- cmd = cmd.sub(/^git\b/, "git --work-tree #{shell_quote(@path)} --git-dir #{shell_quote(vardir)}")
453
+ banner = format_banner(cmd.gsub(trailing_slash(path), ''), banner: banner, multitask: true)
454
+ cmd = cmd.sub(/^git\b/, "git --work-tree #{shell_quote(path)} --git-dir #{shell_quote(gitdir)}")
406
455
  if io
407
456
  [IO.popen(cmd), banner]
408
457
  elsif pipe? ? sync : stdout
409
458
  print_item banner
410
- puts `#{cmd}`
459
+ ret = `#{cmd}`
460
+ if !ret.empty?
461
+ puts ret
462
+ elsif banner && stdout && !pipe?
463
+ puts 'Success'
464
+ end
411
465
  elsif sync || (!exception && !stderr)
412
466
  print_item banner
413
467
  shell(cmd, exception: exception)
@@ -440,7 +494,7 @@ module Squared
440
494
  found = 0
441
495
  lines = []
442
496
  iter.each do |line|
443
- next if grep && !grep.match?(line)
497
+ next if grep && !line.match?(grep)
444
498
 
445
499
  if loglevel
446
500
  log loglevel, line
@@ -464,39 +518,68 @@ module Squared
464
518
  if size > 0
465
519
  args = styles[:banner]&.reject { |s| s.to_s.end_with?('!') } || []
466
520
  args << :bold if args.size <= 1
467
- puts Project.footer "#{sub_style(size, *args)} #{size == 1 ? type.sub(/s$/, '') : type}"
521
+ puts print_footer "#{sub_style(size, *args)} #{size == 1 ? type.sub(/s$/, '') : type}"
468
522
  else
469
523
  puts empty_status("No #{type} were #{action}", 'grep', grep)
470
524
  end
471
525
  end
472
526
 
473
527
  def source_path(files)
474
- files.select { |val| source_path?(val) }.map { |val| shell_quote(base_path(val.strip)) }
528
+ files.select { |val| source_path?(val) }.map { |val| val == '.' ? '.' : shell_quote(base_path(val.strip)) }
475
529
  end
476
530
 
477
- def source_path?(path)
478
- return path.to_s.start_with?("#{@path}#{::File::SEPARATOR}") if Pathname.new(path).absolute?
531
+ def source_path?(val)
532
+ return val.to_s.start_with?("#{path}#{::File::SEPARATOR}") if Pathname.new(val).absolute?
479
533
 
480
- !%r{^\.\.[/\\]}.match?(path)
534
+ !val.match?(%r{^\.\.[/\\]})
481
535
  end
482
536
 
483
537
  private
484
538
 
485
- def append_pathspec(files)
539
+ def append_commit(val)
540
+ val = val.to_s.strip
541
+ val.empty? ? 'HEAD' : val
542
+ end
543
+
544
+ def append_pathspec(files, expect: false)
486
545
  files = source_path(files)
487
- @session << "-- #{files.join(' ')}" unless files.empty?
546
+ if files.empty?
547
+ raise ArgumentError, message('pathspec not within worktree', hint: 'invalid') if expect
548
+ else
549
+ @session << "-- #{files.join(' ')}"
550
+ end
488
551
  end
489
552
 
490
553
  def append_message(val)
491
554
  @session << "--message \"#{double_quote(val)}\"" if val
492
555
  end
493
556
 
494
- def invoked_sync?(action, flag = nil)
495
- !flag.nil? || super(action)
557
+ def append_head
558
+ return unless (val = option('head')) || (val = option('tree-ish'))
559
+
560
+ @session << val
496
561
  end
497
562
 
498
- def option(val)
563
+ def append_ours
564
+ if option('ours')
565
+ @session << '--ours'
566
+ elsif option('theirs')
567
+ @session << '--theirs'
568
+ end
569
+ end
570
+
571
+ def append_submodules(flag = nil)
572
+ if option('recurse-submodules', equals: '0')
573
+ @session << '--no-recurse-submodules'
574
+ elsif flag == :submodules || option('recurse-submodules')
575
+ @session << '--recurse-submodules'
576
+ end
577
+ end
578
+
579
+ def option(val, equals: nil)
499
580
  ret = ENV.fetch("GIT_#{val.gsub(/\W/, '_').upcase}", '')
581
+ return ret == equals.to_s unless equals.nil?
582
+
500
583
  ret unless ret.empty? || ret == '0'
501
584
  end
502
585
 
@@ -504,8 +587,12 @@ module Squared
504
587
  session('git', *cmd)
505
588
  end
506
589
 
507
- def vardir
508
- @vardir ||= base_path('.git')
590
+ def gitdir
591
+ @gitdir ||= base_path('.git')
592
+ end
593
+
594
+ def invoked_sync?(action, flag = nil)
595
+ !flag.nil? || super(action)
509
596
  end
510
597
 
511
598
  def push?