pivotal_tracker 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -1,12 +1,46 @@
1
1
  = pivotal_tracker
2
2
 
3
- This is a simple ruby wrapper for the Pivotal Tracker API.
3
+ This is a simple ruby wrapper for the Pivotal Tracker V2 API utilizing HTTParty and Crack::XML.
4
+
5
+ == Setup
6
+
7
+ Make sure you have gemcutter
8
+ sudo gem install gemcutter
9
+ gem tumble
10
+
11
+ Install the gem
12
+ sudo gem install pivotal_tracker
13
+
14
+ == Usage
15
+
16
+ Create a PivotalTracker object with your API key:
17
+ tracker = PivotalTracker.new('API_KEY')
18
+
19
+ Use any of the currently implemented methods and access them like access the resources returned.
20
+ Notice that all data returned is parsed and built into Mash objects/arrays for you:
21
+ projects = tracker.get_all_projects
22
+ projects.first.memberships.first.person.name
23
+ => "Joslyn Esser"
24
+
25
+ == Currently implemented methods (More to come!)
26
+
27
+ * get_all_activities
28
+ * get_all_project_activities(project_id)
29
+ * get_all_projects
30
+ * get_project(project_id)
31
+ * create_project(name, options = {})
32
+ * get_all_project_memberships(project_id)
33
+ * get_project_membership(project_id, membership_id)
34
+ * add_project_membership(project_id, role, email, options = {})
35
+ * remove_project_membership(project_id, membership_id)
36
+ * get_all_project_iterations(project_id)
37
+ * get_all_project_stories(project_id)
4
38
 
5
39
  == Note on Patches/Pull Requests
6
40
 
7
41
  * Fork the project.
8
42
  * Make your feature addition or bug fix.
9
- * Add tests for it. This is important so I don't break it in a
43
+ * Add specs for it. This is important so I don't break it in a
10
44
  future version unintentionally.
11
45
  * Commit, do not mess with rakefile, version, or history.
