clubhouse.io-ruby 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +70 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/clubhouse.io-ruby.gemspec +26 -0
- data/docs/comments.md +64 -0
- data/docs/epics.md +64 -0
- data/docs/files.md +48 -0
- data/docs/labels.md +49 -0
- data/docs/linked_files.md +64 -0
- data/docs/projects.md +74 -0
- data/docs/stories.md +96 -0
- data/docs/story_links.md +39 -0
- data/docs/tasks.md +66 -0
- data/docs/users.md +26 -0
- data/docs/workflows.md +17 -0
- data/lib/clubhouse.rb +34 -0
- data/lib/clubhouse/api_actions.rb +10 -0
- data/lib/clubhouse/base_resource.rb +108 -0
- data/lib/clubhouse/client.rb +83 -0
- data/lib/clubhouse/comment.rb +45 -0
- data/lib/clubhouse/epic.rb +38 -0
- data/lib/clubhouse/ext/string.rb +9 -0
- data/lib/clubhouse/file.rb +19 -0
- data/lib/clubhouse/label.rb +18 -0
- data/lib/clubhouse/linked_file.rb +13 -0
- data/lib/clubhouse/project.rb +20 -0
- data/lib/clubhouse/story.rb +70 -0
- data/lib/clubhouse/story_link.rb +17 -0
- data/lib/clubhouse/task.rb +45 -0
- data/lib/clubhouse/user.rb +34 -0
- data/lib/clubhouse/version.rb +3 -0
- data/lib/clubhouse/workflow.rb +42 -0
- metadata +137 -0
data/docs/projects.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Projects
|
2
|
+
|
3
|
+
This assumes that you have setup the default client, or will inject your own client.
|
4
|
+
|
5
|
+
## Creating
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
project = Clubhouse::Project.new(
|
9
|
+
name: "Project One",
|
10
|
+
description: 'Project description',
|
11
|
+
color: '#222'
|
12
|
+
)
|
13
|
+
|
14
|
+
project.save
|
15
|
+
```
|
16
|
+
|
17
|
+
Once saved the project object will be reloaded with the response from clubhouse so now your new
|
18
|
+
object will have the created_at and updated_at time that is returned from the API.
|
19
|
+
|
20
|
+
### Required Fields
|
21
|
+
* name
|
22
|
+
|
23
|
+
|
24
|
+
## Updating
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
project = Clubhouse::Project.find(8)
|
28
|
+
|
29
|
+
project.archived = true
|
30
|
+
project.save # Save works for both creating and updating
|
31
|
+
|
32
|
+
=> <#Clubhouse::Project... >
|
33
|
+
|
34
|
+
```
|
35
|
+
|
36
|
+
## Finding by id
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
project = Clubhouse::Project.find(8)
|
40
|
+
|
41
|
+
=> #<Clubhouse::Project:0x007ffcd58002d0 @archived=true, @id=8 ... >
|
42
|
+
```
|
43
|
+
|
44
|
+
## Deleting by id
|
45
|
+
|
46
|
+
When an empty hash is returned this means it was successfull otherwise it will raise an exception
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
Clubhouse::Project.delete(8)
|
50
|
+
|
51
|
+
=> {}
|
52
|
+
```
|
53
|
+
|
54
|
+
## Listing
|
55
|
+
|
56
|
+
Returns a list of all projects
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
Clubhouse::Project.all
|
60
|
+
|
61
|
+
=> [#<Clubhouse::Project:0x007fb142440458 @abbreviation="PT"...>]
|
62
|
+
```
|
63
|
+
|
64
|
+
## Listing all stories for a project
|
65
|
+
|
66
|
+
Returns all the stories for the current project
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
project = Clubhouse::Project.find(8)
|
70
|
+
|
71
|
+
project.stories
|
72
|
+
|
73
|
+
=> [#<Clubhouse::Story:0x007fb144089178 @archived=false, @comments=[{"...>, #<Clubhouse::Story>]
|
74
|
+
```
|
data/docs/stories.md
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
# Stories
|
2
|
+
|
3
|
+
This assumes that you have setup the default client, or will inject your own client check out the README if you haven't already.
|
4
|
+
|
5
|
+
## Creating
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
story = Clubhouse::Story.new(
|
9
|
+
comments:[ {text: 'A comment to start the story'} ],
|
10
|
+
deadline: '2016-12-31T12:30:00Z',
|
11
|
+
estimate: 8,
|
12
|
+
labels: [ {name: 'High'}, {name: :bug } ],
|
13
|
+
name: "Can't login and get 503",
|
14
|
+
project_id: 17,
|
15
|
+
story_type: :bug,
|
16
|
+
tasks: [ {description: 'Monitor server load' } ],
|
17
|
+
workflow_state_id: 2
|
18
|
+
)
|
19
|
+
|
20
|
+
story.save
|
21
|
+
```
|
22
|
+
|
23
|
+
Once saved the story object will be reloaded with the response from clubhouse so now your new object will have the created_at and updated_at time that is returned from the API.
|
24
|
+
|
25
|
+
### Required Fields
|
26
|
+
* name
|
27
|
+
* project_id
|
28
|
+
|
29
|
+
|
30
|
+
## Updating
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
story = Clubhouse::Story.new(name: "Can't login and get 503", project_id: 17).save
|
34
|
+
|
35
|
+
story.story_type = 'bug'
|
36
|
+
story.save # Save works for both creating and updating and only sends the attributes which are permitted
|
37
|
+
|
38
|
+
=> <#Clubhouse::Story... >
|
39
|
+
|
40
|
+
```
|
41
|
+
|
42
|
+
## Finding by id
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
story = Clubhouse::Story.find(696)
|
46
|
+
|
47
|
+
=> #<Clubhouse::Story:0x007ffcd58002d0 @archived=false, @id=696 ... >
|
48
|
+
```
|
49
|
+
|
50
|
+
## Deleting by id
|
51
|
+
|
52
|
+
When an empty hash is returned this means it was successfull otherwise it will raise an exception
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
Clubhouse::Story.delete(696)
|
56
|
+
|
57
|
+
=> {}
|
58
|
+
```
|
59
|
+
|
60
|
+
## Adding comments and tasks quickly
|
61
|
+
|
62
|
+
Once you have saved your story or you find a story and want to add a comment or task quickly. You can do so with the following method calls
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
|
66
|
+
story = Clubhouse::Story.find(696)
|
67
|
+
|
68
|
+
story.add_comment('My comment here')
|
69
|
+
=> [#<Clubhouse::Comment:0x007ffcd41518b8 @text="My comment here", @story_id=696, @author_id="57c75ddd-ad27-4531-8c7d-368d8702cc0d", @created_at... >, <#Clubhouse::Comment>]
|
70
|
+
|
71
|
+
story.add_task('Add acceptance spec')
|
72
|
+
=> [#<Clubhouse::Task:0x007ffcd434efd0 @complete=false, @created_at="2016-09-25T16:44:35Z", @description="Write acceptance spec"...>, <#Clubhouse::Task>]
|
73
|
+
|
74
|
+
```
|
75
|
+
|
76
|
+
When you add a comment or a task it will return an array of all the comments or tasks that exist
|
77
|
+
on that story, you can access all the comments and task and modify them by calling comments or tasks on the story object.
|
78
|
+
|
79
|
+
## Searching
|
80
|
+
|
81
|
+
Searching for stories is open and not restricted. It takes a hash of key, value.
|
82
|
+
You can check which search attributes are valid [here](https://clubhouse.io/api/v1/#search-stories)
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
Clubhouse::Story.search(project_id: 17, estimate: 5, epic_id: 1)
|
86
|
+
|
87
|
+
=> [#<Clubhouse::Story:0x007ffcd58002d0 @archived=false, @id=696 ... >]
|
88
|
+
```
|
89
|
+
|
90
|
+
## Failure
|
91
|
+
All the request calls can fail and if they do you will be presented with an exception.
|
92
|
+
The exception will be explanatory of the issue with the full body content response of the problem from Clubhouse API
|
93
|
+
|
94
|
+
```
|
95
|
+
Clubhouse::BadRequestError: {"message":"The request included invalid or missing parameters.","errors":{"name":"missing-required-key","project_id":"missing-required-key"}
|
96
|
+
```
|
data/docs/story_links.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# StoryLinks
|
2
|
+
|
3
|
+
This assumes that you have setup the default client, or will inject your own client.
|
4
|
+
|
5
|
+
## Creating
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
story_link = Clubhouse::StoryLink.new(
|
9
|
+
subject_id: 3,
|
10
|
+
object_id: 2,
|
11
|
+
verb: 'blocks'
|
12
|
+
)
|
13
|
+
|
14
|
+
story_link.save
|
15
|
+
```
|
16
|
+
|
17
|
+
Once saved the story link object will be reloaded with the response from clubhouse so now your new
|
18
|
+
object will have the created_at and updated_at time that is returned from the API.
|
19
|
+
|
20
|
+
### Required Fields
|
21
|
+
* subject_id
|
22
|
+
* object_id
|
23
|
+
* verb (blocks, duplicates, relates to)
|
24
|
+
|
25
|
+
|
26
|
+
## Updating
|
27
|
+
|
28
|
+
You can't update a story link best thing is to delete and recreate
|
29
|
+
|
30
|
+
|
31
|
+
## Deleting by id
|
32
|
+
|
33
|
+
When an empty hash is returned this means it was successfull otherwise it will raise an exception
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
Clubhouse::StoryLink.delete(8)
|
37
|
+
|
38
|
+
=> {}
|
39
|
+
```
|
data/docs/tasks.md
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# Tasks
|
2
|
+
|
3
|
+
This assumes that you have setup the default client, or will inject your own client.
|
4
|
+
|
5
|
+
It is recommended to create tasks from a story object as described [here](stories.md)
|
6
|
+
|
7
|
+
## Creating
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
task = Clubhouse::Task.new(
|
11
|
+
story_id: 34,
|
12
|
+
description: 'My task',
|
13
|
+
complete: false
|
14
|
+
)
|
15
|
+
|
16
|
+
task.save
|
17
|
+
```
|
18
|
+
|
19
|
+
Once saved the task object will be reloaded with the response from clubhouse so now your new
|
20
|
+
object will have the created_at and updated_at time that is returned from the API.
|
21
|
+
|
22
|
+
### Required Fields
|
23
|
+
* story_id
|
24
|
+
* description
|
25
|
+
|
26
|
+
|
27
|
+
## Updating
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
task = Clubhouse::Task.find(34, 9)
|
31
|
+
|
32
|
+
task.description = "My task"
|
33
|
+
task.complete = true
|
34
|
+
task.save # Save works for both creating and updating
|
35
|
+
|
36
|
+
=> <#Clubhouse::Task... >
|
37
|
+
|
38
|
+
```
|
39
|
+
|
40
|
+
## Finding by id
|
41
|
+
|
42
|
+
Finding a task is different to all other resources the find method takes two arguments
|
43
|
+
|
44
|
+
* story_id
|
45
|
+
* task_id
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
task = Clubhouse::Task.find(34, 8)
|
49
|
+
|
50
|
+
=> #<Clubhouse::Task:0x007ffcd58002d0 @description="Updated task", @id=9, @complete=true ... >
|
51
|
+
```
|
52
|
+
|
53
|
+
## Deleting by id
|
54
|
+
|
55
|
+
Deleting a task is different to all other resources the delete method takes two arguments
|
56
|
+
|
57
|
+
* story_id
|
58
|
+
* task_id
|
59
|
+
|
60
|
+
When an empty hash is returned this means it was successfull otherwise it will raise an exception
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
Clubhouse::Task.delete(34, 8)
|
64
|
+
|
65
|
+
=> {}
|
66
|
+
```
|
data/docs/users.md
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# Users
|
2
|
+
|
3
|
+
This assumes that you have setup the default client, or will inject your own client.
|
4
|
+
|
5
|
+
## Creating, Updating, Deleting
|
6
|
+
|
7
|
+
You can't create, update or delete users via the API this needs to happen only via Clubhouse web
|
8
|
+
|
9
|
+
|
10
|
+
## Finding by id
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
epic = Clubhouse::User.find(3)
|
14
|
+
|
15
|
+
=> #<Clubhouse::User:0x007ffcd58002d0 @disabled=false, @id=3 ... >
|
16
|
+
```
|
17
|
+
|
18
|
+
## Listing
|
19
|
+
|
20
|
+
Returns a list of all users
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
Clubhouse::User.all
|
24
|
+
|
25
|
+
=> [#<Clubhouse::User:0x007fb142170e58 @name="Tester", @deactivated=false,..>, #<Clubhouse::User...>]
|
26
|
+
```
|
data/docs/workflows.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# Workflows
|
2
|
+
|
3
|
+
This assumes that you have setup the default client, or will inject your own client.
|
4
|
+
|
5
|
+
## Creating, Updating, Deleting
|
6
|
+
|
7
|
+
You can't create, update or delete workflows via the API this needs to happen only via Clubhouse web
|
8
|
+
|
9
|
+
## Listing
|
10
|
+
|
11
|
+
Returns a list of all workflows
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
Clubhouse::Workflow.all
|
15
|
+
|
16
|
+
=> [#<Clubhouse::Workflow:0x007fb142034030 @default_state_id=500000011, @id=500000009...>]
|
17
|
+
```
|
data/lib/clubhouse.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
require 'clubhouse/version'
|
5
|
+
require 'clubhouse/ext/string'
|
6
|
+
require 'clubhouse/api_actions'
|
7
|
+
require 'clubhouse/client'
|
8
|
+
require 'clubhouse/base_resource'
|
9
|
+
|
10
|
+
require 'clubhouse/story'
|
11
|
+
require 'clubhouse/label'
|
12
|
+
require 'clubhouse/user'
|
13
|
+
require 'clubhouse/workflow'
|
14
|
+
require 'clubhouse/project'
|
15
|
+
require 'clubhouse/epic'
|
16
|
+
require 'clubhouse/file'
|
17
|
+
require 'clubhouse/linked_file'
|
18
|
+
require 'clubhouse/task'
|
19
|
+
require 'clubhouse/comment'
|
20
|
+
require 'clubhouse/story_link'
|
21
|
+
|
22
|
+
module Clubhouse
|
23
|
+
class NotSupportedByAPIError < StandardError; end
|
24
|
+
class MissingStoryIDError < StandardError; end
|
25
|
+
class StoryNotSavedError < StandardError; end
|
26
|
+
|
27
|
+
class << self
|
28
|
+
attr_accessor :default_client
|
29
|
+
|
30
|
+
def configure
|
31
|
+
yield self if block_given?
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module Clubhouse
|
2
|
+
class InvalidKeyAssignment < StandardError; end
|
3
|
+
class ClientNotSetup < StandardError; end
|
4
|
+
|
5
|
+
class BaseResource
|
6
|
+
attr_writer :client
|
7
|
+
|
8
|
+
class << self
|
9
|
+
attr_reader :endpoint
|
10
|
+
|
11
|
+
def resource(name)
|
12
|
+
@endpoint = name
|
13
|
+
end
|
14
|
+
|
15
|
+
def client
|
16
|
+
Clubhouse.default_client
|
17
|
+
end
|
18
|
+
|
19
|
+
def find(id)
|
20
|
+
client.find(self, self.endpoint, id)
|
21
|
+
end
|
22
|
+
|
23
|
+
def delete(id)
|
24
|
+
client.delete("#{self.endpoint}/#{id}")
|
25
|
+
end
|
26
|
+
|
27
|
+
def all
|
28
|
+
payload = client.get(self.endpoint)
|
29
|
+
payload.collect{|h| self.new.update_object_from_payload(h) }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(attr = {})
|
34
|
+
attr.each do |key, value|
|
35
|
+
begin
|
36
|
+
send("#{key}=", value)
|
37
|
+
rescue NoMethodError
|
38
|
+
raise InvalidKeyAssignment, "You can't assign value to #{key}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.attributes(*keys, **opts)
|
44
|
+
readonly = Array(opts[:readonly])
|
45
|
+
|
46
|
+
class_eval do
|
47
|
+
define_method(:attribute_keys) { (keys + readonly) }
|
48
|
+
|
49
|
+
(keys + readonly).each do |key|
|
50
|
+
define_method(:"#{key}") { instance_variable_get("@#{key}") }
|
51
|
+
|
52
|
+
if !readonly.include?(key)
|
53
|
+
define_method(:"#{key}=") {|v| instance_variable_set("@#{key}", v) }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.attributes_for_update(*keys)
|
60
|
+
class_eval do
|
61
|
+
define_method :update_attributes do
|
62
|
+
keys.reduce({}) do |h, k|
|
63
|
+
h.merge(k => instance_variable_get("@#{k}"))
|
64
|
+
end.reject{|k,v| v.nil?}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.attributes_for_create(*keys)
|
70
|
+
class_eval do
|
71
|
+
define_method :create_attributes do
|
72
|
+
keys.reduce({}) do |h, k|
|
73
|
+
h.merge(k => instance_variable_get("@#{k}"))
|
74
|
+
end.reject{|k,v| v.nil?}
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def client
|
80
|
+
@client ||= Clubhouse.default_client
|
81
|
+
end
|
82
|
+
|
83
|
+
def update_object_from_payload(payload)
|
84
|
+
attribute_keys.each do |k|
|
85
|
+
self.instance_variable_set("@#{k}", payload[k.to_s])
|
86
|
+
end
|
87
|
+
|
88
|
+
self
|
89
|
+
end
|
90
|
+
|
91
|
+
def reload
|
92
|
+
payload = client.get("#{self.class.endpoint}/#{id}")
|
93
|
+
update_object_from_payload(payload)
|
94
|
+
end
|
95
|
+
|
96
|
+
def save
|
97
|
+
raise ClientNotSetup, "A default client or instance client is not setup" unless client
|
98
|
+
|
99
|
+
payload = if id
|
100
|
+
client.put("#{self.class.endpoint}/#{id}", update_attributes)
|
101
|
+
else
|
102
|
+
client.post(self.class.endpoint, create_attributes)
|
103
|
+
end
|
104
|
+
|
105
|
+
update_object_from_payload(payload)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|