3 # ----------------------------------------------------------------------
4 # gitolite command to allow repo "owners" to set "options" on repos
6 # This command can be run by a user to set "options" for any repo that she
9 # However, gitolite does *not* have the concept of an incremental "compile",
10 # and options are only designed to be specified in the gitolite.conf file
11 # (which a user should not be able to even see!). Therefore, we allow one
12 # specific file (conf/options.conf) to be manipulated by a remote user in a
13 # *controlled* fashion, and this file is "include"d in the main gitolite.conf
17 # 1. Runs "gitolite compile" at the end. On really huge systems (where the
18 # sum total of the conf files is in the order of tens of thousands of
19 # lines) this may take a second or two :)
20 # 2. Since "options.conf" is not part of the admin repo, you may need to
21 # back it up separately, just like you currently back up gl-creator and
22 # gl-perms files from individual repos.
23 # 3. "options.conf" is formatted very strictly because it's not meant to be
24 # human edited. If you edit it directly on the server, be careful.
26 # Relevant gitolite doc links:
27 # "wild" repos and "owners"
28 # http://gitolite.com/gitolite/wild.html
29 # http://gitolite.com/gitolite/wild.html#specifying-owners
30 # http://gitolite.com/gitolite/wild.html#appendix-1-owner-and-creator
32 # http://gitolite.com/gitolite/options.html
33 # the "include" statement
34 # http://gitolite.com/gitolite/conf.html#include
37 # 1. Enable the command by adding it to the ENABLE list in the rc file.
39 # 2. Make sure your gitolite.conf has this line at the end:
41 # include "options.conf"
43 # then add/commit/push.
45 # Do NOT add a file called "options.conf" to your gitolite-admin repo!
46 # This means every time you compile (push the admin repo) you will get a
47 # warning about the missing file.
49 # You can either "touch ~/.gitolite/conf/options.conf" on the server, or
50 # take *any* wild repo and add *any* option to create it.
52 # 3. Specify options allowed to be changed by the user. For example:
57 # option user-options = hook\..* foo bar[0-9].*
59 # Users can then set any of these options, but no others.
61 # ----------------------------------------------------------------------
66 use lib
$ENV{GL_LIBDIR
};
70 # ----------------------------------------------------------------------
71 # usage and arg checks
74 Usage: ssh git@host option <repo> add <key> <val>
75 ssh git@host option <repo> del <key>
76 ssh git@host option <repo> list
78 Add, delete, or list options for wild repos. Keys must match one of the
79 allowed patterns; your system administrator will tell you what they are.
81 Doesn't check things like adding a key that already exists (simply overwrites
82 without warning), deleting a key that doesn't, etc.
85 usage
() if not @ARGV or $ARGV[0] eq '-h';
87 my $OPTIONS = "$ENV{HOME}/.gitolite/conf/options.conf";
90 die "sorry, you are not authorised\n" unless owns
($repo);
92 my $op = shift; usage
() unless $op =~ /^(add|del|list)$/;
93 my $key = shift; usage
() if not $key and $op ne 'list';
94 my $val = shift; usage
() if not $val and $op eq 'add';
96 _print
( $OPTIONS, "" ) unless -f
$OPTIONS; # avoid error on first run
97 my $options = slurp
($OPTIONS);
99 # ----------------------------------------------------------------------
100 # get 'list' out of the way first
101 if ( $op eq 'list' ) {
102 print "$1\t$2\n" while $options =~ /^repo $repo\n option (\S+) = (.*)/mg;
106 # ----------------------------------------------------------------------
107 # that leaves 'add' or 'del'
109 # NOTE: sanity check on characters in key and val not needed;
110 # REMOTE_COMMAND_PATT is more restrictive than UNSAFE_PATT anyway!
112 # check if the key is allowed
113 my $user_options = option
( $repo, 'user-options' );
114 # this is a space separated list of allowed option keys
115 my @validkeys = split( ' ', ( $user_options || '' ) );
116 my @matched = grep { $key =~ /^$_$/i } @validkeys;
117 _die
"option '$key' not allowed\n" if ( @matched < 1 );
120 $options =~ s/^repo $repo\n option $key = .*\n//m;
121 # then re-add if needed
122 $options .= "repo $repo\n option $key = $val\n" if $op eq 'add';
124 # ----------------------------------------------------------------------
126 _print
( $OPTIONS, $options );
127 system("gitolite compile");