sugarjar 1.1.2 → 1.1.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4263a42ebb922645e2e0735c3ca33ad94df880fb01f881b2cacb602d733c533e
4
- data.tar.gz: 616fb99c535c491324c1dcc4906b37c8cb424566b62dc64377c61b9a5ef5fd49
3
+ metadata.gz: c689945af0d2bfb7b38477d19da9f58503a15b7be931ab021c4a121a07e6198c
4
+ data.tar.gz: e5fb66f22db68dce1ef31199ea688ff768d753b5df65bc8479744c010d4072c3
5
5
  SHA512:
6
- metadata.gz: 1d918daf7096d1889bf72ee0eca74ef473234ed1ed46e4275418028e9a32c9284b4412ff202a932a3cc43c777bbf55d1455ce8fd8805c965184e4d2bc740e527
7
- data.tar.gz: 0657a6629d97623d40f68d0ffe7a3e0522c951d9b22dc0c7b4b918d78eb27b026ab68d347b1c2fa68661536eceef9cbf3de3ee82b4ea4381da2675f1d34b3f2d
6
+ metadata.gz: 9979e5aa13fd2a176cc5a391b9aef8353c1ddb7e63392ab6291f1781c3a99c39f9e4415a3c8cf02720ed2e0c6683a470978ba4ded3be9f2bb993120980a34863
7
+ data.tar.gz: 81ba9f2079a9cc6a88e9052092795c722f9a48bd6f9d763ddc33dddd48fbde65049a16dca2ca66ad39d2a33f179d175a712d22517e6e8103a5089a8d26d9592d
data/README.md CHANGED
@@ -123,34 +123,142 @@ to `git clone` under the hood.
123
123
  ## Work with stacked branches more easily
124
124
 
125
125
  It's important to break changes into reviewable chunks, but working with
126
- stacked branches can be confusing. Enter `binfo` - it gives you a view of your
127
- current branch all the way up to master. In this example imagine we have a
128
- branch structure like:
126
+ stacked branches can be confusing. SugarJar provides several tools to make this
127
+ easier.
129
128
 
130
- ```text
131
- +- test2.1
132
- /
133
- master --- test --- test2 --- test3
129
+ First, and foremost, is `feature` and `subfeature`. Regardless of stacking, the
130
+ way to create a new feature bracnh with sugarjar is with `sj feature` (or `sj
131
+ f` for short):
132
+
133
+ ```shell
134
+ $ sj feature mynewthing
135
+ Created feature branch mynewthing based on origin/main
134
136
  ```
135
137
 
136
- This is what `binfo` on test3 looks like:
138
+ A "feature" in SugarJar parliance just means that the branch is always created
139
+ from "most_main" - this is usually "upstream/main", but SJ will figure out
140
+ which remote is the "upstream", even if it's "origin", and then will determine
141
+ the primary branch ("main" or for older repos "master"). It's also smart enough
142
+ to fetch that remote first to make sure you're working on the latest HEAD.
143
+
144
+ When you want to create a stacked PR, you can create "subfeature", which, at
145
+ its core is just a branch created from the current branch:
137
146
 
138
147
  ```shell
