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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4263a42ebb922645e2e0735c3ca33ad94df880fb01f881b2cacb602d733c533e
4
- data.tar.gz: 616fb99c535c491324c1dcc4906b37c8cb424566b62dc64377c61b9a5ef5fd49
3
+ metadata.gz: a9489ff071d470b3191dd934f1276cacdc8aeeec8b6cd9b892af1d49d01d04db
4
+ data.tar.gz: 24f37e088410ca5be03df9979aeb31e1996987e2d257767908235bc14903fc92
5
5
  SHA512:
6
- metadata.gz: 1d918daf7096d1889bf72ee0eca74ef473234ed1ed46e4275418028e9a32c9284b4412ff202a932a3cc43c777bbf55d1455ce8fd8805c965184e4d2bc740e527
7
- data.tar.gz: 0657a6629d97623d40f68d0ffe7a3e0522c951d9b22dc0c7b4b918d78eb27b026ab68d347b1c2fa68661536eceef9cbf3de3ee82b4ea4381da2675f1d34b3f2d
6
+ metadata.gz: d3c891c26d1e120f8957f396353f795d4531a212c2fd85e75626d01d27f9ecd8658743bf77fa9062e65c8f5be3f5b1a0dc4f678852dae55b5b4d1e86bf0e97a8
7
+ data.tar.gz: bf01b6eb19fe535bdc0752b722afd513f423d4ccbd04694faceb6d53e1575a5686fab1d6bdf29c8bd58590b8f4e714aefad3a4b09e67fd9fac22383fafddf4d4
data/README.md CHANGED
@@ -4,17 +4,8 @@
4
4
  [![Unittest](https://github.com/jaymzh/sugarjar/workflows/Unittests/badge.svg)](https://github.com/jaymzh/sugarjar/actions?query=workflow%3AUnittests)
5
5
  [![DCO](https://github.com/jaymzh/sugarjar/workflows/DCO%20Check/badge.svg)](https://github.com/jaymzh/sugarjar/actions?query=workflow%3A%22DCO+Check%22)
6
6
 
7
- > [!IMPORTANT]
8
- > As this was meant to replace arc/jf, which has now been open-sourced as
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. 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:
107
+ stacked branches can be confusing. SugarJar provides several tools to make this
108
+ easier.
129
109
 
130
- ```text
131
- +- test2.1
132
- /
133
- master --- test --- test2 --- test3
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
- This is what `binfo` on test3 looks like:
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 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
129
+ $ sj subfeature dependentnewthing
130
+ Created feature branch dependentnewthing based on mynewthing
144
131
  ```
145
132
 
146
- while `binfo` on test2.1 looks like:
133
+ If you create branches like this then sugarjar can now make several things
134
+ much easier:
147
135
 
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
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 `hub`, SugarJar supports GitHub Enterprise. In fact, we provide extra
429
+ Like `gh`, SugarJar supports GitHub Enterprise. In fact, we provide extra
367
430
  features just for it.
368
431
 
369
- We recommend the global or user config specify the `github_host`. However, most
370
- users will also have a few repos from upstream so always specifying a
371
- `github_host` is sub-optimal.
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, when you overwrite the `github_host` on the command line, we go ahead and
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
- In other words, assuming your global SJ config has `github_host:
378
- github.sample.com`, and the you clone sugarjar with:
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
- We will add the `hub.host` to the `sugarjar` clone so that future `hub` or `sj`
385
- commands work without needing to specify..
442
+ In your `~/.config/sugarjar/config.yaml`, but if the `.sugarjar.yaml` in your
443
+ repo has:
386
444
 
387
- ## Choosing a GitHub CLI
445
+ ```yaml
446
+ github_host: github.com
447
+ ```
388
448
 
389
- SugarJar will use `gh` if it is available or otherwise fall back to `hub`. You
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 = { 'color' => true }
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 commit ' +
97
- 'if there is a single commit and if we are using "gh". [default: true]',
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-]use-color', 'Enable color. [default: true]') do |color|
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 <<COMMANDS
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
- # as with above, this can't go into 'options', until after we parse
236
- # the command line args
237
- config = SugarJar::Config.config
238
-
239
- valid_commands = sj.public_methods - Object.public_methods
240
- possible_valid_command = ARGV.any? do |arg|
241
- valid_commands.include?(arg.to_s.to_sym)
242
- end
243
-
244
- # if we're configured to fall thru and the subcommand isn't one
245
- # we recognize, don't parse the options as they may be different
246
- # than git's. For example `git config -l` - we error because we
247
- # require an arguement to `-l`.
248
- if config['fallthru'] && !possible_valid_command
249
- SugarJar::Log.debug(
250
- 'Skipping option parsing: fall-thru is set and we do not recognize ' +
251
- 'any subcommands',
252
- )
253
- else
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
- 'We MIGHT have a valid command... parse-command line options',
240
+ "Continuing option parsing with remaining ARGV: #{argv_copy}",
256
241
  )
257
- # We want to allow people to pass in extra args to be passed to
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
- subcommand = argv_copy.reject { |x| x.start_with?('-') }.first
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
- options = config.merge(options)
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
- argv_copy.delete(subcommand)
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
- if subcommand == 'help'
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
- if is_valid_command
318
- SugarJar::Log.debug(
319
- "running #{subcommand}; extra opts: #{extra_opts.join(', ')}",
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)