github-pivotal-flow 0.2.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 96c3e7ec554233e7990b6a64f15f0d35503d5927
4
- data.tar.gz: 94ed6f85456f4b63b47fe10318d22fa7786f00dc
3
+ metadata.gz: 899947a9ef6741e50d2fcec85f2fc9bbe0b8c402
4
+ data.tar.gz: c085c1c245c4b4a5bdcee3ca0eaa191bf06393b5
5
5
  SHA512:
6
- metadata.gz: 121a7ad7681ec313e1670db59a7e8c5683f926e3241326f61a9854b6d0036fb4a89984e73f7246242a46bf4e6cc895acd2db2e93734483097e9d4754a3328894
7
- data.tar.gz: 183f9dc438715c9b1cc8cc22079fc5c3f3db01f8014ee6f754bd245351067db92413866772e13a8de0bcc24583c99f985e4fe9ea62071b994f5b0fd759bcee99
6
+ metadata.gz: 63f8b8d5e05b61e09f4158224d8981aee3d8ce705ee8adbe2e5ede68c4158fb3aed51fc01d1f9229a481a52ec4a5cbad85de8e464a4683d796197fb18e85fe98
7
+ data.tar.gz: d6384a6ec33fc24e493d1c3edd5ea71d04d3c3a81300cb3a08bd7e67d82f03c956d569f5397c0f9429f99048bc93df8cba231dc01aec4f65fc2049bf273afbd8
data/README.md CHANGED
@@ -27,6 +27,7 @@ $ git start # Creates branch, opens a pull request on Github and starts st
27
27
  $ git commit ...
28
28
  $ git commit ... # Your existing development process
29
29
  $ git commit ...
30
+ $ git publish ... # Push the branch out to origin and open a pull request on github to gather some feedback
30
31
  $ git finish # Merges back into the main branch. Pushes to origin, destroys branch and finishes story.
31
32
  ```
32
33
 
@@ -119,6 +120,10 @@ If it doesn't exist already, a `prepare-commit-msg` commit hook is added to your
119
120
  #
120
121
  ```
121
122
 
123
+ ### `git publish`
124
+ This command pushes your changes back to the origin, and opens a pull request on Github for your branch.
125
+
126
+
122
127
  ### `git finish [--no-complete]`
123
128
  This command finishes a story by merging and cleaning up its branch and then pushing the changes to a remote server.
124
129
  This command can be run in two ways. First it can be run without the `--no-complete` option.
data/bin/git-publish ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby -U
2
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
3
+
4
+ require 'github_pivotal_flow'
5
+
6
+ exit GithubPivotalFlow::Publish.new(*ARGV).run!
@@ -44,4 +44,5 @@ require File.join('github_pivotal_flow', 'github_api')
44
44
  require File.join('github_pivotal_flow', 'story')
45
45
  require File.join('github_pivotal_flow', 'command')
46
46
  require File.join('github_pivotal_flow', 'start')
47
+ require File.join('github_pivotal_flow', 'publish')
47
48
  require File.join('github_pivotal_flow', 'finish')
@@ -0,0 +1,32 @@
1
+ # The class that encapsulates finishing a Pivotal Tracker Story
2
+ module GithubPivotalFlow
3
+ class Publish < Command
4
+
5
+ # Publishes the branch and opens the pull request
6
+ def run!
7
+ story = @configuration.story
8
+ fail("Could not find story associated with branch") unless story
9
+ Git.clean_working_tree?
10
+ Git.push(story.branch_name, set_upstream: true)
11
+ unless story.release?
12
+ print "Creating pull-request on Github... "
13
+ pull_request_params = story.params_for_pull_request.merge(project: @configuration.project)
14
+ @configuration.github_client.create_pullrequest(pull_request_params)
15
+ puts 'OK'
16
+ end
17
+ return 0
18
+ end
19
+
20
+ private
21
+
22
+ def parse_argv(*args)
23
+ OptionParser.new do |opts|
24
+ opts.banner = "Usage: git publish [options]"
25
+ opts.on("-t", "--api-token=", "Pivotal Tracker API key") { |k| options[:api_token] = k }
26
+ opts.on("-p", "--project-id=", "Pivotal Tracker project id") { |p| options[:project_id] = p }
27
+
28
+ opts.on_tail("-h", "--help", "This usage guide") { put opts.to_s; exit 0 }
29
+ end.parse!(args)
30
+ end
31
+ end
32
+ end
@@ -10,12 +10,6 @@ module GithubPivotalFlow
10
10
  story.create_branch!
11
11
  @configuration.story = story # Tag the branch with story attributes
12
12
  Git.add_hook 'prepare-commit-msg', File.join(File.dirname(__FILE__), 'prepare-commit-msg.sh')
13
- unless story.release?
14
- print "Creating pull-request on Github... "
15
- pull_request_params = story.params_for_pull_request.merge(project: @configuration.project)
16
- @configuration.github_client.create_pullrequest(pull_request_params)
17
- puts 'OK'
18
- end
19
13
  story.mark_started!