139
- $ sj binfo
140
- * e451865 (HEAD -> test3) test3
141
- * e545b41 (test2) test2
142
- * c808eae (test1) test1
143
- o 44cf9e2 (origin/master, origin/HEAD, master) Lint/gemspec cleanups
148
+ $ sj subfeature dependentnewthing
149
+ Created feature branch dependentnewthing based on mynewthing
144
150
  ```
145
151
 
146
- while `binfo` on test2.1 looks like:
152
+ If you create branches like this then sugarjar can now make several things
153
+ much easier:
147
154
 
148
- ```shell
149
- $ sj binfo
150
- * 36d0136 (HEAD -> test2.1) test2.1
151
- * e545b41 (test2) test2
152
- * c808eae (test1) test1
153
- o 44cf9e2 (origin/master, origin/HEAD, master) Lint/gemspec cleanups
155
+ * `sj up` will rebase intelligently
156
+ * After an `sj bclean` of a branch earlier in the tree, `sj up` will update
157
+ the tracked branch to "most_main"
158
+
159
+ There are two commands that will show you the state of your stacked branches:
160
+
161
+ * `sj binfo` - shows the current branch and its ancestors up to your primary branch
162
+ * `sj smartlist` (aka `sj sl`) - shows you the whole tree.
163
+
164
+ To continue with the example above, my `smartlist` might look like:
165
+
166
+ ```text
167
+ $ sj sl
168
+ * 59c0522 (HEAD -> dependentnewthing) anothertest
169
+ * 6ebaa28 (mynewthing) test
170
+ o 7a0ffd0 (tag: v1.1.2, origin/main, origin/HEAD, main) Version bump (#160)
171
+ ```
172
+
173
+ This is simple. Now lets make a different feature stack:
174
+
175
+ ```text
176
+ $ sj feature anotherfeature
177
+ Created feature branch anotherfeature based on origin/main
178
+ # do stuff
179
+ $ sj subfeature dependent2
180
+ Created feature branch dependent2 based on anotherfeature
181
+ # do stuff
182
+ ```
183
+
184
+ The `smartlist` will now show us this tree, and it's a bit more interesting:
185
+
186
+ ```text
187
+ $ sj sl
188
+ * af6f143 (HEAD -> dependent2) morestuff
189
+ * 028c7f4 (anotherfeature) stuff
190
+ | * 59c0522 (dependentnewthing) anothertest
191
+ | * 6ebaa28 (mynewthing) test
192
+ |/
193
+ o 7a0ffd0 (tag: v1.1.2, origin/main, origin/HEAD, main) Version bump (#160)
194
+ ```
195
+
196
+ Now, what happens if I make a change to `mynewthing`?
197
+
198
+ ```text
199
+ $ sj co mynewthing
200
+ Switched to branch 'mynewthing'
201
+ Your branch is ahead of 'origin/main' by 1 commit.
202
+ (use "git push" to publish your local commits)
203
+ $ echo 'randomchange' >> README.md
204
+ $ git commit -a -m change
205
+ [mynewthing d33e082] change
206
+ 1 file changed, 1 insertion(+)
207
+ $ sj sl
208
+ * d33e082 (HEAD -> mynewthing) change
209
+ | * af6f143 (dependent2) morestuff
210
+ | * 028c7f4 (anotherfeature) stuff
211
+ | | * 59c0522 (dependentnewthing) anothertest
212
+ | |/
213
+ |/|
214
+ * | 6ebaa28 test
215
+ |/
216
+ o 7a0ffd0 (tag: v1.1.2, origin/main, origin/HEAD, main) Version bump (#160)
217
+ ```
218
+
219
+ We can see here now that `dependentnewthing`, is based off a commit that _used_
220
+ to be `mynewthing`, but `mynewthing` has moved. But SugarJar will handle this
221
+ all correctly when we ask it to update the branch:
222
+
223
+ ```text
224
+ $ sj co dependentnewthing
225
+ Switched to branch 'dependentnewthing'
226
+ Your branch and 'mynewthing' have diverged,
227
+ and have 1 and 1 different commits each, respectively.
228
+ (use "git pull" if you want to integrate the remote branch with yours)
229
+ $ sj up
230
+ dependentnewthing rebased on mynewthing
231
+ $ sj sl
232
+ * 93ed585 (HEAD -> dependentnewthing) anothertest
233
+ * d33e082 (mynewthing) change
234
+ * 6ebaa28 test
235
+ | * af6f143 (dependent2) morestuff
236
+ | * 028c7f4 (anotherfeature) stuff
237
+ |/
238
+ o 7a0ffd0 (tag: v1.1.2, origin/main, origin/HEAD, main) Version bump (#160)
239
+ ```
240
+
241
+ Now, lets say that `mynewthing` gets merged and we use `bclean` to clean it all
242
+ up, what happens then?
243
+
244
+ ```text
245
+ $ sj up
246
+ The brach we were tracking is gone, resetting tracking to origin/main
247
+ dependentnewthing rebased on origin/main
248
+ ```
249
+
250
+ ### Creating Stacked PRs with subfeatures
251
+
252
+ When dependent branches are created with `subfeature`, when you create a PR,
253
+ SugarJar will automatically set the 'base' of the PR to the parent branch. By
254
+ default it'll prompt you about this, but you can set `pr_autostack` to `true`
255
+ in your config to tell it to always do this (or `false` to never do this):
256
+
257
+ ```text
258
+ $ sj spr
259
+ Autofilling in PR from commit message
260
+ It looks like this is a subfeature, would you like to base this PR on mynewthing? [y/n] y
261
+ ...
154
262
  ```
155
263
 
156
264
  ## Have a better lint/unittest experience!
data/bin/sj CHANGED
@@ -93,8 +93,8 @@ parser = OptionParser.new do |opts|
93
93
 
94
94
  opts.on(
95
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]',
96
+ 'When creating a PR, auto fill the title & description from the top ' +
97
+ 'commit if we are using "gh". [default: true]',
98
98
  ) do |autofill|
99
99
  options['pr_autofill'] = autofill
100
100
  end
