new mirror function: 'status all all'
[gitolite.git] / src / commands / option
blobde49aabf0f771509ad473350821c69550a591f59
1 #!/usr/bin/perl
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
7 # owns.
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
14 # file.
16 # WARNINGS:
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
31 # gitolite "options"
32 # http://gitolite.com/gitolite/options.html
33 # the "include" statement
34 # http://gitolite.com/gitolite/conf.html#include
36 # setup:
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:
54 # repo foo/..*
55 # C = blah blah
56 # ...other rules...
57 # option user-options = hook\..* foo bar[0-9].*
59 # Users can then set any of these options, but no others.
61 # ----------------------------------------------------------------------
63 use strict;
64 use warnings;
66 use lib $ENV{GL_LIBDIR};
67 use Gitolite::Easy;
68 use Gitolite::Common;
70 # ----------------------------------------------------------------------
71 # usage and arg checks
73 =for usage
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.
83 =cut
85 usage() if not @ARGV or $ARGV[0] eq '-h';
87 my $OPTIONS = "$ENV{HOME}/.gitolite/conf/options.conf";
89 my $repo = shift;
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;
103 exit 0;
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 );
119 # delete anyway
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 # ----------------------------------------------------------------------
125 # save and compile
126 _print( $OPTIONS, $options );
127 system("gitolite compile");