sugarjar 0.0.1 → 0.0.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/README.md +215 -56
- data/lib/sugarjar/commands.rb +19 -12
- data/lib/sugarjar/config.rb +3 -1
- data/lib/sugarjar/util.rb +24 -1
- data/lib/sugarjar/version.rb +1 -1
- metadata +4 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c9a62438fa0d483eb64cd28cb5de3e603d6907a353194fac8df0bc8cd51a55f1
|
4
|
+
data.tar.gz: ff816417124253671a07ffe4ee2c6cb066a3b8f3f6dc0bac439a667297b595bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a97436c810c10af47d507eeb8c29070da38927884aef6f6ffaa39a9476777ba88e4c176fdb69ab67a979c832c3d32339f1c848c97ef1f6ecd5dcf17025f2b9e0
|
7
|
+
data.tar.gz: 478d20bcc6c8ed561f2ab6294d38a0e3267a96f0e239a565e498b483505dff950ad1712931a777012141e955438bb5f082db75698eb478a36981666bba38af19
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# SugarJar
|
2
2
|
|
3
3
|

|
4
4
|
|
@@ -12,84 +12,219 @@ the Phabricator workflow this aims to bring to the GitHub workflow.
|
|
12
12
|
In particular there are a lot of helpers for using a squash-merge workflow that
|
13
13
|
is poorly handled by the standard toolsets.
|
14
14
|
|
15
|
-
|
15
|
+
If you miss Mondrian or Phabrictor - this is the tool for you!
|
16
16
|
|
17
|
-
|
17
|
+
If you don't, there's a ton of useful stuff for everyone!
|
18
18
|
|
19
|
-
|
20
|
-
arguments such as `-a` or files.
|
19
|
+
## Auto cleanup squash-merged branches
|
21
20
|
|
22
|
-
|
21
|
+
It is common for a PR to go back and forth with a variety of nits, lint fixes,
|
22
|
+
typos, etc. that can muddy history. So many projects will "squash and merge"
|
23
|
+
when they accept a pull request. Howevet, that means `git branch -d <branch>`
|
24
|
+
doesn't work. Git will tell you the branch isn't fully merged. You can, of
|
25
|
+
course `git branch -D <branch>`, but that does no safety checks at all, it
|
26
|
+
forces the deletion.
|
23
27
|
|
24
|
-
|
25
|
-
|
28
|
+
Enter `sj bclean` - it determines of the contents of your branch has been merge
|
29
|
+
and safely deletes if so.
|
26
30
|
|
27
|
-
|
31
|
+
``` shell
|
32
|
+
sj bclean
|
33
|
+
```
|
34
|
+
|
35
|
+
Will delete a branch, if it has been merged, **even if it was squash-merged**.
|
28
36
|
|
29
|
-
|
30
|
-
|
37
|
+
You can pass it a branch if you'd like (it defaults to the branch you're on):
|
38
|
+
`sj bclean <branch>`.
|
31
39
|
|
32
|
-
|
40
|
+
But it gets better! You can use `sj bcleanall` to remove all branches that have
|
41
|
+
been merged:
|
42
|
+
|
43
|
+
```shell
|
44
|
+
$ git branch
|
45
|
+
* argparse
|
46
|
+
master
|
47
|
+
feature
|
48
|
+
hubhost
|
49
|
+
$ git bcleanall
|
50
|
+
Skipping branch argparse - there are unmerged commits
|
51
|
+
Reaped branch feature
|
52
|
+
Reaped branch hubhost
|
53
|
+
```
|
33
54
|
|
34
|
-
|
35
|
-
|
55
|
+
## Smarter clones and remotes
|
56
|
+
|
57
|
+
There's a pattern to every new repo we want to contribute to. First we fork,
|
58
|
+
then we clone the fork, then we add a remote of the upstream repo. It's
|
59
|
+
monotonous. SugarJar does this for you:
|
60
|
+
|
61
|
+
```shell
|
62
|
+
sj smartclone jaymzh/sugarjar
|
63
|
+
```
|
36
64
|
|
37
|
-
|
65
|
+
(also `sj sclone`)
|
38
66
|
|
39
|
-
|
67
|
+
This will:
|
40
68
|
|
41
|
-
|
69
|
+
* Make a fork of the repo, if you don't already have one
|
70
|
+
* Clone your fork
|
71
|
+
* Add the original as an 'upstream' remote
|
42
72
|
|
43
|
-
|
73
|
+
Note that it takes `hub`s short-names for repos. No need to specify a full URL,
|
74
|
+
just a $org/$repo.
|
44
75
|
|
45
|
-
|
76
|
+
Like `git clone`, `sj sclone` will accept an additional arguement as the
|
77
|
+
destination directory to clone to. It will also pass any other unknown options
|
78
|
+
to `git clone` under the hood.
|
46
79
|
|
47
|
-
|
48
|
-
it defaults to creating it based on some form of 'master' instead of your
|
49
|
-
current branch. In order of preference it will be `upstream/master`,
|
50
|
-
`origin/master`, or `master`, depending upon what remotes are available.
|
80
|
+
## Work with stacked branches more easily
|
51
81
|
|
52
|
-
|
82
|
+
It's important to break changes into reviewable chunks, but working with
|
83
|
+
stacked branches can be confusing. Enter `binfo` - it gives you a view of your
|
84
|
+
current branch all the way up to master. In this example imagine we have a
|
85
|
+
branch structure like:
|
53
86
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
87
|
+
```text
|
88
|
+
+- test2.1
|
89
|
+
/
|
90
|
+
master --- test --- test2 --- test3
|
91
|
+
```
|
58
92
|
|
59
|
-
|
93
|
+
This is what `binfo` on test3 looks like:
|
60
94
|
|
61
|
-
|
95
|
+
```shell
|
96
|
+
$ sj binfo
|
97
|
+
* e451865 (HEAD -> test3) test3
|
98
|
+
* e545b41 (test2) test2
|
99
|
+
* c808eae (test1) test1
|
100
|
+
o 44cf9e2 (origin/master, origin/HEAD, master) Lint/gemspec cleanups
|
101
|
+
```
|
62
102
|
|
63
|
-
|
103
|
+
while `binfo` on test2.1 looks like:
|
64
104
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
105
|
+
```shell
|
106
|
+
$ sj binfo
|
107
|
+
* 36d0136 (HEAD -> test2.1) test2.1
|
108
|
+
* e545b41 (test2) test2
|
109
|
+
* c808eae (test1) test1
|
110
|
+
o 44cf9e2 (origin/master, origin/HEAD, master) Lint/gemspec cleanups
|
111
|
+
```
|
70
112
|
|
71
|
-
|
113
|
+
## Have a better lint/unittest experience!
|
72
114
|
|
73
|
-
|
74
|
-
|
115
|
+
Ever made a PR, only to find out later that it failed tests because of some
|
116
|
+
small lint issue? Not anymore! SJ can be configured to run things before
|
117
|
+
pushing. For example,in the SugarJar repo, we have it run Rubocop (ruby lint)
|
118
|
+
and Markdownlint "on_push". If those fail, it lets you know and doesn't push.
|
75
119
|
|
76
|
-
|
77
|
-
|
120
|
+
You can configure SugarJar to tell how how to run both lints and unittests for
|
121
|
+
a given repo and if one or both should be run prior to pushing.
|
78
122
|
|
79
|
-
|
123
|
+
The details on the config file format is below, but we provide three commands:
|
80
124
|
|
81
|
-
|
125
|
+
```shell
|
126
|
+
git lint
|
127
|
+
```
|
82
128
|
|
83
|
-
|
129
|
+
Run all linters.
|
84
130
|
|
85
|
-
|
86
|
-
|
131
|
+
```shell
|
132
|
+
git unit
|
133
|
+
```
|
87
134
|
|
88
|
-
|
135
|
+
Run all unittests.
|
89
136
|
|
90
|
-
|
137
|
+
```shell
|
138
|
+
git smartpush # or spush
|
139
|
+
```
|
91
140
|
|
92
|
-
|
141
|
+
Run configured push-time actions (nothing, lint, unit, both), and do not
|
142
|
+
push if any of them fail.
|
143
|
+
|
144
|
+
## Better push defaults
|
145
|
+
|
146
|
+
In addition to running pre-push tests for you `smartpush` also picks smart
|
147
|
+
defaults for push. So if you `sj spush` with no arguements, it uses the
|
148
|
+
`origin` remote and the same branch name you're on as the remote branch.
|
149
|
+
|
150
|
+
## Cleaning up your own history
|
151
|
+
|
152
|
+
Perhaps you contribute to a project that prefers to use merge commits, so you
|
153
|
+
like to clean up your own history. This is often difficult to get right - a
|
154
|
+
combination of rebases, amends and force pushes. We provide two commands here
|
155
|
+
to help.
|
156
|
+
|
157
|
+
The first is pretty straight forward and is basically just an alias: `sj
|
158
|
+
amend`. It will ammend whatever you want to the most recent commit (just an
|
159
|
+
alias for `git commit --amend`). It has a partner `qamend` (or `amendq` if you
|
160
|
+
prefer) that will do so without prompting to update your commit message.
|
161
|
+
|
162
|
+
So now you've rebased or amended, pushing becomes challening. You can `git push
|
163
|
+
--force`, but everyone knows that's incredibly dangerous. Is there a better
|
164
|
+
way? There is! Git provides `git push --force-with-lease` - it checks to make
|
165
|
+
sure you're up-to-date with the remote before forcing the push. But man that
|
166
|
+
command is a mouthful! Enter `sj fpush`. It has all the smarts of `sj
|
167
|
+
smartpush` (runs configured pre-push actions), but adds `--force-with-lease` to
|
168
|
+
the command!
|
169
|
+
|
170
|
+
## Better feature branches
|
171
|
+
|
172
|
+
When you want to start a new feature, you want to start developing against
|
173
|
+
latest. That's why `sj feature` defaults to creating a branch against what we
|
174
|
+
call "most master". That is, `upstream/master` if it exists, otherwise
|
175
|
+
`origin/master` if that exists, otherwise `master`. You can pass in an
|
176
|
+
additional arguement to base it off of something else.
|
177
|
+
|
178
|
+
```shell
|
179
|
+
$ git branch
|
180
|
+
master
|
181
|
+
test1
|
182
|
+
test2
|
183
|
+
* test2.1
|
184
|
+
test3
|
185
|
+
$ sj feature test-branch
|
186
|
+
Created feature branch test-branch based on origin/master
|
187
|
+
$ sj feature dependent-feature test-branch
|
188
|
+
Created feature branch dependent-feature based on test-branch
|
189
|
+
```
|
190
|
+
|
191
|
+
## And more!
|
192
|
+
|
193
|
+
See `sj help` for more commands!
|
194
|
+
|
195
|
+
## Using SugarJar as a git wrapper
|
196
|
+
|
197
|
+
SugarJar, by default, will pass any command it doesn't know straight to `hub`
|
198
|
+
(which passes commands **it** doesn't know to `git`). As such you can alias it
|
199
|
+
to `git` and just have a super-git.
|
200
|
+
|
201
|
+
```shell
|
202
|
+
$ alias git=sj
|
203
|
+
$ git config -l | grep color
|
204
|
+
color.diff=auto
|
205
|
+
color.status=auto
|
206
|
+
color.branch=auto
|
207
|
+
color.branch.current=yellow reverse
|
208
|
+
color.branch.local=yellow
|
209
|
+
color.branch.remote=green
|
210
|
+
$ git br
|
211
|
+
* dependent-feature 44cf9e2 Lint/gemspec cleanups
|
212
|
+
master 44cf9e2 Lint/gemspec cleanups
|
213
|
+
test-branch 44cf9e2 Lint/gemspec cleanups
|
214
|
+
test1 c808eae [ahead 1] test1
|
215
|
+
test2 e545b41 test2
|
216
|
+
test2.1 c1831b3 test2.1
|
217
|
+
test3 e451865 test3
|
218
|
+
```
|
219
|
+
|
220
|
+
It's for this reason that SugarJar doesn't have conflicting command names. You
|
221
|
+
can turn off fallthru by setting `fallthru: false` in your config.
|
222
|
+
|
223
|
+
The only command we "override" is `version`, in which case we not only print
|
224
|
+
our version, but also call `hub version` which prints its version and calls
|
225
|
+
`git version` too!
|
226
|
+
|
227
|
+
## Configuration
|
93
228
|
|
94
229
|
Sugarjar will read in both a system-level config file
|
95
230
|
(`/etc/sugarjar/config.yaml`) and a user-level config file
|
@@ -133,17 +268,41 @@ on_push:
|
|
133
268
|
- lint
|
134
269
|
```
|
135
270
|
|
271
|
+
## Enterprise GitHub
|
272
|
+
|
273
|
+
Like `hub`, SugarJar supports GitHub Enterprise. In fact, we provide extra
|
274
|
+
features just for it.
|
275
|
+
|
276
|
+
We recommend the global or user config specify the `github_host`. However, most
|
277
|
+
users will also have a few repos from upstream so always specifying a
|
278
|
+
`github_host` is sub-optimal.
|
279
|
+
|
280
|
+
So, when you overwrite the `github_host` on the command line, we go ahead and
|
281
|
+
set the `hub.host` git config in that single repo so that it'll "just work"
|
282
|
+
from there on out.
|
283
|
+
|
284
|
+
In other words, assuming your global SJ config has `github_host:
|
285
|
+
github.sample.com`, and the you clone sugarjar with:
|
286
|
+
|
287
|
+
```shell
|
288
|
+
sj clone jaymzh/sugarjar --github-host githuh.com
|
289
|
+
```
|
290
|
+
|
291
|
+
We will add the `hub.host` to the `sugarjar` clone so that future `hub` or `sj`
|
292
|
+
commands work without needing to specify..
|
293
|
+
|
136
294
|
## FAQ
|
137
295
|
|
138
296
|
Why the name SugarJar?
|
139
297
|
|
140
|
-
It's mostly a backranym. Like jellyfish, I wanted two letters that were on
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
298
|
+
It's mostly a backranym. Like jellyfish, I wanted two letters that were on home
|
299
|
+
row on different sides of the keyboard to make it easy to type. I looked at the
|
300
|
+
possible options that where there and not taken and tried to find one I could
|
301
|
+
make an appropriate name out of. Since this utility adds lots of sugar to git
|
302
|
+
and github, it seemed appropriate.
|
145
303
|
|
146
304
|
Why did you use `hub` instead of the newer `gh` CLI?
|
147
305
|
|
148
|
-
`gh` is
|
149
|
-
|
306
|
+
`gh` is still new and not yet as feature rich as `hub`. Also I wanted SugarJar
|
307
|
+
to be able to be a git wrapper, and so wrapping `hub` allows us to do that but
|
308
|
+
wrapping `gh` does not.
|
data/lib/sugarjar/commands.rb
CHANGED
@@ -22,6 +22,8 @@ class SugarJar
|
|
22
22
|
SugarJar::Log.debug("Feature: #{name}, #{base}")
|
23
23
|
die("#{name} already exists!") if all_branches.include?(name)
|
24
24
|
base ||= most_master
|
25
|
+
base_pieces = base.split('/')
|
26
|
+
hub('fetch', base_pieces[0]) if base_pieces.length > 1
|
25
27
|
hub('checkout', '-b', name, base)
|
26
28
|
SugarJar::Log.info("Created feature branch #{name} based on #{base}")
|
27
29
|
end
|
@@ -44,16 +46,16 @@ class SugarJar
|
|
44
46
|
# rubocop:disable Style/Next
|
45
47
|
unless clean_branch(branch)
|
46
48
|
SugarJar::Log.info(
|
47
|
-
"Skipping branch #{branch} - there are unmerged commits"
|
49
|
+
"Skipping branch #{branch} - there are unmerged commits",
|
48
50
|
)
|
49
51
|
end
|
50
52
|
# rubocop:enable Style/Next
|
51
53
|
end
|
52
54
|
end
|
53
55
|
|
54
|
-
def co(
|
56
|
+
def co(*args)
|
55
57
|
assert_in_repo
|
56
|
-
hub('checkout',
|
58
|
+
hub('checkout', *args)
|
57
59
|
end
|
58
60
|
|
59
61
|
def br
|
@@ -82,7 +84,7 @@ class SugarJar
|
|
82
84
|
def amend(*args)
|
83
85
|
assert_in_repo
|
84
86
|
# This cannot use shellout since we need a full terminal for the editor
|
85
|
-
exit(system('
|
87
|
+
exit(system(which('git'), 'commit', '--amend', *args))
|
86
88
|
end
|
87
89
|
|
88
90
|
def qamend(*args)
|
@@ -104,7 +106,7 @@ class SugarJar
|
|
104
106
|
else
|
105
107
|
SugarJar::Log.error(
|
106
108
|
"Failed to rebase #{branch}, aborting that and moving to next " +
|
107
|
-
'branch'
|
109
|
+
'branch',
|
108
110
|
)
|
109
111
|
hub('rebase', '--abort')
|
110
112
|
end
|
@@ -202,10 +204,15 @@ class SugarJar
|
|
202
204
|
if current == @ghost
|
203
205
|
SugarJar::Log.debug('Repo hub.host already set correctly')
|
204
206
|
else
|
205
|
-
|
206
|
-
|
207
|
+
# Even though we have an explicit config, in most cases, it
|
208
|
+
# comes from a global or user config, but the config in the
|
209
|
+
# local repo we likely set. So we'd just constantly revert that.
|
210
|
+
SugarJar::Log.debug(
|
211
|
+
"Not overwriting repo hub.host. Already set to #{current}. " +
|
212
|
+
"To change it, run `git config --local --add hub.host #{@ghhost}`",
|
207
213
|
)
|
208
214
|
end
|
215
|
+
return
|
209
216
|
end
|
210
217
|
hub('config', '--local', '--add', 'hub.host', @ghhost)
|
211
218
|
end
|
@@ -287,7 +294,7 @@ class SugarJar
|
|
287
294
|
end
|
288
295
|
if out.length.zero?
|
289
296
|
SugarJar::Log.debug(
|
290
|
-
"cherry-pick shows branch #{branch} obviously safe to delete"
|
297
|
+
"cherry-pick shows branch #{branch} obviously safe to delete",
|
291
298
|
)
|
292
299
|
return true
|
293
300
|
end
|
@@ -303,10 +310,10 @@ class SugarJar
|
|
303
310
|
s = hub_nofail('merge', '--squash', branch)
|
304
311
|
if s.error?
|
305
312
|
cleanup_tmp_branch(tmpbranch, branch)
|
306
|
-
error(
|
313
|
+
SugarJar::Log.error(
|
307
314
|
'Failed to merge changes into current master. This means we could ' +
|
308
315
|
'not figure out if this is merged or not. Check manually and use ' +
|
309
|
-
"'git branch -D #{branch}' if it is safe to do so."
|
316
|
+
"'git branch -D #{branch}' if it is safe to do so.",
|
310
317
|
)
|
311
318
|
return false
|
312
319
|
end
|
@@ -317,12 +324,12 @@ class SugarJar
|
|
317
324
|
cleanup_tmp_branch(tmpbranch, branch)
|
318
325
|
if out.empty?
|
319
326
|
SugarJar::Log.debug(
|
320
|
-
'After squash-merging, this branch appears safe to delete'
|
327
|
+
'After squash-merging, this branch appears safe to delete',
|
321
328
|
)
|
322
329
|
true
|
323
330
|
else
|
324
331
|
SugarJar::Log.debug(
|
325
|
-
'After squash-merging, this branch is NOT fully merged to master'
|
332
|
+
'After squash-merging, this branch is NOT fully merged to master',
|
326
333
|
)
|
327
334
|
false
|
328
335
|
end
|
data/lib/sugarjar/config.rb
CHANGED
@@ -22,7 +22,9 @@ class SugarJar
|
|
22
22
|
c = DEFAULTS.dup
|
23
23
|
_find_ordered_files.each do |f|
|
24
24
|
SugarJar::Log.debug("Loading config #{f}")
|
25
|
-
|
25
|
+
data = YAML.safe_load(File.read(f))
|
26
|
+
# an empty file is a `nil` which you can't merge
|
27
|
+
c.merge!(YAML.safe_load(File.read(f))) if data
|
26
28
|
SugarJar::Log.debug("Modified config: #{c}")
|
27
29
|
end
|
28
30
|
c
|
data/lib/sugarjar/util.rb
CHANGED
@@ -3,9 +3,32 @@ require_relative 'log'
|
|
3
3
|
class SugarJar
|
4
4
|
# Some common methods needed by other classes
|
5
5
|
module Util
|
6
|
+
# Finds the first entry in the path for a binary and checks
|
7
|
+
# to make sure it's not us (i.e. we may be linked to as 'git'
|
8
|
+
# or 'hub', but when we are calling that, we don't want ourselves.
|
9
|
+
def which_nofail(cmd)
|
10
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |dir|
|
11
|
+
p = File.join(dir, cmd)
|
12
|
+
# if it exists, and it is executable and is not us...
|
13
|
+
if File.exist?(p) && File.executable?(p) &&
|
14
|
+
File.basename(File.realpath(p)) != 'sj'
|
15
|
+
return p
|
16
|
+
end
|
17
|
+
end
|
18
|
+
false
|
19
|
+
end
|
20
|
+
|
21
|
+
def which(cmd)
|
22
|
+
path = which_nofail(cmd)
|
23
|
+
return path if path
|
24
|
+
|
25
|
+
SugarJar::Log.fatal("Could not find #{cmd} in your path")
|
26
|
+
exit(1)
|
27
|
+
end
|
28
|
+
|
6
29
|
def hub_nofail(*args)
|
7
30
|
SugarJar::Log.trace("Running: hub #{args.join(' ')}")
|
8
|
-
Mixlib::ShellOut.new(['
|
31
|
+
Mixlib::ShellOut.new([which('hub')] + args).run_command
|
9
32
|
end
|
10
33
|
|
11
34
|
def hub(*args)
|
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: 0.0.
|
4
|
+
version: 0.0.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: 2020-06-
|
11
|
+
date: 2020-06-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mixlib-log
|
@@ -38,20 +38,6 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: yaml
|
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
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: bundler
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -130,7 +116,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
130
116
|
- !ruby/object:Gem::Version
|
131
117
|
version: '0'
|
132
118
|
requirements: []
|
133
|
-
|
119
|
+
rubyforge_project:
|
120
|
+
rubygems_version: 2.7.6.2
|
134
121
|
signing_key:
|
135
122
|
specification_version: 4
|
136
123
|
summary: A git/github helper script
|