sugarjar 0.0.6 → 0.0.7
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 +9 -8
- data/bin/sj +19 -1
- data/lib/sugarjar/commands.rb +99 -24
- data/lib/sugarjar/config.rb +1 -1
- data/lib/sugarjar/util.rb +38 -15
- data/lib/sugarjar/version.rb +1 -1
- data/sugarjar.gemspec +1 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9fefe2bc9c94d95d3c869f8636bbabf433ec6196ae8d68b7ac131b4a955a882b
|
4
|
+
data.tar.gz: 5237f94836f686a0e82a8a18543b54179e7190ce874d481e59ae5fe685aa26d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d8ade9a12c3ba79a5ba591123179a80aeff6db7cbd4ab48c42cc27ecd5f5f4c3bcd713b99a04654b7c28e4fca715c3f6535f9938a97f3c55fc41169791f8d6a6
|
7
|
+
data.tar.gz: cbe9733235652a2ee5d777e53eed4a0f7deb9ffdcb69b0825b89c7831c52e5317e1e854b61e038d1a27fd92c85326e560c287e9e162d3068abcd246bc0e9ee48
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# SugarJar
|
2
2
|
|
3
|
-
](https://github.com/jaymzh/sugarjar/actions?query=workflow%3ALint)
|
4
|
+
[](https://github.com/jaymzh/sugarjar/actions?query=workflow%3A%22DCO+Check%22)
|
4
5
|
[](https://badge.fury.io/rb/sugarjar)
|
5
6
|
|
6
7
|
Welcome to SugarJar - a git/github helper. It leverages the amazing GitHub cli,
|
@@ -13,7 +14,7 @@ the Phabricator workflow this aims to bring to the GitHub workflow.
|
|
13
14
|
In particular there are a lot of helpers for using a squash-merge workflow that
|
14
15
|
is poorly handled by the standard toolsets.
|
15
16
|
|
16
|
-
If you miss Mondrian or
|
17
|
+
If you miss Mondrian or Phabricator - this is the tool for you!
|
17
18
|
|
18
19
|
If you don't, there's a ton of useful stuff for everyone!
|
19
20
|
|
@@ -21,7 +22,7 @@ If you don't, there's a ton of useful stuff for everyone!
|
|
21
22
|
|
22
23
|
It is common for a PR to go back and forth with a variety of nits, lint fixes,
|
23
24
|
typos, etc. that can muddy history. So many projects will "squash and merge"
|
24
|
-
when they accept a pull request.
|
25
|
+
when they accept a pull request. However, that means `git branch -d <branch>`
|
25
26
|
doesn't work. Git will tell you the branch isn't fully merged. You can, of
|
26
27
|
course `git branch -D <branch>`, but that does no safety checks at all, it
|
27
28
|
forces the deletion.
|
@@ -74,7 +75,7 @@ This will:
|
|
74
75
|
Note that it takes `hub`s short-names for repos. No need to specify a full URL,
|
75
76
|
just a $org/$repo.
|
76
77
|
|
77
|
-
Like `git clone`, `sj sclone` will accept an additional
|
78
|
+
Like `git clone`, `sj sclone` will accept an additional argument as the
|
78
79
|
destination directory to clone to. It will also pass any other unknown options
|
79
80
|
to `git clone` under the hood.
|
80
81
|
|
@@ -145,7 +146,7 @@ push if any of them fail.
|
|
145
146
|
## Better push defaults
|
146
147
|
|
147
148
|
In addition to running pre-push tests for you `smartpush` also picks smart
|
148
|
-
defaults for push. So if you `sj spush` with no
|
149
|
+
defaults for push. So if you `sj spush` with no arguments, it uses the
|
149
150
|
`origin` remote and the same branch name you're on as the remote branch.
|
150
151
|
|
151
152
|
## Cleaning up your own history
|
@@ -156,11 +157,11 @@ combination of rebases, amends and force pushes. We provide two commands here
|
|
156
157
|
to help.
|
157
158
|
|
158
159
|
The first is pretty straight forward and is basically just an alias: `sj
|
159
|
-
amend`. It will
|
160
|
+
amend`. It will amend whatever you want to the most recent commit (just an
|
160
161
|
alias for `git commit --amend`). It has a partner `qamend` (or `amendq` if you
|
161
162
|
prefer) that will do so without prompting to update your commit message.
|
162
163
|
|
163
|
-
So now you've rebased or amended, pushing becomes
|
164
|
+
So now you've rebased or amended, pushing becomes challenging. You can `git push
|
164
165
|
--force`, but everyone knows that's incredibly dangerous. Is there a better
|
165
166
|
way? There is! Git provides `git push --force-with-lease` - it checks to make
|
166
167
|
sure you're up-to-date with the remote before forcing the push. But man that
|
@@ -174,7 +175,7 @@ When you want to start a new feature, you want to start developing against
|
|
174
175
|
latest. That's why `sj feature` defaults to creating a branch against what we
|
175
176
|
call "most master". That is, `upstream/master` if it exists, otherwise
|
176
177
|
`origin/master` if that exists, otherwise `master`. You can pass in an
|
177
|
-
additional
|
178
|
+
additional argument to base it off of something else.
|
178
179
|
|
179
180
|
```shell
|
180
181
|
$ git branch
|
data/bin/sj
CHANGED
@@ -61,6 +61,20 @@ parser = OptionParser.new do |opts|
|
|
61
61
|
options['log_level'] = level
|
62
62
|
end
|
63
63
|
|
64
|
+
opts.on(
|
65
|
+
'--ignore-dirty',
|
66
|
+
'Tell command that check for a dirty repo to carry on anyway.',
|
67
|
+
) do
|
68
|
+
options['ignore_dirty'] = true
|
69
|
+
end
|
70
|
+
|
71
|
+
opts.on(
|
72
|
+
'--ignore-prerun-failure',
|
73
|
+
'Ignore preprun failure on *push commands.',
|
74
|
+
) do
|
75
|
+
options['ignore_prerun_failure'] = true
|
76
|
+
end
|
77
|
+
|
64
78
|
opts.on('--version') do
|
65
79
|
puts SugarJar::VERSION
|
66
80
|
exit
|
@@ -119,6 +133,10 @@ COMMANDS:
|
|
119
133
|
your account (if not already done) and then setup your remotes
|
120
134
|
so that "origin" is your fork and "upstream" is the upstream.
|
121
135
|
|
136
|
+
smartpullrequest, smartpr, spr
|
137
|
+
A smart wrapper to "hub pull-request" that checks if your repo
|
138
|
+
is dirty before creating the pull request.
|
139
|
+
|
122
140
|
smartpush, spush
|
123
141
|
A smart wrapper to "git push" that runs whatever is defined in
|
124
142
|
"on_push" in .sugarjar.yml, and only pushes if they succeed.
|
@@ -132,7 +150,7 @@ COMMANDS:
|
|
132
150
|
upall
|
133
151
|
Same as "up", but for all branches.
|
134
152
|
|
135
|
-
|
153
|
+
version
|
136
154
|
Print the version of sugarjar, and then run 'hub version'
|
137
155
|
to show the hub and git versions.
|
138
156
|
COMMANDS
|
data/lib/sugarjar/commands.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'mixlib/shellout'
|
2
|
+
|
1
3
|
require_relative 'util'
|
2
4
|
require_relative 'repoconfig'
|
3
5
|
require_relative 'log'
|
@@ -14,6 +16,8 @@ class SugarJar
|
|
14
16
|
SugarJar::Log.debug("Commands.initialize options: #{options}")
|
15
17
|
@ghuser = options['github_user']
|
16
18
|
@ghhost = options['github_host']
|
19
|
+
@ignore_dirty = options['ignore_dirty']
|
20
|
+
@ignore_prerun_failure = options['ignore_prerun_failure']
|
17
21
|
@repo_config = SugarJar::RepoConfig.config
|
18
22
|
return if options['no_change']
|
19
23
|
|
@@ -37,7 +41,10 @@ class SugarJar
|
|
37
41
|
name ||= current_branch
|
38
42
|
# rubocop:disable Style/GuardClause
|
39
43
|
unless clean_branch(name)
|
40
|
-
die(
|
44
|
+
die(
|
45
|
+
"Cannot clean #{name} - there are unmerged commits; use " +
|
46
|
+
"'git branch -D #{name}' to forcefully delete it.",
|
47
|
+
)
|
41
48
|
end
|
42
49
|
# rubocop:enable Style/GuardClause
|
43
50
|
end
|
@@ -51,7 +58,8 @@ class SugarJar
|
|
51
58
|
# rubocop:disable Style/Next
|
52
59
|
unless clean_branch(branch)
|
53
60
|
SugarJar::Log.info(
|
54
|
-
"Skipping branch #{branch} - there are unmerged commits"
|
61
|
+
"Skipping branch #{branch} - there are unmerged commits; use " +
|
62
|
+
"'git branch -D #{branch}' to forcefully delete it.",
|
55
63
|
)
|
56
64
|
end
|
57
65
|
# rubocop:enable Style/Next
|
@@ -139,7 +147,8 @@ class SugarJar
|
|
139
147
|
# Now that we have a repo, if we have a hub host set it.
|
140
148
|
set_hub_host if @ghhost
|
141
149
|
|
142
|
-
org =
|
150
|
+
org = extract_org(repo)
|
151
|
+
SugarJar::Log.debug("Comparing org #{org} to ghuser #{@ghuser}")
|
143
152
|
if org == @ghuser
|
144
153
|
puts 'Cloned forked or self-owned repo. Not creating "upstream".'
|
145
154
|
return
|
@@ -149,9 +158,10 @@ class SugarJar
|
|
149
158
|
if s.error?
|
150
159
|
# if the fork command failed, we already have one, so we have
|
151
160
|
# to swap the remote names ourselves
|
161
|
+
# newer 'hub's don't fail and do the right thing...
|
152
162
|
SugarJar::Log.info("Fork (#{@ghuser}/#{reponame}) detected.")
|
153
163
|
hub('remote', 'rename', 'origin', 'upstream')
|
154
|
-
hub('remote', 'add', 'origin', repo
|
164
|
+
hub('remote', 'add', 'origin', forked_path(repo, @ghuser))
|
155
165
|
else
|
156
166
|
SugarJar::Log.info("Forked #{reponame} to #{@ghuser}")
|
157
167
|
end
|
@@ -162,38 +172,25 @@ class SugarJar
|
|
162
172
|
alias sclone smartclone
|
163
173
|
|
164
174
|
def lint
|
175
|
+
assert_in_repo
|
165
176
|
exit(1) unless run_check('lint')
|
166
177
|
end
|
167
178
|
|
168
179
|
def unit
|
180
|
+
assert_in_repo
|
169
181
|
exit(1) unless run_check('unit')
|
170
182
|
end
|
171
183
|
|
172
184
|
def smartpush(remote = nil, branch = nil)
|
173
|
-
|
174
|
-
|
175
|
-
branch ||= current_branch
|
176
|
-
end
|
177
|
-
|
178
|
-
if run_prepush
|
179
|
-
puts hub('push', remote, branch).stderr
|
180
|
-
else
|
181
|
-
SugarJar::Log.error('Pre-push checks failed. Not pushing.')
|
182
|
-
end
|
185
|
+
assert_in_repo
|
186
|
+
_smartpush(remote, branch, false)
|
183
187
|
end
|
184
188
|
|
185
189
|
alias spush smartpush
|
186
190
|
|
187
191
|
def forcepush(remote = nil, branch = nil)
|
188
|
-
|
189
|
-
|
190
|
-
branch ||= current_branch
|
191
|
-
end
|
192
|
-
if run_prepush
|
193
|
-
puts hub('push', '--force-with-lease', remote, branch).stderr
|
194
|
-
else
|
195
|
-
SugarJar::Log.error('Pre-push checks failed. Not pushing.')
|
196
|
-
end
|
192
|
+
assert_in_repo
|
193
|
+
_smartpush(remote, branch, true)
|
197
194
|
end
|
198
195
|
|
199
196
|
alias fpush forcepush
|
@@ -203,8 +200,86 @@ class SugarJar
|
|
203
200
|
puts hub('version').stdout
|
204
201
|
end
|
205
202
|
|
203
|
+
def smartpullrequest
|
204
|
+
assert_in_repo
|
205
|
+
if dirty?
|
206
|
+
SugarJar::Log.warn(
|
207
|
+
'Your repo is dirty, so I am not going to create a pull request. ' +
|
208
|
+
'You should commit or amend and push it to your remote first.',
|
209
|
+
)
|
210
|
+
exit(1)
|
211
|
+
end
|
212
|
+
system(which('hub'), 'pull-request')
|
213
|
+
end
|
214
|
+
|
215
|
+
alias spr smartpullrequest
|
216
|
+
alias smartpr smartpullrequest
|
217
|
+
|
206
218
|
private
|
207
219
|
|
220
|
+
def _smartpush(remote, branch, force)
|
221
|
+
unless remote && branch
|
222
|
+
remote ||= 'origin'
|
223
|
+
branch ||= current_branch
|
224
|
+
end
|
225
|
+
|
226
|
+
if dirty?
|
227
|
+
if @ignore_dirty
|
228
|
+
SugarJar::Log.warn(
|
229
|
+
'Your repo is dirty, but --ignore-dirty was specified, so ' +
|
230
|
+
'carrying on anyway.',
|
231
|
+
)
|
232
|
+
else
|
233
|
+
SugarJar::Log.error(
|
234
|
+
'Your repo is dirty, so I am not going to push. Please commit ' +
|
235
|
+
'or amend first.',
|
236
|
+
)
|
237
|
+
exit(1)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
unless run_prepush
|
242
|
+
if @ignore_prerun_failure
|
243
|
+
SugarJar::Log.warn(
|
244
|
+
'Pre-push checks failed, but --ignore-prerun-failure was ' +
|
245
|
+
'specified, so carrying on anyway',
|
246
|
+
)
|
247
|
+
else
|
248
|
+
SugarJar::Log.error('Pre-push checks failed. Not pushing.')
|
249
|
+
exit(1)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
args = ['push', remote, branch]
|
254
|
+
args << '--force-with-lease' if force
|
255
|
+
puts hub(*args).stderr
|
256
|
+
end
|
257
|
+
|
258
|
+
def dirty?
|
259
|
+
s = hub_nofail('diff', '--quiet')
|
260
|
+
s.error?
|
261
|
+
end
|
262
|
+
|
263
|
+
def extract_org(path)
|
264
|
+
if path.start_with?('http')
|
265
|
+
File.basename(File.dirname(path))
|
266
|
+
elsif path.start_with?('git@')
|
267
|
+
path.split(':')[1].split('/')[0]
|
268
|
+
else
|
269
|
+
# assume they passed in a hub-friendly name
|
270
|
+
path.split('/').first
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
def forked_path(path, username)
|
275
|
+
repo = if path.start_with?('http', 'git@')
|
276
|
+
File.basename(path)
|
277
|
+
else
|
278
|
+
"#{File.basename(path)}.git"
|
279
|
+
end
|
280
|
+
"git@github.com:#{username}/#{repo}"
|
281
|
+
end
|
282
|
+
|
208
283
|
def set_hub_host
|
209
284
|
return unless in_repo
|
210
285
|
|
@@ -213,7 +288,7 @@ class SugarJar
|
|
213
288
|
SugarJar::Log.info("Setting repo hub.host = #{@ghhost}")
|
214
289
|
else
|
215
290
|
current = s.stdout
|
216
|
-
if current == @
|
291
|
+
if current == @ghhost
|
217
292
|
SugarJar::Log.debug('Repo hub.host already set correctly')
|
218
293
|
else
|
219
294
|
# Even though we have an explicit config, in most cases, it
|
data/lib/sugarjar/config.rb
CHANGED
data/lib/sugarjar/util.rb
CHANGED
@@ -29,23 +29,46 @@ class SugarJar
|
|
29
29
|
def hub_nofail(*args)
|
30
30
|
SugarJar::Log.trace("Running: hub #{args.join(' ')}")
|
31
31
|
s = Mixlib::ShellOut.new([which('hub')] + args).run_command
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
SugarJar::Log.fatal(
|
41
|
-
'That failed, I will bail out. Hub needs to get a github ' +
|
42
|
-
'token. Try running "hub api user" (will list info about ' +
|
43
|
-
'your account) and try this again when that works.',
|
32
|
+
if s.error?
|
33
|
+
# depending on hub version and possibly other things, STDERR
|
34
|
+
# is either "Requires authentication" or "Must authenticate"
|
35
|
+
case s.stderr
|
36
|
+
when /^(Must|Requires) authenticat/
|
37
|
+
SugarJar::Log.info(
|
38
|
+
'Hub was run but no github token exists. Will run "hub api user" ' +
|
39
|
+
"to force\nhub to authenticate...",
|
44
40
|
)
|
45
|
-
|
41
|
+
unless system(which('hub'), 'api', 'user')
|
42
|
+
SugarJar::Log.fatal(
|
43
|
+
'That failed, I will bail out. Hub needs to get a github ' +
|
44
|
+
'token. Try running "hub api user" (will list info about ' +
|
45
|
+
'your account) and try this again when that works.',
|
46
|
+
)
|
47
|
+
exit(1)
|
48
|
+
end
|
49
|
+
SugarJar::Log.info('Re-running original hub command...')
|
50
|
+
s = Mixlib::ShellOut.new([which('hub')] + args).run_command
|
51
|
+
when /^fatal: could not read Username/
|
52
|
+
# On http(s) URLs, git may prompt for username/passwd
|
53
|
+
SugarJar::Log.info(
|
54
|
+
'Hub was run but git prompted for authentication. This probably ' +
|
55
|
+
"means you have\nused an http repo URL instead of an ssh one. It " +
|
56
|
+
"is recommended you reclone\nusing 'sj sclone' to setup your " +
|
57
|
+
"remotes properly. However, in the meantime,\nwe'll go ahead " +
|
58
|
+
"and re-run the command in a shell so you can type in the\n" +
|
59
|
+
'credentials.',
|
60
|
+
)
|
61
|
+
unless system(which('hub'), *args)
|
62
|
+
SugarJar::Log.fatal(
|
63
|
+
'That failed, I will bail out. You can either manually change ' +
|
64
|
+
'your remotes, or simply create a fresh clone with ' +
|
65
|
+
'"sj smartclone".',
|
66
|
+
)
|
67
|
+
exit(1)
|
68
|
+
end
|
69
|
+
SugarJar::Log.info('Re-running original hub command...')
|
70
|
+
s = Mixlib::ShellOut.new([which('hub')] + args).run_command
|
46
71
|
end
|
47
|
-
SugarJar::Log.info('Re-running original hub command...')
|
48
|
-
s = Mixlib::ShellOut.new([which('hub')] + args).run_command
|
49
72
|
end
|
50
73
|
s
|
51
74
|
end
|
data/lib/sugarjar/version.rb
CHANGED
data/sugarjar.gemspec
CHANGED
@@ -8,6 +8,7 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.email = ['phil@ipom.com']
|
9
9
|
spec.license = 'Apache-2.0'
|
10
10
|
spec.homepage = 'https://github.com/jaymzh/sugarjar'
|
11
|
+
spec.required_ruby_version = '>= 2.6.0'
|
11
12
|
docs = %w{README.md LICENSE Gemfile sugarjar.gemspec}
|
12
13
|
spec.extra_rdoc_files = docs
|
13
14
|
spec.executables << 'sj'
|
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.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Phil Dibowitz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mixlib-log
|
@@ -73,7 +73,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
73
73
|
requirements:
|
74
74
|
- - ">="
|
75
75
|
- !ruby/object:Gem::Version
|
76
|
-
version:
|
76
|
+
version: 2.6.0
|
77
77
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
78
|
requirements:
|
79
79
|
- - ">="
|