#! /usr/bin/perl -w use strict ; use Repocafe ; my $prog = substr($0,rindex($0,'/')+1) ; my $Usage = < option a : install new commit hooks for all repo's option pre : only install pre-commit hooks option post : only install post-commit hooks argument repo_id : install commit hooks for repo with id ---------------------------------------- - $prog - create repocafe commit hooks. - $prog creates commit-hooks for one specified repo, or all repo's (-a) ; - by default, both 'pre-commit' and 'post-commit' hooks are installed, from templates in 'lib/'. - It is called by the web application when a new repository is created. - Normally, $prog is not used by repocafe admins. ---------------------------------------- USAGE sub Usage { die "$_[0]$Usage" ; } sub Error { die "$prog: $_[0]\n" ; } sub Warn { warn "$prog: $_[0]\n" ; } # usage: &GetOptions(ARG,ARG,..) defines $opt_ID as 1 or user spec'ed value # usage: &GetOptions(\%opt,ARG,ARG,..) defines $opt{ID} as 1 or user value # ARG = 'ID' | 'ID=SPC' | 'ID:SPC' for no-arg, required-arg or optional-arg # ID = perl identifier # SPC = i|f|s for integer, fixedpoint real or string argument use Getopt::Long ; Getopt::Long::config('no_ignore_case') ; our %opt = () ; Usage('') unless GetOptions ( \%opt, qw(v q d f c=s pre post a help) ) ; if ( $opt{help} ) { print $Usage ; exit 0 ; } Usage("Arg count\n") unless $opt{a} or @ARGV == 1 ; $opt{v} ||= $opt{d} ; $opt{pre} ||= 0 ; $opt{post} ||= 0 ; my $Cafe = make_cafe ( %opt ) ; $Cafe -> set_opts ( %opt ) ; my @HOOKS = () ; my %TEXTS = () ; if ( $opt{pre} ^ $opt{post} ) { push @HOOKS, ( $opt{pre} ? 'pre-commit' : 'post-commit' ) ; } else { @HOOKS = qw(pre-commit post-commit) ; } for my $hook ( @HOOKS ) { my $TEMPL = "lib/$hook" ; Error "can't find commit-hook ($TEMPL)" unless -f $TEMPL ; open TEMPL, $TEMPL or Error "can't open $TEMPL ($!)" ; $TEXTS { $hook } = join '', ; close TEMPL ; } my $www_usr = $Cafe -> conf -> www_user ; my $www_grp = $Cafe -> conf -> www_group ; my $dir_admin = $Cafe -> conf -> dir_admin ; my $UID = $www_usr =~ /^\d+$/ ? $www_usr : getpwnam $www_usr ; my $GID = $www_grp =~ /^\d+$/ ? $www_grp : getgrnam $www_grp ; Error "can't find uid for www_user ($www_usr)" unless defined $UID ; Error "can't find gid for www_group ($www_grp)" unless defined $GID ; if ( $< != 0 and $< != $UID ) { my $msg = "run as root or $www_usr" ; if ( $opt{f} ) { Error "must $msg" ; } else { printf "Warning : should %s\n", $msg ; } } sub install_hook { my $path = shift ; my $text = shift ; my $tag = $opt{f} ? 'DID' : 'WOULD' ; if ( $opt{v} ) { printf "%s install hook %s\n", $tag, $path ; printf "%s chown $UID, $GID, $path\n", $tag ; printf "-----\n%s-----\n", $text if $opt{d} ; } if ( $opt{f} ) { open HOOK, ">$path" or Error "can't write $path ($!)" ; print HOOK $text ; close HOOK ; chown $UID, $GID, $path or Error "can't chown $UID, $GID, $path ($!)" ; chmod 0755, $path or Error "can't chmod 0755 $path ($!)" ; } } my $where = '' ; unless ( $opt{a} ) { my $rid = shift ; $where = "id = $rid" ; } my @repos = $Cafe -> repos -> select ( -where => $where ) ; for my $repo ( sort { $a -> repo_name cmp $b -> repo_name } @repos ) { for my $hook ( @HOOKS ) { my $path = $repo -> path . "/hooks/$hook" ; my $repo_id = $repo -> id ; my $text = $TEXTS { $hook } ; $text =~ s/%dir_admin%/$dir_admin/g ; $text =~ s/%repo_id%/$repo_id/g ; install_hook $path, $text ; } }