sugarjar 3.0.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +5 -1
- data/bin/sj +46 -5
- data/lib/sugarjar/commands/smartclone.rb +23 -10
- data/lib/sugarjar/commands/smartpullrequest.rb +4 -2
- data/lib/sugarjar/commands.rb +20 -31
- data/lib/sugarjar/config.rb +1 -0
- data/lib/sugarjar/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a412f3091d9ce81db841098d46c0b74f5ccf210e7f62916db5f36f68d4f9218f
|
|
4
|
+
data.tar.gz: db6f60757390c2e8decf11cada9a423f4d61284304e9db43ef4785636f621fd3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 550d6c2792dd3b800f8fcbb3ab0d34019ba59ae09596988fc31c92452270d220c6e0a8feead9f767750f2fb529f2e0c60421a8e5756bb5c80974a7329142404b
|
|
7
|
+
data.tar.gz: b723f16e4a2640777ebc8496afa635ff146f0a5de8e0359213aa0824e43b236a312fd199c5ddea047ff5acba604848e48ea94d9716a80ff4d280210b6dc32c83
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# SugarJar Changelog
|
|
2
2
|
|
|
3
|
+
## 3.0.1 (2026-06-19)
|
|
4
|
+
|
|
5
|
+
* Update tests for more resiliency in various package-building environments
|
|
6
|
+
* Better fallbacks for forge type
|
|
7
|
+
* Add config option to disable fork-based flows
|
|
8
|
+
* Fix false-positive for "primary branch doesn't match" error
|
|
9
|
+
* gitlab: Handle 3-level repos better
|
|
10
|
+
* gitlab: Fix `smartpullrequest` issues
|
|
11
|
+
* gitlab: significant improvement to `smartclone`
|
|
12
|
+
* Add `--fork-name` option to enable forking to a different repo name
|
|
13
|
+
|
|
3
14
|
## 3.0.0 (2026-06-08)
|
|
4
15
|
|
|
5
16
|
* Add support for GitLab
|
data/README.md
CHANGED
|
@@ -115,7 +115,8 @@ https://github.com/jaymzh/sugarjar/blob/main/images/sclone.png
|
|
|
115
115
|
|
|
116
116
|
This will:
|
|
117
117
|
|
|
118
|
-
* Fork the repo to your personal org (if you don't already have a fork
|
|
118
|
+
* Fork the repo to your personal org (if you don't already have a fork,
|
|
119
|
+
and if it's not already in your personal org)
|
|
119
120
|
* Clone your fork
|
|
120
121
|
* Add the original as an 'upstream' remote
|
|
121
122
|
|
|
@@ -126,6 +127,9 @@ Like `git clone`, `sj smartclone` will accept an additional argument as the
|
|
|
126
127
|
destination directory to clone to. It will also pass any other unknown options
|
|
127
128
|
to `git clone` under the hood.
|
|
128
129
|
|
|
130
|
+
If you don't work with fork-based workflows, you can set `use_forks: false`
|
|
131
|
+
in your config, or pass in `--no-use-forks` to `sj sclone`.
|
|
132
|
+
|
|
129
133
|
### Work with stacked branches more easily
|
|
130
134
|
|
|
131
135
|
It's important to break changes into reviewable chunks, but working with
|
data/bin/sj
CHANGED
|
@@ -103,6 +103,22 @@ parser = OptionParser.new do |opts|
|
|
|
103
103
|
options['pr_autofill'] = autofill
|
|
104
104
|
end
|
|
105
105
|
|
|
106
|
+
opts.on(
|
|
107
|
+
'--[no-]use-forks',
|
|
108
|
+
'Create (add a remote for) forks, when the organization does not match ' +
|
|
109
|
+
'the user. [default: true]',
|
|
110
|
+
) do |val|
|
|
111
|
+
options['use_forks'] = val
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
opts.on(
|
|
115
|
+
'--fork-name NAME',
|
|
116
|
+
'When forking a repo (in `smartclone`), fork the repo to a different ' +
|
|
117
|
+
'name. See the help for `smartclone` below.',
|
|
118
|
+
) do |val|
|
|
119
|
+
options['fork_name'] = val
|
|
120
|
+
end
|
|
121
|
+
|
|
106
122
|
opts.on(
|
|
107
123
|
'--[no-]pr-autostack',
|
|
108
124
|
'When creating a PR, if this is a subfeature, should we make it a ' +
|
|
@@ -224,15 +240,40 @@ COMMANDS:
|
|
|
224
240
|
Walk all remote branches, and try to delete them if it's safe. See
|
|
225
241
|
"rbclean" for details.
|
|
226
242
|
|
|
227
|
-
smartclone, sclone
|
|
243
|
+
smartclone, sclone <repo> [<dir>]
|
|
228
244
|
A smart wrapper to "git clone" that handles forking and managing
|
|
229
245
|
remotes for you.
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
246
|
+
|
|
247
|
+
If the org of the repository is not the same as your forge user
|
|
248
|
+
then it will fork the repo for you to your account (if not
|
|
249
|
+
already done), clone the repo, and then setup your remotes
|
|
234
250
|
so that "origin" is your fork and "upstream" is the upstream.
|
|
235
251
|
|
|
252
|
+
It is assumed that there will be at least one positional
|
|
253
|
+
argument, and it will be the repo in any format (git, ssh,
|
|
254
|
+
forge-style shortname [e.g. e.g. "$org/$repo"]). A second
|
|
255
|
+
positional argument will be interpreted as the directory to
|
|
256
|
+
clone into.
|
|
257
|
+
|
|
258
|
+
If you want to change the name of the repo in your fork of it,
|
|
259
|
+
you may pass in --fork-name to specify another.
|
|
260
|
+
|
|
261
|
+
Note that if you pass in additional options after ' -- ', they
|
|
262
|
+
will be passed to 'gh' in the case of GitHub, or 'git' in the
|
|
263
|
+
case of GitLab.
|
|
264
|
+
|
|
265
|
+
For example to clone foo/bar/docs on gitlab, but have the
|
|
266
|
+
repo named 'bar-docs' when it's cloned to your org, and to
|
|
267
|
+
have the directory be called 'bar-docs':
|
|
268
|
+
|
|
269
|
+
sj sclone foo/bar/docs bar-docs \
|
|
270
|
+
--forge-type glab --fork-name bar-docs
|
|
271
|
+
|
|
272
|
+
Or for GitHub:
|
|
273
|
+
|
|
274
|
+
sj sclone bar/docs bar-docs \
|
|
275
|
+
--forge-type github --fork-name bar-docs
|
|
276
|
+
|
|
236
277
|
smartlog, sl
|
|
237
278
|
Inspired by Facebook's "sl" extension to Mercurial, this command
|
|
238
279
|
will show you a tree of all your local branches relative to your
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
class SugarJar
|
|
2
2
|
class Commands
|
|
3
|
-
def smartclone(repo,
|
|
4
|
-
reponame = extract_repo(repo)
|
|
5
|
-
dir ||= reponame
|
|
3
|
+
def smartclone(repo, *args)
|
|
6
4
|
org = extract_org(repo)
|
|
5
|
+
reponame = extract_repo(repo)
|
|
6
|
+
dir = if args.length.positive? && !args.first.start_with?('-')
|
|
7
|
+
args.shift
|
|
8
|
+
else
|
|
9
|
+
reponame
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
forkname = @fork_name || reponame
|
|
7
13
|
|
|
8
14
|
SugarJar::Log.info("Cloning #{reponame}...")
|
|
9
15
|
|
|
@@ -13,37 +19,44 @@ class SugarJar
|
|
|
13
19
|
#
|
|
14
20
|
# Unless the repo is in our own org and cannot be forked, then it
|
|
15
21
|
# will fail.
|
|
16
|
-
if
|
|
17
|
-
git('clone', canonicalize_repo(repo), dir, *)
|
|
18
|
-
else
|
|
22
|
+
if @use_forks && @forge_user != org
|
|
19
23
|
if @repo_forge == 'gitlab'
|
|
20
|
-
_gitlab_clone(org, repo, dir, *)
|
|
24
|
+
_gitlab_clone(org, repo, dir, forkname, *args)
|
|
21
25
|
else
|
|
22
|
-
forge(
|
|
26
|
+
forge(
|
|
27
|
+
'repo', 'fork', '--clone', canonicalize_repo(repo), dir,
|
|
28
|
+
'--fork-name', forkname, *args
|
|
29
|
+
)
|
|
23
30
|
end
|
|
24
31
|
|
|
25
32
|
# make the main branch track upstream
|
|
26
33
|
Dir.chdir dir do
|
|
27
34
|
git('branch', '-u', "upstream/#{main_branch}")
|
|
28
35
|
end
|
|
36
|
+
else
|
|
37
|
+
git('clone', canonicalize_repo(repo), dir, *args)
|
|
29
38
|
end
|
|
30
39
|
|
|
31
40
|
SugarJar::Log.info('Remotes "origin" and "upstream" configured.')
|
|
32
41
|
end
|
|
33
42
|
alias sclone smartclone
|
|
34
43
|
|
|
35
|
-
def _gitlab_clone(_org, repo, dir, *)
|
|
44
|
+
def _gitlab_clone(_org, repo, dir, forkname, *)
|
|
36
45
|
# The gitlab CLI is much less forgiving about already-forked
|
|
37
46
|
# repos, and it has no option to clone to a differently-named
|
|
38
47
|
# directory. So we have to special case it.
|
|
39
48
|
|
|
49
|
+
extract_repo(repo)
|
|
50
|
+
|
|
40
51
|
# glab requires a short-name for the fork command...
|
|
41
52
|
shortname = repo_shortname(repo)
|
|
42
53
|
|
|
43
54
|
# We call fork without --clone since --clone can't clone
|
|
44
55
|
# to another directory. Also, we must specify =false, or it
|
|
45
56
|
# will prompt
|
|
46
|
-
s = forge_nofail(
|
|
57
|
+
s = forge_nofail(
|
|
58
|
+
'repo', 'fork', shortname, '--clone=false', '--name', forkname
|
|
59
|
+
)
|
|
47
60
|
|
|
48
61
|
# It fails with:
|
|
49
62
|
# 409 {message: [Project namespace name has already been taken,
|
|
@@ -70,7 +70,7 @@ class SugarJar
|
|
|
70
70
|
# we don't need that since it defaults to the local branch name.
|
|
71
71
|
#
|
|
72
72
|
# Then we need --yes for it to not prompt us
|
|
73
|
-
args.unshift('--head', "#{push_org}/#{
|
|
73
|
+
args.unshift('--head', "#{push_org}/#{repo_name}", '--yes')
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
bin = SugarJar::Util.which(_forge_cmd)
|
|
@@ -103,7 +103,9 @@ class SugarJar
|
|
|
103
103
|
"\tgit remote set-head #{upstream} -a",
|
|
104
104
|
)
|
|
105
105
|
end
|
|
106
|
-
|
|
106
|
+
|
|
107
|
+
# If we don't have an upstream and an origin, we're done
|
|
108
|
+
return if upstream == 'origin'
|
|
107
109
|
|
|
108
110
|
origin_branch = main_remote_branch('origin')
|
|
109
111
|
# NOTE: that on GL, forks don't fork any branches by default, even
|
data/lib/sugarjar/commands.rb
CHANGED
|
@@ -33,6 +33,8 @@ class SugarJar
|
|
|
33
33
|
@pr_autofill = options['pr_autofill']
|
|
34
34
|
@pr_autostack = options['pr_autostack']
|
|
35
35
|
@feature_prefix = options['feature_prefix']
|
|
36
|
+
@use_forks = options['use_forks']
|
|
37
|
+
@fork_name = options['fork_name']
|
|
36
38
|
@checks = {}
|
|
37
39
|
@main_branch = nil
|
|
38
40
|
@main_remote_branches = {}
|
|
@@ -88,27 +90,20 @@ class SugarJar
|
|
|
88
90
|
|
|
89
91
|
# otherwise, if we're in a repo, use the hostname of the remote
|
|
90
92
|
if SugarJar::Util.in_repo?
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
@repo_forge == 'gitlab' ? 'gitlab.com' : 'github.com'
|
|
93
|
+
url = remote_url_map.values.first
|
|
94
|
+
return extract_host(url)
|
|
94
95
|
end
|
|
96
|
+
|
|
97
|
+
@repo_forge == 'gitlab' ? 'gitlab.com' : 'github.com'
|
|
95
98
|
end
|
|
96
99
|
|
|
97
100
|
def repo_shortname(repo)
|
|
98
101
|
# if it's already a shortname, return
|
|
99
102
|
return repo unless repo.start_with?('http', 'git@')
|
|
100
103
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
elsif repo.start_with?('git@')
|
|
105
|
-
relevant = repo.split(':').last
|
|
106
|
-
bits = relevant.split('/')
|
|
107
|
-
end
|
|
108
|
-
repo = bits[-1].gsub('.git', '')
|
|
109
|
-
org = bits[-2]
|
|
110
|
-
|
|
111
|
-
"#{org}/#{repo}"
|
|
104
|
+
repo_name = extract_repo(repo)
|
|
105
|
+
org_name = extract_org(repo)
|
|
106
|
+
[org_name, repo_name].join('/')
|
|
112
107
|
end
|
|
113
108
|
|
|
114
109
|
def set_commit_template
|
|
@@ -176,11 +171,7 @@ class SugarJar
|
|
|
176
171
|
end
|
|
177
172
|
|
|
178
173
|
def determine_main_branch(branches)
|
|
179
|
-
|
|
180
|
-
'main'
|
|
181
|
-
elsif branches.include?('master')
|
|
182
|
-
'master'
|
|
183
|
-
end
|
|
174
|
+
branches.include?('master') ? 'master' : 'main'
|
|
184
175
|
end
|
|
185
176
|
|
|
186
177
|
def main_branch
|
|
@@ -353,12 +344,12 @@ class SugarJar
|
|
|
353
344
|
|
|
354
345
|
def extract_org(repo)
|
|
355
346
|
if repo.start_with?('http')
|
|
356
|
-
|
|
347
|
+
repo.split('://').last.split('/')[1..-2].join('/')
|
|
357
348
|
elsif repo.start_with?('git@')
|
|
358
|
-
repo.split(':')
|
|
349
|
+
repo.split(':').last.split('/')[0..-2].join('/')
|
|
359
350
|
else
|
|
360
|
-
# assume they passed in a
|
|
361
|
-
repo.split('/').
|
|
351
|
+
# assume they passed in a cli-friendly shortname
|
|
352
|
+
repo.split('/')[0..-2].join('/')
|
|
362
353
|
end
|
|
363
354
|
end
|
|
364
355
|
|
|
@@ -429,15 +420,13 @@ class SugarJar
|
|
|
429
420
|
end
|
|
430
421
|
|
|
431
422
|
def _determine_forge_type
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
x.include?('gitlab')
|
|
436
|
-
end
|
|
437
|
-
'gitlab'
|
|
438
|
-
else
|
|
439
|
-
'github'
|
|
423
|
+
if SugarJar::Util.in_repo?
|
|
424
|
+
gl = remote_url_map.values.any? { |x| x.include?('gitlab') }
|
|
425
|
+
return gl ? 'gitlab' : 'github'
|
|
440
426
|
end
|
|
427
|
+
|
|
428
|
+
# if all else fails, guess GH
|
|
429
|
+
'github'
|
|
441
430
|
end
|
|
442
431
|
|
|
443
432
|
def _forge_cmd
|
data/lib/sugarjar/config.rb
CHANGED
data/lib/sugarjar/version.rb
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: 3.0.
|
|
4
|
+
version: 3.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Phil Dibowitz
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-06-
|
|
11
|
+
date: 2026-06-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: deep_merge
|