#!/usr/bin/perl

=pod

=head1 NAME

git-packer - Wrapper for git-{upload|receive}-pack to go through git-server for hooks

=head1 DESCRIPTION

The git-packer wrapper is intended to be used to allow
custom hooks to be caught earlier by the git operation.
This can help when SSH ForceCommand isn't configured
properly or if git isn't being run through SSH at all.

=head1 SYNOPSIS

  [git@gitsrvhost ~]$ mkdir -v ~/bin
  [git@gitsrvhost ~]$ ln -s -v /usr/bin/git-packer ~/bin/git-upload-pack
  [git@gitsrvhost ~]$ ln -s -v /usr/bin/git-packer ~/bin/git-receive-pack
  [git@gitsrvhost ~]$

=head1 AUTHOR

Rob Brown <bbb@cpan.org>

=head1 COPYRIGHT AND LICENSE

Copyright 2015-2026 by Rob Brown <bbb@cpan.org>

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

=cut

use strict;
use warnings;
use File::Spec;
use Cwd qw(abs_path);
use FindBin qw($Script);

-l $0 or die "$0: Not symlink?\n";

if (!exists $ENV{GIT_SERVER_VERSION} and 1 == @ARGV) {
    # We haven't gone through git-server yet? Good catch! Let's do it now:
    $ENV{GIT_SERVER_VERSION} = "";
    $ENV{REMOTE_USER} ||= "admin";
    my $gitdir = shift;
    $gitdir =~ s/'/'\\''/g,$gitdir = "'$gitdir'" if $gitdir =~ m{[^\w/.\-]};
    (my $server = abs_path $0) =~ s/\-\w+$/-server/;
    exec $server,"-c","$Script $gitdir" or die "$server: exec failed: $!\n";;
}

# Already gone through git-server, so just run the real program:
$ENV{GIT_PACKER_TRIED} ||= "";
my $myself = (stat $0)[1] or die "$0: Can't find my inode?\n";
foreach my $path (File::Spec->path) {
    if (my @stat = stat (my $try = "$path/$Script")) {
        # Skip non-executable, skip myself, skip if already tried
        next if !-x _ or $stat[1] == $myself or $ENV{GIT_PACKER_TRIED} =~ /^\Q$try\E$/m;
        # First executable one in the path that isn't me is the winner
        $ENV{GIT_PACKER_TRIED} = join "\n", $try, split /\n/, $ENV{GIT_PACKER_TRIED};
        exec $try, @ARGV or die "$try: exec failed: $!\n";
    }
}
die "$Script: command not found\n";
