Skip to content

Commit

Permalink
Basic read functionality working with specs.
Browse files Browse the repository at this point in the history
  • Loading branch information
forest committed Mar 23, 2014
1 parent 8b74347 commit dd3fb2a
Show file tree
Hide file tree
Showing 31 changed files with 289 additions and 261 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
0.1.0
---
- Initial release.
49 changes: 24 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# TrackerApi

[![Gem Version](https://badge.fury.io/rb/tracker-api.png)](http://badge.fury.io/rb/tracker-api)
[![Build Status](https://travis-ci.org/dashofcode/tracker-api.png?branch=master)](https://travis-ci.org/dashofcode/tracker-api)
[![Code Climate](https://codeclimate.com/github/dashofcode/tracker-api.png)](https://codeclimate.com/github/dashofcode/tracker-api)
[![Coverage Status](https://coveralls.io/repos/dashofcode/tracker-api/badge.png?branch=master)](https://coveralls.io/r/dashofcode/tracker-api?branch=master)
[![Dependency Status](https://gemnasium.com/dashofcode/tracker-api.png)](https://gemnasium.com/dashofcode/tracker-api)
[![Gem Version](https://badge.fury.io/rb/tracker_api.png)](http://badge.fury.io/rb/tracker_api)
[![Build Status](https://travis-ci.org/dashofcode/tracker_api.png?branch=master)](https://travis-ci.org/dashofcode/tracker_api)
[![Code Climate](https://codeclimate.com/github/dashofcode/tracker_api.png)](https://codeclimate.com/github/dashofcode/tracker_api)
[![Coverage Status](https://coveralls.io/repos/dashofcode/tracker_api/badge.png?branch=master)](https://coveralls.io/r/dashofcode/tracker_api?branch=master)
[![Dependency Status](https://gemnasium.com/dashofcode/tracker_api.png)](https://gemnasium.com/dashofcode/tracker_api)

This gem allows you to easily use the [Pivotal Tracker v5 API](https://www.pivotaltracker.com/help/api/rest/v5).

Expand All @@ -14,42 +14,41 @@ It’s powered by [Faraday](https://github.com/lostisland/faraday) and [Virtus](
## Basic Usage

```ruby
Trackher.configure(api_token: 'my-awesome-api-token') # Configure with API Token
client = TrackerApi::Client.new(token: 'my-api-token') # Create API client

projects = Trackher::Project.all # Get all projects
project = Trackher::Project.find(123456) # Find project with given ID
projects = client.projects # Get all projects
project = client.project(123456) # Find project with given ID

project.all # Get all stories for a project
project.stories.where(with_state: :unscheduled).limit(10) # Get 10 unscheduled stories for a project
project.stories.where(filter: 'requester:OWK label:"jedi stuff"') # Get all stories that match the given filters
project.stories.find(847762630) # Find a story with the given ID
project.stories # Get all stories for a project
project.stories(with_state: :unscheduled, limit: 10) # Get 10 unscheduled stories for a project
project.stories(filter: 'requester:OWK label:"jedi stuff"') # Get all stories that match the given filters
project.story(847762630) # Find a story with the given ID

epics = project.epics # Get all epics for a project
epic = epics.first
label = epic.label # Get an epic's label
```

## Scopes & Eager Loading
## Eager Loading

See Pivotal Tracker API [documentation](https://www.pivotaltracker.com/help/api#Response_Controlling_Parameters) for how to use the `fields` parameter.

```ruby
Trackher.with_token('my-special-api-token') do # Use a token for a specific block only
epics = Trackher::Epic.for_project(@project.id) # Get all epics for a project
end
client = TrackerApi::Client.new(token: 'my-api-token') # Create API client

Trackher.configure(api_token: 'my-awesome-api-token') # Configure with API Token
client.project(project_id, fields: ':default,labels(name)') # Eagerly get labels with a project
client.project(project_id, fields: ':default,epics') # Eagerly get epics with a project
```

Trackher::Iteration.current.for_project(@project.id).first # Get current iteration for a project
Trackher::Iteration.done.for_project(@project.id) # Get all done iterations for a project
Trackher::Iteration.done.offset(-2).for_project(@project.id) # Get last 2 done iterations for a project
## TODO

Trackher::Project.where(fields: ':default,labels(name)').find(project_id) # Eagerly get labels with a project
Trackher::Project.where(fields: ':default,epics').find(project_id) # Eagerly get epics with a project
```
- Pagination
- Create, Update, Delete of Resources

## Contributing

Currently this client only supports read-only access to Pivotal Tracker.
I will be extending it as my use cases require, but am happy to accept contributions.
Currently this client supports read-only access to Pivotal Tracker.
We will be extending it as our use cases require, but are always happy to accept contributions.

1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
Expand Down
2 changes: 1 addition & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ require 'rake/testtask'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.libs << 'test'
t.test_files = FileList['test/**/*_spec.rb']
t.test_files = FileList['test/**/*_test.rb']
t.verbose = true
end

Expand Down
20 changes: 4 additions & 16 deletions lib/tracker_api.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
require 'tracker_api/version'

# dependencies
# require 'addressable/uri'
require 'virtus'
require 'faraday'
require 'faraday_middleware'

# stdlib
# require 'forwardable'
require 'forwardable'
require 'logger'
# require 'time'
# require 'yaml'

module TrackerApi
autoload :Error, 'tracker_api/error'
Expand All @@ -23,8 +20,11 @@ class UnexpectedData < StandardError; end

module Endpoints
autoload :Epic, 'tracker_api/endpoints/epic'
autoload :Epics, 'tracker_api/endpoints/epics'
autoload :Iterations, 'tracker_api/endpoints/iterations'
autoload :Project, 'tracker_api/endpoints/project'
autoload :Projects, 'tracker_api/endpoints/projects'
autoload :Stories, 'tracker_api/endpoints/stories'
end

module Resources
Expand All @@ -36,16 +36,4 @@ module Resources
autoload :Story, 'tracker_api/resources/story'
autoload :TimeZone, 'tracker_api/resources/time_zone'
end

# def self.stringify_keys(hash)
# hash.inject({}) { |r, (k, v)| r.merge(k.to_s => v) }
# end

# def self.symbolize_keys(hash)
# hash.inject({}) { |r, (k, v)| r.merge(k.to_sym => v) }
# end

#def self.blank?(string)
# string.nil? || string == ''
#end
end
9 changes: 3 additions & 6 deletions lib/tracker_api/endpoints/epic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,10 @@ def initialize(client)
@client = client
end

def get(params={})
project_id = params.fetch('project_id')
id = params.fetch('id')

def get(project_id, id)
data = client.request(
:method => :get,
:path => "/projects/#{project_id}/epics/#{id}"
method: :get,
:path => "/projects/#{project_id}/epics/#{id}"
).body

Resources::Epic.new({ client: client }.merge(data))
Expand Down
22 changes: 22 additions & 0 deletions lib/tracker_api/endpoints/epics.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module TrackerApi
module Endpoints
class Epics
attr_accessor :client

def initialize(client)
@client = client
end

def get(project_id, params={})
data = client.request(
method: :get,
path: "/projects/#{project_id}/epics",
params: params
).body
raise TrackerApi::Errors::UnexpectedData, 'Array of epics expected' unless data.is_a? Array

data.map { |epic| Resources::Epic.new({ client: client }.merge(epic)) }
end
end
end
end
10 changes: 0 additions & 10 deletions lib/tracker_api/endpoints/get_epics.rb

This file was deleted.

11 changes: 0 additions & 11 deletions lib/tracker_api/endpoints/get_iterations.rb

This file was deleted.

22 changes: 22 additions & 0 deletions lib/tracker_api/endpoints/iterations.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module TrackerApi
module Endpoints
class Iterations
attr_accessor :client

def initialize(client)
@client = client
end

def get(project_id, params={})
data = client.request(
method: :get,
path: "/projects/#{project_id}/iterations",
params: params
).body
raise TrackerApi::Errors::UnexpectedData, 'Array of iterations expected' unless data.is_a? Array

data.map { |iteration| Resources::Iteration.new({ client: client }.merge(iteration)) }
end
end
end
end
22 changes: 22 additions & 0 deletions lib/tracker_api/endpoints/stories.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module TrackerApi
module Endpoints
class Stories
attr_accessor :client

def initialize(client)
@client = client
end

def get(project_id, params={})
data = client.request(
method: :get,
path: "/projects/#{project_id}/stories",
params: params
).body
raise TrackerApi::Errors::UnexpectedData, 'Array of stories expected' unless data.is_a? Array

data.map { |story| Resources::Story.new({ client: client }.merge(story)) }
end
end
end
end
20 changes: 20 additions & 0 deletions lib/tracker_api/endpoints/story.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module TrackerApi
module Endpoints
class Story
attr_accessor :client

def initialize(client)
@client = client
end

def get(project_id, id)
data = client.request(
method: :get,
:path => "/projects/#{project_id}/stories/#{id}"
).body

Resources::Story.new({ client: client }.merge(data))
end
end
end
end
2 changes: 2 additions & 0 deletions lib/tracker_api/resources/epic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ module Resources
class Epic
include Virtus.model

attribute :client

attribute :id, Integer
attribute :created_at, DateTime
attribute :description, String
Expand Down
2 changes: 2 additions & 0 deletions lib/tracker_api/resources/iteration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ module Resources
class Iteration
include Virtus.model

attribute :client

attribute :created_at, DateTime
attribute :finish, DateTime
attribute :id, Integer
Expand Down
59 changes: 36 additions & 23 deletions lib/tracker_api/resources/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,34 +39,47 @@ class Project
attribute :version, Integer
attribute :week_start_day, String

# @return [TrackerApi::Client::Epics] epics associated with this project
#def epics
# requires :identity
# data = connection.get_epics(self.identity).body
#
# connection.epics.load(data)
#end
# @return [Array[Epic]] epics associated with this project
def epics(params={})
raise ArgumentError, 'Expected @epics to be an Array' unless @epics.is_a? Array
return @epics unless @epics.empty?

# @param [Hash] options
# @option options [String] :scope ('') Restricts the state of iterations to return.
@epics = Endpoints::Epics.new(client).get(id, params)
end

# @param [Hash] params
# @option params [String] :scope ('') Restricts the state of iterations to return.
# If not specified, it defaults to all iterations including done.
# Valid enumeration values: done, current, backlog, current_backlog.
# @option options [Integer] :offset The offset of first iteration to return, relative to the
# @option params [Integer] :offset The offset of first iteration to return, relative to the
# set of iterations specified by 'scope', with zero being the first iteration in the scope.
# @option options [Integer] :limit The number of iterations to return relative to the offset.
# @return [Iterations] iterations associated with this project
#def iterations(options = {})
# requires :identity
#
# data = connection.get_iterations(self.identity, options).body
#
# connection.iterations.load(data)
#end
# @option params [Integer] :limit The number of iterations to return relative to the offset.
# @return [Array[Iteration]] iterations associated with this project
def iterations(params = {})
Endpoints::Iterations.new(client).get(id, params)
end

# @param [Hash] params
# @option params [String] :with_label A label name which all returned stories must match.
# @option params [String] :with_state A story's current_state which all returned stories must match.
# Valid enumeration values: accepted, delivered, finished, started, rejected, unstarted, unscheduled
# @option params [String] :filter This parameter supplies a search string;
# only stories that match the search criteria are returned.
# Cannot be used together with any other parameters except limit and offset.
# ex) state:started requester:OWK label:"jedi stuff" keyword
# @option params [Integer] :offset With the first story in your priority list as 0,
# the index of the first story you want returned.
# @option params [Integer] :limit The number of stories you want returned.
# @return [Array[Story]] iterations associated with this project
def stories(params = {})
Endpoints::Stories.new(client).get(id, params)
end

# @return [Iteration] current iteration associated with this project
#def current_iteration
# iterations(scope: 'current').first
#end
# @param [Fixnum] story_id id of story
# @return [Story]
def story(story_id)
Endpoints::Story.new(client).get(id, story_id)
end
end
end
end
2 changes: 2 additions & 0 deletions lib/tracker_api/resources/story.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ module Resources
class Story
include Virtus.model

attribute :client

attribute :accepted_at, DateTime
attribute :comment_ids, Array[Integer]
attribute :created_at, DateTime
Expand Down
2 changes: 1 addition & 1 deletion lib/tracker_api/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module TrackerApi
VERSION = "0.0.1"
VERSION = '0.1.0'
end
Loading

0 comments on commit dd3fb2a

Please sign in to comment.