sugarjar 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bc16295007c8698083a182a521c68481b3cb421644def0115aa04286867dd1eb
4
- data.tar.gz: c901d92e5d7d5287472f52cf56a83d29a5b1b4b0248232278b36e1706bc7117d
3
+ metadata.gz: 4263a42ebb922645e2e0735c3ca33ad94df880fb01f881b2cacb602d733c533e
4
+ data.tar.gz: 616fb99c535c491324c1dcc4906b37c8cb424566b62dc64377c61b9a5ef5fd49
5
5
  SHA512:
6
- metadata.gz: 6d64d758a56feac59e5617544cdde17341c804a8831524c49222f6397e47e886ed16f42280d60584a5231d279410839bdacebda66827ae77bb115addb24f3b6d
7
- data.tar.gz: e65b75d83d852906c713f00d6424a76897177f39eb1f2eaa0b5d17896b6d2fb288de3d1cf0946f5587f5674819a074782279ecdb26094c8038d221fcd7ceab0f
6
+ metadata.gz: 1d918daf7096d1889bf72ee0eca74ef473234ed1ed46e4275418028e9a32c9284b4412ff202a932a3cc43c777bbf55d1455ce8fd8805c965184e4d2bc740e527
7
+ data.tar.gz: 0657a6629d97623d40f68d0ffe7a3e0522c951d9b22dc0c7b4b918d78eb27b026ab68d347b1c2fa68661536eceef9cbf3de3ee82b4ea4381da2675f1d34b3f2d
data/bin/sj CHANGED
@@ -91,6 +91,24 @@ parser = OptionParser.new do |opts|
91
91
  options['log_level'] = level
92
92
  end
93
93
 
94
+ opts.on(
95
+ '--[no-]pr-autofill',
96
+ 'When creating a PR, auto fill the title & description from the commit ' +
97
+ 'if there is a single commit and if we are using "gh". [default: true]',
98
+ ) do |autofill|
99
+ options['pr_autofill'] = autofill
100
+ end
101
+
102
+ opts.on(
103
+ '--[no-]pr-autostack',
104
+ 'When creating a PR, if this is a subfeature, should we make it a ' +
105
+ 'PR on the PR for the parent feature. If not specified, we prompt ' +
106
+ 'when this happens, when true always do this, when false never do ' +
107
+ 'this. Only applicable when usiing "gh".',
108
+ ) do |autostack|
109
+ options['pr_autostack'] = autostack
110
+ end
111
+
94
112
  opts.on('--[no-]use-color', 'Enable color. [default: true]') do |color|
95
113
  options['color'] = color
96
114
  end
@@ -112,10 +130,10 @@ COMMANDS:
112
130
  Same as "amend" but without changing the message. Alias for
113
131
  "git commit --amend --no-edit".
114
132
 
115
- bclean
116
- If safe, delete the current branch. Unlike "git branch -d",
117
- bclean can handle squash-merged branches. Think of it as
118
- a smarter "git branch -d".
133
+ bclean [<branch>]
134
+ If safe, delete the current branch (or the specified branch).
135
+ Unlike "git branch -d", bclean can handle squash-merged branches.
136
+ Think of it as a smarter "git branch -d".
119
137
 
120
138
  bcleanall
121
139
  Walk all branches, and try to delete them if it's safe. See
@@ -127,7 +145,7 @@ COMMANDS:
127
145
  br
128
146
  Verbose branch list. An alias for "git branch -v".
129
147
 
130
- feature
148
+ feature, f <branch_name>
131
149
  Create a "feature" branch. It's morally equivalent to
132
150
  "git checkout -b" except it defaults to creating it based on
133
151
  some form of 'master' instead of your current branch. In order
@@ -177,11 +195,17 @@ COMMANDS:
177
195
  A smart wrapper to "git push" that runs whatever is defined in
178
196
  "on_push" in .sugarjar.yml, and only pushes if they succeed.
179
197
 
198
+ subfeature, sf <feature>
199
+ An alias for 'sj feature <feature> <current_branch>'
200
+
180
201
  unit
181
202
  Run any unitests configured in .sugarjar.yaml.
182
203
 
183
- up
184
- Rebase the current branch on upstream/master or origin/master.
204
+ up [<branch>]
205
+ Rebase the current branch (or specified branch) intelligently.
206
+ In most causes this will check for a main (or master) branch on
207
+ upstream, then origin. If a branch explicitly tracks something
208
+ else, then that will be used, instead.
185
209
 
186
210
  upall
187
211
  Same as "up", but for all branches.
@@ -23,6 +23,8 @@ class SugarJar
23
23
  @repo_config = SugarJar::RepoConfig.config
24
24
  SugarJar::Log.debug("Repoconfig: #{@repo_config}")
25
25
  @color = options['color']
26
+ @pr_autofill = options['pr_autofill']
27
+ @pr_autostack = options['pr_autostack']
26
28
  @feature_prefix = options['feature_prefix']
27
29
  @checks = {}
28
30
  @main_branch = nil
