gitolite 0.0.1.alpha
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +30 -0
- data/README.rdoc +22 -0
- data/Rakefile +2 -0
- data/gitolite.gemspec +24 -0
- data/lib/gitolite.rb +6 -0
- data/lib/gitolite/config.rb +123 -0
- data/lib/gitolite/gitolite_admin.rb +82 -0
- data/lib/gitolite/ssh_key.rb +68 -0
- data/lib/gitolite/version.rb +3 -0
- data/spec/config_spec.rb +4 -0
- data/spec/configs/complicated.conf +298 -0
- data/spec/configs/simple.conf +5 -0
- data/spec/gitolite_admin_spec.rb +4 -0
- data/spec/keys/bob.pub +1 -0
- data/spec/keys/bob@desktop.pub +1 -0
- data/spec/keys/bob@zilla.com.pub +1 -0
- data/spec/keys/bob@zilla.com@desktop.pub +1 -0
- data/spec/keys/jakub123.pub +1 -0
- data/spec/keys/jakub123@foo.net.pub +1 -0
- data/spec/keys/joe@sch.ool.edu.pub +1 -0
- data/spec/keys/joe@sch.ool.edu@desktop.pub +1 -0
- data/spec/spec_helper.rb +0 -0
- data/spec/ssh_key_spec.rb +124 -0
- metadata +121 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
gitolite (0.1.0)
|
5
|
+
grit (~> 2.4.1)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
diff-lcs (1.1.2)
|
11
|
+
grit (2.4.1)
|
12
|
+
diff-lcs (~> 1.1)
|
13
|
+
mime-types (~> 1.15)
|
14
|
+
mime-types (1.16)
|
15
|
+
rspec (2.4.0)
|
16
|
+
rspec-core (~> 2.4.0)
|
17
|
+
rspec-expectations (~> 2.4.0)
|
18
|
+
rspec-mocks (~> 2.4.0)
|
19
|
+
rspec-core (2.4.0)
|
20
|
+
rspec-expectations (2.4.0)
|
21
|
+
diff-lcs (~> 1.1.2)
|
22
|
+
rspec-mocks (2.4.0)
|
23
|
+
|
24
|
+
PLATFORMS
|
25
|
+
ruby
|
26
|
+
x86-mingw32
|
27
|
+
|
28
|
+
DEPENDENCIES
|
29
|
+
gitolite!
|
30
|
+
rspec (~> 2.4.0)
|
data/README.rdoc
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
= gitolite - Coming soon
|
2
|
+
|
3
|
+
This gem is designed to provide a Ruby interface to the {gitolite}[https://github.com/sitaramc/gitolite] git backend system. I am aiming to provide all management functionality that is available via the gitolite-admin repository (like SSH keys, repository permissions, etc)
|
4
|
+
|
5
|
+
== Requirements
|
6
|
+
* Ruby 1.9.2 or higher
|
7
|
+
* a working {gitolite}[https://github.com/sitaramc/gitolite] installation
|
8
|
+
* the <tt>gitolite-admin</tt> repository checked out locally
|
9
|
+
|
10
|
+
== Installation
|
11
|
+
|
12
|
+
gem install gitolite
|
13
|
+
|
14
|
+
== Usage
|
15
|
+
|
16
|
+
== Caveats
|
17
|
+
=== 1.8.x compatibility
|
18
|
+
This gem should work properly on Ruby 1.8.x with the exception of deny rules. In order to fully support Ruby < 1.9.x, an ordered Hash is required, such as the one implemented by ActiveSupport. Support will be added if there appears to be a demand for it.
|
19
|
+
|
20
|
+
== Documentation
|
21
|
+
|
22
|
+
== Future
|
data/Rakefile
ADDED
data/gitolite.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "gitolite/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "gitolite"
|
7
|
+
s.version = Gitolite::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Stafford Brunk"]
|
10
|
+
s.email = ["wingrunr21@gmail.com"]
|
11
|
+
s.homepage = "https://www.github.com/wingrunr21/gitolite"
|
12
|
+
s.summary = %q{A Ruby gem for manipulating the gitolite git backend via the gitolite-admin repository.}
|
13
|
+
s.description = %q{This gem is designed to provide a Ruby interface to the gitolite git backend system. This gem aims to provide all management functionality that is available via the gitolite-admin repository (like SSH keys, repository permissions, etc)}
|
14
|
+
|
15
|
+
s.rubyforge_project = "gitolite"
|
16
|
+
|
17
|
+
s.add_development_dependency "rspec", "~> 2.4.0"
|
18
|
+
s.add_dependency "grit", "~> 2.4.1"
|
19
|
+
|
20
|
+
s.files = `git ls-files`.split("\n")
|
21
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
22
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
23
|
+
s.require_paths = ["lib"]
|
24
|
+
end
|
data/lib/gitolite.rb
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
module Gitolite
|
2
|
+
class Config
|
3
|
+
attr_accessor :repos, :groups
|
4
|
+
|
5
|
+
def initialize(config)
|
6
|
+
@repos = {}
|
7
|
+
@groups = Hash.new { |k,v| k[v] = [] }
|
8
|
+
process_config(config)
|
9
|
+
end
|
10
|
+
|
11
|
+
#Represents a repo inside the gitolite configuration. The name, permissions, and git config
|
12
|
+
#options are all encapsulated in this class
|
13
|
+
class Repo
|
14
|
+
ALLOWED_PERMISSIONS = ['C', 'R', 'RW', 'RW+', 'RWC', 'RW+C', 'RWD', 'RW+D', 'RWCD', 'RW+CD', '-']
|
15
|
+
|
16
|
+
attr_accessor :permissions, :name, :config
|
17
|
+
|
18
|
+
def initialize(name)
|
19
|
+
@name = name
|
20
|
+
@permissions = Hash.new {|k,v| k[v] = Hash.new{|k2, v2| k2[v2] = [] }}
|
21
|
+
@config = {}
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_permission(perm, refex, users)
|
25
|
+
if ALLOWED_PERMISSIONS.include? perm
|
26
|
+
@permissions[perm][refex].concat users
|
27
|
+
else
|
28
|
+
raise InvalidPermissionError, "#{perm} is not in the allowed list of permissions!"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_git_config(key, value)
|
33
|
+
@config[key] = value
|
34
|
+
end
|
35
|
+
|
36
|
+
def unset_git_config(key)
|
37
|
+
@config.delete(key)
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_s
|
41
|
+
@name
|
42
|
+
end
|
43
|
+
|
44
|
+
#Gets raised if a permission that isn't in the allowed
|
45
|
+
#list is passed in
|
46
|
+
class InvalidPermissionError < RuntimeError
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
#Based on
|
52
|
+
#https://github.com/sitaramc/gitolite/blob/pu/src/gl-compile-conf#cleanup_conf_line
|
53
|
+
def cleanup_config_line(line)
|
54
|
+
#remove comments, even those that happen inline
|
55
|
+
line.gsub!(/^((".*?"|[^#"])*)#.*/) {|m| m=$1}
|
56
|
+
|
57
|
+
#fix whitespace
|
58
|
+
line.gsub!('=', ' = ')
|
59
|
+
line.gsub!(/\s+/, ' ')
|
60
|
+
line.strip!
|
61
|
+
end
|
62
|
+
|
63
|
+
def process_config(config)
|
64
|
+
context = [] #will store our context for permissions or config declarations
|
65
|
+
|
66
|
+
#Read each line of our config
|
67
|
+
File.open(config, 'r').each do |l|
|
68
|
+
|
69
|
+
line = cleanup_config_line(l)
|
70
|
+
next if line.empty? #lines are empty if we killed a comment
|
71
|
+
|
72
|
+
case line.strip
|
73
|
+
#found a repo definition
|
74
|
+
when /^repo (.*)/
|
75
|
+
#Empty our current context
|
76
|
+
context = []
|
77
|
+
|
78
|
+
repos = $1.split
|
79
|
+
repos.each do |r|
|
80
|
+
context << r
|
81
|
+
|
82
|
+
@repos[r] = Repo.new(r) unless @repos.has_key? r
|
83
|
+
end
|
84
|
+
#repo permissions
|
85
|
+
when /^(-|C|R|RW\+?(?:C?D?|D?C?)) (.* )?= (.+)/
|
86
|
+
perm = $1
|
87
|
+
refex = $2 || ""
|
88
|
+
users = $3.split
|
89
|
+
|
90
|
+
context.each do |c|
|
91
|
+
@repos[c].add_permission(perm, refex, users)
|
92
|
+
end
|
93
|
+
#repo git config
|
94
|
+
when /^config (.+) = ?(.*)/
|
95
|
+
key = $1
|
96
|
+
value = $2
|
97
|
+
|
98
|
+
context.each do |c|
|
99
|
+
@repos[c].set_git_config(key, value)
|
100
|
+
end
|
101
|
+
#group definition
|
102
|
+
when /^(@\S+) = ?(.*)/
|
103
|
+
group = $1
|
104
|
+
users = $2.split
|
105
|
+
|
106
|
+
@groups[group].concat users
|
107
|
+
@groups[group].uniq!
|
108
|
+
#gitweb definition
|
109
|
+
when /^(\S+)(?: "(.*?)")? = "(.*)"$/
|
110
|
+
#ignore gitweb right now
|
111
|
+
puts line
|
112
|
+
when /^include "(.+)"/
|
113
|
+
#ignore includes for now
|
114
|
+
else
|
115
|
+
puts "The following line cannot be processed:"
|
116
|
+
puts "'#{line}'"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module Gitolite
|
2
|
+
class GitoliteAdmin
|
3
|
+
attr_accessor :gl_admin, :ssh_keys, :config
|
4
|
+
|
5
|
+
CONF = "/conf/gitolite.conf"
|
6
|
+
KEYDIR = "/keydir"
|
7
|
+
|
8
|
+
#Intialize with the path to
|
9
|
+
#the gitolite-admin repository
|
10
|
+
def initialize(path, options = {})
|
11
|
+
@gl_admin = Grit::Repo.new(path)
|
12
|
+
|
13
|
+
@path = path
|
14
|
+
@conf = options[:conf] || CONF
|
15
|
+
@keydir = options[:keydir] || KEYDIR
|
16
|
+
|
17
|
+
@ssh_keys = load_keys(File.join(@path, @keydir))
|
18
|
+
@config = Config.new(File.join(@path, @conf))
|
19
|
+
end
|
20
|
+
|
21
|
+
#Writes all aspects out to the file system
|
22
|
+
#will also stage all changes
|
23
|
+
def save
|
24
|
+
#Process config file
|
25
|
+
|
26
|
+
#Process ssh keys
|
27
|
+
files = list_keys(File.join(@path, @keydir)).map{|f| File.basename f}
|
28
|
+
keys = @ssh_keys.values.map{|f| f.map {|t| t.filename}}.flatten
|
29
|
+
|
30
|
+
#Remove all keys we don't have a record for
|
31
|
+
to_remove = (files - keys).map { |f| File.join(@keydir, f)}
|
32
|
+
@gl_admin.remove(to_remove) unless to_remove.empty?
|
33
|
+
|
34
|
+
#Write all keys to files, overwriting existing keys
|
35
|
+
keys.each do |key|
|
36
|
+
File.open(key, "w") do |f|
|
37
|
+
f.write key.to_s
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
#commits all staged changes and pushes back
|
43
|
+
#to origin
|
44
|
+
def apply
|
45
|
+
status = @gl_admin.status
|
46
|
+
end
|
47
|
+
|
48
|
+
#Calls save and apply in order
|
49
|
+
def save_and_apply
|
50
|
+
end
|
51
|
+
|
52
|
+
def add_key(key)
|
53
|
+
raise "Key must be of type Gitolite::SSHKey!" unless key.instance_of? Gitolite::SSHKey
|
54
|
+
@ssh_keys[key.owner] << key
|
55
|
+
end
|
56
|
+
|
57
|
+
def rm_key(key)
|
58
|
+
@ssh_keys[key.owner].delete key
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
#Loads all .pub files in the gitolite-admin
|
63
|
+
#keydir directory
|
64
|
+
def load_keys(path)
|
65
|
+
keys = Hash.new {|k,v| k[v] = []}
|
66
|
+
|
67
|
+
list_keys(path).each do |key|
|
68
|
+
new_key = SSHKey.from_file(File.join(path, key))
|
69
|
+
owner = new_key.owner
|
70
|
+
|
71
|
+
keys[owner] << new_key
|
72
|
+
end
|
73
|
+
|
74
|
+
keys
|
75
|
+
end
|
76
|
+
|
77
|
+
def list_keys(path)
|
78
|
+
Dir.chdir(path)
|
79
|
+
Dir.glob("**/*.pub")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Gitolite
|
2
|
+
#Models an SSH key within gitolite
|
3
|
+
#provides support for multikeys
|
4
|
+
#
|
5
|
+
#Types of multi keys:
|
6
|
+
# bob.pub => username: bob
|
7
|
+
# bob@desktop.pub => username: bob, location: desktop
|
8
|
+
# bob@email.com.pub => username: bob@email.com
|
9
|
+
# bob@email.com@desktop.pub => username: bob@email.com, location: desktop
|
10
|
+
|
11
|
+
class SSHKey
|
12
|
+
attr_accessor :owner, :location, :type, :blob, :email
|
13
|
+
|
14
|
+
def initialize(type, blob, email, owner = nil, location = "")
|
15
|
+
@type = type
|
16
|
+
@blob = blob
|
17
|
+
@email = email
|
18
|
+
|
19
|
+
@owner = owner || email
|
20
|
+
@location = location
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.from_file(key)
|
24
|
+
|
25
|
+
raise "#{key} does not exist!" unless File.exists?(key)
|
26
|
+
|
27
|
+
#Get our owner and location
|
28
|
+
File.basename(key) =~ /^(\w+(?:@(?:\w+\.)+\D{2,4})?)(?:@(\w+))?.pub$/i
|
29
|
+
owner = $1
|
30
|
+
location = $2 || ""
|
31
|
+
|
32
|
+
#Get parts of the key
|
33
|
+
type, blob, email = File.read(key).split
|
34
|
+
|
35
|
+
#If the key didn't have an email, just use the owner
|
36
|
+
if email.nil?
|
37
|
+
email = owner
|
38
|
+
end
|
39
|
+
|
40
|
+
self.new(type, blob, email, owner, location)
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_s
|
44
|
+
[@type, @blob, @email].join(' ')
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_file(filename)
|
48
|
+
File.open(filename, "w") do |f|
|
49
|
+
f.write (self.to_s)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def filename
|
54
|
+
file = @owner
|
55
|
+
file += "@#{@location}" unless @location.empty?
|
56
|
+
file += ".pub"
|
57
|
+
end
|
58
|
+
|
59
|
+
def ==(key)
|
60
|
+
@type == key.type &&
|
61
|
+
@blob == key.blob &&
|
62
|
+
@email == key.email &&
|
63
|
+
@owner == key.owner &&
|
64
|
+
@location == key.location
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,298 @@
|
|
1
|
+
# example conf file for gitolite
|
2
|
+
|
3
|
+
# ----------------------------------------------------------------------------
|
4
|
+
# overall syntax:
|
5
|
+
# - everything is space-separated; no commas, semicolons, etc (except in
|
6
|
+
# the description string for gitweb)
|
7
|
+
# - comments in the normal shell-ish style; no surprises there
|
8
|
+
# - there are NO continuation lines of any kind
|
9
|
+
# - user/repo names as simple as possible; they must start with an
|
10
|
+
# alphanumeric, but after that they can also contain ".", "_", "-".
|
11
|
+
# - usernames can optionally be followed by an "@" and a domainname
|
12
|
+
# containing at least one "." (this allows you to use an email
|
13
|
+
# address as someone's username)
|
14
|
+
# - reponames can contain "/" characters (this allows you to
|
15
|
+
# put your repos in a tree-structure for convenience)
|
16
|
+
|
17
|
+
# objectives, over and above gitosis:
|
18
|
+
# - simpler syntax
|
19
|
+
# - easier gitweb/daemon control
|
20
|
+
# - specify who can push a branch/tag
|
21
|
+
# - specify who can rewind a branch/rewrite a tag
|
22
|
+
|
23
|
+
# ----------------------------------------------------------------------------
|
24
|
+
|
25
|
+
# GROUPS
|
26
|
+
# ------
|
27
|
+
|
28
|
+
# syntax:
|
29
|
+
# @groupname = [one or more names]
|
30
|
+
|
31
|
+
# groups let you club (user or group) names together for convenience
|
32
|
+
|
33
|
+
# * a group is like a #define in C except that it can *accumulate* values
|
34
|
+
# * the config file is parsed in a single-pass, so later *additions* to a
|
35
|
+
# group name cannot affect earlier *uses* of it
|
36
|
+
|
37
|
+
# The following examples should illustrate all this:
|
38
|
+
|
39
|
+
# you can have a group of people...
|
40
|
+
@staff = sitaram some_dev another-dev
|
41
|
+
|
42
|
+
# ...or a group of repos
|
43
|
+
@oss_repos = gitolite linux git perl rakudo entrans vkc
|
44
|
+
|
45
|
+
# ...or even a group of refexes
|
46
|
+
@important = master$ QA_done refs/tags/v[0-9]
|
47
|
+
# (see later for what "refex"s are; I'm only mentioning it
|
48
|
+
# here to emphasise that you can group them too)
|
49
|
+
|
50
|
+
# even sliced and diced differently
|
51
|
+
@admins = sitaram admin2
|
52
|
+
# notice that sitaram is in 2 groups (staff and admins)
|
53
|
+
|
54
|
+
# if you repeat a group name in another definition line, the
|
55
|
+
# new ones get added to the old ones (they accumulate)
|
56
|
+
@staff = au.thor
|
57
|
+
# so now "@staff" expands to all 4 names
|
58
|
+
|
59
|
+
# groups can include other groups, and the included group will
|
60
|
+
# be expanded to whatever value it currently has
|
61
|
+
@interns = indy james
|
62
|
+
@staff = bob @interns
|
63
|
+
# "@staff" expands to 7 names now
|
64
|
+
@interns = han
|
65
|
+
# "@interns" now has 3 names in it, but note that this does
|
66
|
+
# not change @staff
|
67
|
+
|
68
|
+
# REPO AND BRANCH PERMISSIONS
|
69
|
+
# ---------------------------
|
70
|
+
|
71
|
+
# syntax:
|
72
|
+
# start line:
|
73
|
+
# repo [one or more repos and/or repo groups]
|
74
|
+
# followed by one or more permissions lines:
|
75
|
+
# (C|R|RW|RW+|RWC|RW+C|RWD|RW+D|RWCD|RW+CD) [zero or more refexes] = [one or more users]
|
76
|
+
|
77
|
+
# there are 6 types of permissions: R, RW, and RW+ are simple (the "+" means
|
78
|
+
# permission to "rewind" -- force push a non-fast forward to -- a branch).
|
79
|
+
# The *standalone* C permission pertains to creating a REPO and is described
|
80
|
+
# in doc/wildcard-repositories.mkd. The C and D *suffixes* to the RW/RW+
|
81
|
+
# permissions pertain to creating or deleting a BRANCH, and are described in
|
82
|
+
# doc/3-faq-tips-etc.mkd, in the sections on "separating push and create
|
83
|
+
# rights" and "separating delete and rewind rights" respectively.
|
84
|
+
|
85
|
+
# how permissions are matched:
|
86
|
+
# - user, repo, and access (W or +) are known. For that combination, if
|
87
|
+
# any of the refexes match the refname being updated, the push succeeds.
|
88
|
+
# If none of them match, it fails
|
89
|
+
|
90
|
+
# what's a refex? a regex to match against the ref being updated (get it?)
|
91
|
+
# See next section for more on refexes
|
92
|
+
|
93
|
+
# BASIC PERMISSIONS (repo level only; apply to all branches/tags in repo)
|
94
|
+
|
95
|
+
# most important rule of all -- specify who can make changes
|
96
|
+
# to *this* file take effect
|
97
|
+
repo gitolite-admin
|
98
|
+
RW+ = @admins
|
99
|
+
|
100
|
+
# "@all" is a special, predefined, group name of all users
|
101
|
+
# (everyone who has a pubkey in keydir)
|
102
|
+
repo testing
|
103
|
+
RW+ = @all
|
104
|
+
|
105
|
+
# this repo is visible to staff but only sitaram can write to it
|
106
|
+
repo gitolite
|
107
|
+
R = @staff
|
108
|
+
RW+ = sitaram
|
109
|
+
|
110
|
+
# you can split up access rules for a repo for convenience
|
111
|
+
# (notice that @oss_repos contains gitolite also)
|
112
|
+
repo @oss_repos
|
113
|
+
R = @all
|
114
|
+
|
115
|
+
# set permissions to all repos. *Please* do see
|
116
|
+
# doc/3-faq-tips-etc.mkd for notes on this feature
|
117
|
+
repo @all
|
118
|
+
RW+ = @admins
|
119
|
+
|
120
|
+
# SPECIFYING AND USING A REFEX
|
121
|
+
|
122
|
+
# - refexes are specified in perl regex syntax
|
123
|
+
# - refexes are prefix-matched (they are internally anchored with "^"
|
124
|
+
# before being used), which means a refex like "refs/tags/v[0-9]"
|
125
|
+
# matches anything *starting with* that pattern. There may be text
|
126
|
+
# after it (example: refs/tags/v4-r3/p7), and it will still match
|
127
|
+
|
128
|
+
# ADVANCED PERMISSIONS USING REFEXES
|
129
|
+
|
130
|
+
# - if no refex appears, the rule applies to all refs in that repo
|
131
|
+
# - a refex is automatically prefixed by "refs/heads/" if it doesn't start
|
132
|
+
# with "refs/" (so tags have to be explicitly named as
|
133
|
+
# refs/tags/pattern)
|
134
|
+
|
135
|
+
# here's the example from
|
136
|
+
# Documentation/howto/update-hook-example.txt:
|
137
|
+
|
138
|
+
# refs/heads/master junio
|
139
|
+
# +refs/heads/pu junio
|
140
|
+
# refs/heads/cogito$ pasky
|
141
|
+
# refs/heads/bw/.* linus
|
142
|
+
# refs/heads/tmp/.* .*
|
143
|
+
# refs/tags/v[0-9].* junio
|
144
|
+
|
145
|
+
# and here're the equivalent gitolite refexes
|
146
|
+
repo git
|
147
|
+
RW = bobzilla
|
148
|
+
RW master = junio
|
149
|
+
RW+ pu = junio
|
150
|
+
RW cogito$ = pasky
|
151
|
+
RW bw/ = linus
|
152
|
+
RW tmp/ = @all
|
153
|
+
RW refs/tags/v[0-9] = junio
|
154
|
+
|
155
|
+
# DENY/EXCLUDE RULES
|
156
|
+
|
157
|
+
# ***IMPORTANT NOTES ABOUT "DENY" RULES***:
|
158
|
+
|
159
|
+
# - deny rules do NOT affect read access. They only apply to write access.
|
160
|
+
#
|
161
|
+
# - when using deny rules, the order of your rules starts to matter, where
|
162
|
+
# earlier it did not. The first matching rule applies, where "matching" is
|
163
|
+
# defined as either permitting the operation you're attempting (`W` or `+`),
|
164
|
+
# which results in success, or a "deny" (`-`), which results in failure.
|
165
|
+
# (As before, a fallthrough also results in failure).
|
166
|
+
|
167
|
+
# in the example above, you cannot easily say "anyone can write any tag,
|
168
|
+
# except version tags can only be written by junio". The following might look
|
169
|
+
# like it works but it doesn't:
|
170
|
+
|
171
|
+
# RW refs/tags/v[0-9] = junio
|
172
|
+
# RW refs/tags/ = junio linus pasky @others
|
173
|
+
|
174
|
+
# if you use "deny" rules, however, you can do this (a "deny" rule just uses
|
175
|
+
# "-" instead of "R" or "RW" or "RW+" in the permission field)
|
176
|
+
|
177
|
+
RW refs/tags/v[0-9] = junio
|
178
|
+
- refs/tags/v[0-9] = linus pasky @others
|
179
|
+
RW refs/tags/ = junio linus pasky @others
|
180
|
+
|
181
|
+
# FILE/DIR NAME BASED RESTRICTIONS
|
182
|
+
# --------------------------------
|
183
|
+
|
184
|
+
# Here's a hopefully self-explanatory example. Assume the project has the
|
185
|
+
# following contents at the top level: a README, a "doc/" directory, and an
|
186
|
+
# "src/" directory.
|
187
|
+
|
188
|
+
repo foo
|
189
|
+
RW+ = lead_dev # rule 1
|
190
|
+
RW = dev1 dev2 dev3 dev4 # rule 2
|
191
|
+
|
192
|
+
RW NAME/ = lead_dev # rule 3
|
193
|
+
RW NAME/doc/ = dev1 dev2 # rule 4
|
194
|
+
RW NAME/src/ = dev1 dev2 dev3 dev4 # rule 5
|
195
|
+
|
196
|
+
# Notes
|
197
|
+
|
198
|
+
# - the "NAME/" is part of the syntax; think of it as a keyword if you like.
|
199
|
+
# The rest of it is treated as a refex to match against each file being
|
200
|
+
# touched (see "SPECIFYING AND USING A REFEX" above for details)
|
201
|
+
|
202
|
+
# - file/dir NAME-based restrictions are *in addition* to normal (branch-name
|
203
|
+
# based) restrictions; they are not a *replacement* for them. This is why
|
204
|
+
# rule #2 (or something like it, maybe with a more specific branch-name) is
|
205
|
+
# needed; without it, dev1/2/3/4 cannot push any branches.
|
206
|
+
|
207
|
+
# - if a repo has *any* NAME/ rules, then NAME-based restrictions are checked
|
208
|
+
# for *all* users. This is why rule 3 is needed, even though we don't
|
209
|
+
# actually have any NAME-based restrictions on lead_dev. Notice the pattern
|
210
|
+
# on rule 3.
|
211
|
+
|
212
|
+
# - *each* file touched by the commits being pushed is checked against those
|
213
|
+
# rules. So, lead_dev can push changes to any files, dev1/2 can push
|
214
|
+
# changes to files in "doc/" and "src/" (but not the top level README), and
|
215
|
+
# dev3/4 can only push changes to files in "src/".
|
216
|
+
|
217
|
+
# GITWEB AND DAEMON STUFF
|
218
|
+
# -----------------------
|
219
|
+
|
220
|
+
# No specific syntax for gitweb and daemon access; just make the repo readable
|
221
|
+
# ("R" access) to the special users "gitweb" and "daemon"
|
222
|
+
|
223
|
+
# make "@oss_repos" (all 7 of them!) accessible via git daemon
|
224
|
+
repo @oss_repos
|
225
|
+
R = daemon
|
226
|
+
|
227
|
+
# make the two *large* repos accessible via gitweb
|
228
|
+
repo linux perl
|
229
|
+
R = gitweb
|
230
|
+
|
231
|
+
# REPO OWNER/DESCRIPTION LINE FOR GITWEB
|
232
|
+
|
233
|
+
# syntax, one of:
|
234
|
+
# reponame = "some description string in double quotes"
|
235
|
+
# reponame "owner name" = "some description string in double quotes"
|
236
|
+
|
237
|
+
# note: setting a description also gives gitweb access; you do not have to
|
238
|
+
# give gitweb access as described above if you're specifying a description
|
239
|
+
|
240
|
+
gitolite "Sitaram Chamarty" = "fast, secure, access control for git in a corporate environment"
|
241
|
+
|
242
|
+
# REPO SPECIFIC GITCONFIG
|
243
|
+
# -----------------------
|
244
|
+
|
245
|
+
# update 2010-02-06; this won't work unless the rc file has the right
|
246
|
+
# settings; please see comments around the variable $GL_GITCONFIG_KEYS in
|
247
|
+
# conf/example.gitolite.rc for details and security information.
|
248
|
+
|
249
|
+
# (Thanks to teemu dot matilainen at iki dot fi)
|
250
|
+
|
251
|
+
# this should be specified within a "repo" stanza
|
252
|
+
|
253
|
+
# syntax:
|
254
|
+
# config sectionname.keyname = [optional value_string]
|
255
|
+
|
256
|
+
# example usage: if you placed a hook in hooks/common that requires
|
257
|
+
# configuration information that is specific to each repo, you could do this:
|
258
|
+
|
259
|
+
repo gitolite
|
260
|
+
config hooks.mailinglist = gitolite-commits@example.tld
|
261
|
+
config hooks.emailprefix = "[gitolite] "
|
262
|
+
config foo.bar = ""
|
263
|
+
config foo.baz =
|
264
|
+
|
265
|
+
# This does either a plain "git config section.key value" (for the first 3
|
266
|
+
# examples above) or "git config --unset-all section.key" (for the last
|
267
|
+
# example). Other forms (--add, the value_regex, etc) are not supported.
|
268
|
+
|
269
|
+
# INCLUDE SOME OTHER FILE
|
270
|
+
# -----------------------
|
271
|
+
|
272
|
+
include "foo.conf"
|
273
|
+
|
274
|
+
# this includes the contents of $GL_ADMINDIR/conf/foo.conf here
|
275
|
+
|
276
|
+
# Notes:
|
277
|
+
# - the include statement is not allowed inside delegated fragments for
|
278
|
+
# security reasons.
|
279
|
+
# - you can also use an absolute path if you like, although in the interests
|
280
|
+
# of cloning the admin-repo sanely you should avoid doing this!
|
281
|
+
|
282
|
+
# EXTERNAL COMMAND HELPERS -- RSYNC
|
283
|
+
# ---------------------------------
|
284
|
+
|
285
|
+
# If $RSYNC_BASE is non-empty, the following config entries come into play
|
286
|
+
# (otherwise they are ignored):
|
287
|
+
|
288
|
+
# a "fake" git repository to collect rsync rules. Gitolite does not
|
289
|
+
# auto-create any repo whose name starts with EXTCMD/
|
290
|
+
repo EXTCMD/rsync
|
291
|
+
# grant permissions to files/dirs within the $RSYNC_BASE tree. A leading
|
292
|
+
# NAME/ is required as a prefix; the actual path starts after that. Matching
|
293
|
+
# follows the same rules as given in "FILE/DIR NAME BASED RESTRICTIONS" above
|
294
|
+
RW NAME/ = sitaram
|
295
|
+
RW NAME/foo/ = user1
|
296
|
+
R NAME/bar/ = user2
|
297
|
+
# just to remind you that these are perl regexes, not shell globs
|
298
|
+
RW NAME/baz/.*/*.c = user3
|
data/spec/keys/bob.pub
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6EFlh48tzCnepmggd09sUEM4m1zH3Fs/X6XWm1MAkEnMsD5hFGjkcNabDM8vq9zIRZ05YC6Gxo2plstAf+X4Y636+hyFvbDONB9mRP7DxJhFRaBScSFH60jeTz4ue2ExH3xA1JkaHMcV5vooUqG4BW8Vy/sz8wt/s0aIg9xqkrPOnfvqwunZ/zFUNyL8tC1HY3zGUkRzEVd2yRKaI+DGyRsh8HuYIb2X3NQ0YsU3uGGud7ObmxDbM7WGniyxRVK3lYCvgnTjvdPGi7Xx9QNQz53zLFbklGPZSfpFFHS84qR0Rd/+MnpT50FODhTmXHZtZF1eik09z63GW3YVt4PGoQ== bob@zilla.com
|
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwZc2kw4Bc8Kksp0XBiDR/rDrUAmv2THB9OVbRwJ7TEelU8OFJqCx1syjdjAgS+LE3K5d5xtDMYRlxE2hkl8V6EySY9Q35qWqaqhmS8erZap0qiCWM5vlzxWFKOpnhQdNbNjA7a7FSTDT6ThOC9sTCJfMvNdBiiUUGGDE48AvtwtF3er24h8w7J5623AICfOdhfPAFavTO6/QpeHRe8QOkbBJ2oaJDer4rDetgtBUgHXh3jANgD2ICRFd9l5eCozkDCISFJ6Xg2Eq8gMJ2DKj3BSzBpRPiAJ1YVsr/cBzGxRVRPS6Go485E2r7l7zAsE1t/t6eRUU4W5ZeopxD4GUXQ== bob@zilla.com
|
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAu1cY+0C5QV/0mcdobqS673BVlT7weW1lZKp83v8kTYHJJ8NLKixnPf4VePUoE5IMdmWMHNtAtSCG+X/Gdo/2VBHWbZ/O2mC2WSYH0u/nk+Bw0l30/vbV0wP3rcapY42BiMl/H0CPuxql99SBcVJoAaKkxJ4uvyR/hQ+mEmSIYz7mD11opCC6owmWm7R5Sdf2UGXzYXHwu5G9DdIE+QcmYbLkltCBHwa17syoM5QtetbHc/S/wbudrLclJXPHJ0xEtJMhGEHzNJndwYpOA4R61O+phIXIwdtdBeCAxAQyb9hf+qrOBaMfXyFn/WF0ov8hAnKDWWKg74e4ZHYJ2qPSRw== bob@zilla.com
|
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAsRofYfjAUdw0McxGpLTxBbZyKN05HGY19ZIjEQmBPUe2Skt1i/SLwIYzTzKv6vEgAdT9SwmCsO/jpDY/ZM+MhWy4okBisn04yIHCW10q4+YNo2WatzttEa1W+hC58nKtoq/0HkvPVdoeOZxcNtpjvgvkrXH2zdmX7xnA1AAWtqRNkRYWPKjiojkg92aqmJLISSIDeZs2wvXbFO3BJhkvyr3W60cinKhGBBscvdCYUi5pb9dXIFhEEqRf1JkT5CEmF3p4GqSt4/L79nR0LV45grS4NbcN+fCnjWZ8PQhmJ+WPLKkydgR1YvobeY7zDHdHJXWLhsPa+SjwI3WfzrB+GQ== bob@zilla.com
|
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAvtAkUG0e/dgqzb9Vtj6mspYCueII5U/gx3fnpIb2j8ng/ZJPPLYIb2UCwHdFBj/VZerKiJn6epJRi8qj4ddC4Z/LPNgjn06gbjAAubyb2Lki/XSvizpP6j4OtRnt/Vf17n1hyUKN0OAQmSaf1DoXsvWHpb64U7WxbY3Z3XLdJlqtIXW0vr3X13RKx6JZDGM2re/1ymZ5SJZT/KTruqtC42Yu4C2ktSa+JRh82+jALGy/5A/o1lsCziCSE/+iycVNM9hSfbwGTC1AVT1WO2BiQlduUL3tk4XyMEjlOXF2K4FobcBhLTrNtLc24vnlx5HkcBmuubq7x6g1pw4znwItgQ== jakub123@foo.net
|
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEArDPbrc0rP+Pux38Y14rMkgbPHo7iY89/VG80BH8dXVB1nisFHgY6zJdSPJ3zrEm1j81Hc7tZvd3FGjOKP8Ae02/J8O4WaVdB5pMo81YxQWu3eV6nD7x7AIeZEBauK7zV3eqyxTZ/V0oBd7e9VKMukxoiv+RXlXdItpH0md3bpQ3IreFjfaBrFnX0QLdGx0CjimKtMNOU7yKRlvuGcrvMoRtXSUzssAUtjmy8cRabBqZyJVOFrk6MhE1VpcAEE47Sb2ovFgfx5w4kA7mRAz6jO+MAM5go0lGoK26WrR9p/ZXuhmmdjQMPdSCssGQxni657vLp3F7PGV2AG35M58IwuQ==
|
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAu9Y0aeYzlF/e/JZDYr4s/BmCnU5WATugdxnEDboTFgSt0rIZ3P+93m+wchGgP/GzspHa/gSIBBjDBwmzPlhdNieJdiNyJ0n0BvUWOBlI3wNQLU+wdqa1UwxQyPZNSplxyzhcsIgD6kPqYR9JE6Yga7QUnJdP/vAB+XtMoZlc+CVKjxLrjijSHX57WJ0bSXwKtYVHtgCGtJ1mmAZV/q64SR3mqEwB7WG0BTNwT0ruHRk4Zg/EpuutStYGne23/1FBSrfMirQCEneTiLOO/vAibWLzTRWSVyRT9YJYeH0Cp5dXnu3MqPL6+PhaP+iDtx6Vo/h2jeCJZpJUJb7dX9nl/Q== joe@sch.ool.edu
|
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAt6+DWErgYKwCLQ+1DiD05iZc1FFgU2n+QXSqAOIjU5O2FKVgGU5JLOGydidOUK/vWRrPmS045Iv4BxTPIUPMLjn9lBjUkY7ZxfJb5aSW+9zwE/5/073DswRwHVZuxsxfScgqkwenTjN6bbM+qnASn+b6yxfRLmp86IzIXxKp2EiJ4Anw/9oUxre/K25WemTo8eUfKLfTS+z0KLSs1C9TJpO/MkDkHiv1S2wcnduA+nVcbSo7MuxrVDdQIQcDf0gKwwLwxtvKZXtUWC3Ji9kn3F86aRVBuMcl068t+UbbKvLc0BKo7RFMQ+nHXHosu1GJBwal+wWygbBksTk+92hRGQ== joe@sch.ool.edu
|
data/spec/spec_helper.rb
ADDED
File without changes
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'gitolite/ssh_key'
|
2
|
+
include Gitolite
|
3
|
+
|
4
|
+
describe Gitolite::SSHKey do
|
5
|
+
describe '#owner' do
|
6
|
+
it 'owner should be bob for bob.pub' do
|
7
|
+
key = File.join(File.dirname(__FILE__),'keys', 'bob.pub')
|
8
|
+
s = SSHKey.new(key)
|
9
|
+
s.owner.should == 'bob'
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'owner should be bob for bob@desktop.pub' do
|
13
|
+
key = File.join(File.dirname(__FILE__),'keys', 'bob@desktop.pub')
|
14
|
+
s = SSHKey.new(key)
|
15
|
+
s.owner.should == 'bob'
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'owner should be bob@zilla.com for bob@zilla.com.pub' do
|
19
|
+
key = File.join(File.dirname(__FILE__),'keys', 'bob@zilla.com.pub')
|
20
|
+
s = SSHKey.new(key)
|
21
|
+
s.owner.should == 'bob@zilla.com'
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'owner should be bob@zilla.com for bob@zilla.com@desktop.pub' do
|
25
|
+
key = File.join(File.dirname(__FILE__),'keys', 'bob@zilla.com@desktop.pub')
|
26
|
+
s = SSHKey.new(key)
|
27
|
+
s.owner.should == 'bob@zilla.com'
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'owner should be jakub123 for jakub123.pub' do
|
31
|
+
key = File.join(File.dirname(__FILE__),'keys', 'jakub123.pub')
|
32
|
+
s = SSHKey.new(key)
|
33
|
+
s.owner.should == 'jakub123'
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'owner should be jakub123@foo.net for jakub123@foo.net.pub' do
|
37
|
+
key = File.join(File.dirname(__FILE__),'keys', 'jakub123@foo.net.pub')
|
38
|
+
s = SSHKey.new(key)
|
39
|
+
s.owner.should == 'jakub123@foo.net'
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'owner should be joe@sch.ool.edu for joe@sch.ool.edu' do
|
43
|
+
key = File.join(File.dirname(__FILE__),'keys', 'joe@sch.ool.edu.pub')
|
44
|
+
s = SSHKey.new(key)
|
45
|
+
s.owner.should == 'joe@sch.ool.edu'
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'owner should be joe@sch.ool.edu for joe@sch.ool.edu@desktop.pub' do
|
49
|
+
key = File.join(File.dirname(__FILE__),'keys', 'joe@sch.ool.edu@desktop.pub')
|
50
|
+
s = SSHKey.new(key)
|
51
|
+
s.owner.should == 'joe@sch.ool.edu'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#location' do
|
56
|
+
it 'location should be "" for bob.pub' do
|
57
|
+
key = File.join(File.dirname(__FILE__),'keys', 'bob.pub')
|
58
|
+
s = SSHKey.new(key)
|
59
|
+
s.location.should == ''
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'location should be "desktop" for bob@desktop.pub' do
|
63
|
+
key = File.join(File.dirname(__FILE__),'keys', 'bob@desktop.pub')
|
64
|
+
s = SSHKey.new(key)
|
65
|
+
s.location.should == 'desktop'
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'location should be "" for bob@zilla.com.pub' do
|
69
|
+
key = File.join(File.dirname(__FILE__),'keys', 'bob@zilla.com.pub')
|
70
|
+
s = SSHKey.new(key)
|
71
|
+
s.location.should == ''
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'location should be "desktop" for bob@zilla.com@desktop.pub' do
|
75
|
+
key = File.join(File.dirname(__FILE__),'keys', 'bob@zilla.com@desktop.pub')
|
76
|
+
s = SSHKey.new(key)
|
77
|
+
s.location.should == 'desktop'
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'location should be "" for jakub123.pub' do
|
81
|
+
key = File.join(File.dirname(__FILE__),'keys', 'jakub123.pub')
|
82
|
+
s = SSHKey.new(key)
|
83
|
+
s.location.should == ''
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'location should be "" for jakub123@foo.net.pub' do
|
87
|
+
key = File.join(File.dirname(__FILE__),'keys', 'jakub123@foo.net.pub')
|
88
|
+
s = SSHKey.new(key)
|
89
|
+
s.location.should == ''
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'location should be "" for joe@sch.ool.edu' do
|
93
|
+
key = File.join(File.dirname(__FILE__),'keys', 'joe@sch.ool.edu.pub')
|
94
|
+
s = SSHKey.new(key)
|
95
|
+
s.location.should == ''
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'location should be "desktop" for joe@sch.ool.edu@desktop.pub' do
|
99
|
+
key = File.join(File.dirname(__FILE__),'keys', 'joe@sch.ool.edu@desktop.pub')
|
100
|
+
s = SSHKey.new(key)
|
101
|
+
s.location.should == 'desktop'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe '#keys' do
|
106
|
+
it 'should load ssh key properly' do
|
107
|
+
key = File.join(File.dirname(__FILE__),'keys', 'bob.pub')
|
108
|
+
s = SSHKey.new(key)
|
109
|
+
parts = File.read(key).split #should get type, blob, email
|
110
|
+
|
111
|
+
s.type.should == parts[0]
|
112
|
+
s.blob.should == parts[1]
|
113
|
+
s.email.should == parts[2]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe '#email' do
|
118
|
+
it 'should use owner if email is missing' do
|
119
|
+
key = File.join(File.dirname(__FILE__),'keys', 'jakub123@foo.net.pub')
|
120
|
+
s = SSHKey.new(key)
|
121
|
+
s.owner.should == s.email
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
metadata
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gitolite
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: true
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- alpha
|
10
|
+
version: 0.0.1.alpha
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Stafford Brunk
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-01-30 00:00:00 -05:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rspec
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
segments:
|
30
|
+
- 2
|
31
|
+
- 4
|
32
|
+
- 0
|
33
|
+
version: 2.4.0
|
34
|
+
type: :development
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: grit
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
segments:
|
45
|
+
- 2
|
46
|
+
- 4
|
47
|
+
- 1
|
48
|
+
version: 2.4.1
|
49
|
+
type: :runtime
|
50
|
+
version_requirements: *id002
|
51
|
+
description: This gem is designed to provide a Ruby interface to the gitolite git backend system. This gem aims to provide all management functionality that is available via the gitolite-admin repository (like SSH keys, repository permissions, etc)
|
52
|
+
email:
|
53
|
+
- wingrunr21@gmail.com
|
54
|
+
executables: []
|
55
|
+
|
56
|
+
extensions: []
|
57
|
+
|
58
|
+
extra_rdoc_files: []
|
59
|
+
|
60
|
+
files:
|
61
|
+
- .gitignore
|
62
|
+
- Gemfile
|
63
|
+
- Gemfile.lock
|
64
|
+
- README.rdoc
|
65
|
+
- Rakefile
|
66
|
+
- gitolite.gemspec
|
67
|
+
- lib/gitolite.rb
|
68
|
+
- lib/gitolite/config.rb
|
69
|
+
- lib/gitolite/gitolite_admin.rb
|
70
|
+
- lib/gitolite/ssh_key.rb
|
71
|
+
- lib/gitolite/version.rb
|
72
|
+
- spec/config_spec.rb
|
73
|
+
- spec/configs/complicated.conf
|
74
|
+
- spec/configs/simple.conf
|
75
|
+
- spec/gitolite_admin_spec.rb
|
76
|
+
- spec/keys/bob.pub
|
77
|
+
- spec/keys/bob@desktop.pub
|
78
|
+
- spec/keys/bob@zilla.com.pub
|
79
|
+
- spec/keys/bob@zilla.com@desktop.pub
|
80
|
+
- spec/keys/jakub123.pub
|
81
|
+
- spec/keys/jakub123@foo.net.pub
|
82
|
+
- spec/keys/joe@sch.ool.edu.pub
|
83
|
+
- spec/keys/joe@sch.ool.edu@desktop.pub
|
84
|
+
- spec/spec_helper.rb
|
85
|
+
- spec/ssh_key_spec.rb
|
86
|
+
has_rdoc: true
|
87
|
+
homepage: https://www.github.com/wingrunr21/gitolite
|
88
|
+
licenses: []
|
89
|
+
|
90
|
+
post_install_message:
|
91
|
+
rdoc_options: []
|
92
|
+
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
version: "0"
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
105
|
+
requirements:
|
106
|
+
- - ">"
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
segments:
|
109
|
+
- 1
|
110
|
+
- 3
|
111
|
+
- 1
|
112
|
+
version: 1.3.1
|
113
|
+
requirements: []
|
114
|
+
|
115
|
+
rubyforge_project: gitolite
|
116
|
+
rubygems_version: 1.3.7
|
117
|
+
signing_key:
|
118
|
+
specification_version: 3
|
119
|
+
summary: A Ruby gem for manipulating the gitolite git backend via the gitolite-admin repository.
|
120
|
+
test_files: []
|
121
|
+
|