sugarjar 1.1.1 → 1.1.2
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/bin/sj +31 -7
- data/lib/sugarjar/commands.rb +93 -18
- data/lib/sugarjar/config.rb +2 -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: 4263a42ebb922645e2e0735c3ca33ad94df880fb01f881b2cacb602d733c533e
|
4
|
+
data.tar.gz: 616fb99c535c491324c1dcc4906b37c8cb424566b62dc64377c61b9a5ef5fd49
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d918daf7096d1889bf72ee0eca74ef473234ed1ed46e4275418028e9a32c9284b4412ff202a932a3cc43c777bbf55d1455ce8fd8805c965184e4d2bc740e527
|
7
|
+
data.tar.gz: 0657a6629d97623d40f68d0ffe7a3e0522c951d9b22dc0c7b4b918d78eb27b026ab68d347b1c2fa68661536eceef9cbf3de3ee82b4ea4381da2675f1d34b3f2d
|
data/bin/sj
CHANGED
@@ -91,6 +91,24 @@ parser = OptionParser.new do |opts|
|
|
91
91
|
options['log_level'] = level
|
92
92
|
end
|
93
93
|
|
94
|
+
opts.on(
|
95
|
+
'--[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]',
|
98
|
+
) do |autofill|
|
99
|
+
options['pr_autofill'] = autofill
|
100
|
+
end
|
101
|
+
|
102
|
+
opts.on(
|
103
|
+
'--[no-]pr-autostack',
|
104
|
+
'When creating a PR, if this is a subfeature, should we make it a ' +
|
105
|
+
'PR on the PR for the parent feature. If not specified, we prompt ' +
|
106
|
+
'when this happens, when true always do this, when false never do ' +
|
107
|
+
'this. Only applicable when usiing "gh".',
|
108
|
+
) do |autostack|
|
109
|
+
options['pr_autostack'] = autostack
|
110
|
+
end
|
111
|
+
|
94
112
|
opts.on('--[no-]use-color', 'Enable color. [default: true]') do |color|
|
95
113
|
options['color'] = color
|
96
114
|
end
|
@@ -112,10 +130,10 @@ COMMANDS:
|
|
112
130
|
Same as "amend" but without changing the message. Alias for
|
113
131
|
"git commit --amend --no-edit".
|
114
132
|
|
115
|
-
bclean
|
116
|
-
If safe, delete the current branch
|
117
|
-
bclean can handle squash-merged branches.
|
118
|
-
a smarter "git branch -d".
|
133
|
+
bclean [<branch>]
|
134
|
+
If safe, delete the current branch (or the specified branch).
|
135
|
+
Unlike "git branch -d", bclean can handle squash-merged branches.
|
136
|
+
Think of it as a smarter "git branch -d".
|
119
137
|
|
120
138
|
bcleanall
|
121
139
|
Walk all branches, and try to delete them if it's safe. See
|
@@ -127,7 +145,7 @@ COMMANDS:
|
|
127
145
|
br
|
128
146
|
Verbose branch list. An alias for "git branch -v".
|
129
147
|
|
130
|
-
feature
|
148
|
+
feature, f <branch_name>
|
131
149
|
Create a "feature" branch. It's morally equivalent to
|
132
150
|
"git checkout -b" except it defaults to creating it based on
|
133
151
|
some form of 'master' instead of your current branch. In order
|
@@ -177,11 +195,17 @@ COMMANDS:
|
|
177
195
|
A smart wrapper to "git push" that runs whatever is defined in
|
178
196
|
"on_push" in .sugarjar.yml, and only pushes if they succeed.
|
179
197
|
|
198
|
+
subfeature, sf <feature>
|
199
|
+
An alias for 'sj feature <feature> <current_branch>'
|
200
|
+
|
180
201
|
unit
|
181
202
|
Run any unitests configured in .sugarjar.yaml.
|
182
203
|
|
183
|
-
up
|
184
|
-
Rebase the current branch
|
204
|
+
up [<branch>]
|
205
|
+
Rebase the current branch (or specified branch) intelligently.
|
206
|
+
In most causes this will check for a main (or master) branch on
|
207
|
+
upstream, then origin. If a branch explicitly tracks something
|
208
|
+
else, then that will be used, instead.
|
185
209
|
|
186
210
|
upall
|
187
211
|
Same as "up", but for all branches.
|
data/lib/sugarjar/commands.rb
CHANGED
@@ -23,6 +23,8 @@ class SugarJar
|
|
23
23
|
@repo_config = SugarJar::RepoConfig.config
|
24
24
|
SugarJar::Log.debug("Repoconfig: #{@repo_config}")
|
25
25
|
@color = options['color']
|
26
|
+
@pr_autofill = options['pr_autofill']
|
27
|
+
@pr_autostack = options['pr_autostack']
|
26
28
|
@feature_prefix = options['feature_prefix']
|
27
29
|
@checks = {}
|
28
30
|
@main_branch = nil
|
@@ -43,19 +45,31 @@ class SugarJar
|
|
43
45
|
name = fprefix(name)
|
44
46
|
die("#{name} already exists!") if all_local_branches.include?(name)
|
45
47
|
base ||= most_main
|
46
|
-
|
47
|
-
|
48
|
+
# If our base is a local branch, don't try to parse it for a remote name
|
49
|
+
unless all_local_branches.include?(base)
|
50
|
+
base_pieces = base.split('/')
|
51
|
+
git('fetch', base_pieces[0]) if base_pieces.length > 1
|
52
|
+
end
|
48
53
|
git('checkout', '-b', name, base)
|
54
|
+
git('branch', '-u', base)
|
49
55
|
SugarJar::Log.info(
|
50
56
|
"Created feature branch #{color(name, :green)} based on " +
|
51
57
|
color(base, :green),
|
52
58
|
)
|
53
59
|
end
|
60
|
+
alias f feature
|
61
|
+
|
62
|
+
def subfeature(name)
|
63
|
+
assert_in_repo
|
64
|
+
SugarJar::Log.debug("Subfature: #{name}")
|
65
|
+
feature(name, current_branch)
|
66
|
+
end
|
67
|
+
alias sf subfeature
|
54
68
|
|
55
69
|
def bclean(name = nil)
|
56
70
|
assert_in_repo
|
57
71
|
name ||= current_branch
|
58
|
-
name = fprefix(name)
|
72
|
+
name = fprefix(name)
|
59
73
|
if clean_branch(name)
|
60
74
|
SugarJar::Log.info("#{name}: #{color('reaped', :green)}")
|
61
75
|
else
|
@@ -100,7 +114,7 @@ class SugarJar
|
|
100
114
|
# and then add any featureprefix, and if _that_ is a branch
|
101
115
|
# name, replace the last arguement with that
|
102
116
|
name = args.last
|
103
|
-
bname = fprefix(name)
|
117
|
+
bname = fprefix(name)
|
104
118
|
if all_local_branches.include?(bname)
|
105
119
|
SugarJar::Log.debug("Featurepefixing #{name} -> #{bname}")
|
106
120
|
args[-1] = bname
|
@@ -133,11 +147,14 @@ class SugarJar
|
|
133
147
|
|
134
148
|
alias sl smartlog
|
135
149
|
|
136
|
-
def up
|
150
|
+
def up(branch = nil)
|
137
151
|
assert_in_repo
|
152
|
+
branch ||= current_branch
|
153
|
+
branch = fprefix(branch)
|
138
154
|
# get a copy of our current branch, if rebase fails, we won't
|
139
155
|
# be able to determine it without backing out
|
140
156
|
curr = current_branch
|
157
|
+
git('checkout', branch)
|
141
158
|
result = gitup
|
142
159
|
if result['so'].error?
|
143
160
|
backout = ''
|
@@ -156,6 +173,8 @@ class SugarJar
|
|
156
173
|
SugarJar::Log.info(
|
157
174
|
"#{color(current_branch, :green)} rebased on #{result['base']}",
|
158
175
|
)
|
176
|
+
# go back to where we were if we rebased a different branch
|
177
|
+
git('checkout', curr) if branch != curr
|
159
178
|
end
|
160
179
|
end
|
161
180
|
|
@@ -302,6 +321,7 @@ class SugarJar
|
|
302
321
|
def smartpullrequest(*args)
|
303
322
|
assert_in_repo
|
304
323
|
assert_common_main_branch
|
324
|
+
|
305
325
|
if dirty?
|
306
326
|
SugarJar::Log.warn(
|
307
327
|
'Your repo is dirty, so I am not going to create a pull request. ' +
|
@@ -309,9 +329,38 @@ class SugarJar
|
|
309
329
|
)
|
310
330
|
exit(1)
|
311
331
|
end
|
332
|
+
|
312
333
|
if gh?
|
334
|
+
curr = current_branch
|
335
|
+
base = tracked_branch
|
336
|
+
if @pr_autofill
|
337
|
+
num_commits = git(
|
338
|
+
'rev-list', '--count', curr, "^#{base}"
|
339
|
+
).stdout.strip.to_i
|
340
|
+
if num_commits > 1
|
341
|
+
SugarJar::Log.debug(
|
342
|
+
"Not using --fill because there are #{num_commits} commits",
|
343
|
+
)
|
344
|
+
else
|
345
|
+
SugarJar::Log.info('Autofilling in PR from commit message')
|
346
|
+
args.unshift('--fill')
|
347
|
+
end
|
348
|
+
end
|
349
|
+
if subfeature?(base)
|
350
|
+
# nil is prompt, true is always, false is never
|
351
|
+
if @pr_autostack.nil?
|
352
|
+
$stdout.print(
|
353
|
+
'It looks like this is a subfeature, would you like to base ' +
|
354
|
+
"this PR on #{base}? [y/n] ",
|
355
|
+
)
|
356
|
+
ans = $stdin.gets.strip
|
357
|
+
args += ['--base', base] if %w{Y y}.include?(ans)
|
358
|
+
elsif @pr_autostack
|
359
|
+
args += ['--base', base]
|
360
|
+
end
|
361
|
+
end
|
313
362
|
SugarJar::Log.trace("Running: gh pr create #{args.join(' ')}")
|
314
|
-
system(which('gh'), 'pr', 'create',
|
363
|
+
system(which('gh'), 'pr', 'create', *args)
|
315
364
|
else
|
316
365
|
SugarJar::Log.trace("Running: hub pull-request #{args.join(' ')}")
|
317
366
|
system(which('hub'), 'pull-request', *args)
|
@@ -341,7 +390,7 @@ class SugarJar
|
|
341
390
|
|
342
391
|
src = "origin/#{current_branch}"
|
343
392
|
fetch('origin')
|
344
|
-
diff = git('diff', src).stdout
|
393
|
+
diff = git('diff', "..#{src}").stdout
|
345
394
|
return unless diff && !diff.empty?
|
346
395
|
|
347
396
|
puts "Will merge the following suggestions:\n\n#{diff}"
|
@@ -369,6 +418,9 @@ class SugarJar
|
|
369
418
|
def fprefix(name)
|
370
419
|
return name unless @feature_prefix
|
371
420
|
|
421
|
+
return name if name.start_with?(@feature_prefix)
|
422
|
+
return name if all_local_branches.include?(name)
|
423
|
+
|
372
424
|
newname = "#{@feature_prefix}#{name}"
|
373
425
|
SugarJar::Log.debug(
|
374
426
|
"Munging feature name: #{name} -> #{newname} due to feature prefix",
|
@@ -712,11 +764,15 @@ class SugarJar
|
|
712
764
|
end
|
713
765
|
|
714
766
|
def all_local_branches
|
715
|
-
|
716
|
-
|
717
|
-
|
767
|
+
git(
|
768
|
+
'branch', '--format', '%(refname)'
|
769
|
+
).stdout.lines.map do |line|
|
770
|
+
branch_from_ref(line.strip)
|
718
771
|
end
|
719
|
-
|
772
|
+
end
|
773
|
+
|
774
|
+
def all_remotes
|
775
|
+
git('remote').stdout.lines.map(&:strip)
|
720
776
|
end
|
721
777
|
|
722
778
|
def safe_to_clean(branch)
|
@@ -794,14 +850,28 @@ class SugarJar
|
|
794
850
|
SugarJar::Log.debug('Fetching upstream')
|
795
851
|
fetch_upstream
|
796
852
|
curr = current_branch
|
797
|
-
|
853
|
+
# this isn't a hash, it's a named param, silly rubocop
|
854
|
+
# rubocop:disable Style/HashSyntax
|
855
|
+
base = tracked_branch(fallback: false)
|
856
|
+
# rubocop:enable Style/HashSyntax
|
857
|
+
unless base
|
858
|
+
SugarJar::Log.info(
|
859
|
+
'The brach we were tracking is gone, resetting tracking to ' +
|
860
|
+
most_main,
|
861
|
+
)
|
862
|
+
git('branch', '-u', most_main)
|
863
|
+
base = most_main
|
864
|
+
end
|
865
|
+
# If this is a subfeature based on a local branch which has since
|
866
|
+
# been deleted, 'tracked branch' will automatically return <most_main>
|
867
|
+
# so we don't need any special handling for that
|
798
868
|
if !MAIN_BRANCHES.include?(curr) && base == "origin/#{curr}"
|
799
869
|
SugarJar::Log.warn(
|
800
870
|
"This branch is tracking origin/#{curr}, which is probably your " +
|
801
871
|
'downstream (where you push _to_) as opposed to your upstream ' +
|
802
872
|
'(where you pull _from_). This means that "sj up" is probably ' +
|
803
873
|
'rebasing on the wrong thing and doing nothing. You probably want ' +
|
804
|
-
|
874
|
+
"to do a 'git branch -u #{most_main}'.",
|
805
875
|
)
|
806
876
|
end
|
807
877
|
SugarJar::Log.debug('Rebasing')
|
@@ -812,6 +882,12 @@ class SugarJar
|
|
812
882
|
}
|
813
883
|
end
|
814
884
|
|
885
|
+
# determine if this branch is based on another local branch (i.e. is a
|
886
|
+
# subfeature). Used to figure out of we should stack the PR
|
887
|
+
def subfeature?(base)
|
888
|
+
all_local_branches.reject { |x| x == most_main }.include?(base)
|
889
|
+
end
|
890
|
+
|
815
891
|
def rebase_in_progress?
|
816
892
|
# for rebase without -i
|
817
893
|
rebase_file = git('rev-parse', '--git-path', 'rebase-apply').stdout.strip
|
@@ -821,12 +897,13 @@ class SugarJar
|
|
821
897
|
File.exist?(rebase_file) || File.exist?(rebase_merge_file)
|
822
898
|
end
|
823
899
|
|
824
|
-
def tracked_branch
|
900
|
+
def tracked_branch(fallback: true)
|
825
901
|
s = git_nofail(
|
826
902
|
'rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}'
|
827
903
|
)
|
828
904
|
if s.error?
|
829
|
-
most_main
|
905
|
+
fallback ? most_main : nil
|
906
|
+
|
830
907
|
else
|
831
908
|
s.stdout.strip
|
832
909
|
end
|
@@ -844,9 +921,7 @@ class SugarJar
|
|
844
921
|
def upstream
|
845
922
|
return @remote if @remote
|
846
923
|
|
847
|
-
|
848
|
-
|
849
|
-
remotes = s.stdout.lines.map(&:strip)
|
924
|
+
remotes = all_remotes
|
850
925
|
SugarJar::Log.debug("remotes is #{remotes}")
|
851
926
|
if remotes.empty?
|
852
927
|
@remote = nil
|
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: 1.1.
|
4
|
+
version: 1.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Phil Dibowitz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-04-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: deep_merge
|