gitolite-dtg 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,302 @@
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
+ foo = "Foo is a nice test repo"
242
+ foobar "Bob Zilla" = "Foobar is top secret"
243
+ bar = "A nice place to get drinks"
244
+
245
+ # REPO SPECIFIC GITCONFIG
246
+ # -----------------------
247
+
248
+ # update 2010-02-06; this won't work unless the rc file has the right
249
+ # settings; please see comments around the variable $GL_GITCONFIG_KEYS in
250
+ # conf/example.gitolite.rc for details and security information.
251
+
252
+ # (Thanks to teemu dot matilainen at iki dot fi)
253
+
254
+ # this should be specified within a "repo" stanza
255
+
256
+ # syntax:
257
+ # config sectionname.keyname = [optional value_string]
258
+
259
+ # example usage: if you placed a hook in hooks/common that requires
260
+ # configuration information that is specific to each repo, you could do this:
261
+
262
+ repo gitolite
263
+ config hooks.mailinglist = gitolite-commits@example.tld
264
+ config hooks.emailprefix = "[gitolite] "
265
+ config foo.bar = ""
266
+ config foo.baz =
267
+
268
+ # This does either a plain "git config section.key value" (for the first 3
269
+ # examples above) or "git config --unset-all section.key" (for the last
270
+ # example). Other forms (--add, the value_regex, etc) are not supported.
271
+
272
+ # INCLUDE SOME OTHER FILE
273
+ # -----------------------
274
+
275
+ include "foo.conf"
276
+ subconf "bar.conf"
277
+
278
+ # this includes the contents of $GL_ADMINDIR/conf/foo.conf here
279
+
280
+ # Notes:
281
+ # - the include statement is not allowed inside delegated fragments for
282
+ # security reasons.
283
+ # - you can also use an absolute path if you like, although in the interests
284
+ # of cloning the admin-repo sanely you should avoid doing this!
285
+
286
+ # EXTERNAL COMMAND HELPERS -- RSYNC
287
+ # ---------------------------------
288
+
289
+ # If $RSYNC_BASE is non-empty, the following config entries come into play
290
+ # (otherwise they are ignored):
291
+
292
+ # a "fake" git repository to collect rsync rules. Gitolite does not
293
+ # auto-create any repo whose name starts with EXTCMD/
294
+ repo EXTCMD/rsync
295
+ # grant permissions to files/dirs within the $RSYNC_BASE tree. A leading
296
+ # NAME/ is required as a prefix; the actual path starts after that. Matching
297
+ # follows the same rules as given in "FILE/DIR NAME BASED RESTRICTIONS" above
298
+ RW NAME/ = sitaram
299
+ RW NAME/foo/ = user1
300
+ R NAME/bar/ = user2
301
+ # just to remind you that these are perl regexes, not shell globs
302
+ RW NAME/baz/.*/*.c = user3
@@ -0,0 +1,5 @@
1
+ repo gitolite-admin
2
+ RW+ = bobzilla
3
+
4
+ repo testing
5
+ RW+ = @all
@@ -0,0 +1,4 @@
1
+ require 'gitolite/gitolite_admin'
2
+
3
+ describe Gitolite::GitoliteAdmin do
4
+ end
@@ -0,0 +1,126 @@
1
+ require 'gitolite/config/group'
2
+ require 'spec_helper'
3
+
4
+ describe Gitolite::Config::Group do
5
+ describe "#new" do
6
+ it "should create a new group with an empty list of users" do
7
+ group = Gitolite::Config::Group.new("testgroup")
8
+ group.users.empty?.should be true
9
+ group.name.should == "testgroup"
10
+ end
11
+
12
+ it "should create a new group with a name containing #{Gitolite::Config::Group::PREPEND_CHAR}" do
13
+ name = "#{Gitolite::Config::Group::PREPEND_CHAR}testgroup"
14
+ group = Gitolite::Config::Group.new(name)
15
+ group.name.should == "testgroup"
16
+ end
17
+ end
18
+
19
+ describe "users" do
20
+ before :each do
21
+ @group = Gitolite::Config::Group.new('testgroup')
22
+ end
23
+
24
+ describe "#add_user" do
25
+ it "should allow adding one user with a string" do
26
+ @group.add_user("bob")
27
+ @group.size.should == 1
28
+ @group.users.first.should == "bob"
29
+ end
30
+
31
+ it "should allow adding one user with a symbol" do
32
+ @group.add_user(:bob)
33
+ @group.size.should == 1
34
+ @group.users.first.should == "bob"
35
+ end
36
+
37
+ it "should not add the same user twice" do
38
+ @group.add_user("bob")
39
+ @group.size.should == 1
40
+ @group.add_user(:bob)
41
+ @group.size.should == 1
42
+ @group.users.first.should == "bob"
43
+ end
44
+
45
+ it "should maintain users in sorted order" do
46
+ @group.add_user("susan")
47
+ @group.add_user("peyton")
48
+ @group.add_user("bob")
49
+ @group.users.first.should == "bob"
50
+ @group.users.last.should == "susan"
51
+ end
52
+ end
53
+
54
+ describe "#add_users" do
55
+ it "should allow adding multiple users at once" do
56
+ @group.add_users("bob", "joe", "sue", "sam", "dan")
57
+ @group.size.should == 5
58
+ end
59
+
60
+ it "should allow adding multiple users in nested arrays" do
61
+ @group.add_users(["bob", "joe", ["sam", "sue", "dan"]], "bill")
62
+ @group.size.should == 6
63
+ end
64
+
65
+ it "should allow adding users of symbols and strings" do
66
+ @group.add_users("bob", :joe, :sue, "sam")
67
+ @group.size.should == 4
68
+ end
69
+
70
+ it "should not add the same user twice" do
71
+ @group.add_users("bob", :bob, "bob", "sam")
72
+ @group.size.should == 2
73
+ end
74
+ end
75
+
76
+ describe "#rm_user" do
77
+ before :each do
78
+ @group.add_users("bob", "joe", "susan", "sam", "alex")
79
+ end
80
+
81
+ it "should support removing a user via a String" do
82
+ @group.rm_user("bob")
83
+ @group.size.should == 4
84
+ end
85
+
86
+ it "should support removing a user via a Symbol" do
87
+ @group.rm_user(:bob)
88
+ @group.size.should == 4
89
+ end
90
+ end
91
+
92
+ describe "#empty!" do
93
+ it "should clear all users from the group" do
94
+ @group.add_users("bob", "joe", "sue", "jim")
95
+ @group.size.should == 4
96
+ @group.empty!
97
+ @group.size.should == 0
98
+ end
99
+ end
100
+
101
+ describe "#size" do
102
+ it "should reflect how many users are in the group" do
103
+ @group.add_users("bob", "joe", "sue", "jim")
104
+ @group.users.length.should == @group.size
105
+ end
106
+ end
107
+
108
+ describe "#has_user?" do
109
+ it "should search for a user via a String" do
110
+ @group.add_user("bob")
111
+ @group.has_user?("bob").should be true
112
+ end
113
+
114
+ it "should search for a user via a Symbol" do
115
+ @group.add_user(:bob)
116
+ @group.has_user?(:bob).should be true
117
+ end
118
+ end
119
+ end
120
+
121
+ describe "#to_s" do
122
+ group = Gitolite::Config::Group.new("testgroup")
123
+ group.add_users("bob", "joe", "sam", "sue")
124
+ group.to_s.should == "@testgroup = bob joe sam sue\n" #10 spaces after @testgroup
125
+ end
126
+ end
data/spec/repo_spec.rb ADDED
@@ -0,0 +1,184 @@
1
+ require 'hashery'
2
+ require 'gitolite/config/repo'
3
+ require 'spec_helper'
4
+
5
+ describe Gitolite::Config::Repo do
6
+ before(:each) do
7
+ @repo = Gitolite::Config::Repo.new("CoolRepo")
8
+ end
9
+
10
+ describe '#new' do
11
+ it 'should create a repo called "CoolRepo"' do
12
+ @repo.name.should == "CoolRepo"
13
+ end
14
+ end
15
+
16
+ describe "deny rules" do
17
+ it 'should maintain the order of rules for a repository' do
18
+ @repo.add_permission("RW+", "", "bob", "joe", "sam")
19
+ @repo.add_permission("R", "", "sue", "jen", "greg")
20
+ @repo.add_permission("-", "refs/tags/test[0-9]", "@students", "jessica")
21
+ @repo.add_permission("RW", "refs/tags/test[0-9]", "@teachers", "bill", "todd")
22
+ @repo.add_permission("R", "refs/tags/test[0-9]", "@profs")
23
+
24
+ @repo.permissions.length.should == 2
25
+ @repo.permissions[0].size.should == 2
26
+ @repo.permissions[1].size.should == 3
27
+ end
28
+ end
29
+
30
+ describe '#add_permission' do
31
+ it 'should allow adding a permission to the permissions list' do
32
+ @repo.add_permission("RW+")
33
+ @repo.permissions.length.should == 1
34
+ @repo.permissions.first.keys.first.should == "RW+"
35
+ end
36
+
37
+ it 'should allow adding a permission while specifying a refex' do
38
+ @repo.add_permission("RW+", "refs/heads/master")
39
+ @repo.permissions.length.should == 1
40
+ @repo.permissions.first.keys.first.should == "RW+"
41
+ @repo.permissions.first.values.last.first.first.should == "refs/heads/master"
42
+ end
43
+
44
+ it 'should allow specifying users individually' do
45
+ @repo.add_permission("RW+", "", "bob", "joe", "susan", "sam", "bill")
46
+ @repo.permissions.first["RW+"][""].should == %w[bob joe susan sam bill]
47
+ end
48
+
49
+ it 'should allow specifying users as an array' do
50
+ users = %w[bob joe susan sam bill]
51
+
52
+ @repo.add_permission("RW+", "", users)
53
+ @repo.permissions.first["RW+"][""].should == users
54
+ end
55
+
56
+ it 'should not allow adding an invalid permission via an InvalidPermissionError' do
57
+ expect {@repo.add_permission("BadPerm")}.to raise_error
58
+ end
59
+ end
60
+
61
+ describe "permissions" do
62
+ before(:each) do
63
+ @repo = Gitolite::Config::Repo.new("CoolRepo")
64
+ end
65
+
66
+ it 'should allow adding the permission C' do
67
+ @repo.add_permission("C", "", "bob")
68
+ end
69
+
70
+ it 'should allow adding the permission -' do
71
+ @repo.add_permission("-", "", "bob")
72
+ end
73
+
74
+ it 'should allow adding the permission R' do
75
+ @repo.add_permission("R", "", "bob")
76
+ end
77
+
78
+ it 'should allow adding the permission RM' do
79
+ @repo.add_permission("RM", "", "bob")
80
+ end
81
+
82
+ it 'should allow adding the permission RW' do
83
+ @repo.add_permission("RW", "", "bob")
84
+ end
85
+
86
+ it 'should allow adding the permission RWM' do
87
+ @repo.add_permission("RWM", "", "bob")
88
+ end
89
+
90
+ it 'should allow adding the permission RW+' do
91
+ @repo.add_permission("RW+", "", "bob")
92
+ end
93
+
94
+ it 'should allow adding the permission RW+M' do
95
+ @repo.add_permission("RW+M", "", "bob")
96
+ end
97
+
98
+ it 'should allow adding the permission RWC' do
99
+ @repo.add_permission("RWC", "", "bob")
100
+ end
101
+
102
+ it 'should allow adding the permission RWCM' do
103
+ @repo.add_permission("RWCM", "", "bob")
104
+ end
105
+
106
+ it 'should allow adding the permission RW+C' do
107
+ @repo.add_permission("RW+C", "", "bob")
108
+ end
109
+
110
+ it 'should allow adding the permission RW+CM' do
111
+ @repo.add_permission("RW+CM", "", "bob")
112
+ end
113
+
114
+ it 'should allow adding the permission RWD' do
115
+ @repo.add_permission("RWD", "", "bob")
116
+ end
117
+
118
+ it 'should allow adding the permission RWDM' do
119
+ @repo.add_permission("RWDM", "", "bob")
120
+ end
121
+
122
+ it 'should allow adding the permission RW+D' do
123
+ @repo.add_permission("RW+D", "", "bob")
124
+ end
125
+
126
+ it 'should allow adding the permission RW+DM' do
127
+ @repo.add_permission("RW+DM", "", "bob")
128
+ end
129
+
130
+ it 'should allow adding the permission RWCD' do
131
+ @repo.add_permission("RWCD", "", "bob")
132
+ end
133
+
134
+ it 'should allow adding the permission RWCDM' do
135
+ @repo.add_permission("RWCDM", "", "bob")
136
+ end
137
+
138
+ it 'should allow adding the permission RW+CD' do
139
+ @repo.add_permission("RW+CD", "", "bob")
140
+ end
141
+
142
+ it 'should allow adding the permission RW+CDM' do
143
+ @repo.add_permission("RW+CDM", "", "bob")
144
+ end
145
+ end
146
+
147
+ describe 'git config options' do
148
+ it 'should allow setting a git configuration option' do
149
+ email = "bob@zilla.com"
150
+ @repo.set_git_config("email", email).should == email
151
+ end
152
+
153
+ it 'should allow deletion of an existing git configuration option' do
154
+ email = "bob@zilla.com"
155
+ @repo.set_git_config("email", email)
156
+ @repo.unset_git_config("email").should == email
157
+ end
158
+
159
+ end
160
+
161
+ describe 'permission management' do
162
+ it 'should combine two entries for the same permission and refex' do
163
+ users = %w[bob joe susan sam bill]
164
+ more_users = %w[sally peyton andrew erin]
165
+
166
+ @repo.add_permission("RW+", "", users)
167
+ @repo.add_permission("RW+", "", more_users)
168
+ @repo.permissions.first["RW+"][""].should == users.concat(more_users)
169
+ @repo.permissions.first["RW+"][""].length.should == 9
170
+ end
171
+
172
+ it 'should not list the same users twice for the same permission level' do
173
+ users = %w[bob joe susan sam bill]
174
+ more_users = %w[bob peyton andrew erin]
175
+ even_more_users = %w[bob jim wayne courtney]
176
+
177
+ @repo.add_permission("RW+", "", users)
178
+ @repo.add_permission("RW+", "", more_users)
179
+ @repo.add_permission("RW+", "", even_more_users)
180
+ @repo.permissions.first["RW+"][""].should == users.concat(more_users).concat(even_more_users).uniq!
181
+ @repo.permissions.first["RW+"][""].length.should == 11
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,2 @@
1
+ require 'forgery'
2
+ require 'tmpdir'