pivo_flow 0.6 → 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.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/CHANGELOG.md +18 -0
- data/README.md +4 -37
- data/bin/pf-prepare-commit-msg +10 -4
- data/lib/pivo_flow/cli.rb +3 -8
- data/lib/pivo_flow/pivotal.rb +14 -10
- data/lib/pivo_flow/state.rb +23 -0
- data/lib/pivo_flow/version.rb +1 -1
- data/lib/pivo_flow.rb +1 -0
- data/pivo_flow.gemspec +0 -1
- data/spec/pivo_flow/base_spec.rb +18 -16
- data/spec/pivo_flow/cli_spec.rb +18 -35
- data/spec/pivo_flow/pivotal_spec.rb +67 -63
- data/spec/pivo_flow/state_spec.rb +38 -0
- data/spec/spec_helper.rb +19 -11
- metadata +7 -5
- data/.travis.yml +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3b0e99ca7d80278c1cee9005ae3c938aa10da3e8
|
4
|
+
data.tar.gz: 1d37fb1d48975ec2f1374c6965c63e32cfe2b79b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0fcc5cd5b21649c2ef9ae3e9157861f6f0beacf675a585c6353d7c0567ec2ac075cb5554505a7cc56519e1419cd58236d4b3d9a63c23d210348ce8dd6762e0ff
|
7
|
+
data.tar.gz: 28688a32e8c4af94d3ccf7d3dbc73c3782132b3a791d9816ab99e1bc9ae722f6075795650b78c0789fb3c72d04466eb7db4d9eabfe2c83b69d5e8a49d303e789
|
data/.rspec
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# Change Log
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
# 0.7 - 2017-10-06
|
6
|
+
|
7
|
+
Thanks [David Balatero](https://github.com/dbalatero) for your help with this
|
8
|
+
release!
|
9
|
+
|
10
|
+
## Added
|
11
|
+
|
12
|
+
* [Ability to track story ID by branch](https://github.com/lubieniebieski/pivo_flow/pull/20)
|
13
|
+
|
14
|
+
## Fixed
|
15
|
+
|
16
|
+
* [Readme badges](https://github.com/lubieniebieski/pivo_flow/pull/21)
|
17
|
+
* [Commit message fixes](https://github.com/lubieniebieski/pivo_flow/pull/23)
|
18
|
+
* [Make branch names start with the name, downcased](https://github.com/lubieniebieski/pivo_flow/pull/22)
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# PivoFlow
|
2
2
|
|
3
|
-
[](https://codeclimate.com/github/lubieniebieski/pivo_flow)
|
4
|
+
[](https://circleci.com/gh/lubieniebieski/pivo_flow)
|
5
5
|
|
6
6
|
PivoFlow lets you choose the story you are currently working on from Pivotal Tracker. Intended for all the people, who doesn't like feature-branch approach or are "merdżuj - nie pier*ol"-theory enthusiasts.
|
7
7
|
|
@@ -61,42 +61,9 @@ Show current STORY_ID from temp file
|
|
61
61
|
|
62
62
|
This gem installs a `pepare-commit-msg` hook by adding a reference to `pf-prepare-commit-msg` file. In short: you shouldn't be worried about your own `prepare-commit-msg` hook, the one added by `pivo_flow` will be added in the last line of original hook file.
|
63
63
|
|
64
|
-
##
|
65
|
-
### 0.6 Current release
|
64
|
+
## Changelog
|
66
65
|
|
67
|
-
|
68
|
-
|
69
|
-
### 0.5
|
70
|
-
|
71
|
-
* set ticket id without connecting to pivotal with 'pf set NUMBER'
|
72
|
-
|
73
|
-
### 0.4
|
74
|
-
|
75
|
-
* colorized output
|
76
|
-
* **TODO** story statistics
|
77
|
-
* **TODO** git statistics (number of commits in some peroid, average, etc.)
|
78
|
-
|
79
|
-
### 0.3
|
80
|
-
|
81
|
-
* single-story view with comments and tasks
|
82
|
-
* flow:
|
83
|
-
* select story
|
84
|
-
* read the story description
|
85
|
-
* accept or back to story selection
|
86
|
-
* `pf info` displaying info about current task
|
87
|
-
* `pf deliver` ability to deliver finished stories [#6]
|
88
|
-
* options via `OptionParser`
|
89
|
-
|
90
|
-
### 0.2
|
91
|
-
|
92
|
-
* git hook
|
93
|
-
* formatted output
|
94
|
-
* bugfixes
|
95
|
-
|
96
|
-
### before 0.2
|
97
|
-
|
98
|
-
* gem basic structure
|
99
|
-
* git config read/write
|
66
|
+
See [CHANGELOG.md](https://github.com/lubieniebieski/pivo_flow/blob/master/CHANGELOG.md) file
|
100
67
|
|
101
68
|
## Contributing
|
102
69
|
|
data/bin/pf-prepare-commit-msg
CHANGED
@@ -1,13 +1,19 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
|
2
|
+
|
3
|
+
branch_name = `git symbolic-ref HEAD 2>/dev/null | cut -d '/' -f3`.strip
|
4
|
+
story_path = "tmp/.pivo_flow/stories/#{branch_name}"
|
5
|
+
|
6
|
+
if !branch_name.empty? && File.exists?(story_path)
|
4
7
|
story_id = File.read(story_path).strip
|
8
|
+
|
5
9
|
if story_id =~ /(\d{7,})/
|
6
10
|
puts IO.read(ARGV[0])
|
7
11
|
commit_msg = IO.read(ARGV[0])
|
8
|
-
|
12
|
+
|
13
|
+
unless commit_msg.include?("##{$1}") or commit_msg =~ /Merge branch/
|
9
14
|
File.open(ARGV[0], 'w') do |file|
|
10
|
-
file.print commit_msg
|
15
|
+
file.print commit_msg.strip
|
16
|
+
file.print "\n\n"
|
11
17
|
file.print "[##{story_id}]"
|
12
18
|
end
|
13
19
|
end
|
data/lib/pivo_flow/cli.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
module PivoFlow
|
2
2
|
class Cli
|
3
|
+
include PivoFlow::State
|
3
4
|
|
4
5
|
def initialize *args
|
5
|
-
@file_story_path = File.join(Dir.pwd, "/tmp/.pivotal_story_id")
|
6
6
|
@args = args
|
7
7
|
end
|
8
8
|
|
@@ -58,7 +58,7 @@ module PivoFlow
|
|
58
58
|
|
59
59
|
def clear
|
60
60
|
unless current_story_id.nil?
|
61
|
-
FileUtils.remove_file(
|
61
|
+
FileUtils.remove_file(current_story_id_file_path)
|
62
62
|
puts "Current pivotal story id cleared."
|
63
63
|
else
|
64
64
|
puts no_story_found_message
|
@@ -98,7 +98,7 @@ module PivoFlow
|
|
98
98
|
end
|
99
99
|
|
100
100
|
def no_story_found_message
|
101
|
-
"No story found in #{
|
101
|
+
"No story found in #{current_story_id_file_path}"
|
102
102
|
end
|
103
103
|
|
104
104
|
def no_method_error
|
@@ -109,11 +109,6 @@ module PivoFlow
|
|
109
109
|
puts "Ups, no such method..."
|
110
110
|
end
|
111
111
|
|
112
|
-
def current_story_id
|
113
|
-
return nil unless File.exists?(@file_story_path)
|
114
|
-
File.open(@file_story_path).read.strip
|
115
|
-
end
|
116
|
-
|
117
112
|
def parse_argv(args)
|
118
113
|
@options = {}
|
119
114
|
|
data/lib/pivo_flow/pivotal.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
module PivoFlow
|
3
3
|
class Pivotal < Base
|
4
|
-
|
5
|
-
@story_id_file_name = ".pivotal_story_id"
|
6
|
-
@story_id_tmp_path = File.join(@current_dir, "/tmp")
|
7
|
-
@story_id_file_path = File.join(@story_id_tmp_path, @story_id_file_name)
|
4
|
+
include PivoFlow::State
|
8
5
|
|
6
|
+
def run
|
9
7
|
PivotalTracker::Client.token = @options["api-token"]
|
10
8
|
PivotalTracker::Client.use_ssl = true
|
11
9
|
end
|
@@ -228,15 +226,21 @@ module PivoFlow
|
|
228
226
|
|
229
227
|
def create_branch story_id
|
230
228
|
story = find_story(story_id)
|
229
|
+
|
231
230
|
if story.nil?
|
232
|
-
puts "Sorry, this story
|
231
|
+
puts "Sorry, this story could not be found (#{story_id})"
|
233
232
|
return
|
234
233
|
end
|
235
234
|
|
236
|
-
ticket_name = story.name
|
237
|
-
|
235
|
+
ticket_name = story.name
|
236
|
+
.tr('^A-Za-z0-9 ', '')
|
237
|
+
.tr(' ', '-')
|
238
|
+
.downcase
|
239
|
+
|
240
|
+
branch_name = [ticket_name, story.id].join("-")
|
238
241
|
|
239
242
|
git_create_branch(branch_name)
|
243
|
+
save_story_id_to_file(story_id)
|
240
244
|
end
|
241
245
|
|
242
246
|
def start_story story_id
|
@@ -252,12 +256,12 @@ module PivoFlow
|
|
252
256
|
end
|
253
257
|
|
254
258
|
def remove_story_id_file
|
255
|
-
FileUtils.remove_file(
|
259
|
+
FileUtils.remove_file(current_story_id_file_path)
|
256
260
|
end
|
257
261
|
|
258
262
|
def save_story_id_to_file story_id
|
259
|
-
FileUtils.mkdir_p(
|
260
|
-
File.open(
|
263
|
+
FileUtils.mkdir_p(story_id_tmp_path)
|
264
|
+
File.open(current_story_id_file_path, 'w') { |f| f.write(story_id) }
|
261
265
|
end
|
262
266
|
|
263
267
|
def show_stories count=9
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module PivoFlow
|
2
|
+
module State
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def current_branch_name
|
6
|
+
Grit::Repo.new(Dir.pwd).head.name
|
7
|
+
end
|
8
|
+
|
9
|
+
def story_id_tmp_path
|
10
|
+
"#{Dir.pwd}/tmp/.pivo_flow/stories"
|
11
|
+
end
|
12
|
+
|
13
|
+
def current_story_id_file_path
|
14
|
+
File.join(story_id_tmp_path, current_branch_name)
|
15
|
+
end
|
16
|
+
|
17
|
+
def current_story_id
|
18
|
+
return nil unless File.exist?(current_story_id_file_path)
|
19
|
+
|
20
|
+
File.read(current_story_id_file_path)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/pivo_flow/version.rb
CHANGED
data/lib/pivo_flow.rb
CHANGED
data/pivo_flow.gemspec
CHANGED
data/spec/pivo_flow/base_spec.rb
CHANGED
@@ -1,23 +1,27 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
require_relative './../../lib/pivo_flow/errors'
|
3
|
-
describe PivoFlow::Base do
|
4
3
|
|
4
|
+
describe PivoFlow::Base do
|
5
5
|
let(:base) { PivoFlow::Base.new }
|
6
6
|
|
7
7
|
before do
|
8
|
-
PivoFlow::Base.
|
8
|
+
allow_any_instance_of(PivoFlow::Base).to receive(:puts)
|
9
|
+
|
9
10
|
stub_git_config
|
10
11
|
stub_base_methods(PivoFlow::Base)
|
11
12
|
end
|
12
13
|
|
13
14
|
it "raises exception if it's outside of git repo" do
|
14
|
-
PivoFlow::Base.
|
15
|
-
|
15
|
+
allow_any_instance_of(PivoFlow::Base).to receive(:git_directory_present?)
|
16
|
+
.and_return(false)
|
17
|
+
|
18
|
+
expect{ base }.to raise_error(PivoFlow::Errors::NoGitRepoFound)
|
16
19
|
end
|
17
20
|
|
18
21
|
it "calls hook installation if it's needed" do
|
19
|
-
PivoFlow::Base.
|
20
|
-
PivoFlow::Base.
|
22
|
+
allow_any_instance_of(PivoFlow::Base).to receive(:git_hook_needed?).and_return(true)
|
23
|
+
allow_any_instance_of(PivoFlow::Base).to receive(:install_git_hook)
|
24
|
+
|
21
25
|
base
|
22
26
|
end
|
23
27
|
|
@@ -33,13 +37,13 @@ describe PivoFlow::Base do
|
|
33
37
|
|
34
38
|
it "creates an executable prepare-commit-msg file" do
|
35
39
|
base.install_git_hook
|
36
|
-
File.executable?(file_name).
|
40
|
+
expect(File.executable?(file_name)).to be_truthy
|
37
41
|
end
|
38
42
|
|
39
43
|
it "creates an executable pf-prepare-commit-msg file" do
|
40
44
|
File.delete pf_file_name if File.exists? pf_file_name
|
41
45
|
base.install_git_hook
|
42
|
-
File.executable?(pf_file_name).
|
46
|
+
expect(File.executable?(pf_file_name)).to be_truthy
|
43
47
|
end
|
44
48
|
|
45
49
|
end
|
@@ -47,15 +51,15 @@ describe PivoFlow::Base do
|
|
47
51
|
describe "parses git config" do
|
48
52
|
|
49
53
|
it "and returns project id" do
|
50
|
-
base.options["project-id"].
|
54
|
+
expect(base.options["project-id"]).to eq "123456"
|
51
55
|
end
|
52
56
|
|
53
57
|
it "and returns api token" do
|
54
|
-
base.options["api-token"].
|
58
|
+
expect(base.options["api-token"]).to eq "testtesttesttesttesttesttesttest"
|
55
59
|
end
|
56
60
|
|
57
61
|
it "returns user name" do
|
58
|
-
base.user_name.
|
62
|
+
expect(base.user_name).to eq "Adam Newman"
|
59
63
|
end
|
60
64
|
|
61
65
|
end
|
@@ -67,18 +71,16 @@ describe PivoFlow::Base do
|
|
67
71
|
'pivo-flow.api-token' => nil,
|
68
72
|
'pivo-flow.project-id' => nil}
|
69
73
|
)
|
70
|
-
PivoFlow::Base.any_instance.stub(:git_config_ok?).and_return(false)
|
71
74
|
|
75
|
+
allow_any_instance_of(PivoFlow::Base).to receive(:git_config_ok?).and_return(false)
|
72
76
|
end
|
73
77
|
|
74
78
|
PivoFlow::Base::KEYS_AND_QUESTIONS.each do |key, value|
|
75
79
|
it "changes #{key} value" do
|
76
|
-
PivoFlow::Base.
|
80
|
+
allow_any_instance_of(PivoFlow::Base).to receive(:ask_question).and_return(key)
|
77
81
|
new_key = key.split(".").last
|
78
|
-
base.options[new_key].
|
82
|
+
expect(base.options[new_key]).to eq key
|
79
83
|
end
|
80
84
|
end
|
81
|
-
|
82
85
|
end
|
83
|
-
|
84
86
|
end
|
data/spec/pivo_flow/cli_spec.rb
CHANGED
@@ -4,7 +4,7 @@ describe PivoFlow::Cli do
|
|
4
4
|
|
5
5
|
before(:each) do
|
6
6
|
# we don't need cli output all over the specs
|
7
|
-
PivoFlow::Cli.
|
7
|
+
allow_any_instance_of(PivoFlow::Cli).to receive(:puts)
|
8
8
|
end
|
9
9
|
|
10
10
|
describe "with no args provided" do
|
@@ -12,7 +12,7 @@ describe PivoFlow::Cli do
|
|
12
12
|
let(:command) { PivoFlow::Cli.new.go! }
|
13
13
|
|
14
14
|
before(:each) do
|
15
|
-
PivoFlow::Cli.
|
15
|
+
expect_any_instance_of(PivoFlow::Cli).to receive(:no_method_error).and_return(true)
|
16
16
|
end
|
17
17
|
|
18
18
|
it "calls no_method_error message " do
|
@@ -30,7 +30,7 @@ describe PivoFlow::Cli do
|
|
30
30
|
let(:command) { PivoFlow::Cli.new("invalid_method_name").go! }
|
31
31
|
|
32
32
|
before(:each) do
|
33
|
-
PivoFlow::Cli.
|
33
|
+
expect_any_instance_of(PivoFlow::Cli).to receive(:invalid_method_error)
|
34
34
|
end
|
35
35
|
|
36
36
|
it "calls invalid_method_error message" do
|
@@ -44,11 +44,11 @@ describe PivoFlow::Cli do
|
|
44
44
|
end
|
45
45
|
|
46
46
|
describe "with valid command" do
|
47
|
-
cmd
|
47
|
+
let(:cmd) { "stories" }
|
48
48
|
let(:command) { PivoFlow::Cli.new(cmd).go! }
|
49
49
|
|
50
50
|
before do
|
51
|
-
PivoFlow::Cli.
|
51
|
+
expect_any_instance_of(PivoFlow::Cli).to receive(cmd.to_sym)
|
52
52
|
end
|
53
53
|
|
54
54
|
it "runs this command if it is public" do
|
@@ -58,44 +58,27 @@ describe PivoFlow::Cli do
|
|
58
58
|
it "returns 0" do
|
59
59
|
expect(command).to eq 0
|
60
60
|
end
|
61
|
-
|
62
|
-
end
|
63
|
-
|
64
|
-
describe "reads story id from file" do
|
65
|
-
|
66
|
-
it "and returns nil if there is no such file" do
|
67
|
-
File.stub(:exists?).and_return(false)
|
68
|
-
PivoFlow::Cli.new.send(:current_story_id).should be_nil
|
69
|
-
end
|
70
|
-
|
71
|
-
it "and returns story id if file exists" do
|
72
|
-
File.stub(:exists?).and_return(true)
|
73
|
-
f = mock('File', :read => "123")
|
74
|
-
File.stub(:open).and_return(f)
|
75
|
-
PivoFlow::Cli.new.send(:current_story_id).should eq "123"
|
76
|
-
end
|
77
61
|
end
|
78
62
|
|
79
63
|
describe "finish method" do
|
80
|
-
|
81
64
|
it "calls finish_story on pivotal object on finish method" do
|
82
|
-
pivo =
|
83
|
-
PivoFlow::Cli.
|
84
|
-
pivo.
|
85
|
-
PivoFlow::Cli.
|
65
|
+
pivo = instance_double("PivoFlow::Pivotal")
|
66
|
+
expect_any_instance_of(PivoFlow::Cli).to receive(:pivotal_object).and_return(pivo)
|
67
|
+
expect(pivo).to receive(:finish_story).with("123")
|
68
|
+
expect_any_instance_of(PivoFlow::Cli).to receive(:current_story_id).twice.and_return("123")
|
86
69
|
PivoFlow::Cli.new("finish").go!
|
87
70
|
end
|
88
71
|
|
89
72
|
it "returns 1 if there is no current_story_id" do
|
90
|
-
PivoFlow::Cli.
|
91
|
-
PivoFlow::Cli.new.send(:finish).
|
73
|
+
expect_any_instance_of(PivoFlow::Cli).to receive(:current_story_id).and_return(nil)
|
74
|
+
expect(PivoFlow::Cli.new.send(:finish)).to eq 1
|
92
75
|
end
|
93
76
|
end
|
94
77
|
|
95
78
|
describe "start method" do
|
96
79
|
|
97
80
|
it "returns 1 if no story given" do
|
98
|
-
PivoFlow::Cli.new.send(:start).
|
81
|
+
expect(PivoFlow::Cli.new.send(:start)).to eq 1
|
99
82
|
end
|
100
83
|
|
101
84
|
end
|
@@ -103,14 +86,14 @@ describe PivoFlow::Cli do
|
|
103
86
|
describe "clear method" do
|
104
87
|
|
105
88
|
it "returns 1 if current story is nil" do
|
106
|
-
PivoFlow::Cli.
|
107
|
-
PivoFlow::Cli.new.send(:clear).
|
89
|
+
expect_any_instance_of(PivoFlow::Cli).to receive(:current_story_id).and_return(nil)
|
90
|
+
expect(PivoFlow::Cli.new.send(:clear)).to eq 1
|
108
91
|
end
|
109
92
|
|
110
93
|
|
111
94
|
it "removes file if current story is present" do
|
112
|
-
PivoFlow::Cli.
|
113
|
-
FileUtils.
|
95
|
+
expect_any_instance_of(PivoFlow::Cli).to receive(:current_story_id).and_return(1)
|
96
|
+
expect(FileUtils).to receive(:remove_file).and_return(true)
|
114
97
|
PivoFlow::Cli.new.send(:clear)
|
115
98
|
end
|
116
99
|
|
@@ -121,8 +104,8 @@ describe PivoFlow::Cli do
|
|
121
104
|
methods = [:stories, :start, :info, :finish, :clear, :help, :reconfig, :current, :deliver]
|
122
105
|
methods.each do |method|
|
123
106
|
it "#{method.to_s}" do
|
124
|
-
PivoFlow::Cli.
|
125
|
-
PivoFlow::Cli.new(method.to_s).go
|
107
|
+
allow_any_instance_of(PivoFlow::Cli).to receive(method)
|
108
|
+
expect(PivoFlow::Cli.new(method.to_s).go!).to eq 0
|
126
109
|
end
|
127
110
|
end
|
128
111
|
end
|
@@ -6,66 +6,68 @@ describe PivoFlow::Pivotal do
|
|
6
6
|
|
7
7
|
before do
|
8
8
|
stub_git_config
|
9
|
-
|
9
|
+
|
10
|
+
allow_any_instance_of(PivoFlow::Pivotal).to receive(:puts)
|
11
|
+
|
10
12
|
stub_base_methods(PivoFlow::Pivotal)
|
11
13
|
end
|
12
14
|
|
13
15
|
describe "raises exception" do
|
14
16
|
it "when project id is incorrect" do
|
15
17
|
VCR.use_cassette(:pivotal_fetch_project_not_found) do
|
16
|
-
expect{pivotal.fetch_stories}
|
18
|
+
expect { pivotal.fetch_stories }
|
19
|
+
.to raise_error(PivoFlow::Errors::UnsuccessfulPivotalConnection)
|
17
20
|
end
|
18
21
|
end
|
19
22
|
|
20
23
|
it "when api-token is incorrect (unauthorized)" do
|
21
24
|
VCR.use_cassette(:pivotal_fetch_project_unauthorized) do
|
22
|
-
expect{pivotal.fetch_stories}
|
25
|
+
expect { pivotal.fetch_stories }
|
26
|
+
.to raise_error(PivoFlow::Errors::UnsuccessfulPivotalConnection)
|
23
27
|
end
|
24
28
|
end
|
25
|
-
|
26
29
|
end
|
27
30
|
|
28
31
|
describe "methods" do
|
29
|
-
|
30
32
|
before(:each) do
|
31
33
|
stub_pivotal_project
|
32
34
|
pivotal.run
|
33
35
|
end
|
34
36
|
|
35
37
|
it "does not call pivotal upon run" do
|
36
|
-
pivotal.options[:project].
|
38
|
+
expect(pivotal.options[:project]).to be_nil
|
37
39
|
end
|
38
40
|
|
39
41
|
it "calls pivotal when necessary" do
|
40
|
-
pivotal.
|
42
|
+
expect(pivotal).to receive(:ensure_project).once
|
41
43
|
pivotal.fetch_stories
|
42
44
|
end
|
43
45
|
|
44
46
|
it "does not call pivotal twice" do
|
45
|
-
PivotalTracker::Project.
|
47
|
+
expect(PivotalTracker::Project).to receive(:find).once
|
46
48
|
2.times { pivotal.fetch_stories }
|
47
49
|
end
|
48
50
|
|
49
51
|
it "user_stories takes only stories owned by current user" do
|
50
|
-
pivotal.user_stories.
|
52
|
+
expect(pivotal.user_stories).to eq [@story_feature]
|
51
53
|
end
|
52
54
|
|
53
55
|
it "unasigned_stories takes only stories with no user" do
|
54
|
-
pivotal.unasigned_stories.
|
56
|
+
expect(pivotal.unasigned_stories).to eq [@story_unassigned]
|
55
57
|
end
|
56
58
|
|
57
59
|
it "show_stories should display stories on output" do
|
58
|
-
pivotal.
|
60
|
+
expect(pivotal).to receive(:list_stories_to_output)
|
59
61
|
pivotal.show_stories
|
60
62
|
end
|
61
63
|
|
62
64
|
describe "story_string" do
|
63
65
|
|
64
66
|
it "includes story id" do
|
65
|
-
pivotal.story_string(@story_feature).
|
67
|
+
expect(pivotal.story_string(@story_feature)).to match(/[##{@story_feature.id}]/) end
|
66
68
|
|
67
69
|
it "includes story name" do
|
68
|
-
pivotal.story_string(@story_feature).
|
70
|
+
expect(pivotal.story_string(@story_feature)).to match(/#{@story_feature.name}/)
|
69
71
|
end
|
70
72
|
|
71
73
|
end
|
@@ -73,9 +75,9 @@ describe PivoFlow::Pivotal do
|
|
73
75
|
describe "deliver" do
|
74
76
|
|
75
77
|
it "list only the stories with 'finished' status" do
|
76
|
-
pivotal.
|
77
|
-
@project.
|
78
|
-
pivotal.
|
78
|
+
expect(pivotal).to receive(:user_name).and_return(@story_finished.owned_by)
|
79
|
+
allow(@project).to receive_message_chain(:stories, :all).and_return([@story_finished])
|
80
|
+
expect(pivotal).to receive(:list_stories_to_output).with([@story_finished], "deliver")
|
79
81
|
pivotal.deliver
|
80
82
|
end
|
81
83
|
|
@@ -84,11 +86,11 @@ describe PivoFlow::Pivotal do
|
|
84
86
|
describe "list_stories_to_output" do
|
85
87
|
|
86
88
|
it "returns 1 if stories are nil" do
|
87
|
-
pivotal.list_stories_to_output(nil).
|
89
|
+
expect(pivotal.list_stories_to_output(nil)).to eq 1
|
88
90
|
end
|
89
91
|
|
90
92
|
it "returns 1 if stories are []" do
|
91
|
-
pivotal.list_stories_to_output([]).
|
93
|
+
expect(pivotal.list_stories_to_output([])).to eq 1
|
92
94
|
end
|
93
95
|
|
94
96
|
end
|
@@ -96,9 +98,9 @@ describe PivoFlow::Pivotal do
|
|
96
98
|
describe "show_story" do
|
97
99
|
|
98
100
|
after(:each) do
|
99
|
-
pivotal.
|
101
|
+
allow(pivotal).to receive(:show_stories)
|
100
102
|
# pivotal.stub(:update_story)
|
101
|
-
pivotal.
|
103
|
+
allow(pivotal).to receive(:show_info)
|
102
104
|
|
103
105
|
pivotal.show_story 1
|
104
106
|
end
|
@@ -106,41 +108,41 @@ describe PivoFlow::Pivotal do
|
|
106
108
|
describe "if story's state is 'finished'" do
|
107
109
|
|
108
110
|
before(:each) do
|
109
|
-
@story_feature.
|
110
|
-
pivotal.
|
111
|
+
allow(@story_feature).to receive(:current_state).and_return("finished")
|
112
|
+
allow(pivotal).to receive(:ask_question).and_return("y")
|
111
113
|
end
|
112
114
|
|
113
115
|
it "ask for deliver the story" do
|
114
|
-
pivotal.
|
116
|
+
expect(pivotal).to receive(:ask_question).with(/deliver/)
|
115
117
|
end
|
116
118
|
|
117
119
|
it "updates story on pivotal with 'delivered' status" do
|
118
|
-
@story_feature.
|
120
|
+
expect(@story_feature).to receive(:update).with({ owned_by: @story_feature.owned_by, current_state: :delivered })
|
119
121
|
end
|
120
122
|
|
121
123
|
end
|
122
124
|
|
123
125
|
|
124
126
|
it "shows info about the story" do
|
125
|
-
pivotal.
|
126
|
-
pivotal.
|
127
|
+
allow(pivotal).to receive(:ask_question).and_return("no")
|
128
|
+
expect(pivotal).to receive(:show_info)
|
127
129
|
end
|
128
130
|
|
129
131
|
it "updates the story if user response is 'yes'" do
|
130
|
-
pivotal.
|
131
|
-
pivotal.
|
132
|
+
allow(pivotal).to receive(:ask_question).and_return("yes")
|
133
|
+
expect(pivotal).to receive(:update_story)
|
132
134
|
end
|
133
135
|
|
134
136
|
it "show stories if user response is 'no'" do
|
135
|
-
pivotal.
|
136
|
-
pivotal.
|
137
|
+
allow(pivotal).to receive(:ask_question).and_return("no")
|
138
|
+
expect(pivotal).to receive(:show_stories)
|
137
139
|
end
|
138
140
|
end
|
139
141
|
|
140
142
|
describe "start_story" do
|
141
143
|
|
142
144
|
before(:each) do
|
143
|
-
@story_feature.
|
145
|
+
expect(@story_feature).to receive(:update).with({ current_state: :started, owned_by: pivotal.user_name })
|
144
146
|
end
|
145
147
|
|
146
148
|
it "updates pivotal tracker" do
|
@@ -148,13 +150,12 @@ describe PivoFlow::Pivotal do
|
|
148
150
|
end
|
149
151
|
|
150
152
|
it "returns true on success" do
|
151
|
-
pivotal.start_story(@story_feature.id).
|
153
|
+
expect(pivotal.start_story(@story_feature.id)).to be_truthy
|
152
154
|
end
|
153
|
-
|
154
155
|
end
|
155
156
|
|
156
157
|
it "show_info returns 1 if there is no story" do
|
157
|
-
@project.
|
158
|
+
allow(@project).to receive_message_chain(:stories, :all).and_return([])
|
158
159
|
expect(pivotal.show_info).to eq 1
|
159
160
|
end
|
160
161
|
|
@@ -168,47 +169,50 @@ describe PivoFlow::Pivotal do
|
|
168
169
|
|
169
170
|
|
170
171
|
it "is the first of user's started stories" do
|
171
|
-
@project.
|
172
|
+
allow(@project).to receive_message_chain(:stories, :all).and_return([@users_story1, @users_story2])
|
172
173
|
|
173
|
-
pivotal.current_story.
|
174
|
+
expect(pivotal.current_story).to eq @users_story1
|
174
175
|
end
|
175
176
|
|
176
177
|
it "is the first of user's stories if he has no started stories" do
|
177
|
-
@project.
|
178
|
+
allow(@project).to receive_message_chain(:stories, :all).and_return([@users_story3, @users_story4])
|
178
179
|
|
179
|
-
pivotal.current_story.
|
180
|
+
expect(pivotal.current_story).to eq @users_story3
|
180
181
|
end
|
181
182
|
|
182
183
|
it "is nil if there is no stories assigned to user" do
|
183
|
-
@project.
|
184
|
-
pivotal.current_story.
|
184
|
+
allow(@project).to receive_message_chain(:stories, :all).and_return([])
|
185
|
+
expect(pivotal.current_story).to be_nil
|
185
186
|
end
|
186
187
|
|
187
188
|
end
|
188
189
|
|
189
190
|
end
|
190
191
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
192
|
+
def stub_pivotal_project
|
193
|
+
@project = PivotalTracker::Project.new(id: 123456, name: "testproject")
|
194
|
+
|
195
|
+
@story_feature = PivotalTracker::Story.new(
|
196
|
+
id: 1,
|
197
|
+
url: "http://www.pivotaltracker.com/story/show/1",
|
198
|
+
created_at: DateTime.now,
|
199
|
+
project_id: 123456,
|
200
|
+
name: "story no 1",
|
201
|
+
description: "story description",
|
202
|
+
story_type: "feature",
|
203
|
+
estimate: 3,
|
204
|
+
current_state: "started",
|
205
|
+
requested_by: "Paul Newman",
|
206
|
+
owned_by: "Adam Newman",
|
207
|
+
labels: "first,second"
|
208
|
+
)
|
209
|
+
|
210
|
+
allow(@story_feature).to receive_message_chain(:update).and_return(double(errors: []))
|
211
|
+
@story_unassigned = PivotalTracker::Story.new(owned_by: nil, name: "test", current_state: "started")
|
212
|
+
@story_rejected = PivotalTracker::Story.new(current_state: "rejected", owned_by: "Mark Marco", name: "test_rejected")
|
213
|
+
@story_finished = PivotalTracker::Story.new(current_state: "finished", owned_by: "Mark Marco", name: "finished")
|
214
|
+
|
215
|
+
allow(@project).to receive_message_chain(:stories, :all).and_return([@story_feature, @story_unassigned, @story_rejected, @story_finished])
|
216
|
+
allow(PivotalTracker::Project).to receive(:find).and_return(@project)
|
217
|
+
end
|
214
218
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe PivoFlow::State do
|
4
|
+
describe "#current_story_id_file_path" do
|
5
|
+
before do
|
6
|
+
allow(PivoFlow::State).to receive(:current_branch_name) { "cool-branch" }
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should return a path to a branch-based file name" do
|
10
|
+
expect(PivoFlow::State.current_story_id_file_path).to eq(
|
11
|
+
"#{Dir.pwd}/tmp/.pivo_flow/stories/cool-branch"
|
12
|
+
)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#current_story_id" do
|
17
|
+
let(:tmp_file) { "#{Dir.pwd}/tmp/.pivo_flow/stories/cool-branch" }
|
18
|
+
|
19
|
+
before do
|
20
|
+
allow(PivoFlow::State).to receive(:current_branch_name) { "cool-branch" }
|
21
|
+
|
22
|
+
FileUtils.mkdir_p(PivoFlow::State.story_id_tmp_path)
|
23
|
+
File.write(tmp_file, "123456")
|
24
|
+
end
|
25
|
+
|
26
|
+
after { FileUtils.remove_file(tmp_file) }
|
27
|
+
|
28
|
+
it "should read it from the tmp file" do
|
29
|
+
expect(PivoFlow::State.current_story_id).to eq("123456")
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should return nil if there's no file for it yet" do
|
33
|
+
allow(PivoFlow::State).to receive(:current_branch_name) { "different" }
|
34
|
+
|
35
|
+
expect(PivoFlow::State.current_story_id).to be_nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -12,18 +12,26 @@ VCR.configure do |c|
|
|
12
12
|
c.cassette_library_dir = 'spec/pivo_flow/vcr_cassettes'
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
15
|
+
module StubHelpers
|
16
|
+
def stub_git_config(options = {})
|
17
|
+
git_options = {
|
18
|
+
"pivo-flow.api-token" => "testtesttesttesttesttesttesttest",
|
19
|
+
"pivo-flow.project-id" => "123456",
|
20
|
+
"user.name" => "Adam Newman"
|
21
|
+
}.merge(options)
|
22
22
|
|
23
|
+
allow(Grit::Repo).to receive(:new) do
|
24
|
+
instance_double('Grit::Repo', config: git_options)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def stub_base_methods(klass)
|
29
|
+
allow_any_instance_of(klass).to receive(:git_hook_needed?) { false }
|
30
|
+
allow_any_instance_of(klass).to receive(:git_directory_present?) { true }
|
31
|
+
allow_any_instance_of(klass).to receive(:git_config_ok?) { true }
|
32
|
+
end
|
23
33
|
end
|
24
34
|
|
25
|
-
|
26
|
-
|
27
|
-
klass.any_instance.stub(:git_directory_present?).and_return(true)
|
28
|
-
klass.any_instance.stub(:git_config_ok?).and_return(true)
|
35
|
+
RSpec.configure do |config|
|
36
|
+
config.include StubHelpers
|
29
37
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pivo_flow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.7'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Nowak
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-10-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pivotal-tracker
|
@@ -148,7 +148,7 @@ extra_rdoc_files: []
|
|
148
148
|
files:
|
149
149
|
- ".gitignore"
|
150
150
|
- ".rspec"
|
151
|
-
-
|
151
|
+
- CHANGELOG.md
|
152
152
|
- Gemfile
|
153
153
|
- LICENSE
|
154
154
|
- README.md
|
@@ -161,11 +161,13 @@ files:
|
|
161
161
|
- lib/pivo_flow/core_extensions.rb
|
162
162
|
- lib/pivo_flow/errors.rb
|
163
163
|
- lib/pivo_flow/pivotal.rb
|
164
|
+
- lib/pivo_flow/state.rb
|
164
165
|
- lib/pivo_flow/version.rb
|
165
166
|
- pivo_flow.gemspec
|
166
167
|
- spec/pivo_flow/base_spec.rb
|
167
168
|
- spec/pivo_flow/cli_spec.rb
|
168
169
|
- spec/pivo_flow/pivotal_spec.rb
|
170
|
+
- spec/pivo_flow/state_spec.rb
|
169
171
|
- spec/pivo_flow/vcr_cassettes/pivotal_fetch_project_not_found.yml
|
170
172
|
- spec/pivo_flow/vcr_cassettes/pivotal_fetch_project_unauthorized.yml
|
171
173
|
- spec/spec_helper.rb
|
@@ -188,7 +190,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
188
190
|
version: '0'
|
189
191
|
requirements: []
|
190
192
|
rubyforge_project:
|
191
|
-
rubygems_version: 2.
|
193
|
+
rubygems_version: 2.6.11
|
192
194
|
signing_key:
|
193
195
|
specification_version: 4
|
194
196
|
summary: Simple pivotal tracker integration for day to day work with git
|
@@ -196,7 +198,7 @@ test_files:
|
|
196
198
|
- spec/pivo_flow/base_spec.rb
|
197
199
|
- spec/pivo_flow/cli_spec.rb
|
198
200
|
- spec/pivo_flow/pivotal_spec.rb
|
201
|
+
- spec/pivo_flow/state_spec.rb
|
199
202
|
- spec/pivo_flow/vcr_cassettes/pivotal_fetch_project_not_found.yml
|
200
203
|
- spec/pivo_flow/vcr_cassettes/pivotal_fetch_project_unauthorized.yml
|
201
204
|
- spec/spec_helper.rb
|
202
|
-
has_rdoc:
|