github-pivotal-flow 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.
- data/README.md +3 -1
- data/lib/github_pivotal_flow/git.rb +15 -6
- data/lib/github_pivotal_flow/story.rb +11 -12
- data/spec/github_pivotal_flow/finish_spec.rb +19 -12
- data/spec/github_pivotal_flow/git_spec.rb +25 -11
- data/spec/github_pivotal_flow/start_spec.rb +26 -14
- data/spec/github_pivotal_flow/story_spec.rb +123 -99
- metadata +48 -14
- checksums.yaml +0 -7
data/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Github Pivotal Flow
|
|
2
2
|
|
|
3
|
+
<img src="https://travis-ci.org/roomorama/github-pivotal-flow.png" data-bindattr-34="34" title="Build Status Images">
|
|
4
|
+
|
|
3
5
|
`github-pivotal-flow` provides a set of additional Git commands to help developers when working with [Pivotal Tracker][pivotal-tracker], git-flow and Github pull requests.
|
|
4
6
|
It follows the branch structure recommended by [Git flow][git-flow].
|
|
5
7
|
|
|
@@ -9,7 +11,7 @@ This is the tool we use internally to speed up our development process.
|
|
|
9
11
|
[git-flow]: https://github.com/nvie/gitflow
|
|
10
12
|
|
|
11
13
|
## Installation
|
|
12
|
-
`github-pivotal-flow` requires at least **Ruby 1.
|
|
14
|
+
`github-pivotal-flow` requires at least **Ruby 1.9.3**, **Git 1.8.2.1** in order to run. It is tested against Rubies _1.9.3_, _2.0.0_ and _2.1.0_. In order to install it, do the following:
|
|
13
15
|
|
|
14
16
|
```plain
|
|
15
17
|
$ gem install github-pivotal-flow
|
|
@@ -50,10 +50,12 @@ module GithubPivotalFlow
|
|
|
50
50
|
puts 'OK'
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
-
def self.publish(branch_name)
|
|
53
|
+
def self.publish(branch_name, options = {})
|
|
54
54
|
branch_name ||= self.current_branch
|
|
55
55
|
exec "git checkout --quiet #{branch_name}" unless branch_name == self.current_branch
|
|
56
|
-
|
|
56
|
+
command = "git push"
|
|
57
|
+
|
|
58
|
+
exec "#{command} #{self.get_remote} #{branch_name}"
|
|
57
59
|
end
|
|
58
60
|
|
|
59
61
|
def self.commit(options = {})
|
|
@@ -79,10 +81,16 @@ module GithubPivotalFlow
|
|
|
79
81
|
end
|
|
80
82
|
|
|
81
83
|
def self.push(*refs)
|
|
84
|
+
options = {}
|
|
85
|
+
if refs.last.is_a?(Hash)
|
|
86
|
+
options = refs.delete_at(-1)
|
|
87
|
+
end
|
|
82
88
|
remote = self.get_remote
|
|
83
89
|
|
|
84
90
|
print "Pushing to #{remote}... "
|
|
85
|
-
|
|
91
|
+
command = "git push --quiet"
|
|
92
|
+
command << " -u" if options[:set_upstream]
|
|
93
|
+
exec "#{command} #{remote} " + refs.join(' ')
|
|
86
94
|
puts 'OK'
|
|
87
95
|
end
|
|
88
96
|
|
|
@@ -126,9 +134,6 @@ module GithubPivotalFlow
|
|
|
126
134
|
def self.add_hook(name, source, overwrite = false)
|
|
127
135
|
hooks_directory = File.join repository_root, '.git', 'hooks'
|
|
128
136
|
hook = File.join hooks_directory, name
|
|
129
|
-
puts "Overwrite: #{overwrite}"
|
|
130
|
-
puts "Hook: #{hook}"
|
|
131
|
-
puts "File.exists?: #{File.exist?(hook)}"
|
|
132
137
|
if overwrite || !File.exist?(hook)
|
|
133
138
|
print "Creating Git hook #{name}... "
|
|
134
139
|
|
|
@@ -145,6 +150,10 @@ module GithubPivotalFlow
|
|
|
145
150
|
end
|
|
146
151
|
|
|
147
152
|
private
|
|
153
|
+
def self.escape_commit_message(message)
|
|
154
|
+
message.gsub('"', '\"').sub(/!\z/, '! ')
|
|
155
|
+
end
|
|
156
|
+
|
|
148
157
|
def self.exec(command, abort_on_failure = true)
|
|
149
158
|
return Shell.exec(command, abort_on_failure)
|
|
150
159
|
end
|
|
@@ -77,9 +77,9 @@ module GithubPivotalFlow
|
|
|
77
77
|
puts 'OK'
|
|
78
78
|
end
|
|
79
79
|
|
|
80
|
-
def create_branch!(commit_message = nil)
|
|
80
|
+
def create_branch!(commit_message = nil, options = {})
|
|
81
81
|
commit_message ||= "Starting [#{story.story_type} ##{story.id}]: #{story.name}"
|
|
82
|
-
|
|
82
|
+
commit_message << " [ci skip]" unless options[:run_ci]
|
|
83
83
|
print "Creating branch for story with branch name #{branch_name} from #{root_branch_name}... "
|
|
84
84
|
Git.checkout(root_branch_name)
|
|
85
85
|
root_origin = Git.get_remote
|
|
@@ -89,7 +89,7 @@ module GithubPivotalFlow
|
|
|
89
89
|
Git.set_config('root-branch', root_branch_name, :branch)
|
|
90
90
|
Git.set_config('root-remote', root_origin, :branch)
|
|
91
91
|
Git.commit(commit_message: commit_message, allow_empty: true)
|
|
92
|
-
Git.
|
|
92
|
+
Git.push(branch_name, set_upstream: true)
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
def merge_to_root!(commit_message = nil, options = {})
|
|
@@ -100,7 +100,7 @@ module GithubPivotalFlow
|
|
|
100
100
|
Git.pull_remote(root_branch_name)
|
|
101
101
|
Git.merge(branch_name, commit_message: commit_message, no_ff: true)
|
|
102
102
|
self.delete_branch!
|
|
103
|
-
Git.
|
|
103
|
+
Git.push(root_branch_name)
|
|
104
104
|
self.cleanup!
|
|
105
105
|
end
|
|
106
106
|
|
|
@@ -118,8 +118,7 @@ module GithubPivotalFlow
|
|
|
118
118
|
Git.merge(branch_name, commit_message: commit_message, no_ff: true)
|
|
119
119
|
Git.checkout(master_branch_name)
|
|
120
120
|
self.delete_branch!
|
|
121
|
-
Git.
|
|
122
|
-
Git.publish(development_branch_name)
|
|
121
|
+
Git.push(master_branch_name, root_branch_name)
|
|
123
122
|
Git.push_tags
|
|
124
123
|
self.cleanup!
|
|
125
124
|
end
|
|
@@ -138,8 +137,12 @@ module GithubPivotalFlow
|
|
|
138
137
|
# Shell.exec("hub pull-request -m \"#{self.name}\n\n#{self.description}\" -b #{root_branch_name} -h #{branch_name}")
|
|
139
138
|
#end
|
|
140
139
|
|
|
141
|
-
def
|
|
142
|
-
@
|
|
140
|
+
def branch_name
|
|
141
|
+
@branch_name ||= branch_name_from(branch_prefix, story.id, branch_suffix)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def branch_suffix
|
|
145
|
+
@branch_suffix ||= ask("Enter branch name (#{branch_name_from(branch_prefix, story.id, "<branch-name>")}): ")
|
|
143
146
|
end
|
|
144
147
|
|
|
145
148
|
def branch_name_from(branch_prefix, story_id, branch_name)
|
|
@@ -153,10 +156,6 @@ module GithubPivotalFlow
|
|
|
153
156
|
end
|
|
154
157
|
end
|
|
155
158
|
|
|
156
|
-
def branch_name
|
|
157
|
-
@branch_name ||= branch_name_from(branch_prefix, story.id, @branch_suffix)
|
|
158
|
-
end
|
|
159
|
-
|
|
160
159
|
def root_branch_name
|
|
161
160
|
case story_type
|
|
162
161
|
when 'chore'
|
|
@@ -9,27 +9,34 @@ module GithubPivotalFlow
|
|
|
9
9
|
|
|
10
10
|
@project = double('project')
|
|
11
11
|
@story = double('story')
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
@configuration = double('configuration')
|
|
13
|
+
@configuration.stub(
|
|
14
|
+
development_branch: 'development',
|
|
15
|
+
master_branch: 'master',
|
|
16
|
+
feature_prefix: 'feature/',
|
|
17
|
+
hotfix_prefix: 'hotfix/',
|
|
18
|
+
release_prefix: 'release/',
|
|
19
|
+
api_token: 'token',
|
|
20
|
+
project_id: '123',
|
|
21
|
+
story: @story)
|
|
22
|
+
allow(Git).to receive(:repository_root)
|
|
23
|
+
allow(Configuration).to receive(:new).and_return(@configuration)
|
|
24
|
+
allow(PivotalTracker::Project).to receive(:find).and_return(@project)
|
|
16
25
|
@finish = Finish.new
|
|
17
26
|
end
|
|
18
27
|
|
|
19
28
|
it 'merges the branch back to its root by default' do
|
|
20
|
-
|
|
21
|
-
@story.
|
|
22
|
-
@story.
|
|
23
|
-
@story.should_receive(:merge_to_root!)
|
|
29
|
+
expect(@story).to receive(:release?).and_return(false)
|
|
30
|
+
expect(@story).to receive(:can_merge?).and_return(true)
|
|
31
|
+
expect(@story).to receive(:merge_to_root!).and_return(nil)
|
|
24
32
|
|
|
25
33
|
@finish.run!
|
|
26
34
|
end
|
|
27
35
|
|
|
28
36
|
it 'merges as a release instead if it is a release branch' do
|
|
29
|
-
|
|
30
|
-
@story.
|
|
31
|
-
@story.
|
|
32
|
-
@story.should_receive(:merge_release!)
|
|
37
|
+
expect(@story).to receive(:release?).and_return(true)
|
|
38
|
+
expect(@story).to receive(:can_merge?).and_return(true)
|
|
39
|
+
expect(@story).to receive(:merge_release!)
|
|
33
40
|
|
|
34
41
|
@finish.run!
|
|
35
42
|
end
|
|
@@ -4,13 +4,13 @@ module GithubPivotalFlow
|
|
|
4
4
|
describe Git do
|
|
5
5
|
|
|
6
6
|
before do
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
$stdout = StringIO.new
|
|
8
|
+
$stderr = StringIO.new
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
describe '.current_branch' do
|
|
12
12
|
it 'returns the current branch name' do
|
|
13
|
-
Shell.
|
|
13
|
+
expect(Shell).to receive(:exec).with('git branch', true).and_return(" master\n * dev_branch")
|
|
14
14
|
|
|
15
15
|
current_branch = Git.current_branch
|
|
16
16
|
|
|
@@ -85,7 +85,7 @@ module GithubPivotalFlow
|
|
|
85
85
|
end
|
|
86
86
|
|
|
87
87
|
it 'sets configuration when :local scope is specified' do
|
|
88
|
-
Shell.
|
|
88
|
+
expect(Shell).to receive(:exec).with('git config --local test_key test_value', true)
|
|
89
89
|
|
|
90
90
|
Git.set_config 'test_key', 'test_value', :local
|
|
91
91
|
end
|
|
@@ -109,10 +109,10 @@ module GithubPivotalFlow
|
|
|
109
109
|
Dir.mktmpdir do |root|
|
|
110
110
|
Git.should_receive(:repository_root).and_return(root)
|
|
111
111
|
hook = "#{root}/.git/hooks/prepare-commit-msg"
|
|
112
|
-
File.
|
|
112
|
+
expect(File).to receive(:exist?).with(hook).and_return(true)
|
|
113
113
|
|
|
114
114
|
Git.add_hook 'prepare-commit-msg', __FILE__
|
|
115
|
-
File.
|
|
115
|
+
expect(File).to receive(:exist?).and_call_original
|
|
116
116
|
expect(File.exist?(hook)).to be_false
|
|
117
117
|
end
|
|
118
118
|
end
|
|
@@ -121,11 +121,11 @@ module GithubPivotalFlow
|
|
|
121
121
|
Dir.mktmpdir do |root|
|
|
122
122
|
Git.should_receive(:repository_root).and_return(root)
|
|
123
123
|
hook = "#{root}/.git/hooks/prepare-commit-msg"
|
|
124
|
-
File.should_receive(:exist?).with(hook).and_return(false)
|
|
124
|
+
#File.should_receive(:exist?).with(hook).and_return(false)
|
|
125
|
+
expect(File).to receive(:exist?).with(hook).and_return(false)
|
|
125
126
|
|
|
126
127
|
Git.add_hook 'prepare-commit-msg', __FILE__
|
|
127
|
-
|
|
128
|
-
File.should_receive(:exist?).and_call_original
|
|
128
|
+
expect(File).to receive(:exist?).with(hook).and_call_original
|
|
129
129
|
expect(File.exist?(hook)).to be_true
|
|
130
130
|
end
|
|
131
131
|
end
|
|
@@ -152,19 +152,27 @@ module GithubPivotalFlow
|
|
|
152
152
|
end
|
|
153
153
|
|
|
154
154
|
describe '.push' do
|
|
155
|
-
|
|
155
|
+
before do
|
|
156
156
|
Git.should_receive(:get_config).with('remote', :branch).and_return('origin')
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it 'pushes changes back to the origin without refs' do
|
|
157
160
|
Shell.should_receive(:exec).with('git push --quiet origin ', true)
|
|
158
161
|
|
|
159
162
|
Git.push
|
|
160
163
|
end
|
|
161
164
|
|
|
162
165
|
it 'pushes changes back to the origin with refs' do
|
|
163
|
-
Git.should_receive(:get_config).with('remote', :branch).and_return('origin')
|
|
164
166
|
Shell.should_receive(:exec).with('git push --quiet origin foo bar', true)
|
|
165
167
|
|
|
166
168
|
Git.push 'foo', 'bar'
|
|
167
169
|
end
|
|
170
|
+
|
|
171
|
+
it 'supports passing in the set_upstream option after a ref' do
|
|
172
|
+
Shell.should_receive(:exec).with('git push --quiet -u origin foo', true)
|
|
173
|
+
|
|
174
|
+
Git.push 'foo', set_upstream: true
|
|
175
|
+
end
|
|
168
176
|
end
|
|
169
177
|
|
|
170
178
|
describe '.commit' do
|
|
@@ -173,6 +181,12 @@ module GithubPivotalFlow
|
|
|
173
181
|
|
|
174
182
|
Git.commit commit_message: 'test_message', allow_empty: true
|
|
175
183
|
end
|
|
184
|
+
|
|
185
|
+
it 'correctly escapes quotes for the commit message' do
|
|
186
|
+
expect(Shell).to receive(:exec).with(%Q(git commit --quiet --allow-empty -m "It's a \"hard\" not life"), true)
|
|
187
|
+
|
|
188
|
+
Git.commit commit_message: "It's a \"hard\" not life", allow_empty: true
|
|
189
|
+
end
|
|
176
190
|
end
|
|
177
191
|
|
|
178
192
|
describe '.tag' do
|
|
@@ -9,25 +9,37 @@ module GithubPivotalFlow
|
|
|
9
9
|
@project = double('project')
|
|
10
10
|
@story = double('story')
|
|
11
11
|
@ghclient = double('ghclient')
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
@ghproject = double('ghproject')
|
|
13
|
+
@configuration = double('configuration')
|
|
14
|
+
@configuration.stub(
|
|
15
|
+
development_branch: 'development',
|
|
16
|
+
master_branch: 'master',
|
|
17
|
+
feature_prefix: 'feature/',
|
|
18
|
+
hotfix_prefix: 'hotfix/',
|
|
19
|
+
release_prefix: 'release/',
|
|
20
|
+
api_token: 'token',
|
|
21
|
+
project_id: '123',
|
|
22
|
+
github_project: @ghproject,
|
|
23
|
+
story: @story)
|
|
24
|
+
allow(Git).to receive(:repository_root)
|
|
25
|
+
allow(GitHubAPI).to receive(:new).and_return(@ghclient)
|
|
26
|
+
allow(Configuration).to receive(:new).and_return(@configuration)
|
|
27
|
+
allow(PivotalTracker::Project).to receive(:find).and_return(@project)
|
|
17
28
|
@start = Start.new()
|
|
18
29
|
end
|
|
19
30
|
|
|
20
31
|
it 'should run' do
|
|
21
32
|
@start.options[:args] = 'test_filter'
|
|
22
|
-
@story.stub(:unestimated? => false, :release? => false)
|
|
23
|
-
|
|
24
|
-
Story.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
Git.
|
|
28
|
-
@
|
|
29
|
-
|
|
30
|
-
@
|
|
33
|
+
@story.stub(:unestimated? => false, :release? => false, params_for_pull_request: {})
|
|
34
|
+
|
|
35
|
+
expect(Story).to receive(:select_story).with(@project, 'test_filter').and_return(@story)
|
|
36
|
+
expect(Story).to receive(:pretty_print)
|
|
37
|
+
expect(@story).to receive(:create_branch!)
|
|
38
|
+
expect(Git).to receive(:add_hook)
|
|
39
|
+
expect(@configuration).to receive(:story=).with(@story).and_return(true)
|
|
40
|
+
#@story.should_receive(:params_for_pull_request).and_return({})
|
|
41
|
+
expect(@ghclient).to receive(:create_pullrequest)
|
|
42
|
+
expect(@story).to receive(:mark_started!)
|
|
31
43
|
|
|
32
44
|
@start.run!
|
|
33
45
|
end
|
|
@@ -13,113 +13,137 @@ module GithubPivotalFlow
|
|
|
13
13
|
@menu = double('menu')
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
16
|
+
describe '.pretty_print' do
|
|
17
|
+
it 'pretty-prints story information' do
|
|
18
|
+
story = double('story')
|
|
19
|
+
story.should_receive(:name)
|
|
20
|
+
story.should_receive(:description).and_return("description-1\ndescription-2")
|
|
21
|
+
PivotalTracker::Note.should_receive(:all).and_return([
|
|
22
|
+
PivotalTracker::Note.new(:noted_at => Date.new, :text => 'note-1')
|
|
23
|
+
])
|
|
24
|
+
|
|
25
|
+
Story.pretty_print story
|
|
26
|
+
|
|
27
|
+
expect($stdout.string).to eq(
|
|
28
|
+
" Title: \n" +
|
|
29
|
+
"Description: description-1\n" +
|
|
30
|
+
" description-2\n" +
|
|
31
|
+
" Note 1: note-1\n" +
|
|
32
|
+
"\n")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'does not pretty print description or notes if there are none (empty)' do
|
|
36
|
+
story = double('story')
|
|
37
|
+
story.should_receive(:name)
|
|
38
|
+
story.should_receive(:description)
|
|
39
|
+
PivotalTracker::Note.should_receive(:all).and_return([])
|
|
40
|
+
|
|
41
|
+
Story.pretty_print story
|
|
42
|
+
|
|
43
|
+
expect($stdout.string).to eq(
|
|
44
|
+
" Title: \n" +
|
|
45
|
+
"\n")
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'does not pretty print description or notes if there are none (nil)' do
|
|
49
|
+
story = double('story')
|
|
50
|
+
story.should_receive(:name)
|
|
51
|
+
story.should_receive(:description).and_return('')
|
|
52
|
+
PivotalTracker::Note.should_receive(:all).and_return([])
|
|
53
|
+
|
|
54
|
+
Story.pretty_print story
|
|
55
|
+
|
|
56
|
+
expect($stdout.string).to eq(
|
|
57
|
+
" Title: \n" +
|
|
58
|
+
"\n")
|
|
59
|
+
end
|
|
32
60
|
end
|
|
33
61
|
|
|
34
|
-
|
|
35
|
-
story
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
62
|
+
describe '.select_story' do
|
|
63
|
+
it 'selects a story directly if the filter is a number' do
|
|
64
|
+
@project.should_receive(:stories).and_return(@stories)
|
|
65
|
+
@stories.should_receive(:find).with(12345678).and_return(@story)
|
|
66
|
+
|
|
67
|
+
story = Story.select_story @project, '12345678'
|
|
68
|
+
|
|
69
|
+
expect(story).to be_a(Story)
|
|
70
|
+
expect(story.story).to be(@story)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'selects a story if the result of the query is a single story' do
|
|
74
|
+
@project.should_receive(:stories).and_return(@stories)
|
|
75
|
+
@stories.should_receive(:all).with(
|
|
76
|
+
:current_state => %w(rejected unstarted unscheduled),
|
|
77
|
+
:limit => 1,
|
|
78
|
+
:story_type => 'release'
|
|
79
|
+
).and_return([@story])
|
|
80
|
+
|
|
81
|
+
story = Story.select_story @project, 'release', 1
|
|
82
|
+
|
|
83
|
+
expect(story).to be_a(Story)
|
|
84
|
+
expect(story.story).to be(@story)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it 'prompts the user for a story if the result of the query is more than a single story' do
|
|
88
|
+
@project.should_receive(:stories).and_return(@stories)
|
|
89
|
+
@stories.should_receive(:all).with(
|
|
90
|
+
:current_state => %w(rejected unstarted unscheduled),
|
|
91
|
+
:limit => 5,
|
|
92
|
+
:story_type => 'feature'
|
|
93
|
+
).and_return([
|
|
94
|
+
PivotalTracker::Story.new(:name => 'name-1'),
|
|
95
|
+
PivotalTracker::Story.new(:name => 'name-2')
|
|
96
|
+
])
|
|
97
|
+
@menu.should_receive(:prompt=)
|
|
98
|
+
@menu.should_receive(:choice).with('name-1')
|
|
99
|
+
@menu.should_receive(:choice).with('name-2')
|
|
100
|
+
Story.should_receive(:choose) { |&arg| arg.call @menu }.and_return(@story)
|
|
101
|
+
|
|
102
|
+
story = Story.select_story @project, 'feature'
|
|
103
|
+
|
|
104
|
+
expect(story).to be_a(Story)
|
|
105
|
+
expect(story.story).to be(@story)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it 'prompts the user with the story type if no filter is specified' do
|
|
109
|
+
@project.should_receive(:stories).and_return(@stories)
|
|
110
|
+
@stories.should_receive(:all).with(
|
|
111
|
+
:current_state => %w(rejected unstarted unscheduled),
|
|
112
|
+
:limit => 5
|
|
113
|
+
).and_return([
|
|
114
|
+
PivotalTracker::Story.new(:story_type => 'chore', :name => 'name-1'),
|
|
115
|
+
PivotalTracker::Story.new(:story_type => 'bug', :name => 'name-2')
|
|
116
|
+
])
|
|
117
|
+
@menu.should_receive(:prompt=)
|
|
118
|
+
@menu.should_receive(:choice).with('CHORE name-1')
|
|
119
|
+
@menu.should_receive(:choice).with('BUG name-2')
|
|
120
|
+
Story.should_receive(:choose) { |&arg| arg.call @menu }.and_return(@story)
|
|
121
|
+
|
|
122
|
+
story = Story.select_story @project
|
|
123
|
+
|
|
124
|
+
expect(story).to be_a(Story)
|
|
125
|
+
expect(story.story).to be(@story)
|
|
126
|
+
end
|
|
58
127
|
end
|
|
59
128
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
129
|
+
describe '#create_branch!' do
|
|
130
|
+
before do
|
|
131
|
+
@story.stub(story_type: 'feature', id: '123456', name: 'test', description: 'description')
|
|
132
|
+
end
|
|
63
133
|
|
|
64
|
-
|
|
134
|
+
it 'includes a tag to skip the ci build for the initial blank commit' do
|
|
135
|
+
Git.stub(checkout: nil, pull_remote: nil, create_branch: nil, set_config: nil, push: nil)
|
|
136
|
+
Git.should_receive(:commit).with(hash_including(commit_message: 'Message [ci skip]')).and_return(true)
|
|
65
137
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
it 'should select a story if the result of the query is a single story' do
|
|
71
|
-
@project.should_receive(:stories).and_return(@stories)
|
|
72
|
-
@stories.should_receive(:all).with(
|
|
73
|
-
:current_state => %w(rejected unstarted unscheduled),
|
|
74
|
-
:limit => 1,
|
|
75
|
-
:story_type => 'release'
|
|
76
|
-
).and_return([@story])
|
|
77
|
-
|
|
78
|
-
story = Story.select_story @project, 'release', 1
|
|
138
|
+
Story.new(@story).create_branch!('Message')
|
|
139
|
+
end
|
|
79
140
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
it 'should prompt the user for a story if the result of the query is more than a single story' do
|
|
85
|
-
@project.should_receive(:stories).and_return(@stories)
|
|
86
|
-
@stories.should_receive(:all).with(
|
|
87
|
-
:current_state => %w(rejected unstarted unscheduled),
|
|
88
|
-
:limit => 5,
|
|
89
|
-
:story_type => 'feature'
|
|
90
|
-
).and_return([
|
|
91
|
-
PivotalTracker::Story.new(:name => 'name-1'),
|
|
92
|
-
PivotalTracker::Story.new(:name => 'name-2')
|
|
93
|
-
])
|
|
94
|
-
@menu.should_receive(:prompt=)
|
|
95
|
-
@menu.should_receive(:choice).with('name-1')
|
|
96
|
-
@menu.should_receive(:choice).with('name-2')
|
|
97
|
-
Story.should_receive(:choose) { |&arg| arg.call @menu }.and_return(@story)
|
|
98
|
-
|
|
99
|
-
story = Story.select_story @project, 'feature'
|
|
100
|
-
|
|
101
|
-
expect(story).to be_a(Story)
|
|
102
|
-
expect(story.story).to be(@story)
|
|
103
|
-
end
|
|
141
|
+
it 'pushes the local branch and sets the upstream using the -u flag' do
|
|
142
|
+
Git.stub(checkout: nil, pull_remote: nil, create_branch: nil, set_config: nil, commit: nil)
|
|
143
|
+
Git.should_receive(:push).with(instance_of(String), hash_including(set_upstream: true))
|
|
104
144
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
@stories.should_receive(:all).with(
|
|
108
|
-
:current_state => %w(rejected unstarted unscheduled),
|
|
109
|
-
:limit => 5
|
|
110
|
-
).and_return([
|
|
111
|
-
PivotalTracker::Story.new(:story_type => 'chore', :name => 'name-1'),
|
|
112
|
-
PivotalTracker::Story.new(:story_type => 'bug', :name => 'name-2')
|
|
113
|
-
])
|
|
114
|
-
@menu.should_receive(:prompt=)
|
|
115
|
-
@menu.should_receive(:choice).with('CHORE name-1')
|
|
116
|
-
@menu.should_receive(:choice).with('BUG name-2')
|
|
117
|
-
Story.should_receive(:choose) { |&arg| arg.call @menu }.and_return(@story)
|
|
118
|
-
|
|
119
|
-
story = Story.select_story @project
|
|
120
|
-
|
|
121
|
-
expect(story).to be_a(Story)
|
|
122
|
-
expect(story.story).to be(@story)
|
|
145
|
+
Story.new(@story).create_branch!('Message')
|
|
146
|
+
end
|
|
123
147
|
end
|
|
124
148
|
end
|
|
125
149
|
end
|
metadata
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: github-pivotal-flow
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.7
|
|
5
|
+
prerelease:
|
|
5
6
|
platform: ruby
|
|
6
7
|
authors:
|
|
7
8
|
- Donald Piret
|
|
8
9
|
autorequire:
|
|
9
10
|
bindir: bin
|
|
10
11
|
cert_chain: []
|
|
11
|
-
date: 2014-01-
|
|
12
|
+
date: 2014-01-22 00:00:00.000000000 Z
|
|
12
13
|
dependencies:
|
|
13
14
|
- !ruby/object:Gem::Dependency
|
|
14
15
|
name: highline
|
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
|
17
|
+
none: false
|
|
16
18
|
requirements:
|
|
17
19
|
- - ~>
|
|
18
20
|
- !ruby/object:Gem::Version
|
|
@@ -20,6 +22,7 @@ dependencies:
|
|
|
20
22
|
type: :runtime
|
|
21
23
|
prerelease: false
|
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
23
26
|
requirements:
|
|
24
27
|
- - ~>
|
|
25
28
|
- !ruby/object:Gem::Version
|
|
@@ -27,6 +30,7 @@ dependencies:
|
|
|
27
30
|
- !ruby/object:Gem::Dependency
|
|
28
31
|
name: pivotal-tracker
|
|
29
32
|
requirement: !ruby/object:Gem::Requirement
|
|
33
|
+
none: false
|
|
30
34
|
requirements:
|
|
31
35
|
- - ~>
|
|
32
36
|
- !ruby/object:Gem::Version
|
|
@@ -34,6 +38,7 @@ dependencies:
|
|
|
34
38
|
type: :runtime
|
|
35
39
|
prerelease: false
|
|
36
40
|
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
37
42
|
requirements:
|
|
38
43
|
- - ~>
|
|
39
44
|
- !ruby/object:Gem::Version
|
|
@@ -41,6 +46,7 @@ dependencies:
|
|
|
41
46
|
- !ruby/object:Gem::Dependency
|
|
42
47
|
name: bundler
|
|
43
48
|
requirement: !ruby/object:Gem::Requirement
|
|
49
|
+
none: false
|
|
44
50
|
requirements:
|
|
45
51
|
- - ~>
|
|
46
52
|
- !ruby/object:Gem::Version
|
|
@@ -48,6 +54,7 @@ dependencies:
|
|
|
48
54
|
type: :development
|
|
49
55
|
prerelease: false
|
|
50
56
|
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
none: false
|
|
51
58
|
requirements:
|
|
52
59
|
- - ~>
|
|
53
60
|
- !ruby/object:Gem::Version
|
|
@@ -55,6 +62,7 @@ dependencies:
|
|
|
55
62
|
- !ruby/object:Gem::Dependency
|
|
56
63
|
name: rake
|
|
57
64
|
requirement: !ruby/object:Gem::Requirement
|
|
65
|
+
none: false
|
|
58
66
|
requirements:
|
|
59
67
|
- - ~>
|
|
60
68
|
- !ruby/object:Gem::Version
|
|
@@ -62,6 +70,7 @@ dependencies:
|
|
|
62
70
|
type: :development
|
|
63
71
|
prerelease: false
|
|
64
72
|
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
+
none: false
|
|
65
74
|
requirements:
|
|
66
75
|
- - ~>
|
|
67
76
|
- !ruby/object:Gem::Version
|
|
@@ -69,6 +78,7 @@ dependencies:
|
|
|
69
78
|
- !ruby/object:Gem::Dependency
|
|
70
79
|
name: redcarpet
|
|
71
80
|
requirement: !ruby/object:Gem::Requirement
|
|
81
|
+
none: false
|
|
72
82
|
requirements:
|
|
73
83
|
- - ~>
|
|
74
84
|
- !ruby/object:Gem::Version
|
|
@@ -76,6 +86,7 @@ dependencies:
|
|
|
76
86
|
type: :development
|
|
77
87
|
prerelease: false
|
|
78
88
|
version_requirements: !ruby/object:Gem::Requirement
|
|
89
|
+
none: false
|
|
79
90
|
requirements:
|
|
80
91
|
- - ~>
|
|
81
92
|
- !ruby/object:Gem::Version
|
|
@@ -83,20 +94,39 @@ dependencies:
|
|
|
83
94
|
- !ruby/object:Gem::Dependency
|
|
84
95
|
name: rspec
|
|
85
96
|
requirement: !ruby/object:Gem::Requirement
|
|
97
|
+
none: false
|
|
86
98
|
requirements:
|
|
87
99
|
- - ~>
|
|
88
100
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: '2.
|
|
101
|
+
version: '2.14'
|
|
90
102
|
type: :development
|
|
91
103
|
prerelease: false
|
|
92
104
|
version_requirements: !ruby/object:Gem::Requirement
|
|
105
|
+
none: false
|
|
93
106
|
requirements:
|
|
94
107
|
- - ~>
|
|
95
108
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: '2.
|
|
109
|
+
version: '2.14'
|
|
110
|
+
- !ruby/object:Gem::Dependency
|
|
111
|
+
name: rspec-mocks
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
113
|
+
none: false
|
|
114
|
+
requirements:
|
|
115
|
+
- - ~>
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '2.14'
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
none: false
|
|
122
|
+
requirements:
|
|
123
|
+
- - ~>
|
|
124
|
+
- !ruby/object:Gem::Version
|
|
125
|
+
version: '2.14'
|
|
97
126
|
- !ruby/object:Gem::Dependency
|
|
98
127
|
name: simplecov
|
|
99
128
|
requirement: !ruby/object:Gem::Requirement
|
|
129
|
+
none: false
|
|
100
130
|
requirements:
|
|
101
131
|
- - ~>
|
|
102
132
|
- !ruby/object:Gem::Version
|
|
@@ -104,6 +134,7 @@ dependencies:
|
|
|
104
134
|
type: :development
|
|
105
135
|
prerelease: false
|
|
106
136
|
version_requirements: !ruby/object:Gem::Requirement
|
|
137
|
+
none: false
|
|
107
138
|
requirements:
|
|
108
139
|
- - ~>
|
|
109
140
|
- !ruby/object:Gem::Version
|
|
@@ -111,6 +142,7 @@ dependencies:
|
|
|
111
142
|
- !ruby/object:Gem::Dependency
|
|
112
143
|
name: yard
|
|
113
144
|
requirement: !ruby/object:Gem::Requirement
|
|
145
|
+
none: false
|
|
114
146
|
requirements:
|
|
115
147
|
- - ~>
|
|
116
148
|
- !ruby/object:Gem::Version
|
|
@@ -118,6 +150,7 @@ dependencies:
|
|
|
118
150
|
type: :development
|
|
119
151
|
prerelease: false
|
|
120
152
|
version_requirements: !ruby/object:Gem::Requirement
|
|
153
|
+
none: false
|
|
121
154
|
requirements:
|
|
122
155
|
- - ~>
|
|
123
156
|
- !ruby/object:Gem::Version
|
|
@@ -133,20 +166,20 @@ extra_rdoc_files: []
|
|
|
133
166
|
files:
|
|
134
167
|
- LICENSE
|
|
135
168
|
- README.md
|
|
136
|
-
- bin/git-finish
|
|
137
|
-
- bin/git-start
|
|
138
169
|
- lib/core_ext/object/blank.rb
|
|
139
|
-
- lib/github_pivotal_flow.rb
|
|
140
170
|
- lib/github_pivotal_flow/command.rb
|
|
141
171
|
- lib/github_pivotal_flow/configuration.rb
|
|
142
172
|
- lib/github_pivotal_flow/finish.rb
|
|
143
173
|
- lib/github_pivotal_flow/git.rb
|
|
144
174
|
- lib/github_pivotal_flow/github_api.rb
|
|
145
|
-
- lib/github_pivotal_flow/prepare-commit-msg.sh
|
|
146
175
|
- lib/github_pivotal_flow/project.rb
|
|
147
176
|
- lib/github_pivotal_flow/shell.rb
|
|
148
177
|
- lib/github_pivotal_flow/start.rb
|
|
149
178
|
- lib/github_pivotal_flow/story.rb
|
|
179
|
+
- lib/github_pivotal_flow.rb
|
|
180
|
+
- lib/github_pivotal_flow/prepare-commit-msg.sh
|
|
181
|
+
- bin/git-finish
|
|
182
|
+
- bin/git-start
|
|
150
183
|
- spec/github_pivotal_flow/configuration_spec.rb
|
|
151
184
|
- spec/github_pivotal_flow/finish_spec.rb
|
|
152
185
|
- spec/github_pivotal_flow/git_spec.rb
|
|
@@ -156,26 +189,27 @@ files:
|
|
|
156
189
|
homepage: https://github.com/roomorama/github-pivotal-flow
|
|
157
190
|
licenses:
|
|
158
191
|
- MIT
|
|
159
|
-
metadata: {}
|
|
160
192
|
post_install_message:
|
|
161
193
|
rdoc_options: []
|
|
162
194
|
require_paths:
|
|
163
195
|
- lib
|
|
164
196
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
197
|
+
none: false
|
|
165
198
|
requirements:
|
|
166
|
-
- - '>='
|
|
199
|
+
- - ! '>='
|
|
167
200
|
- !ruby/object:Gem::Version
|
|
168
|
-
version: 1.
|
|
201
|
+
version: 1.9.3
|
|
169
202
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
203
|
+
none: false
|
|
170
204
|
requirements:
|
|
171
|
-
- - '>='
|
|
205
|
+
- - ! '>='
|
|
172
206
|
- !ruby/object:Gem::Version
|
|
173
207
|
version: '0'
|
|
174
208
|
requirements: []
|
|
175
209
|
rubyforge_project:
|
|
176
|
-
rubygems_version:
|
|
210
|
+
rubygems_version: 1.8.23
|
|
177
211
|
signing_key:
|
|
178
|
-
specification_version:
|
|
212
|
+
specification_version: 3
|
|
179
213
|
summary: Git commands for integration with Pivotal Tracker and Github pull requests
|
|
180
214
|
test_files:
|
|
181
215
|
- spec/github_pivotal_flow/configuration_spec.rb
|
checksums.yaml
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
SHA1:
|
|
3
|
-
metadata.gz: 96f8e674edd44441caf0dd7f407730f55a171a3f
|
|
4
|
-
data.tar.gz: 97b78ad1be19763ce08bbedfec0b4b3794e906f6
|
|
5
|
-
SHA512:
|
|
6
|
-
metadata.gz: d8036b44e6e88d57b2bfa537bdf51ebe9e83e5b5d1864f5915e246bdedc7bd9be19ee987c7a7d0a949dae5ecdf7fbf0c448c5c28e15396cf6ca449488d49e09e
|
|
7
|
-
data.tar.gz: a213f34c076c60a34debc78964cf218a9853370d437e3b7151f6dfd3b39c525ed45aff464cd44c62da559a9ae19a778a06bfc7303009b108cec8b8e46cef59a1
|