thoughtbot-enforcer 0.0.2
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/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +42 -0
- data/Rakefile +68 -0
- data/VERSION +1 -0
- data/bin/enforcer +19 -0
- data/enforcer.gemspec +66 -0
- data/features/manage_collaborators.feature +45 -0
- data/features/step_definitions/enforcer_steps.rb +30 -0
- data/features/support/env.rb +24 -0
- data/lib/enforcer.rb +40 -0
- data/lib/repository.rb +41 -0
- data/test/enforcer_test.rb +89 -0
- data/test/integration.rb +9 -0
- data/test/repository_test.rb +84 -0
- data/test/test_helper.rb +30 -0
- metadata +93 -0
data/.document
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2009 thoughtbot
|
|
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.
|
data/README.rdoc
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
= enforcer
|
|
2
|
+
|
|
3
|
+
A simple way to manage permissions on GitHub.
|
|
4
|
+
|
|
5
|
+
== usage
|
|
6
|
+
|
|
7
|
+
Create an enforcer script and then run it with the "enforcer" executable.
|
|
8
|
+
|
|
9
|
+
enforcer my_enforcer_script.rb
|
|
10
|
+
|
|
11
|
+
== howto
|
|
12
|
+
|
|
13
|
+
The DSL should be formed like such:
|
|
14
|
+
|
|
15
|
+
Enforcer "your github account", "your github api key" do
|
|
16
|
+
project "some project", "user1", "user2", "user3"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
The users passed into the project are then set as the collaborators. Any
|
|
20
|
+
users not listed are removed. You could use a GitHub API wrapper like
|
|
21
|
+
Octopi to load up your projects as well. Here's a more complex example:
|
|
22
|
+
|
|
23
|
+
require 'octopi'
|
|
24
|
+
include Octopi
|
|
25
|
+
account = "thoughtbot"
|
|
26
|
+
token = "deadbeef"
|
|
27
|
+
|
|
28
|
+
Enforcer account, token do
|
|
29
|
+
authenticated_with account, token do |github|
|
|
30
|
+
@projects = github.user.repositories.map { |repo| repo.name }.sort
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
users = %w[user1 user2 user3]
|
|
34
|
+
|
|
35
|
+
@projects.each do |name|
|
|
36
|
+
project name, *users
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
== legal
|
|
41
|
+
|
|
42
|
+
Copyright (c) 2009 thoughtbot. See LICENSE for details.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'rake'
|
|
3
|
+
|
|
4
|
+
task :default => [:test, :features]
|
|
5
|
+
|
|
6
|
+
begin
|
|
7
|
+
require 'jeweler'
|
|
8
|
+
Jeweler::Tasks.new do |gem|
|
|
9
|
+
gem.name = "enforcer"
|
|
10
|
+
gem.summary = %Q{A simple way to manage permissions on GitHub}
|
|
11
|
+
gem.email = "nquaranto@thoughtbot.com"
|
|
12
|
+
gem.homepage = "http://github.com/thoughtbot/enforcer"
|
|
13
|
+
gem.authors = ["Nick Quaranto"]
|
|
14
|
+
gem.add_dependency("httparty")
|
|
15
|
+
gem.add_dependency("fcoury-octopi")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
rescue LoadError
|
|
19
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
require 'rake/testtask'
|
|
23
|
+
Rake::TestTask.new(:test) do |test|
|
|
24
|
+
test.libs << 'lib' << 'test'
|
|
25
|
+
test.pattern = 'test/**/*_test.rb'
|
|
26
|
+
test.verbose = true
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
begin
|
|
30
|
+
require 'rcov/rcovtask'
|
|
31
|
+
Rcov::RcovTask.new do |test|
|
|
32
|
+
test.libs << 'test'
|
|
33
|
+
test.pattern = 'test/**/*_test.rb'
|
|
34
|
+
test.verbose = true
|
|
35
|
+
end
|
|
36
|
+
rescue LoadError
|
|
37
|
+
task :rcov do
|
|
38
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
require 'rake/rdoctask'
|
|
43
|
+
Rake::RDocTask.new do |rdoc|
|
|
44
|
+
if File.exist?('VERSION.yml')
|
|
45
|
+
config = YAML.load(File.read('VERSION.yml'))
|
|
46
|
+
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
|
47
|
+
else
|
|
48
|
+
version = ""
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
52
|
+
rdoc.title = "enforcer #{version}"
|
|
53
|
+
rdoc.rdoc_files.include('README*')
|
|
54
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
begin
|
|
58
|
+
require 'cucumber/rake/task'
|
|
59
|
+
|
|
60
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
|
61
|
+
t.cucumber_opts = "--format progress"
|
|
62
|
+
end
|
|
63
|
+
rescue LoadError
|
|
64
|
+
desc 'Cucumber rake task not available'
|
|
65
|
+
task :features do
|
|
66
|
+
abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin'
|
|
67
|
+
end
|
|
68
|
+
end
|
data/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.0.2
|
data/bin/enforcer
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
$:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
|
|
4
|
+
|
|
5
|
+
help = <<HELP
|
|
6
|
+
Enforcer is a simple way to manage permissions on GitHub.
|
|
7
|
+
|
|
8
|
+
Basic usage:
|
|
9
|
+
enforcer my_enforcer_script.rb
|
|
10
|
+
HELP
|
|
11
|
+
|
|
12
|
+
if ARGV.size == 1 && File.exist?(ARGV[0])
|
|
13
|
+
require 'enforcer'
|
|
14
|
+
load ARGV[0]
|
|
15
|
+
else
|
|
16
|
+
puts help
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
|
data/enforcer.gemspec
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Generated by jeweler
|
|
2
|
+
# DO NOT EDIT THIS FILE
|
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
|
4
|
+
# -*- encoding: utf-8 -*-
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |s|
|
|
7
|
+
s.name = %q{enforcer}
|
|
8
|
+
s.version = "0.0.2"
|
|
9
|
+
|
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
|
+
s.authors = ["Nick Quaranto"]
|
|
12
|
+
s.date = %q{2009-08-24}
|
|
13
|
+
s.default_executable = %q{enforcer}
|
|
14
|
+
s.email = %q{nquaranto@thoughtbot.com}
|
|
15
|
+
s.executables = ["enforcer"]
|
|
16
|
+
s.extra_rdoc_files = [
|
|
17
|
+
"LICENSE",
|
|
18
|
+
"README.rdoc"
|
|
19
|
+
]
|
|
20
|
+
s.files = [
|
|
21
|
+
".document",
|
|
22
|
+
".gitignore",
|
|
23
|
+
"LICENSE",
|
|
24
|
+
"README.rdoc",
|
|
25
|
+
"Rakefile",
|
|
26
|
+
"VERSION",
|
|
27
|
+
"bin/enforcer",
|
|
28
|
+
"enforcer.gemspec",
|
|
29
|
+
"features/manage_collaborators.feature",
|
|
30
|
+
"features/step_definitions/enforcer_steps.rb",
|
|
31
|
+
"features/support/env.rb",
|
|
32
|
+
"lib/enforcer.rb",
|
|
33
|
+
"lib/repository.rb",
|
|
34
|
+
"test/enforcer_test.rb",
|
|
35
|
+
"test/integration.rb",
|
|
36
|
+
"test/repository_test.rb",
|
|
37
|
+
"test/test_helper.rb"
|
|
38
|
+
]
|
|
39
|
+
s.homepage = %q{http://github.com/thoughtbot/enforcer}
|
|
40
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
|
41
|
+
s.require_paths = ["lib"]
|
|
42
|
+
s.rubygems_version = %q{1.3.4}
|
|
43
|
+
s.summary = %q{A simple way to manage permissions on GitHub}
|
|
44
|
+
s.test_files = [
|
|
45
|
+
"test/enforcer_test.rb",
|
|
46
|
+
"test/integration.rb",
|
|
47
|
+
"test/repository_test.rb",
|
|
48
|
+
"test/test_helper.rb"
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
if s.respond_to? :specification_version then
|
|
52
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
|
53
|
+
s.specification_version = 3
|
|
54
|
+
|
|
55
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
|
56
|
+
s.add_runtime_dependency(%q<httparty>, [">= 0"])
|
|
57
|
+
s.add_runtime_dependency(%q<fcoury-octopi>, [">= 0"])
|
|
58
|
+
else
|
|
59
|
+
s.add_dependency(%q<httparty>, [">= 0"])
|
|
60
|
+
s.add_dependency(%q<fcoury-octopi>, [">= 0"])
|
|
61
|
+
end
|
|
62
|
+
else
|
|
63
|
+
s.add_dependency(%q<httparty>, [">= 0"])
|
|
64
|
+
s.add_dependency(%q<fcoury-octopi>, [">= 0"])
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
Feature: Manage collaborators
|
|
2
|
+
Background:
|
|
3
|
+
Given an account "thoughtbot" with an api key of "deadbeef"
|
|
4
|
+
|
|
5
|
+
Scenario: Adding a single collaborator for a specific project
|
|
6
|
+
When I execute the following code
|
|
7
|
+
"""
|
|
8
|
+
Enforcer "thoughtbot", "deadbeef" do
|
|
9
|
+
project "shoulda", 'rmmt'
|
|
10
|
+
end
|
|
11
|
+
"""
|
|
12
|
+
Then the GitHub API should have received a request to add "rmmt" as a collaborator for "shoulda"
|
|
13
|
+
|
|
14
|
+
Scenario: Adding a single collaborator for more than one project
|
|
15
|
+
When I execute the following code
|
|
16
|
+
"""
|
|
17
|
+
Enforcer "thoughtbot", "deadbeef" do
|
|
18
|
+
project "shoulda", 'rmmt'
|
|
19
|
+
project "factory_girl", 'qrush'
|
|
20
|
+
end
|
|
21
|
+
"""
|
|
22
|
+
Then the GitHub API should have received a request to add "rmmt" as a collaborator for "shoulda"
|
|
23
|
+
Then the GitHub API should have received a request to add "qrush" as a collaborator for "factory_girl"
|
|
24
|
+
|
|
25
|
+
Scenario: Adding more than one collaborators for a specific project
|
|
26
|
+
When I execute the following code
|
|
27
|
+
"""
|
|
28
|
+
Enforcer "thoughtbot", "deadbeef" do
|
|
29
|
+
project "shoulda", 'rmmt', 'coreyhaines', 'qrush'
|
|
30
|
+
end
|
|
31
|
+
"""
|
|
32
|
+
Then the GitHub API should have received a request to add "rmmt" as a collaborator for "shoulda"
|
|
33
|
+
And the GitHub API should have received a request to add "coreyhaines" as a collaborator for "shoulda"
|
|
34
|
+
And the GitHub API should have received a request to add "qrush" as a collaborator for "shoulda"
|
|
35
|
+
|
|
36
|
+
Scenario: Removing one collaborator from the project
|
|
37
|
+
Given "qrush" is a collaborator for "shoulda"
|
|
38
|
+
When I execute the following code
|
|
39
|
+
"""
|
|
40
|
+
Enforcer "thoughtbot", "deadbeef" do
|
|
41
|
+
project "shoulda", 'coreyhaines'
|
|
42
|
+
end
|
|
43
|
+
"""
|
|
44
|
+
Then the GitHub API should have received a request to add "coreyhaines" as a collaborator for "shoulda"
|
|
45
|
+
And the GitHub API should have received a request to remove "qrush" as a collaborator for "shoulda"
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
Before do
|
|
2
|
+
@repo = "repo"
|
|
3
|
+
@existing_collaborators = []
|
|
4
|
+
|
|
5
|
+
stub(Repository).new(anything, anything, anything) { @repo }
|
|
6
|
+
stub(@repo).add(anything)
|
|
7
|
+
stub(@repo).remove(anything)
|
|
8
|
+
stub(@repo).list { @existing_collaborators }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
Given /^an account "(.*)" with an api key of "(.*)"$/ do |account, api_key|
|
|
12
|
+
@account = account
|
|
13
|
+
@api_key = api_key
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
Given /^"([^\"]*)" is a collaborator for "([^\"]*)"$/ do |user, repo|
|
|
17
|
+
@existing_collaborators << user
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
When /^I execute the following code$/ do |code|
|
|
21
|
+
eval(code)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
Then /^the GitHub API should have received a request to add "(.*)" as a collaborator for "(.*)"$/ do |user, repo|
|
|
25
|
+
assert_received(@repo) { |subject| subject.add(user) }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
Then /^the GitHub API should have received a request to remove "([^\"]*)" as a collaborator for "([^\"]*)"$/ do |user, repo|
|
|
29
|
+
assert_received(@repo) { |subject| subject.remove(user) }
|
|
30
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
require 'rr'
|
|
3
|
+
require 'test/unit'
|
|
4
|
+
require 'enforcer'
|
|
5
|
+
require 'fakeweb'
|
|
6
|
+
|
|
7
|
+
FakeWeb.allow_net_connect = false
|
|
8
|
+
|
|
9
|
+
World(Test::Unit::Assertions)
|
|
10
|
+
World(RR::Adapters::TestUnit)
|
|
11
|
+
|
|
12
|
+
Before do
|
|
13
|
+
RR.reset
|
|
14
|
+
stub(STDOUT).puts
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
After do
|
|
18
|
+
begin
|
|
19
|
+
RR.verify
|
|
20
|
+
ensure
|
|
21
|
+
RR.reset
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
data/lib/enforcer.rb
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
$:.unshift(File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
require 'rubygems'
|
|
4
|
+
require 'httparty'
|
|
5
|
+
require 'json'
|
|
6
|
+
|
|
7
|
+
require 'repository'
|
|
8
|
+
|
|
9
|
+
class Enforcer
|
|
10
|
+
def initialize(account_name, api_key)
|
|
11
|
+
@account_name = account_name
|
|
12
|
+
@api_key = api_key
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def project(project_name, *collaborators)
|
|
16
|
+
return if collaborators.nil?
|
|
17
|
+
|
|
18
|
+
STDOUT.puts "Enforcing settings for #{project_name}"
|
|
19
|
+
repo = Repository.new(@account_name, @api_key, project_name)
|
|
20
|
+
|
|
21
|
+
existing_collaborators = repo.list
|
|
22
|
+
|
|
23
|
+
if existing_collaborators.nil?
|
|
24
|
+
STDOUT.puts ">> Can't find existing collaborators for this project"
|
|
25
|
+
return
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
{ :add => collaborators - existing_collaborators,
|
|
29
|
+
:remove => existing_collaborators - collaborators}.each_pair do |action, group|
|
|
30
|
+
group.each do |collaborator|
|
|
31
|
+
repo.send(action, collaborator)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def Enforcer(account_name, api_key, &block)
|
|
38
|
+
enforcer = Enforcer.new(account_name, api_key)
|
|
39
|
+
enforcer.instance_eval(&block)
|
|
40
|
+
end
|
data/lib/repository.rb
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
class Repository
|
|
2
|
+
include HTTParty
|
|
3
|
+
base_uri 'http://github.com/api/v2/json/repos'
|
|
4
|
+
|
|
5
|
+
HTTP_ERRORS = [Timeout::Error,
|
|
6
|
+
Errno::EINVAL,
|
|
7
|
+
Errno::ECONNRESET,
|
|
8
|
+
EOFError,
|
|
9
|
+
Net::HTTPBadResponse,
|
|
10
|
+
Net::HTTPHeaderSyntaxError,
|
|
11
|
+
Net::ProtocolError]
|
|
12
|
+
|
|
13
|
+
def initialize(account, api_key, project)
|
|
14
|
+
@account = account
|
|
15
|
+
@project = project
|
|
16
|
+
@api_key = api_key
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def request(method, path)
|
|
20
|
+
begin
|
|
21
|
+
response = self.class.send(method, path, :body => { :login => @account, :token => @api_key })
|
|
22
|
+
response['collaborators']
|
|
23
|
+
rescue *HTTP_ERRORS => ex
|
|
24
|
+
STDOUT.puts ">> There was a problem contacting GitHub: #{ex}"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def list
|
|
29
|
+
request(:get, "/show/#{@account}/#{@project}/collaborators")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def add(collaborator)
|
|
33
|
+
STDOUT.puts ">> Adding #{collaborator}"
|
|
34
|
+
request(:post, "/collaborators/#{@project}/add/#{collaborator}")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def remove(collaborator)
|
|
38
|
+
STDOUT.puts ">> Removing #{collaborator}"
|
|
39
|
+
request(:post, "/collaborators/#{@project}/remove/#{collaborator}")
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class EnforcerTest < Test::Unit::TestCase
|
|
4
|
+
context "with an enforcer" do
|
|
5
|
+
setup do
|
|
6
|
+
@existing_collaborators = []
|
|
7
|
+
@repo = "repo"
|
|
8
|
+
@project = "project"
|
|
9
|
+
@account = "user"
|
|
10
|
+
@api_key = "api key"
|
|
11
|
+
|
|
12
|
+
stub(@repo).add(anything)
|
|
13
|
+
stub(@repo).list { @existing_collaborators }
|
|
14
|
+
mock(Repository).new(@account, @api_key, @project) { @repo }
|
|
15
|
+
|
|
16
|
+
@enforcer = Enforcer.new(@account, @api_key)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
should "totally skip adding/removing collaborators if the existing collaborators can't be found" do
|
|
20
|
+
@existing_collaborators = nil
|
|
21
|
+
|
|
22
|
+
assert_nothing_raised do
|
|
23
|
+
@enforcer.project @project, 'chaines'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
assert_received(@repo) do |subject|
|
|
27
|
+
subject.add('chaines').never
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
should "add a collaborator to the project" do
|
|
32
|
+
@enforcer.project @project, 'chaines'
|
|
33
|
+
|
|
34
|
+
assert_received(@repo) do |subject|
|
|
35
|
+
subject.add('chaines')
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
should "add collaborators to the project" do
|
|
40
|
+
@enforcer.project @project, 'chaines', 'qrush'
|
|
41
|
+
|
|
42
|
+
assert_received(@repo) do |subject|
|
|
43
|
+
subject.add('chaines')
|
|
44
|
+
subject.add('qrush')
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
context "with an existing user" do
|
|
49
|
+
setup do
|
|
50
|
+
@existing_user = "ralph"
|
|
51
|
+
stub(@repo).remove(anything)
|
|
52
|
+
@existing_collaborators << "ralph"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
should "not add existing user to the project" do
|
|
56
|
+
@enforcer.project @project, 'ralph'
|
|
57
|
+
|
|
58
|
+
assert_received(@repo) do |subject|
|
|
59
|
+
subject.add('ralph').never
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
should "remove existing user from the project if not in collaborators" do
|
|
64
|
+
@enforcer.project @project, 'qrush'
|
|
65
|
+
|
|
66
|
+
assert_received(@repo) do |subject|
|
|
67
|
+
subject.add('qrush')
|
|
68
|
+
subject.remove(@existing_user)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
context "setting up enforcer dsl" do
|
|
75
|
+
setup do
|
|
76
|
+
@enforcer = "enforcer"
|
|
77
|
+
stub(@enforcer).project(anything, anything)
|
|
78
|
+
|
|
79
|
+
@account = "thoughtbot"
|
|
80
|
+
@api_key = "api key"
|
|
81
|
+
mock(Enforcer).new(@account, @api_key) { @enforcer }
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
should "be there and take a string and block" do
|
|
85
|
+
Enforcer(@account, @api_key) { project("shoulda", "corey") {} }
|
|
86
|
+
assert_received(@enforcer) { |subject| subject.project("shoulda", "corey") }
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
data/test/integration.rb
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class RepositoryTest < Test::Unit::TestCase
|
|
4
|
+
context "with github api credentials" do
|
|
5
|
+
setup do
|
|
6
|
+
@account = "thoughtbot"
|
|
7
|
+
@api_key = "deadbeef"
|
|
8
|
+
@project = "project"
|
|
9
|
+
@user = "coreyhaines" + rand(10).to_s
|
|
10
|
+
@repo = Repository.new(@account, @api_key, @project)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
should "set base uri" do
|
|
14
|
+
assert_equal "http://github.com/api/v2/json/repos", Repository.base_uri
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
context "github is down" do
|
|
18
|
+
should "not fail" do
|
|
19
|
+
stub(Repository).get(anything, anything) { raise TimeoutError }
|
|
20
|
+
assert_nothing_raised do
|
|
21
|
+
@repo.list
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
context "listing collaborators" do
|
|
27
|
+
setup do
|
|
28
|
+
@collaborators = ["qrush", "coreyhaines"]
|
|
29
|
+
stub(Repository).get(anything, anything) { {'collaborators' => @collaborators} }
|
|
30
|
+
@result = @repo.list
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
should "return just the usernames" do
|
|
34
|
+
assert_equal @collaborators, @result
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
should "hit the github api" do
|
|
38
|
+
assert_received(Repository) do |subject|
|
|
39
|
+
subject.get("/show/#{@account}/#{@project}/collaborators",
|
|
40
|
+
:body => {:login => @account, :token => @api_key}) { { 'collaborators' => @collaborators } }
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context "adding a collaborator" do
|
|
46
|
+
setup do
|
|
47
|
+
@collaborators = ["qrush", @user]
|
|
48
|
+
stub(Repository).post(anything, anything) { {'collaborators' => @collaborators }}
|
|
49
|
+
@collaborators = @repo.add(@user)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
should "hit the github api" do
|
|
53
|
+
assert_received(Repository) do |subject|
|
|
54
|
+
subject.post("/collaborators/#{@project}/add/#{@user}", :body => {
|
|
55
|
+
:login => @account,
|
|
56
|
+
:token => @api_key})
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
should "return the new collaborators" do
|
|
61
|
+
assert_equal ["qrush", @user], @collaborators
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
context "removing a collaborator" do
|
|
65
|
+
setup do
|
|
66
|
+
@collaborators = ["qrush"]
|
|
67
|
+
stub(Repository).post(anything, anything) { {'collaborators' => @collaborators }}
|
|
68
|
+
@result = @repo.remove(@user)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
should "hit the github api" do
|
|
72
|
+
assert_received(Repository) do |subject|
|
|
73
|
+
subject.post("/collaborators/#{@project}/remove/#{@user}", :body => {
|
|
74
|
+
:login => @account,
|
|
75
|
+
:token => @api_key})
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
should "return the new collaborators" do
|
|
80
|
+
assert_equal ["qrush"], @result
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
data/test/test_helper.rb
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require 'shoulda'
|
|
4
|
+
require 'rr'
|
|
5
|
+
|
|
6
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
7
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
8
|
+
require 'enforcer'
|
|
9
|
+
|
|
10
|
+
begin
|
|
11
|
+
require 'redgreen'
|
|
12
|
+
rescue LoadError
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class Test::Unit::TestCase
|
|
16
|
+
include RR::Adapters::TestUnit
|
|
17
|
+
|
|
18
|
+
def setup
|
|
19
|
+
RR.reset
|
|
20
|
+
stub(STDOUT).puts
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def teardown
|
|
24
|
+
begin
|
|
25
|
+
RR.verify
|
|
26
|
+
ensure
|
|
27
|
+
RR.reset
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: thoughtbot-enforcer
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.2
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Nick Quaranto
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
|
|
12
|
+
date: 2009-08-24 00:00:00 -07:00
|
|
13
|
+
default_executable: enforcer
|
|
14
|
+
dependencies:
|
|
15
|
+
- !ruby/object:Gem::Dependency
|
|
16
|
+
name: httparty
|
|
17
|
+
type: :runtime
|
|
18
|
+
version_requirement:
|
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
20
|
+
requirements:
|
|
21
|
+
- - ">="
|
|
22
|
+
- !ruby/object:Gem::Version
|
|
23
|
+
version: "0"
|
|
24
|
+
version:
|
|
25
|
+
- !ruby/object:Gem::Dependency
|
|
26
|
+
name: fcoury-octopi
|
|
27
|
+
type: :runtime
|
|
28
|
+
version_requirement:
|
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: "0"
|
|
34
|
+
version:
|
|
35
|
+
description:
|
|
36
|
+
email: nquaranto@thoughtbot.com
|
|
37
|
+
executables:
|
|
38
|
+
- enforcer
|
|
39
|
+
extensions: []
|
|
40
|
+
|
|
41
|
+
extra_rdoc_files:
|
|
42
|
+
- LICENSE
|
|
43
|
+
- README.rdoc
|
|
44
|
+
files:
|
|
45
|
+
- .document
|
|
46
|
+
- .gitignore
|
|
47
|
+
- LICENSE
|
|
48
|
+
- README.rdoc
|
|
49
|
+
- Rakefile
|
|
50
|
+
- VERSION
|
|
51
|
+
- bin/enforcer
|
|
52
|
+
- enforcer.gemspec
|
|
53
|
+
- features/manage_collaborators.feature
|
|
54
|
+
- features/step_definitions/enforcer_steps.rb
|
|
55
|
+
- features/support/env.rb
|
|
56
|
+
- lib/enforcer.rb
|
|
57
|
+
- lib/repository.rb
|
|
58
|
+
- test/enforcer_test.rb
|
|
59
|
+
- test/integration.rb
|
|
60
|
+
- test/repository_test.rb
|
|
61
|
+
- test/test_helper.rb
|
|
62
|
+
has_rdoc: false
|
|
63
|
+
homepage: http://github.com/thoughtbot/enforcer
|
|
64
|
+
licenses:
|
|
65
|
+
post_install_message:
|
|
66
|
+
rdoc_options:
|
|
67
|
+
- --charset=UTF-8
|
|
68
|
+
require_paths:
|
|
69
|
+
- lib
|
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: "0"
|
|
75
|
+
version:
|
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
77
|
+
requirements:
|
|
78
|
+
- - ">="
|
|
79
|
+
- !ruby/object:Gem::Version
|
|
80
|
+
version: "0"
|
|
81
|
+
version:
|
|
82
|
+
requirements: []
|
|
83
|
+
|
|
84
|
+
rubyforge_project:
|
|
85
|
+
rubygems_version: 1.3.5
|
|
86
|
+
signing_key:
|
|
87
|
+
specification_version: 3
|
|
88
|
+
summary: A simple way to manage permissions on GitHub
|
|
89
|
+
test_files:
|
|
90
|
+
- test/enforcer_test.rb
|
|
91
|
+
- test/integration.rb
|
|
92
|
+
- test/repository_test.rb
|
|
93
|
+
- test/test_helper.rb
|