bucketface 0.1.1
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/.gitignore +5 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +32 -0
- data/Rakefile +11 -0
- data/bucketface.gemspec +28 -0
- data/lib/bucketface/client.rb +127 -0
- data/lib/bucketface/repository.rb +28 -0
- data/lib/bucketface/version.rb +3 -0
- data/lib/bucketface.rb +41 -0
- data/test/bucketface_test.rb +137 -0
- data/test/fixtures/branches.json +17 -0
- data/test/fixtures/changeset.json +19 -0
- data/test/fixtures/changesets.json +360 -0
- data/test/fixtures/close_issue.txt +1 -0
- data/test/fixtures/events.json +100 -0
- data/test/fixtures/followers.json +47 -0
- data/test/fixtures/full_user.json +43 -0
- data/test/fixtures/issue.json +22 -0
- data/test/fixtures/issue_followers.json +11 -0
- data/test/fixtures/issues.json +51 -0
- data/test/fixtures/open_issue.json +23 -0
- data/test/fixtures/repo.json +7 -0
- data/test/fixtures/repo_events.json +114 -0
- data/test/fixtures/repo_followers.json +11 -0
- data/test/fixtures/repos.json +17 -0
- data/test/fixtures/tags.json +148 -0
- data/test/fixtures/user.json +17 -0
- data/test/helper.rb +39 -0
- metadata +205 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
bucketface (0.0.1)
|
5
|
+
hashie (~> 0.3.0)
|
6
|
+
httparty (~> 0.6.1)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
crack (0.1.8)
|
12
|
+
fakeweb (1.3.0)
|
13
|
+
hashie (0.3.1)
|
14
|
+
httparty (0.6.1)
|
15
|
+
crack (= 0.1.8)
|
16
|
+
jnunemaker-matchy (0.4.0)
|
17
|
+
mocha (0.9.10)
|
18
|
+
rake
|
19
|
+
rake (0.8.7)
|
20
|
+
shoulda (2.11.3)
|
21
|
+
|
22
|
+
PLATFORMS
|
23
|
+
ruby
|
24
|
+
|
25
|
+
DEPENDENCIES
|
26
|
+
bucketface!
|
27
|
+
fakeweb (~> 1.3)
|
28
|
+
hashie (~> 0.3.0)
|
29
|
+
httparty (~> 0.6.1)
|
30
|
+
jnunemaker-matchy (~> 0.4.0)
|
31
|
+
mocha (~> 0.9)
|
32
|
+
shoulda (~> 2.11)
|
data/Rakefile
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'shoulda/tasks'
|
5
|
+
|
6
|
+
require 'rake/testtask'
|
7
|
+
Rake::TestTask.new(:test) do |test|
|
8
|
+
test.ruby_opts = ["-rubygems"] if defined? Gem
|
9
|
+
test.libs << "lib" << "test"
|
10
|
+
test.pattern = "test/**/*_test.rb"
|
11
|
+
end
|
data/bucketface.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "bucketface/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "bucketface"
|
7
|
+
s.version = Bucketface::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Rafael George"]
|
10
|
+
s.email = ["george.rafael@gmail.com"]
|
11
|
+
s.homepage = ""
|
12
|
+
s.summary = %q{Provides a wrapper for Bitbucket API}
|
13
|
+
s.description = %q{Provides a wrapper for Bitbucket API}
|
14
|
+
|
15
|
+
s.rubyforge_project = "bucketface"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_development_dependency('fakeweb', '~> 1.3')
|
23
|
+
s.add_development_dependency('jnunemaker-matchy', '~> 0.4.0')
|
24
|
+
s.add_development_dependency('mocha', '~> 0.9')
|
25
|
+
s.add_development_dependency('shoulda', '~> 2.11')
|
26
|
+
s.add_runtime_dependency('hashie', '~> 0.3.0')
|
27
|
+
s.add_runtime_dependency('httparty', '~> 0.6.1')
|
28
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
module Bucketface
|
2
|
+
class Client
|
3
|
+
include HTTParty
|
4
|
+
format :json
|
5
|
+
base_uri "https://api.bitbucket.org/1.0"
|
6
|
+
|
7
|
+
attr_reader :login
|
8
|
+
|
9
|
+
def initialize(auth={})
|
10
|
+
if auth[:password].nil?
|
11
|
+
@login = auth[:login]
|
12
|
+
@token = auth[:token]
|
13
|
+
self.class.basic_auth(nil, nil)
|
14
|
+
else
|
15
|
+
@login = auth[:login]
|
16
|
+
self.class.basic_auth(@login, auth[:password])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def user(login=self.login)
|
21
|
+
get("/users/#{login}/").user
|
22
|
+
end
|
23
|
+
|
24
|
+
def followers(login=self.login)
|
25
|
+
get("/users/#{login}/followers/").followers
|
26
|
+
end
|
27
|
+
|
28
|
+
def repo_followers(repo)
|
29
|
+
repo = Repository.new(repo)
|
30
|
+
get("/repositories/#{repo.user}/#{repo.to_s}/followers/").followers
|
31
|
+
end
|
32
|
+
|
33
|
+
def issue_followers(repo, id)
|
34
|
+
repo = Repository.new(repo)
|
35
|
+
get("/repositories/#{repo.user}/#{repo.to_s}/issues/#{id}/followers/").followers
|
36
|
+
end
|
37
|
+
|
38
|
+
def issues(repo)
|
39
|
+
repo = Repository.new(repo)
|
40
|
+
get("/repositories/#{repo.user}/#{repo.to_s}/issues/").issues
|
41
|
+
end
|
42
|
+
|
43
|
+
def issue(repo, id)
|
44
|
+
repo = Repository.new(repo)
|
45
|
+
get("/repositories/#{repo.user}/#{repo.to_s}/issues/#{id}/")
|
46
|
+
end
|
47
|
+
|
48
|
+
def repo(repo)
|
49
|
+
repo = Repository.new(repo)
|
50
|
+
get("/repositories/#{repo.user}/#{repo.to_s}/")
|
51
|
+
end
|
52
|
+
|
53
|
+
def list_repos(login=self.login)
|
54
|
+
get("/users/#{login}/").repositories
|
55
|
+
end
|
56
|
+
|
57
|
+
def branches(repo)
|
58
|
+
repo = Repository.new(repo)
|
59
|
+
get("/repositories/#{repo.user}/#{repo.to_s}/branches/")
|
60
|
+
end
|
61
|
+
|
62
|
+
def tags(repo)
|
63
|
+
repo = Repository.new(repo)
|
64
|
+
get("/repositories/#{repo.user}/#{repo.to_s}/tags/")
|
65
|
+
end
|
66
|
+
|
67
|
+
def open_issue(repo, title, body)
|
68
|
+
rep = Repository.new(repo)
|
69
|
+
post("/repositories/#{rep.user}/#{rep.to_s}/issues/", :body => {:title => title, :content => body})
|
70
|
+
end
|
71
|
+
|
72
|
+
def close_issue(repo, id)
|
73
|
+
repo = Repository.new(repo)
|
74
|
+
delete("/repositories/#{repo.user}/#{repo.to_s}/issues/#{id}/")
|
75
|
+
end
|
76
|
+
|
77
|
+
def changesets(repo)
|
78
|
+
repo = Repository.new(repo)
|
79
|
+
get_resource("/repositories/#{repo.user}/#{repo.to_s}/changesets/").changesets
|
80
|
+
end
|
81
|
+
|
82
|
+
def changeset(repo, changeset)
|
83
|
+
repo = Repository.new(repo)
|
84
|
+
get("/repositories/#{repo.user}/#{repo.to_s}/changesets/#{changeset}/")
|
85
|
+
end
|
86
|
+
|
87
|
+
def events(login=self.login)
|
88
|
+
get("/users/#{login}/events/").events
|
89
|
+
end
|
90
|
+
|
91
|
+
def repo_events(repo)
|
92
|
+
repo = Repository.new(repo)
|
93
|
+
get("/repositories/#{repo.user}/#{repo.to_s}/events/").events
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
def get(path, options = {})
|
98
|
+
Hashie::Mash.new(self.class.get(path, options))
|
99
|
+
end
|
100
|
+
|
101
|
+
def post(path, options = {})
|
102
|
+
Hashie::Mash.new(self.class.post(path, options))
|
103
|
+
end
|
104
|
+
|
105
|
+
def delete(path, options = {})
|
106
|
+
self.class.delete(path, options)
|
107
|
+
end
|
108
|
+
|
109
|
+
def get_resource(path, options ={})
|
110
|
+
get(path, {:query => options})
|
111
|
+
end
|
112
|
+
|
113
|
+
def post_resource(path, options = {})
|
114
|
+
post(path, options)
|
115
|
+
end
|
116
|
+
|
117
|
+
def self.delete(*args); handle_response super end
|
118
|
+
|
119
|
+
def self.handle_response(response)
|
120
|
+
case response.code
|
121
|
+
when 204 then return "Success!"
|
122
|
+
else
|
123
|
+
response
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Bucketface
|
2
|
+
class Repository
|
3
|
+
attr_accessor :username, :name
|
4
|
+
|
5
|
+
def initialize(repo)
|
6
|
+
case repo
|
7
|
+
when String
|
8
|
+
repo = repo.split("/")
|
9
|
+
@name = repo.pop
|
10
|
+
@username = repo.pop
|
11
|
+
when Repository
|
12
|
+
@username = repo.username
|
13
|
+
@name = repo.name
|
14
|
+
when Hash
|
15
|
+
@name = repo[:repo] ||= repo[:name]
|
16
|
+
@username = repo[:username] ||= repo[:user]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def user
|
21
|
+
@username
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
@name
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/bucketface.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
require 'httparty'
|
4
|
+
require 'hashie'
|
5
|
+
Hash.send :include, Hashie::HashExtensions
|
6
|
+
|
7
|
+
libdir = File.dirname(__FILE__)
|
8
|
+
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
9
|
+
|
10
|
+
require 'bucketface/repository'
|
11
|
+
require 'bucketface/client'
|
12
|
+
|
13
|
+
module Bucketface
|
14
|
+
extend SingleForwardable
|
15
|
+
|
16
|
+
class BucketfaceError < StandardError
|
17
|
+
attr_reader :data
|
18
|
+
|
19
|
+
def initialize(data)
|
20
|
+
@data = data
|
21
|
+
super
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.client; Client.new end
|
26
|
+
|
27
|
+
# Users
|
28
|
+
def_delegators :client, :user, :followers
|
29
|
+
|
30
|
+
# Repositories
|
31
|
+
def_delegators :client, :repo_followers, :repo, :list_repos, :branches, :tags
|
32
|
+
|
33
|
+
# Issues
|
34
|
+
def_delegators :client, :issue_followers, :issues, :issue
|
35
|
+
|
36
|
+
# Changesets
|
37
|
+
def_delegators :client, :changesets, :changeset
|
38
|
+
|
39
|
+
# Events
|
40
|
+
def_delegators :client, :events, :repo_events
|
41
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__)) + '/helper'
|
2
|
+
|
3
|
+
class BucketfaceTest < Test::Unit::TestCase
|
4
|
+
context "when authenticated" do
|
5
|
+
setup do
|
6
|
+
@client = Bucketface::Client.new(:login => 'cored', :token => '2U812')
|
7
|
+
end
|
8
|
+
|
9
|
+
should "authenticate via basic auth" do
|
10
|
+
stub_get('https://cored:2U812@api.bitbucket.org/1.0/users/cored/?', 'full_user.json')
|
11
|
+
client = Bucketface::Client.new(:login => 'cored', :password => '2U812')
|
12
|
+
user = client.user
|
13
|
+
user.is_private?.should == false
|
14
|
+
end
|
15
|
+
|
16
|
+
should "return followers for an user authenticated user" do
|
17
|
+
stub_get('/users/cored/followers/?', 'followers.json')
|
18
|
+
followers = @client.followers
|
19
|
+
followers.size.should == 3
|
20
|
+
end
|
21
|
+
|
22
|
+
should "open an issue" do
|
23
|
+
stub_post('/repositories/cored/test-repo/issues/', 'open_issue.json')
|
24
|
+
issue = @client.open_issue({:username => 'cored', :repo => 'test-repo'}, "testing", "testing")
|
25
|
+
issue.title.should == "new issue"
|
26
|
+
end
|
27
|
+
|
28
|
+
should "delete an issue" do
|
29
|
+
stub_delete('/repositories/cored/test-repo/issues/1/', 'close_issue.txt')
|
30
|
+
issue = @client.close_issue({:username => 'cored', :repo => 'test-repo'}, 1)
|
31
|
+
issue.should == "Success!"
|
32
|
+
end
|
33
|
+
|
34
|
+
should "update an issue"
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
context "user resource" do
|
39
|
+
should "return user info" do
|
40
|
+
stub_get("/users/cored/", "user.json")
|
41
|
+
user = Bucketface.user("cored")
|
42
|
+
user.username.should == 'cored'
|
43
|
+
end
|
44
|
+
|
45
|
+
should "return followers for a user" do
|
46
|
+
stub_get("/users/cored/followers/", "followers.json")
|
47
|
+
followers = Bucketface.followers("cored")
|
48
|
+
followers.size.should == 3
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "changeset resource" do
|
53
|
+
should "return a list of changeset for a giving repository" do
|
54
|
+
stub_get("/repositories/cored/test-repo/changesets/", "changesets.json")
|
55
|
+
changesets = Bucketface.changesets(:username => 'cored', :repo => 'test-repo')
|
56
|
+
changesets.size.should == 15
|
57
|
+
end
|
58
|
+
|
59
|
+
should "return an specific changeset for a giving repository" do
|
60
|
+
stub_get("/repositories/cored/test-repo/changesets/fa57572a9acf/", "changeset.json")
|
61
|
+
changeset = Bucketface.changeset({:username => 'cored', :repo => 'test-repo'}, 'fa57572a9acf')
|
62
|
+
changeset.author.should == 'jespern'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "events resource" do
|
67
|
+
should "return a list of events for a giving user" do
|
68
|
+
stub_get("/users/cored/events/", "events.json")
|
69
|
+
events = Bucketface.events('cored')
|
70
|
+
events.size.should == 5
|
71
|
+
events.first.repository.slug.should == 'test-repo'
|
72
|
+
end
|
73
|
+
|
74
|
+
should "return a list of events for a giving repository" do
|
75
|
+
stub_get("/repositories/cored/test-repo/events/", "repo_events.json")
|
76
|
+
events = Bucketface.repo_events(:username => 'cored', :repo => 'test-repo')
|
77
|
+
events.size.should == 6
|
78
|
+
events.first.repository.slug == 'test-repo'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context "repository resource" do
|
83
|
+
should "return list of followers for a giving repository" do
|
84
|
+
stub_get("/repositories/cored/test-repo/followers/", "repo_followers.json")
|
85
|
+
repo_followers = Bucketface.repo_followers({:user => "cored", :repo => "test-repo"})
|
86
|
+
repo_followers.size.should == 1
|
87
|
+
end
|
88
|
+
|
89
|
+
should "return repository info" do
|
90
|
+
stub_get("/repositories/cored/test-repo/", "repo.json")
|
91
|
+
repo = Bucketface.repo(:user => "cored", :repo => "test-repo")
|
92
|
+
repo.name.should == "test-repo"
|
93
|
+
end
|
94
|
+
|
95
|
+
should "list repositories for an user" do
|
96
|
+
stub_get("/users/cored/", "repos.json")
|
97
|
+
repos = Bucketface.list_repos("cored")
|
98
|
+
repos.first.name.should == "test-repo"
|
99
|
+
end
|
100
|
+
|
101
|
+
should "list branches in a giving repo" do
|
102
|
+
stub_get("/repositories/cored/test-repo/branches/", "branches.json")
|
103
|
+
branches = Bucketface.branches(:user => "cored", :repo => "test-repo")
|
104
|
+
branches.size.should == 1
|
105
|
+
assert branches.include?("default")
|
106
|
+
end
|
107
|
+
|
108
|
+
should "list all the tags in a giving repo" do
|
109
|
+
stub_get("/repositories/cored/test-repo/tags/", "tags.json")
|
110
|
+
tags = Bucketface.tags(:user => "cored", :repo => "test-repo")
|
111
|
+
tags.size.should == 6
|
112
|
+
assert tags.include?("0.6.4")
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context "issue resource" do
|
117
|
+
should "return the list of followers of an issue" do
|
118
|
+
stub_get("/repositories/cored/test-repo/issues/1/followers/", "issue_followers.json")
|
119
|
+
issue_followers = Bucketface.issue_followers({:user => "cored", :repo => "test-repo"},"1")
|
120
|
+
issue_followers.size.should == 1
|
121
|
+
end
|
122
|
+
|
123
|
+
should "return the list of issues for a giving repository" do
|
124
|
+
stub_get("/repositories/cored/test-repo/issues/", "issues.json")
|
125
|
+
issues = Bucketface.issues({:user => "cored", :repo => "test-repo"})
|
126
|
+
issues.size.should == 2
|
127
|
+
issues.first.title.should == "Another issue test"
|
128
|
+
end
|
129
|
+
|
130
|
+
should "return an individual issue" do
|
131
|
+
stub_get("/repositories/cored/test-repo/issues/1/", "issue.json")
|
132
|
+
issue = Bucketface.issue({:user => "cored", :repo => "test-repo"}, "1")
|
133
|
+
issue.title.should == "Test issue"
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
{
|
2
|
+
"default": {
|
3
|
+
"node": "10c1068f1171",
|
4
|
+
"files": [],
|
5
|
+
"author": "elpargo",
|
6
|
+
"timestamp": "2009-08-26 17:11:33",
|
7
|
+
"raw_node": "10c1068f117163e7c3e98d2a461799481367b727",
|
8
|
+
"parents": [
|
9
|
+
"041529d47395",
|
10
|
+
"b119fb3263f7"
|
11
|
+
],
|
12
|
+
"branch": "default",
|
13
|
+
"message": "- merging",
|
14
|
+
"revision": 132,
|
15
|
+
"size": 0
|
16
|
+
}
|
17
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
{
|
2
|
+
"node": "fa57572a9acf",
|
3
|
+
"files": [
|
4
|
+
{
|
5
|
+
"type": "modified",
|
6
|
+
"file": "piston/handler.py"
|
7
|
+
}
|
8
|
+
],
|
9
|
+
"author": "jespern",
|
10
|
+
"timestamp": "2009-09-09 12:55:07",
|
11
|
+
"raw_node": "fa57572a9acf7b66aa66f739af6d1391075f9f21",
|
12
|
+
"parents": [
|
13
|
+
"aaf0c2d64294"
|
14
|
+
],
|
15
|
+
"branch": "default",
|
16
|
+
"message": "warning in case of a model being registered twice under different handlers, configurable via PISTON_IGNORE_DUPE_MODELS",
|
17
|
+
"revision": 207,
|
18
|
+
"size": 561
|
19
|
+
}
|