20
14
  return 0
21
15
  end
@@ -91,7 +91,6 @@ module GithubPivotalFlow
91
91
  Git.set_config('root-branch', root_branch_name, :branch)
92
92
  Git.set_config('root-remote', root_origin, :branch)
93
93
  Git.commit(commit_message: commit_message, allow_empty: true)
94
- Git.push(branch_name, set_upstream: true)
95
94
  end
96
95
 
97
96
  def merge_to_root!(commit_message = nil, options = {})
@@ -164,8 +163,8 @@ module GithubPivotalFlow
164
163
  # For release branches the format is release/5.0
165
164
  "#{Git.get_config(KEY_RELEASE_PREFIX, :inherited)}#{branch_name}"
166
165
  else
167
- n = "#{branch_prefix}#{story_id}"
168
- n << "-#{branch_name}" unless branch_name.blank?
166
+ n = "#{branch_prefix}"
167
+ n << "#{branch_name}" unless branch_name.blank?
169
168
  n
170
169
  end
171
170
  end
@@ -1,3 +1,3 @@
1
1
  module GithubPivotalFlow
2
- VERSION = '0.2.0'
2
+ VERSION = '1.0.0'
3
3
  end
@@ -5,15 +5,10 @@ module GithubPivotalFlow
5
5
  before do
6
6
  $stdout = StringIO.new
7
7
  $stderr = StringIO.new
8
- @configuration = double('configuration')
9
8
  @project = double('project')
9
+ @configuration = double('configuration', validate: true, project_id: 123456, project: @project)
10
10
  allow(Configuration).to receive(:new).and_return(@configuration)
11
11
  allow(PivotalTracker::Project).to receive(:find).and_return(@project)
12
- @configuration.stub(
13
- validate: true,
14
- project_id: 123456,
15
- project: @project,
16
- )
17
12
  end
18
13
 
19
14
  describe '#initialize' do
@@ -16,7 +16,7 @@ module GithubPivotalFlow
16
16
 
17
17
  describe '#api_token' do
18
18
  it 'does not prompt the user for the API token if it is already configured' do
19
- Git.should_receive(:get_config).with('pivotal.api-token', :inherited).and_return('test_api_token')
19
+ expect(Git).to receive(:get_config).with('pivotal.api-token', :inherited).and_return('test_api_token')
20
20
 
21
21
  api_token = @configuration.api_token
22
22
 
@@ -24,9 +24,9 @@ module GithubPivotalFlow
24
24
  end
25
25
 
26
26
  it 'prompts the user for the API token if it is not configured and stores it in the local git config' do
27
- Git.should_receive(:get_config).with('pivotal.api-token', :inherited).and_return('')
28
- @configuration.should_receive(:ask).and_return('test_api_token')
29
- Git.should_receive(:set_config).with('pivotal.api-token', 'test_api_token', :local)
27
+ expect(Git).to receive(:get_config).with('pivotal.api-token', :inherited).and_return('')
28
+ expect(@configuration).to receive(:ask).and_return('test_api_token')
29
+ expect(Git).to receive(:set_config).with('pivotal.api-token', 'test_api_token', :local)
30
30
  api_token = @configuration.api_token
31
31
  expect(api_token).to eq('test_api_token')
32
32
  end
@@ -34,22 +34,22 @@ module GithubPivotalFlow
34
34
 
35
35
  describe '#project_id' do
36
36
  it 'does not prompt the user for the project id if it is already configured' do
37
- Git.should_receive(:get_config).with('pivotal.project-id', :inherited).and_return('test_project_id')
37
+ expect(Git).to receive(:get_config).with('pivotal.project-id', :inherited).and_return('test_project_id')
38
38
  project_id = @configuration.project_id
39
39
  expect(project_id).to eq('test_project_id')
40
40
  end
41
41
 
42
42
  it 'prompts the user for the project id if it is not configured' do
43
- Git.should_receive(:get_config).with('pivotal.project-id', :inherited).and_return('')
43
+ expect(Git).to receive(:get_config).with('pivotal.project-id', :inherited).and_return('')
44
44
  menu = double('menu')
