diff options
Diffstat (limited to '')
-rwxr-xr-x | src/commands/writable | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/src/commands/writable b/src/commands/writable new file mode 100755 index 0000000..3e97f0b --- /dev/null +++ b/src/commands/writable @@ -0,0 +1,63 @@ +#!/usr/bin/perl +use strict; +use warnings; + +use lib $ENV{GL_LIBDIR}; +use Gitolite::Easy; + +=for usage +Usage: gitolite writable <reponame>|@all on|off|status + +Disable/re-enable pushes to all repos or named repo. Useful to run +non-git-aware backups and so on. + +'on' enables, 'off' disables, writes (pushes) to the named repo or all repos. +'status' returns the current status as shell truth (i.e., exit code 0 for +writable, 1 for not writable). + +With 'off', any subsequent text is taken to be the message to be shown to +users when their pushes get rejected. If it is not supplied, it will take it +from STDIN; this allows longer messages. +=cut + +usage() if not @ARGV or @ARGV < 2 or $ARGV[0] eq '-h'; +usage() if $ARGV[1] ne 'on' and $ARGV[1] ne 'off' and $ARGV[1] ne 'status'; + +my $repo = shift; +my $op = shift; # on|off|status + +if ( $repo eq '@all' ) { + _die "you are not authorized" if $ENV{GL_USER} and not is_admin(); +} else { + _die "you are not authorized" if $ENV{GL_USER} and not( owns($repo) or is_admin() or ( can_write($repo) and $op eq 'status' ) ); +} + +my $msg = join( " ", @ARGV ); +# try STDIN only if no msg found in args *and* it's an 'off' command +if ( not $msg and $op eq 'off' ) { + say2 "...please type the message to be shown to users:"; + $msg = join( "", <> ); +} + +my $sf = ".gitolite.down"; +my $rb = $ENV{GL_REPO_BASE}; + +if ( $repo eq '@all' ) { + target( $ENV{HOME} ); +} else { + target("$rb/$repo.git"); + target( $ENV{HOME} ) if $op eq 'status'; +} + +exit 0; + +sub target { + my $repodir = shift; + if ( $op eq 'status' ) { + exit 1 if -e "$repodir/$sf"; + } elsif ( $op eq 'on' ) { + unlink "$repodir/$sf"; + } elsif ( $op eq 'off' ) { + _print( "$repodir/$sf", $msg ); + } +} |