@@ -104,7 +104,7 @@ parser = OptionParser.new do |opts|
104
104
  'When creating a PR, if this is a subfeature, should we make it a ' +
105
105
  'PR on the PR for the parent feature. If not specified, we prompt ' +
106
106
  'when this happens, when true always do this, when false never do ' +
107
- 'this. Only applicable when usiing "gh".',
107
+ 'this. Only applicable when usiing "gh" and on branch-based PRs.',
108
108
  ) do |autostack|
109
109
  options['pr_autostack'] = autostack
110
110
  end
@@ -334,31 +334,40 @@ class SugarJar
334
334
  curr = current_branch
335
335
  base = tracked_branch
336
336
  if @pr_autofill
337
+ SugarJar::Log.info('Autofilling in PR from commit message')
337
338
  num_commits = git(
338
339
  'rev-list', '--count', curr, "^#{base}"
339
340
  ).stdout.strip.to_i
340
341
  if num_commits > 1
341
- SugarJar::Log.debug(
342
- "Not using --fill because there are #{num_commits} commits",
343
- )
342
+ args.unshift('--fill-first')
344
343
  else
345
- SugarJar::Log.info('Autofilling in PR from commit message')
346
344
  args.unshift('--fill')
347
345
  end
348
346
  end
349
347
  if subfeature?(base)
348
+ if upstream != push_org
349
+ SugarJar::Log.warn(
350
+ 'Unfortunately you cannot based one PR on another PR when' +
351
+ " using fork-based PRs. We will base this on #{most_main}." +
352
+ ' This just means the PR "Changes" tab will show changes for' +
353
+ ' the full stack until those other PRs are merged and this PR' +
354
+ ' PR is rebased.',
355
+ )
350
356
  # nil is prompt, true is always, false is never
351
- if @pr_autostack.nil?
357
+ elsif @pr_autostack.nil?
352
358
  $stdout.print(
353
359
  'It looks like this is a subfeature, would you like to base ' +
354
360
  "this PR on #{base}? [y/n] ",
355
361
  )
356
362
  ans = $stdin.gets.strip
357
- args += ['--base', base] if %w{Y y}.include?(ans)
363
+ args.unshift('--base', base) if %w{Y y}.include?(ans)
358
364
  elsif @pr_autostack
359
- args += ['--base', base]
365
+ args.unshift('--base', base)
360
366
  end
361
367
  end
368
+ # <org>:<branch> is the GH API syntax for:
369
+ # look for a branch of name <branch>, from a fork in owner <org>
370
+ args.unshift('--head', "#{push_org}:#{curr}")
362
371
  SugarJar::Log.trace("Running: gh pr create #{args.join(' ')}")
363
372
  system(which('gh'), 'pr', 'create', *args)
364
373
  else
@@ -482,6 +491,10 @@ class SugarJar
482
491
  end
483
492
  end
484
493
 
494
+ def extract_repo(repo)
495
+ File.basename(repo, '.git')
496
+ end
497
+
485
498
  def forked_repo(repo, username)
486
499
  repo = if repo.start_with?('http', 'git@')
487
500
  File.basename(repo)
@@ -898,15 +911,21 @@ class SugarJar
898
911
  end
899
912
 
900
913
  def tracked_branch(fallback: true)
914
+ branch = nil
901
915
  s = git_nofail(
902
916
  'rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}'
903
917
  )
904
918
  if s.error?
905
- fallback ? most_main : nil
906
-
919
+ branch = fallback ? most_main : nil
920
+ SugarJar::Log.debug("No specific tracked branch, using #{branch}")
907
921
  else
908
- s.stdout.strip
922
+ branch = s.stdout.strip
923
+ SugarJar::Log.debug(
924
+ "Using explicit tracked branch: #{branch}, use " +
925
+ '`git branch -u` to change',
926
+ )
909
927
  end
928
+ branch
910
929
  end
911
930
 
912
931
  def most_main
@@ -937,6 +956,12 @@ class SugarJar
937
956
  @remote
938
957
  end
939
958
 
959
+ # Whatever org we push to, regardless of if this is a fork or not
960
+ def push_org
961
+ url = git('remote', 'get-url', 'origin').stdout.strip
962
+ extract_org(url)
963
+ end
964
+
940
965
  def branch_from_ref(ref, type = :local)
941
966
  # local branches are refs/head/XXXX
942
967
  # remote branches are refs/remotes/<remote>/XXXX
@@ -1,3 +1,3 @@
1
1
  class SugarJar
2
- VERSION = '1.1.2'.freeze
2
+ VERSION = '1.1.3'.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.2
4
+ version: 1.1.3
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-04-26 00:00:00.000000000 Z
11
+ date: 2025-02-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: deep_merge