sugarjar 1.1.2 → 2.0.0.beta.1
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 +4 -4
- data/README.md +164 -104
- data/bin/sj +65 -111
- data/lib/sugarjar/commands.rb +19 -966
- data/lib/sugarjar/config.rb +22 -2
- data/lib/sugarjar/util.rb +298 -66
- data/lib/sugarjar/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a9489ff071d470b3191dd934f1276cacdc8aeeec8b6cd9b892af1d49d01d04db
|
4
|
+
data.tar.gz: 24f37e088410ca5be03df9979aeb31e1996987e2d257767908235bc14903fc92
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d3c891c26d1e120f8957f396353f795d4531a212c2fd85e75626d01d27f9ecd8658743bf77fa9062e65c8f5be3f5b1a0dc4f678852dae55b5b4d1e86bf0e97a8
|
7
|
+
data.tar.gz: bf01b6eb19fe535bdc0752b722afd513f423d4ccbd04694faceb6d53e1575a5686fab1d6bdf29c8bd58590b8f4e714aefad3a4b09e67fd9fac22383fafddf4d4
|
data/README.md
CHANGED
@@ -4,17 +4,8 @@
|
|
4
4
|
[](https://github.com/jaymzh/sugarjar/actions?query=workflow%3AUnittests)
|
5
5
|
[](https://github.com/jaymzh/sugarjar/actions?query=workflow%3A%22DCO+Check%22)
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
> [Sapling](https://sapling-scm.com/), I highly recommend taking a look at that!
|
10
|
-
>
|
11
|
-
> Sapling is a great tool and solves a variety of problems SugarJar will never
|
12
|
-
> be able to. However, it is a bigger workflow change, so existing SJ users
|
13
|
-
> may choose to stick with this. Similarly some workflows may not be suitable
|
14
|
-
> for Sapling. I still plan to maintain and develop SugarJar for the time being.
|
15
|
-
|
16
|
-
Welcome to SugarJar - a git/github helper. It needs one of the GitHub CLI's:
|
17
|
-
either [gh](https://cli.github.com/) or the older [hub](https://hub.github.com/).
|
7
|
+
Welcome to SugarJar - a git/github helper. The only requirements are Ruby,
|
8
|
+
`git`, and [gh](https://cli.github.com/).
|
18
9
|
|
19
10
|
SugarJar is inspired by [arcanist](https://github.com/phacility/arcanist), and
|
20
11
|
its replacement at Facebook, JellyFish. Many of the features they provide for
|
@@ -46,16 +37,6 @@ Ubuntu package maintainer.
|
|
46
37
|
|
47
38
|
For MacOS users, we recommend using Homebrew - SugarJar is now in Homebrew Core.
|
48
39
|
|
49
|
-
NOTE: If you previously used our custom Homebrew tap, you should remove and
|
50
|
-
untap it:
|
51
|
-
|
52
|
-
```shell
|
53
|
-
homebrew uninstall sugarjar
|
54
|
-
homebrew untap jaymzh/sugarjar
|
55
|
-
```
|
56
|
-
|
57
|
-
Then you can install the core version (`brew install sugarjar`).
|
58
|
-
|
59
40
|
Finally, if none of those work for you, you can clone this repo and run it
|
60
41
|
directly from there.
|
61
42
|
|
@@ -123,34 +104,142 @@ to `git clone` under the hood.
|
|
123
104
|
## Work with stacked branches more easily
|
124
105
|
|
125
106
|
It's important to break changes into reviewable chunks, but working with
|
126
|
-
stacked branches can be confusing.
|
127
|
-
|
128
|
-
branch structure like:
|
107
|
+
stacked branches can be confusing. SugarJar provides several tools to make this
|
108
|
+
easier.
|
129
109
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
110
|
+
First, and foremost, is `feature` and `subfeature`. Regardless of stacking, the
|
111
|
+
way to create a new feature bracnh with sugarjar is with `sj feature` (or `sj
|
112
|
+
f` for short):
|
113
|
+
|
114
|
+
```shell
|
115
|
+
$ sj feature mynewthing
|
116
|
+
Created feature branch mynewthing based on origin/main
|
134
117
|
```
|
135
118
|
|
136
|
-
|
119
|
+
A "feature" in SugarJar parliance just means that the branch is always created
|
120
|
+
from "most_main" - this is usually "upstream/main", but SJ will figure out
|
121
|
+
which remote is the "upstream", even if it's "origin", and then will determine
|
122
|
+
the primary branch ("main" or for older repos "master"). It's also smart enough
|
123
|
+
to fetch that remote first to make sure you're working on the latest HEAD.
|
124
|
+
|
125
|
+
When you want to create a stacked PR, you can create "subfeature", which, at
|
126
|
+
its core is just a branch created from the current branch:
|
137
127
|
|
138
128
|
```shell
|
139
|
-
$ sj
|
140
|
-
|
141
|
-
* e545b41 (test2) test2
|
142
|
-
* c808eae (test1) test1
|
143
|
-
o 44cf9e2 (origin/master, origin/HEAD, master) Lint/gemspec cleanups
|
129
|
+
$ sj subfeature dependentnewthing
|
130
|
+
Created feature branch dependentnewthing based on mynewthing
|
144
131
|
```
|
145
132
|
|
146
|
-
|
133
|
+
If you create branches like this then sugarjar can now make several things
|
134
|
+
much easier:
|
147
135
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
136
|
+
* `sj up` will rebase intelligently
|
137
|
+
* After an `sj bclean` of a branch earlier in the tree, `sj up` will update
|
138
|
+
the tracked branch to "most_main"
|
139
|
+
|
140
|
+
There are two commands that will show you the state of your stacked branches:
|
141
|
+
|
142
|
+
* `sj binfo` - shows the current branch and its ancestors up to your primary branch
|
143
|
+
* `sj smartlist` (aka `sj sl`) - shows you the whole tree.
|
144
|
+
|
145
|
+
To continue with the example above, my `smartlist` might look like:
|
146
|
+
|
147
|
+
```text
|
148
|
+
$ sj sl
|
149
|
+
* 59c0522 (HEAD -> dependentnewthing) anothertest
|
150
|
+
* 6ebaa28 (mynewthing) test
|
151
|
+
o 7a0ffd0 (tag: v1.1.2, origin/main, origin/HEAD, main) Version bump (#160)
|
152
|
+
```
|
153
|
+
|
154
|
+
This is simple. Now lets make a different feature stack:
|
155
|
+
|
156
|
+
```text
|
157
|
+
$ sj feature anotherfeature
|
158
|
+
Created feature branch anotherfeature based on origin/main
|
159
|
+
# do stuff
|
160
|
+
$ sj subfeature dependent2
|
161
|
+
Created feature branch dependent2 based on anotherfeature
|
162
|
+
# do stuff
|
163
|
+
```
|
164
|
+
|
165
|
+
The `smartlist` will now show us this tree, and it's a bit more interesting:
|
166
|
+
|
167
|
+
```text
|
168
|
+
$ sj sl
|
169
|
+
* af6f143 (HEAD -> dependent2) morestuff
|
170
|
+
* 028c7f4 (anotherfeature) stuff
|
171
|
+
| * 59c0522 (dependentnewthing) anothertest
|
172
|
+
| * 6ebaa28 (mynewthing) test
|
173
|
+
|/
|
174
|
+
o 7a0ffd0 (tag: v1.1.2, origin/main, origin/HEAD, main) Version bump (#160)
|
175
|
+
```
|
176
|
+
|
177
|
+
Now, what happens if I make a change to `mynewthing`?
|
178
|
+
|
179
|
+
```text
|
180
|
+
$ sj co mynewthing
|
181
|
+
Switched to branch 'mynewthing'
|
182
|
+
Your branch is ahead of 'origin/main' by 1 commit.
|
183
|
+
(use "git push" to publish your local commits)
|
184
|
+
$ echo 'randomchange' >> README.md
|
185
|
+
$ git commit -a -m change
|
186
|
+
[mynewthing d33e082] change
|
187
|
+
1 file changed, 1 insertion(+)
|
188
|
+
$ sj sl
|
189
|
+
* d33e082 (HEAD -> mynewthing) change
|
190
|
+
| * af6f143 (dependent2) morestuff
|
191
|
+
| * 028c7f4 (anotherfeature) stuff
|
192
|
+
| | * 59c0522 (dependentnewthing) anothertest
|
193
|
+
| |/
|
194
|
+
|/|
|
195
|
+
* | 6ebaa28 test
|
196
|
+
|/
|
197
|
+
o 7a0ffd0 (tag: v1.1.2, origin/main, origin/HEAD, main) Version bump (#160)
|
198
|
+
```
|
199
|
+
|
200
|
+
We can see here now that `dependentnewthing`, is based off a commit that _used_
|
201
|
+
to be `mynewthing`, but `mynewthing` has moved. But SugarJar will handle this
|
202
|
+
all correctly when we ask it to update the branch:
|
203
|
+
|
204
|
+
```text
|
205
|
+
$ sj co dependentnewthing
|
206
|
+
Switched to branch 'dependentnewthing'
|
207
|
+
Your branch and 'mynewthing' have diverged,
|
208
|
+
and have 1 and 1 different commits each, respectively.
|
209
|
+
(use "git pull" if you want to integrate the remote branch with yours)
|
210
|
+
$ sj up
|
211
|
+
dependentnewthing rebased on mynewthing
|
212
|
+
$ sj sl
|
213
|
+
* 93ed585 (HEAD -> dependentnewthing) anothertest
|
214
|
+
* d33e082 (mynewthing) change
|
215
|
+
* 6ebaa28 test
|
216
|
+
| * af6f143 (dependent2) morestuff
|
217
|
+
| * 028c7f4 (anotherfeature) stuff
|
218
|
+
|/
|
219
|
+
o 7a0ffd0 (tag: v1.1.2, origin/main, origin/HEAD, main) Version bump (#160)
|
220
|
+
```
|
221
|
+
|
222
|
+
Now, lets say that `mynewthing` gets merged and we use `bclean` to clean it all
|
223
|
+
up, what happens then?
|
224
|
+
|
225
|
+
```text
|
226
|
+
$ sj up
|
227
|
+
The brach we were tracking is gone, resetting tracking to origin/main
|
228
|
+
dependentnewthing rebased on origin/main
|
229
|
+
```
|
230
|
+
|
231
|
+
### Creating Stacked PRs with subfeatures
|
232
|
+
|
233
|
+
When dependent branches are created with `subfeature`, when you create a PR,
|
234
|
+
SugarJar will automatically set the 'base' of the PR to the parent branch. By
|
235
|
+
default it'll prompt you about this, but you can set `pr_autostack` to `true`
|
236
|
+
in your config to tell it to always do this (or `false` to never do this):
|
237
|
+
|
238
|
+
```text
|
239
|
+
$ sj spr
|
240
|
+
Autofilling in PR from commit message
|
241
|
+
It looks like this is a subfeature, would you like to base this PR on mynewthing? [y/n] y
|
242
|
+
...
|
154
243
|
```
|
155
244
|
|
156
245
|
## Have a better lint/unittest experience!
|
@@ -259,41 +348,6 @@ merge.
|
|
259
348
|
|
260
349
|
See `sj help` for more commands!
|
261
350
|
|
262
|
-
## Using SugarJar as a git wrapper
|
263
|
-
|
264
|
-
SugarJar, by default, will pass any command it doesn't know straight to `hub`
|
265
|
-
(which passes commands **it** doesn't know to `git`). If you have configured
|
266
|
-
SugarJar to use `gh` instead of `hub`, then it will pass commands straight to
|
267
|
-
`git` since `gh` doesn't act as a `git` wrapper.
|
268
|
-
|
269
|
-
As such you can alias it to `git` and just have a super-git.
|
270
|
-
|
271
|
-
```shell
|
272
|
-
$ alias git=sj
|
273
|
-
$ git config -l | grep color
|
274
|
-
color.diff=auto
|
275
|
-
color.status=auto
|
276
|
-
color.branch=auto
|
277
|
-
color.branch.current=yellow reverse
|
278
|
-
color.branch.local=yellow
|
279
|
-
color.branch.remote=green
|
280
|
-
$ git br
|
281
|
-
* dependent-feature 44cf9e2 Lint/gemspec cleanups
|
282
|
-
master 44cf9e2 Lint/gemspec cleanups
|
283
|
-
test-branch 44cf9e2 Lint/gemspec cleanups
|
284
|
-
test1 c808eae [ahead 1] test1
|
285
|
-
test2 e545b41 test2
|
286
|
-
test2.1 c1831b3 test2.1
|
287
|
-
test3 e451865 test3
|
288
|
-
```
|
289
|
-
|
290
|
-
It's for this reason that SugarJar doesn't have conflicting command names. You
|
291
|
-
can turn off fallthru by setting `fallthru: false` in your config.
|
292
|
-
|
293
|
-
The only command we "override" is `version`, in which case we not only print
|
294
|
-
our version, but also call `hub version` which prints its version and calls
|
295
|
-
`git version` too!
|
296
|
-
|
297
351
|
## Configuration
|
298
352
|
|
299
353
|
Sugarjar will read in both a system-level config file
|
@@ -312,6 +366,15 @@ In addition, the environment variable `SUGARJAR_LOGLEVEL` can be defined to set
|
|
312
366
|
a log level. This is primarily used as a way to turn debug on earlier in order to
|
313
367
|
troubleshoot configuration parsing.
|
314
368
|
|
369
|
+
Deprecated fields will cause a warning, but you can suppress that warning by
|
370
|
+
defining `ignore_deprecated_options`, for example:
|
371
|
+
|
372
|
+
```yaml
|
373
|
+
old_option: foo
|
374
|
+
ignore_deprecated_options:
|
375
|
+
- old_options
|
376
|
+
```
|
377
|
+
|
315
378
|
## Repository Configuration
|
316
379
|
|
317
380
|
Sugarjar looks for a `.sugarjar.yaml` in the root of the repository to tell it
|
@@ -363,33 +426,27 @@ prone, so this setting will automatically set this up for each developer.
|
|
363
426
|
|
364
427
|
## Enterprise GitHub
|
365
428
|
|
366
|
-
Like `
|
429
|
+
Like `gh`, SugarJar supports GitHub Enterprise. In fact, we provide extra
|
367
430
|
features just for it.
|
368
431
|
|
369
|
-
|
370
|
-
users will also have a few repos
|
371
|
-
|
432
|
+
You can set `github_host` in your global or user config, but since most
|
433
|
+
users will also have a few opensource repos, you can override it in the
|
434
|
+
Repository Config as well.
|
372
435
|
|
373
|
-
So,
|
374
|
-
set the `hub.host` git config in that single repo so that it'll "just work"
|
375
|
-
from there on out.
|
436
|
+
So, for example you might have:
|
376
437
|
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
```shell
|
381
|
-
sj clone jaymzh/sugarjar --github-host githuh.com
|
438
|
+
```yaml
|
439
|
+
github_host: gh.sample.com
|
382
440
|
```
|
383
441
|
|
384
|
-
|
385
|
-
|
442
|
+
In your `~/.config/sugarjar/config.yaml`, but if the `.sugarjar.yaml` in your
|
443
|
+
repo has:
|
386
444
|
|
387
|
-
|
445
|
+
```yaml
|
446
|
+
github_host: github.com
|
447
|
+
```
|
388
448
|
|
389
|
-
|
390
|
-
can override this by specifying `--github-cli` on the command line or setting
|
391
|
-
`github_cli` to either `gh` or `hub` (it defaults to `auto`) in your
|
392
|
-
configuration.
|
449
|
+
Then we will configure `gh` to talk to github.com when in that repo.
|
393
450
|
|
394
451
|
## FAQ
|
395
452
|
|
@@ -401,15 +458,6 @@ possible options that where there and not taken and tried to find one I could
|
|
401
458
|
make an appropriate name out of. Since this utility adds lots of sugar to git
|
402
459
|
and github, it seemed appropriate.
|
403
460
|
|
404
|
-
**Why did you originally use `hub` instead of the newer `gh` CLI?**
|
405
|
-
|
406
|
-
When I originally wrote SugarJar, `gh` was in early development, and `hub` had
|
407
|
-
many more features. In addition, I wrote SugarJar to be a wrapper for git/hub,
|
408
|
-
and `hub` allows this but `gh` does not.
|
409
|
-
|
410
|
-
When `gh` matured, we added experimental `gh` support in 0.0.11, and switched the
|
411
|
-
default to prefer `gh` in 1.0.0.
|
412
|
-
|
413
461
|
**I'd like to package SugarJar for my favorite distro/OS, is that OK?**
|
414
462
|
|
415
463
|
Of course! But I'd appreciate you emailing me to give me a heads up. Doing so
|
@@ -426,3 +474,15 @@ it on Windows, but I'll happily accept patches for Windows compatibility.
|
|
426
474
|
If the package for your OS/distro didn't set it up manually, you should find
|
427
475
|
that `sugarjar_completion.bash` is included in the package, and you can simply
|
428
476
|
source that in your dotfiles, assuming you are using bash.
|
477
|
+
|
478
|
+
**What happens now that Sapling is released?**
|
479
|
+
|
480
|
+
SugarJar isn't going anywhere anytime soon. This was meant to replace arc/jf,
|
481
|
+
which has now been open-sourced as [Sapling](https://sapling-scm.com/), so I
|
482
|
+
highly recommend taking a look at that!
|
483
|
+
|
484
|
+
Sapling is a great tool and solves a variety of problems SugarJar will never be
|
485
|
+
able to. However, it is a significant workflow change, that won't be
|
486
|
+
appropriate for all users or use-cases. Similarly there are workflows and tools
|
487
|
+
that Sapling breaks. So worry not, SugarJar will continue to be maintained and
|
488
|
+
developed
|
data/bin/sj
CHANGED
@@ -13,7 +13,8 @@ SugarJar::Log.level = Logger::INFO
|
|
13
13
|
|
14
14
|
# Don't put defaults here, put them in SugarJar::Config - otherwise
|
15
15
|
# these defaults overwrite whatever is in config files.
|
16
|
-
options = {
|
16
|
+
options = {}
|
17
|
+
|
17
18
|
# If ENV['SUGARJAR_DEBUG'] is set, it overrides the config file,
|
18
19
|
# but not the command line options, so set that one here. Also
|
19
20
|
# start the logger at that level, in case we are debugging option loading
|
@@ -21,6 +22,7 @@ options = { 'color' => true }
|
|
21
22
|
if ENV['SUGARJAR_LOGLEVEL']
|
22
23
|
options['log_level'] = SugarJar::Log.level = ENV['SUGARJAR_LOGLEVEL'].to_sym
|
23
24
|
end
|
25
|
+
|
24
26
|
parser = OptionParser.new do |opts|
|
25
27
|
opts.banner = 'Usage: sj <command> [<args>] [<options>]'
|
26
28
|
|
@@ -29,24 +31,10 @@ parser = OptionParser.new do |opts|
|
|
29
31
|
opts.separator ''
|
30
32
|
opts.separator 'OPTIONS:'
|
31
33
|
|
32
|
-
opts.on('--[no-]fallthru', 'Fall-thru to git. [default: true]') do |fallthru|
|
33
|
-
options['fallthru'] = fallthru
|
34
|
-
end
|
35
|
-
|
36
34
|
opts.on('--feature-prefix', 'Prefix to use for feature branches') do |prefix|
|
37
35
|
options['feature_prefix'] = prefix
|
38
36
|
end
|
39
37
|
|
40
|
-
opts.on(
|
41
|
-
'--github-cli CLI',
|
42
|
-
%w{gh cli},
|
43
|
-
'Github CLI to use ("gh" or "hub" or "auto"). Auto (the default) will ' +
|
44
|
-
'prefer "gh" if it is available but will fall back to "hub." ' +
|
45
|
-
'[default: "auto"]',
|
46
|
-
) do |cli|
|
47
|
-
options['github_cli'] = cli
|
48
|
-
end
|
49
|
-
|
50
38
|
opts.on(
|
51
39
|
'--github-host HOST',
|
52
40
|
'The host for "hub". Note that we will set this in the local repo ' +
|
@@ -93,8 +81,8 @@ parser = OptionParser.new do |opts|
|
|
93
81
|
|
94
82
|
opts.on(
|
95
83
|
'--[no-]pr-autofill',
|
96
|
-
'When creating a PR, auto fill the title & description from the
|
97
|
-
'
|
84
|
+
'When creating a PR, auto fill the title & description from the top ' +
|
85
|
+
'commit if we are using "gh". [default: true]',
|
98
86
|
) do |autofill|
|
99
87
|
options['pr_autofill'] = autofill
|
100
88
|
end
|
@@ -104,12 +92,12 @@ parser = OptionParser.new do |opts|
|
|
104
92
|
'When creating a PR, if this is a subfeature, should we make it a ' +
|
105
93
|
'PR on the PR for the parent feature. If not specified, we prompt ' +
|
106
94
|
'when this happens, when true always do this, when false never do ' +
|
107
|
-
'this. Only applicable when usiing "gh".',
|
95
|
+
'this. Only applicable when usiing "gh" and on branch-based PRs.',
|
108
96
|
) do |autostack|
|
109
97
|
options['pr_autostack'] = autostack
|
110
98
|
end
|
111
99
|
|
112
|
-
opts.on('--[no-]
|
100
|
+
opts.on('--[no-]color', 'Enable color. [default: true]') do |color|
|
113
101
|
options['color'] = color
|
114
102
|
end
|
115
103
|
|
@@ -119,7 +107,7 @@ parser = OptionParser.new do |opts|
|
|
119
107
|
end
|
120
108
|
|
121
109
|
# rubocop:disable Layout/HeredocIndentation
|
122
|
-
opts.separator <<
|
110
|
+
opts.separator <<COMMANDTEXT
|
123
111
|
|
124
112
|
COMMANDS:
|
125
113
|
amend
|
@@ -145,6 +133,10 @@ COMMANDS:
|
|
145
133
|
br
|
146
134
|
Verbose branch list. An alias for "git branch -v".
|
147
135
|
|
136
|
+
debuginfo
|
137
|
+
Prints out a bunch of version and config information useful for
|
138
|
+
including in bug reports.
|
139
|
+
|
148
140
|
feature, f <branch_name>
|
149
141
|
Create a "feature" branch. It's morally equivalent to
|
150
142
|
"git checkout -b" except it defaults to creating it based on
|
@@ -209,99 +201,66 @@ COMMANDS:
|
|
209
201
|
|
210
202
|
upall
|
211
203
|
Same as "up", but for all branches.
|
212
|
-
|
213
|
-
version
|
214
|
-
Print the version of sugarjar, and then run 'hub version'
|
215
|
-
to show the hub and git versions.
|
216
|
-
|
217
|
-
Be sure to checkout Sapling (https://sapling-scm.com/)! SugarJar was written as
|
218
|
-
a stop-gap to get Sapling features before it was open-sourced, and as such
|
219
|
-
Sapling may serve your needs even better.
|
220
|
-
COMMANDS
|
204
|
+
COMMANDTEXT
|
221
205
|
|
222
206
|
# rubocop:enable Layout/HeredocIndentation
|
223
207
|
end
|
224
208
|
|
225
|
-
# we make a copy of these because we will assign back to the ARGV
|
226
|
-
# we parse later. We also need a pristine copy in case we want to
|
227
|
-
# run git as we were called.
|
228
|
-
argv_copy = ARGV.dup
|
229
|
-
|
230
|
-
# We don't have options yet, but we need an instance of SJ in order
|
231
|
-
# to list public methods. We will recreate it
|
232
|
-
sj = SugarJar::Commands.new(options.merge({ 'no_change' => true }))
|
233
209
|
extra_opts = []
|
210
|
+
argv_copy = ARGV.dup
|
234
211
|
|
235
|
-
#
|
236
|
-
#
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
#
|
245
|
-
#
|
246
|
-
#
|
247
|
-
#
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
212
|
+
# We want to allow people to pass in extra args to be passed to commands (like
|
213
|
+
# `amend`), but OptionParser doesn't easily allow this. So we loop over it,
|
214
|
+
# catching exceptions.
|
215
|
+
|
216
|
+
begin
|
217
|
+
# HOWEVER, anytime it throws an exception, for some reason, it clears
|
218
|
+
# out all of ARGV, or whatever you passed to as ARGV.
|
219
|
+
#
|
220
|
+
# This not only prevents further parsing, but also means we lose
|
221
|
+
# any non-option arguements (like the subcommand!)
|
222
|
+
#
|
223
|
+
# So we save a copy, and if we throw an exception, save the option that
|
224
|
+
# caused it, remove that option from our copy, and then re-populate argv
|
225
|
+
# with what's left.
|
226
|
+
#
|
227
|
+
# By doing this we not only get to parse all the options properly and
|
228
|
+
# save unknown ones, but non-option arguements, which OptionParser
|
229
|
+
# normally leaves in ARGV stay in ARGV.
|
230
|
+
saved_argv = argv_copy.dup
|
231
|
+
parser.parse!(argv_copy)
|
232
|
+
rescue OptionParser::InvalidOption => e
|
233
|
+
SugarJar::Log.debug("Saving unknown argument #{e.args}")
|
234
|
+
extra_opts += e.args
|
235
|
+
|
236
|
+
# e.args is an array, but it's only ever one arguement per exception
|
237
|
+
saved_argv.delete(e.args.first)
|
238
|
+
argv_copy = saved_argv.dup
|
254
239
|
SugarJar::Log.debug(
|
255
|
-
|
240
|
+
"Continuing option parsing with remaining ARGV: #{argv_copy}",
|
256
241
|
)
|
257
|
-
|
258
|
-
# git commands, but OptionParser doesn't easily allow this. So we
|
259
|
-
# loop over it, catching exceptions.
|
260
|
-
begin
|
261
|
-
# HOWEVER, anytime it throws an exception, for some reason, it clears
|
262
|
-
# out all of ARGV, or whatever you passed to as ARGV.
|
263
|
-
#
|
264
|
-
# This not only prevents further parsing, but also means we lose
|
265
|
-
# any non-option arguements (like the subcommand!)
|
266
|
-
#
|
267
|
-
# So we save a copy, and if we throw an exception, save the option that
|
268
|
-
# caused it, remove that option from our copy, and then re-populate argv
|
269
|
-
# with what's left.
|
270
|
-
#
|
271
|
-
# By doing this we not only get to parse all the options properly and
|
272
|
-
# save unknown ones, but non-option arguements, which OptionParser
|
273
|
-
# normally leaves in ARGV stay in ARGV.
|
274
|
-
saved_argv = argv_copy.dup
|
275
|
-
parser.parse!(argv_copy)
|
276
|
-
rescue OptionParser::InvalidOption => e
|
277
|
-
SugarJar::Log.debug("Saving unknown argument #{e.args}")
|
278
|
-
extra_opts += e.args
|
279
|
-
|
280
|
-
# e.args is an array, but it's only ever one arguement per exception
|
281
|
-
saved_argv.delete(e.args.first)
|
282
|
-
argv_copy = saved_argv.dup
|
283
|
-
SugarJar::Log.debug(
|
284
|
-
"Continuing option parsing with remaining ARGV: #{argv_copy}",
|
285
|
-
)
|
286
|
-
retry
|
287
|
-
end
|
242
|
+
retry
|
288
243
|
end
|
289
244
|
|
290
|
-
|
245
|
+
options = SugarJar::Config.config.merge(options)
|
246
|
+
SugarJar::Log.level = options['log_level'].to_sym if options['log_level']
|
291
247
|
|
248
|
+
subcommand = argv_copy.reject { |x| x.start_with?('-') }.first
|
292
249
|
if ARGV.empty? || !subcommand
|
293
250
|
puts parser
|
294
251
|
exit
|
295
252
|
end
|
296
253
|
|
297
|
-
|
254
|
+
SugarJar::Log.debug("Final config: #{options}")
|
298
255
|
|
299
|
-
# Recreate SJ with all of our options
|
300
|
-
SugarJar::Log.level = options['log_level'].to_sym if options['log_level']
|
301
256
|
sj = SugarJar::Commands.new(options)
|
302
|
-
|
257
|
+
valid_commands = sj.public_methods - Object.public_methods
|
303
258
|
is_valid_command = valid_commands.include?(subcommand.to_sym)
|
304
|
-
|
259
|
+
# We can't do .delete(subcommand) because someone could, for example
|
260
|
+
# have a branch called 'co' and then do 'sj co co' - which will then
|
261
|
+
# remove _all_ instances of 'co'. So find the first instance and remove
|
262
|
+
# that.
|
263
|
+
argv_copy.delete_at(argv_copy.find_index(subcommand))
|
305
264
|
SugarJar::Log.debug("subcommand is #{subcommand}")
|
306
265
|
|
307
266
|
# Extra options we got, plus any left over arguements are what we
|
@@ -309,25 +268,20 @@ SugarJar::Log.debug("subcommand is #{subcommand}")
|
|
309
268
|
extra_opts += argv_copy
|
310
269
|
SugarJar::Log.debug("extra unknown options: #{extra_opts}")
|
311
270
|
|
312
|
-
|
271
|
+
case subcommand
|
272
|
+
when 'help'
|
313
273
|
puts parser
|
314
274
|
exit
|
275
|
+
when 'debuginfo'
|
276
|
+
extra_opts = [options]
|
315
277
|
end
|
316
278
|
|
317
|
-
|
318
|
-
SugarJar::Log.
|
319
|
-
|
320
|
-
)
|
321
|
-
sj.send(subcommand.to_sym, *extra_opts)
|
322
|
-
elsif options['fallthru']
|
323
|
-
SugarJar::Log.debug("Falling thru to: hub #{ARGV.join(' ')}")
|
324
|
-
if options['github_cli'] == 'hub'
|
325
|
-
exec('hub', *ARGV)
|
326
|
-
else
|
327
|
-
# If we're using 'gh', it doesn't have 'git fall thru' support, so
|
328
|
-
# we pass thru directly to 'git'
|
329
|
-
exec('git', *ARGV)
|
330
|
-
end
|
331
|
-
else
|
332
|
-
SugarJar::Log.error("No such subcommand: #{subcommand}")
|
279
|
+
unless is_valid_command
|
280
|
+
SugarJar::Log.fatal("No such subcommand: #{subcommand}")
|
281
|
+
exit 1
|
333
282
|
end
|
283
|
+
|
284
|
+
SugarJar::Log.debug(
|
285
|
+
"running #{subcommand}; extra opts: #{extra_opts.join(', ')}",
|
286
|
+
)
|
287
|
+
sj.send(subcommand.to_sym, *extra_opts)
|