github-control 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/github-control +5 -0
- data/config/example.yml +5 -0
- data/lib/github-control.rb +35 -0
- data/lib/github-control/action.rb +19 -0
- data/lib/github-control/actions/add_collaborators.rb +34 -0
- data/lib/github-control/actions/collaborators.rb +31 -0
- data/lib/github-control/actions/remove_collaborators.rb +34 -0
- data/lib/github-control/actions/repositories.rb +23 -0
- data/lib/github-control/actions/shell.rb +17 -0
- data/lib/github-control/cli.rb +105 -0
- data/lib/github-control/collaborators.rb +36 -0
- data/lib/github-control/console.rb +63 -0
- data/lib/github-control/post_receive_urls.rb +54 -0
- data/lib/github-control/repositories.rb +61 -0
- data/lib/github-control/repository.rb +33 -0
- data/lib/github-control/user.rb +21 -0
- data/lib/github-control/version.rb +3 -0
- data/spec/github_control_spec.rb +53 -0
- data/spec/models/post_receive_urls_spec.rb +46 -0
- data/spec/models/user_spec.rb +0 -0
- data/spec/spec_helper.rb +12 -0
- metadata +94 -0
data/bin/github-control
ADDED
data/config/example.yml
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'json'
|
5
|
+
rescue LoadError
|
6
|
+
require 'rubygems'
|
7
|
+
require 'json'
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'rest_client'
|
11
|
+
require 'nokogiri'
|
12
|
+
|
13
|
+
module GithubControl
|
14
|
+
class Error < StandardError; end
|
15
|
+
class APIError < Error; end
|
16
|
+
class ProblemWithOptions < Error; end
|
17
|
+
end
|
18
|
+
|
19
|
+
$:.unshift File.dirname(__FILE__)
|
20
|
+
|
21
|
+
require 'github-control/version'
|
22
|
+
require 'github-control/cli'
|
23
|
+
require 'github-control/console'
|
24
|
+
require 'github-control/user'
|
25
|
+
require 'github-control/repository'
|
26
|
+
require 'github-control/repositories'
|
27
|
+
require 'github-control/collaborators'
|
28
|
+
require 'github-control/post_receive_urls'
|
29
|
+
|
30
|
+
require 'github-control/action'
|
31
|
+
require 'github-control/actions/repositories'
|
32
|
+
require 'github-control/actions/shell'
|
33
|
+
require 'github-control/actions/collaborators'
|
34
|
+
require 'github-control/actions/add_collaborators'
|
35
|
+
require 'github-control/actions/remove_collaborators'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module GithubControl
|
2
|
+
class Action
|
3
|
+
def initialize(cli)
|
4
|
+
@cli = cli
|
5
|
+
end
|
6
|
+
|
7
|
+
def options
|
8
|
+
@options ||= {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_options(parser)
|
12
|
+
raise NotImplementedError, "Please implement the #{self.class}#add_options method"
|
13
|
+
end
|
14
|
+
|
15
|
+
def call
|
16
|
+
raise NotImplementedError, "Please implement the #{self.class}#call method"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module GithubControl
|
2
|
+
module Actions
|
3
|
+
class AddCollaborators < Action
|
4
|
+
def add_options(parser)
|
5
|
+
parser.on("-R name", "--repository name", "The repository on Github") do |repository_name|
|
6
|
+
options[:repository_name] = repository_name
|
7
|
+
end
|
8
|
+
|
9
|
+
parser.on("-U name", "--user name", "The user on Github") do |user_name|
|
10
|
+
options[:user_name] = user_name
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def call
|
15
|
+
puts "Adding #{user.name} to the collaborators of #{repository.full_name}"
|
16
|
+
puts "-" * 40
|
17
|
+
if repository.collaborators.include?(user)
|
18
|
+
puts "#{user.name} is already a collaborator"
|
19
|
+
else
|
20
|
+
repository.collaborators << user
|
21
|
+
puts "Done"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def repository
|
26
|
+
@cli.console.current_user.repo_for(options[:repository_name] || raise(ProblemWithOptions, "Please specify a repository"))
|
27
|
+
end
|
28
|
+
|
29
|
+
def user
|
30
|
+
@cli.console.user_for(options[:user_name] || raise(ProblemWithOptions, "Please specify a user"))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module GithubControl
|
2
|
+
module Actions
|
3
|
+
class Collaborators < Action
|
4
|
+
def add_options(parser)
|
5
|
+
parser.on("-R name", "--repository name", "The repository on Github") do |repository_name|
|
6
|
+
options[:repository_name] = repository_name
|
7
|
+
end
|
8
|
+
|
9
|
+
parser.on("-U name", "--user name", "The user on Github") do |user_name|
|
10
|
+
options[:user_name] = user_name
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def call
|
15
|
+
puts "Listing the collaborators of #{repository.full_name}"
|
16
|
+
puts "-" * 40
|
17
|
+
repository.collaborators.each do |user|
|
18
|
+
puts "- #{user.name}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def repository
|
23
|
+
user.repo_for(options[:repository_name] || raise(ProblemWithOptions, "Please specify a repository"))
|
24
|
+
end
|
25
|
+
|
26
|
+
def user
|
27
|
+
@cli.console.user_for(options[:user_name] || raise(ProblemWithOptions, "Please specify a user"))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module GithubControl
|
2
|
+
module Actions
|
3
|
+
class RemoveCollaborators < Action
|
4
|
+
def add_options(parser)
|
5
|
+
parser.on("-R name", "--repository name", "The repository on Github") do |repository_name|
|
6
|
+
options[:repository_name] = repository_name
|
7
|
+
end
|
8
|
+
|
9
|
+
parser.on("-U name", "--user name", "The user on Github") do |user_name|
|
10
|
+
options[:user_name] = user_name
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def call
|
15
|
+
puts "Removing #{user.name} from the collaborators of #{repository.full_name}"
|
16
|
+
puts "-" * 40
|
17
|
+
unless repository.collaborators.include?(user)
|
18
|
+
puts "#{user.name} is not a collaborator"
|
19
|
+
else
|
20
|
+
repository.collaborators.delete(user)
|
21
|
+
puts "Done"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def repository
|
26
|
+
@cli.console.current_user.repo_for(options[:repository_name] || raise(ProblemWithOptions, "Please specify a repository"))
|
27
|
+
end
|
28
|
+
|
29
|
+
def user
|
30
|
+
@cli.console.user_for(options[:user_name] || raise(ProblemWithOptions, "Please specify a user"))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module GithubControl
|
2
|
+
module Actions
|
3
|
+
class Repositories < Action
|
4
|
+
def add_options(parser)
|
5
|
+
parser.on("-U name", "--user name", "The user to list the repositories") do |user_name|
|
6
|
+
options[:user_name] = user_name
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def call
|
11
|
+
puts "Repositories for #{user.name}"
|
12
|
+
puts "-" * 40
|
13
|
+
user.repositories.each do |repo|
|
14
|
+
puts "- #{repo.name}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def user
|
19
|
+
@cli.console.user_for(options[:user_name] || @cli.console.current_user.name)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'irb'
|
2
|
+
|
3
|
+
module GithubControl
|
4
|
+
module Actions
|
5
|
+
class Shell < Action
|
6
|
+
def add_options(parser)
|
7
|
+
end
|
8
|
+
|
9
|
+
def call
|
10
|
+
console = @cli.console
|
11
|
+
puts "You are now able to interact with Github via the 'github' method"
|
12
|
+
Object.send(:define_method, :github) { console }
|
13
|
+
IRB.start
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module GithubControl
|
4
|
+
class CLI
|
5
|
+
def self.execute(args)
|
6
|
+
new(args).run
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(args)
|
10
|
+
@args = args
|
11
|
+
end
|
12
|
+
|
13
|
+
def run
|
14
|
+
current_action.add_options(option_parser)
|
15
|
+
option_parser.parse!(@args)
|
16
|
+
current_action.call
|
17
|
+
rescue ProblemWithOptions, OptionParser::ParseError => e
|
18
|
+
puts e.backtrace
|
19
|
+
$stderr.puts
|
20
|
+
$stderr.puts e.message
|
21
|
+
$stderr.puts
|
22
|
+
$stderr.puts option_parser
|
23
|
+
exit 2
|
24
|
+
end
|
25
|
+
|
26
|
+
def current_action
|
27
|
+
@current_action ||= create_action
|
28
|
+
end
|
29
|
+
|
30
|
+
def create_action
|
31
|
+
case action_name
|
32
|
+
when "list"
|
33
|
+
Actions::Repositories.new(self)
|
34
|
+
when "shell"
|
35
|
+
Actions::Shell.new(self)
|
36
|
+
when "collab"
|
37
|
+
Actions::Collaborators.new(self)
|
38
|
+
when "add_collab"
|
39
|
+
Actions::AddCollaborators.new(self)
|
40
|
+
when "remove_collab"
|
41
|
+
Actions::RemoveCollaborators.new(self)
|
42
|
+
else
|
43
|
+
raise ProblemWithOptions, "#{action_name} is not a valid action"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def action_name
|
48
|
+
@action_name ||= @args.shift || raise(ProblemWithOptions, "Please provide an action to run")
|
49
|
+
end
|
50
|
+
|
51
|
+
def console
|
52
|
+
@console ||= Console.new(user_config)
|
53
|
+
end
|
54
|
+
|
55
|
+
def user_config
|
56
|
+
config["user"] || raise(ProblemWithOptions, "You need to provide user data in the YAML file")
|
57
|
+
end
|
58
|
+
|
59
|
+
def config
|
60
|
+
@config ||= YAML.load_file(config_filename)
|
61
|
+
end
|
62
|
+
|
63
|
+
def config_filename
|
64
|
+
options[:config_filename] || raise(ProblemWithOptions, "You need to provide the path to the YAML filename")
|
65
|
+
end
|
66
|
+
|
67
|
+
def options
|
68
|
+
@options ||= {
|
69
|
+
:debug => false,
|
70
|
+
:argv => @args,
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
def option_parser
|
75
|
+
@option_parser ||= OptionParser.new do |opts|
|
76
|
+
opts.banner = "Usage: github-control #{@action_name || '[action]'} [options] ..."
|
77
|
+
|
78
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
79
|
+
$stderr.puts opts
|
80
|
+
exit
|
81
|
+
end
|
82
|
+
|
83
|
+
opts.on("--debug", "Display debugging information") {
|
84
|
+
options[:debug] = true
|
85
|
+
$debug = true
|
86
|
+
}
|
87
|
+
|
88
|
+
opts.on("-c filename", "--config filename", "Load the config from this YAML file") do |filename|
|
89
|
+
options[:config_filename] = filename
|
90
|
+
end
|
91
|
+
|
92
|
+
opts.on("-v", "--version", "Display the github version, and exit.") do
|
93
|
+
puts "Github Control version #{GithubControl::VERSION}"
|
94
|
+
exit
|
95
|
+
end
|
96
|
+
|
97
|
+
opts.separator ""
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def inspect
|
102
|
+
"#<#{self.class} logged in as #{current_user.name.inspect}>"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module GithubControl
|
2
|
+
class Collaborators
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
attr_reader :repository
|
6
|
+
|
7
|
+
def initialize(repository)
|
8
|
+
@repository = repository
|
9
|
+
end
|
10
|
+
|
11
|
+
def create(user)
|
12
|
+
@repository.owner.cli.post("/repos/collaborators/" \
|
13
|
+
"#{@repository.name}/add/#{user}")
|
14
|
+
end
|
15
|
+
|
16
|
+
def delete(user)
|
17
|
+
@repository.owner.cli.post("/repos/collaborators/" \
|
18
|
+
"#{@repository.name}/remove/#{user}")
|
19
|
+
end
|
20
|
+
|
21
|
+
def each(&block)
|
22
|
+
set.each(&block)
|
23
|
+
end
|
24
|
+
|
25
|
+
def set
|
26
|
+
@set ||= json_data["collaborators"].map { |name|
|
27
|
+
@repository.owner.cli.user_for(name)
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def json_data
|
32
|
+
@repository.owner.cli.post("/repos/show/" \
|
33
|
+
"#{@repository.owner.name}/#{@repository.name}/collaborators")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module GithubControl
|
2
|
+
class Console
|
3
|
+
def initialize(user_config)
|
4
|
+
@user_config = user_config
|
5
|
+
@users = {}
|
6
|
+
end
|
7
|
+
|
8
|
+
def current_user
|
9
|
+
@current_user ||= user_for(user_name)
|
10
|
+
end
|
11
|
+
|
12
|
+
def user_for(name)
|
13
|
+
@users[name] ||= User.new(self, name)
|
14
|
+
end
|
15
|
+
|
16
|
+
def post(path, params={})
|
17
|
+
params.merge!(:login => user_name, :token => user_token)
|
18
|
+
data = JSON.parse(RestClient.post(url_for(path), params))
|
19
|
+
if error = data["error"]
|
20
|
+
raise APIError, error.first["error"]
|
21
|
+
else
|
22
|
+
data
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def get(path, params={})
|
27
|
+
RestClient.get(url_for(path), params)
|
28
|
+
end
|
29
|
+
|
30
|
+
def url_for(path)
|
31
|
+
"http://github.com/api/v2/json#{path}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def cookies
|
35
|
+
@cookies ||= session_cookie
|
36
|
+
end
|
37
|
+
|
38
|
+
def session_cookie
|
39
|
+
response = raw_post("/session", {:login => user_name,
|
40
|
+
:password => user_password}, {}, :auto_redirect => false)
|
41
|
+
response.headers[:set_cookie].split(";").first
|
42
|
+
end
|
43
|
+
|
44
|
+
def user_name
|
45
|
+
@user_config["name"] ||
|
46
|
+
raise(ProblemWithOptions, "You need to provide the user name in the YAML file")
|
47
|
+
end
|
48
|
+
|
49
|
+
def user_token
|
50
|
+
@user_config["token"] ||
|
51
|
+
raise(ProblemWithOptions, "You need to provide the user token in the YAML file")
|
52
|
+
end
|
53
|
+
|
54
|
+
def user_password
|
55
|
+
@user_config["password"] ||
|
56
|
+
raise(ProblemWithOptions, "You need to provide the user password in the YAML file")
|
57
|
+
end
|
58
|
+
|
59
|
+
def inspect
|
60
|
+
"#<#{self.class} logged in as #{current_user.name.inspect}>"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module GithubControl
|
2
|
+
class PostReceiveUrls
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def initialize(repository)
|
6
|
+
@repository = repository
|
7
|
+
end
|
8
|
+
attr_reader :repository
|
9
|
+
|
10
|
+
def <<(url)
|
11
|
+
update_with(set + [url])
|
12
|
+
end
|
13
|
+
|
14
|
+
def delete(url)
|
15
|
+
update_with(set - [url])
|
16
|
+
end
|
17
|
+
|
18
|
+
def clear
|
19
|
+
update_with([])
|
20
|
+
end
|
21
|
+
|
22
|
+
def update_with(urls)
|
23
|
+
form_data = []
|
24
|
+
urls.each do |url|
|
25
|
+
value = URI.escape(url.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
|
26
|
+
form_data << "urls[]=#{value}"
|
27
|
+
end
|
28
|
+
@repository.owner.cli.scrape_post("/#{@repository.owner.name}/#{@repository.name}/edit/postreceive_urls",
|
29
|
+
form_data.join("&"), :accept => 'text/javascript')
|
30
|
+
end
|
31
|
+
|
32
|
+
def empty?
|
33
|
+
set.empty?
|
34
|
+
end
|
35
|
+
|
36
|
+
def each(&block)
|
37
|
+
set.each(&block)
|
38
|
+
end
|
39
|
+
|
40
|
+
def set
|
41
|
+
set = []
|
42
|
+
doc = Nokogiri::HTML(html_data)
|
43
|
+
doc.search("fieldset#postreceive_urls.service-hook form p input[name='urls[]']").each do |input|
|
44
|
+
set << input["value"] if input["value"]
|
45
|
+
end
|
46
|
+
set
|
47
|
+
end
|
48
|
+
|
49
|
+
def html_data
|
50
|
+
@repository.owner.cli.scrape_get("/#{@repository.owner.name}/#{@repository.name}/edit/hooks")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module GithubControl
|
2
|
+
class Repositories
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def initialize(user)
|
6
|
+
@user = user
|
7
|
+
end
|
8
|
+
|
9
|
+
def create(name, access)
|
10
|
+
@user.cli.post("/repos/create",
|
11
|
+
:name => name,
|
12
|
+
:public => access == :public ? 1 : 0
|
13
|
+
)
|
14
|
+
|
15
|
+
repo = Repository.new(@user, name, access)
|
16
|
+
set << repo
|
17
|
+
repo
|
18
|
+
end
|
19
|
+
|
20
|
+
def [](name)
|
21
|
+
set.detect { |r| r.name == name }
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete(name)
|
25
|
+
response = @user.cli.post("/repos/delete/#{name}")
|
26
|
+
@user.cli.post("/repos/delete/#{name}",
|
27
|
+
:delete_token => response["delete_token"])
|
28
|
+
any? && set.delete(name)
|
29
|
+
end
|
30
|
+
|
31
|
+
def destroy
|
32
|
+
each { |r| delete(r.name) }
|
33
|
+
end
|
34
|
+
|
35
|
+
def each(&block)
|
36
|
+
set.each(&block)
|
37
|
+
end
|
38
|
+
|
39
|
+
def clear
|
40
|
+
@set = nil
|
41
|
+
end
|
42
|
+
|
43
|
+
def empty?
|
44
|
+
! any?
|
45
|
+
end
|
46
|
+
|
47
|
+
def size
|
48
|
+
set.size
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
def set
|
53
|
+
@set ||= @user.cli.post("/repos/show/#{@user.name}")["repositories"].
|
54
|
+
sort_by { |r| r["name"] }.
|
55
|
+
map { |r|
|
56
|
+
access = r["private"] ? :private : :public
|
57
|
+
Repository.new(@user, r["name"], access)
|
58
|
+
}
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module GithubControl
|
2
|
+
class Repository
|
3
|
+
attr_reader :owner, :name, :access
|
4
|
+
|
5
|
+
def initialize(owner, name, access)
|
6
|
+
@owner, @name, @access = owner, name, access
|
7
|
+
end
|
8
|
+
|
9
|
+
def private?
|
10
|
+
@access == :private
|
11
|
+
end
|
12
|
+
|
13
|
+
def public?
|
14
|
+
@access == :public
|
15
|
+
end
|
16
|
+
|
17
|
+
def full_name
|
18
|
+
"#{@owner.name}/#{@name}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def collaborators
|
22
|
+
@collaborators ||= Collaborators.new(self)
|
23
|
+
end
|
24
|
+
|
25
|
+
def post_receive_urls
|
26
|
+
@post_receive_urls ||= PostReceiveUrls.new(self)
|
27
|
+
end
|
28
|
+
|
29
|
+
def destroy
|
30
|
+
@owner.repositories.delete(@name)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module GithubControl
|
2
|
+
class User
|
3
|
+
attr_reader :cli, :name
|
4
|
+
|
5
|
+
def initialize(cli, name)
|
6
|
+
@cli, @name = cli, name
|
7
|
+
end
|
8
|
+
|
9
|
+
def repositories
|
10
|
+
@repos ||= Repositories.new(self)
|
11
|
+
end
|
12
|
+
|
13
|
+
def public_repositories
|
14
|
+
repositories.select { |r| r.public? }
|
15
|
+
end
|
16
|
+
|
17
|
+
def private_repositories
|
18
|
+
repositories.select { |r| r.private? }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Github Control" do
|
4
|
+
def config
|
5
|
+
@config ||= YAML.load_file("spec/config.yml")["user"]
|
6
|
+
end
|
7
|
+
|
8
|
+
def console
|
9
|
+
@console ||= GithubControl::Console.new(config)
|
10
|
+
end
|
11
|
+
|
12
|
+
def current_user
|
13
|
+
@user ||= console.current_user
|
14
|
+
end
|
15
|
+
|
16
|
+
before(:all) do
|
17
|
+
RestClient.log = "restclient.log"
|
18
|
+
end
|
19
|
+
|
20
|
+
before(:each) do
|
21
|
+
current_user.repositories.destroy
|
22
|
+
end
|
23
|
+
|
24
|
+
it "creates a public repository" do
|
25
|
+
current_user.should have(:no).repositories
|
26
|
+
current_user.repositories.create("public-repo", :public)
|
27
|
+
current_user.should have(1).repositories
|
28
|
+
current_user.repositories["public-repo"].should be_public
|
29
|
+
end
|
30
|
+
|
31
|
+
it "creates a private repository" do
|
32
|
+
current_user.should have(:no).private_repositories
|
33
|
+
current_user.repositories.create("private-repo", :private)
|
34
|
+
current_user.should have(1).private_repositories
|
35
|
+
current_user.repositories["private-repo"].should be_private
|
36
|
+
end
|
37
|
+
|
38
|
+
it "creates and destroys collaborators on a repository" do
|
39
|
+
repo = current_user.repositories.create("test-repo", :public)
|
40
|
+
repo.collaborators << GithubControl::User.new("atmos", console)
|
41
|
+
repo.collaborators << GithubControl::User.new("tim", console)
|
42
|
+
repo.collaborators << GithubControl::User.new("ben", console)
|
43
|
+
repo.collaborators << GithubControl::User.new("sr", console)
|
44
|
+
|
45
|
+
repo.should have(4).collaborators
|
46
|
+
|
47
|
+
# sorry dude :(
|
48
|
+
repo.collaborators.delete("atmos")
|
49
|
+
repo.should have(3).collaborators
|
50
|
+
end
|
51
|
+
|
52
|
+
it "adds and remove post-receive urls"
|
53
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe "Post-receive URLs" do
|
4
|
+
describe "for a repository with a single URL" do
|
5
|
+
before(:each) do
|
6
|
+
@repo = @console.current_user.repo_for("with-one-post-receive-url")
|
7
|
+
end
|
8
|
+
|
9
|
+
it "can be fetched" do
|
10
|
+
@repo.post_receive_urls.to_a.should == ["http://github-control.r.spork.in/post-receive"]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "for a repository with no URLs" do
|
15
|
+
before(:each) do
|
16
|
+
@repo = @console.current_user.repo_for("with-no-post-receive-urls")
|
17
|
+
@repo.post_receive_urls.clear
|
18
|
+
end
|
19
|
+
|
20
|
+
it "can be fetched" do
|
21
|
+
@repo.post_receive_urls.should be_empty
|
22
|
+
end
|
23
|
+
|
24
|
+
it "adds a new URL" do
|
25
|
+
@repo.post_receive_urls << "http://example.org"
|
26
|
+
@repo.post_receive_urls.to_a.should == ["http://example.org"]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "for a repository with 3 URLs" do
|
31
|
+
before(:each) do
|
32
|
+
@repo = @console.current_user.repo_for("with-three-post-receive-urls")
|
33
|
+
urls = ["http://example.com/1", "http://example.com/2", "http://example.com/3"]
|
34
|
+
@repo.post_receive_urls.update_with(urls)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "can be fetched" do
|
38
|
+
@repo.post_receive_urls.to_a.should == ["http://example.com/1", "http://example.com/2", "http://example.com/3"]
|
39
|
+
end
|
40
|
+
|
41
|
+
it "adds a new URL" do
|
42
|
+
@repo.post_receive_urls.delete("http://example.com/1")
|
43
|
+
@repo.post_receive_urls.to_a.should == ["http://example.com/2", "http://example.com/3"]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
File without changes
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec'
|
2
|
+
require 'randexp'
|
3
|
+
require "pp"
|
4
|
+
|
5
|
+
require File.dirname(__FILE__) + '/../lib/github-control'
|
6
|
+
|
7
|
+
Spec::Runner.configure do |config|
|
8
|
+
config.mock_with(:rr)
|
9
|
+
config.before(:all) do
|
10
|
+
@console = GithubControl::Console.new(YAML.load_file(File.dirname(__FILE__) + '/config.yml')["user"])
|
11
|
+
end
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: github-control
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tim Carey-Smith
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-11-28 00:00:00 -08:00
|
13
|
+
default_executable: github-control
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rest-client
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.9.2
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: json
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.1.3
|
34
|
+
version:
|
35
|
+
description: github-control allows you to interact with Github through a nice ruby interface
|
36
|
+
email: tim@spork.in
|
37
|
+
executables:
|
38
|
+
- github-control
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
files:
|
44
|
+
- config/example.yml
|
45
|
+
- lib/github-control/action.rb
|
46
|
+
- lib/github-control/actions/add_collaborators.rb
|
47
|
+
- lib/github-control/actions/collaborators.rb
|
48
|
+
- lib/github-control/actions/remove_collaborators.rb
|
49
|
+
- lib/github-control/actions/repositories.rb
|
50
|
+
- lib/github-control/actions/shell.rb
|
51
|
+
- lib/github-control/cli.rb
|
52
|
+
- lib/github-control/collaborators.rb
|
53
|
+
- lib/github-control/console.rb
|
54
|
+
- lib/github-control/post_receive_urls.rb
|
55
|
+
- lib/github-control/repositories.rb
|
56
|
+
- lib/github-control/repository.rb
|
57
|
+
- lib/github-control/user.rb
|
58
|
+
- lib/github-control/version.rb
|
59
|
+
- lib/github-control.rb
|
60
|
+
- spec/github_control_spec.rb
|
61
|
+
- spec/models/post_receive_urls_spec.rb
|
62
|
+
- spec/models/user_spec.rb
|
63
|
+
- spec/spec_helper.rb
|
64
|
+
has_rdoc: true
|
65
|
+
homepage: http://github.com/halorgium/github-control
|
66
|
+
licenses: []
|
67
|
+
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options:
|
70
|
+
- --inline-source
|
71
|
+
- --charset=UTF-8
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: "0"
|
79
|
+
version:
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: "0"
|
85
|
+
version:
|
86
|
+
requirements: []
|
87
|
+
|
88
|
+
rubyforge_project:
|
89
|
+
rubygems_version: 1.3.5
|
90
|
+
signing_key:
|
91
|
+
specification_version: 3
|
92
|
+
summary: github-control allows you to interact with Github through a nice ruby interface
|
93
|
+
test_files: []
|
94
|
+
|