ddollar-octopi 0.0.13

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.
@@ -0,0 +1,3 @@
1
+ examples/github.yml
2
+ rdoc/
3
+ pkg/
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Felipe Coury
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,169 @@
1
+ = octopi
2
+
3
+ Octopi is a Ruby interface to GitHub API v2 (http://develop.github.com).
4
+
5
+ To install it as a Gem, just run:
6
+
7
+ $ sudo gem install octopi
8
+
9
+ Get notifications via Twitter, following @octopi_gem:
10
+ http://twitter.com/octopi_gem
11
+
12
+ == Authenticated Usage
13
+
14
+ === Seamless authentication using .gitconfig defaults
15
+
16
+ If you have your <tt>~/.gitconfig</tt> file in place, and you have a [github] section (if you don't, take a look at this GitHub Guides entry: http://github.com/guides/tell-git-your-user-name-and-email-address), you can use seamless authentication using this method:
17
+
18
+ authenticated do |g|
19
+ repo = g.repository("api-labrat")
20
+ (...)
21
+ end
22
+
23
+ === Explicit authentication
24
+
25
+ Sometimes, you may not want to get authentication data from <tt>~/.gitconfig</tt>. You want to use GitHub API authenticated as a third party. For this use case, you have a couple of options too.
26
+
27
+ <b>1. Providing login and token inline:</b>
28
+
29
+ authenticated_with "mylogin", "mytoken" do |g|
30
+ repo = g.repository("api-labrat")
31
+ issue = repo.open_issue :title => "Sample issue",
32
+ :body => "This issue was opened using GitHub API and Octopi"
33
+ puts issue.number
34
+ end
35
+
36
+ <b>2. Providing a YAML file with authentication information:</b>
37
+
38
+ Use the following format:
39
+
40
+ #
41
+ # Octopi GitHub API configuration file
42
+ #
43
+
44
+ # GitHub user login and token
45
+ login: github-username
46
+ token: github-token
47
+
48
+ # Trace level
49
+ # Possible values:
50
+ # false - no tracing, same as if the param is ommited
51
+ # true - will output each POST or GET operation to the stdout
52
+ # curl - same as true, but in addition will output the curl equivalent of each command (for debugging)
53
+ trace: curl
54
+
55
+ And change the way you connect to:
56
+
57
+ authenticated_with :config => "github.yml" do |g|
58
+ (...)
59
+ end
60
+
61
+ == Anonymous Usage
62
+
63
+ This reflects the usage of the API to retrieve information on a read-only fashion, where the user doesn't have to be authenticated.
64
+
65
+ === Users API
66
+
67
+ Getting user information
68
+
69
+ user = User.find("fcoury")
70
+ puts "#{user.name} is being followed by #{user.followers.join(", ")} and following #{user.following.join(", ")}"
71
+
72
+ The bang methods `followers!` and `following!` retrieves a full User object for each user login returned, so it has to be used carefully.
73
+
74
+ user.followers!.each do |u|
75
+ puts " - #{u.name} (#{u.login}) has #{u.public_repo_count} repo(s)"
76
+ end
77
+
78
+ Searching for user
79
+
80
+ users = User.find_all("silva")
81
+ puts "#{users.size} users found for 'silva':"
82
+ users.each do |u|
83
+ puts " - #{u.name}"
84
+ end
85
+
86
+ === Repositories API
87
+
88
+ repo = user.repository("octopi") # same as: Repository.find("fcoury", "octopi")
89
+ puts "Repository: #{repo.name} - #{repo.description} (by #{repo.owner}) - #{repo.url}"
90
+ puts " Tags: #{repo.tags and repo.tags.map {|t| t.name}.join(", ")}"
91
+
92
+ Search:
93
+
94
+ repos = Repository.find_all("ruby", "git")
95
+ puts "#{repos.size} repository(ies) with 'ruby' and 'git':"
96
+ repos.each do |r|
97
+ puts " - #{r.name}"
98
+ end
99
+
100
+ Issues API integrated into the Repository object:
101
+
102
+ issue = repo.issues.first
103
+ puts "First open issue: #{issue.number} - #{issue.title} - Created at: #{issue.created_at}"
104
+
105
+ Single issue information:
106
+
107
+ issue = repo.issue(11)
108
+
109
+ Commits API information from a Repository object:
110
+
111
+ first_commit = repo.commits.first
112
+ puts "First commit: #{first_commit.id} - #{first_commit.message} - by #{first_commit.author['name']}"
113
+
114
+ Single commit information:
115
+
116
+ puts "Diff:"
117
+ first_commit.details.modified.each {|m| puts "#{m['filename']} DIFF: #{m['diff']}" }
118
+
119
+ == Tracing
120
+
121
+ === Levels
122
+
123
+ You can can use tracing to enable better debugging output when something goes wrong. There are 3 tracing levels:
124
+
125
+ * false (default) - no tracing
126
+ * true - will output each GET and POST calls, along with URL and params
127
+ * curl - same as true, but additionally outputs the curl command to replicate the issue
128
+
129
+ If you choose curl tracing, the curl command equivalent to each command sent to GitHub will be output to the stdout, like this example:
130
+
131
+ => Trace on: curl
132
+ POST: /issues/open/webbynode/api-labrat params: body=This issue was opened using GitHub API and Octopi, title=Sample issue
133
+ ===== curl version
134
+ curl -F 'body=This issue was opened using GitHub API and Octopi' -F 'login=mylogin' -F 'token=mytoken' -F 'title=Sample issue' http://github.com/api/v2/issues/open/webbynode/api-labrat
135
+ ==================
136
+
137
+ === Enabling
138
+
139
+ Tracing can be enabled in different ways, depending on the API feature you're using:
140
+
141
+ <b>Anonymous (this will be improved later):</b>
142
+
143
+ ANONYMOUS_API.trace_level = "trace-level"
144
+
145
+ <b>Seamless authenticated</b>
146
+
147
+ authenticated :trace => "trace-level" do |g|; ...; end
148
+
149
+ <b>Explicitly authenticated</b>
150
+
151
+ Current version of explicit authentication requires a :config param to a YAML file to allow tracing. For enabling tracing on a YAML file refer to the config.yml example presented on the Explicit authentication section.
152
+
153
+ == Author
154
+
155
+ * Felipe Coury - http://felipecoury.com
156
+ * HasMany.info blog - http://hasmany.info
157
+
158
+ == Contributors
159
+
160
+ In alphabetical order:
161
+
162
+ * Brandon Calloway - http://github.com/bcalloway
163
+ * runpaint - http://github.com/runpaint
164
+
165
+ Thanks guys!
166
+
167
+ == Copyright
168
+
169
+ Copyright (c) 2009 Felipe Coury. See LICENSE for details.
@@ -0,0 +1,83 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "octopi"
8
+ gem.summary = %Q{A Ruby interface to GitHub API v2}
9
+ gem.email = "felipe.coury@gmail.com"
10
+ gem.homepage = "http://github.com/fcoury/octopi"
11
+ gem.authors = ["Felipe Coury"]
12
+ gem.rubyforge_project = "octopi"
13
+
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ rescue LoadError
17
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
18
+ end
19
+
20
+ begin
21
+ require 'rake/contrib/sshpublisher'
22
+ namespace :rubyforge do
23
+
24
+ desc "Release gem and RDoc documentation to RubyForge"
25
+ task :release => ["rubyforge:release:gem", "rubyforge:release:docs"]
26
+
27
+ namespace :release do
28
+ desc "Publish RDoc to RubyForge."
29
+ task :docs => [:rdoc] do
30
+ config = YAML.load(
31
+ File.read(File.expand_path('~/.rubyforge/user-config.yml'))
32
+ )
33
+
34
+ host = "#{config['username']}@rubyforge.org"
35
+ remote_dir = "/var/www/gforge-projects/octopi/"
36
+ local_dir = 'rdoc'
37
+
38
+ Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
39
+ end
40
+ end
41
+ end
42
+ rescue LoadError
43
+ puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured."
44
+ end
45
+
46
+ require 'rake/testtask'
47
+ Rake::TestTask.new(:test) do |test|
48
+ test.libs << 'lib' << 'test'
49
+ test.pattern = 'test/**/*_test.rb'
50
+ test.verbose = false
51
+ end
52
+
53
+ begin
54
+ require 'rcov/rcovtask'
55
+ Rcov::RcovTask.new do |test|
56
+ test.libs << 'test'
57
+ test.pattern = 'test/**/*_test.rb'
58
+ test.verbose = true
59
+ end
60
+ rescue LoadError
61
+ task :rcov do
62
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
63
+ end
64
+ end
65
+
66
+
67
+ task :default => :test
68
+
69
+ require 'rake/rdoctask'
70
+ Rake::RDocTask.new do |rdoc|
71
+ if File.exist?('VERSION.yml')
72
+ config = YAML.load(File.read('VERSION.yml'))
73
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
74
+ else
75
+ version = ""
76
+ end
77
+
78
+ rdoc.rdoc_dir = 'rdoc'
79
+ rdoc.title = "octopi #{version}"
80
+ rdoc.rdoc_files.include('README*')
81
+ rdoc.rdoc_files.include('lib/**/*.rb')
82
+ end
83
+
@@ -0,0 +1,4 @@
1
+ ---
2
+ :patch: 13
3
+ :major: 0
4
+ :minor: 0
@@ -0,0 +1,100 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'octopi')
2
+
3
+ USAGE_MSG = <<EOF
4
+ Usage: #{$0} <user> [<directory>]
5
+
6
+ Performs a backup of the named user's GitHub.com data.
7
+
8
+ This script will fetch the repositories, along with their metadata and
9
+ associated issues, for the named user. It will also retrieve the user's
10
+ profile, and those of his followers. This data will be stored in
11
+ <directory>/<user>. If a directory is not supplied, ~/.github-backup will be
12
+ used instead.
13
+ EOF
14
+ # TODO: Accept list of targets as argument. The main use case is somebody
15
+ # wanting all of their repositories checked out, without the performane hit
16
+ # and clutter of the extraneous metadata,
17
+ include Octopi
18
+
19
+ class Object
20
+ def to_yaml_file(file)
21
+ File.open("#{file}.yaml", 'w') do |f|
22
+ YAML.dump(self, f)
23
+ end
24
+ end
25
+ end
26
+
27
+ TARGETS = [:user, :followers, :repositories, :issues]
28
+
29
+ @user, @basedir = ARGV
30
+ raise ArgumentError, USAGE_MSG unless @user
31
+ @basedir ||= File.expand_path("~/.github-backup")
32
+ @basedir = File.join(@basedir,@user)
33
+ TARGETS.map{|k| k.to_s}.each do |dir|
34
+ dir = File.join(@basedir,dir)
35
+ FileUtils.mkdir_p(dir) unless File.exists? dir
36
+ end
37
+
38
+ @user = User.find(@user)
39
+
40
+ def user
41
+ puts "* Saving profile"
42
+ @user.to_yaml_file(@user.login)
43
+ end
44
+
45
+ def followers
46
+ @user.followers!.each do |follower|
47
+ puts "* #{follower.login} (#{follower.name})"
48
+ follower.to_yaml_file(follower.login)
49
+ end
50
+ end
51
+
52
+ def repositories
53
+ @user.repositories.each do |repo|
54
+ puts "* #{repo.name} (#{repo.description})\n---"
55
+
56
+ git_dir = File.join(repo.name,'.git')
57
+ # FIXME: Instead of just checking for a Git directory, we could try `git
58
+ # pull`, and if that indicates that the repository doesn't exist, `git
59
+ # clone`
60
+ if File.exists? git_dir
61
+ Dir.chdir repo.name do
62
+ # FIXME: If this fails, try deleting the clone and re-cloning?
63
+ # FIXME: Confirm this is the best solution as opposed to re-cloning
64
+ # every time, using `git fetch` or `git clone --mirror`.
65
+ system("git pull")
66
+ end
67
+ else
68
+ system("git clone #{repo.clone_url}")
69
+ end
70
+ repo.to_yaml_file(repo.name)
71
+ puts
72
+ end
73
+ end
74
+
75
+ # TODO: For forked repositories whose parents have issue trackers, get their
76
+ # issues instead.
77
+ def issues
78
+ FileUtils.mkdir_p @user.repositories.map{|r| r.name}
79
+ @user.repositories.each do |repo|
80
+ puts "#{repo.name}"
81
+ Dir.chdir(repo.name) do
82
+ repo.all_issues.each do |issue|
83
+ puts "* #{issue.title} [#{issue.state}]"
84
+ issue.to_yaml_file(issue.number)
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ TARGETS.each do |target|
91
+ target.to_s.each do |title|
92
+ puts title.capitalize
93
+ title.length.times {print '#'}
94
+ end
95
+ puts
96
+ Dir.chdir(File.join(@basedir, target.to_s)) do
97
+ send(target)
98
+ end
99
+ puts
100
+ end
@@ -0,0 +1,20 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'octopi')
2
+
3
+ include Octopi
4
+
5
+ authenticated :trace => "curl" do |g|
6
+ repo = g.repository("api-labrat")
7
+
8
+ issue = repo.open_issue :title => "Sample issue",
9
+ :body => "This issue was opened using GitHub API and Octopi"
10
+ puts "Successfully opened issue \##{issue.number}"
11
+
12
+ # # labels = issue.add_label "Working", "Todo"
13
+ # # puts "Labels: #{labels.inspect}"
14
+
15
+ issue.close
16
+ puts "Successfully closed issue \##{issue.number}"
17
+
18
+ # labels = issue.remove_label "Todo"
19
+ # puts "Successfully removed label Todo. Current labels: #{labels.inspect}"
20
+ end
@@ -0,0 +1,14 @@
1
+ #
2
+ # Octopi GitHub API configuration file
3
+ #
4
+
5
+ # GitHub user login and token
6
+ login: github-username
7
+ token: github-token
8
+
9
+ # Trace level
10
+ # Possible values:
11
+ # false - no tracing, same as if the param is ommited
12
+ # true - will output each POST or GET operation to the stdout
13
+ # curl - same as true, but in addition will output the curl equivalent of each command (for debugging)
14
+ trace: curl
@@ -0,0 +1,18 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'octopi')
2
+
3
+ include Octopi
4
+
5
+ user = User.find("fcoury")
6
+ puts user.name
7
+
8
+ repo = user.repository("octopi")
9
+ puts repo.description
10
+
11
+ issue = Issue.find_all(user.login, repo.name).first
12
+ puts "First open issue: #{issue.number} - #{issue.title} - Created at: #{issue.created_at}"
13
+
14
+ issue2 = repo.issues.first
15
+ puts "First open issue: #{issue.number} - #{issue.title} - Created at: #{issue.created_at}"
16
+
17
+ issue3 = repo.issue(issue2.number)
18
+ puts "First open issue: #{issue.number} - #{issue.title} - Created at: #{issue.created_at}"
@@ -0,0 +1,50 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'octopi')
2
+
3
+ include Octopi
4
+
5
+ # user information
6
+ user = User.find("fcoury")
7
+ puts "#{user.name} is being followed by #{user.followers.join(", ")} and following #{user.following.join(", ")}"
8
+
9
+ # the bang version of followers and following
10
+ # fetches user object for each user, but is
11
+ # a lot more expensive
12
+ user.followers!.each do |u|
13
+ puts " - #{u.name} (#{u.login}) has #{u.public_repo_count} repo(s)"
14
+ end
15
+
16
+ # search user
17
+ users = User.find_all("silva")
18
+ puts "#{users.size} users found for 'silva':"
19
+ users.each do |u|
20
+ puts " - #{u.name}"
21
+ end
22
+
23
+ # repository information
24
+ # to get all repos for user: user.repositories
25
+ repo = user.repository("octopi") # same as: Repository.find("fcoury", "octopi")
26
+ puts "Repository: #{repo.name} - #{repo.description} (by #{repo.owner}) - #{repo.url}"
27
+ puts " Tags: #{repo.tags and repo.tags.map {|t| t.name}.join(", ")}"
28
+
29
+ issue = repo.issues.first
30
+ puts "Sample open issue: #{issue.number} - #{issue.title} - Created at: #{issue.created_at}"
31
+
32
+ # commits of a the repository
33
+ commit = repo.commits.first
34
+ puts "Commit: #{commit.id} - #{commit.message} - by #{commit.author['name']}"
35
+
36
+ # single commit information
37
+ # details is the same as: Commit.find(commit)
38
+ puts "Diff:"
39
+ commit.details.modified.each {|m| puts "#{m['filename']} DIFF: #{m['diff']}" }
40
+
41
+ # repository search
42
+ repos = Repository.find_all("ruby", "git")
43
+ puts "#{repos.size} repository(ies) with 'ruby' and 'git':"
44
+ repos.each do |r|
45
+ puts " - #{r.name}"
46
+ end
47
+
48
+ # connect "user", "<< token >>" do |github|
49
+ # puts github.user.name
50
+ # end