fuselage 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.DS_Store +0 -0
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.markdown +65 -0
- data/Rakefile +15 -0
- data/examples/authenticated.rb +21 -0
- data/examples/simple.rb +6 -0
- data/fuselage.gemspec +25 -0
- data/lib/.DS_Store +0 -0
- data/lib/fuselage/api.rb +100 -0
- data/lib/fuselage/base.rb +27 -0
- data/lib/fuselage/blob.rb +31 -0
- data/lib/fuselage/commit.rb +49 -0
- data/lib/fuselage/error.rb +28 -0
- data/lib/fuselage/reference.rb +50 -0
- data/lib/fuselage/repository.rb +111 -0
- data/lib/fuselage/tag.rb +44 -0
- data/lib/fuselage/tree.rb +41 -0
- data/lib/fuselage/user.rb +80 -0
- data/lib/fuselage/version.rb +3 -0
- data/lib/fuselage.rb +31 -0
- data/test/base_test.rb +17 -0
- data/test/blob_test.rb +29 -0
- data/test/commits_test.rb +30 -0
- data/test/references_test.rb +38 -0
- data/test/repository_test.rb +103 -0
- data/test/stubs/blobs/tester/new +16 -0
- data/test/stubs/blobs/tester/old +18 -0
- data/test/stubs/commits/tester/new +36 -0
- data/test/stubs/commits/tester/old +58 -0
- data/test/stubs/refs/tester/all +58 -0
- data/test/stubs/refs/tester/master +20 -0
- data/test/stubs/refs/tester/new +20 -0
- data/test/stubs/repos/coreycollins/tester/branches +27 -0
- data/test/stubs/repos/coreycollins/tester/commits +71 -0
- data/test/stubs/repos/coreycollins/tester/main +41 -0
- data/test/stubs/repos/coreycollins/tester/tags +40 -0
- data/test/stubs/repos/show/coreycollins +39 -0
- data/test/stubs/repos/show/coreycollins-private +39 -0
- data/test/stubs/repos/show/gitpilot +39 -0
- data/test/stubs/repos/show/gitpilot-private +120 -0
- data/test/stubs/tags/tester/new +27 -0
- data/test/stubs/tags/tester/old +27 -0
- data/test/stubs/trees/tester/new +26 -0
- data/test/stubs/trees/tester/old +25 -0
- data/test/stubs/users/coreycollins +34 -0
- data/test/stubs/users/coreycollins-private +34 -0
- data/test/stubs/users/emails +0 -0
- data/test/stubs/users/followers +25 -0
- data/test/stubs/users/following +25 -0
- data/test/stubs/users/repositories +40 -0
- data/test/test_helper.rb +103 -0
- data/test/user_test.rb +60 -0
- metadata +139 -0
data/.DS_Store
ADDED
Binary file
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.markdown
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
#Fuselage
|
2
|
+
|
3
|
+
Fuselage is a light weight Ruby wrapper for the Github v3 api. It was inspired by the Github v2 Ruby wrapper octopi.
|
4
|
+
|
5
|
+
It was created for Gitpilot. Check us out at: http://www.gitpilot.com
|
6
|
+
|
7
|
+
##Credits
|
8
|
+
|
9
|
+
* Corey Collins
|
10
|
+
* JP Richardson
|
11
|
+
|
12
|
+
##Install
|
13
|
+
|
14
|
+
Fuselage can easily be installed as a Ruby gem:
|
15
|
+
|
16
|
+
$ [sudo] gem install fuselage
|
17
|
+
|
18
|
+
##Usage
|
19
|
+
|
20
|
+
To use fuselage just include it in your script:
|
21
|
+
|
22
|
+
require 'fuselage'
|
23
|
+
|
24
|
+
include Fuselage
|
25
|
+
|
26
|
+
###Authenicated
|
27
|
+
|
28
|
+
If you have genereated a access token through github, then you can use the authenicated api with this method:
|
29
|
+
|
30
|
+
authenicated do
|
31
|
+
repo = Repository.find('private-repo')
|
32
|
+
end
|
33
|
+
|
34
|
+
###Anonymous
|
35
|
+
|
36
|
+
Otherwise, if you are not authenticated there is no need to wrap your method call in the block. Like:
|
37
|
+
|
38
|
+
repo = Repository.find('public-repo')
|
39
|
+
|
40
|
+
|
41
|
+
## API Completed
|
42
|
+
|
43
|
+
This is still a work in progress and not all of the api has been mapped yet. So far these have been mapped.
|
44
|
+
|
45
|
+
**1. Users**
|
46
|
+
|
47
|
+
**2. Repos**
|
48
|
+
|
49
|
+
**3. Git Data**
|
50
|
+
|
51
|
+
##License
|
52
|
+
|
53
|
+
Copyright (c) 2011, Gitpilot LLC
|
54
|
+
|
55
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
56
|
+
purpose with or without fee is hereby granted, provided that the above
|
57
|
+
copyright notice and this permission notice appear in all copies.
|
58
|
+
|
59
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
60
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
61
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
62
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
63
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
64
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
65
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'bundler'
|
4
|
+
|
5
|
+
Bundler::GemHelper.install_tasks
|
6
|
+
|
7
|
+
require 'rake/testtask'
|
8
|
+
Rake::TestTask.new(:test) do |test|
|
9
|
+
test.libs << 'lib' << 'test'
|
10
|
+
test.libs << File.dirname(__FILE__)
|
11
|
+
test.pattern = 'test/**/*_test.rb'
|
12
|
+
test.verbose = false
|
13
|
+
end
|
14
|
+
|
15
|
+
task :default => :test
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), %w[.. lib cockpit]))
|
2
|
+
|
3
|
+
include Fuselage
|
4
|
+
|
5
|
+
access_token = "YOUR ACCESS TOKEN"
|
6
|
+
|
7
|
+
#Creating a branch on a private repo
|
8
|
+
|
9
|
+
authenticated(access_token) do
|
10
|
+
|
11
|
+
#Find the repo.
|
12
|
+
repo = Repository.find('private-repo')
|
13
|
+
|
14
|
+
# Get the most recent commit to point the reference to.
|
15
|
+
recent_commit = repo.most_recent_commit
|
16
|
+
|
17
|
+
#Create the reference
|
18
|
+
ref = Reference.create(repo.name, 'new-branch', recent_commit.sha)
|
19
|
+
|
20
|
+
puts ref
|
21
|
+
end
|
data/examples/simple.rb
ADDED
data/fuselage.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "fuselage/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "fuselage"
|
7
|
+
s.version = Fuselage::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Corey Collins"]
|
10
|
+
s.email = ["corey@gitpilot.com"]
|
11
|
+
s.homepage = ""
|
12
|
+
s.summary = %q{LightWeight Github API v3 Wrapper}
|
13
|
+
s.description = %q{LightWeight Github API v3 Wrapper}
|
14
|
+
|
15
|
+
s.rubyforge_project = "fuselage"
|
16
|
+
|
17
|
+
s.add_development_dependency "rspec"
|
18
|
+
s.add_development_dependency "fakeweb"
|
19
|
+
s.add_dependency "httparty"
|
20
|
+
|
21
|
+
s.files = `git ls-files`.split("\n")
|
22
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
23
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
24
|
+
s.require_paths = ["lib"]
|
25
|
+
end
|
data/lib/.DS_Store
ADDED
Binary file
|
data/lib/fuselage/api.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
module Fuselage
|
4
|
+
# Dummy class, so AnonymousApi and AuthApi have somewhere to inherit from
|
5
|
+
class Api
|
6
|
+
attr_accessor :token, :read_only
|
7
|
+
end
|
8
|
+
|
9
|
+
# Used for accessing the Github API anonymously
|
10
|
+
class AnonymousApi < Api
|
11
|
+
include HTTParty
|
12
|
+
include Singleton
|
13
|
+
base_uri "https://api.github.com"
|
14
|
+
|
15
|
+
def read_only?
|
16
|
+
true
|
17
|
+
end
|
18
|
+
|
19
|
+
def auth_parameters
|
20
|
+
{ }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class AuthApi < Api
|
25
|
+
include HTTParty
|
26
|
+
include Singleton
|
27
|
+
base_uri "https://api.github.com"
|
28
|
+
|
29
|
+
def read_only?
|
30
|
+
false
|
31
|
+
end
|
32
|
+
|
33
|
+
def auth_parameters
|
34
|
+
{:access_token => Api.me.token }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# This is the real API class.
|
39
|
+
#
|
40
|
+
# API requests are limited to 60 per minute.
|
41
|
+
#
|
42
|
+
# Sets up basic methods for accessing the API.
|
43
|
+
class Api
|
44
|
+
@@api = Fuselage::AnonymousApi.instance
|
45
|
+
@@authenticated = false
|
46
|
+
|
47
|
+
include Singleton
|
48
|
+
|
49
|
+
RETRYABLE_STATUS = [403]
|
50
|
+
MAX_RETRIES = 5
|
51
|
+
# Would be nice if cattr_accessor was available, oh well.
|
52
|
+
|
53
|
+
# We use this to check if we use the auth or anonymous api
|
54
|
+
def self.authenticated
|
55
|
+
@@authenticated
|
56
|
+
end
|
57
|
+
|
58
|
+
# We set this to true when the user has auth'd.
|
59
|
+
def self.authenticated=(value)
|
60
|
+
@@authenticated = value
|
61
|
+
end
|
62
|
+
|
63
|
+
# The API we're using
|
64
|
+
def self.api
|
65
|
+
@@api
|
66
|
+
end
|
67
|
+
|
68
|
+
class << self
|
69
|
+
alias_method :me, :api
|
70
|
+
end
|
71
|
+
|
72
|
+
# set the API we're using
|
73
|
+
def self.api=(value)
|
74
|
+
@@api = value
|
75
|
+
end
|
76
|
+
|
77
|
+
def get(path, params = {}, klass=nil)
|
78
|
+
resp = self.class.get(path, { :query => params.merge(auth_parameters) })
|
79
|
+
raise NotFound, klass || self.class if resp.code.to_i == 404
|
80
|
+
raise APIError,
|
81
|
+
"GitHub returned status #{resp.code}" unless resp.code.to_i == 200 || resp.code.to_i == 201
|
82
|
+
resp
|
83
|
+
end
|
84
|
+
|
85
|
+
def post(path, params = {}, klass=nil)
|
86
|
+
resp = self.class.post(path, { :query => auth_parameters, :body => params.to_json } )
|
87
|
+
raise NotFound, klass || self.class if resp.code.to_i == 404
|
88
|
+
raise APIError,
|
89
|
+
"GitHub returned status #{resp.code}" unless resp.code.to_i == 200 || resp.code.to_i == 201
|
90
|
+
resp
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def method_missing(method, *args)
|
96
|
+
api.send(method, *args)
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Fuselage
|
2
|
+
class Base
|
3
|
+
|
4
|
+
attr_accessor :api
|
5
|
+
|
6
|
+
def initialize(attributes={})
|
7
|
+
# Useful for finding out what attr_accessor needs for classes
|
8
|
+
# puts caller.first.inspect
|
9
|
+
# puts "#{self.class.inspect} #{attributes.keys.map { |s| s.to_sym }.inspect}"
|
10
|
+
attributes.each do |key, value|
|
11
|
+
method = "#{key}="
|
12
|
+
self.send(method, value) if respond_to? method
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.get(path, params={})
|
17
|
+
response = Api.api.get(path, params, self)
|
18
|
+
response.parsed_response
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.post(path, params={})
|
22
|
+
response = Api.api.post(path, params, self)
|
23
|
+
response.parsed_response
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Fuselage
|
2
|
+
class Blob < Base
|
3
|
+
|
4
|
+
attr_accessor :sha, :content, :encoding
|
5
|
+
|
6
|
+
# Find a blob
|
7
|
+
#
|
8
|
+
# examples:
|
9
|
+
# Blob.find('cockpit', '45f6d8e74e145b910be4e15f67ef3892fe7abb26')
|
10
|
+
def self.find(repo, sha, user=nil)
|
11
|
+
raise AuthenticationRequired unless Api.authenticated
|
12
|
+
user ||= User.current.login
|
13
|
+
Blob.new(get("/repos/#{user}/#{repo}/git/blobs/#{sha}").merge(:sha => sha))
|
14
|
+
end
|
15
|
+
|
16
|
+
# Create a blob
|
17
|
+
#
|
18
|
+
# Content must be in utf-8 encoding.
|
19
|
+
# TODO: Add suport for base-64.
|
20
|
+
#
|
21
|
+
# examples:
|
22
|
+
# Blob.create('cockpit', 'Some really cool data.')
|
23
|
+
def self.create(repo, content)
|
24
|
+
raise AuthenticationRequired unless Api.authenticated
|
25
|
+
params = {:content => content, :encoding => 'utf-8'}
|
26
|
+
user = User.current.login
|
27
|
+
Blob.new(post("/repos/#{user}/#{repo}/git/blobs", params))
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Fuselage
|
2
|
+
class Commit < Base
|
3
|
+
|
4
|
+
attr_accessor :sha, :message, :parents, :author, :url, :tree, :committer
|
5
|
+
|
6
|
+
# Find a commit
|
7
|
+
#
|
8
|
+
# examples:
|
9
|
+
# Blob.find('cockpit', '45f6d8e74e145b910be4e15f67ef3892fe7abb26')
|
10
|
+
def self.find(repo, sha, user=nil)
|
11
|
+
raise AuthenticationRequired unless Api.authenticated
|
12
|
+
user ||= User.current.login
|
13
|
+
Commit.new(get("/repos/#{user}/#{repo}/commits/#{sha}"))
|
14
|
+
end
|
15
|
+
|
16
|
+
# Create a commit
|
17
|
+
#
|
18
|
+
# Options:
|
19
|
+
# :author
|
20
|
+
# :name
|
21
|
+
# :date
|
22
|
+
# :email
|
23
|
+
# :committer
|
24
|
+
# :name
|
25
|
+
# :date
|
26
|
+
# :email
|
27
|
+
#
|
28
|
+
# examples:
|
29
|
+
# Commit.create('cockpit', 'This is a new commit', '45f6d8e74e145b910be4e15f67ef3892fe7abb26', ['45f6d8e74e145b910be4e15f67ef3892fe7abb26'])
|
30
|
+
#
|
31
|
+
# Commit.create('cockpit', 'Comit with author', '45f6d8e74e145b910be4e15f67ef3892fe7abb26', ['45f6d8e74e145b910be4e15f67ef3892fe7abb26'], {
|
32
|
+
# :author => {:name => 'Corey', :email => 'corey@gitpilot.com'}
|
33
|
+
# })
|
34
|
+
def self.create(repo, message, tree, parents=[], options={})
|
35
|
+
raise AuthenticationRequired unless Api.authenticated
|
36
|
+
params = {:message => message, :tree => tree, :parents => parents}.merge(options)
|
37
|
+
user = User.current.login
|
38
|
+
Commit.new(post("/repos/#{user}/#{repo}/git/commits", params))
|
39
|
+
end
|
40
|
+
|
41
|
+
def merge_attributes(attributes)
|
42
|
+
attributes.each do |key, value|
|
43
|
+
method = "#{key}="
|
44
|
+
self.send(method, value) if respond_to? method
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Fuselage
|
2
|
+
|
3
|
+
class RegisterError < StandardError; end
|
4
|
+
|
5
|
+
class FormatError < StandardError
|
6
|
+
def initialize(f)
|
7
|
+
super("Got unexpected format (got #{f.first} for #{f.last})")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class AuthenticationRequired < StandardError
|
12
|
+
end
|
13
|
+
|
14
|
+
class APIError < StandardError
|
15
|
+
end
|
16
|
+
|
17
|
+
class InvalidLogin < StandardError
|
18
|
+
end
|
19
|
+
|
20
|
+
class ArgumentMustBeHash < Exception; end
|
21
|
+
|
22
|
+
class NotFound < Exception
|
23
|
+
def initialize(klass)
|
24
|
+
super "The #{klass.to_s.split("::").last} could not be found or created. It could be private."
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Fuselage
|
2
|
+
class Reference < Base
|
3
|
+
|
4
|
+
attr_accessor :ref, :url, :object
|
5
|
+
|
6
|
+
# Find a reference
|
7
|
+
#
|
8
|
+
# ref must have 'heads/' in front of branch name
|
9
|
+
#
|
10
|
+
# examples:
|
11
|
+
# Reference.find('cockpit', 'hads/master')
|
12
|
+
def self.find(repo, ref, user=nil)
|
13
|
+
raise AuthenticationRequired unless Api.authenticated
|
14
|
+
user ||= User.current.login
|
15
|
+
Reference.new(get("/repos/#{user}/#{repo}/git/refs/#{ref}"))
|
16
|
+
end
|
17
|
+
|
18
|
+
# Finds all the refs for a given repo.
|
19
|
+
def self.find_all(repo, user=nil)
|
20
|
+
raise AuthenticationRequired unless Api.authenticated
|
21
|
+
user ||= User.current.login
|
22
|
+
refs = []
|
23
|
+
get("/repos/#{user}/#{repo}/git/refs").each { |r| refs << Reference.new(r) }
|
24
|
+
refs
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.create(repo, ref, sha)
|
28
|
+
raise AuthenticationRequired unless Api.authenticated
|
29
|
+
params = {:ref => ref, :sha => sha}
|
30
|
+
user = User.current.login
|
31
|
+
Reference.new(post("/repos/#{user}/#{repo}/git/refs", params))
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.update(repo, ref, sha, force=true, user=nil)
|
35
|
+
raise AuthenticationRequired unless Api.authenticated
|
36
|
+
params = {:force => force, :sha => sha}
|
37
|
+
user ||= User.current.login
|
38
|
+
Reference.new(post("/repos/#{user}/#{repo}/git/refs/#{ref}", params))
|
39
|
+
end
|
40
|
+
|
41
|
+
def sha
|
42
|
+
object['sha'] if object
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_s
|
46
|
+
ref
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Fuselage
|
2
|
+
class Repository < Base
|
3
|
+
|
4
|
+
attr_accessor :description, :url, :forks, :name, :homepage, :watchers,
|
5
|
+
:owner, :private, :fork, :open_issues, :pledgie, :size
|
6
|
+
|
7
|
+
|
8
|
+
# Finds a repo with current authenticated user
|
9
|
+
#
|
10
|
+
def self.find(repo, options={})
|
11
|
+
options = {:type => 'all'}.merge(options)
|
12
|
+
if options[:user]
|
13
|
+
Repository.new(get("/repos/#{options[:user]}/#{repo}", {:type => options[:type]}))
|
14
|
+
else
|
15
|
+
raise AuthenticationRequired unless Api.authenticated
|
16
|
+
Repository.new(get("/repos/#{User.current.login}/#{repo}", {:type => options[:type]}))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Finds all public repos identified by the given username
|
21
|
+
#
|
22
|
+
def self.find_all(options={})
|
23
|
+
options = {:type => 'all'}.merge(options)
|
24
|
+
repos = []
|
25
|
+
if options[:user]
|
26
|
+
get("/users/#{options[:user]}/repos", {:type => options[:type]}).each { |r| repos << Repository.new(r) }
|
27
|
+
else
|
28
|
+
raise AuthenticationRequired unless Api.authenticated
|
29
|
+
get("/user/repos", {:type => options[:type]}).each { |r| repos << Repository.new(r) }
|
30
|
+
end
|
31
|
+
repos
|
32
|
+
end
|
33
|
+
|
34
|
+
# Finds all public repos identified by the given organization
|
35
|
+
#
|
36
|
+
def self.find_by_organization(organization, options={})
|
37
|
+
options = {:type => 'all'}.merge(options)
|
38
|
+
repos = []
|
39
|
+
get("/orgs/#{organization}/repos", {:type => options[:type]}).each { |r| repos << Repository.new(r) }
|
40
|
+
repos
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.create(name, options={})
|
44
|
+
raise AuthenticationRequired unless Api.authenticated
|
45
|
+
Repository.new(post('/user/repos', {:name => name}.merge(options)))
|
46
|
+
end
|
47
|
+
|
48
|
+
def tags
|
49
|
+
raise AuthenticationRequired unless Api.authenticated
|
50
|
+
tags = []
|
51
|
+
Repository.get("/repos/#{User.current.login}/#{self.name}/tags").each do |t|
|
52
|
+
tag = Tag.new
|
53
|
+
tag.tag = t['name']
|
54
|
+
if t['commit']
|
55
|
+
tag.object = t['commit']
|
56
|
+
tag.object['type'] = 'commit'
|
57
|
+
end
|
58
|
+
tags << tag
|
59
|
+
end
|
60
|
+
tags
|
61
|
+
end
|
62
|
+
|
63
|
+
def branches
|
64
|
+
raise AuthenticationRequired unless Api.authenticated
|
65
|
+
branches = []
|
66
|
+
Repository.get("/repos/#{User.current.login}/#{self.name}/branches").each do |b|
|
67
|
+
branch = Reference.new
|
68
|
+
branch.ref = 'ref/heads/' + b['name']
|
69
|
+
branch.url = b['url']
|
70
|
+
if b['commit']
|
71
|
+
branch.object = b['commit']
|
72
|
+
branch.object['type'] = 'commit'
|
73
|
+
end
|
74
|
+
branches << branch
|
75
|
+
end
|
76
|
+
branches
|
77
|
+
end
|
78
|
+
|
79
|
+
def commits(options={})
|
80
|
+
raise AuthenticationRequired unless Api.authenticated
|
81
|
+
commits = []
|
82
|
+
Repository.get("/repos/#{User.current.login}/#{self.name}/commits", options).each do |c|
|
83
|
+
commit = Commit.new(c)
|
84
|
+
if c['commit']
|
85
|
+
commit.merge_attributes(c['commit'])
|
86
|
+
end
|
87
|
+
commits << commit
|
88
|
+
end
|
89
|
+
commits
|
90
|
+
end
|
91
|
+
|
92
|
+
def most_recent_commit(ref_sha)
|
93
|
+
commits = self.commits(:sha => ref_sha)
|
94
|
+
commits.first
|
95
|
+
end
|
96
|
+
|
97
|
+
def create_branch(name, parent_sha)
|
98
|
+
Reference.create(self.name, "refs/heads/#{name}", parent_sha)
|
99
|
+
end
|
100
|
+
|
101
|
+
def to_s
|
102
|
+
name
|
103
|
+
end
|
104
|
+
|
105
|
+
def pp
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
data/lib/fuselage/tag.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
module Fuselage
|
2
|
+
class Tag < Base
|
3
|
+
attr_accessor :tag, :sha, :message, :tagger, :object, :url
|
4
|
+
|
5
|
+
# Find a tag
|
6
|
+
#
|
7
|
+
# examples:
|
8
|
+
# Tag.find('cockpit', '45f6d8e74e145b910be4e15f67ef3892fe7abb26')
|
9
|
+
def self.find(repo, sha, user=nil)
|
10
|
+
raise AuthenticationRequired unless Api.authenticated
|
11
|
+
user ||= User.current.login
|
12
|
+
Tag.new(get("/repos/#{user}/#{repo}/git/tags/#{sha}"))
|
13
|
+
end
|
14
|
+
|
15
|
+
# Create a tag
|
16
|
+
#
|
17
|
+
#
|
18
|
+
# Options:
|
19
|
+
# :type, values: 'commit', 'tree', and 'blob'. default is commit
|
20
|
+
# :tagger
|
21
|
+
# :name
|
22
|
+
# :date
|
23
|
+
# :email
|
24
|
+
#
|
25
|
+
# examples:
|
26
|
+
# Tag.create('cockpit', v1.0', 'New tag', '45f6d8e74e145b910be4e15f67ef3892fe7abb26')
|
27
|
+
#
|
28
|
+
# Commit.create('cockpit', v1.0', 'New tag', '45f6d8e74e145b910be4e15f67ef3892fe7abb26', {
|
29
|
+
# :tagger => {:name => 'Corey', :email => 'corey@gitpilot.com'}
|
30
|
+
# })
|
31
|
+
def self.create(repo, tag, message, object, options={})
|
32
|
+
raise AuthenticationRequired unless Api.authenticated
|
33
|
+
options = {:type => 'commit'}.merge(options)
|
34
|
+
params = {:tag => tag, :message => message, :object => object}.merge(options)
|
35
|
+
user = User.current.login
|
36
|
+
Tag.new(post("/repos/#{user}/#{repo}/git/blobs", params))
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_s
|
40
|
+
tag
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Fuselage
|
2
|
+
class Tree < Base
|
3
|
+
|
4
|
+
attr_accessor :sha, :url, :tree, :path, :mode
|
5
|
+
|
6
|
+
# Find a tree
|
7
|
+
#
|
8
|
+
# examples:
|
9
|
+
# Tree.find('cockpit', '45f6d8e74e145b910be4e15f67ef3892fe7abb26')
|
10
|
+
def self.find(repo, sha, user=nil)
|
11
|
+
raise AuthenticationRequired unless Api.authenticated
|
12
|
+
user ||= User.current.login
|
13
|
+
Commit.new(get("/repos/#{user}/#{repo}/trees/#{sha}"))
|
14
|
+
end
|
15
|
+
|
16
|
+
# Create a tree
|
17
|
+
#
|
18
|
+
# Tree Hash:
|
19
|
+
# :path => 'file',
|
20
|
+
# :mode => '100644', refer to http://developer.github.com/v3/git/trees/ for modes.
|
21
|
+
# :type => 'commit', values: 'commit', 'tree', and 'blob'.
|
22
|
+
# :sha => '45f6d8e74e145b910be4e15f67ef3892fe7abb26'
|
23
|
+
# or
|
24
|
+
# :content => 'Some UTF-8 Encoded Content'
|
25
|
+
#
|
26
|
+
# Options:
|
27
|
+
# :type, values: 'commit', 'tree', and 'blob'. default is commit
|
28
|
+
# :tagger
|
29
|
+
# :name
|
30
|
+
# :date
|
31
|
+
# :email
|
32
|
+
#
|
33
|
+
def self.create(repo, tree_hashes=[], options={})
|
34
|
+
raise AuthenticationRequired unless Api.authenticated
|
35
|
+
params = {:tree => tree_hashes }.merge(options)
|
36
|
+
user = User.current.login
|
37
|
+
Tree.new(post("/repos/#{user}/#{repo}/git/trees", params))
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|