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 ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
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
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'lib/enforcer'
4
+
5
+ token = `git config github.token`
6
+
7
+ Enforcer "qrush", token.chomp do
8
+ project "aquinas", "qrush", "mittens"
9
+ end
@@ -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
@@ -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