pivotal-tracker-fox 0.5.10

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.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +5 -0
  4. data/Gemfile +17 -0
  5. data/Gemfile.lock +57 -0
  6. data/LICENSE +20 -0
  7. data/README.rdoc +82 -0
  8. data/Rakefile +46 -0
  9. data/VERSION +1 -0
  10. data/lib/pivotal-tracker.rb +40 -0
  11. data/lib/pivotal-tracker/activity.rb +45 -0
  12. data/lib/pivotal-tracker/attachment.rb +16 -0
  13. data/lib/pivotal-tracker/client.rb +81 -0
  14. data/lib/pivotal-tracker/extensions.rb +11 -0
  15. data/lib/pivotal-tracker/iteration.rb +40 -0
  16. data/lib/pivotal-tracker/membership.rb +20 -0
  17. data/lib/pivotal-tracker/note.rb +58 -0
  18. data/lib/pivotal-tracker/project.rb +94 -0
  19. data/lib/pivotal-tracker/proxy.rb +64 -0
  20. data/lib/pivotal-tracker/story.rb +157 -0
  21. data/lib/pivotal-tracker/task.rb +71 -0
  22. data/lib/pivotal-tracker/validation.rb +69 -0
  23. data/lib/pivotal_tracker.rb +2 -0
  24. data/pivotal-tracker.gemspec +131 -0
  25. data/spec/fixtures/activity.xml +177 -0
  26. data/spec/fixtures/bugs.xml +279 -0
  27. data/spec/fixtures/created_note.xml +14 -0
  28. data/spec/fixtures/created_story.xml +14 -0
  29. data/spec/fixtures/features.xml +293 -0
  30. data/spec/fixtures/iterations_all.xml +243 -0
  31. data/spec/fixtures/iterations_backlog.xml +166 -0
  32. data/spec/fixtures/iterations_current.xml +48 -0
  33. data/spec/fixtures/iterations_current_backlog.xml +211 -0
  34. data/spec/fixtures/iterations_done.xml +34 -0
  35. data/spec/fixtures/memberships.xml +42 -0
  36. data/spec/fixtures/notes.xml +33 -0
  37. data/spec/fixtures/project.xml +53 -0
  38. data/spec/fixtures/project_activity.xml +177 -0
  39. data/spec/fixtures/projects.xml +107 -0
  40. data/spec/fixtures/stale_fish.yml +167 -0
  41. data/spec/fixtures/stories.xml +293 -0
  42. data/spec/fixtures/story-4459994.xml +37 -0
  43. data/spec/fixtures/story-4460038.xml +46 -0
  44. data/spec/fixtures/story-4460598.xml +32 -0
  45. data/spec/fixtures/story-4473735.xml +48 -0
  46. data/spec/fixtures/tasks.xml +24 -0
  47. data/spec/fixtures/update_tasks.xml +8 -0
  48. data/spec/pivotal-tracker/activity_spec.rb +32 -0
  49. data/spec/pivotal-tracker/attachment_spec.rb +62 -0
  50. data/spec/pivotal-tracker/client_spec.rb +148 -0
  51. data/spec/pivotal-tracker/iteration_spec.rb +76 -0
  52. data/spec/pivotal-tracker/membership_spec.rb +20 -0
  53. data/spec/pivotal-tracker/note_spec.rb +61 -0
  54. data/spec/pivotal-tracker/project_spec.rb +98 -0
  55. data/spec/pivotal-tracker/story_spec.rb +247 -0
  56. data/spec/pivotal-tracker/task_spec.rb +33 -0
  57. data/spec/spec.opts +1 -0
  58. data/spec/spec_helper.rb +46 -0
  59. data/spec/support/stale_fish_fixtures.rb +71 -0
  60. metadata +287 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 80d343bd4d40b36df622edb5fe15fa98b76ec0fd
