sugarjar 0.0.7 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Lint](https://github.com/jaymzh/sugarjar/workflows/Lint/badge.svg)](https://github.com/jaymzh/sugarjar/actions?query=workflow%3ALint)
|
4
|
+
[![Unittest](https://github.com/jaymzh/sugarjar/workflows/Unittests/badge.svg)](https://github.com/jaymzh/sugarjar/actions?query=workflow%3AUnittests)
|
4
5
|
[![DCO](https://github.com/jaymzh/sugarjar/workflows/DCO%20Check/badge.svg)](https://github.com/jaymzh/sugarjar/actions?query=workflow%3A%22DCO+Check%22)
|
5
6
|
[![Gem Version](https://badge.fury.io/rb/sugarjar.svg)](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
|
+
![smartlog screenshot](https://github.com/jaymzh/sugarjar/blob/master/smartlog.png)
|
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: []
|