12
46
  (if you want to have your own version, that is fine but
data/Rakefile CHANGED
@@ -5,7 +5,7 @@ begin
5
5
  require 'jeweler'
6
6
  Jeweler::Tasks.new do |gem|
7
7
  gem.name = "pivotal_tracker"
8
- gem.summary = %Q{Simple ruby wrapper for the Pivotal Tracker API}
8
+ gem.summary = %Q{Ruby wrapper for the Pivotal Tracker V2 API utilizing HTTParty and Crack XML parsing}
9
9
  gem.email = "joslyn.esser@gmail.com"
10
10
  gem.homepage = "http://github.com/joslynesser/pivotal_tracker"
11
11
  gem.authors = ["Joslyn Esser"]
@@ -14,6 +14,7 @@ begin
14
14
  gem.add_development_dependency "fakeweb", ">= 1.2.7"
15
15
 
16
16
  gem.add_dependency "httparty", ">= 0.4.5"
17
+ gem.add_dependency "mash", ">= 0.0.3"
17
18
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
19
  end
19
20
  Jeweler::GemcutterTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -0,0 +1,16 @@
1
+ class PivotalTracker::Error < StandardError
2
+ attr_reader :data
3
+
4
+ def initialize(data)
5
+ @data = data
6
+ super
7
+ end
8
+ end
9
+
10
+ class PivotalTracker::BadRequest < PivotalTracker::Error; end
11
+ class PivotalTracker::Unauthorized < PivotalTracker::Error; end
12
+
13
+ class PivotalTracker::General < StandardError; end
14
+ class PivotalTracker::Unavailable < StandardError; end
15
+ class PivotalTracker::InformPivotal < StandardError; end
16
+ class PivotalTracker::ResourceNotFound < StandardError; end
@@ -1,7 +1,9 @@
1
1
  require 'rubygems'
2
2
  require 'httparty'
3
+ require 'mash'
3
4
 
4
5
  class PivotalTracker
6
+
5
7
  include HTTParty
6
8
  base_uri 'www.pivotaltracker.com/services/v2'
7
9
  format :xml
@@ -10,20 +12,110 @@ class PivotalTracker
10
12
  self.class.headers 'X-TrackerToken' => api_token
11
13
  end
12
14
 
15
+ def get_all_activities
16
+ response = self.class.get("/activities")
17
+ raise_errors(response)
18
+ parse_response(response, 'activities')
19
+ end
20
+
21
+ def get_all_project_activities(project_id)
22
+ response = self.class.get("/projects/#{project_id}/activities")
23
+ raise_errors(response)
24
+ parse_response(response, 'activities')
25
+ end
26
+
27
+ def get_all_projects
28
+ response = self.class.get("/projects")
29
+ raise_errors(response)
30
+ parse_response(response, 'projects')
31
+ end
32
+
33
+ def get_project(project_id)
34
+ response = self.class.get("/projects/#{project_id}")
35
+ raise_errors(response)
36
+ parse_response(response, 'project')
37
+ end
38
+
13
39
  def create_project(name, options = {})
14
- data = self.class.post('/projects/', :body => {:project => options.merge(:name => name)})
15
- project = PivotalTracker::Project.new(data['project'])
40
+ response = self.class.post('/projects', :body => {:project => options.merge(:name => name)})
41
+ raise_errors(response)
42
+ parse_response(response, 'project')
16
43
  end
17
44
 
18
- def add_member_to_project(project_id, role, email, person_options = {})
19
- data = self.class.post("/projects/#{project_id}/memberships/", :body => {:membership => {:role => role, :person => person_options.merge(:email => email)}})
20
- membership = PivotalTracker::Membership.new(data['membership'])
45
+ def get_all_project_memberships(project_id)
46
+ response = self.class.get("/projects/#{project_id}/memberships")
47
+ raise_errors(response)
48
+ parse_response(response, 'memberships')
21
49
  end
22
50
 
23
- def remove_member_from_project(project_id, membership_id)
24
- data = self.class.delete("/projects/#{project_id}/memberships/#{membership_id}/")
25
- membership = PivotalTracker::Membership.new(data['membership']) if data['membership']
51
+ def get_project_membership(project_id, membership_id)
52
+ response = self.class.get("/projects/#{project_id}/memberships/#{membership_id}")
53
+ raise_errors(response)
54
+ parse_response(response, 'membership')
26
55
  end
56
+
57
+ def add_project_membership(project_id, role, email, options = {})
58
+ response = self.class.post("/projects/#{project_id}/memberships", :body => {:membership => {:role => role, :person => options.merge(:email => email)}})
59
+ raise_errors(response)
60
+ parse_response(response, 'membership')
61
+ end
62
+
63
+ def remove_project_membership(project_id, membership_id)
64
+ response = self.class.delete("/projects/#{project_id}/memberships/#{membership_id}")
65
+ raise_errors(response)
66
+ parse_response(response, 'membership')
67
+ end
68
+
69
+ def get_all_project_iterations(project_id)
70
+ response = self.class.get("/projects/#{project_id}/iterations")
71
+ raise_errors(response)
72
+ parse_response(response, 'iterations')
73
+ end
74
+
75
+ def get_all_project_stories(project_id)
76
+ response = self.class.get("/projects/#{project_id}/stories")
77
+ raise_errors(response)
78
+ parse_response(response, 'stories')
79
+ end
80
+
81
+ private
82
+
83
+ def raise_errors(response)
84
+ case response.code.to_i
85
+ when 400
86
+ raise PivotalTracker::BadRequest.new(response), "(#{response.code}): #{response.message} - #{response['message'] if response}"
87
+ when 401
88
+ raise PivotalTracker::Unauthorized.new(response), "(#{response.code}): #{response.message} - #{response.body if response}"
89
+ when 403
90
+ raise PivotalTracker::General, "(#{response.code}): #{response.message}"
91
+ when 404
92
+ raise PivotalTracker::ResourceNotFound, "(#{response.code}): #{response.message}"
93
+ when 500
94
+ raise PivotalTracker::InformPivotal, "Pivotal Tracker had an internal error. Please let them know. (#{response.code}): #{response.message}"
95
+ when 502..503
96
+ raise PivotalTracker::Unavailable, "(#{response.code}): #{response.message}"
97
+ end
98
+ end
99
+
100
+ # Create Mash objects from response data for the given resource(s)
101
+ def parse_response(response, resource)
102
+ response = cleanup_pivotal_data(response.body)
103
+ data = response[resource]
104
+ if data.is_a?(Array)
105
+ data.collect {|object| Mash.new(object)}
106
+ else
107
+ Mash.new(data)
108
+ end
109
+ end
110
+
111
+ # Make Crack's XML parsing happy by correctly defining Pivotal's nested collections as arrays
112
+ # This can be removed when all collections returned by Pivotal Tracker's API have the type=array attribute set
113
+ def cleanup_pivotal_data(body)
114
+ %w{ projects memberships iterations stories }.each do |resource|
115
+ body.gsub!("<#{resource}>", "<#{resource} type=\"array\">")
116
+ end
117
+ response = Crack::XML.parse(body)
118
+ end
27
119
  end
28
120
 
29
- require File.dirname(__FILE__) + '/pivotal_tracker/data'
121
+ require File.dirname(__FILE__) + '/pivotal_tracker/error'
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{pivotal_tracker}
8
- s.version = "0.1.0"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Joslyn Esser"]
12
- s.date = %q{2009-11-05}
12
+ s.date = %q{2009-11-06}
13
13
  s.email = %q{joslyn.esser@gmail.com}
14
14
  s.extra_rdoc_files = [
15
15
  "LICENSE",
@@ -23,10 +23,16 @@ Gem::Specification.new do |s|
23
23
  "Rakefile",
24
24
  "VERSION",
25
25
  "lib/pivotal_tracker.rb",
26
- "lib/pivotal_tracker/data.rb",
26
+ "lib/pivotal_tracker/error.rb",
27
27
  "pivotal_tracker.gemspec",
28
+ "spec/fixtures/activities.xml",
29
+ "spec/fixtures/iterations.xml",
28
30
  "spec/fixtures/membership.xml",
31
+ "spec/fixtures/memberships.xml",
29
32
  "spec/fixtures/project.xml",
33
+ "spec/fixtures/projects.xml",
34
+ "spec/fixtures/stories.xml",
35
+ "spec/fixtures/story.xml",
30
36
  "spec/pivotal_tracker_spec.rb",
31
37
  "spec/spec.opts",
32
38
  "spec/spec_helper.rb"
@@ -35,7 +41,7 @@ Gem::Specification.new do |s|
35
41
  s.rdoc_options = ["--charset=UTF-8"]
36
42
  s.require_paths = ["lib"]
37
43
  s.rubygems_version = %q{1.3.5}
38
- s.summary = %q{Simple ruby wrapper for the Pivotal Tracker API}
44
+ s.summary = %q{Ruby wrapper for the Pivotal Tracker V2 API utilizing HTTParty and Crack XML parsing}
39
45
  s.test_files = [
40
46
  "spec/pivotal_tracker_spec.rb",
41
47
  "spec/spec_helper.rb"
@@ -49,15 +55,18 @@ Gem::Specification.new do |s|
49
55
  s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
50
56
  s.add_development_dependency(%q<fakeweb>, [">= 1.2.7"])
51
57
  s.add_runtime_dependency(%q<httparty>, [">= 0.4.5"])
58
+ s.add_runtime_dependency(%q<mash>, [">= 0.0.3"])
52
59
  else
53
60
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
54
61
  s.add_dependency(%q<fakeweb>, [">= 1.2.7"])
55
62
  s.add_dependency(%q<httparty>, [">= 0.4.5"])
63
+ s.add_dependency(%q<mash>, [">= 0.0.3"])
56
64
  end
57
65
  else
58
66
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
59
67
  s.add_dependency(%q<fakeweb>, [">= 1.2.7"])
60
68
  s.add_dependency(%q<httparty>, [">= 0.4.5"])
69
+ s.add_dependency(%q<mash>, [">= 0.0.3"])
61
70
  end
62
71
  end
63
72
 
@@ -0,0 +1,19 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <activities type="array">
3
+ <activity>
4
+ <id type="integer">1031</id>
5
+ <project>Sample Project</project>
6
+ <story>More power to shields</story>
7
+ <description>James Kirk accepted &quot;More power to shields&quot;</description>
8
+ <author>James Kirk </author>
9
+ <when>06/01/2009 08:22 AM</when>
10
+ </activity>
11
+ <activity>
12
+ <id type="integer">1030</id>
13
+ <project>Another Sample Project</project>
14
+ <story>Warp speed</story>
15
+ <description>Montgomery Scott rejected &quot;Warp speend&quot; with comments: &quot;Warp speed isn't working&quot;</description>
16
+ <author>Montgomery Scott</author>
17
+ <when>06/01/2009 12:22 AM</when>
18
+ </activity>
19
+ </activities>
@@ -0,0 +1,24 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <iterations type="array">
3
+ <iteration>
4
+ <id type="integer">1</id>
5
+ <number type="integer">1</number>
6
+ <start type="datetime">2009/03/16 00:00:00 UTC</start>
7
+ <finish type="datetime">2009/03/23 00:00:00 UTC</finish>
8
+ <stories>
9
+ <story>
10
+ <id type="integer">1</id>
11
+ <story_type>feature</story_type>
12
+ <url>STORY_URL</url>
13
+ <estimate type="integer">2</estimate>
14
+ <current_state>accepted</current_state>
15
+ <description>Windoze Save Dialog thingy</description>
16
+ <name>The Save Dialog</name>
17
+ <requested_by>Dana Deer</requested_by>
18
+ <owned_by>Rob</owned_by>
19
+ <created_at type="datetime">2009/03/16 16:55:04 UTC</created_at>
20
+ <accepted_at type="datetime">2009/03/19 19:00:00 UTC</accepted_at>
21
+ </story>
22
+ </stories>
23
+ </iteration>
24
+ </iterations>
@@ -0,0 +1,29 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <memberships type="array">
3
+ <membership>
4
+ <id>1</id>
5
+ <person>
6
+ <email>picard@earth.ufp</email>
7
+ <name>Jean-Luc Picard</name>
8
+ <initials>jlp</initials>
9
+ </person>
10
+ <role>Owner</role>
11
+ <project>
12
+ <id>1</id>
13
+ <name>Warp Engine Upgrades</name>
14
+ </project>
15
+ </membership>
16
+ <membership>
17
+ <id>2</id>
18
+ <person>
19
+ <email>jadzia@trill.ufp</email>
20
+ <name>Jadzia Dax</name>
21
+ <initials>JD</initials>
22
+ </person>
23
+ <role>Member</role>
24
+ <project>
25
+ <id>1</id>
26
+ <name>Warp Engine Upgrades</name>
27
+ </project>
28
+ </membership>
29
+ </memberships>
@@ -0,0 +1,46 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <projects type="array">
3
+ <project>
4
+ <id>1</id>
5
+ <name>Sample Project</name>
6
+ <iteration_length type="integer">2</iteration_length>
7
+ <week_start_day>Monday</week_start_day>
8
+ <point_scale>0,1,2,3</point_scale>
9
+ <velocity_scheme>Average of 4 iterations</velocity_scheme>
10
+ <initial_velocity>10</initial_velocity>
11
+ <number_of_done_iterations_to_show>12</number_of_done_iterations_to_show>
12
+ <allow_attachments>true</allow_attachments>
13
+ <public>false</public>
14
+ <use_https>true</use_https>
15
+ <bugs_and_chores_are_estimatable>false</bugs_and_chores_are_estimatable>
16
+ <commit_mode>false</commit_mode>
17
+ <memberships>
18
+ <membership>
19
+ <id>1006</id>
20
+ <person>
21
+ <email>kirkybaby@earth.ufp</email>
22
+ <name>James T. Kirk</name>
23
+ <initials>JTK</initials>
24
+ </person>
25
+ <role>Owner</role>
26
+ </membership>
27
+ </memberships>
28
+ </project>
29
+ <project>
30
+ <id>2</id>
31
+ <name>Sample Project 2</name>
32
+ <iteration_length type="integer">4</iteration_length>
33
+ <week_start_day>Monday</week_start_day>
34
+ <point_scale>0,1,2,3</point_scale>
35
+ <velocity_scheme>Average of 4 iterations</velocity_scheme>
36
+ <initial_velocity>10</initial_velocity>
37
+ <number_of_done_iterations_to_show>12</number_of_done_iterations_to_show>
38
+ <allow_attachments>false</allow_attachments>
39
+ <public>true</public>
40
+ <use_https>false</use_https>
41
+ <bugs_and_chores_are_estimatable>false</bugs_and_chores_are_estimatable>
42
+ <commit_mode>false</commit_mode>
43
+ <memberships>
44
+ </memberships>
45
+ </project>
46
+ </projects>
@@ -0,0 +1,17 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <stories type="array" count="10" total="10">
3
+ <story>
4
+ <id type="integer">STORY_ID</id>
5
+ <story_type>feature</story_type>
6
+ <url>http://www.pivotaltracker.com/story/show/STORY_ID</url>
7
+ <estimate type="integer">1</estimate>
8
+ <current_state>accepted</current_state>
9
+ <description></description>
10
+ <name>More power to shields</name>
11
+ <requested_by>James Kirk</requested_by>
12
+ <owned_by>Montgomery Scott</owned_by>
13
+ <created_at type="datetime">2008/12/10 00:00:00 UTC</created_at>
14
+ <accepted_at type="datetime">2008/12/10 00:00:00 UTC</accepted_at>
15
+ <labels>label 1,label 2,label 3</labels>
16
+ </story>
17
+ </stories>
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <story>
3
+ <id type="integer">2751</id>
4
+ <story_type>feature</story_type>
5
+ <url>http://www.pivotaltracker.com/story/show/2751</url>
6
+ <estimate type="integer">-1</estimate>
7
+ <current_state>unscheduled</current_state>
8
+ <description></description>
9
+ <name>Fire torpedoes</name>
10
+ <requested_by>James Kirk</requested_by>
11
+ <created_at type="datetime">2008/12/10 00:00:00 UTC</created_at>
12
+ </story>
@@ -1,6 +1,6 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
- describe "PivotalTracker" do
3
+ describe PivotalTracker do
4
4
 
5
5
  describe "Initialization" do
6
6
  it "should require an API token" do
@@ -13,52 +13,111 @@ describe "PivotalTracker" do
13
13
  end
14
14
  end
15
15
 
16
- describe "Data" do
16
+ describe "API" do
17
17
  before(:each) do
18
- @data = PivotalTracker::Data.new({'foo' => 'bar'})
18
+ @tracker = PivotalTracker.new('12345')
19
19
  end
20
-
21
- it "should resemble a nested OpenStruct" do
22
- @data.foo.should == 'bar'
20
+
21
+ describe "Activities" do
22
+ it "should get all recent activities" do
23
+ stub_get('/activities', 'activities.xml')
24
+ activities = @tracker.get_all_activities
25
+ activities.first.description.should == "James Kirk accepted \"More power to shields\""
26
+ end
27
+
28
+ it "should get all recent activities for a given project" do
29
+ stub_get('/projects/1/activities', 'activities.xml')
30
+ activities = @tracker.get_all_project_activities(1)
31
+ activities.first.description.should == "James Kirk accepted \"More power to shields\""
32
+ end
23
33
  end
24
34
 
25
- it "should return nil for missing keys" do
26
- @data.foobar.should be_nil
35
+ describe "Projects" do
36
+ it "should get all projects" do
37
+ stub_get('/projects', 'projects.xml')
38
+ projects = @tracker.get_all_projects
39
+ projects.first.name.should == 'Sample Project'
40
+ projects.first.memberships.first.person.name.should == 'James T. Kirk'
41
+ end
42
+
43
+ it "should get a project" do
44
+ stub_get("/projects/27", 'project.xml')
45
+ project = @tracker.get_project(27)
46
+ project.name.should == 'Cardassian War Plans'
47
+ end
48
+
49
+ it "should create a project" do
50
+ stub_post('/projects', 'project.xml')
51
+ project = @tracker.create_project('Cardassian War Plans')
52
+ project.name.should == 'Cardassian War Plans'
53
+ end
27
54
  end
28
- end
29
55
 
30
- describe "Projects" do
31
- before(:each) do
32
- @tracker = PivotalTracker.new('12345')
33
- end
56
+ describe "Memberships" do
57
+ it "should get all memberships for a given project" do
58
+ stub_get('/projects/1/memberships', 'memberships.xml')
59
+ memberships = @tracker.get_all_project_memberships(1)
60
+ memberships.first.person.name.should == 'Jean-Luc Picard'
61
+ end
62
+
63
+ it "should get a single membership for a given project" do
64
+ stub_get('/projects/1/memberships/15007', 'membership.xml')
65
+ membership = @tracker.get_project_membership(1, 15007)
66
+ membership.person.name.should == 'Jadzia Dax'
67
+ end
68
+
69
+ it "should add memberships to a given project" do
70
+ stub_post('/projects/12345/memberships', 'membership.xml')
71
+ membership = @tracker.add_project_membership(12345, 'Member', 'jadzia@trill.ufp')
72
+ membership.person.name.should == 'Jadzia Dax'
73
+ end
34
74
 
35
- it "should create projects" do
36
- stub_post('/projects/', 'project.xml')
37
- project = @tracker.create_project('Cardassian War Plans')
38
- project.name.should == 'Cardassian War Plans'
39
- end
40
- end
41
-
42
- describe "Memberships" do
43
- before(:each) do
44
- @tracker = PivotalTracker.new('12345')
75
+ it "should remove memberships from a given project" do
76
+ stub_delete('/projects/12345/memberships/15007', 'membership.xml')
77
+ membership = @tracker.remove_project_membership(12345, 15007)
78
+ membership.person.name.should == 'Jadzia Dax'
79
+ end
45
80
  end
46
81
 
47
- it "should add members to a given project" do
48
- stub_post('/projects/12345/memberships/', 'membership.xml')
49
- membership = @tracker.add_member_to_project(12345, 'Member', 'jadzia@trill.ufp')
50
- membership.person.name.should == 'Jadzia Dax'
82
+ describe "Iterations" do
83
+ it "should get all iterations for a given project" do
84
+ stub_get('/projects/1/iterations', 'iterations.xml')
85
+ iterations = @tracker.get_all_project_iterations(1)
86
+ iterations.first.stories.first.story_type.should == 'feature'
87
+ end
88
+
89
+ it "should get iterations filtered by done, current, or backlog" do
90
+ pending
91
+ end
92
+
93
+ it "should get iterations by limit and offset" do
94
+ pending
95
+ end
51
96
  end
52
97
 
53
- it "should remove members from a given project" do
54
- stub_delete('/projects/12345/memberships/15007/', 'membership.xml')
55
- membership = @tracker.remove_member_from_project(12345, 15007)
56
- membership.person.name.should == 'Jadzia Dax'
98
+ describe "Stories" do
99
+ it "should get all stories for a given project" do
100
+ stub_get('/projects/1/stories', 'stories.xml')
101
+ stories = @tracker.get_all_project_stories(1)
102
+ stories.first.owned_by.should == 'Montgomery Scott'
103
+ end
104
+
105
+ it "should get all stories for a project based on a given filter" do
106
+ pending
107
+ end
108
+
109
+ it "should get all stories for a project paginated by a limit and offset" do
110
+ pending
111
+ end
112
+
113
+ it "should create a new story for a given project" do
114
+ pending
115
+ end
57
116
  end
58
117
  end
59
118
 
60
119
  describe "Error Handling" do
61
- it "should be handled" do
120
+ it "should be spec'd" do
62
121
  pending
63
122
  end
64
123
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pivotal_tracker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joslyn Esser
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-05 00:00:00 -08:00
12
+ date: 2009-11-06 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -42,6 +42,16 @@ dependencies:
42
42
  - !ruby/object:Gem::Version
43
43
  version: 0.4.5
44
44
  version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: mash
47
+ type: :runtime
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 0.0.3
54
+ version:
45
55
  description:
46
56
  email: joslyn.esser@gmail.com
47
57
  executables: []
@@ -59,10 +69,16 @@ files:
59
69
  - Rakefile
60
70
  - VERSION
61
71
  - lib/pivotal_tracker.rb
62
- - lib/pivotal_tracker/data.rb
72
+ - lib/pivotal_tracker/error.rb
63
73
  - pivotal_tracker.gemspec
74
+ - spec/fixtures/activities.xml
75
+ - spec/fixtures/iterations.xml
64
76
  - spec/fixtures/membership.xml
77
+ - spec/fixtures/memberships.xml
65
78
  - spec/fixtures/project.xml
79
+ - spec/fixtures/projects.xml
80
+ - spec/fixtures/stories.xml
81
+ - spec/fixtures/story.xml
66
82
  - spec/pivotal_tracker_spec.rb
67
83
  - spec/spec.opts
68
84
  - spec/spec_helper.rb
@@ -93,7 +109,7 @@ rubyforge_project:
93
109
  rubygems_version: 1.3.5
94
110
  signing_key:
95
111
  specification_version: 3
96
- summary: Simple ruby wrapper for the Pivotal Tracker API
112
+ summary: Ruby wrapper for the Pivotal Tracker V2 API utilizing HTTParty and Crack XML parsing
97
113
  test_files:
98
114
  - spec/pivotal_tracker_spec.rb
99
115
  - spec/spec_helper.rb
@@ -1,18 +0,0 @@
1
- require 'ostruct'
2
-
3
- class PivotalTracker
4
- class Data < OpenStruct
5
- def initialize(data)
6
- @table = {}
7
- if data
8
- for key, value in data
9
- @table[key.to_sym] = value.instance_of?(Hash) ? Data.new(value) : value
10
- new_ostruct_member(key)
11
- end
12
- end
13
- end
14
- end
15
-
16
- class Project < Data; end
17
- class Membership < Data; end
18
- end