45
- menu.should_receive(:prompt=)
46
- PivotalTracker::Project.should_receive(:all).and_return([
45
+ expect(menu).to receive(:prompt=)
46
+ expect(PivotalTracker::Project).to receive(:all).and_return([
47
47
  PivotalTracker::Project.new(:id => 'id-2', :name => 'name-2'),
48
48
  PivotalTracker::Project.new(:id => 'id-1', :name => 'name-1')])
49
- menu.should_receive(:choice).with('name-1')
50
- menu.should_receive(:choice).with('name-2')
51
- @configuration.should_receive(:choose) { |&arg| arg.call menu }.and_return('test_project_id')
52
- Git.should_receive(:set_config).with('pivotal.project-id', 'test_project_id', :local)
49
+ expect(menu).to receive(:choice).with('name-1')
50
+ expect(menu).to receive(:choice).with('name-2')
51
+ expect(@configuration).to receive(:choose) { |&arg| arg.call menu }.and_return('test_project_id')
52
+ expect(Git).to receive(:set_config).with('pivotal.project-id', 'test_project_id', :local)
53
53
 
54
54
  project_id = @configuration.project_id
55
55
 
@@ -86,7 +86,7 @@ module GithubPivotalFlow
86
86
  end
87
87
 
88
88
  it 'uses the branch name to deduce the story id if no git config is found' do
89
- Git.stub(:current_branch).and_return('feature/12345678-sample_feature')
89
+ allow(Git).to receive(:current_branch).and_return('feature/12345678-sample_feature')
90
90
  expect(Git).to receive(:get_config).with('pivotal-story-id', :branch).and_return(' ')
91
91
  expect(project).to receive(:stories).and_return(stories)
92
92
  expect(stories).to receive(:find).with(12345678).and_return(pivotal_story)
@@ -97,7 +97,7 @@ module GithubPivotalFlow
97
97
  end
98
98
 
99
99
  it 'prompts for the story id if the branch name does not match the known format' do
100
- Git.stub(:current_branch).and_return('unknownformat')
100
+ allow(Git).to receive(:current_branch).and_return('unknownformat')
101
101
  expect(Git).to receive(:get_config).with('pivotal-story-id', :branch).and_return(' ')
102
102
  expect(@configuration).to receive(:ask).and_return('12345678')
103
103
  expect(Git).to receive(:set_config).with('pivotal-story-id', '12345678', :branch)
@@ -112,8 +112,8 @@ module GithubPivotalFlow
112
112
 
113
113
  describe '#project' do
114
114
  it 'supports working with git urls from the configuration' do
115
- Git.should_receive(:get_remote).and_return('origin')
116
- Git.should_receive(:get_config).with('remote.origin.url').and_return('git@github.com:roomorama/github-pivotal-flow.git')
115
+ expect(Git).to receive(:get_remote).and_return('origin')
116
+ expect(Git).to receive(:get_config).with('remote.origin.url').and_return('git@github.com:roomorama/github-pivotal-flow.git')
117
117
  project = @configuration.project
118
118
  expect(project.owner).to eq('roomorama')
119
119
  expect(project.name).to eq('github-pivotal-flow')
@@ -9,19 +9,18 @@ module GithubPivotalFlow
9
9
 
10
10
  @project = double('project')
11
11
  @story = double('story', branch_name: 'feature/1234-sample_story')
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
- project: @project,
22
- github_client: @ghclient,
23
- story: @story,
24
- validate: true,
12
+ @configuration = double('configuration',
13
+ development_branch: 'development',
14
+ master_branch: 'master',
15
+ feature_prefix: 'feature/',
16
+ hotfix_prefix: 'hotfix/',
17
+ release_prefix: 'release/',
18
+ api_token: 'token',
19
+ project_id: '123',
20
+ project: @project,
21
+ github_client: @ghclient,
22
+ story: @story,
23
+ validate: true
25
24
  )
26
25
  allow(Configuration).to receive(:new).and_return(@configuration)
27
26
  allow(Project).to receive(:find).and_return(@project)
@@ -27,7 +27,7 @@ module GithubPivotalFlow
27
27
  git_directory = File.expand_path '.git', root
28
28
  Dir.mkdir git_directory
29
29
 
30
- Dir.should_receive(:pwd).and_return(child_directory)
30
+ expect(Dir).to receive(:pwd).and_return(child_directory)
31
31
 
32
32
  repository_root = Git.repository_root
33
33
 
@@ -40,7 +40,7 @@ module GithubPivotalFlow
40
40
  child_directory = File.expand_path 'child', root
41
41
  Dir.mkdir child_directory
42
42
 
43
- Dir.should_receive(:pwd).and_return(child_directory)
43
+ expect(Dir).to receive(:pwd).and_return(child_directory)
44
44
 
45
45
  expect { Git.repository_root }.to raise_error
46
46
  end
@@ -49,8 +49,8 @@ module GithubPivotalFlow
49
49
 
50
50
  describe '.get_config' do
51
51
  it 'gets configuration scoped by branch when :branch scope is specified' do
52
- Git.should_receive(:current_branch).and_return('test_branch_name')
53
- Shell.should_receive(:exec).with('git config branch.test_branch_name.test_key', false).and_return('test_value')
52
+ expect(Git).to receive(:current_branch).and_return('test_branch_name')
53
+ expect(Shell).to receive(:exec).with('git config branch.test_branch_name.test_key', false).and_return('test_value')
54
54
 
55
55
  value = Git.get_config 'test_key', :branch
56
56
 
@@ -58,7 +58,7 @@ module GithubPivotalFlow
58
58
  end
59
59
 
60
60
  it 'gets configuration when :inherited scope is specified' do
61
- Shell.should_receive(:exec).with('git config test_key', false).and_return('test_value')
61
+ expect(Shell).to receive(:exec).with('git config test_key', false).and_return('test_value')
62
62
 
63
63
  value = Git.get_config 'test_key', :inherited
64
64
 
@@ -72,14 +72,14 @@ module GithubPivotalFlow
72
72
 
73
73
  describe '.set_config' do
74
74
  it 'sets configuration when :branch scope is specified' do
75
- Git.should_receive(:current_branch).and_return('test_branch_name')
76
- Shell.should_receive(:exec).with('git config --local branch.test_branch_name.test_key test_value', true)
75
+ expect(Git).to receive(:current_branch).and_return('test_branch_name')
76
+ expect(Shell).to receive(:exec).with('git config --local branch.test_branch_name.test_key test_value', true)
77
77
 
78
78
  Git.set_config 'test_key', 'test_value', :branch
79
79
  end
80
80
 
81
81
  it 'sets configuration when :global scope is specified' do
82
- Shell.should_receive(:exec).with('git config --global test_key test_value', true)
82
+ expect(Shell).to receive(:exec).with('git config --global test_key test_value', true)
83
83
 
84
84
  Git.set_config 'test_key', 'test_value', :global
85
85
  end
@@ -97,55 +97,54 @@ module GithubPivotalFlow
97
97
 
98
98
  describe '.create_branch' do
99
99
  it 'creates a branch' do
100
- Git.stub(:current_branch).and_return('master')
101
- Shell.should_receive(:exec).with('git branch --quiet dev_branch', true)
100
+ allow(Git).to receive(:current_branch).and_return('master')
101
+ expect(Shell).to receive(:exec).with('git branch --quiet dev_branch', true)
102
102
  Git.create_branch 'dev_branch'
103
103
  end
104
104
  end
105
105
 
106
- #FIXME: Can't seem to set an expectation on File for some reason...
107
106
  describe '.add_hook' do
108
107
  it 'does not add a hook if it already exists' do
109
108
  Dir.mktmpdir do |root|
110
- Git.should_receive(:repository_root).and_return(root)
109
+ expect(Git).to receive(:repository_root).and_return(root)
111
110
  hook = "#{root}/.git/hooks/prepare-commit-msg"
112
111
  expect(File).to receive(:exist?).with(hook).and_return(true)
113
112
 
114
113
  Git.add_hook 'prepare-commit-msg', __FILE__
115
114
  allow(File).to receive(:exist?).and_call_original
116
- expect(File.exist?(hook)).to be_false
115
+ expect(File.exist?(hook)).to be_falsy
117
116
  end
118
117
  end
119
118
 
120
119
  it 'adds a hook if it does not exist' do
121
120
  Dir.mktmpdir do |root|
122
- Git.should_receive(:repository_root).and_return(root)
121
+ expect(Git).to receive(:repository_root).and_return(root)
123
122
  hook = "#{root}/.git/hooks/prepare-commit-msg"
124
123
  #File.should_receive(:exist?).with(hook).and_return(false)
125
124
  expect(File).to receive(:exist?).with(hook).and_return(false)
126
125
 
127
126
  Git.add_hook 'prepare-commit-msg', __FILE__
128
127
  expect(File).to receive(:exist?).with(hook).and_call_original
129
- expect(File.exist?(hook)).to be_true
128
+ expect(File.exist?(hook)).to be_truthy
130
129
  end
131
130
  end
132
131
 
133
132
  it 'adds a hook if it already exists and overwrite is true' do
134
133
  Dir.mktmpdir do |root|
135
- Git.should_receive(:repository_root).and_return(root)
134
+ expect(Git).to receive(:repository_root).and_return(root)
136
135
  hook = "#{root}/.git/hooks/prepare-commit-msg"
137
136
 
138
137
  Git.add_hook 'prepare-commit-msg', __FILE__, true
139
138
 
140
- File.should_receive(:exist?).and_call_original
141
- expect(File.exist?(hook)).to be_true
139
+ expect(File).to receive(:exist?).and_call_original
140
+ expect(File.exist?(hook)).to be_truthy
142
141
  end
143
142
  end
144
143
  end
145
144
 
146
145
  describe '.merge' do
147
146
  it 'merges branches' do
148
- Shell.should_receive(:exec).with("git merge --quiet --no-ff -m \"Merge development_branch to master\" development_branch", true)
147
+ expect(Shell).to receive(:exec).with("git merge --quiet --no-ff -m \"Merge development_branch to master\" development_branch", true)
149
148
 
150
149
  Git.merge 'development_branch', commit_message: 'Merge development_branch to master', no_ff: true
151
150
  end
@@ -153,23 +152,23 @@ module GithubPivotalFlow
153
152
 
154
153
  describe '.push' do
155
154
  before do
156
- Git.should_receive(:get_config).with('remote', :branch).and_return('origin')
155
+ expect(Git).to receive(:get_config).with('remote', :branch).and_return('origin')
157
156
  end
158
157
 
159
158
  it 'pushes changes back to the origin without refs' do
160
- Shell.should_receive(:exec).with('git push --quiet origin ', true)
159
+ expect(Shell).to receive(:exec).with('git push --quiet origin ', true)
161
160
 
162
161
  Git.push
163
162
  end
164
163
 
165
164
  it 'pushes changes back to the origin with refs' do
166
- Shell.should_receive(:exec).with('git push --quiet origin foo bar', true)
165
+ expect(Shell).to receive(:exec).with('git push --quiet origin foo bar', true)
167
166
 
168
167
  Git.push 'foo', 'bar'
169
168
  end
170
169
 
171
170
  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)
171
+ expect(Shell).to receive(:exec).with('git push --quiet -u origin foo', true)
173
172
 
174
173
  Git.push 'foo', set_upstream: true
175
174
  end
@@ -177,7 +176,7 @@ module GithubPivotalFlow
177
176
 
178
177
  describe '.commit' do
179
178
  it 'creates a commit' do
180
- Shell.should_receive(:exec).with("git commit --quiet --allow-empty -m \"test_message\"", true)
179
+ expect(Shell).to receive(:exec).with("git commit --quiet --allow-empty -m \"test_message\"", true)
181
180
 
182
181
  Git.commit commit_message: 'test_message', allow_empty: true
183
182
  end
@@ -191,7 +190,7 @@ module GithubPivotalFlow
191
190
 
192
191
  describe '.tag' do
193
192
  it 'creates a tag' do
194
- Shell.should_receive(:exec).with('git tag 1.0.0.RELEASE', true)
193
+ expect(Shell).to receive(:exec).with('git tag 1.0.0.RELEASE', true)
195
194
 
196
195
  Git.tag '1.0.0.RELEASE'
197
196
  end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ module GithubPivotalFlow
4
+ describe Publish do
5
+ before do
6
+ $stdout = StringIO.new
7
+ $stderr = StringIO.new
8
+
9
+ @project = double('project')
10
+ @story = double('story',
11
+ branch_name: 'feature/1234-sample_story',
12
+ release?: false,
13
+ params_for_pull_request: {})
14
+ @ghclient = double('ghclient')
15
+ @ghproject = double('ghproject')
16
+ @configuration = double('configuration',
17
+ development_branch: 'development',
18
+ master_branch: 'master',
19
+ feature_prefix: 'feature/',
20
+ hotfix_prefix: 'hotfix/',
21
+ release_prefix: 'release/',
22
+ api_token: 'token',
23
+ project_id: '123',
24
+ project: @project,
25
+ github_client: @ghclient,
26
+ story: @story,
27
+ validate: true
28
+ )
29
+ allow(Configuration).to receive(:new).and_return(@configuration)
30
+ allow(Project).to receive(:find).and_return(@project)
31
+ allow(@ghclient).to receive(:create_pullrequest).and_return(true)
32
+ allow(Git).to receive(:push).and_return(true)
33
+ @publish = Publish.new
34
+ end
35
+
36
+ it 'fails if we cannot find the story this branch relates to' do
37
+ allow(@configuration).to receive(:story).and_return(nil)
38
+ expect { @publish.run! }.to raise_error("Could not find story associated with branch")
39
+ end
40
+
41
+ it 'fails with a dirty working tree' do
42
+ allow(Shell).to receive(:exec).with("git diff --no-ext-diff --ignore-submodules --quiet --exit-code", false).and_return(true)
43
+ allow(Shell).to receive(:exec).with("git diff-index --cached --quiet --ignore-submodules HEAD --", false).and_raise "fatal: Index contains uncommited changes. Aborting."
44
+ expect { @publish.run! }.to raise_error(RuntimeError)
45
+ end
46
+
47
+ context 'with a clean working tree' do
48
+ before do
49
+ allow(Git).to receive(:clean_working_tree?).and_return(true)
50
+
51
+ end
52
+
53
+ it 'pushes the branch back to the origin and sets the upstream' do
54
+ expect(Git).to receive(:push).with(instance_of(String), hash_including(set_upstream: true)).and_return(true)
55
+
56
+ @publish.run!
57
+ end
58
+
59
+ it 'opens a pull request' do
60
+ expect(@ghclient).to receive(:create_pullrequest).and_return(true)
61
+
62
+ @publish.run!
63
+ end
64
+ end
65
+ end
66
+ end
@@ -9,8 +9,8 @@ module GithubPivotalFlow
9
9
  end
10
10
 
11
11
  it 'should return result when exit code is 0' do
12
- Shell.should_receive(:`).with('test_command').and_return('test_result')
13
- $?.should_receive(:exitstatus).and_return(0)
12
+ expect(Shell).to receive(:`).with('test_command').and_return('test_result')
13
+ expect($?).to receive(:exitstatus).and_return(0)
14
14
 
15
15
  result = Shell.exec 'test_command'
16
16
 
@@ -18,17 +18,17 @@ module GithubPivotalFlow
18
18
  end
19
19
 
20
20
  it "should abort with 'FAIL' when the exit code is not 0" do
21
- Shell.should_receive(:`).with('test_command')
22
- $?.should_receive(:exitstatus).and_return(-1)
21
+ expect(Shell).to receive(:`).with('test_command')
22
+ expect($?).to receive(:exitstatus).and_return(-1)
23
23
 
24
- lambda { Shell.exec 'test_command' }.should raise_error(SystemExit)
24
+ expect { Shell.exec 'test_command' }.to raise_error
25
25
 
26
26
  expect($stderr.string).to match(/FAIL/)
27
27
  end
28
28
 
29
29
  it 'should return result when the exit code is not 0 and told not to abort on failure' do
30
- Shell.should_receive(:`).with('test_command')
31
- $?.should_receive(:exitstatus).and_return(-1)
30
+ expect(Shell).to receive(:`).with('test_command')
31
+ expect($?).to receive(:exitstatus).and_return(-1)
32
32
 
33
33
  Shell.exec 'test_command', false
34
34
  end
@@ -5,46 +5,79 @@ module GithubPivotalFlow
5
5
  before do
6
6
  $stdout = StringIO.new
7
7
  $stderr = StringIO.new
8
- @story = double('story')
9
- @project = double('project')
10
- @project.stub(
11
- stories: [@story]
8
+ @story = double('story',
9
+ unestimated?: false,
10
+ release?: false
11
+ )
12
+ @project = double('project',
13
+ stories: [@story]
12
14
  )
13
15
  @ghclient = double('ghclient')
14
16
  @ghproject = double('ghproject')
15
- @configuration = double('configuration')
16
- @configuration.stub(
17
- development_branch: 'development',
18
- master_branch: 'master',
19
- feature_prefix: 'feature/',
20
- hotfix_prefix: 'hotfix/',
21
- release_prefix: 'release/',
22
- api_token: 'token',
23
- project_id: '123',
24
- project: @project,
25
- github_client: @ghclient,
26
- story: @story,
27
- validate: true,
17
+ @configuration = double('configuration',
18
+ development_branch: 'development',
19
+ master_branch: 'master',
20
+ feature_prefix: 'feature/',
21
+ hotfix_prefix: 'hotfix/',
22
+ release_prefix: 'release/',
23
+ api_token: 'token',
24
+ project_id: '123',
25
+ project: @project,
26
+ github_client: @ghclient,
27
+ story: @story,
28
+ validate: true
28
29
  )
29
30
  allow(Configuration).to receive(:new).and_return(@configuration)
30
31
  allow(PivotalTracker::Project).to receive(:find).and_return(@project)
32
+ allow(@story).to receive(:create_branch!).and_return(true)
33
+ allow(Git).to receive(:add_hook)
34
+ allow(@configuration).to receive(:story=).with(@story).and_return(true)
35
+ allow(@story).to receive(:mark_started!)
31
36
  @start = Start.new()
32
37
  end
33
38
 
34
- it 'should runs correctly' do
39
+ it 'selects the story and pretty prints out the options' do
35
40
  @start.options[:args] = 'test_filter'
36
- @story.stub(:unestimated? => false, :release? => false, params_for_pull_request: {})
37
-
38
41
  expect(Story).to receive(:select_story).with(@project, 'test_filter').and_return(@story)
39
42
  expect(Story).to receive(:pretty_print)
40
- expect(@story).to receive(:create_branch!)
41
- expect(Git).to receive(:add_hook)
42
- expect(@configuration).to receive(:story=).with(@story).and_return(true)
43
- #@story.should_receive(:params_for_pull_request).and_return({})
44
- expect(@ghclient).to receive(:create_pullrequest)
45
- expect(@story).to receive(:mark_started!)
46
43
 
47
44
  @start.run!
48
45
  end
46
+
47
+ context 'with a story selected' do
48
+ before do
49
+ @start.options[:args] = 'test_filter'
50
+ allow(Story).to receive(:select_story).with(@project, 'test_filter').and_return(@story)
51
+ allow(Story).to receive(:pretty_print)
52
+ end
53
+
54
+ it 'should runs correctly' do
55
+ @start.run!
56
+ end
57
+
58
+ it 'creates the branch for the story' do
59
+ expect(@story).to receive(:create_branch!)
60
+
61
+ @start.run!
62
+ end
63
+
64
+ it 'adds the Git hook' do
65
+ expect(Git).to receive(:add_hook)
66
+
67
+ @start.run!
68
+ end
69
+
70
+ it 'stores the current story in the configuration' do
71
+ expect(@configuration).to receive(:story=).with(@story).and_return(true)
72
+
73
+ @start.run!
74
+ end
75
+
76
+ it 'marks the story as started in tracker' do
77
+ expect(@story).to receive(:mark_started!)
78
+
79
+ @start.run!
80
+ end
81
+ end
49
82
  end
50
83
  end
@@ -19,9 +19,9 @@ module GithubPivotalFlow
19
19
  describe '.pretty_print' do
20
20
  it 'pretty-prints story information' do
21
21
  story = double('story')
22
- story.should_receive(:name)
23
- story.should_receive(:description).and_return("description-1\ndescription-2")
24
- PivotalTracker::Note.should_receive(:all).and_return([PivotalTracker::Note.new(:noted_at => Date.new, :text => 'note-1')])
22
+ expect(story).to receive(:name)
23
+ expect(story).to receive(:description).and_return("description-1\ndescription-2")
24
+ expect(PivotalTracker::Note).to receive(:all).and_return([PivotalTracker::Note.new(:noted_at => Date.new, :text => 'note-1')])
25
25
 
26
26
  Story.pretty_print story
27
27
 
@@ -35,9 +35,9 @@ module GithubPivotalFlow
35
35
 
36
36
  it 'does not pretty print description or notes if there are none (empty)' do
37
37
  story = double('story')
38
- story.should_receive(:name)
39
- story.should_receive(:description)
40
- PivotalTracker::Note.should_receive(:all).and_return([])
38
+ expect(story).to receive(:name)
39
+ expect(story).to receive(:description)
40
+ expect(PivotalTracker::Note).to receive(:all).and_return([])
41
41
 
42
42
  Story.pretty_print story
43
43
 
@@ -48,9 +48,9 @@ module GithubPivotalFlow
48
48
 
49
49
  it 'does not pretty print description or notes if there are none (nil)' do
50
50
  story = double('story')
51
- story.should_receive(:name)
52
- story.should_receive(:description).and_return('')
53
- PivotalTracker::Note.should_receive(:all).and_return([])
51
+ expect(story).to receive(:name)
52
+ expect(story).to receive(:description).and_return('')
53
+ expect(PivotalTracker::Note).to receive(:all).and_return([])
54
54
 
55
55
  Story.pretty_print story
56
56
 
@@ -125,48 +125,46 @@ module GithubPivotalFlow
125
125
 
126
126
  describe '#create_branch!' do
127
127
  before do
128
- Git.stub(
129
- checkout: nil,
130
- pull_remote: nil,
131
- create_branch: nil,
132
- set_config: nil,
133
- get_config: nil,
134
- push: nil,
135
- commit: nil,
136
- get_remote: 'origin',
137
- )
138
- @pivotal_story.stub(
139
- story_type: 'feature',
140
- id: '123456',
141
- name: 'test',
142
- description: 'description')
128
+ allow(Git).to receive(:checkout).and_return(nil)
129
+ allow(Git).to receive(:pull_remote).and_return(nil)
130
+ allow(Git).to receive(:create_branch).and_return(nil)
131
+ allow(Git).to receive(:set_config).and_return(nil)
132
+ allow(Git).to receive(:get_config).and_return(nil)
133
+ allow(Git).to receive(:push).and_return(nil)
134
+ allow(Git).to receive(:commit).and_return(nil)
135
+ allow(Git).to receive(:get_remote).and_return(nil)
136
+ allow(@pivotal_story).to receive(:story_type).and_return('feature')
137
+ allow(@pivotal_story).to receive(:id).and_return('123456')
138
+ allow(@pivotal_story).to receive(:name).and_return('test')
139
+ allow(@pivotal_story).to receive(:description).and_return('description')
143
140
  @story = GithubPivotalFlow::Story.new(@project, @pivotal_story)
144
141
  allow(@story).to receive(:ask).and_return('test')
145
142
  end
146
143
 
147
144
  it 'prompts the user for a branch extension name' do
148
145
  allow(@story).to receive(:branch_prefix).and_return('feature/')
149
- expect(@story).to receive(:ask).with("Enter branch name (feature/123456-<branch-name>): ").and_return('super-branch')
146
+ expect(@story).to receive(:ask).with("Enter branch name (feature/<branch-name>): ").and_return('super-branch')
150
147
 
151
148
  @story.create_branch!('Message')
152
149
  end
153
150
 
154
151
  it 'includes a tag to skip the ci build for the initial blank commit' do
155
- @story.stub(branch_name: 'feature/123456-my_branch')
152
+ allow(@story).to receive(:branch_name).and_return('feature/123456-my_branch')
156
153
  expect(Git).to receive(:commit).with(hash_including(commit_message: 'Message [ci skip]')).and_return(true)
157
154
 
158
155
  @story.create_branch!('Message')
159
156
  end
160
157
 
161
- it 'pushes the local branch and sets the upstream using the -u flag' do
162
- @story.stub(branch_name: 'feature/123456-my_branch')
163
- expect(Git).to receive(:push).with(instance_of(String), hash_including(set_upstream: true))
158
+ it 'does not push the local branch' do
159
+ allow(@story).to receive(:branch_name).and_return('feature/123456-my_branch')
160
+ expect(Git).to_not receive(:push)
164
161
 
165
162
  @story.create_branch!('Message')
166
163
  end
167
164
 
168
165
  it 'supports stories with quotes in their name' do
169
- @story.stub(name: 'Fancy story with "quotes"', branch_name: 'feature/123456-my_branch')
166
+ allow(@story).to receive(:name).and_return('Fancy story with "quotes"')
167
+ allow(@story).to receive(:branch_name).and_return('feature/123456-my_branch')
170
168
  expect(Git).to receive(:commit).with(hash_including(commit_message: 'Starting [feature #123456]: Fancy story with \"quotes\" [ci skip]'))
171
169
 
172
170
  @story.create_branch!
metadata CHANGED
@@ -1,139 +1,139 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: github-pivotal-flow
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Donald Piret
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-03 00:00:00.000000000 Z
11
+ date: 2014-03-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: highline
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.6'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.6'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: pivotal-tracker
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0.5'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.5'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '1.3'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.3'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ~>
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
61
  version: '10.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ~>
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '10.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: redcarpet
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ~>
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
75
  version: '2.2'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ~>
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '2.2'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rspec
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ~>
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
89
  version: '2.14'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ~>
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '2.14'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rspec-mocks
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ~>
101
+ - - "~>"
102
102
  - !ruby/object:Gem::Version
103
103
  version: '2.14'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ~>
108
+ - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '2.14'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: simplecov
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - ~>
115
+ - - "~>"
116
116
  - !ruby/object:Gem::Version
117
117
  version: '0.7'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - ~>
122
+ - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0.7'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: yard
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - ~>
129
+ - - "~>"
130
130
  - !ruby/object:Gem::Version
131
131
  version: '0.8'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - ~>
136
+ - - "~>"
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0.8'
139
139
  description: Provides a set of additional Git commands to help developers when working
@@ -141,6 +141,7 @@ description: Provides a set of additional Git commands to help developers when w
141
141
  email: donald@donaldpiret.com
142
142
  executables:
143
143
  - git-finish
144
+ - git-publish
144
145
  - git-start
145
146
  extensions: []
146
147
  extra_rdoc_files: []
@@ -148,6 +149,7 @@ files:
148
149
  - LICENSE
149
150
  - README.md
150
151
  - bin/git-finish
152
+ - bin/git-publish
151
153
  - bin/git-start
152
154
  - lib/core_ext/object/blank.rb
153
155
  - lib/github_pivotal_flow.rb
@@ -158,6 +160,7 @@ files:
158
160
  - lib/github_pivotal_flow/github_api.rb
159
161
  - lib/github_pivotal_flow/prepare-commit-msg.sh
160
162
  - lib/github_pivotal_flow/project.rb
163
+ - lib/github_pivotal_flow/publish.rb
161
164
  - lib/github_pivotal_flow/shell.rb
162
165
  - lib/github_pivotal_flow/start.rb
163
166
  - lib/github_pivotal_flow/story.rb
@@ -166,6 +169,7 @@ files:
166
169
  - spec/github_pivotal_flow/configuration_spec.rb
167
170
  - spec/github_pivotal_flow/finish_spec.rb
168
171
  - spec/github_pivotal_flow/git_spec.rb
172
+ - spec/github_pivotal_flow/publish_spec.rb
169
173
  - spec/github_pivotal_flow/shell_spec.rb
170
174
  - spec/github_pivotal_flow/start_spec.rb
171
175
  - spec/github_pivotal_flow/story_spec.rb
@@ -179,17 +183,17 @@ require_paths:
179
183
  - lib
180
184
  required_ruby_version: !ruby/object:Gem::Requirement
181
185
  requirements:
182
- - - '>='
186
+ - - ">="
183
187
  - !ruby/object:Gem::Version
184
188
  version: 1.9.3
185
189
  required_rubygems_version: !ruby/object:Gem::Requirement
186
190
  requirements:
187
- - - '>='
191
+ - - ">="
188
192
  - !ruby/object:Gem::Version
189
193
  version: '0'
190
194
  requirements: []
191
195
  rubyforge_project:
192
- rubygems_version: 2.2.1
196
+ rubygems_version: 2.2.2
193
197
  signing_key:
194
198
  specification_version: 4
195
199
  summary: Git commands for integration with Pivotal Tracker and Github pull requests
@@ -198,6 +202,7 @@ test_files:
198
202
  - spec/github_pivotal_flow/configuration_spec.rb
199
203
  - spec/github_pivotal_flow/finish_spec.rb
200
204
  - spec/github_pivotal_flow/git_spec.rb
205
+ - spec/github_pivotal_flow/publish_spec.rb
201
206
  - spec/github_pivotal_flow/shell_spec.rb
202
207
  - spec/github_pivotal_flow/start_spec.rb
203
208
  - spec/github_pivotal_flow/story_spec.rb