@@ -43,19 +45,31 @@ class SugarJar
43
45
  name = fprefix(name)
44
46
  die("#{name} already exists!") if all_local_branches.include?(name)
45
47
  base ||= most_main
46
- base_pieces = base.split('/')
47
- git('fetch', base_pieces[0]) if base_pieces.length > 1
48
+ # If our base is a local branch, don't try to parse it for a remote name
49
+ unless all_local_branches.include?(base)
50
+ base_pieces = base.split('/')
51
+ git('fetch', base_pieces[0]) if base_pieces.length > 1
52
+ end
48
53
  git('checkout', '-b', name, base)
54
+ git('branch', '-u', base)
49
55
  SugarJar::Log.info(
50
56
  "Created feature branch #{color(name, :green)} based on " +
51
57
  color(base, :green),
52
58
  )
53
59
  end
60
+ alias f feature
61
+
62
+ def subfeature(name)
63
+ assert_in_repo
64
+ SugarJar::Log.debug("Subfature: #{name}")
65
+ feature(name, current_branch)
66
+ end
67
+ alias sf subfeature
54
68
 
55
69
  def bclean(name = nil)
56
70
  assert_in_repo
57
71
  name ||= current_branch
58
- name = fprefix(name) unless all_local_branches.include?(name)
72
+ name = fprefix(name)
59
73
  if clean_branch(name)
60
74
  SugarJar::Log.info("#{name}: #{color('reaped', :green)}")
61
75
  else
@@ -100,7 +114,7 @@ class SugarJar
100
114
  # and then add any featureprefix, and if _that_ is a branch
101
115
  # name, replace the last arguement with that
102
116
  name = args.last
103
- bname = fprefix(name) unless all_local_branches.include?(name)
117
+ bname = fprefix(name)
104
118
  if all_local_branches.include?(bname)
105
119
  SugarJar::Log.debug("Featurepefixing #{name} -> #{bname}")
106
120
  args[-1] = bname
@@ -133,11 +147,14 @@ class SugarJar
133
147
 
134
148
  alias sl smartlog
135
149
 
136
- def up
150
+ def up(branch = nil)
137
151
  assert_in_repo
152
+ branch ||= current_branch
153
+ branch = fprefix(branch)
138
154
  # get a copy of our current branch, if rebase fails, we won't
139
155
  # be able to determine it without backing out
140
156
  curr = current_branch
157
+ git('checkout', branch)
141
158
  result = gitup
142
159
  if result['so'].error?
143
160
  backout = ''
@@ -156,6 +173,8 @@ class SugarJar
156
173
  SugarJar::Log.info(
157
174
  "#{color(current_branch, :green)} rebased on #{result['base']}",
158
175
  )
176
+ # go back to where we were if we rebased a different branch
177
+ git('checkout', curr) if branch != curr
159
178
  end
160
179
  end
161
180
 
@@ -302,6 +321,7 @@ class SugarJar
302
321
  def smartpullrequest(*args)
303
322
  assert_in_repo
304
323
  assert_common_main_branch
324
+
305
325
  if dirty?
306
326
  SugarJar::Log.warn(
307
327
  'Your repo is dirty, so I am not going to create a pull request. ' +
@@ -309,9 +329,38 @@ class SugarJar
309
329
  )
310
330
  exit(1)
311
331
  end
332
+
312
333
  if gh?
334
+ curr = current_branch
335
+ base = tracked_branch
336
+ if @pr_autofill
337
+ num_commits = git(
338
+ 'rev-list', '--count', curr, "^#{base}"
339
+ ).stdout.strip.to_i
340
+ if num_commits > 1
341
+ SugarJar::Log.debug(
342
+ "Not using --fill because there are #{num_commits} commits",
343
+ )
344
+ else
345
+ SugarJar::Log.info('Autofilling in PR from commit message')
346
+ args.unshift('--fill')
347
+ end
348
+ end
349
+ if subfeature?(base)
350
+ # nil is prompt, true is always, false is never
351
+ if @pr_autostack.nil?
352
+ $stdout.print(
353
+ 'It looks like this is a subfeature, would you like to base ' +
354
+ "this PR on #{base}? [y/n] ",
355
+ )
356
+ ans = $stdin.gets.strip
357
+ args += ['--base', base] if %w{Y y}.include?(ans)
358
+ elsif @pr_autostack
359
+ args += ['--base', base]
360
+ end
361
+ end
313
362
  SugarJar::Log.trace("Running: gh pr create #{args.join(' ')}")
314
- system(which('gh'), 'pr', 'create', '--fill', *args)
363
+ system(which('gh'), 'pr', 'create', *args)
315
364
  else
316
365
  SugarJar::Log.trace("Running: hub pull-request #{args.join(' ')}")
317
366
  system(which('hub'), 'pull-request', *args)
@@ -341,7 +390,7 @@ class SugarJar
341
390
 
342
391
  src = "origin/#{current_branch}"
343
392
  fetch('origin')
