From: keni Date: Thu, 12 Feb 2015 00:42:57 +0000 (-0500) Subject: initial git setup X-Git-Tag: MOVE2GIT^0 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=34221670bc81de75eab4b1e214ce479eb7dd51af;p=nethack initial git setup --- diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..72533dbce --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +*.[ch] filter=NHtext merge=NHsubst +* text=auto +*.hqx -text +*.sln -text +*.vcxproj -text diff --git a/DEVEL/.gitattributes.swp b/DEVEL/.gitattributes.swp new file mode 100644 index 000000000..1d91c53a5 Binary files /dev/null and b/DEVEL/.gitattributes.swp differ diff --git a/DEVEL/DOTGIT/TARGET b/DEVEL/DOTGIT/TARGET new file mode 100644 index 000000000..6b8710a71 --- /dev/null +++ b/DEVEL/DOTGIT/TARGET @@ -0,0 +1 @@ +.git diff --git a/DEVEL/Developer.txt b/DEVEL/Developer.txt new file mode 100644 index 000000000..7c4fa4908 --- /dev/null +++ b/DEVEL/Developer.txt @@ -0,0 +1,164 @@ + ___ _ + | \ _____ _____| |___ _ __ ___ _ _ + | |) / -_) V / -_) / _ \ '_ \/ -_) '_| + |___/\___|\_/\___|_\___/ .__/\___|_| + |_| + +$NHDT-Date$ + +Welcome to the NetHack Infrastructure Developer's Guide. + +This is the info you need if you are developing code for NetHack. +(This information is from DevTeam. If you are working with a variant please +check for additional documentation for that variant.) + +For information on building NetHack, see README in the top level directory. +For information on playing NetHack, see the Guidebook in the doc directory. + +DANGER! WORK IN PROGRESS! Known issues marked XXX. + +CONTENTS +1. email +2. git repositories +3. bug reporting +4. git configuration +5. variable expansion +6. reserved names +------------------------------------------------------------------------------ +1. email +Email to devteam@nethack.org will usually get a response, but it may take a +while. Please do not send save files, binary screen grabs, or other large +things. +------------------------------------------------------------------------------ +2. git repositories +The public NetHack git repository is available (read-only) on SourceForge at: + git://git.code.sf.net/p/nethack/NHsource +------------------------------------------------------------------------------ +3. bug reporting +Please use the form at http://www.nethack.org/common/contact.html (or send +us an email if that's more appropriate). +------------------------------------------------------------------------------ +4. git configuration +A. If you have never set up git on this machine before: + (This assumes you will only be using git for NetHack. If you are going to + use it for other projects as well, think before you type.) + Tell git what name (or nicname) and email address to use for you: + git config --global user.name "MY NAME" + git config --global user.email USER@EXAMPLE.COM + You probably want to set up a credential cache. + Mac OS X: + git config --global credential.helper osxkeychain +XXX windows +XXX linux +B. Specify the prefix for variable substitution: + (This assumes you are not a member of DevTeam or any variant's development + team. If you are, this may be wrong. Look for more specific documentation.) + Decide where you want to put this info; it should NOT be inside the + tree you cloned from git. I use ~/nethack/GITADDDIR; for that base, + create the needed directories and edit the file: + ~/nethack/GITADDDIR/DOTGIT/PRE + Put this in it (if your OS is not Unix-like you may need to change + the first line): + #!/bin/sh + git config nethack.substprefix MINE +C. Configure the repository: + - cd to the top level of the repository + - tell the repository about the directory you created above: + git config nethack.gitadddir FULL_PATH_TO_GITADDDIR + so for the example above: + git config nethack.gitadddir ~/nethack/GITADDDIR + - do the automated setup: + perl DEVEL/nhgitset.pl + If it complains, fix what it complains about. nhgitset.pl accepts + the following options: + -v verbose + -n dry run + You can re-run nhgitset.pl as often as needed; occasionally we will + update it and ask you to run it again. +D. aliases + Two aliases are installed by nhgitset.pl: + nhadd + nhcommit + These two commands take the same options as the normal git add and commit + commands but perform RCS/CVS-style variable substitution. Note that the + substitutions do not show up in the working directory. + + Note that nothing terrible will happen if you do not use the nh* versions + of the commands. + + Supported substitutions: + MINE-Date the commit time and date + Experimental substitutions: + MINE-Revision CVS style revision number + MINE-Branch the current git branch + +That's it. If you need to do something more when setting up your repository, +keep reading. Otherwise, you are done with this section. + +1) to run your own hooks in addition to ours: + name your hook + WHEN-HOOKNAME + where WHEN is + PRE (run your code before the NetHack hook) + POST (run your code after the NetHack hook) + and HOOKNAME is the normal git name of the hook. + Be sure to test carefully since the composition of two bits of code may or + may not do what you want. +2) to install other bits on setup: + Put additional files in the GITADDDIR tree. Use "DOTGIT" instead of + ".git". If a file called PRE, POST, or INSTEAD exists in a + subdirectory of GITADDDIR, it is run before the copy, after the copy, + or instead of the copy. No copy operation is attempted in the DOTGIT + directory; use a script and standard git commands to change the + contents as needed. +3) NB: In all namespaces, anything that matches m/^nh/i or m/^nethack/i is + reserved. +------------------------------------------------------------------------------ +5. variable expansion +A. Introduction + We have implemented an RCS/CVS/SVN style variable expansion mechanism. + References of either of the formats: + $PREFIX-VARNAME$ + $PREFIX-VARNAME: VALUE $ + will be handled (if enabled). + + The PREFIX is the value in the git config variable nethack.substprefix. + VARNAME is one of: + Date + Branch (experimental) + Revision (experimental) + other names will give a warning. + +B. Enabling variable expansion + Variable expansion is controlled by the .gitattributes file. + + To enable variable expansion: + pattern filter=NHtext merge=NHsubst + To disable variable expansion: + pattern -filter + + More information: "git help gitattributes" + +C. Oddities + To trigger variable expansion, you _must_ use "git nhadd" or "git nhcommit" + instead of "git add" or "git commit." Nothing terrible will happen if you + use the wrong one, but the values will not be updated. + + Due to the way this abuses git filters, the updated values are not visible + in your working tree. + +D. Using your own hooks + You can use your own hooks - put them in .git/hooks as usual BUT name them + as follows: + WHEN-HOOKNAME + where WHEN is: + PRE (execute the code before the NetHack hook) + POST (execute the code after the NetHack hook) + and HOOKNAME is the normal git name for the hook. + + Test carefully - interactions between hooks can be nasty. +------------------------------------------------------------------------------ +6. reserved names + Anything that matches m/^nh/i or m/^nethack/i is reserved in all + namespaces (environment, file names, git config, etc). +------------------------------------------------------------------------------ diff --git a/DEVEL/hooksdir/.NHgithook.pm.swp b/DEVEL/hooksdir/.NHgithook.pm.swp new file mode 100644 index 000000000..19e7ec873 Binary files /dev/null and b/DEVEL/hooksdir/.NHgithook.pm.swp differ diff --git a/DEVEL/hooksdir/NHadd b/DEVEL/hooksdir/NHadd new file mode 100755 index 000000000..55a86ee08 --- /dev/null +++ b/DEVEL/hooksdir/NHadd @@ -0,0 +1,14 @@ +#!/usr/bin/perl +# wrapper for nhadd and nhcommit aliases +# $NHDT-Date$ + +%ok = map { $_ => 1 } ('add', 'commit'); + +die "Bad subcommand '$ARGV[0]'" unless $ok{$ARGV[0]}; + +if(length $ENV{GIT_PREFIX}){ + chdir($ENV{GIT_PREFIX}) or die "Can't chdir $ENV{GIT_PREFIX}: $!"; +} + +$ENV{NHMODE} = 1; +exec "git", @ARGV or die "Can't exec git: $!"; diff --git a/DEVEL/hooksdir/NHgithook.pm b/DEVEL/hooksdir/NHgithook.pm new file mode 100644 index 000000000..6024c1c03 --- /dev/null +++ b/DEVEL/hooksdir/NHgithook.pm @@ -0,0 +1,205 @@ +# +# NHgithook.pm +# NetHack Git Hook Module +# $NHDT-Date$ + +package NHgithook; +use Cwd; + +### +### CONFIG +### +my $trace = 0; +my $tracefile = "/tmp/nhgitt.$$"; + +# OS hackery +my $DS = quotemeta('/'); +if ($^O eq "MSWin32") +{ + $DS = quotemeta('\\'); +} + +our %saved_env; +our @saved_argv; +our $saved_input; + +sub saveSTDIN { + @saved_input = ; + + if($trace){ + print TRACE "STDIN:\n"; + print TRACE $saved_input; + print TRACE "ENDSTDIN\n"; + } + + tie *STDIN, 'NHIO::STDIN', @saved_input; +} + +# XXX this needs a re-write (don't tie and untie, just set NEXT=0) +# (the sensitive thing is @foo = ) +sub resetSTDIN{ + my $x = tied(*STDIN); + my %x = %$x; + my $data = @$x{DATA}; + untie *STDIN; + tie *STDIN, 'NHIO::STDIN', $data; +} + +# don't need this now +#sub restore { +# open STDIN, "<", \$saved_input or die "reopen STDIN: $!"; +# @ARGV = @saved_argv; +# %ENV = %saved_env; +#} + +sub PRE { + &do_hook("PRE"); +} + +sub POST { + &do_hook("POST"); +} + +# PRIVATE +sub do_hook { + my($p) = @_; + my $hname = $0; + $hname =~ s!^((.*$DS)|())(.*)!$1$p-$4!; + if(-x $hname){ + print TRACE "START $p: $hname\n" if($trace); + + open TOHOOK, "|-", $hname or die "open $hname: $!"; + print TOHOOK ; + close TOHOOK or die "close $hname: $! $?"; + + print TRACE "END $p\n" if($trace); + } +} + +sub trace_start { + return unless($trace); + my $self = shift; + open TRACE, ">>", $tracefile; + print TRACE "START CLIENT PID:$$ ARGV:\n"; + print TRACE "CWD: " . cwd() . "\n"; + print TRACE "[0] $0\n"; + my $x1; + for(my $x=0;$x $ENV{$k}\n"; + } +} + +BEGIN { + %saved_env = %ENV; + @saved_argv = @ARGV; + &trace_start; +} + +### +### ugly mess so we can re-read STDIN +### +package NHIO::STDIN; +sub TIEHANDLE { + my $class = shift; + my %fh; + # XXX yuck + if(ref @_[0]){ + $fh{DATA} = @_[0]; + } else { + $fh{DATA} = \@_; + } + $fh{NEXT} = 0; + return bless \%fh, $class; +} + +sub READLINE { + my $self = shift; + return undef if($self->{EOF}); + if(wantarray){ + my $lim = $#{$self->{DATA}}; + my @ary = @{$self->{DATA}}[$self->{NEXT}..$lim]; + my @rv = @ary[$self->{NEXT}..$#ary]; + $self->{EOF} = 1; + return @rv; + } else{ + my $rv = $self->{DATA}[$self->{NEXT}]; + if(length $rv){ + $self->{NEXT}++; + return $rv; + } else { + $self->{EOF} = 1; + return undef; + } + } +} + +sub EOF { + $self = shift; + return $self->{EOF}; +} + +1; +__END__ + +=head1 NAME + +NHgithook - common code for NetHack git hooks (and other git bits) + +=head1 SYNOPSIS + + BEGIN { + my $DS = quotemeta('/'); + my $PDS = '/'; + if ($^O eq "MSWin32") + { + $DS = quotemeta('\\'); + $PDS = '\\'; + } + + push(@INC, $ENV{GIT_DIR}.$PDS."hooks"); # for most hooks + push(@INC, ($0 =~ m!^(.*)$DS!)[0]); # when the above doesn't work + + $gitdir = `git rev-parse --git-dir`; # and when the above really doesn't work + $gitdir =~ s/[\r\n]*$/; + push(@INC, $gitdir.$PDS."hooks"); + } + use NHgithook; + + &NHgithook::saveSTDIN; + &NHgithook::PRE; + (core hook code) + &NHgithook::POST; + +=head1 DESCRIPTION + +Buffers call information so multiple independent actions may be coded for +Git hooks and similar Git callouts. + +=head1 SETUP + +Changing the C<$trace> and C<$tracefile> variables requires editing the +module source. Setting C<$trace> enables tracing, logs basic information, +and leaves the C filehandle open for additional output; output to this +filehandle must be guarded by C<$NHgithook::trace>. Setting +C<$tracefile> specifies the file used for trace output. Note that C<$$> +may be useful since multiple processes may be live at the same time. + +=head1 FUNCTIONS + + NHgithook::saveSTDIN reads STDIN until EOF and saves it + NHgithook::PRE runs the PRE hook, if it exists + NHgithook::POST runs the POST hook, if it exists + +=head1 BUGS + +Some features not well tested, especially under Windows. + +=head1 AUTHOR + +Kenneth Lorber (keni@his.com) diff --git a/DEVEL/hooksdir/NHsubst b/DEVEL/hooksdir/NHsubst new file mode 100755 index 000000000..2c0c3c774 --- /dev/null +++ b/DEVEL/hooksdir/NHsubst @@ -0,0 +1,366 @@ +#!/usr/bin/perl +# +# NHsubst +# $NHDT-Date$ +# git merge driver for substitutions (like RCS/CVS) +# driver line: .... %O %A %B %L +use strict; + +my $debug = 0; +my $rawin = 0; # feed diff to stdin for testing (do NOT set $debug=1) + +# We want TRACE open so we don't need to test $debug everywhere, but we skip +# this first block because it's expensive and dumpfile() hangs with $rawin. +my $sink = ($^O eq "MSWin32") ? "NUL" : "/dev/null"; +my $dbgfile = ($^O eq "MSWin32") ? "$ENV{TEMP}.$$" : "/tmp/trace.$$"; +open TRACE, ">>", ($debug==0)? $sink : $dbgfile; +if($debug){ + print TRACE "START CLIENT ARGV:\n"; + print TRACE "[0] $0\n"; + my $x1; + for(my $x=0;$x $ENV{$k}\n"; + } + print TRACE "CWD: " . `pwd`; + &dumpfile($ARGV[0], "[0O]"); + &dumpfile($ARGV[1], "[1A]"); + &dumpfile($ARGV[2], "[2B]"); + print TRACE "L=$ARGV[3]\n"; + print TRACE "END\n"; +} + +my $mark_len = $ARGV[3]; +$mark_len = 3 if($mark_len==0 && $rawin); + +my $mark_start = '<' x $mark_len; +my $mark_middle = '=' x $mark_len; +my $mark_end = '>' x $mark_len; + +my $PREFIX; +# pick up the prefix for substitutions in this repo +if($rawin){ + $PREFIX = "TEST"; +} else { + $PREFIX = `git config --local --get nethack.substprefix`; + chomp($PREFIX); +} + +my @out; +my $cntout; +if($rawin){ + @out = ; +} else { + #system "git merge-file -p .... > temp + my $tags = "-L CURRENT -L ANCESTOR -L OTHER"; # XXX should "CURRENT" be "MINE"? + @out = `git merge-file -p $tags $ARGV[1] $ARGV[0] $ARGV[2]`; + #NB: we don't check the exit value because it's useless + print TRACE "MERGE-FILE START\n".join("",@out)."MERGE-FILE END\n"; +} + +($cntout,@out) = &edit_merge(@out); + +if($rawin){ + print "COUNT: $cntout\n"; + print @out; +} else { + # spit @out to $ARGV[1] (careful: what about EOL character?) + open OUT, ">$ARGV[1]" or die "Can't open $ARGV[1]"; + print OUT @out; + close OUT; + + print TRACE "WRITING START ($ARGV[1])\n".join("",@out)."WRITING END\n"; + &dumpfile($ARGV[1], "READBACK"); +} +print TRACE "COUNT: $cntout\n"; + +exit( ($cntout>0) ? 1 : 0); + +#git merge-file [-L [-L [-L ]]] +# [--ours|--theirs|--union] [-p|--stdout] [-q|--quiet] [--marker-size=] +# [--[no-]diff3] +#The `merge.*.driver` variable's value is used to construct a command to run to merge ancestor's +# version (%O), current version (%A) and the other branches' version (%B). These three tokens are +# replaced with the names of temporary files that hold the contents of these versions when the +# command line is built. Additionally, %L will be replaced with the conflict marker size (see +# below). + +# keep failing so we don't need to keep changing the setup while building this script + +sub dumpfile { + my($file, $tag) = @_; + print TRACE "FILE $tag START\n"; + print TRACE `hexdump -C $file`; + print TRACE "FILE END\n"; +} + +sub edit_merge { + my(@input) = @_; + # $::count is a bit ugly XXX + local $::count = 0; # we need the number of conflicts for exit() + my @out; + + local $_; + while($_ = shift @input){ + if(m/^$mark_start /){ + print TRACE "FOUND A CONFLICT\n"; + my @conflict; + push(@conflict, $_); + while($_ = shift @input){ + push(@conflict, $_); + if(m/^$mark_end /){ + last; + } + } + push(@out, &edit_conflict(@conflict)); + } else { + push(@out, $_); + } + } + print TRACE "RETURN count=$::count\n"; + return($::count, @out); +} + +sub edit_conflict { + my(@in) = @_; + + print TRACE "EDIT START: " . scalar(@in)."\n"; + if($debug){ + foreach my $x (@in){ my $xx = $x; chomp($xx); print TRACE "-$xx-\n"; } + } + print TRACE "EDIT END INPUT\n"; + + # one-line change - use as base case to develop the code + # ours ARGV[1] top-of-diff + # theirs ARGV[2] bottom-of-diff + # simple conflict: + # [0] <<<<<<< d1 + # [1] $$PREFIX-Date: 1 ... + # [2] ======= + # [3] $$PREFIX-Date: 3 ... + # [4] >>>>>>> d3 + if(scalar(@in) == 5 && $in[2] =~ m/^$mark_middle/){ + my $back = &merge_one_line_maybe($in[1],$in[3]); # (ours, theirs) + if(!defined $back){ + $::count++; # leave the conflict + return @in; + } else { + return ($back); + } + # NOTREACHED + } else { +# XXX LATER +# Start at the top of both sections and work downwards. As long as the lines can be merged, +# push them out and keep going. If there are lines left, we will still have a conflict but +# we can try to make it smaller. Push out the start-conflict marker. Start at the +# bottom of both section and work upwards. As long as the lines can be merged, reverse push out +# the merged line and keep going. (We know there will be lines left at some point.) Push out +# remaining (middle) lines from OURS. Push out mark_middle. Push out remaining middle lines +# from THEIRS. Push out end-conflict marker. $::count++; return (@a,$b,@c,$d,@e,$f,@g) +# @a +# $b = <<< +# @c +# $d = === +# @e +# $f = >>> +# @g + } + # not matched - return the unchanged conflict + $::count++; + return @in; +} + +# XXX This is expensive. Add a quick check for "anything that looks like a subst var" and just +# declare the lines unmergeable if it fails. +sub merge_one_line_maybe { + my($ours, $theirs) = @_; + + my $more = 1; + my $fail = 0; + my $out = ''; + # TYPES: + # 0 no match + # 1 unexpanded var + # 2 expanded var + # 3 non-var text + my($ourstype, $theirtype); + my($oursvar, $theirvar); + my($oursval, $theirval); + + while($more){ + ($ourstype, $theirtype) = (0,0); + ($oursvar, $theirvar) = (undef, undef); + ($oursvar, $theirvar) = (undef, undef); + # unexpanded var + if($ours =~ m/\G\$$PREFIX-([A-Z][a-z]+)\$/gc){ + $ourstype = 1; + $oursvar = $1; + } + if($theirs =~ m/\G\$$PREFIX-([A-Z][a-z]+)\$/gc){ + $theirtype = 1; + $theirvar = $1; + } + # expanded var + unless($ourstype){ + if($ours =~ m/\G\$$PREFIX-([A-Za-z]+):\s+(.*?)\s\$/gc){ + $ourstype = 2; + $oursvar = $1; + $oursval = $2; + } + } + unless($theirtype){ + if($theirs =~ m/\G\$$PREFIX-([A-Za-z]+):\s+(.*?)\s\$/gc){ + $theirtype = 2; + $theirvar = $1; + $theirval = $2; + } + } + # non-var text + unless($ourstype){ + if($ours =~ m/\G(\$?[^\x24]*)/gc){ + $ourstype = 3; + $oursval = $1; + } + } + unless($theirtype){ + if($theirs =~ m/\G(\$?[^\x24]*)/gc){ + $theirtype = 3; + $theirval = $1; + } + } + + # are we done? + if(pos($ours)==length $ours && pos($theirs) == length $theirs){ + $more = 0; + } + if($ourstype == 0 && $theirtype == 0){ + die "NHsubst MERGE FAILED - aborted infinite loop\n"; + } + + # now see if ours and their match or can be resolved + # text + if($ourstype == 3 && $theirtype == 3){ + if($oursval eq $theirval){ + $out .= $oursval; + next; + } + return undef; + } + if($ourstype == 3 || $theirtype == 3){ + return undef; + } +# XXX we could do better: on failure of one field, return 2 lines with the fields we _can_ fix +# substituted into those lines, leaving only the fail-to-match bits for the user to +# deal with. Later. + # vars (all 4 cases) + if($oursvar ne $theirvar){ + return undef; + } + my $m = merge_one_var_maybe($oursvar, $oursval, $theirval); + if(! defined $m){ + return undef; + } + $out .= $m; + } + return $out; +} + +# return undef if we can't merge the values; $NAME: VALUE $ or $NAME$ (as appropriate) if we can. +sub merge_one_var_maybe { + my($varname, $oursval, $theirval) = @_; + my $resolvedas; + { + no strict; + my $fn = "PREFIX::$varname"; + if(defined &$fn){ + $resolvedas = &$fn($PREFIX,$varname,$oursval, $theirval); + } else { + $resolvedas = undef; # can't resolve + } + } + + if(!defined $resolvedas){ + $::count++; # we have an externally visible conflict + return undef; + } else { + return $resolvedas; + } + # NOTREACHED +} + +package PREFIX; +# Resolve the conflict of a single var's 2 values. Return undef to leave the conflict. +sub Date { + my($PREFIX, $varname, $mine, $theirs) = @_; + my $m = ($mine =~ m/(\d+)/)[0]; + my $t = ($theirs =~ m/(\d+)/)[0]; + return undef unless ($m>0) && ($t>0); + + return "\$$PREFIX-$varname: " . (($m>$t)?$mine:$theirs) .' $'; +} + +#sub Header { +#sub Author { + +sub Branch { + my($PREFIX, $varname, $mine, $theirs) = @_; + return "\$$PREFIX-$varname: $mine \$"; +} + +sub Revision { + my($PREFIX, $varname, $mine, $theirs) = @_; + return "\$$PREFIX-$varname: $mine \$"; +} +__END__ + +TEST 1: +<<< d1 +$TEST-Date: 1 $ +=== +$TEST-Date: 3 $ +>>> d3 + +TEST 2: +nothing +at all + +TEST 3: +<<< d1 +a line +=== +one line +two lines +>>> d3 + +TEST 4: +<<< d1 +$TEST-Date: 1 $ yes +=== +$TEST-Date: 1 $ no +>>> d3 + +TEST 5: +<<< d1 +$TEST-Date: 3 $ yes +=== +$TEST-Date: 1 $ yes +>>> d3 + +TEST 6: +<<< d1 +$TEST-Date: 3 $ yes$TEST-Date: 4 $ +=== +$TEST-Date: 1 $ yes$TEST-Date: 5 $ +>>> d3 + +TEST 7: +<<< d1 +$TEST-Branch: mine $ +=== +$TEST-Branch: theirs $ +>>> d3 diff --git a/DEVEL/hooksdir/NHtext b/DEVEL/hooksdir/NHtext new file mode 100755 index 000000000..487a6f669 --- /dev/null +++ b/DEVEL/hooksdir/NHtext @@ -0,0 +1,145 @@ +#!/usr/bin/perl +# +# NHtext +# $NHDT-Date$ +# clean/smudge filter for handling substitutions +use strict; + +my $debug = 0; + +my $sink = ($^O eq "MSWin32")? "NUL" :"/dev/null"; +my $dbgfile = ($^O eq "MSWin32") ? "$ENV{TEMP}.$$" : "/tmp/trace.$$"; +open TRACE, ">>", ($debug==0)? $sink : $dbgfile; +print TRACE "START CLIENT ARGV:\n"; +print TRACE "[0] $0\n"; +my $x1; +for(my $x=0;$x $ENV{$k}\n"; +} +print TRACE "CWD: " . `pwd`; +print TRACE "END\n"; + +# pick up the prefix for substitutions in this repo +my $PREFIX = `git config --local --get nethack.substprefix`; +chomp($PREFIX); + +my $submode = 0; # ok to make non-cleaning changes to file +my $mode; + +if($ARGV[0] eq "--clean"){ + $mode = "c"; + if(0 == 0+$ENV{NHMODE}){ + $submode = 1; # do NOT add extra changes to the file + print TRACE "SKIPPING\n"; + } +} elsif($ARGV[0] eq "--smudge"){ + $mode = "s"; +} else { + warn "Unknown mode '$ARGV[0]'\n"; + exit 1; +} + +# XXX for now, there isn't any - if we get called, we subst. No options for now. +# get relevent config info +#XXX +#git check-attr -a $ARGV[1] + +# process stdin to stdout + +while(){ + print TRACE "IN: $_"; + # $1 - var and value (not including trailing $) + # $2 - var + # $4 - value or undef +# s/\$$PREFIX-(([A-Za-z][A-Za-z0-9_]*)(: ([^\N{DOLLAR SIGN}]+))?)\s*\$/&handlevar($2,$4)/eg; + s/\$$PREFIX-(([A-Za-z][A-Za-z0-9_]*)(: ([^\x24]+))?)\s*\$/&handlevar($2,$4)/eg; + print; + print TRACE "OT: $_"; +} + +sub handlevar { + my($var, $val) = @_; + + my $subname = "PREFIX::$var"; + if(defined &$subname){ + no strict; + $val = &$subname($val,$mode,$submode); + } else { + warn "No handler for \$$PREFIX-$var\n"; + } + + if(length $val){ + return "\$$PREFIX-$var: $val \$"; + } else { + return "\$$PREFIX-$var\$"; + } +} + +package PREFIX; +use POSIX qw(strftime); + +# On push, put in the current date because we changed the file. +# On pull, keep the current value so we can see the last change date. +sub Date { + my($val, $mode, $submode) = @_; + if($mode eq "c"){ + if($submode==0){ + # we add this to make merge easier for now XXX + my $now = time; # not %s below - may not be portable + # YYYY/MM/DD HH:MM:SS + $val = "$now " . strftime("%Y/%m/%d %H:%M:%S", gmtime($now)); + } + } + if($mode eq "s"){ + $val =~ s/\s*$//; # XXX why do I need this? + } + return $val; +} + +#sub Header { +#} +#sub Author { +#} + +# NB: the standard-ish Revision line isn't enough - you need Branch/Revision - +# but we split it into 2 so we can use the standard processing code on Revision +# and just slip Branch in. +sub Branch { + my($val, $mode, $submode) = @_; + if($mode eq "c"){ + if($submode==0){ + $val = `git branch --no-color --contains`; + chomp($val); #XXX + $val =~ s/^\*\s*//; + } + } + if($mode eq "s"){ +#XXX do we need this now? + $val =~ s/\s*$//; # XXX why do I need this? + } + return $val; +} + +sub Revision { + my($val, $mode, $submode) = @_; + if($mode eq "c"){ + if($submode==0){ + my $file = $ARGV[1]; + my @val = `git log --follow --oneline $file`; + $val = sprintf("1.%d",0+$#val); + } + } + if($mode eq "s"){ +#XXX do we need this here? + $val =~ s/\s*$//; # XXX why do I need this? + } + return $val; +} + +__END__ diff --git a/DEVEL/hooksdir/TARGET b/DEVEL/hooksdir/TARGET new file mode 100644 index 000000000..f321e283d --- /dev/null +++ b/DEVEL/hooksdir/TARGET @@ -0,0 +1 @@ +.git/hooks diff --git a/DEVEL/hooksdir/applypatch-msg b/DEVEL/hooksdir/applypatch-msg new file mode 100755 index 000000000..b5bf990fe --- /dev/null +++ b/DEVEL/hooksdir/applypatch-msg @@ -0,0 +1,30 @@ +#!/usr/bin/perl +# $NHDT-Date$ + +#STARTUP-START +BEGIN { + # OS hackery has to be duplicated in each of the hooks :/ + # first the directory separator + my $DS = quotemeta('/'); + my $PDS = '/'; + # msys: POSIXish over a Windows filesystem (so / not \ but \r\n not \n). + # temporarily removed because inconsistent behavior + # if ($^O eq "msys") + # { + # $/ = "\r\n"; + # $\ = "\r\n"; + # } + if($^O eq "MSWin32"){ + $DS = quotemeta('\\'); + $PDS = '\\'; + } + $gitdir = `git rev-parse --git-dir`; + chomp $gitdir; + push(@INC, $gitdir.$PDS."hooks"); +} +use NHgithook; +#STARTUP-END + +&NHgithook::PRE; +&NHgithook::POST; +exit 0; diff --git a/DEVEL/hooksdir/commit-msg b/DEVEL/hooksdir/commit-msg new file mode 100755 index 000000000..b5bf990fe --- /dev/null +++ b/DEVEL/hooksdir/commit-msg @@ -0,0 +1,30 @@ +#!/usr/bin/perl +# $NHDT-Date$ + +#STARTUP-START +BEGIN { + # OS hackery has to be duplicated in each of the hooks :/ + # first the directory separator + my $DS = quotemeta('/'); + my $PDS = '/'; + # msys: POSIXish over a Windows filesystem (so / not \ but \r\n not \n). + # temporarily removed because inconsistent behavior + # if ($^O eq "msys") + # { + # $/ = "\r\n"; + # $\ = "\r\n"; + # } + if($^O eq "MSWin32"){ + $DS = quotemeta('\\'); + $PDS = '\\'; + } + $gitdir = `git rev-parse --git-dir`; + chomp $gitdir; + push(@INC, $gitdir.$PDS."hooks"); +} +use NHgithook; +#STARTUP-END + +&NHgithook::PRE; +&NHgithook::POST; +exit 0; diff --git a/DEVEL/hooksdir/post-applypatch b/DEVEL/hooksdir/post-applypatch new file mode 100755 index 000000000..b5bf990fe --- /dev/null +++ b/DEVEL/hooksdir/post-applypatch @@ -0,0 +1,30 @@ +#!/usr/bin/perl +# $NHDT-Date$ + +#STARTUP-START +BEGIN { + # OS hackery has to be duplicated in each of the hooks :/ + # first the directory separator + my $DS = quotemeta('/'); + my $PDS = '/'; + # msys: POSIXish over a Windows filesystem (so / not \ but \r\n not \n). + # temporarily removed because inconsistent behavior + # if ($^O eq "msys") + # { + # $/ = "\r\n"; + # $\ = "\r\n"; + # } + if($^O eq "MSWin32"){ + $DS = quotemeta('\\'); + $PDS = '\\'; + } + $gitdir = `git rev-parse --git-dir`; + chomp $gitdir; + push(@INC, $gitdir.$PDS."hooks"); +} +use NHgithook; +#STARTUP-END + +&NHgithook::PRE; +&NHgithook::POST; +exit 0; diff --git a/DEVEL/hooksdir/post-checkout b/DEVEL/hooksdir/post-checkout new file mode 100755 index 000000000..b5bf990fe --- /dev/null +++ b/DEVEL/hooksdir/post-checkout @@ -0,0 +1,30 @@ +#!/usr/bin/perl +# $NHDT-Date$ + +#STARTUP-START +BEGIN { + # OS hackery has to be duplicated in each of the hooks :/ + # first the directory separator + my $DS = quotemeta('/'); + my $PDS = '/'; + # msys: POSIXish over a Windows filesystem (so / not \ but \r\n not \n). + # temporarily removed because inconsistent behavior + # if ($^O eq "msys") + # { + # $/ = "\r\n"; + # $\ = "\r\n"; + # } + if($^O eq "MSWin32"){ + $DS = quotemeta('\\'); + $PDS = '\\'; + } + $gitdir = `git rev-parse --git-dir`; + chomp $gitdir; + push(@INC, $gitdir.$PDS."hooks"); +} +use NHgithook; +#STARTUP-END + +&NHgithook::PRE; +&NHgithook::POST; +exit 0; diff --git a/DEVEL/hooksdir/post-commit b/DEVEL/hooksdir/post-commit new file mode 100755 index 000000000..b5bf990fe --- /dev/null +++ b/DEVEL/hooksdir/post-commit @@ -0,0 +1,30 @@ +#!/usr/bin/perl +# $NHDT-Date$ + +#STARTUP-START +BEGIN { + # OS hackery has to be duplicated in each of the hooks :/ + # first the directory separator + my $DS = quotemeta('/'); + my $PDS = '/'; + # msys: POSIXish over a Windows filesystem (so / not \ but \r\n not \n). + # temporarily removed because inconsistent behavior + # if ($^O eq "msys") + # { + # $/ = "\r\n"; + # $\ = "\r\n"; + # } + if($^O eq "MSWin32"){ + $DS = quotemeta('\\'); + $PDS = '\\'; + } + $gitdir = `git rev-parse --git-dir`; + chomp $gitdir; + push(@INC, $gitdir.$PDS."hooks"); +} +use NHgithook; +#STARTUP-END + +&NHgithook::PRE; +&NHgithook::POST; +exit 0; diff --git a/DEVEL/hooksdir/post-merge b/DEVEL/hooksdir/post-merge new file mode 100755 index 000000000..b5bf990fe --- /dev/null +++ b/DEVEL/hooksdir/post-merge @@ -0,0 +1,30 @@ +#!/usr/bin/perl +# $NHDT-Date$ + +#STARTUP-START +BEGIN { + # OS hackery has to be duplicated in each of the hooks :/ + # first the directory separator + my $DS = quotemeta('/'); + my $PDS = '/'; + # msys: POSIXish over a Windows filesystem (so / not \ but \r\n not \n). + # temporarily removed because inconsistent behavior + # if ($^O eq "msys") + # { + # $/ = "\r\n"; + # $\ = "\r\n"; + # } + if($^O eq "MSWin32"){ + $DS = quotemeta('\\'); + $PDS = '\\'; + } + $gitdir = `git rev-parse --git-dir`; + chomp $gitdir; + push(@INC, $gitdir.$PDS."hooks"); +} +use NHgithook; +#STARTUP-END + +&NHgithook::PRE; +&NHgithook::POST; +exit 0; diff --git a/DEVEL/hooksdir/post-rewrite b/DEVEL/hooksdir/post-rewrite new file mode 100755 index 000000000..e1b2524f3 --- /dev/null +++ b/DEVEL/hooksdir/post-rewrite @@ -0,0 +1,32 @@ +#!/usr/bin/perl +# $NHDT-Date$ + +#STARTUP-START +BEGIN { + # OS hackery has to be duplicated in each of the hooks :/ + # first the directory separator + my $DS = quotemeta('/'); + my $PDS = '/'; + # msys: POSIXish over a Windows filesystem (so / not \ but \r\n not \n). + # temporarily removed because inconsistent behavior + # if ($^O eq "msys") + # { + # $/ = "\r\n"; + # $\ = "\r\n"; + # } + if($^O eq "MSWin32"){ + $DS = quotemeta('\\'); + $PDS = '\\'; + } + $gitdir = `git rev-parse --git-dir`; + chomp $gitdir; + push(@INC, $gitdir.$PDS."hooks"); +} +use NHgithook; +#STARTUP-END + +&NHgithook::saveSTDIN; +&NHgithook::PRE; +&NHgithook::resetSTDIN; +&NHgithook::POST; +exit 0; diff --git a/DEVEL/hooksdir/pre-applypatch b/DEVEL/hooksdir/pre-applypatch new file mode 100755 index 000000000..b5bf990fe --- /dev/null +++ b/DEVEL/hooksdir/pre-applypatch @@ -0,0 +1,30 @@ +#!/usr/bin/perl +# $NHDT-Date$ + +#STARTUP-START +BEGIN { + # OS hackery has to be duplicated in each of the hooks :/ + # first the directory separator + my $DS = quotemeta('/'); + my $PDS = '/'; + # msys: POSIXish over a Windows filesystem (so / not \ but \r\n not \n). + # temporarily removed because inconsistent behavior + # if ($^O eq "msys") + # { + # $/ = "\r\n"; + # $\ = "\r\n"; + # } + if($^O eq "MSWin32"){ + $DS = quotemeta('\\'); + $PDS = '\\'; + } + $gitdir = `git rev-parse --git-dir`; + chomp $gitdir; + push(@INC, $gitdir.$PDS."hooks"); +} +use NHgithook; +#STARTUP-END + +&NHgithook::PRE; +&NHgithook::POST; +exit 0; diff --git a/DEVEL/hooksdir/pre-auto-gc b/DEVEL/hooksdir/pre-auto-gc new file mode 100755 index 000000000..b5bf990fe --- /dev/null +++ b/DEVEL/hooksdir/pre-auto-gc @@ -0,0 +1,30 @@ +#!/usr/bin/perl +# $NHDT-Date$ + +#STARTUP-START +BEGIN { + # OS hackery has to be duplicated in each of the hooks :/ + # first the directory separator + my $DS = quotemeta('/'); + my $PDS = '/'; + # msys: POSIXish over a Windows filesystem (so / not \ but \r\n not \n). + # temporarily removed because inconsistent behavior + # if ($^O eq "msys") + # { + # $/ = "\r\n"; + # $\ = "\r\n"; + # } + if($^O eq "MSWin32"){ + $DS = quotemeta('\\'); + $PDS = '\\'; + } + $gitdir = `git rev-parse --git-dir`; + chomp $gitdir; + push(@INC, $gitdir.$PDS."hooks"); +} +use NHgithook; +#STARTUP-END + +&NHgithook::PRE; +&NHgithook::POST; +exit 0; diff --git a/DEVEL/hooksdir/pre-commit b/DEVEL/hooksdir/pre-commit new file mode 100755 index 000000000..b5bf990fe --- /dev/null +++ b/DEVEL/hooksdir/pre-commit @@ -0,0 +1,30 @@ +#!/usr/bin/perl +# $NHDT-Date$ + +#STARTUP-START +BEGIN { + # OS hackery has to be duplicated in each of the hooks :/ + # first the directory separator + my $DS = quotemeta('/'); + my $PDS = '/'; + # msys: POSIXish over a Windows filesystem (so / not \ but \r\n not \n). + # temporarily removed because inconsistent behavior + # if ($^O eq "msys") + # { + # $/ = "\r\n"; + # $\ = "\r\n"; + # } + if($^O eq "MSWin32"){ + $DS = quotemeta('\\'); + $PDS = '\\'; + } + $gitdir = `git rev-parse --git-dir`; + chomp $gitdir; + push(@INC, $gitdir.$PDS."hooks"); +} +use NHgithook; +#STARTUP-END + +&NHgithook::PRE; +&NHgithook::POST; +exit 0; diff --git a/DEVEL/hooksdir/pre-push b/DEVEL/hooksdir/pre-push new file mode 100755 index 000000000..e1b2524f3 --- /dev/null +++ b/DEVEL/hooksdir/pre-push @@ -0,0 +1,32 @@ +#!/usr/bin/perl +# $NHDT-Date$ + +#STARTUP-START +BEGIN { + # OS hackery has to be duplicated in each of the hooks :/ + # first the directory separator + my $DS = quotemeta('/'); + my $PDS = '/'; + # msys: POSIXish over a Windows filesystem (so / not \ but \r\n not \n). + # temporarily removed because inconsistent behavior + # if ($^O eq "msys") + # { + # $/ = "\r\n"; + # $\ = "\r\n"; + # } + if($^O eq "MSWin32"){ + $DS = quotemeta('\\'); + $PDS = '\\'; + } + $gitdir = `git rev-parse --git-dir`; + chomp $gitdir; + push(@INC, $gitdir.$PDS."hooks"); +} +use NHgithook; +#STARTUP-END + +&NHgithook::saveSTDIN; +&NHgithook::PRE; +&NHgithook::resetSTDIN; +&NHgithook::POST; +exit 0; diff --git a/DEVEL/hooksdir/pre-rebase b/DEVEL/hooksdir/pre-rebase new file mode 100755 index 000000000..b5bf990fe --- /dev/null +++ b/DEVEL/hooksdir/pre-rebase @@ -0,0 +1,30 @@ +#!/usr/bin/perl +# $NHDT-Date$ + +#STARTUP-START +BEGIN { + # OS hackery has to be duplicated in each of the hooks :/ + # first the directory separator + my $DS = quotemeta('/'); + my $PDS = '/'; + # msys: POSIXish over a Windows filesystem (so / not \ but \r\n not \n). + # temporarily removed because inconsistent behavior + # if ($^O eq "msys") + # { + # $/ = "\r\n"; + # $\ = "\r\n"; + # } + if($^O eq "MSWin32"){ + $DS = quotemeta('\\'); + $PDS = '\\'; + } + $gitdir = `git rev-parse --git-dir`; + chomp $gitdir; + push(@INC, $gitdir.$PDS."hooks"); +} +use NHgithook; +#STARTUP-END + +&NHgithook::PRE; +&NHgithook::POST; +exit 0; diff --git a/DEVEL/hooksdir/prepare-commit-msg b/DEVEL/hooksdir/prepare-commit-msg new file mode 100755 index 000000000..b5bf990fe --- /dev/null +++ b/DEVEL/hooksdir/prepare-commit-msg @@ -0,0 +1,30 @@ +#!/usr/bin/perl +# $NHDT-Date$ + +#STARTUP-START +BEGIN { + # OS hackery has to be duplicated in each of the hooks :/ + # first the directory separator + my $DS = quotemeta('/'); + my $PDS = '/'; + # msys: POSIXish over a Windows filesystem (so / not \ but \r\n not \n). + # temporarily removed because inconsistent behavior + # if ($^O eq "msys") + # { + # $/ = "\r\n"; + # $\ = "\r\n"; + # } + if($^O eq "MSWin32"){ + $DS = quotemeta('\\'); + $PDS = '\\'; + } + $gitdir = `git rev-parse --git-dir`; + chomp $gitdir; + push(@INC, $gitdir.$PDS."hooks"); +} +use NHgithook; +#STARTUP-END + +&NHgithook::PRE; +&NHgithook::POST; +exit 0; diff --git a/DEVEL/nhgitset.pl b/DEVEL/nhgitset.pl new file mode 100755 index 000000000..183c73d69 --- /dev/null +++ b/DEVEL/nhgitset.pl @@ -0,0 +1,317 @@ +#!/usr/bin/perl +# $NHDT-Date$ + +# value of nethack.setupversion we will end up with when this is done +# version 1 is reserved for repos checked out before versioning was added +my $version_new = 2; +my $version_old = 0; # current version, if any (0 is no entry ergo new repo) + +use Cwd; +use Getopt::Std; + +# Activestate Perl doesn't include File::Spec. Grr. +BEGIN { + eval "require File::Spec::Functions"; + if($@){ + die <import; +} + +exit 1 unless(getopts('nvf')); # TODO: this can probably have better output + +# OS hackery +my $DS = quotemeta('/'); # Directory Separator (for regex) +my $DSP = '/'; # ... for printing +# Temporarily disabled; there's something weird about msys +# msys: POSIXish over a Windows filesystem (so / not \ but \r\n not \n). +#if($^O eq "msys"){ +# $/ = "\r\n"; +# $\ = "\r\n"; +# # NB: We don't need to do anything about File::Spec. It doesn't know +# # about msys but it defaults to Unix, so we'll be ok. +#} +if($^O eq "MSWin32"){ + $DS = quotemeta('\\'); + $DSP = '\\'; +} + +# make sure we're at the top level of a repo +if(! -d ".git"){ + die "This is not the top level of a git repository.\n"; +} + +my $vtemp = `git config --local --get nethack.setupversion`; +chomp($vtemp); +if($vtemp > 0){ + $version_old = 0+$vtemp; + if($version_old != $version_new){ + print STDERR "Migrating from setup version $version_old to $version_new\n" if($opt_v); + } +} +# legacy check: +if(length $vtemp == 0){ + if(`git config --get merge.NHsubst.name` =~ m/^Net/){ + $version_old = 1; + print STDERR "Migrating to setup version 1\n" if($opt_v); + } +} + +my $gitadddir = `git config --get nethack.gitadddir`; +chomp($gitadddir); +if(length $gitadddir){ + if(! -d $gitadddir){ + die "nethack.gitadddir has invalid value '$gitadddir'\n"; + } +} +print STDERR "nethack.gitadddir=$gitadddir\n" if($opt_v); + +# This is (relatively) safe because we know we're at R in R/DEVEL/nhgitset.pl +my $srcdir = ($0 =~ m!^(.*)$DS!)[0]; + +if(! -f catfile($srcdir, 'nhgitset.pl')){ + die "I can't find myself in '$srcdir'\n"; +} + +print STDERR "Copying from: $srcdir\n" if($opt_v); + +if($opt_f || $version_old==0){ + print STDERR "Configuring line endings\n" if($opt_v); + unlink catfile('.git','index') unless($opt_n); + system("git reset") unless($opt_n); + system("git config --local core.safecrlf true") unless($opt_n); + system("git config --local core.autocrlf false") unless($opt_n); +} elsif($version_old <2){ + my $xx = `git config --get --local core.safecrlf`; + if($xx !~ m/true/){ + print STDERR "\nNeed to 'rm .git${DSP}index;git reset'.\n"; + print STDERR " When ready to proceed, re-run with -f flag.\n"; + exit 2; + } +} + + + +print STDERR "Installing aliases\n" if($opt_v); +$addpath = catfile(curdir(),'.git','hooks','NHadd'); +&add_alias('nhadd', "!$addpath add"); +&add_alias('nhcommit', "!$addpath commit"); + +print STDERR "Installing filter/merge\n" if($opt_v); + +if($^O eq "MSWin32"){ + $cmd = '.git\\\\hooks\\\\NHtext'; +} else { + $cmd = catfile(curdir(),'.git','hooks','NHtext'); +} +&add_config('filter.NHtext.clean', "$cmd --clean %f"); +&add_config('filter.NHtext.smudge', "$cmd --smudge %f"); + +$cmd = catfile(curdir(),'.git','hooks','NHsubst'); +&add_config('merge.NHsubst.name', 'NetHack Keyword Substitution'); +&add_config('merge.NHsubst.driver', "$cmd %O %A %B %L"); + +print STDERR "Running directories\n" if($opt_v); + +foreach my $dir ( glob("$srcdir$DS*") ){ + next unless(-d $dir); + + my $target = catfile($dir, 'TARGET'); + next unless(-f $target); + + open TARGET, '<', $target or die "$target: $!"; + my $targetpath = ; + # still have to eat all these line endings under msys, so instead of chomp use this: + $targetpath =~ s![\r\n]!!g; + close TARGET; + print STDERR "Directory $dir -> $targetpath\n" if($opt_v); + + my $enddir = $dir; + $enddir =~ s!.*$DS!!; + if(! &process_override($enddir, "INSTEAD")){ + &process_override($enddir, "PRE"); + my $fnname = "do_dir_$enddir"; + if(defined &$fnname){ + &$fnname($dir, $targetpath); + } + &process_override($enddir, "POST"); + } +} + +&check_prefix; # for variable substitution + +if($version_old != $version_new){ + print STDERR "Setting version to $version_new\n" if($opt_v); + if(! $opt_n){ + system("git config nethack.setupversion $version_new"); + if($?){ + die "Can't set nethack.setupversion $version_new: $?,$!\n"; + } + } +} + +exit 0; + +sub process_override { + my($srcdir, $plname) = @_; + return 0 unless(length $gitadddir); + + my $plpath = catfile($gitadddir, $srcdir, $plname); +#print STDERR " ",catfile($srcdir, $plname),"\n"; # save this for updating docs - list of overrides + return 0 unless(-x $plpath); + + print STDERR "Running $plpath\n" if($opt_v); + # current directory is top of target repo + + unless($opt_n){ + system("$plpath $opt_v") and die "Callout $plpath failed: $?\n"; + } + return 1; +} + +sub add_alias { + my($name, $def) = @_; + &add_config("alias.$name",$def); +} + +sub add_config { + my($name, $val) = @_; + system('git', 'config', '--local', $name, $val) unless($opt_n); +} + +sub check_prefix { + my $lcl = `git config --local --get nethack.substprefix`; + chomp($lcl); + if(0==length $lcl){ + my $other = `git config --get nethack.substprefix`; + chomp($other); + if(0==length $other){ + print STDERR "ERROR: nethack.substprefix is not set anywhere. Set it and re-run.\n"; + exit 2; + } else { + &add_config('nethack.substprefix', $other); + print STDERR "Copying prefix '$other' to local repository.\n" if($opt_v); + } + $lcl = $other; # for display below + } + print "\n\nUsing prefix '$lcl' - PLEASE MAKE SURE THIS IS CORRECT\n\n"; +} + +sub do_dir_DOTGIT { +if(1){ + # We are NOT going to mess with config now. + return; +} else { + my($srcdir, $targetdir) = @_; +#warn "do_dir_DOTGIT($srcdir, $targetdir)\n"; + my $cname = "$srcdir/config"; + if(-e $cname){ + print STDERR "Appending to .git/config\n" if($opt_v); + open CONFIG, ">>.git/config" or die "open .git/config: $!"; + open IN, "<", $cname or die "open $cname: $!"; + my @data = ; + print CONFIG @data; + close IN; + close CONFIG; + } else { + print STDERR " Nothing to add to .git/config\n" if($opt_v); + } +# XXX are there other files in .git that we might want to handle? +# So just in case: + for my $file ( glob("$srcdir/*") ){ + next if( $file =~ m!.*/TARGET$! ); + next if( $file =~ m!.*/config$! ); + die "ERROR: no handler for $file\n"; + } +} +} + +sub do_dir_hooksdir { + my($srcdir, $targetdir) = @_; + + for my $path ( glob("$srcdir$DS*") ){ + + next if( $path =~ m!.*${DS}TARGET$! ); + + my $file = $path; + + $file =~ s!.*$DS!!; + + $file = catfile($targetdir, $file); + + next if($opt_n); + + open IN, "<", $path or die "Can't open $path: $!"; + open OUT, ">", "$file" or die "Can't open $file: $!"; + while(){ + print OUT; + } + close OUT; + close IN; + + if(! -x $file){ + chmod 0755 ,$file; + } + } +} + +__END__ +(can we change the .gitattributes syntax to include a comment character?) +maybe [comment] attr.c:parse_attr_line +grr - looks like # is the comment character + + + +=head1 NAME + +nhgitset.pl - Setup program for NetHack git repositories + +=head1 SYNOPSIS + + cd THE_REPO + [git config nethack.gitadddir GITADDDIR] + perl SOME_PATH/DEVEL/nhgitset.pl [-v][-n][-f] + +=head1 DESCRIPTION + +nhgitset.pl installs NetHack-specific setup after a C (or after +changes to the desired configuration, which are installed by re-running +nhgitset.pl). + +The follwing options are available: + +B<-f> Force. Do not use this unless the program requests it. + +B<-n> Make no changes. + +B<-v> Verbose output. + +=head1 CONFIG + +nhgitset.pl uses the following non-standard C variables: + +nethack.gitadddir + + DOTGIT/INSTEAD + DOTGIT/PRE + DOTGIT/POST + hooksdir/INSTEAD + hooksdir/PRE + hooksdir/POST + +nethack.setupversion + +nethack.substprefix + + +=head1 EXIT STATUS + +0 Success. + +1 Fail. + +2 Intervention required.