pivotal-github 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +53 -83
- data/lib/pivotal-github.rb +0 -2
- data/lib/pivotal-github/command.rb +14 -4
- data/lib/pivotal-github/story_commit.rb +9 -12
- data/lib/pivotal-github/story_pull_request.rb +1 -12
- data/lib/pivotal-github/version.rb +1 -1
- data/spec/commands/story_commit_spec.rb +23 -21
- data/spec/commands/story_merge_spec.rb +3 -3
- data/spec/commands/story_pull_request_spec.rb +2 -9
- metadata +2 -12
- data/bin/git-story-pull +0 -5
- data/bin/git-story-push +0 -5
- data/lib/pivotal-github/story_pull.rb +0 -41
- data/lib/pivotal-github/story_push.rb +0 -36
- data/spec/commands/story_pull_spec.rb +0 -40
- data/spec/commands/story_push_spec.rb +0 -37
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# pivotal-github
|
2
2
|
|
3
|
-
The `pivotal-github` gem facilitates a [Pivotal Tracker](http://pivotaltracker.com/)–[GitHub](http://github.com/) workflow inspired by the workflow used by [Logical Reality](http://lrdesign.com/). (
|
3
|
+
The `pivotal-github` gem facilitates a [Pivotal Tracker](http://pivotaltracker.com/)–[GitHub](http://github.com/) workflow inspired by the workflow used by [Logical Reality](http://lrdesign.com/). (Despite its name, `pivotal-github` also works fine with [BitBucket](http://bitbucket.com/); see **Configuration** below.) As per usual, there are several projects (notably [git-flow](https://github.com/nvie/gitflow) and [git-pivotal](https://github.com/trydionel/git-pivotal)) that implement similar solutions, but none met my exact needs, so I rolled my own.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -8,42 +8,67 @@ You can install the `pivotal-github` gem directly as follows:
|
|
8
8
|
|
9
9
|
$ gem install pivotal-github
|
10
10
|
|
11
|
+
The full workflow described herein requires some of the Git utilities from [git-utils](https://github.com/mhartl/git-utils), so it is recommended to install those as well.
|
11
12
|
|
12
13
|
## Usage
|
13
14
|
|
14
|
-
The `pivotal-github` gem adds several additional Git commands to the local environment. The main addition, `git story-commit`, automatically incorporates the Pivotal Tracker story id(s) into the commit messages, while adding options to mark the story **Finished** or **Delivered**.
|
15
|
+
The `pivotal-github` gem adds several additional Git commands to the local environment. The main addition, `git story-commit`, automatically incorporates the Pivotal Tracker story id(s) into the commit messages, while adding options to mark the story **Finished** or **Delivered**.
|
15
16
|
|
16
|
-
The `git story-commit` command makes the assumption that any string of digits in the branch name is a story id. This means that
|
17
|
+
The `git story-commit` command makes the assumption that any string of digits in the branch name is a story id. This means that the branch names `6283185-add-markdown-support`, `6283185_add_markdown_support`, and `add-markdown-support-6283185` all correspond to story id `6283185`, while `add-things-6283185-3141592` corresponds to both `6283185` *and* `3141592`.
|
17
18
|
|
18
19
|
The full set of commands is as follows:
|
19
20
|
|
20
21
|
### git story-commit
|
21
22
|
|
22
|
-
`git story-commit` makes a standard `git commit` with the story number added to the commit message. This automatically adds a link at Pivotal Tracker between the story and the diff when the branch gets pushed up to GitHub.
|
23
|
+
`git story-commit` makes a standard `git commit` with the story number added to the commit message. This automatically adds a link at Pivotal Tracker between the story and the diff when the branch gets pushed up to GitHub.
|
23
24
|
|
24
25
|
For example, when on a branch called `add-markdown-support-6283185`, the `git story-commit` command automatically adds `[#6283185]` to the commit message:
|
25
|
-
|
26
|
+
|
26
27
|
$ git story-commit -am "Add foo bars"
|
27
|
-
[add-markdown-support-6283185 6f56414]
|
28
|
+
[add-markdown-support-6283185 6f56414] Add foo bars
|
29
|
+
|
30
|
+
The commit message is multiline and includes the story id:
|
31
|
+
|
32
|
+
Add foo bars
|
33
|
+
|
34
|
+
[#6283185]
|
35
|
+
|
36
|
+
(Previous versions of `pivotal-github` put the story id on the same line as the commit summary (per the usage at the [Pivotal Tracker API](https://www.pivotaltracker.com/help/api?version=v3)), but placing it in a separate line gives the user direct control over the length of the message. It also looks less cluttered.)
|
28
37
|
|
29
38
|
To mark a story as **Finished**, add the `-f` flag:
|
30
39
|
|
31
40
|
$ git story-commit -f -am "Remove baz quuxes"
|
32
|
-
|
41
|
+
|
42
|
+
This gives the message
|
43
|
+
|
44
|
+
Remove baz quuxes
|
45
|
+
|
46
|
+
[Finishes #6283185]
|
33
47
|
|
34
48
|
To mark a story as **Delivered**, add the `-d` flag:
|
35
49
|
|
36
50
|
$ git story-commit -d -am "Remove baz quuxes"
|
37
|
-
|
51
|
+
|
52
|
+
The message in this case is
|
53
|
+
|
54
|
+
Remove baz quuxes
|
55
|
+
|
56
|
+
[Delivers #6283185]
|
38
57
|
|
39
58
|
Either the `-f` flag or the `-d` flag can be combined with other flags, yielding commands like
|
40
59
|
|
41
60
|
$ git story-commit -dam "Remove baz quuxes"
|
42
61
|
|
43
|
-
`git story commit` supports multiple story numbers as well. For example, with a branch called `add-things-6283185-3141592`, we could deliver both stories as follows
|
62
|
+
`git story commit` supports multiple story numbers as well. For example, with a branch called `add-things-6283185-3141592`, we could deliver both stories as follows:
|
44
63
|
|
45
64
|
$ git story-commit -dam "Remove baz quuxes"
|
46
|
-
[add-things-6283185-3141592 7g56429]
|
65
|
+
[add-things-6283185-3141592 7g56429] Remove baz quuxes
|
66
|
+
|
67
|
+
The message here is
|
68
|
+
|
69
|
+
Remove baz quuxes
|
70
|
+
|
71
|
+
[Delivers #6283185 #3141592]
|
47
72
|
|
48
73
|
#### Options
|
49
74
|
|
@@ -57,70 +82,16 @@ Either the `-f` flag or the `-d` flag can be combined with other flags, yielding
|
|
57
82
|
|
58
83
|
Additionally, `git story-commit` accepts any options valid for `git commit`. (`git story-commit` supports the `-a` flag even though that's a valid option to `git commit` so that the compound flag in `git story-commit -am "message"` works.)
|
59
84
|
|
60
|
-
### git story-push
|
61
|
-
|
62
|
-
`git story push` creates a remote branch at `origin` with the name of the current branch:
|
63
|
-
|
64
|
-
$ git story-push
|
65
|
-
* [new branch] add-markdown-support-6283185 -> add-markdown-support-6283185
|
66
|
-
|
67
|
-
#### Options
|
68
|
-
|
69
|
-
Usage: git story-push [options]
|
70
|
-
-t, --target TARGET push to a given target (defaults to origin)
|
71
|
-
-h, --help this usage guide
|
72
|
-
|
73
|
-
Additionall, `git story-push` accepts any options valid for `git push`.
|
74
|
-
|
75
|
-
### git story-pull
|
76
|
-
|
77
|
-
`git story-pull` syncs the local `master` with the remote `master`. On a branch called `add-markdown-support-6283185`, `git story-pull` is equivalent to the following:
|
78
|
-
|
79
|
-
$ git checkout master
|
80
|
-
$ git pull
|
81
|
-
$ git checkout add-markdown-support-6283185
|
82
|
-
|
83
|
-
The purpose of `git story-pull` is to prepare the local story branch for rebasing against `master`:
|
84
|
-
|
85
|
-
$ git story-pull
|
86
|
-
$ git rebase master
|
87
|
-
|
88
|
-
(This is essentially equivalent to
|
89
|
-
|
90
|
-
$ git fetch
|
91
|
-
$ git rebase origin/master
|
92
|
-
|
93
|
-
but I don't like having `master` and `origin/master` be different since that means you have to remember to run `git pull` on `master` some time down the line.)
|
94
|
-
|
95
|
-
If you've already pushed the story, you'll have to force a subsequent push using
|
96
|
-
|
97
|
-
$ git push --force
|
98
|
-
|
99
|
-
If someone else might already have pulled the branch, you should probably merge `master` instead of rebasing against it:
|
100
|
-
|
101
|
-
$ git story-push
|
102
|
-
$ git story-pull
|
103
|
-
$ git merge master
|
104
|
-
|
105
|
-
|
106
|
-
#### Options
|
107
|
-
|
108
|
-
Usage: git story-pull [options]
|
109
|
-
-d, --development BRANCH development branch (defaults to master)
|
110
|
-
-h, --help this usage guide
|
111
|
-
|
112
|
-
Additionally, `git story-pull` accepts any options valid for `git pull`.
|
113
|
-
|
114
85
|
### git story-merge
|
115
86
|
|
116
|
-
`git story-merge` merges the current branch into `master`. On a branch called `add-markdown-support-6283185`, `git story-merge` is equivalent to the following:
|
87
|
+
`git story-merge` merges the current branch into `master`. On a branch called `add-markdown-support-6283185`, `git story-merge` is equivalent to the following:
|
117
88
|
|
118
89
|
$ git checkout master
|
119
90
|
$ git merge --no-ff --log add-markdown-support-6283185
|
120
91
|
|
121
92
|
Note that this effectively changes the default merge behavior from fast-forward to no-fast-forward, which makes it possible to use `git log` to see which of the commit objects together have implemented a story. As noted in [A successful Git branching model](http://nvie.com/posts/a-successful-git-branching-model/),
|
122
93
|
|
123
|
-
> The `--no-ff` flag causes the merge to always create a new commit object, even if the merge could be performed with a fast-forward. This avoids losing information about the historical existence of a feature branch and groups together all commits that together added the feature… Yes, it will create a few more (empty) commit objects, but the gain is much bigger
|
94
|
+
> The `--no-ff` flag causes the merge to always create a new commit object, even if the merge could be performed with a fast-forward. This avoids losing information about the historical existence of a feature branch and groups together all commits that together added the feature… Yes, it will create a few more (empty) commit objects, but the gain is much bigger than that cost.
|
124
95
|
|
125
96
|
In addition, the `--log` option puts the commit messages from the individual commits in the merge message, which arranges for the merge commit itself to appear in the activity log at Pivotal Tracker. This is especially useful for viewing the full diff represented by the commit.
|
126
97
|
|
@@ -143,7 +114,7 @@ Additionally, `git story-merge` accepts any options valid for `git merge`.
|
|
143
114
|
|
144
115
|
$ git story-pull-request
|
145
116
|
|
146
|
-
By default, `git story-pull-request` issues a `git
|
117
|
+
By default, `git story-pull-request` issues a `git push-branch` as well, just in case the local branch hasn't yet been pushed up to the remote repository.
|
147
118
|
|
148
119
|
As with `git story-merge`, by default `git story-pull-request` exits with a warning if the most recent commit doesn't finish the story.
|
149
120
|
|
@@ -151,12 +122,11 @@ As with `git story-merge`, by default `git story-pull-request` exits with a warn
|
|
151
122
|
|
152
123
|
Usage: git story-pull-request [options]
|
153
124
|
-f, --force override unfinished story warning
|
154
|
-
-s, --skip skip `git story-push`
|
155
125
|
-h, --help this usage guide
|
156
126
|
|
157
127
|
### story-open
|
158
128
|
|
159
|
-
The `story-open` command (
|
129
|
+
The `story-open` command (*note*: no `git`) opens the current story in the default browser (OS X–only):
|
160
130
|
|
161
131
|
$ story-open
|
162
132
|
|
@@ -168,15 +138,17 @@ In order to use the `pivotal-github` gem, you need to configure a post-receive h
|
|
168
138
|
The `pivotal-github` command names follow the Git convention of being verbose (e.g., unlike Subversion, Git doesn't natively support `co` for `checkout`), but I recommend setting up aliases as necessary. Here are some suggestions, formatted so that they can be pasted directly into a terminal window:
|
169
139
|
|
170
140
|
git config --global alias.sc story-commit
|
171
|
-
git config --global alias.sp story-push
|
172
|
-
git config --global alias.sl story-pull
|
173
141
|
git config --global alias.sm story-merge
|
174
142
|
git config --global alias.spr story-pull-request
|
175
143
|
|
144
|
+
I also recommend setting up an alias for `git push-branch` from [git-utils](https://github.com/mhartl/git-utils):
|
145
|
+
|
146
|
+
git config --global alias.pb push-branch
|
147
|
+
|
176
148
|
A single-developer workflow would then look like this:
|
177
149
|
|
178
150
|
$ git co -b add-markdown-support-6283185
|
179
|
-
$ git
|
151
|
+
$ git pb
|
180
152
|
<work>
|
181
153
|
$ git sc -am "Added foo"
|
182
154
|
$ git push
|
@@ -185,12 +157,10 @@ A single-developer workflow would then look like this:
|
|
185
157
|
<complete story>
|
186
158
|
$ git sc -f -am "Added baz"
|
187
159
|
$ git push
|
188
|
-
$ git
|
160
|
+
$ git sync
|
189
161
|
$ git rebase master
|
190
162
|
$ git sm
|
191
163
|
|
192
|
-
Note that this workflow uses `git sp` (and subsequent invocations of `git push`) only to create a remote backup. The principal purpose of `git story-push` is to support the integrated code review workflow described below.
|
193
|
-
|
194
164
|
## Workflow with integrated code reivew
|
195
165
|
|
196
166
|
The `pivotal-github` gem is degined to support a workflow involving integrated code review, which has the usual benefits: at least two pairs of eyes see any committed code, and at least two brains know basically what the committed code does. The cost is that having a second developer involved can slow you down. I suggest using your judgment to determine which workflow makes the most sense on a story-by-story basis.
|
@@ -201,16 +171,16 @@ Here's the process in detail:
|
|
201
171
|
|
202
172
|
1. Start an issue at [Pivotal Tracker](http://pivotaltracker.com/) and copy the story id to your buffer
|
203
173
|
2. Create a branch in the local Git repository containing the story id and a brief description: `git checkout -b add-markdown-support-6283185`
|
204
|
-
3. Create a remote branch at [GitHub](http://github.com/) using `git
|
174
|
+
3. Create a remote branch at [GitHub](http://github.com/) using `git push-branch`
|
205
175
|
3. Use `git story-commit` to make commits, which includes the story number in the commit message: `git story-commit -am "Add syntax highlighting"`
|
206
176
|
4. Continue pushing up after each commit using `git push` as usual
|
207
177
|
4. When done with the story, add `-f` to mark the story as **Finished** using `git story-commit -f -am "Add paragraph breaks"` or as **Delivered** using `git story-commit -d -am "Add paragraph breaks"`
|
208
|
-
4. Rebase against `master` using `git
|
178
|
+
4. Rebase against `master` using `git sync` followed by `git rebase master` or `git rebase master --interactive` (optionally squashing commit messages as described in the article [A Git Workflow for Agile Teams](http://reinh.com/blog/2009/03/02/a-git-workflow-for-agile-teams.html))
|
209
179
|
4. Push up with `git push`
|
210
180
|
6. At the GitHub page for the repo, select **Branches** and submit a pull request
|
211
181
|
6. (On OS X, replace the previous two steps with `git story-pull-request`)
|
212
182
|
6. Assign the pull request to Bob at GitHub
|
213
|
-
7. On the Pivotal Tracker story, add a comment with the pull request URL
|
183
|
+
7. On the Pivotal Tracker story, add a comment with the pull request URL, and optionally change the **Owner** to Bob
|
214
184
|
8. Continue working, taking care to branch off of the current story branch if its changes are required to continue
|
215
185
|
|
216
186
|
Rather than immediately submitting a pull request, Alice can also continue by branching off the previous story branch, working on a set of related features, and then issue Bob a pull request for the final branch when she reaches a natural stopping place.
|
@@ -219,14 +189,14 @@ Rather than immediately submitting a pull request, Alice can also continue by br
|
|
219
189
|
### Developer #2 (Bob)
|
220
190
|
|
221
191
|
1. Select **Pull Requests** at GitHub and review the pull request diffs
|
222
|
-
2. If acceptable, merge the branch by clicking on the button at GitHub
|
192
|
+
2. If acceptable, merge the branch by clicking on the button at GitHub, and optionally accept the story at Pivotal Tracker
|
223
193
|
3. If not acceptable, manually change the state at Pivotal Tracker to **Rejected** and leave a note (at GitHub or at Pivotal Tracker) indicating the reason
|
224
194
|
4. If the branch can't be automatically merged, mark the story as **Rejected**
|
225
195
|
|
226
196
|
### Developer #1 (Alice)
|
227
197
|
|
228
|
-
1. After getting the GitHub notification that the pull request has been merged, mark the Pivotal Tracker story finished
|
229
|
-
2. If the pull request was rejected, make the necessary changes and follow the previous steps above
|
198
|
+
1. After getting the GitHub notification that the pull request has been merged, mark the Pivotal Tracker story finished (unless assigned to Bob)
|
199
|
+
2. If the pull request was rejected, make the necessary changes and follow the previous steps above
|
230
200
|
|
231
201
|
|
232
202
|
## Merge conflicts
|
@@ -241,12 +211,12 @@ When the branch can't automatically be merged at GitHub, follow these steps:
|
|
241
211
|
|
242
212
|
### Devleloper #1 (Alice)
|
243
213
|
|
244
|
-
1. While on the story branch, run `git
|
214
|
+
1. While on the story branch, run `git sync`
|
245
215
|
2. Rebase against `master` with `git rebase master` **or** merge with `master` using `git merge master`
|
246
216
|
4. Either handle resulting conflicts by hand or use the visual merge tool: `git mergetool`
|
247
217
|
5. Commit the change: `git commit -a`
|
248
218
|
6. Push up the modified branch: `git push`
|
249
|
-
7. **(experimental)** Add a Chore to revisit the pull request and assign to Developer #2 (Bob)
|
219
|
+
7. **(experimental)** Add a Chore to revisit the pull request and assign to Developer #2 (Bob)
|
250
220
|
|
251
221
|
|
252
222
|
Now Bob should be able to merge in the pull request automatically using the nice big green button at GitHub.
|
data/lib/pivotal-github.rb
CHANGED
@@ -2,8 +2,6 @@ require "pivotal-github/version"
|
|
2
2
|
require "pivotal-github/options"
|
3
3
|
require "pivotal-github/command"
|
4
4
|
require "pivotal-github/story_commit"
|
5
|
-
require "pivotal-github/story_push"
|
6
|
-
require "pivotal-github/story_pull"
|
7
5
|
require "pivotal-github/story_merge"
|
8
6
|
require "pivotal-github/story_open"
|
9
7
|
require "pivotal-github/story_pull_request"
|
@@ -28,7 +28,7 @@ class Command
|
|
28
28
|
# Returns the story id (or ids).
|
29
29
|
# We extract the story id(s) from the branch name, so that, e.g.,
|
30
30
|
# the branch `add-markdown-support-6283185` gives story_id '6283185'.
|
31
|
-
# New as of version 0.7, we support multiple story ids in a single
|
31
|
+
# New as of version 0.7, we support multiple story ids in a single
|
32
32
|
# branch name, so that `add-markdown-support-6283185-3141592` can be used
|
33
33
|
# to update story 6283185 and story 3141592 simultaneously.
|
34
34
|
def story_ids
|
@@ -47,13 +47,14 @@ class Command
|
|
47
47
|
debug = args.delete('--debug')
|
48
48
|
command = command_class.new(args)
|
49
49
|
if debug
|
50
|
-
puts command.cmd
|
50
|
+
puts command.cmd
|
51
51
|
return 1
|
52
52
|
else
|
53
|
+
check_git_utils
|
53
54
|
command.run!
|
54
55
|
return 0
|
55
56
|
end
|
56
|
-
end
|
57
|
+
end
|
57
58
|
|
58
59
|
private
|
59
60
|
|
@@ -65,6 +66,15 @@ class Command
|
|
65
66
|
def argument_string(args)
|
66
67
|
args.inject([]) do |opts, opt|
|
67
68
|
opts << (opt =~ /^-/ ? opt : opt.inspect)
|
68
|
-
end.join(' ')
|
69
|
+
end.join(' ')
|
70
|
+
end
|
71
|
+
|
72
|
+
# Exits if the git-utils aren't installed.
|
73
|
+
def self.check_git_utils
|
74
|
+
if `which git-pull-request`.empty?
|
75
|
+
msg = "Install git-utils (https://github.com/mhartl/git-utils)"
|
76
|
+
$stderr.puts msg
|
77
|
+
exit 1
|
78
|
+
end
|
69
79
|
end
|
70
80
|
end
|
@@ -24,20 +24,16 @@ class StoryCommit < Command
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
# Returns the message for the story id(s) and action (if any).
|
27
28
|
def message
|
28
|
-
if
|
29
|
-
|
30
|
-
|
29
|
+
if finish?
|
30
|
+
label = "Finishes #{message_ids}"
|
31
|
+
elsif deliver?
|
32
|
+
label = "Delivers #{message_ids}"
|
31
33
|
else
|
32
|
-
|
33
|
-
label = "Finishes #{message_ids}"
|
34
|
-
elsif deliver?
|
35
|
-
label = "Delivers #{message_ids}"
|
36
|
-
else
|
37
|
-
label = message_ids
|
38
|
-
end
|
39
|
-
"[#{label}] #{options.message}"
|
34
|
+
label = message_ids
|
40
35
|
end
|
36
|
+
"[#{label}]"
|
41
37
|
end
|
42
38
|
|
43
39
|
# Returns the story ids formatted for story commits.
|
@@ -54,7 +50,8 @@ class StoryCommit < Command
|
|
54
50
|
def cmd
|
55
51
|
c = ['git commit']
|
56
52
|
c << '-a' if all?
|
57
|
-
c << %(-m "#{message}") if message?
|
53
|
+
c << %(-m "#{options.message}") if message?
|
54
|
+
c << %(-m "#{message}") unless story_ids.empty?
|
58
55
|
c << argument_string(unknown_options) unless unknown_options.empty?
|
59
56
|
c.join(' ')
|
60
57
|
end
|
@@ -9,9 +9,6 @@ class StoryPullRequest < FinishedCommand
|
|
9
9
|
opts.on("-f", "--force", "override unfinished story warning") do |opt|
|
10
10
|
self.options.force = opt
|
11
11
|
end
|
12
|
-
opts.on("-s", "--skip", "skip `git story-push`") do |opt|
|
13
|
-
self.options.skip = opt
|
14
|
-
end
|
15
12
|
opts.on_tail("-h", "--help", "this usage guide") do
|
16
13
|
puts opts.to_s; exit 0
|
17
14
|
end
|
@@ -21,11 +18,7 @@ class StoryPullRequest < FinishedCommand
|
|
21
18
|
# Returns a command appropriate for executing at the command line
|
22
19
|
# I.e., 'open https://www.pivotaltracker.com/story/show/6283185'
|
23
20
|
def cmd
|
24
|
-
|
25
|
-
"open #{uri}"
|
26
|
-
else
|
27
|
-
"git story-push && open #{uri}"
|
28
|
-
end
|
21
|
+
"git pull-request"
|
29
22
|
end
|
30
23
|
|
31
24
|
def uri
|
@@ -46,8 +39,4 @@ class StoryPullRequest < FinishedCommand
|
|
46
39
|
def origin_uri
|
47
40
|
remote_location.sub(/^git@(.+?):(.+)$/, 'https://\1/\2')
|
48
41
|
end
|
49
|
-
|
50
|
-
def skip?
|
51
|
-
options.skip
|
52
|
-
end
|
53
42
|
end
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe StoryCommit do
|
4
4
|
|
5
|
-
let(:command) { StoryCommit.new(['-m', '
|
5
|
+
let(:command) { StoryCommit.new(['-m', 'msg', '-a', '-z', '--foo']) }
|
6
6
|
before { command.stub(:story_branch).and_return('6283185-tau-manifesto') }
|
7
7
|
subject { command }
|
8
8
|
|
@@ -19,26 +19,26 @@ describe StoryCommit do
|
|
19
19
|
describe "parse" do
|
20
20
|
subject { command.options }
|
21
21
|
|
22
|
-
its(:message) { should == '
|
22
|
+
its(:message) { should == 'msg' }
|
23
23
|
its(:all) { should be_true }
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
27
|
describe "with only known options" do
|
28
|
-
let(:command) { StoryCommit.new(['-m', '
|
28
|
+
let(:command) { StoryCommit.new(['-m', 'msg', '-a']) }
|
29
29
|
it_should_behave_like "story-commit with known options"
|
30
30
|
end
|
31
31
|
|
32
32
|
describe "with a compound argument" do
|
33
|
-
let(:command) { StoryCommit.new(['-am', '
|
33
|
+
let(:command) { StoryCommit.new(['-am', 'msg']) }
|
34
34
|
it_should_behave_like "story-commit with known options"
|
35
35
|
end
|
36
36
|
|
37
37
|
describe "with some unknown options" do
|
38
|
-
let(:command) { StoryCommit.new(['-m', '
|
39
|
-
|
38
|
+
let(:command) { StoryCommit.new(['-m', 'msg', '-a', '-z', '--foo']) }
|
39
|
+
|
40
40
|
it_should_behave_like "story-commit with known options"
|
41
|
-
|
41
|
+
|
42
42
|
it "should not raise an error" do
|
43
43
|
expect { command.parse }.not_to raise_error(OptionParser::InvalidOption)
|
44
44
|
end
|
@@ -51,7 +51,7 @@ describe StoryCommit do
|
|
51
51
|
|
52
52
|
describe "command with message" do
|
53
53
|
its(:cmd) do
|
54
|
-
should == %(git commit -a -m "[##{command.story_id}]
|
54
|
+
should == %(git commit -a -m "msg" -m "[##{command.story_id}]" -z --foo)
|
55
55
|
end
|
56
56
|
|
57
57
|
describe "when used with branches containing multiple stories" do
|
@@ -60,21 +60,23 @@ describe StoryCommit do
|
|
60
60
|
end
|
61
61
|
its(:cmd) do
|
62
62
|
delivered_ids = '#6283185 #3141592'
|
63
|
-
should == %(git commit -a -m "[#{delivered_ids}]
|
63
|
+
should == %(git commit -a -m "msg" -m "[#{delivered_ids}]" -z --foo)
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
68
|
describe "command with no message" do
|
69
69
|
let(:command) { StoryCommit.new(['-a', '-z', '--foo']) }
|
70
|
-
its(:cmd)
|
70
|
+
its(:cmd) do
|
71
|
+
should == %(git commit -a -m "[##{command.story_id}]" -z --foo)
|
72
|
+
end
|
71
73
|
end
|
72
74
|
|
73
75
|
describe "command with finish flag" do
|
74
|
-
let(:command) { StoryCommit.new(['-m', '
|
76
|
+
let(:command) { StoryCommit.new(['-m', 'msg', '-f']) }
|
75
77
|
its(:cmd) do
|
76
|
-
should == %(git commit -m "[Finishes ##{command.story_id}]
|
77
|
-
end
|
78
|
+
should == %(git commit -m "msg" -m "[Finishes ##{command.story_id}]")
|
79
|
+
end
|
78
80
|
|
79
81
|
describe "when used with branches containing multiple stories" do
|
80
82
|
before do
|
@@ -82,15 +84,15 @@ describe StoryCommit do
|
|
82
84
|
end
|
83
85
|
its(:cmd) do
|
84
86
|
delivered_ids = '#6283185 #3141592'
|
85
|
-
should == %(git commit -m "[Finishes #{delivered_ids}]
|
87
|
+
should == %(git commit -m "msg" -m "[Finishes #{delivered_ids}]")
|
86
88
|
end
|
87
89
|
end
|
88
90
|
end
|
89
91
|
|
90
92
|
describe "command with deliver flag" do
|
91
|
-
let(:command) { StoryCommit.new(['-m', '
|
93
|
+
let(:command) { StoryCommit.new(['-m', 'msg', '-d']) }
|
92
94
|
its(:cmd) do
|
93
|
-
should == %(git commit -m "[Delivers ##{command.story_id}]
|
95
|
+
should == %(git commit -m "msg" -m "[Delivers ##{command.story_id}]")
|
94
96
|
end
|
95
97
|
|
96
98
|
describe "when used with branches containing multiple stories" do
|
@@ -99,7 +101,7 @@ describe StoryCommit do
|
|
99
101
|
end
|
100
102
|
its(:cmd) do
|
101
103
|
delivered_ids = '#6283185 #3141592'
|
102
|
-
should == %(git commit -m "[Delivers #{delivered_ids}]
|
104
|
+
should == %(git commit -m "msg" -m "[Delivers #{delivered_ids}]")
|
103
105
|
end
|
104
106
|
end
|
105
107
|
end
|
@@ -107,15 +109,15 @@ describe StoryCommit do
|
|
107
109
|
describe "command with no story id" do
|
108
110
|
before { command.stub(:story_branch).and_return('tau-manifesto') }
|
109
111
|
its(:cmd) do
|
110
|
-
should == %(git commit -a -m "
|
111
|
-
end
|
112
|
+
should == %(git commit -a -m "msg" -z --foo)
|
113
|
+
end
|
112
114
|
end
|
113
115
|
|
114
116
|
describe "command-line command" do
|
115
|
-
let(:command) { `bin/git-story-commit -a -m "
|
117
|
+
let(:command) { `bin/git-story-commit -a -m "msg" -z --debug` }
|
116
118
|
subject { command }
|
117
119
|
it { should =~ /git commit -a -m/ }
|
118
|
-
it { should =~ /
|
120
|
+
it { should =~ /msg/ }
|
119
121
|
it { should =~ /-z/ }
|
120
122
|
it { should_not =~ /--debug/ }
|
121
123
|
end
|
@@ -21,14 +21,14 @@ describe StoryMerge do
|
|
21
21
|
end
|
22
22
|
|
23
23
|
describe "with a custom development branch" do
|
24
|
-
let(:command) {
|
24
|
+
let(:command) { StoryMerge.new(['-d', 'develop']) }
|
25
25
|
its(:cmd) { should =~ /git checkout develop/ }
|
26
26
|
end
|
27
27
|
|
28
28
|
describe "with some unknown options" do
|
29
|
-
let(:command) {
|
29
|
+
let(:command) { StoryMerge.new(['-d', 'develop', '-a', '-z', '--foo']) }
|
30
30
|
it_should_behave_like "story-merge with known options"
|
31
|
-
its(:cmd) { should =~
|
31
|
+
its(:cmd) { should =~ /-a -z --foo/ }
|
32
32
|
end
|
33
33
|
|
34
34
|
describe "command-line command" do
|
@@ -10,8 +10,7 @@ describe StoryPullRequest do
|
|
10
10
|
end
|
11
11
|
subject { command }
|
12
12
|
|
13
|
-
its(:cmd) { should =~ /
|
14
|
-
its(:cmd) { should =~ /git story-push/ }
|
13
|
+
its(:cmd) { should =~ /git pull-request/ }
|
15
14
|
|
16
15
|
describe 'origin uri parsing' do
|
17
16
|
let(:correct_origin) { 'https://github.com/mhartl/foo' }
|
@@ -33,13 +32,7 @@ describe StoryPullRequest do
|
|
33
32
|
|
34
33
|
describe "command-line command" do
|
35
34
|
subject { `bin/git-story-pull-request --debug` }
|
36
|
-
it { should =~ /pull\/new/ }
|
37
35
|
it { should_not =~ /\.git/ }
|
38
|
-
it { should =~ /git
|
39
|
-
|
40
|
-
describe "with a skip option" do
|
41
|
-
subject { `bin/git-story-pull-request --skip --debug` }
|
42
|
-
it { should_not =~ /git story-push/ }
|
43
|
-
end
|
36
|
+
it { should =~ /git pull-request/ }
|
44
37
|
end
|
45
38
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pivotal-github
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-06-04 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Add commands for Pivotal Tracker-GitHub integration
|
15
15
|
email:
|
@@ -17,9 +17,7 @@ email:
|
|
17
17
|
executables:
|
18
18
|
- git-story-commit
|
19
19
|
- git-story-merge
|
20
|
-
- git-story-pull
|
21
20
|
- git-story-pull-request
|
22
|
-
- git-story-push
|
23
21
|
- story-open
|
24
22
|
extensions: []
|
25
23
|
extra_rdoc_files: []
|
@@ -34,9 +32,7 @@ files:
|
|
34
32
|
- Rakefile
|
35
33
|
- bin/git-story-commit
|
36
34
|
- bin/git-story-merge
|
37
|
-
- bin/git-story-pull
|
38
35
|
- bin/git-story-pull-request
|
39
|
-
- bin/git-story-push
|
40
36
|
- bin/story-open
|
41
37
|
- lib/pivotal-github.rb
|
42
38
|
- lib/pivotal-github/command.rb
|
@@ -45,9 +41,7 @@ files:
|
|
45
41
|
- lib/pivotal-github/story_commit.rb
|
46
42
|
- lib/pivotal-github/story_merge.rb
|
47
43
|
- lib/pivotal-github/story_open.rb
|
48
|
-
- lib/pivotal-github/story_pull.rb
|
49
44
|
- lib/pivotal-github/story_pull_request.rb
|
50
|
-
- lib/pivotal-github/story_push.rb
|
51
45
|
- lib/pivotal-github/version.rb
|
52
46
|
- pivotal-github.gemspec
|
53
47
|
- spec/commands/command_spec.rb
|
@@ -55,8 +49,6 @@ files:
|
|
55
49
|
- spec/commands/story_merge_spec.rb
|
56
50
|
- spec/commands/story_open_spec.rb
|
57
51
|
- spec/commands/story_pull_request_spec.rb
|
58
|
-
- spec/commands/story_pull_spec.rb
|
59
|
-
- spec/commands/story_push_spec.rb
|
60
52
|
- spec/options/options_spec.rb
|
61
53
|
- spec/spec_helper.rb
|
62
54
|
homepage: https://github.com/mhartl/pivotal-github
|
@@ -89,7 +81,5 @@ test_files:
|
|
89
81
|
- spec/commands/story_merge_spec.rb
|
90
82
|
- spec/commands/story_open_spec.rb
|
91
83
|
- spec/commands/story_pull_request_spec.rb
|
92
|
-
- spec/commands/story_pull_spec.rb
|
93
|
-
- spec/commands/story_push_spec.rb
|
94
84
|
- spec/options/options_spec.rb
|
95
85
|
- spec/spec_helper.rb
|
data/bin/git-story-pull
DELETED
data/bin/git-story-push
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
require 'pivotal-github/command'
|
2
|
-
|
3
|
-
class StoryPull < Command
|
4
|
-
|
5
|
-
def parser
|
6
|
-
OptionParser.new do |opts|
|
7
|
-
opts.banner = "Usage: git story-pull [options]"
|
8
|
-
opts.on("-d", "--development BRANCH",
|
9
|
-
"development branch (defaults to master)") do |opt|
|
10
|
-
self.options.development = opt
|
11
|
-
end
|
12
|
-
opts.on_tail("-h", "--help", "this usage guide") do
|
13
|
-
puts opts.to_s; exit 0
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
# Returns a command appropriate for executing at the command line
|
19
|
-
# For example:
|
20
|
-
# git checkout master
|
21
|
-
# git pull
|
22
|
-
# git checkout <story branch>
|
23
|
-
def cmd
|
24
|
-
lines = ["git checkout #{development_branch}"]
|
25
|
-
c = ['git pull']
|
26
|
-
c << argument_string(unknown_options) unless unknown_options.empty?
|
27
|
-
lines << c.join(' ')
|
28
|
-
lines << ["git checkout #{story_branch}"]
|
29
|
-
lines.join("\n")
|
30
|
-
end
|
31
|
-
|
32
|
-
def run!
|
33
|
-
system cmd
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def development_branch
|
39
|
-
options.development || 'master'
|
40
|
-
end
|
41
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
require 'pivotal-github/command'
|
2
|
-
|
3
|
-
class StoryPush < Command
|
4
|
-
|
5
|
-
def parser
|
6
|
-
OptionParser.new do |opts|
|
7
|
-
opts.banner = "Usage: git story-push [options]"
|
8
|
-
opts.on("-t", "--target TARGET",
|
9
|
-
"push to a given target (defaults to origin)") do |t|
|
10
|
-
self.options.target = t
|
11
|
-
end
|
12
|
-
opts.on_tail("-h", "--help", "this usage guide") do
|
13
|
-
puts opts.to_s; exit 0
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
# Returns a command appropriate for executing at the command line
|
19
|
-
def cmd
|
20
|
-
c = ['git push']
|
21
|
-
c << argument_string(unknown_options) unless unknown_options.empty?
|
22
|
-
c << target
|
23
|
-
c << story_branch
|
24
|
-
c.join(' ')
|
25
|
-
end
|
26
|
-
|
27
|
-
def run!
|
28
|
-
system cmd
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def target
|
34
|
-
options.target || 'origin'
|
35
|
-
end
|
36
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe StoryPull do
|
4
|
-
|
5
|
-
let(:command) { StoryPull.new }
|
6
|
-
before { command.stub(:story_branch).and_return('6283185-tau-manifesto') }
|
7
|
-
subject { command }
|
8
|
-
|
9
|
-
its(:cmd) { should =~ /git pull/ }
|
10
|
-
|
11
|
-
shared_examples "story-pull with known options" do
|
12
|
-
subject { command }
|
13
|
-
it "should not raise an error" do
|
14
|
-
expect { command.parse }.not_to raise_error(OptionParser::InvalidOption)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
describe "with no options" do
|
19
|
-
its(:cmd) { should =~ /git checkout master/ }
|
20
|
-
its(:cmd) { should =~ /git pull/ }
|
21
|
-
its(:cmd) { should =~ /git checkout #{command.story_branch}/ }
|
22
|
-
end
|
23
|
-
|
24
|
-
describe "with a custom development branch" do
|
25
|
-
let(:command) { StoryPull.new(['-d', 'develop']) }
|
26
|
-
its(:cmd) { should =~ /git checkout develop/ }
|
27
|
-
end
|
28
|
-
|
29
|
-
describe "with some unknown options" do
|
30
|
-
let(:command) { StoryPull.new(['-d', 'develop', '-a', '-z', '--foo']) }
|
31
|
-
it_should_behave_like "story-pull with known options"
|
32
|
-
its(:cmd) { should =~ /git pull -a -z --foo/ }
|
33
|
-
end
|
34
|
-
|
35
|
-
describe "command-line command" do
|
36
|
-
subject { `bin/git-story-pull --debug -z -d develop` }
|
37
|
-
it { should =~ /git checkout develop/ }
|
38
|
-
it { should =~ /git pull -z/ }
|
39
|
-
end
|
40
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe StoryPush do
|
4
|
-
|
5
|
-
let(:command) { StoryPush.new }
|
6
|
-
before { command.stub(:story_branch).and_return('6283185-tau-manifesto') }
|
7
|
-
subject { command }
|
8
|
-
|
9
|
-
its(:cmd) { should =~ /git push/ }
|
10
|
-
|
11
|
-
shared_examples "story-push with known options" do
|
12
|
-
subject { command }
|
13
|
-
it "should not raise an error" do
|
14
|
-
expect { command.parse }.not_to raise_error(OptionParser::InvalidOption)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
describe "with no options" do
|
19
|
-
its(:cmd) { should == "git push origin #{command.story_branch}" }
|
20
|
-
end
|
21
|
-
|
22
|
-
describe "with a target option" do
|
23
|
-
let(:command) { StoryPush.new(['-t', 'heroku']) }
|
24
|
-
its(:cmd) { should =~ /git push heroku/ }
|
25
|
-
end
|
26
|
-
|
27
|
-
describe "with some unknown options" do
|
28
|
-
let(:command) { StoryPush.new(['-p', 'develop', '-a', '-z', '--foo']) }
|
29
|
-
it_should_behave_like "story-push with known options"
|
30
|
-
its(:cmd) { should =~ /-a -z --foo/ }
|
31
|
-
end
|
32
|
-
|
33
|
-
describe "command-line command" do
|
34
|
-
subject { `bin/git-story-push --debug -z -t heroku` }
|
35
|
-
it { should =~ /git push -z heroku/ }
|
36
|
-
end
|
37
|
-
end
|