sugarjar 0.0.7 → 0.0.10
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/LICENSE +1 -1
- data/README.md +29 -5
- data/bin/sj +26 -12
- data/lib/sugarjar/commands.rb +190 -71
- data/lib/sugarjar/util.rb +6 -1
- data/lib/sugarjar/version.rb +1 -1
- data/sugarjar.gemspec +4 -0
- metadata +23 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a1c65749738fac53cfb69c3ec42007433f7598e3e43dd36e33217c8c0efbbb2e
|
4
|
+
data.tar.gz: 50288abc1d21962e793731a937a8dd886bd2674db269ed62fbb0f89bb4121850
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 97ca2433bccc9e15d8c86ab141fa74e8f441f62cdb2be16e3131e2dcf71b37319ed0399990a96cb8c34ee4c55e75f1eca8a652cd5c7031f272493eec3fdb0f9a
|
7
|
+
data.tar.gz: 5395379c1ca16bc50c900cd75a4b72665c0079dfe48f8717d38640d4ba610cc571c5f407333e088c0c387f19dc620039e3a406f03d6d6ea4a72a7348b98e7a41
|
data/LICENSE
CHANGED
@@ -186,7 +186,7 @@
|
|
186
186
|
same "printed page" as the copyright notice for easier
|
187
187
|
identification within third-party archives.
|
188
188
|
|
189
|
-
Copyright
|
189
|
+
Copyright 2020-present Phil Dibowitz
|
190
190
|
|
191
191
|
Licensed under the Apache License, Version 2.0 (the "License");
|
192
192
|
you may not use this file except in compliance with the License.
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# SugarJar
|
2
2
|
|
3
3
|
[](https://github.com/jaymzh/sugarjar/actions?query=workflow%3ALint)
|
4
|
+
[](https://github.com/jaymzh/sugarjar/actions?query=workflow%3AUnittests)
|
4
5
|
[](https://github.com/jaymzh/sugarjar/actions?query=workflow%3A%22DCO+Check%22)
|
5
6
|
[](https://badge.fury.io/rb/sugarjar)
|
6
7
|
|
@@ -8,7 +9,7 @@ Welcome to SugarJar - a git/github helper. It leverages the amazing GitHub cli,
|
|
8
9
|
[hub](https://hub.github.com/), so you'll need that installed.
|
9
10
|
|
10
11
|
SugarJar is inspired by [arcanist](https://github.com/phacility/arcanist), and
|
11
|
-
|
12
|
+
its replacement at Facebook, JellyFish. Many of the features they provide for
|
12
13
|
the Phabricator workflow this aims to bring to the GitHub workflow.
|
13
14
|
|
14
15
|
In particular there are a lot of helpers for using a squash-merge workflow that
|
@@ -27,7 +28,7 @@ doesn't work. Git will tell you the branch isn't fully merged. You can, of
|
|
27
28
|
course `git branch -D <branch>`, but that does no safety checks at all, it
|
28
29
|
forces the deletion.
|
29
30
|
|
30
|
-
Enter `sj bclean` - it determines
|
31
|
+
Enter `sj bclean` - it determines if the contents of your branch has been merge
|
31
32
|
and safely deletes if so.
|
32
33
|
|
33
34
|
``` shell
|
@@ -119,7 +120,7 @@ small lint issue? Not anymore! SJ can be configured to run things before
|
|
119
120
|
pushing. For example,in the SugarJar repo, we have it run Rubocop (ruby lint)
|
120
121
|
and Markdownlint "on_push". If those fail, it lets you know and doesn't push.
|
121
122
|
|
122
|
-
You can configure SugarJar to tell
|
123
|
+
You can configure SugarJar to tell it how to run both lints and unittests for
|
123
124
|
a given repo and if one or both should be run prior to pushing.
|
124
125
|
|
125
126
|
The details on the config file format is below, but we provide three commands:
|
@@ -190,6 +191,13 @@ $ sj feature dependent-feature test-branch
|
|
190
191
|
Created feature branch dependent-feature based on test-branch
|
191
192
|
```
|
192
193
|
|
194
|
+
## Smartlog
|
195
|
+
|
196
|
+
Smartlog will show you a tree diagram of your branches! Simply run `sj
|
197
|
+
smartlog` or `sj sl` for short.
|
198
|
+
|
199
|
+

|
200
|
+
|
193
201
|
## And more!
|
194
202
|
|
195
203
|
See `sj help` for more commands!
|
@@ -236,8 +244,8 @@ yaml file is a straight key-value pair of options without their '--'. For
|
|
236
244
|
example:
|
237
245
|
|
238
246
|
```yaml
|
239
|
-
|
240
|
-
|
247
|
+
log_level: debug
|
248
|
+
github_user: jaymzh
|
241
249
|
```
|
242
250
|
|
243
251
|
In addition, the environment variable `SUGARJAR_DEBUG` can be defined to set
|
@@ -304,6 +312,22 @@ sj clone jaymzh/sugarjar --github-host githuh.com
|
|
304
312
|
We will add the `hub.host` to the `sugarjar` clone so that future `hub` or `sj`
|
305
313
|
commands work without needing to specify..
|
306
314
|
|
315
|
+
## Installing
|
316
|
+
|
317
|
+
There are many ways to install SugarJar. The easiest is to use one of the
|
318
|
+
packages we provide in the
|
319
|
+
[releases](https://github.com/jaymzh/sugarjar/releases) section. Currently we
|
320
|
+
provide packages for Fedora, CentOS, Debian, and Ubuntu, but if you want
|
321
|
+
others, file an Issue. Since these packages are
|
322
|
+
[omnibus](https://github.com/chef/omnibus) packages which means they are bundled
|
323
|
+
with all of their dependencies. This means these packages will likely work as-is
|
324
|
+
on later releases of these distros or any similar distros.
|
325
|
+
|
326
|
+
We also distribute SugarJar via [RubyGems](https://rubygems.org/gems/sugarjar/),
|
327
|
+
so you can install it as a gem either via system ruby or via rvm/rbenv.
|
328
|
+
|
329
|
+
Finally you can clone the git repo and run it from within the repo if you'd like.
|
330
|
+
|
307
331
|
## FAQ
|
308
332
|
|
309
333
|
Why the name SugarJar?
|
data/bin/sj
CHANGED
@@ -13,7 +13,7 @@ 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 = { 'color' => true }
|
17
17
|
# If ENV['SUGARJAR_DEBUG'] is set, it overrides the config file,
|
18
18
|
# but not the command line options, so set that one here. Also
|
19
19
|
# start the logger at that level, in case we are debugging option loading
|
@@ -53,14 +53,6 @@ parser = OptionParser.new do |opts|
|
|
53
53
|
exit
|
54
54
|
end
|
55
55
|
|
56
|
-
opts.on(
|
57
|
-
'--log-level LEVEL',
|
58
|
-
'Set logging level (fatal, error, warning, info, debug, trace). Default: ' +
|
59
|
-
'info',
|
60
|
-
) do |level|
|
61
|
-
options['log_level'] = level
|
62
|
-
end
|
63
|
-
|
64
56
|
opts.on(
|
65
57
|
'--ignore-dirty',
|
66
58
|
'Tell command that check for a dirty repo to carry on anyway.',
|
@@ -75,6 +67,18 @@ parser = OptionParser.new do |opts|
|
|
75
67
|
options['ignore_prerun_failure'] = true
|
76
68
|
end
|
77
69
|
|
70
|
+
opts.on(
|
71
|
+
'--log-level LEVEL',
|
72
|
+
'Set logging level (fatal, error, warning, info, debug, trace). Default: ' +
|
73
|
+
'info',
|
74
|
+
) do |level|
|
75
|
+
options['log_level'] = level
|
76
|
+
end
|
77
|
+
|
78
|
+
opts.on('--[no-]use-color', 'Enable color. [default: true]') do |color|
|
79
|
+
options['color'] = color
|
80
|
+
end
|
81
|
+
|
78
82
|
opts.on('--version') do
|
79
83
|
puts SugarJar::VERSION
|
80
84
|
exit
|
@@ -133,6 +137,11 @@ COMMANDS:
|
|
133
137
|
your account (if not already done) and then setup your remotes
|
134
138
|
so that "origin" is your fork and "upstream" is the upstream.
|
135
139
|
|
140
|
+
smartlog, sl
|
141
|
+
Inspired by Facebook's "sl" extension to Mercurial, this command
|
142
|
+
will show you a tree of all your local branches relative to your
|
143
|
+
upstream.
|
144
|
+
|
136
145
|
smartpullrequest, smartpr, spr
|
137
146
|
A smart wrapper to "hub pull-request" that checks if your repo
|
138
147
|
is dirty before creating the pull request.
|
@@ -173,19 +182,23 @@ extra_opts = []
|
|
173
182
|
config = SugarJar::Config.config
|
174
183
|
|
175
184
|
valid_commands = sj.public_methods - Object.public_methods
|
176
|
-
|
177
|
-
|
185
|
+
possible_valid_command = ARGV.any? do |arg|
|
186
|
+
valid_commands.include?(arg.to_s.to_sym)
|
187
|
+
end
|
178
188
|
|
179
189
|
# if we're configured to fall thru and the subcommand isn't one
|
180
190
|
# we recognize, don't parse the options as they may be different
|
181
191
|
# than git's. For example `git config -l` - we error because we
|
182
192
|
# require an arguement to `-l`.
|
183
|
-
if config['fallthru'] && !
|
193
|
+
if config['fallthru'] && !possible_valid_command
|
184
194
|
SugarJar::Log.debug(
|
185
195
|
'Skipping option parsing: fall-thru is set and we do not recognize ' +
|
186
196
|
'any subcommands',
|
187
197
|
)
|
188
198
|
else
|
199
|
+
SugarJar::Log.debug(
|
200
|
+
'We MIGHT have a valid command... parse-command line options',
|
201
|
+
)
|
189
202
|
# We want to allow people to pass in extra args to be passed to
|
190
203
|
# git commands, but OptionParser doesn't easily allow this. So we
|
191
204
|
# loop over it, catching exceptions.
|
@@ -231,6 +244,7 @@ SugarJar::Log.level = options['log_level'].to_sym if options['log_level']
|
|
231
244
|
sj = SugarJar::Commands.new(options)
|
232
245
|
|
233
246
|
subcommand = argv_copy.reject { |x| x.start_with?('-') }.first
|
247
|
+
is_valid_command = valid_commands.include?(subcommand.to_sym)
|
234
248
|
argv_copy.delete(subcommand)
|
235
249
|
SugarJar::Log.debug("subcommand is #{subcommand}")
|
236
250
|
|
data/lib/sugarjar/commands.rb
CHANGED
@@ -12,6 +12,8 @@ class SugarJar
|
|
12
12
|
class Commands
|
13
13
|
include SugarJar::Util
|
14
14
|
|
15
|
+
MAIN_BRANCHES = %w{master main}.freeze
|
16
|
+
|
15
17
|
def initialize(options)
|
16
18
|
SugarJar::Log.debug("Commands.initialize options: #{options}")
|
17
19
|
@ghuser = options['github_user']
|
@@ -19,6 +21,7 @@ class SugarJar
|
|
19
21
|
@ignore_dirty = options['ignore_dirty']
|
20
22
|
@ignore_prerun_failure = options['ignore_prerun_failure']
|
21
23
|
@repo_config = SugarJar::RepoConfig.config
|
24
|
+
@color = options['color']
|
22
25
|
return if options['no_change']
|
23
26
|
|
24
27
|
set_hub_host if @ghhost
|
@@ -29,58 +32,66 @@ class SugarJar
|
|
29
32
|
assert_in_repo
|
30
33
|
SugarJar::Log.debug("Feature: #{name}, #{base}")
|
31
34
|
die("#{name} already exists!") if all_branches.include?(name)
|
32
|
-
base ||=
|
35
|
+
base ||= most_main
|
33
36
|
base_pieces = base.split('/')
|
34
37
|
hub('fetch', base_pieces[0]) if base_pieces.length > 1
|
35
38
|
hub('checkout', '-b', name, base)
|
36
|
-
SugarJar::Log.info(
|
39
|
+
SugarJar::Log.info(
|
40
|
+
"Created feature branch #{color(name, :green)} based on " +
|
41
|
+
color(base, :green),
|
42
|
+
)
|
37
43
|
end
|
38
44
|
|
39
45
|
def bclean(name = nil)
|
40
46
|
assert_in_repo
|
41
47
|
name ||= current_branch
|
42
|
-
|
43
|
-
|
48
|
+
if clean_branch(name)
|
49
|
+
SugarJar::Log.info("#{name}: #{color('reaped', :green)}")
|
50
|
+
else
|
44
51
|
die(
|
45
|
-
"Cannot clean #{name}
|
46
|
-
"'git branch -D #{name}' to forcefully delete it.",
|
52
|
+
"#{color("Cannot clean #{name}", :red)}! there are unmerged " +
|
53
|
+
"commits; use 'git branch -D #{name}' to forcefully delete it.",
|
47
54
|
)
|
48
55
|
end
|
49
|
-
# rubocop:enable Style/GuardClause
|
50
56
|
end
|
51
57
|
|
52
58
|
def bcleanall
|
53
59
|
assert_in_repo
|
54
60
|
curr = current_branch
|
55
61
|
all_branches.each do |branch|
|
56
|
-
|
62
|
+
if MAIN_BRANCHES.include?(branch)
|
63
|
+
SugarJar::Log.debug("Skipping #{branch}")
|
64
|
+
next
|
65
|
+
end
|
57
66
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
67
|
+
if clean_branch(branch)
|
68
|
+
SugarJar::Log.info("#{branch}: #{color('reaped', :green)}")
|
69
|
+
else
|
70
|
+
SugarJar::Log.info("#{branch}: skipped")
|
71
|
+
SugarJar::Log.debug(
|
72
|
+
"There are unmerged commits; use 'git branch -D #{branch}' to " +
|
73
|
+
'forcefully delete it)',
|
63
74
|
)
|
64
75
|
end
|
65
|
-
# rubocop:enable Style/Next
|
66
76
|
end
|
67
77
|
|
68
|
-
# Return to the branch we were on, or
|
78
|
+
# Return to the branch we were on, or main
|
69
79
|
if all_branches.include?(curr)
|
70
80
|
hub('checkout', curr)
|
71
81
|
else
|
72
|
-
|
82
|
+
checkout_main_branch
|
73
83
|
end
|
74
84
|
end
|
75
85
|
|
76
86
|
def co(*args)
|
77
87
|
assert_in_repo
|
78
|
-
hub('checkout', *args)
|
88
|
+
s = hub('checkout', *args)
|
89
|
+
SugarJar::Log.info(s.stderr + s.stdout.chomp)
|
79
90
|
end
|
80
91
|
|
81
92
|
def br
|
82
93
|
assert_in_repo
|
83
|
-
|
94
|
+
SugarJar::Log.info(hub('branch', '-v').stdout.chomp)
|
84
95
|
end
|
85
96
|
|
86
97
|
def binfo
|
@@ -88,16 +99,38 @@ class SugarJar
|
|
88
99
|
SugarJar::Log.info(hub(
|
89
100
|
'log', '--graph', '--oneline', '--decorate', '--boundary',
|
90
101
|
"#{tracked_branch}.."
|
91
|
-
).stdout)
|
102
|
+
).stdout.chomp)
|
103
|
+
end
|
104
|
+
|
105
|
+
# binfo for all branches
|
106
|
+
def smartlog
|
107
|
+
assert_in_repo
|
108
|
+
SugarJar::Log.info(hub(
|
109
|
+
'log', '--graph', '--oneline', '--decorate', '--boundary',
|
110
|
+
'--branches', "#{most_main}.."
|
111
|
+
).stdout.chomp)
|
92
112
|
end
|
93
113
|
|
114
|
+
alias sl smartlog
|
115
|
+
|
94
116
|
def up
|
95
117
|
assert_in_repo
|
118
|
+
# get a copy of our current branch, if rebase fails, we won't
|
119
|
+
# be able to determine it without backing out
|
120
|
+
curr = current_branch
|
96
121
|
result = gitup
|
97
|
-
if result
|
98
|
-
|
122
|
+
if result['so'].error?
|
123
|
+
die(
|
124
|
+
"#{color(curr, :red)}: Failed to rebase on " +
|
125
|
+
"#{result['base']}. Leaving the repo as-is. You can get out of " +
|
126
|
+
'this with a `git rebase --abort`. Output from failed rebase is: ' +
|
127
|
+
"\nSTDOUT:\n#{result['so'].stdout.lines.map { |x| "\t#{x}" }.join}" +
|
128
|
+
"\nSTDERR:\n#{result['so'].stderr.lines.map { |x| "\t#{x}" }.join}",
|
129
|
+
)
|
99
130
|
else
|
100
|
-
|
131
|
+
SugarJar::Log.info(
|
132
|
+
"#{color(current_branch, :green)} rebased on #{result['base']}",
|
133
|
+
)
|
101
134
|
end
|
102
135
|
end
|
103
136
|
|
@@ -117,18 +150,21 @@ class SugarJar
|
|
117
150
|
def upall
|
118
151
|
assert_in_repo
|
119
152
|
all_branches.each do |branch|
|
120
|
-
next if branch
|
153
|
+
next if MAIN_BRANCHES.include?(branch)
|
121
154
|
|
122
155
|
hub('checkout', branch)
|
123
156
|
result = gitup
|
124
|
-
if result
|
125
|
-
SugarJar::Log.info("Rebased #{branch} on #{result}")
|
126
|
-
else
|
157
|
+
if result['so'].error?
|
127
158
|
SugarJar::Log.error(
|
128
|
-
"
|
129
|
-
'branch',
|
159
|
+
"#{color(branch, :red)} failed rebase. Reverting attempt and " +
|
160
|
+
'moving to next branch. Try `sj up` manually on that branch.',
|
130
161
|
)
|
131
162
|
hub('rebase', '--abort')
|
163
|
+
else
|
164
|
+
SugarJar::Log.info(
|
165
|
+
"#{color(branch, :green)} rebased on " +
|
166
|
+
color(result['base'], :green).to_s,
|
167
|
+
)
|
132
168
|
end
|
133
169
|
end
|
134
170
|
end
|
@@ -141,7 +177,7 @@ class SugarJar
|
|
141
177
|
reponame = File.basename(repo, '.git')
|
142
178
|
dir ||= reponame
|
143
179
|
SugarJar::Log.info("Cloning #{reponame}...")
|
144
|
-
hub('clone', repo, dir, *args)
|
180
|
+
hub('clone', canonicalize_repo(repo), dir, *args)
|
145
181
|
|
146
182
|
Dir.chdir dir do
|
147
183
|
# Now that we have a repo, if we have a hub host set it.
|
@@ -156,12 +192,26 @@ class SugarJar
|
|
156
192
|
|
157
193
|
s = hub_nofail('fork', '--remote-name=origin')
|
158
194
|
if s.error?
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
195
|
+
if s.stdout.include?('SAML enforcement')
|
196
|
+
SugarJar::Log.info(
|
197
|
+
'Forking the repo failed because the repo requires SAML ' +
|
198
|
+
"authentication. Full output:\n\n\t#{s.stdout}",
|
199
|
+
)
|
200
|
+
exit(1)
|
201
|
+
else
|
202
|
+
# In old versions of hub, it would fail if the upstream fork
|
203
|
+
# already existed. If we got an error, but didn't recognize
|
204
|
+
# that, we'll assume that's what happened and try to add the
|
205
|
+
# remote ourselves.
|
206
|
+
SugarJar::Log.info("Fork (#{@ghuser}/#{reponame}) detected.")
|
207
|
+
SugarJar::Log.debug(
|
208
|
+
'The above is a bit of a lie. "hub" failed to fork and it was ' +
|
209
|
+
'not a SAML error, so our best guess is that a fork exists ' +
|
210
|
+
'and so we will try to configure it.',
|
211
|
+
)
|
212
|
+
hub('remote', 'rename', 'origin', 'upstream')
|
213
|
+
hub('remote', 'add', 'origin', forked_repo(repo, @ghuser))
|
214
|
+
end
|
165
215
|
else
|
166
216
|
SugarJar::Log.info("Forked #{reponame} to #{@ghuser}")
|
167
217
|
end
|
@@ -260,24 +310,36 @@ class SugarJar
|
|
260
310
|
s.error?
|
261
311
|
end
|
262
312
|
|
263
|
-
def extract_org(
|
264
|
-
if
|
265
|
-
File.basename(File.dirname(
|
266
|
-
elsif
|
267
|
-
|
313
|
+
def extract_org(repo)
|
314
|
+
if repo.start_with?('http')
|
315
|
+
File.basename(File.dirname(repo))
|
316
|
+
elsif repo.start_with?('git@')
|
317
|
+
repo.split(':')[1].split('/')[0]
|
268
318
|
else
|
269
319
|
# assume they passed in a hub-friendly name
|
270
|
-
|
320
|
+
repo.split('/').first
|
271
321
|
end
|
272
322
|
end
|
273
323
|
|
274
|
-
def
|
275
|
-
repo = if
|
276
|
-
File.basename(
|
324
|
+
def forked_repo(repo, username)
|
325
|
+
repo = if repo.start_with?('http', 'git@')
|
326
|
+
File.basename(repo)
|
277
327
|
else
|
278
|
-
"#{File.basename(
|
328
|
+
"#{File.basename(repo)}.git"
|
279
329
|
end
|
280
|
-
"git@github.com:#{username}/#{repo}"
|
330
|
+
"git@#{@ghhost || 'github.com'}:#{username}/#{repo}"
|
331
|
+
end
|
332
|
+
|
333
|
+
# Hub will default to https, but we should always default to SSH
|
334
|
+
# unless otherwise specified since https will cause prompting.
|
335
|
+
def canonicalize_repo(repo)
|
336
|
+
# if they fully-qualified it, we're good
|
337
|
+
return repo if repo.start_with?('http', 'git@')
|
338
|
+
|
339
|
+
# otherwise, ti's a shortname
|
340
|
+
cr = "git@#{@ghhost || 'github.com'}:#{repo}.git"
|
341
|
+
SugarJar::Log.debug("canonicalized #{repo} to #{cr}")
|
342
|
+
cr
|
281
343
|
end
|
282
344
|
|
283
345
|
def set_hub_host
|
@@ -352,21 +414,55 @@ class SugarJar
|
|
352
414
|
end
|
353
415
|
Dir.chdir repo_root do
|
354
416
|
@repo_config[type].each do |check|
|
355
|
-
SugarJar::Log.
|
417
|
+
SugarJar::Log.debug("Running #{type} #{check}")
|
356
418
|
|
357
|
-
|
358
|
-
|
419
|
+
short = check.split.first
|
420
|
+
unless File.exist?(short)
|
421
|
+
SugarJar::Log.error("Configured #{type} #{short} does not exist!")
|
359
422
|
return false
|
360
423
|
end
|
361
424
|
s = Mixlib::ShellOut.new(check).run_command
|
362
|
-
next unless s.error?
|
363
425
|
|
426
|
+
# Linters auto-correct, lets handle that gracefully
|
427
|
+
if type == 'lint' && dirty?
|
428
|
+
SugarJar::Log.info(
|
429
|
+
"[#{type}] #{short}: #{color('Corrected', :yellow)}",
|
430
|
+
)
|
431
|
+
SugarJar::Log.warn(
|
432
|
+
"The linter modified the repo. Here's the diff:\n",
|
433
|
+
)
|
434
|
+
puts hub('diff').stdout
|
435
|
+
loop do
|
436
|
+
$stdout.print(
|
437
|
+
"\nWould you like to\n\t[q]uit and inspect\n\t[a]mend the " +
|
438
|
+
"changes to the current commit and re-run\n > ",
|
439
|
+
)
|
440
|
+
ans = $stdin.gets.strip
|
441
|
+
case ans
|
442
|
+
when /^q/
|
443
|
+
SugarJar::Log.info('Exiting at user request.')
|
444
|
+
exit(1)
|
445
|
+
when /^a/
|
446
|
+
qamend('-a')
|
447
|
+
# break here, if we get out of this loop we 'redo', assuming
|
448
|
+
# the user chose this option
|
449
|
+
break
|
450
|
+
end
|
451
|
+
end
|
452
|
+
redo
|
453
|
+
end
|
454
|
+
|
455
|
+
if s.error?
|
456
|
+
SugarJar::Log.info(
|
457
|
+
"[#{type}] #{short} #{color('failed', :red)}, output follows " +
|
458
|
+
"(see debug for more)\n#{s.stdout}",
|
459
|
+
)
|
460
|
+
SugarJar::Log.debug(s.format_for_exception)
|
461
|
+
return false
|
462
|
+
end
|
364
463
|
SugarJar::Log.info(
|
365
|
-
"#{type} #{
|
366
|
-
s.stdout.to_s,
|
464
|
+
"[#{type}] #{short}: #{color('OK', :green)}",
|
367
465
|
)
|
368
|
-
SugarJar::Log.debug(s.format_for_exception)
|
369
|
-
return false
|
370
466
|
end
|
371
467
|
end
|
372
468
|
end
|
@@ -375,7 +471,7 @@ class SugarJar
|
|
375
471
|
@repo_config['on_push']&.each do |item|
|
376
472
|
SugarJar::Log.debug("Running on_push check type #{item}")
|
377
473
|
unless send(:run_check, item)
|
378
|
-
SugarJar::Log.info("
|
474
|
+
SugarJar::Log.info("[prepush]: #{item} #{color('failed', :red)}.")
|
379
475
|
return false
|
380
476
|
end
|
381
477
|
end
|
@@ -391,25 +487,30 @@ class SugarJar
|
|
391
487
|
die('sugarjar must be run from inside a git repo') unless in_repo
|
392
488
|
end
|
393
489
|
|
490
|
+
def main_branch
|
491
|
+
@main_branch = all_branches.include?('main') ? 'main' : 'master'
|
492
|
+
end
|
493
|
+
|
494
|
+
def checkout_main_branch
|
495
|
+
hub('checkout', main_branch)
|
496
|
+
end
|
497
|
+
|
394
498
|
def clean_branch(name)
|
395
|
-
die(
|
499
|
+
die("Cannot remove #{name} branch") if MAIN_BRANCHES.include?(name)
|
396
500
|
SugarJar::Log.debug('Fetch relevant remote...')
|
397
501
|
fetch_upstream
|
398
502
|
return false unless safe_to_clean(name)
|
399
503
|
|
400
504
|
SugarJar::Log.debug('branch deemed safe to delete...')
|
401
|
-
|
505
|
+
checkout_main_branch
|
402
506
|
hub('branch', '-D', name)
|
403
507
|
gitup
|
404
|
-
SugarJar::Log.info("Reaped branch #{name}")
|
405
508
|
true
|
406
509
|
end
|
407
510
|
|
408
511
|
def all_branches
|
409
512
|
branches = []
|
410
513
|
hub('branch', '--format', '%(refname)').stdout.lines.each do |line|
|
411
|
-
next if line == 'master'
|
412
|
-
|
413
514
|
branches << line.strip.split('/')[2]
|
414
515
|
end
|
415
516
|
branches
|
@@ -433,7 +534,7 @@ class SugarJar
|
|
433
534
|
|
434
535
|
# if the "easy" check didn't work, it's probably because there
|
435
536
|
# was a squash-merge. To check for that we make our own squash
|
436
|
-
# merge to upstream/
|
537
|
+
# merge to upstream/main and see if that has any delta
|
437
538
|
|
438
539
|
# First we need a temp branch to work on
|
439
540
|
tmpbranch = "_sugar_jar.#{Process.pid}"
|
@@ -442,8 +543,8 @@ class SugarJar
|
|
442
543
|
s = hub_nofail('merge', '--squash', branch)
|
443
544
|
if s.error?
|
444
545
|
cleanup_tmp_branch(tmpbranch, branch)
|
445
|
-
SugarJar::Log.
|
446
|
-
'Failed to merge changes into current
|
546
|
+
SugarJar::Log.debug(
|
547
|
+
'Failed to merge changes into current main. This means we could ' +
|
447
548
|
'not figure out if this is merged or not. Check manually and use ' +
|
448
549
|
"'git branch -D #{branch}' if it is safe to do so.",
|
449
550
|
)
|
@@ -461,7 +562,7 @@ class SugarJar
|
|
461
562
|
true
|
462
563
|
else
|
463
564
|
SugarJar::Log.debug(
|
464
|
-
'After squash-merging, this branch is NOT fully merged to
|
565
|
+
'After squash-merging, this branch is NOT fully merged to main',
|
465
566
|
)
|
466
567
|
false
|
467
568
|
end
|
@@ -486,9 +587,8 @@ class SugarJar
|
|
486
587
|
SugarJar::Log.debug('Fetching upstream')
|
487
588
|
fetch_upstream
|
488
589
|
curr = current_branch
|
489
|
-
SugarJar::Log.debug('Rebasing')
|
490
590
|
base = tracked_branch
|
491
|
-
if curr
|
591
|
+
if !MAIN_BRANCHES.include?(curr) && base == "origin/#{curr}"
|
492
592
|
SugarJar::Log.warn(
|
493
593
|
"This branch is tracking origin/#{curr}, which is probably your " +
|
494
594
|
'downstream (where you push _to_) as opposed to your upstream ' +
|
@@ -497,8 +597,12 @@ class SugarJar
|
|
497
597
|
'to do a "git branch -u upstream".',
|
498
598
|
)
|
499
599
|
end
|
600
|
+
SugarJar::Log.debug('Rebasing')
|
500
601
|
s = hub_nofail('rebase', base)
|
501
|
-
|
602
|
+
{
|
603
|
+
'so' => s,
|
604
|
+
'base' => base,
|
605
|
+
}
|
502
606
|
end
|
503
607
|
|
504
608
|
def tracked_branch
|
@@ -506,18 +610,18 @@ class SugarJar
|
|
506
610
|
'rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}'
|
507
611
|
)
|
508
612
|
if s.error?
|
509
|
-
|
613
|
+
most_main
|
510
614
|
else
|
511
615
|
s.stdout.strip
|
512
616
|
end
|
513
617
|
end
|
514
618
|
|
515
|
-
def
|
619
|
+
def most_main
|
516
620
|
us = upstream
|
517
621
|
if us
|
518
|
-
"#{us}
|
622
|
+
"#{us}/#{main_branch}"
|
519
623
|
else
|
520
|
-
|
624
|
+
main_branch
|
521
625
|
end
|
522
626
|
end
|
523
627
|
|
@@ -541,5 +645,20 @@ class SugarJar
|
|
541
645
|
end
|
542
646
|
@remote
|
543
647
|
end
|
648
|
+
|
649
|
+
def color(string, *colors)
|
650
|
+
if @color
|
651
|
+
pastel.decorate(string, *colors)
|
652
|
+
else
|
653
|
+
string
|
654
|
+
end
|
655
|
+
end
|
656
|
+
|
657
|
+
def pastel
|
658
|
+
@pastel ||= begin
|
659
|
+
require 'pastel'
|
660
|
+
Pastel.new
|
661
|
+
end
|
662
|
+
end
|
544
663
|
end
|
545
664
|
end
|
data/lib/sugarjar/util.rb
CHANGED
@@ -27,6 +27,10 @@ class SugarJar
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def hub_nofail(*args)
|
30
|
+
if %w{diff log grep branch}.include?(args[0]) &&
|
31
|
+
args.none? { |x| x.include?('color') }
|
32
|
+
args << (@color ? '--color' : '--no-color')
|
33
|
+
end
|
30
34
|
SugarJar::Log.trace("Running: hub #{args.join(' ')}")
|
31
35
|
s = Mixlib::ShellOut.new([which('hub')] + args).run_command
|
32
36
|
if s.error?
|
@@ -48,7 +52,8 @@ class SugarJar
|
|
48
52
|
end
|
49
53
|
SugarJar::Log.info('Re-running original hub command...')
|
50
54
|
s = Mixlib::ShellOut.new([which('hub')] + args).run_command
|
51
|
-
when /^fatal: could not read Username/
|
55
|
+
when /^fatal: could not read Username/, /Anonymous access denied/
|
56
|
+
|
52
57
|
# On http(s) URLs, git may prompt for username/passwd
|
53
58
|
SugarJar::Log.info(
|
54
59
|
'Hub was run but git prompted for authentication. This probably ' +
|
data/lib/sugarjar/version.rb
CHANGED
data/sugarjar.gemspec
CHANGED
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: 0.0.
|
4
|
+
version: 0.0.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Phil Dibowitz
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-08-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mixlib-log
|
@@ -38,7 +38,21 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
-
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pastel
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description:
|
42
56
|
email:
|
43
57
|
- phil@ipom.com
|
44
58
|
executables:
|
@@ -64,8 +78,9 @@ files:
|
|
64
78
|
homepage: https://github.com/jaymzh/sugarjar
|
65
79
|
licenses:
|
66
80
|
- Apache-2.0
|
67
|
-
metadata:
|
68
|
-
|
81
|
+
metadata:
|
82
|
+
rubygems_mfa_required: 'true'
|
83
|
+
post_install_message:
|
69
84
|
rdoc_options: []
|
70
85
|
require_paths:
|
71
86
|
- lib
|
@@ -80,8 +95,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
95
|
- !ruby/object:Gem::Version
|
81
96
|
version: '0'
|
82
97
|
requirements: []
|
83
|
-
rubygems_version: 3.
|
84
|
-
signing_key:
|
98
|
+
rubygems_version: 3.3.15
|
99
|
+
signing_key:
|
85
100
|
specification_version: 4
|
86
101
|
summary: A git/github helper script
|
87
102
|
test_files: []
|