4
+ data.tar.gz: 8fa41a04e8520910f816cb30d70e77c52e36f87a
5
+ SHA512:
6
+ metadata.gz: 09742ce0b199d6439c49868dad497285ec1c3d5d3d14b0c8ca463bad5b10efb2cb29bc667bddf3d2f6bd3f0391416056a8124cfa097ddc48a5619a5965ac2367
7
+ data.tar.gz: bf9455c9183e487da98d2770e7f989550c6eea875ee85abdfe49c65149e2ba835e0f2c126774a6484cac3c77794b91217e4dd568e8bf20ffdf916abca36b3488
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ source 'http://rubygems.org'
2
+
3
+ group :runtime do
4
+ gem 'rest-client', '~> 1.6.0'
5
+ gem 'nokogiri-happymapper', '>= 0.5.4', :require => 'happymapper'
6
+ gem 'builder'
7
+ gem 'nokogiri', '>= 1.5.5'
8
+ gem 'crack'
9
+ end
10
+
11
+ group :test do
12
+ gem 'rspec'
13
+ gem 'rake'
14
+ gem 'jeweler'
15
+ gem 'stale_fish', '~> 1.3.2'
16
+ gem 'autotest'
17
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,57 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ ZenTest (4.8.2)
5
+ activesupport (3.2.9)
6
+ i18n (~> 0.6)
7
+ multi_json (~> 1.0)
8
+ autotest (4.4.6)
9
+ ZenTest (>= 4.4.1)
10
+ builder (3.1.4)
11
+ crack (0.3.1)
12
+ diff-lcs (1.1.3)
13
+ fakeweb (1.3.0)
14
+ git (1.2.5)
15
+ i18n (0.6.1)
16
+ jeweler (1.8.4)
17
+ bundler (~> 1.0)
18
+ git (>= 1.2.5)
19
+ rake
20
+ rdoc
21
+ json (1.7.5)
22
+ mime-types (1.19)
23
+ multi_json (1.3.7)
24
+ nokogiri (1.5.5)
25
+ nokogiri-happymapper (0.5.6)
26
+ nokogiri (~> 1.5)
27
+ rake (10.0.2)
28
+ rdoc (3.12)
29
+ json (~> 1.4)
30
+ rest-client (1.6.7)
31
+ mime-types (>= 1.16)
32
+ rspec (2.12.0)
33
+ rspec-core (~> 2.12.0)
34
+ rspec-expectations (~> 2.12.0)
35
+ rspec-mocks (~> 2.12.0)
36
+ rspec-core (2.12.0)
37
+ rspec-expectations (2.12.0)
38
+ diff-lcs (~> 1.1.3)
39
+ rspec-mocks (2.12.0)
40
+ stale_fish (1.3.2)
41
+ activesupport
42
+ fakeweb
43
+
44
+ PLATFORMS
45
+ ruby
46
+
47
+ DEPENDENCIES
48
+ autotest
49
+ builder
50
+ crack
51
+ jeweler
52
+ nokogiri (>= 1.5.5)
53
+ nokogiri-happymapper (>= 0.5.4)
54
+ rake
55
+ rest-client (~> 1.6.0)
56
+ rspec
57
+ stale_fish (~> 1.3.2)
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Justin Smestad
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.rdoc ADDED
@@ -0,0 +1,82 @@
1
+ = pivotal-tracker.rb
2
+
3
+ Ruby wrapper for Pivotal Tracker API, no frameworks required. Simply Ruby.
4
+
5
+ {<img src="https://secure.travis-ci.org/jsmestad/pivotal-tracker.png" />}[http://travis-ci.org/jsmestad/pivotal-tracker]
6
+ {<img src="https://badge.fury.io/rb/pivotal-tracker.png" alt="Gem Version" />}[http://rubygems.org/gems/pivotal-tracker]
7
+
8
+ == Features
9
+
10
+ * Compatible with Pivotal Tracker API version 3
11
+ * ActiveRecord-style Wrapper API
12
+ * Support for SSL protected repositories
13
+
14
+ == Overview
15
+
16
+ PivotalTracker::Client.token('myusername@email.com', 'secretpassword') # Automatically fetch API Token
17
+ PivotalTracker::Client.token = 'jkfduisj97823974j2kl24899234' # Manually set API Token
18
+
19
+ @projects = PivotalTracker::Project.all # return all projects
20
+ @a_project = PivotalTracker::Project.find(84739) # find project with a given ID
21
+
22
+ @a_project.stories.all # return all stories for "a_project"
23
+ @a_project.stories.all(:label => 'overdue', :story_type => ['bug', 'chore']) # return all stories that match the passed filters
24
+ @a_project.stories.find(847762630) # find story with a given ID
25
+
26
+ @a_project.stories.create(:name => 'My Story', :story_type => 'feature') # create a story for this project
27
+
28
+ # all tracker defined filters are allowed, as well as :limit & :offset for pagination
29
+
30
+ # The below pattern below is planned to be added to the final release:
31
+
32
+ @a_project.stories << PivotalTracker::Story.new(84739, :name => 'Ur Story') # same as earlier story creation, useful for copying/cloning from proj
33
+
34
+
35
+ @story = @a_project.stories.find(847762630)
36
+ @story.notes.all # return all notes (comments) for a story
37
+ @story.notes.create(:text => 'A new comment', :noted_at => '06/29/2010 05:00 EST') # add a new note
38
+
39
+
40
+ @story.attachments # return an array of all attachment items (data only, not the files)
41
+ @story.upload_attachment(file_path) # add a file attachment to @story that can be found at file_path
42
+
43
+
44
+ # All 4 examples below return a PivotalTracker::Story from the new project, with the same story ID
45
+
46
+ @story.move_to_project(123456) # move @story to the project with ID 123456
47
+ @story.move_to_project('123456') # same as above
48
+ @story.move_to_project(@project) # move @story to @project
49
+ @story.move_to_project(@another_story) # move @story into the same project as @another_story
50
+
51
+
52
+ # Connect to custom API endpoint
53
+ PivotalTracker::Client.tracker_host = 'www.my-pivotal-tracker.com'
54
+
55
+ The API is based on the following this gist: http://gist.github.com/283120
56
+
57
+ == Getting Started
58
+
59
+ * Installing:
60
+
61
+ $ gem install pivotal-tracker
62
+
63
+ * Contributing (requires Bundler >= 0.9.7):
64
+
65
+ $ git clone git://github.com/jsmestad/pivotal-tracker
66
+ $ cd pivotal-tracker
67
+ $ bundle install
68
+ $ bundle exec rake
69
+
70
+ == Additional Information
71
+
72
+ * Wiki: http://wiki.github.com/jsmestad/pivotal-tracker
73
+ * Documentation: http://rdoc.info/projects/jsmestad/pivotal-tracker
74
+ * Pivotal API v3 Docs: http://www.pivotaltracker.com/help/api?version=v3
75
+
76
+ == Contributors along the way
77
+
78
+ * Justin Smestad (http://github.com/jsmestad)
79
+ * Josh Nichols (http://github.com/technicalpickles)
80
+ * Terence Lee (http://github.com/hone)
81
+ * Jon Mischo (http://github.com/supertaz)
82
+ * Gabor Ratky (http://github.com/rgabo)
data/Rakefile ADDED
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+
8
+ begin
9
+ require 'jeweler'
10
+ Jeweler::Tasks.new do |gem|
11
+ gem.name = "pivotal-tracker"
12
+ gem.summary = %Q{Ruby wrapper for the Pivotal Tracker API}
13
+ gem.email = "justin.smestad@gmail.com"
14
+ gem.homepage = "http://github.com/jsmestad/pivotal-tracker"
15
+ gem.authors = ["Justin Smestad", "Josh Nichols", "Terence Lee"]
16
+
17
+ gem.add_dependency 'rest-client', '~> 1.6.0'
18
+ gem.add_dependency 'happymapper', '>= 0.3.2'
19
+ gem.add_dependency 'builder'
20
+ gem.add_dependency 'nokogiri', '>= 1.4.3'
21
+
22
+ gem.add_development_dependency 'rspec'
23
+ gem.add_development_dependency 'bundler', '~> 1.0.12'
24
+ gem.add_development_dependency 'jeweler'
25
+ gem.add_development_dependency 'stale_fish', '~> 1.3.0'
26
+ end
27
+ Jeweler::GemcutterTasks.new
28
+ rescue LoadError
29
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
30
+ end
31
+
32
+ require 'rspec/core'
33
+ require 'rspec/core/rake_task'
34
+ RSpec::Core::RakeTask.new(:spec)
35
+
36
+ task :default => :spec
37
+
38
+ begin
39
+ require 'yard'
40
+ YARD::Rake::YardocTask.new
41
+ rescue LoadError
42
+ task :yardoc do
43
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
44
+ end
45
+ end
46
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.5.11
@@ -0,0 +1,40 @@
1
+ require 'cgi'
2
+ require 'rest_client'
3
+ require 'happymapper'
4
+ require 'nokogiri'
5
+
6
+
7
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'validation')
8
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'extensions')
9
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'proxy')
10
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'client')
11
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'project')
12
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'attachment')
13
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'story')
14
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'task')
15
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'membership')
16
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'activity')
17
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'iteration')
18
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'note')
19
+
20
+ module PivotalTracker
21
+
22
+ # define error types
23
+ class ProjectNotSpecified < StandardError; end
24
+
25
+ def self.encode_options(options)
26
+ options_strings = options.inject({}) do |m, (k,v)|
27
+ if [:limit, :offset].include?(k.to_sym)
28
+ m.update k => v
29
+ elsif k.to_sym == :search
30
+ m.update :filter => v
31
+ else
32
+ filter_query = %{#{k}:#{[v].flatten.join(",")}}
33
+ m.update :filter => (m[:filter] ? "#{m[:filter]} #{filter_query}" : filter_query)
34
+ end
35
+ end.map {|k,v| "#{k}=#{CGI.escape(v.to_s)}"}
36
+
37
+ %{?#{options_strings.join("&")}} unless options_strings.empty?
38
+ end
39
+
40
+ end
@@ -0,0 +1,45 @@
1
+ module PivotalTracker
2
+ class Activity
3
+ include HappyMapper
4
+ class << self
5
+ def all(project=nil, options={})
6
+ params = self.encode_options(options)
7
+ if project
8
+ parse(Client.connection["/projects/#{project.id}/activities#{params}"].get)
9
+ else
10
+ parse(Client.connection["/activities#{params}"].get)
11
+ end
12
+ end
13
+
14
+ protected
15
+
16
+ def encode_options(options)
17
+ return nil if !options.is_a?(Hash) || options.empty?
18
+
19
+ options_string = []
20
+ options_string << "limit=#{options.delete(:limit)}" if options[:limit]
21
+ options_string << "newer_than_version=#{options.delete(:newer_than_version)}" if options[:newer_than_version]
22
+
23
+ if options[:occurred_since]
24
+ options_string << "occurred_since_date=\"#{options[:occurred_since].utc}\""
25
+ elsif options[:occurred_since_date]
26
+ options_string << "occurred_since_date=#{URI.escape options[:occurred_since_date].strftime("%Y/%m/%d %H:%M:%S %Z")}"
27
+ end
28
+
29
+ return "?#{options_string.join('&')}"
30
+ end
31
+
32
+ end
33
+
34
+ element :id, Integer
35
+ element :version, Integer
36
+ element :event_type, String
37
+ element :occurred_at, DateTime
38
+ element :author, String
39
+ element :project_id, Integer
40
+ element :description, String
41
+
42
+ has_many :stories, Story
43
+
44
+ end
45
+ end
@@ -0,0 +1,16 @@
1
+ module PivotalTracker
2
+ class Attachment
3
+ include HappyMapper
4
+
5
+ tag 'attachment'
6
+
7
+ element :id, Integer
8
+ element :filename, String
9
+ element :description, String
10
+ element :uploaded_by, String
11
+ element :uploaded_at, DateTime
12
+ element :url, String
13
+ element :status, String
14
+
15
+ end
16
+ end
@@ -0,0 +1,81 @@
1
+ module PivotalTracker
2
+
3
+ class Client
4
+
5
+ class NoToken < StandardError; end
6
+
7
+ class << self
8
+ attr_writer :use_ssl, :token, :tracker_host
9
+
10
+ def use_ssl
11
+ @use_ssl || false
12
+ end
13
+
14
+ def token(username, password, method='post')
15
+ response = if method == 'post'
16
+ RestClient.post api_ssl_url + '/tokens/active', :username => username, :password => password
17
+ else
18
+ RestClient.get "#{api_ssl_url(username, password)}/tokens/active"
19
+ end
20
+ @token= Nokogiri::XML(response.body).search('guid').inner_html
21
+ end
22
+
23
+ # this is your connection for the entire module
24
+ def connection(options={})
25
+ raise NoToken if @token.to_s.empty?
26
+
27
+ @connections ||= {}
28
+
29
+ cached_connection? && !protocol_changed? ? cached_connection : new_connection
30
+ end
31
+
32
+ def clear_connections
33
+ @connections = nil
34
+ end
35
+
36
+ def tracker_host
37
+ @tracker_host ||= "www.pivotaltracker.com"
38
+ end
39
+
40
+ def api_ssl_url(user=nil, password=nil)
41
+ user_password = (user && password) ? "#{user}:#{password}@" : ''
42
+ "https://#{user_password}#{tracker_host}#{api_path}"
43
+ end
44
+
45
+ def api_url
46
+ "http://#{tracker_host}#{api_path}"
47
+ end
48
+
49
+ protected
50
+
51
+ def protocol
52
+ use_ssl ? 'https' : 'http'
53
+ end
54
+
55
+ def cached_connection?
56
+ !@connections[@token].nil?
57
+ end
58
+
59
+ def cached_connection
60
+ @connections[@token]
61
+ end
62
+
63
+ def new_connection
64
+ @connections[@token] = RestClient::Resource.new("#{use_ssl ? api_ssl_url : api_url}", :headers => {'X-TrackerToken' => @token, 'Content-Type' => 'application/xml'})
65
+ end
66
+
67
+ def protocol_changed?
68
+ cached_connection? ? (cached_connection_protocol != protocol) : false
69
+ end
70
+
71
+ def cached_connection_protocol
72
+ cached_connection.url.match(/^(.*):\/\//).captures.first
73
+ end
74
+
75
+ def api_path
76
+ '/services/v3'
77
+ end
78
+ end
79
+
80
+ end
81
+ end
@@ -0,0 +1,11 @@
1
+ # Happymapper patch for RestClient API Change (response => response.body)
2
+
3
+ module HappyMapper
4
+ module ClassMethods
5
+ alias_method :orig_parse, :parse
6
+ def parse(xml, options={})
7
+ xml = xml.to_s if xml.is_a?(RestClient::Response)
8
+ orig_parse(xml, options)
9
+ end
10
+ end
11
+ end