westarete-tracker-tools 0.3.0
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/.document +5 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/Gemfile +30 -0
- data/Gemfile.lock +59 -0
- data/LICENSE.txt +20 -0
- data/README.md +190 -0
- data/Rakefile +79 -0
- data/VERSION +1 -0
- data/autotest/discover.rb +1 -0
- data/bin/backlog +47 -0
- data/bin/done +53 -0
- data/bin/finished +25 -0
- data/bin/validate +29 -0
- data/ci +21 -0
- data/lib/westarete-tracker-tools.rb +6 -0
- data/lib/westarete-tracker-tools/project.rb +69 -0
- data/lib/westarete-tracker-tools/story.rb +137 -0
- data/spec/fixtures/vcr/WestAreteTrackerTools_Project.yml +525 -0
- data/spec/fixtures/vcr/WestAreteTrackerTools_Story.yml +777 -0
- data/spec/helper.rb +17 -0
- data/spec/project_spec.rb +132 -0
- data/spec/story_spec.rb +408 -0
- data/spec/vcr_helper.rb +11 -0
- data/westarete-tracker-tools.gemspec +109 -0
- metadata +248 -0
data/.document
ADDED
data/.rspec
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use 1.8.7@westarete-tracker-tools
|
data/Gemfile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
source :rubygems
|
2
|
+
|
3
|
+
# Tools for creating a gem
|
4
|
+
gem 'jeweler', '1.5.2'
|
5
|
+
|
6
|
+
# API wrapper for Pivotal Tracker
|
7
|
+
gem 'pivotal-tracker', '0.3.0'
|
8
|
+
|
9
|
+
# Validations and relationships
|
10
|
+
gem 'activemodel', '3.0.3'
|
11
|
+
|
12
|
+
group :development do
|
13
|
+
# Test framework
|
14
|
+
gem 'rspec', '2.2.0'
|
15
|
+
|
16
|
+
# Produce rspec output in junit format for jenkins
|
17
|
+
gem 'ci_reporter', '1.6.4'
|
18
|
+
|
19
|
+
# Measure test coverage
|
20
|
+
gem 'rcov', '0.9.9'
|
21
|
+
|
22
|
+
# Automatically run tests as you code
|
23
|
+
gem 'autotest', '4.4.6'
|
24
|
+
|
25
|
+
# Record and play back API requests during tests
|
26
|
+
gem 'vcr', '1.4.0'
|
27
|
+
|
28
|
+
# Mock out API requests
|
29
|
+
gem 'fakeweb', '1.3.0'
|
30
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
ZenTest (4.4.2)
|
5
|
+
activemodel (3.0.3)
|
6
|
+
activesupport (= 3.0.3)
|
7
|
+
builder (~> 2.1.2)
|
8
|
+
i18n (~> 0.4)
|
9
|
+
activesupport (3.0.3)
|
10
|
+
autotest (4.4.6)
|
11
|
+
ZenTest (>= 4.4.1)
|
12
|
+
builder (2.1.2)
|
13
|
+
ci_reporter (1.6.4)
|
14
|
+
builder (>= 2.1.2)
|
15
|
+
diff-lcs (1.1.2)
|
16
|
+
fakeweb (1.3.0)
|
17
|
+
git (1.2.5)
|
18
|
+
happymapper (0.3.2)
|
19
|
+
libxml-ruby (~> 1.1.3)
|
20
|
+
i18n (0.5.0)
|
21
|
+
jeweler (1.5.2)
|
22
|
+
bundler (~> 1.0.0)
|
23
|
+
git (>= 1.2.5)
|
24
|
+
rake
|
25
|
+
libxml-ruby (1.1.4)
|
26
|
+
mime-types (1.16)
|
27
|
+
nokogiri (1.4.3.1)
|
28
|
+
pivotal-tracker (0.3.0)
|
29
|
+
builder
|
30
|
+
happymapper (>= 0.3.2)
|
31
|
+
nokogiri (~> 1.4.3.1)
|
32
|
+
rest-client (~> 1.6.0)
|
33
|
+
rake (0.8.7)
|
34
|
+
rcov (0.9.9)
|
35
|
+
rest-client (1.6.1)
|
36
|
+
mime-types (>= 1.16)
|
37
|
+
rspec (2.2.0)
|
38
|
+
rspec-core (~> 2.2)
|
39
|
+
rspec-expectations (~> 2.2)
|
40
|
+
rspec-mocks (~> 2.2)
|
41
|
+
rspec-core (2.4.0)
|
42
|
+
rspec-expectations (2.4.0)
|
43
|
+
diff-lcs (~> 1.1.2)
|
44
|
+
rspec-mocks (2.4.0)
|
45
|
+
vcr (1.4.0)
|
46
|
+
|
47
|
+
PLATFORMS
|
48
|
+
ruby
|
49
|
+
|
50
|
+
DEPENDENCIES
|
51
|
+
activemodel (= 3.0.3)
|
52
|
+
autotest (= 4.4.6)
|
53
|
+
ci_reporter (= 1.6.4)
|
54
|
+
fakeweb (= 1.3.0)
|
55
|
+
jeweler (= 1.5.2)
|
56
|
+
pivotal-tracker (= 0.3.0)
|
57
|
+
rcov (= 0.9.9)
|
58
|
+
rspec (= 2.2.0)
|
59
|
+
vcr (= 1.4.0)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 West Arete Computing, Inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,190 @@
|
|
1
|
+
# westarete-tracker-tools
|
2
|
+
|
3
|
+
This gem contains a set of tools and extensions that West Arete uses to report
|
4
|
+
on [Pivotal Tracker](https://www.pivotaltracker.com/) across all of its
|
5
|
+
projects.
|
6
|
+
|
7
|
+
## Goals
|
8
|
+
|
9
|
+
* Extract the set of stories that are available to work on across all active
|
10
|
+
projects
|
11
|
+
* Validate stories in the backlog to ensure that they meet our standards
|
12
|
+
* Report on completed iterations for billing and reporting purposes
|
13
|
+
* Wedge the following additional information into each feature:
|
14
|
+
* Risk
|
15
|
+
* Price
|
16
|
+
|
17
|
+
## Manifesto
|
18
|
+
|
19
|
+
This is an opinionated gem. It assumes that you are using Tracker the way that
|
20
|
+
West Arete is using it. That is to say:
|
21
|
+
|
22
|
+
* Stories are not available to be worked on until they are in the backlog
|
23
|
+
* Features are not allowed into the backlog until they have all of the
|
24
|
+
following attributes:
|
25
|
+
* A substantial description
|
26
|
+
* A point estimate
|
27
|
+
* A risk rating (see below)
|
28
|
+
* A price or cost estimate (see below)
|
29
|
+
* Stories should be requested by the project's stakeholder
|
30
|
+
* Acceptance of a story implies that it is ready to be invoiced
|
31
|
+
|
32
|
+
If these rules do not hold true for your organization, you may need to fork
|
33
|
+
this project and modify the behavior so that it better suits your needs.
|
34
|
+
|
35
|
+
### Risk
|
36
|
+
|
37
|
+
West Arete assigns an objective risk rating to each feature. This helps us to
|
38
|
+
achieve a balanced risk profile for each iteration for the sake of developer
|
39
|
+
productivity and happiness. It also gives valuable feedback to the managers
|
40
|
+
about how the feature should be priced, so that risk is apportioned fairly
|
41
|
+
between West Arete and the client.
|
42
|
+
|
43
|
+
Our ratings borrow from the rock climbing tradition of using movie ratings
|
44
|
+
to communicate risk. A climb that is rated PG is generally less dangerous than
|
45
|
+
one that is rated R. In the same way, we assign a risk rating to each feature:
|
46
|
+
|
47
|
+
* G: I have implemented something exactly like this recently.
|
48
|
+
* PG: I have implemented something quite similar to this.
|
49
|
+
* PG-13: I know how to do this, but it will involve a gem, library, or
|
50
|
+
technique that I haven't used before.
|
51
|
+
* R: I know how to do this, but I don't know exactly how long it will take; or
|
52
|
+
it involves an entirely new environment; or it involves adopting outsiders'
|
53
|
+
code.
|
54
|
+
* X: I'm not completely sure I will succeed at implementing this.
|
55
|
+
|
56
|
+
Risk ratings are only assigned to features. They are not assigned to bugs,
|
57
|
+
chores, or releases (although an average rating could probably be determined
|
58
|
+
for the latter).
|
59
|
+
|
60
|
+
There are a couple implicit ramifications of this system:
|
61
|
+
|
62
|
+
* Risk is dependent upon the person or team who will be implementing the
|
63
|
+
feature -- what is G for one person or team may be R for another.
|
64
|
+
* Risk is dependent upon the implementation. The decision to implement a
|
65
|
+
feature using a new gem will increase the risk to at least PG-13, even if it's
|
66
|
+
anticipated that it will be easier to accomplish (which may reduce the point
|
67
|
+
estimate).
|
68
|
+
|
69
|
+
Risk is encoded into a story in Tracker by enclosing it in square braces at
|
70
|
+
the beginning of the feature's title. For example:
|
71
|
+
|
72
|
+
[PG-13] Geolocation
|
73
|
+
|
74
|
+
### Price
|
75
|
+
|
76
|
+
West Arete generally prices its services per feature. Whenever possible, the
|
77
|
+
price is set as a fixed bid per story. However, when the risk for a feature is
|
78
|
+
too high, the feature is usually implemented at an hourly rate so that the
|
79
|
+
risk is shared by both West Arete and the Client.
|
80
|
+
|
81
|
+
With this library, prices are set in Tracker by having a manager comment on
|
82
|
+
the story with the estimated price. The library picks up on this by searching
|
83
|
+
the managers' comments for the words "cost" or "price" followed by a dollar
|
84
|
+
figure. The most recent managers' comment that sets a price wins.
|
85
|
+
|
86
|
+
## Setup
|
87
|
+
|
88
|
+
You'll need to create a `.pivotal_tracker_api_token` file in your home
|
89
|
+
directory. It should contain nothing but your API key from the bottom of [your
|
90
|
+
Tracker profile page](https://www.pivotaltracker.com/profile).
|
91
|
+
|
92
|
+
## Library
|
93
|
+
|
94
|
+
This gem provides a clean, high-level reporting interface to the [Pivotal
|
95
|
+
Tracker v3 API](https://www.pivotaltracker.com/help/api).
|
96
|
+
|
97
|
+
Under the covers, this gem uses the [pivotal-tracker
|
98
|
+
gem](https://github.com/jsmestad/pivotal-tracker) to do the actual
|
99
|
+
communication with the Pivotal API. We've encapsulated that gem's object model
|
100
|
+
to provide a higher level interface that adds our own custom functionality.
|
101
|
+
|
102
|
+
However, our interface is not a superset of the pivotal-tracker gem -- we've
|
103
|
+
only implemented the portions of the API that are useful to us.
|
104
|
+
|
105
|
+
The API documentation for this gem is here:
|
106
|
+
|
107
|
+
<http://rdoc.info/github/westarete/westarete-tracker-tools/master/frames>
|
108
|
+
|
109
|
+
## Executables
|
110
|
+
|
111
|
+
There are two command-line executables that are included with the gem. They
|
112
|
+
build upon the library to do some key reporting for us.
|
113
|
+
|
114
|
+
Both scripts presume that they're being run on Mac OS X, so that they can
|
115
|
+
easily write to the clipboard.
|
116
|
+
|
117
|
+
### backlog
|
118
|
+
|
119
|
+
This script collects all stories that are available to be worked on across
|
120
|
+
all projects.
|
121
|
+
|
122
|
+
Example usage:
|
123
|
+
|
124
|
+
bundle exec bin/backlog
|
125
|
+
|
126
|
+
The standard output reports progress and any story validation errors that are
|
127
|
+
encountered. A healthy backlog should have no errors. A link to each story
|
128
|
+
is provided.
|
129
|
+
|
130
|
+
After the script has completed successfully, a report of all the available
|
131
|
+
stories is copied to the clipboard and is ready to be pasted into a
|
132
|
+
spreadsheet.
|
133
|
+
|
134
|
+
### done
|
135
|
+
|
136
|
+
This script summarizes the accepted stories across all projects for a given
|
137
|
+
iteration.
|
138
|
+
|
139
|
+
It accepts a sole command line argument: an integer of zero or less, which
|
140
|
+
represents the iteration offset. An offset of zero means the current
|
141
|
+
iteration. An offset of -1 means the previous iteration. An offset of -2 means
|
142
|
+
two iterations ago, etc. If the script is run with no arguments, it reports on
|
143
|
+
the current iteration (an offset of 0).
|
144
|
+
|
145
|
+
Example usage:
|
146
|
+
|
147
|
+
bundle exec bin/done -2
|
148
|
+
|
149
|
+
This will gather all completed stories from two iterations ago. The standard
|
150
|
+
output will report on progress and any invalid stories that are encountered.
|
151
|
+
After completion, a summary of the stories will be left on the clipboard,
|
152
|
+
ready to be pasted into a spreadsheet.
|
153
|
+
|
154
|
+
### finished
|
155
|
+
|
156
|
+
This script looks for stories that are close to being done. They may be in a
|
157
|
+
state of "finished", "delivered", or "rejected". The team can run this
|
158
|
+
periodically to see which stories or stakeholders need a nudge to get a story
|
159
|
+
completed.
|
160
|
+
|
161
|
+
### validate
|
162
|
+
|
163
|
+
This script simply scrutinizes the backlog looking for stories that fail
|
164
|
+
validation. It reports any problems and then exits with a non-zero status if
|
165
|
+
any stories fail. It's designed to be run from a continuous integration
|
166
|
+
system.
|
167
|
+
|
168
|
+
## Contributing to westarete-tracker-tools
|
169
|
+
|
170
|
+
* Check out the latest master to make sure the feature hasn't been implemented
|
171
|
+
or the bug hasn't been fixed yet
|
172
|
+
* Check out the issue tracker to make sure someone already hasn't requested it
|
173
|
+
and/or contributed it
|
174
|
+
* Fork the project
|
175
|
+
* Start a feature/bugfix branch
|
176
|
+
* Commit and push until you are happy with your contribution
|
177
|
+
* Make sure to add tests for it. This is important so I don't break it in a
|
178
|
+
future version unintentionally.
|
179
|
+
* Please try not to mess with the Rakefile, version, or history. If you want
|
180
|
+
to have your own version, or is otherwise necessary, that is fine, but please
|
181
|
+
isolate to its own commit so I can cherry-pick around it.
|
182
|
+
|
183
|
+
This project follows the conventions of [Semantic
|
184
|
+
Versioning](http://semver.org/).
|
185
|
+
|
186
|
+
## Copyright
|
187
|
+
|
188
|
+
Copyright (c) 2011 West Arete Computing, Inc. See LICENSE.txt for
|
189
|
+
further details.
|
190
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "westarete-tracker-tools"
|
16
|
+
gem.homepage = "http://github.com/westarete/westarete-tracker-tools"
|
17
|
+
gem.license = "MIT"
|
18
|
+
gem.summary = %Q{A set of tools and extensions that West Arete uses to report
|
19
|
+
on Pivotal Tracker.}
|
20
|
+
gem.description = %Q{
|
21
|
+
This gem contains a set of tools and extensions that West Arete uses to report
|
22
|
+
on Pivotal Tracker across all of its projects.
|
23
|
+
|
24
|
+
Goals:
|
25
|
+
|
26
|
+
* Extract the set of stories that are available to work on across all active
|
27
|
+
projects
|
28
|
+
* Validate stories in the backlog to ensure that they meet our standards
|
29
|
+
* Report on completed iterations for billing and reporting purposes
|
30
|
+
* Wedge the following additional information into each feature:
|
31
|
+
* Risk
|
32
|
+
* Price
|
33
|
+
}
|
34
|
+
gem.email = "scott@westarete.com"
|
35
|
+
gem.authors = ["Scott Woods"]
|
36
|
+
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
37
|
+
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
38
|
+
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
|
39
|
+
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
40
|
+
end
|
41
|
+
Jeweler::RubygemsDotOrgTasks.new
|
42
|
+
|
43
|
+
# Produce test output that jenkins can read.
|
44
|
+
require 'ci/reporter/rake/rspec' # use this if you're using RSpec
|
45
|
+
# require 'ci/reporter/rake/cucumber' # use this if you're using Cucumber
|
46
|
+
# require 'ci/reporter/rake/test_unit' # use this if you're using Test::Unit
|
47
|
+
|
48
|
+
begin
|
49
|
+
require 'rspec/core/rake_task'
|
50
|
+
RSpec::Core::RakeTask.new('spec')
|
51
|
+
RSpec::Core::RakeTask.new('spec:rcov') do |t|
|
52
|
+
t.rcov = true
|
53
|
+
t.rcov_opts = %w{ --exclude spec --exclude gems }
|
54
|
+
end
|
55
|
+
task :default => :spec
|
56
|
+
rescue LoadError
|
57
|
+
puts "Could not find rspec gem. RSpec tasks will not be available."
|
58
|
+
end
|
59
|
+
|
60
|
+
begin
|
61
|
+
require 'rcov/rcovtask'
|
62
|
+
Rcov::RcovTask.new do |test|
|
63
|
+
test.libs << 'spec'
|
64
|
+
test.pattern = 'spec/**/*_spec.rb'
|
65
|
+
test.verbose = true
|
66
|
+
end
|
67
|
+
rescue LoadError
|
68
|
+
puts "Could not find rcov gem. Coverage tasks will not be available."
|
69
|
+
end
|
70
|
+
|
71
|
+
require 'rake/rdoctask'
|
72
|
+
Rake::RDocTask.new do |rdoc|
|
73
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
74
|
+
|
75
|
+
rdoc.rdoc_dir = 'rdoc'
|
76
|
+
rdoc.title = "westarete-tracker-tools #{version}"
|
77
|
+
rdoc.rdoc_files.include('README*')
|
78
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
79
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.0
|
@@ -0,0 +1 @@
|
|
1
|
+
Autotest.add_discovery { "rspec2" }
|
data/bin/backlog
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Extract all stories across all backlogs of all projects into a format
|
4
|
+
# that's ready to be pasted into a spreadsheet. Also report on any validation
|
5
|
+
# errors that are encountered.
|
6
|
+
|
7
|
+
require 'rubygems'
|
8
|
+
require 'bundler/setup'
|
9
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
10
|
+
require 'westarete-tracker-tools'
|
11
|
+
|
12
|
+
include WestAreteTrackerTools
|
13
|
+
|
14
|
+
number_of_problems = 0
|
15
|
+
IO.popen('pbcopy', 'w') do |clipboard|
|
16
|
+
Project.all.each do |project|
|
17
|
+
puts "- #{project.name}"
|
18
|
+
project.backlog.each do |story|
|
19
|
+
if ! story.valid?
|
20
|
+
puts " - Invalid Story"
|
21
|
+
puts " story_type: #{story.story_type}"
|
22
|
+
puts " name: \"#{story.name}\""
|
23
|
+
puts " url: #{story.url}"
|
24
|
+
puts " errors:"
|
25
|
+
story.errors.full_messages.each do |error|
|
26
|
+
puts " - #{error}"
|
27
|
+
end
|
28
|
+
number_of_problems += 1
|
29
|
+
end
|
30
|
+
clipboard.puts [
|
31
|
+
nil, # week starting
|
32
|
+
project.name,
|
33
|
+
story.story_type,
|
34
|
+
story.points,
|
35
|
+
story.risk,
|
36
|
+
nil, # deliverable type
|
37
|
+
story.name,
|
38
|
+
nil, # fixed / hourly
|
39
|
+
story.price,
|
40
|
+
story.url
|
41
|
+
].join("\t")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
puts "\nDone."
|
46
|
+
puts "The master backlog has been copied to your clipboard and is ready to be pasted into a spreadsheet."
|
47
|
+
exit number_of_problems
|