344
- diff = git('diff', src).stdout
393
+ diff = git('diff', "..#{src}").stdout
345
394
  return unless diff && !diff.empty?
346
395
 
347
396
  puts "Will merge the following suggestions:\n\n#{diff}"
@@ -369,6 +418,9 @@ class SugarJar
369
418
  def fprefix(name)
370
419
  return name unless @feature_prefix
371
420
 
421
+ return name if name.start_with?(@feature_prefix)
422
+ return name if all_local_branches.include?(name)
423
+
372
424
  newname = "#{@feature_prefix}#{name}"
373
425
  SugarJar::Log.debug(
374
426
  "Munging feature name: #{name} -> #{newname} due to feature prefix",
@@ -712,11 +764,15 @@ class SugarJar
712
764
  end
713
765
 
714
766
  def all_local_branches
715
- branches = []
716
- git('branch', '--format', '%(refname)').stdout.lines.each do |line|
717
- branches << branch_from_ref(line.strip)
767
+ git(
768
+ 'branch', '--format', '%(refname)'
769
+ ).stdout.lines.map do |line|
770
+ branch_from_ref(line.strip)
718
771
  end
719
- branches
772
+ end
773
+
774
+ def all_remotes
775
+ git('remote').stdout.lines.map(&:strip)
720
776
  end
721
777
 
722
778
  def safe_to_clean(branch)
@@ -794,14 +850,28 @@ class SugarJar
794
850
  SugarJar::Log.debug('Fetching upstream')
795
851
  fetch_upstream
796
852
  curr = current_branch
797
- base = tracked_branch
853
+ # this isn't a hash, it's a named param, silly rubocop
854
+ # rubocop:disable Style/HashSyntax
855
+ base = tracked_branch(fallback: false)
856
+ # rubocop:enable Style/HashSyntax
857
+ unless base
858
+ SugarJar::Log.info(
859
+ 'The brach we were tracking is gone, resetting tracking to ' +
860
+ most_main,
861
+ )
862
+ git('branch', '-u', most_main)
863
+ base = most_main
864
+ end
865
+ # If this is a subfeature based on a local branch which has since
866
+ # been deleted, 'tracked branch' will automatically return <most_main>
867
+ # so we don't need any special handling for that
798
868
  if !MAIN_BRANCHES.include?(curr) && base == "origin/#{curr}"
799
869
  SugarJar::Log.warn(
800
870
  "This branch is tracking origin/#{curr}, which is probably your " +
801
871
  'downstream (where you push _to_) as opposed to your upstream ' +
802
872
  '(where you pull _from_). This means that "sj up" is probably ' +
803
873
  'rebasing on the wrong thing and doing nothing. You probably want ' +
804
- 'to do a "git branch -u upstream".',
874
+ "to do a 'git branch -u #{most_main}'.",
805
875
  )
806
876
  end
807
877
  SugarJar::Log.debug('Rebasing')
@@ -812,6 +882,12 @@ class SugarJar
812
882
  }
813
883
  end
814
884
 
885
+ # determine if this branch is based on another local branch (i.e. is a
886
+ # subfeature). Used to figure out of we should stack the PR
887
+ def subfeature?(base)
888
+ all_local_branches.reject { |x| x == most_main }.include?(base)
889
+ end
890
+
815
891
  def rebase_in_progress?
816
892
  # for rebase without -i
817
893
  rebase_file = git('rev-parse', '--git-path', 'rebase-apply').stdout.strip
@@ -821,12 +897,13 @@ class SugarJar
821
897
  File.exist?(rebase_file) || File.exist?(rebase_merge_file)
822
898
  end
823
899
 
824
- def tracked_branch
900
+ def tracked_branch(fallback: true)
825
901
  s = git_nofail(
826
902
  'rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}'
827
903
  )
828
904
  if s.error?
829
- most_main
905
+ fallback ? most_main : nil
906
+
830
907
  else
831
908
  s.stdout.strip
832
909
  end
@@ -844,9 +921,7 @@ class SugarJar
844
921
  def upstream
845
922
  return @remote if @remote
846
923
 
847
- s = git('remote')
848
-
849
- remotes = s.stdout.lines.map(&:strip)
924
+ remotes = all_remotes
850
925
  SugarJar::Log.debug("remotes is #{remotes}")
851
926
  if remotes.empty?
852
927
  @remote = nil
@@ -9,6 +9,8 @@ class SugarJar
9
9
  'github_cli' => 'auto',
10
10
  'github_user' => ENV.fetch('USER'),
11
11
  'fallthru' => true,
12
+ 'pr_autofill' => true,
13
+ 'pr_autostack' => nil,
12
14
  }.freeze
13
15
 
14
16
  def self._find_ordered_files
@@ -1,3 +1,3 @@
1
1
  class SugarJar
2
- VERSION = '1.1.1'.freeze
2
+ VERSION = '1.1.2'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sugarjar
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Phil Dibowitz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-13 00:00:00.000000000 Z
11
+ date: 2024-04-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: deep_merge