nhgitset version 4

To update, run "perl DEVEL/nhgitset.pl"

Fixes:
- "nhcommit -a" has been fixed
- NHDT was hardwired in places
- no longer complain about a missing dat directory outside of the
    NetHack source tree
- make update of gitinfo atomic
- Replace some hardwired directory separators with OS-dependent constructs

Backwards Incompatibilities:
- NH_DATESUB's DATE() is now Date() to match the other variables
- MSYS2 requires an additional Perl package - the MSYS2 docs have
    been updated

New Help System:
- git nhhelp
   This command mirrors "git help" for nh* commands.
- See git nhhelp nhsub for general help on substitution variables

New Substitution Variables:
-Brev()
    An aBREViation of $PREFIX-Branch$:$PREFIX-Revision$ - this
    may help get line length under control in file headers.
-Assert(TYPE=VALUE)
    If TYPE does not match VALUE, do not substitute on this line.
    TYPE P checks VALUE against nethack.substprefix
-Project(arg)
    Returns nethack.projectname if there is no arg and an uppercase
    version if arg is uc.

Other New Features:
- Add nethack.projectname
- Documentation updates - see "git nhhelp nhsub"
- On checkout or merge of a branch, check for nhgitset version updates
  and provide an optional message to the user.
- Move NH_DATESUB substitutions here from cron job to keep dates in sync
- PREFIX-* keywords now available in NH_DATESUB templates
- Support use of nhgitset.pl from a different repo; note that update
  checks will be dependent on keeping the original source repo up-to-date
  and in the same location.
This commit is contained in:
nhkeni
2024-11-11 09:15:49 -05:00
parent dcf18b2b69
commit 36e8d9e6fc
27 changed files with 1412 additions and 677 deletions
+5 -4
View File
@@ -92,10 +92,11 @@ B. Specify the prefix for variable substitution:
tree you cloned from git. I use ~/nethack/GITADDDIR; for that base, tree you cloned from git. I use ~/nethack/GITADDDIR; for that base,
create the needed directories and edit the file: create the needed directories and edit the file:
~/nethack/GITADDDIR/DOTGIT/PRE ~/nethack/GITADDDIR/DOTGIT/PRE
Put this in it (if your OS is not Unix-like you may need to change Put this in it, adapting it to your variant (if your OS is not Unix-like
the first line): you may need to change the first line):
#!/bin/sh #!/bin/sh
git config nethack.substprefix MINE git config nethack.substprefix MINE
git config nethack.projectname MineHack
Now make it executable: Now make it executable:
chmod +x ~/nethack/GITADDDIR/DOTGIT/PRE chmod +x ~/nethack/GITADDDIR/DOTGIT/PRE
C. Configure the repository: C. Configure the repository:
@@ -169,8 +170,8 @@ A. Introduction
The PREFIX is the value in the git config variable nethack.substprefix. The PREFIX is the value in the git config variable nethack.substprefix.
VARNAME is one of: VARNAME is one of:
Date Date
Branch (experimental) Branch
Revision (experimental) Revision
other names will give a warning. other names will give a warning.
B. Enabling variable expansion B. Enabling variable expansion
+40
View File
@@ -0,0 +1,40 @@
4
Fixes:
- "nhcommit -a" has been fixed
- NHDT was hardwired in places
- no longer complain about a missing dat directory outside of the
NetHack source tree
- make update of gitinfo atomic
- Replace some hardwired directory separators with OS-dependent constructs
Backwards Incompatibilities:
- NH_DATESUB's DATE() is now Date() to match the other variables
- MSYS2 requires an additional Perl package - the MSYS2 docs have
been updated
New Help System:
- git nhhelp
This command mirrors "git help" for nh* commands.
- See git nhhelp nhsub for general help on substitution variables
New Substitution Variables:
-Brev()
An aBREViation of $PREFIX-Branch$:$PREFIX-Revision$ - this
may help get line length under control in file headers.
-Assert(TYPE=VALUE)
If TYPE does not match VALUE, do not substitute on this line.
TYPE P checks VALUE against nethack.substprefix
-Project(arg)
Returns nethack.projectname if there is no arg and an uppercase
version if arg is uc.
Other New Features:
- Add nethack.projectname
- Documentation updates - see "git nhhelp nhsub"
- On checkout or merge of a branch, check for nhgitset version updates
- Move NH_DATESUB substitutions here from cron job to keep dates in sync
- PREFIX-* keywords now available in NH_DATESUB templates
- Support use of nhgitset.pl from a different repo; note that update
checks will be dependent on keeping the original source repo up-to-date
and in the same location.
+21
View File
@@ -20,3 +20,24 @@ if(length $ENV{GIT_PREFIX}){
} }
exec "git", @ARGV or die "Can't exec git: $!"; exec "git", @ARGV or die "Can't exec git: $!";
__END__
=for nhgitset nhadd Add file contents to the index with NetHack additions
=for nhgitset nhcommit Record changes to the repository with NetHack additions
=head1 NAME
C<NHadd> - NetHack internal common code for nhadd and nhcommit
=head1 SYNOPSIS
C<git nhadd E<lt>git add optionsE<gt>>
C<git nhcommit E<lt>git add optionsE<gt>>
=head1 DESCRIPTION
Run nhsub with the given arguments, then run C<git add> or C<git commit>
with the given arguments. Note that only basic arguments for those commands
are understood; more complex situations may be handled by running C<git nhsub>
manually before running C<git add> or C<git commit>.
+158 -9
View File
@@ -16,9 +16,11 @@ my $tracefile = "/tmp/nhgitt.$$";
# OS hackery # OS hackery
my $DS = quotemeta('/'); my $DS = quotemeta('/');
my $PDS = '/';
if ($^O eq "MSWin32") if ($^O eq "MSWin32")
{ {
$DS = quotemeta('\\'); $DS = quotemeta('\\');
$PDS = '\\';
} }
our %saved_env; our %saved_env;
@@ -37,8 +39,6 @@ sub saveSTDIN {
tie *STDIN, 'NHIO::STDIN', @saved_input; 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 = <STDIN> )
sub resetSTDIN{ sub resetSTDIN{
my $x = tied(*STDIN); my $x = tied(*STDIN);
my %x = %$x; my %x = %$x;
@@ -62,14 +62,135 @@ sub POST {
&do_hook("POST"); &do_hook("POST");
} }
###
### versioning for nhgitset and friends
###
# values of nethack.setupversion and DEVEL/VERSION:
# 1 is reserved for repos checked out before versioning was added
# 2 used clean/smudge filter, poorly
# 3 was first production version
# 4 added the version file and version checking; nhhelp, NH_DATESUB support, etc.
sub version_in_devel {
# (1) check for a non-null nethack.setuppath - this handles
# any repo that has already been set up (but NOT checking
# out <v4 over >=v4 since nethack.setuppath will exist but
# DEVEL/VERSION will not).
# XXX if the source repo has been removed, we'll fall back to
# the third case - hopefully that's ok.
# XXX there's no way to recover from a missing source repo
# without editing .git/config.
my $path = `git config --local nethack.setuppath`;
chomp $path;
$path =~ s/DEVEL$//; # NOP if config not set
# (2) else check the local directory; that will be correct for NHsource.
if(0 == length $path){
$path = `git rev-parse --show-toplevel`;
chomp $path;
$path = '' unless(-d "$path${PDS}DEVEL");
}
# (3) If that doesn't exist, check using the invocation path; that will be
# correct for other repos during nhgitset (but will also fail for
# checking out 3 over 4).
if(0 == length $path){
# strip out "DEVEL"
$path = ($0 =~ m!^(.*)${PDS}DEVEL${PDS}.*?(*nla:DEVEL)!)[0];
}
# Uh oh?
if(0==length($path) or (! -d "$path${PDS}DEVEL")){
die "Can't locate DEVEL directory in '$path'.";
}
# Handle checking out version <4 over version >=4. If
# this seems to be the situation, don't revert the code.
return 0 if(! -f "$path${PDS}DEVEL${PDS}VERSION");
my $version;
my $verfile = "$path${PDS}DEVEL${PDS}VERSION";
open VERFH,"<",$verfile or die "xCan't open $verfile: $!";
$version = 0+<VERFH>;
my $message = join('',<VERFH>);
close VERFH;
die "Valid version not found in $verfile" unless($version >= 4);
return ($version,$message) if($version > 0);
return 0;
}
sub version_in_git {
my $vtemp = `git config --local --get nethack.setupversion`;
chomp($vtemp);
return $vtemp if($vtemp > 0);
return 0;
}
sub version_set_git {
my $version_new = $_[0];
system("git config nethack.setupversion $version_new");
if($?){
die "Can't set nethack.setupversion $version_new: $?,$!\n";
}
}
### ###
### store githash and gitbranch in dat/gitinfo.txt ### store githash and gitbranch in dat/gitinfo.txt
### ###
# CAUTION! This is run not just from git hooks, but also from
# sys/unix/gitinfo.sh
sub nhversioning { sub nhversioning {
use strict; use strict;
use warnings; use warnings;
# See if we're (probably) in a "git pull", in which case we need to
# check for upgrades.
my $check_upgrade = 1 if($_[0]);
# Check for pre-v4 source repo.
my $is_sourcerepo;
{
chomp($is_sourcerepo = `git config --type=int --get nethack.is-sourcerepo`);
if(0 == length $is_sourcerepo){ # not set - assume old repo
$is_sourcerepo = 1;
}elsif($is_sourcerepo==1){
;
}elsif($is_sourcerepo==0){
;
}
}
# Skip the skipping tests if we're being called directly.
# NB: post-commit has no args, but that will be caught by
# the next test for non-source repos.
if($#ARGV != -1){
# Skip this if we didn't change branches, but see if we need to warn.
if(defined($ARGV[2]) and ($ARGV[2] == 0)){
# Because we can create an out of sync state, possibly warn.
my $ref = $ARGV[1];
if($is_sourcerepo and (0 != 0+`git diff --name-only $ref $ref^ |grep ^DEVEL|wc -l`)){
warn "WARNING: DEVEL directory changed. Versioning may be inconsistent\n";
}
return
}
}
if($check_upgrade){
my $current_version = version_in_git();
my($new_version,$message) = version_in_devel();
if($new_version > $current_version){
warn "nhgitset.pl and/or related programs have changed.\n";
warn "Please re-run nhgitset.pl to update from version $current_version to $new_version.\n";
if(length $message){
warn "Additional information\n$message\n";
}
}
}
# Skip versioning if we aren't in a source repo.
return if(0==$is_sourcerepo);
my $git_sha = `git rev-parse HEAD`; my $git_sha = `git rev-parse HEAD`;
$git_sha =~ s/\s+//g; $git_sha =~ s/\s+//g;
my $git_branch = `git rev-parse --abbrev-ref HEAD`; my $git_branch = `git rev-parse --abbrev-ref HEAD`;
@@ -77,7 +198,14 @@ sub nhversioning {
die "git rev-parse failed" unless(length $git_sha and length $git_branch); die "git rev-parse failed" unless(length $git_sha and length $git_branch);
my $exists = 0; my $exists = 0;
if (open my $fh, '<', 'dat/gitinfo.txt') { no strict 'refs';
no strict 'subs';
my $file_gitinfo = "dat${PDS}gitinfo.txt";
my $file_gittemp = "dat${PDS}TMPgitinfo.txt";
use strict 'subs';
use strict 'refs';
if (open my $fh, '<', $file_gitinfo) {
$exists = 1; $exists = 1;
my $hashok = 0; my $hashok = 0;
my $branchok = 0; my $branchok = 0;
@@ -91,19 +219,29 @@ sub nhversioning {
} }
close $fh; close $fh;
if ($hashok && $branchok) { if ($hashok && $branchok) {
print "dat/gitinfo.txt unchanged, githash=".$git_sha."\n"; print "$file_gitinfo unchanged, githash=".$git_sha."\n";
return; return;
} }
} else { } else {
print "WARNING: Can't find dat directory\n" unless(-d "dat"); warn "WARNING: Can't find dat directory\n" unless(-d "dat");
return;
} }
if (open my $fh, '>', 'dat/gitinfo.txt') { if (open my $fh, '>', $file_gittemp) {
my $how = ($exists ? "updated" : "created"); my $how = ($exists ? "updated" : "created");
print $fh 'githash='.$git_sha."\n"; print $fh 'githash='.$git_sha."\n";
print $fh 'gitbranch='.$git_branch."\n"; print $fh 'gitbranch='.$git_branch."\n";
print "dat/gitinfo.txt ".$how.", githash=".$git_sha."\n"; print "$file_gitinfo ".$how.", githash=".$git_sha."\n";
if(close($fh)){
if(rename($file_gittemp, $file_gitinfo)){
; # all ok
} else { } else {
print "WARNING: Unable to open dat/gitinfo.txt: $!\n"; warn "WARNING: Can't rename $file_gittemp -> $file_gitinfo";
}
} else {
warn "WARNING: Can't close temp file: $!";
}
} else {
warn "WARNING: Unable to open $file_gitinfo: $!\n";
} }
} }
@@ -155,7 +293,6 @@ package NHIO::STDIN;
sub TIEHANDLE { sub TIEHANDLE {
my $class = shift; my $class = shift;
my %fh; my %fh;
# XXX yuck
if(ref @_[0]){ if(ref @_[0]){
$fh{DATA} = @_[0]; $fh{DATA} = @_[0];
} else { } else {
@@ -223,11 +360,20 @@ NHgithook - common code for NetHack git hooks (and other git bits)
(core hook code) (core hook code)
&NHgithook::POST; &NHgithook::POST;
__END__
=for nhgitset NHgithook Infrastructure for NetHack git hooks.
=head1 DESCRIPTION =head1 DESCRIPTION
Perl module for infrastructure of NetHack Git hooks.
Buffers call information so multiple independent actions may be coded for Buffers call information so multiple independent actions may be coded for
Git hooks and similar Git callouts. Git hooks and similar Git callouts.
Maintains C<dat/gitinfo.txt>.
Common routines for dealing with nethack.setupversion git config variable.
=head1 SETUP =head1 SETUP
Changing the C<$trace> and C<$tracefile> variables requires editing the Changing the C<$trace> and C<$tracefile> variables requires editing the
@@ -247,6 +393,9 @@ may be useful since multiple processes may be live at the same time.
Some features not well tested, especially under Windows. Some features not well tested, especially under Windows.
Not well documented, but almost no one needs to change (or even call)
this code.
=head1 AUTHOR =head1 AUTHOR
Kenneth Lorber (keni@his.com) Kenneth Lorber (keni@his.com)
+14
View File
@@ -396,3 +396,17 @@ TEST 8:
=== ===
/* NetHack 3.7 objnam.c $TEST-Date: 1426977394 2015/03/21 22:36:34 $ $TEST-Branch: master $:$TEST-Revision: 1.108 $ */ /* NetHack 3.7 objnam.c $TEST-Date: 1426977394 2015/03/21 22:36:34 $ $TEST-Branch: master $:$TEST-Revision: 1.108 $ */
>>> d3 >>> d3
=for nhgitset NHsubst NetHack merge driver
=head1 NAME
C<NHsubst> - NetHack merge driver
=head1 SYNOPSIS
(called from C<git>, do not invoke directly)
=head1 DESCRIPTION
This is invoked by git through .git/config.
+5 -3
View File
@@ -3,6 +3,8 @@
# Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland
# NetHack may be freely redistributed. See license for details. # NetHack may be freely redistributed. See license for details.
# Not in use as of v3, but could come back in the future.
# clean/smudge filter for handling substitutions # clean/smudge filter for handling substitutions
use strict; use strict;
@@ -54,9 +56,9 @@ if($ARGV[0] eq "--clean"){
exit 1; exit 1;
} }
# XXX for now, there isn't any - if we get called, we subst. No options for now. # XX for now, there isn't any - if we get called, we subst. No options for now.
# get relevant config info # get relevant config info
#XXX #XX
#git check-attr -a $ARGV[1] #git check-attr -a $ARGV[1]
# Process stdin to stdout. # Process stdin to stdout.
@@ -109,7 +111,7 @@ sub Date {
my($val, $mode, $submode) = @_; my($val, $mode, $submode) = @_;
if($mode eq "c"){ if($mode eq "c"){
if($submode==0){ if($submode==0){
# we add this to make merge easier for now XXX # we add this to make merge easier for now XX
my $now = time; # not %s below - may not be portable my $now = time; # not %s below - may not be portable
# YYYY/MM/DD HH:MM:SS # YYYY/MM/DD HH:MM:SS
$val = "$now " . strftime("%Y/%m/%d %H:%M:%S", gmtime($now)); $val = "$now " . strftime("%Y/%m/%d %H:%M:%S", gmtime($now));
+79
View File
@@ -0,0 +1,79 @@
#!/usr/bin/perl
# $NHDT-Date: 1730238507 2024/10/29 21:48:27 $ $NHDT-Brev: keni-gitset:1.0 $
# Copyright (c) 2024 by Kenneth Lorber, Kensington, Maryland
# NetHack may be freely redistributed. See license for details.
# This deals with a git problem: there is no way to do:
# git help alias-name
# (yes, that will show the definition of the alias, but not show an actual
# help document).
#
# So we implement this:
# nhhelp
# With no arguments, run perldoc on this file.
# nhhelp FOO
# Run perldoc on .git/hooks/FOO (if it exists).
if($#ARGV == -1){
system("perldoc $0")==0 or die "perldoc error: $!\n";
exit 0;
}
if($#ARGV == 0){
if($ARGV[0] eq "-a"){
&listhelp;
exit 0;
}
chomp(my $target = `git config nethack.aliashelp.$ARGV[0]`);
my $file = ".git/hooks/$target";
if(-f $file){
system("perldoc $file")==0 or die "perldoc error: $!\n";
} else {
print "Unknown name '$ARGV[0]'\n";
&usage;
}
exit 0;
}
&usage;
exit 0;
sub usage {
print <<E_O_M;
usage: git nhhelp [<nhcmd>|-a]
E_O_M
}
sub listhelp {
print "nhhelp is available for:\n";
my @namelist = `git config --name-only --get-regexp 'nethack.aliashelp.*'`;
print "NAMELIST $?\n" if($?);
@namelist = map {
if(m/^nethack.aliashelp.(.*)/){
chomp(my $x = `git config 'nethack.aliasdesc.$1'`);
sprintf("%-12s %s",$1,$x);
}
} sort @namelist;
print " " . join("\n ", @namelist)."\n";
exit 0;
}
__END__
=for nhgitset nhhelp Help on NetHack git commands
=head1 NAME
C<nhhelp> - NetHack git command for help on NetHack git commands
=head1 SYNOPSIS
C<git nhhelp [nhcmd|-a]>
=head1 DESCRIPTION
With no arguments, print this message.
With one argument matching a NetHack git command, print the
documentation for that command.
With the argument C<-a>, show all available nhhelp topics with one line
summaries.
+334 -63
View File
@@ -1,5 +1,5 @@
#!/usr/bin/perl #!/usr/bin/perl
# $NHDT-Date: 1524689646 2018/04/25 20:54:06 $ Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.7 $ # $NHDT-Date: 1524689646 2018/04/25 20:54:06 $ Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $
# Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland
# NetHack may be freely redistributed. See license for details. # NetHack may be freely redistributed. See license for details.
@@ -8,6 +8,8 @@
use strict; use strict;
our %opt; #cmd v n f F m (other single char, but we don't care) our %opt; #cmd v n f F m (other single char, but we don't care)
my $mode; # a c d f (add, commit, date, date -f) my $mode; # a c d f (add, commit, date, date -f)
our $count;
our $skip;
if(length $ENV{GIT_PREFIX}){ if(length $ENV{GIT_PREFIX}){
chdir($ENV{GIT_PREFIX}) or die "Can't chdir $ENV{GIT_PREFIX}: $!"; chdir($ENV{GIT_PREFIX}) or die "Can't chdir $ENV{GIT_PREFIX}: $!";
@@ -23,7 +25,8 @@ if(length $ENV{GIT_PREFIX}){
# (see "git help status" for table) # (see "git help status" for table)
# No default. Undef means something unexpected happened. # No default. Undef means something unexpected happened.
my %codes = ( my %codes = (
'f M'=>1, 'f D'=>1, # [MD] not updated # [MD] not updated
'f M'=>1, 'f D'=>1,
'a M'=>0, 'a D'=>0, 'a M'=>0, 'a D'=>0,
'd M'=>0, 'd D'=>0, 'd M'=>0, 'd D'=>0,
'c M'=>0, 'c D'=>0, 'c M'=>0, 'c D'=>0,
@@ -83,10 +86,13 @@ my %codes = (
# AA unmerged, both added # AA unmerged, both added
# UU unmerged, both modified # UU unmerged, both modified
# ------------------------------------------------- # -------------------------------------------------
'a??'=>1, 'f??'=>1, # ?? untracked # ?? untracked
'a??'=>1, 'f??'=>1,
'd??'=>0, 'c??'=>0, 'd??'=>0, 'c??'=>0,
'f!!'=>1, # !! ignored # !! ignored
'f!!'=>1,
'a!!'=>0, 'd!!'=>0, 'c!!'=>0, 'a!!'=>0, 'd!!'=>0, 'c!!'=>0,
'f@@'=>1, # @@ internal ignored 'f@@'=>1, # @@ internal ignored
@@ -138,8 +144,8 @@ foreach my $e (@rawlist0){
push(@rawlist,'.') if($#rawlist == -1); push(@rawlist,'.') if($#rawlist == -1);
# pick up the prefix for substitutions in this repo # pick up the prefix for substitutions in this repo
#TEST my $PREFIX = &git_config('nethack','substprefix'); my $PREFIX = &git_config('nethack','substprefix');
my $PREFIX = "NHDT"; die "nethack.substprefix not set in git config" unless(length($PREFIX) > 0);
print "PREFIX: '$PREFIX'\n" if($opt{v}); print "PREFIX: '$PREFIX'\n" if($opt{v});
while(@rawlist){ while(@rawlist){
@@ -171,8 +177,24 @@ while(@rawlist){
} }
} }
# XXX could batch things up - later sub checkattr {
my($kw, $file) = @_;
my $attr = `git check-attr $kw -- $file`;
if($attr =~ m/$kw:\s+(.*)/){
# This is a bug in git. What if the value of an attribute is the
# string "unset"? Sigh.
if(! $opt{F}){
if($1 eq "unset" || $1 eq "unspecified"){
print " NOATTR: $attr" if($opt{v}>=2);
return 0;
}
}
return 1;
}
return 0;
}
# XXX could batch things up - later
sub schedule_work { sub schedule_work {
my($file) = @_; my($file) = @_;
print "CHECK: '$file'\n" if($opt{v}>=2); print "CHECK: '$file'\n" if($opt{v}>=2);
@@ -201,29 +223,18 @@ sub schedule_work {
return; return;
} }
} }
# FALLTHROUGH and continue
#print "ACCEPT TEST\n"; # XXXXXXXXXX TEST
#return;
my $attr = `git check-attr NHSUBST -- $file`; my $do_nhsubst = &checkattr('NHSUBST', $file);
if($attr =~ m/NHSUBST:\s+(.*)/){ my $do_nhdatesub = &checkattr('NH_DATESUB', $file);
# XXX this is a bug in git. What if the value of an attribute is the &process_file($file, $do_nhsubst, $do_nhdatesub);
# string "unset"? Sigh. # XXX no longer reachable - parse errors not caught properly?
if(! $opt{F}){ # die "Can't parse check-attr return: $attr\n";
if($1 eq "unset" || $1 eq "unspecified"){
print " NOATTR: $attr" if($opt{v}>=2);
return;
}
}
&process_file($file);
return;
}
die "Can't parse check-attr return: $attr\n";
} }
sub process_file { sub process_file {
my($file) = @_; my($file, $do_nhsubst, $do_nhdatesub) = @_;
print "DOFIL: $file\n" if($opt{v}>=1); print "DOFIL: $file\n" if($opt{v}>=1);
$count=0; # if we don't change anything, don't re-write the file
# For speed we read in the entire file then do the substitutions. # For speed we read in the entire file then do the substitutions.
local($_) = ''; local($_) = '';
@@ -237,31 +248,60 @@ sub process_file {
} }
close INFILE; close INFILE;
local $::current_file = $file; # used under handlevar local $::current_file = $file; # used under handle*
if($do_nhsubst){
# TODO: This doesn't handle PREFIX-Assert. To do that,
# we need to capture an entire line, call new sub handlevars()
# and let it iterate across all PREFIX-Foo while
# maintaining $::skip and reverting (like &handledatesub does).
# Also: capture optional arg: $NHDT-Foo(arg)$ $NHDT-Foo(arg): value $
# $1 - var and value (including trailing space but not $) # $1 - var and value (including trailing space but not $)
# $2 - var # $2 - var
# $4 - value or undef # $4 - value or undef
#s/\$$PREFIX-(([A-Za-z][A-Za-z0-9_]*)(: ([^\N{DOLLAR SIGN}]+))?)\$/&handlevar($2,$4)/eg; # \x24 == $
my $count = s/\$$PREFIX-(([A-Za-z][A-Za-z0-9_]*)(: ([^\x24]+))?)\$/&handlevar($2,$4)/eg; s/\$$PREFIX-(([A-Za-z][A-Za-z0-9_]*)(: ([^\x24]+) )?)\$/&handlevar($2,$4,1)/eg;
# XXX had o modifier, why? }
if($do_nhdatesub){
# e.g:
#.\"DO NOT REMOVE NH_DATESUB .TH MAKEDEFS 6 "DATE(%-d %B %Y)" NETHACK
#.TH MAKEDEFS 6 "8 February 2022" NETHACK
# locate the keyword and the rest of the line, capturing the rest of the line (the pattern)
# use zero width assertions so we can capture them but not replace them (DOES THIS WORK?)
#and grab the next line (the replaced text)
# $1 - pattern
# $2 - the next line (the expanded pattern)
s/
\sNH_DATESUB\s+ # our trigger
(.*)[\n\r]+ # save the pattern in $1
\K # but don't replace it
(.*) # save the oldvalue in $2
/
&handledatesub($2, $1) # replace oldvalue
/emxg;
#/m so ^$ match at each line
#/x this will be a mess, so attempt to comment it
}
#print STDERR "COUNT = $count\n";
return unless($count>0); return unless($count>0);
return if($opt{n}); return if($opt{n});
my $mode = 0777 & (stat($file))[2];
my $ofile = $file . ".nht"; my $ofile = $file . ".nht";
my $mode = 0777 & (stat($file))[2]; # save the original mode
open(TOUT, ">", $ofile) or die "Can't open $ofile"; open(TOUT, ">", $ofile) or die "Can't open $ofile";
# die "write failed: $!" unless defined syswrite(TOUT, $_);
my $offset = 0; my $offset = 0;
my $sent; my $sent;
#print STDERR "L=",length,"\n";
while($offset < length){ while($offset < length){
$sent = syswrite(TOUT, $_, (length($_) - $offset), $offset); $sent = syswrite(TOUT, $_, (length($_) - $offset), $offset);
die "write failed: $!" unless defined($sent); die "write failed: $!" unless defined($sent);
#print STDERR "rv=$sent\n";
last if($sent == (length($_) - $offset)); last if($sent == (length($_) - $offset));
$offset += $sent; $offset += $sent;
#print STDERR "loop: O=$offset\n";
} }
close TOUT or die "Can't close $ofile"; close TOUT or die "Can't close $ofile";
@@ -270,8 +310,6 @@ my $count = s/\$$PREFIX-(([A-Za-z][A-Za-z0-9_]*)(: ([^\x24]+))?)\$/&handlevar($2
rename $ofile, $file or die "Can't rename $ofile to $file"; rename $ofile, $file or die "Can't rename $ofile to $file";
} }
# XXX docs for --fixup and --squash are wrong in git's synopsis. --file missing
# --message --template -t
sub cmdparse { sub cmdparse {
my(@in) = @_; my(@in) = @_;
@@ -308,7 +346,7 @@ sub cmdparse {
shift @in; shift @in;
next; next;
} }
# XXX this is messy - time for a rewrite?
if(m/^-(.*)/){ if(m/^-(.*)/){
foreach my $single ( split(//,$1) ){ foreach my $single ( split(//,$1) ){
# don't do -v here from add/commit # don't do -v here from add/commit
@@ -334,7 +372,7 @@ sub cmdparse {
last; last;
} }
if($single =~ m/[cCFm]/){ if($single =~ m/[cCFm]/){
#XXX this will be a mess if the argument is wrong, but can we tell? No. # This will be a mess if the argument is wrong, but can we tell? No.
shift @in; shift @in;
last; last;
} }
@@ -349,19 +387,36 @@ sub cmdparse {
$mode = 'f' if($opt{cmd} eq 'add' && $opt{f}); $mode = 'f' if($opt{cmd} eq 'add' && $opt{f});
if($opt{cmd} eq 'add' && $#in == -1){ if($opt{cmd} eq 'add' && $#in == -1){
# "git nhadd" with no files has nothing to work on
exit 0; exit 0;
} }
if($opt{cmd} eq 'commit' && $#in == -1){ if($opt{cmd} eq 'commit' && $#in == -1){
# "git nhcommit" with no args handles files already
# added, we assume with "git nhadd"
exit 0; exit 0;
} }
if($opt{cmd} eq 'add' && $opt{a} && $#in != -1){ if($opt{cmd} eq 'commit' && $opt{a} && $#in == -1){
# "git commit -a" does multiple things; we only care
# about modigied files.
#XXX this assumes $RS is set properly for Windows - need to check that
my @x = split(/$::RS/,`git ls-files -m`);
chomp(@x);
push(@in, @x);
}
if($opt{cmd} eq 'commit' && $opt{a} && $#in != -1){
# Let git complain about this for us.
exit 0; exit 0;
} }
if($opt{cmd} eq 'add' && $opt{a}){ # "git add" doesn't have a -a option
my $x = `git rev-parse --show-toplevel`; # if($opt{cmd} eq 'add' && $opt{a} && $#in != -1){
$x =~ s/[\n\r]+$//; # exit 0;
push(@in, $x); # }
} # I don't know what this was trying to do, but it's wrong.
# if($opt{cmd} eq 'add' && $opt{a}){
# my $x = `git rev-parse --show-toplevel`;
# $x =~ s/[\n\r]+$//;
# push(@in, $x);
# }
return @in; # this is our file list return @in; # this is our file list
} }
@@ -373,26 +428,83 @@ sub git_config {
die "Missing config var: [$section] $var\n"; die "Missing config var: [$section] $var\n";
} }
sub handlevar { # (oldvalue, pattern)
my($var, $val) = @_; sub handledatesub {
# print "HIT '$var' '$val'\n" if($debug2); my $oldval = $_[0]; # used if assert fails
$skip = 0; # one if assert fails
my $out = $_[1]; # the pattern, which we'll edit in place
#print "OLD: '$oldval;\n";
#print "PAT: '$out'\n";
my $newvalue = $_[1];
$out =~ s/
\b # don't substitute on a partial word
(Assert|Date|Branch|Revision|Brev|Project) # $1 - keyword
\( # (
([^)]*) # $2 - argument
\) # )
/&onedatesub($1,$2)
/egx;
{
local $::x = $_[0] ne $out;
if ($::x){
$count += $::x;
# warn "COUNT++";
}
}
#print STDERR "OUT SKIP=$skip count=$count\n";
#print STDERR "OUT old='$oldval'\n new='$out'\n";
return ($skip>0 or $count==0) ? $oldval : $out;
}
sub onedatesub {
my($kw, $arg) = @_;
my $sname = "PREFIX::$kw";
die "internal error, '$sname' not defined" unless defined(&$sname);
no strict;
my $rv = &$sname(undef, $arg);
return $rv;
}
# Assert(P=prefix)
# Date(format)
# Branch()
# Revision()
# Brev() Branch:Rev (aBREViated)
sub handlevar {
my($var, $val, $wrap) = @_;
#print "HV '$var' '$val'\n";
my $oldval = $val;
my $subname = "PREFIX::$var"; my $subname = "PREFIX::$var";
if(defined &$subname){ if(defined &$subname){
no strict; no strict;
print " SUBIN: $var '$val'\n" if($opt{v}>=3); print " SUBIN: $var '$val'\n" if($opt{v}>=3);
$val =~ s/\s+$//; $val =~ s/\s+$//;
$val = &$subname($val); $val = &$subname($val, undef);
print " SUBOT: $var '$val'\n" if($opt{v}>=3); print " SUBOT: $var '$val'\n" if($opt{v}>=3);
{
local $::x = ($oldval ne $val);
if ($::x){
$count += $::x;
# warn "COUNT2++ o='$oldval' v='$val'";
}
}
} else { } else {
warn "No handler for \$$PREFIX-$var\n"; warn "No handler for \$$PREFIX-$var\n";
} }
if($wrap){
if(length $val){ if(length $val){
return "\$$PREFIX-$var: $val \$"; return "\$$PREFIX-$var: $val \$";
} else { } else {
return "\$$PREFIX-$var\$"; return "\$$PREFIX-$var\$";
} }
} else {
return $val;
}
} }
sub lsfiles { sub lsfiles {
@@ -411,20 +523,35 @@ sub lsfiles {
package PREFIX; package PREFIX;
use POSIX qw(strftime); 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 { sub Date {
my($val) = @_; my(undef, $val) = @_;
my $now; my $now;
if($opt{m}){
my $hash = `git log -1 '--format=format:%H' $::current_file`; # DONE XXX after several bug fixes, this set of ifs needs some cleanup
my $hash = `git log -1 '--format=format:%H' $::current_file`;
$now = $^T;
# if($opt{m} or not defined $hash){
# cope with file not yet added to git
if(not defined $hash){
if(-f $::current_file){
$now = (stat($::current_file))[9];
} else {
die "Can't find file '$::current_file'\n";
}
} elsif($opt{m}) {
#author keni <keni@his.com> 1429884677 -0400 #author keni <keni@his.com> 1429884677 -0400
chomp($now = `git cat-file -p $hash | awk '/author/{print \$4}'`); chomp($now = `git cat-file -p $hash | awk '/author/{print \$4}'`);
} else {
$now = time;
} }
# } else {
# }
# DONE XXX simplify this with %s ?
# my $fmt = length $val ? $val : "%Y/%m/%d %H:%M:%S";
my $fmt = length $val ? $val : "%s %Y/%m/%d %H:%M:%S";
# YYYY/MM/DD HH:MM:SS # YYYY/MM/DD HH:MM:SS
$val = "$now " . strftime("%Y/%m/%d %H:%M:%S", gmtime($now)); # $val = ((length $val==0)?"$now ":"") . strftime($fmt, gmtime($now));
$val = strftime($fmt, gmtime($now));
return $val; return $val;
} }
@@ -434,10 +561,11 @@ sub Date {
#} #}
# NB: the standard-ish Revision line isn't enough - you need Branch:Revision - # 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 # but we split it into 2 so we can use the standard processing code on
# and just slip Branch in. # Revision and just slip Branch in.
# But see new Brev below.
sub Branch { sub Branch {
my($val) = @_; my $val;
$val = `git symbolic-ref -q --short HEAD`; $val = `git symbolic-ref -q --short HEAD`;
$val =~ s/[\n\r]*$//; $val =~ s/[\n\r]*$//;
$val =~ s/^\*\s*//; $val =~ s/^\*\s*//;
@@ -446,14 +574,71 @@ sub Branch {
} }
sub Revision { sub Revision {
my($val) = @_; my $val;
my @val = `git log --follow --oneline $::current_file`; my @val = `git log --follow --oneline $::current_file`;
my $ver = 0+$#val; my $ver = 0+$#val;
$ver = 0 if($ver < 0); $ver = 0 if($ver < 0);
$val = "1.$ver"; $val = "1.$ver";
return $val; return $val;
} }
sub Brev {
my $branch;
$branch = `git symbolic-ref -q --short HEAD`;
$branch =~ s/[\n\r]*$//;
$branch =~ s/^\*\s*//;
$branch = "(unknown)" unless($branch =~ m/^[[:print:]]+$/);
my @val = `git log --follow --oneline $::current_file`;
my $ver = 0+$#val;
$ver = 0 if($ver < 0);
$ver = "1.$ver";
my $val = "$branch:$ver";
return $val;
}
sub Project {
my(undef, $arg) = @_;
my $pn = &::git_config('nethack','projectname');
if(length $arg == 0){
;
} elsif($arg eq 'uc'){
$pn = uc($pn);
} else {
warn "unknown argument '$arg' to Project()\n";
}
return $pn;
}
sub Assert {
my(undef, $val) = @_;
my($key, $arg) = ($val =~ m/^(.)=(.*)/);
if(!defined $arg){
warn "syntax error: Assert($val)\n";
$::skip = 1;
}
my $prefix = $2;
# P assert arg matches saved prefix
if('P' eq $key){
my $repoid = &::git_config('nethack','substprefix');
if($repoid ne $prefix){
$::skip = 1
}
return '';
}
warn "Unknown Assert type '$key'\n";
return '';
}
__END__ __END__
=for nhgitset nhsub Update substitution variables
=head1 NAME =head1 NAME
@@ -473,9 +658,15 @@ commands.
The program re-writes those files listed on the command line; if the file The program re-writes those files listed on the command line; if the file
is actually a directory, the program recurses into that directory tree. is actually a directory, the program recurses into that directory tree.
Not all files found are re-written; some are ignored and those with no Not all files found are re-written; only those with the attribute
substitution variables are not re-written. Unless changed by the options, NHSUBST (for inline substitutions) or NH_DATESUB (for template
files that have not changed are not affected. substitution) are considered; finally those with no substitution
variables or no changes due to subtitution variables are not
re-written. Unless changed by the options, files that have not
changed are not affected.
As a special case, a file not yet added to Git may be the target of
C<nhsub>.
If no files are listed on the command line, the current directory is If no files are listed on the command line, the current directory is
checked as if specified as C<.>. checked as if specified as C<.>.
@@ -519,3 +710,83 @@ updated when last changed. (Do not use C<git nhadd>/C<git nhcommit> after C<nhsu
or the changes will be overwritten with the current date.) or the changes will be overwritten with the current date.)
=back =back
=head1 SUBSTITUTION VALRIABLES
=over
=item Assert(type=value)
If the assertion fails, no substitutions occur on this line.
If the assertion passes, substitutions occur as usual.
(There is no PREFIX-Assert form at this time, as it would make no sense
for the one Assert type currently implemented.)
=over
=item P
Type C<P> assertions compare the current Git config variable
C<nethack.substprefix>
with the C<value> and succeed if they are identical.
=back
=item Date(format) / PREFIX-Date
This variable usually substitutes the current time but see C<-m> above.
The format of the resulting date varies. For C<PREFIX-Date> or C<Date()> with
no format, "%s %Y/%m/%d %H:%M:%S" is used. Otherwise the given strftime
format is used.
=item Branch() / PREFIX-Branch
This variable is replaced with the name of the currently checked out Git
branch.
=item Revision() / PREFIX-Revision
This variable's value emulates a RCS or CVS style revision number.
It consists of "1." followed by the number of commits affecting the
current file.
=item Brev() / PREFIX-Brev
This is a convenience variable that concatenates C<Branch>, a colon, and
C<Revision>. Short for "aBREViated".
=item Project()
Returns git variable nethack.projectname. If given the argument C<uc>, returns
an upper-case version of nethack.projectname.
=back
=head1 SUBSTITUTION STYLES
=head2 Prefix Substitution
If a file has the Git attribute C<NHSUBST>, any
text that looks like a RCS/CVS variable substitution will perform
that substitution. That is, either of the following forms:
$Var$
$Var: Value $
=head2 Template Substitution
If a file has the Git attribute C<NH_DATESUB>, any line that has
the token C<NH_DATESUB> will replace the I<next> line with the
variable expansion of everything after that token. For example:
.\"DO NOT REMOVE NH_DATESUB .ds f2 DATE(%B %-d, %Y)
.ds f2 September 13, 2024
=head1 SEE ALSO
git help gitattributes
perldoc nhgitset.pl
+6 -2
View File
@@ -1,5 +1,5 @@
#!/usr/bin/perl #!/usr/bin/perl
# $NHDT-Date: 1524689631 2018/04/25 20:53:51 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.1 $ # NetHack 3.7 post-applypatch $NHDT-Date: 1524689631 2018/04/25 20:53:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $
# Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland
# NetHack may be freely redistributed. See license for details. # NetHack may be freely redistributed. See license for details.
@@ -24,7 +24,11 @@ BEGIN {
chomp $gitdir; chomp $gitdir;
push(@INC, $gitdir.$PDS."hooks"); push(@INC, $gitdir.$PDS."hooks");
} }
use NHgithook; eval {use NHgithook;};
if($@){
warn "loading NHgithook failed: $@";
$nogithook = 1;
}
#STARTUP-END #STARTUP-END
&NHgithook::PRE; &NHgithook::PRE;
+7 -2
View File
@@ -24,10 +24,15 @@ BEGIN {
chomp $gitdir; chomp $gitdir;
push(@INC, $gitdir.$PDS."hooks"); push(@INC, $gitdir.$PDS."hooks");
} }
use NHgithook; eval {use NHgithook;};
if($@){
warn "loading NHgithook failed: $@";
$nogithook = 1;
}
#STARTUP-END #STARTUP-END
&NHgithook::PRE; &NHgithook::PRE;
&NHgithook::nhversioning; eval { &NHgithook::nhversioning unless($nogithook) };
warn "nhversioning failed: $@" if($@);
&NHgithook::POST; &NHgithook::POST;
exit 0; exit 0;
+9 -2
View File
@@ -24,10 +24,17 @@ BEGIN {
chomp $gitdir; chomp $gitdir;
push(@INC, $gitdir.$PDS."hooks"); push(@INC, $gitdir.$PDS."hooks");
} }
use NHgithook; eval {use NHgithook;};
if($@){
warn "loading NHgithook failed: $@";
$nogithook = 1;
}
#STARTUP-END #STARTUP-END
&NHgithook::PRE; &NHgithook::PRE;
&NHgithook::nhversioning; eval { &NHgithook::nhversioning unless($nogithook) };
warn "nhversioning failed: $@" if($@);
&NHgithook::POST; &NHgithook::POST;
exit 0; exit 0;
+7 -2
View File
@@ -25,10 +25,15 @@ BEGIN {
push(@INC, $gitdir.$PDS."hooks"); push(@INC, $gitdir.$PDS."hooks");
} }
use NHgithook; eval {use NHgithook;};
if($@){
warn "loading NHgithook failed: $@";
$nogithook = 1;
}
#STARTUP-END #STARTUP-END
&NHgithook::PRE; &NHgithook::PRE;
&NHgithook::nhversioning; eval { &NHgithook::nhversioning(1) unless($nogithook) };
warn "nhversioning failed: $@" if($@);
&NHgithook::POST; &NHgithook::POST;
exit 0; exit 0;
+5 -1
View File
@@ -24,7 +24,11 @@ BEGIN {
chomp $gitdir; chomp $gitdir;
push(@INC, $gitdir.$PDS."hooks"); push(@INC, $gitdir.$PDS."hooks");
} }
use NHgithook; eval {use NHgithook;};
if($@){
warn "loading NHgithook failed: $@";
$nogithook = 1;
}
#STARTUP-END #STARTUP-END
&NHgithook::saveSTDIN; &NHgithook::saveSTDIN;
+5 -1
View File
@@ -24,7 +24,11 @@ BEGIN {
chomp $gitdir; chomp $gitdir;
push(@INC, $gitdir.$PDS."hooks"); push(@INC, $gitdir.$PDS."hooks");
} }
use NHgithook; eval {use NHgithook;};
if($@){
warn "loading NHgithook failed: $@";
$nogithook = 1;
}
#STARTUP-END #STARTUP-END
&NHgithook::PRE; &NHgithook::PRE;
+5 -1
View File
@@ -24,7 +24,11 @@ BEGIN {
chomp $gitdir; chomp $gitdir;
push(@INC, $gitdir.$PDS."hooks"); push(@INC, $gitdir.$PDS."hooks");
} }
use NHgithook; eval {use NHgithook;};
if($@){
warn "loading NHgithook failed: $@";
$nogithook = 1;
}
#STARTUP-END #STARTUP-END
&NHgithook::PRE; &NHgithook::PRE;
+5 -1
View File
@@ -24,7 +24,11 @@ BEGIN {
chomp $gitdir; chomp $gitdir;
push(@INC, $gitdir.$PDS."hooks"); push(@INC, $gitdir.$PDS."hooks");
} }
use NHgithook; eval {use NHgithook;};
if($@){
warn "loading NHgithook failed: $@";
$nogithook = 1;
}
#STARTUP-END #STARTUP-END
&NHgithook::PRE; &NHgithook::PRE;
+5 -1
View File
@@ -24,7 +24,11 @@ BEGIN {
chomp $gitdir; chomp $gitdir;
push(@INC, $gitdir.$PDS."hooks"); push(@INC, $gitdir.$PDS."hooks");
} }
use NHgithook; eval {use NHgithook;};
if($@){
warn "loading NHgithook failed: $@";
$nogithook = 1;
}
#STARTUP-END #STARTUP-END
&NHgithook::saveSTDIN; &NHgithook::saveSTDIN;
+5 -1
View File
@@ -24,7 +24,11 @@ BEGIN {
chomp $gitdir; chomp $gitdir;
push(@INC, $gitdir.$PDS."hooks"); push(@INC, $gitdir.$PDS."hooks");
} }
use NHgithook; eval {use NHgithook;};
if($@){
warn "loading NHgithook failed: $@";
$nogithook = 1;
}
#STARTUP-END #STARTUP-END
&NHgithook::PRE; &NHgithook::PRE;
+6 -2
View File
@@ -1,5 +1,5 @@
#!/usr/bin/perl #!/usr/bin/perl
# $NHDT-Date: 1524689633 2018/04/25 20:53:53 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.1 $ # NetHack 3.7 prepare-commit-msg $NHDT-Date: 1524689633 2018/04/25 20:53:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $
# Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland
# NetHack may be freely redistributed. See license for details. # NetHack may be freely redistributed. See license for details.
@@ -24,7 +24,11 @@ BEGIN {
chomp $gitdir; chomp $gitdir;
push(@INC, $gitdir.$PDS."hooks"); push(@INC, $gitdir.$PDS."hooks");
} }
use NHgithook; eval {use NHgithook;};
if($@){
warn "loading NHgithook failed: $@";
$nogithook = 1;
}
#STARTUP-END #STARTUP-END
&NHgithook::PRE; &NHgithook::PRE;
+172 -66
View File
@@ -3,10 +3,6 @@
# Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland
# NetHack may be freely redistributed. See license for details. # NetHack may be freely redistributed. See license for details.
# 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 = 3;
my $version_old = 0; # current version, if any (0 is no entry ergo new repo)
use Cwd; use Cwd;
use Getopt::Std; use Getopt::Std;
@@ -18,7 +14,7 @@ BEGIN {
die <<E_O_M; die <<E_O_M;
File::Spec not found. (If you are running ActiveState Perl please run: File::Spec not found. (If you are running ActiveState Perl please run:
cpan File::Spec cpan File::Spec
and re-run this program. then re-run this program.
E_O_M E_O_M
} }
File::Spec::Functions->import; File::Spec::Functions->import;
@@ -26,9 +22,10 @@ E_O_M
exit 1 unless(getopts('nvf')); # TODO: this can probably have better output exit 1 unless(getopts('nvf')); # TODO: this can probably have better output
# OS hackery BEGIN {
my $DS = quotemeta('/'); # Directory Separator (for regex) # OS hackery
my $DSP = '/'; # ... for printing $DS = quotemeta('/'); # Directory Separator (for regex)
$PDS = '/'; # ... for printing
# Temporarily disabled; there's something weird about msys # Temporarily disabled; there's something weird about msys
# msys: POSIXish over a Windows filesystem (so / not \ but \r\n not \n). # msys: POSIXish over a Windows filesystem (so / not \ but \r\n not \n).
#if($^O eq "msys"){ #if($^O eq "msys"){
@@ -37,26 +34,71 @@ my $DSP = '/'; # ... for printing
# # NB: We don't need to do anything about File::Spec. It doesn't know # # 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. # # about msys but it defaults to Unix, so we'll be ok.
#} #}
if($^O eq "MSWin32"){ if($^O eq "MSWin32"){
$DS = quotemeta('\\'); $DS = quotemeta('\\');
$DSP = '\\'; $PDS = '\\';
}
# Fix @INC so we can 'use NHgithook' before it's installed.
# Set $is_sourcerepo while we're at it - same logic.
{
# Special case for running nhgitset against a different repo.
# Must preceed the normal case!
# NB: we use $DEVhooksdir later in the program
$DEVhooksdir = ($0 =~ m!^(.*)$DS!)[0];
chomp($DEVhooksdir);
$DEVhooksdir .= $PDS."hooksdir";
push(@INC, $DEVhooksdir) if(-d $DEVhooksdir);
# This one is for the normal case (in NHsource)
my $topdir = `git rev-parse --show-toplevel`;
chomp $topdir;
$topdir .= "${PDS}DEVEL${PDS}hooksdir";
push(@INC, $topdir) if(-d $topdir);
$is_sourcerepo = 0;
$is_sourcerepo = 1 if(-d $topdir);
}
} }
use NHgithook;
# current (installed) version, if any (0 is no entry ergo new repo)
my $version_old = NHgithook::version_in_git;
# version this program will install
my($version_new,$message_new) = NHgithook::version_in_devel;
if(0==$version_new and !opt_f){
# Edge case: this repo has been set up using version >= 4, but now we're running
# nhgitset after checking out DEVEL supporting version <4.
# Use -f to recover from broken DEVEL code.
print STDERR "DEVEL has version <4 code but version >=4 code already installed. Stopping.\n";
print STDERR "(If you need to reinstall the old code, rerun with -f\n";
exit 0;
}
die "Valid version not found in DEVEL/VERSION" unless(0==$version_new or $version_new >= 4);
# make sure we're at the top level of a repo # make sure we're at the top level of a repo
if(! -d ".git"){ if(! -d ".git"){
die "This is not the top level of a git repository.\n"; die "This is not the top level of a git repository.\n";
} }
my $vtemp = `git config --local --get nethack.setupversion`; if($version_old >= $version_new and !opt_f){
chomp($vtemp); print STDERR "Nothing to do.\n";
if($vtemp > 0){ exit 0;
$version_old = 0+$vtemp; }
if($version_old > 0){
if($version_old != $version_new){ if($version_old != $version_new){
print STDERR "Migrating from setup version $version_old to $version_new\n" if($opt_v); print STDERR "Migrating from setup version $version_old to $version_new\n";
if(length $message_new){
print STDERR "Additional information:\n$message_new\n";
}
} }
} }
# legacy check: # legacy check:
if(length $vtemp == 0){ if(length $version_old == 0){
if(`git config --get merge.NHsubst.name` =~ m/^Net/){ if(`git config --get merge.NHsubst.name` =~ m/^Net/){
$version_old = 1; $version_old = 1;
print STDERR "Migrating to setup version 1\n" if($opt_v); print STDERR "Migrating to setup version 1\n" if($opt_v);
@@ -75,6 +117,8 @@ 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 # This is (relatively) safe because we know we're at R in R/DEVEL/nhgitset.pl
my $srcdir = ($0 =~ m!^(.*)$DS!)[0]; my $srcdir = ($0 =~ m!^(.*)$DS!)[0];
#XXX do I really want a full path for srcdir? how badly?
if(! -f catfile($srcdir, 'nhgitset.pl')){ if(! -f catfile($srcdir, 'nhgitset.pl')){
die "I can't find myself in '$srcdir'\n"; die "I can't find myself in '$srcdir'\n";
} }
@@ -83,32 +127,36 @@ print STDERR "Copying from: $srcdir\n" if($opt_v);
if($opt_f || $version_old==0){ if($opt_f || $version_old==0){
print STDERR "Configuring line endings\n" if($opt_v); print STDERR "Configuring line endings\n" if($opt_v);
unlink catfile('.git','index') unless($opt_n);
system("git reset") unless($opt_n); system("git reset") unless($opt_n);
system("git config --local core.safecrlf true") unless($opt_n); &add_config('core.safecrlf', 'true') unless($opt_n);
system("git config --local core.autocrlf false") unless($opt_n); &add_config('core.autocrlf', 'false') unless($opt_n);
} elsif($version_old <2){ } elsif($version_old <2){
my $xx = `git config --get --local core.safecrlf`; my $xx = `git config --get --local core.safecrlf`;
if($xx !~ m/true/){ if($xx !~ m/true/){
print STDERR "\nNeed to 'rm .git${DSP}index;git reset'.\n"; print STDERR "\nNeed to 'rm .git${PDS}index;git reset'.\n";
print STDERR " When ready to proceed, re-run with -f flag.\n"; print STDERR " When ready to proceed, re-run with -f flag.\n";
exit 2; exit 2;
} }
} }
print STDERR "Installing aliases\n" if($opt_v); print STDERR "Installing aliases\n" if($opt_v);
$addpath = catfile(curdir(),'.git','hooks','NHadd'); $addpath = catfile(curdir(),'.git','hooks','NHadd');
&add_alias('nhadd', "!$addpath add"); &add_alias('nhadd', "!$addpath add");
&add_help('nhadd', 'NHadd');
&add_alias('nhcommit', "!$addpath commit"); &add_alias('nhcommit', "!$addpath commit");
&add_help('nhcommit', 'NHadd');
my $nhsub = catfile(curdir(),'.git','hooks','nhsub'); my $nhsub = catfile(curdir(),'.git','hooks','nhsub');
&add_alias('nhsub', "!$nhsub"); &add_alias('nhsub', "!$nhsub");
&add_help('nhsub', 'nhsub');
&add_alias('nhhelp', '!'.catfile(curdir(),'.git','hooks','nhhelp'));
&add_help('nhhelp', 'nhhelp');
&add_help('NHsubst', 'NHsubst');
&add_help('NHgithook', 'NHgithook.pm');
print STDERR "Installing filter/merge\n" if($opt_v);
# XXXX need it in NHadd to find nhsub???
# removed at version 3 # removed at version 3
#print STDERR "Installing filter/merge\n" if($opt_v);
#if($^O eq "MSWin32"){ #if($^O eq "MSWin32"){
# $cmd = '.git\\\\hooks\\\\NHtext'; # $cmd = '.git\\\\hooks\\\\NHtext';
#} else { #} else {
@@ -126,13 +174,18 @@ if($version_old == 1 or $version_old == 2){
unlink catfile(curdir(),'.git','hooks','NHtext') unless($opt_n); unlink catfile(curdir(),'.git','hooks','NHtext') unless($opt_n);
} }
&add_config('nethack.setuppath',$srcdir);
&add_config('nethack.is-sourcerepo',0+$is_sourcerepo);
$cmd = catfile(curdir(),'.git','hooks','NHsubst'); $cmd = catfile(curdir(),'.git','hooks','NHsubst');
&add_config('merge.NHsubst.name', 'NetHack Keyword Substitution'); &add_config('merge.NHsubst.name', 'NetHack Keyword Substitution');
&add_config('merge.NHsubst.driver', "$cmd %O %A %B %L"); &add_config('merge.NHsubst.driver', "$cmd %O %A %B %L");
print STDERR "Running directories\n" if($opt_v); print STDERR "Running directories\n" if($opt_v);
foreach my $dir ( glob("$srcdir$DS*") ){ # copy directories into .git (right now that's just hooks
my @gitadd = length($gitadddir)?glob("$gitadddir$DS*"):undef;
foreach my $dir ( (glob("$srcdir$DS*"), @gitadd) ){
next unless(-d $dir); next unless(-d $dir);
my $target = catfile($dir, 'TARGET'); my $target = catfile($dir, 'TARGET');
@@ -157,31 +210,51 @@ foreach my $dir ( glob("$srcdir$DS*") ){
} }
} }
&check_prefix; # for variable substitution &check_gitvars; # for variable substitution
if($version_old != $version_new){ if($version_old != $version_new or $opt_f){
print STDERR "Setting version to $version_new\n" if($opt_v); print STDERR "Setting version to $version_new\n" if($opt_v);
if(! $opt_n){ NHgithook::version_set_git($version_new) if(! $opt_n);
system("git config nethack.setupversion $version_new");
if($?){
die "Can't set nethack.setupversion $version_new: $?,$!\n";
}
}
} }
exit 0; exit 0;
sub add_help {
my($cmd, $file) = @_;
&add_config("nethack.aliashelp.$cmd", $file);
# pull out =for nhgitset CMD description...
my $desc = '';
open my $fh, "<", "$DEVhooksdir/$file";
if($fh){
while(<$fh>){
m/^=for\s+nhgitset\s+\Q$cmd\E\s+(.*)/ && do {
$desc = $1;
last;
}
}
close $fh;
} else {
warn "Can't open: '$DEVhooksdir/$file' ($!)\n";
}
if(length $desc){
&add_config("nethack.aliasdesc.$cmd", $desc);
} else {
&add_config("nethack.aliasdesc.$cmd", "(no description available)");
}
}
sub process_override { sub process_override {
my($srcdir, $plname) = @_; my($srcdir, $plname) = @_;
return 0 unless(length $gitadddir); return 0 unless(length $gitadddir);
my $plpath = catfile($gitadddir, $srcdir, $plname); 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); return 0 unless(-x $plpath);
print STDERR "Running $plpath\n" if($opt_v); print STDERR "RunningOverride $plpath\n" if($opt_v);
# current directory is top of target repo
# current directory is top of target repo
unless($opt_n){ unless($opt_n){
system("$plpath $opt_v") and die "Callout $plpath failed: $?\n"; system("$plpath $opt_v") and die "Callout $plpath failed: $?\n";
} }
@@ -198,52 +271,42 @@ sub add_config {
system('git', 'config', '--local', $name, $val) unless($opt_n); system('git', 'config', '--local', $name, $val) unless($opt_n);
} }
sub check_gitvars {
&check_prefix("substprefix");
&check_prefix("projectname");
}
sub check_prefix { sub check_prefix {
my $lcl = `git config --local --get nethack.substprefix`; my $which = $_[0];
my $lcl = `git config --local --get nethack.$which`;
chomp($lcl); chomp($lcl);
if(0==length $lcl){ if(0==length $lcl){
my $other = `git config --get nethack.substprefix`; my $other = `git config --get nethack.$which`;
chomp($other); chomp($other);
if(0==length $other){ if(0==length $other){
print STDERR "ERROR: nethack.substprefix is not set anywhere. Set it and re-run.\n"; print STDERR "ERROR: nethack.$which is not set anywhere. Set it and re-run.\n";
exit 2; exit 2;
} else { } else {
&add_config('nethack.substprefix', $other); &add_config('nethack.$which', $other);
print STDERR "Copying prefix '$other' to local repository.\n" if($opt_v); print STDERR "Copying prefix '$other' to local repository.\n" if($opt_v);
} }
$lcl = $other; # for display below $lcl = $other; # for display below
} }
print "\n\nUsing prefix '$lcl' - PLEASE MAKE SURE THIS IS CORRECT\n\n"; print "Using $which '$lcl' - PLEASE MAKE SURE THIS IS CORRECT\n";
} }
sub do_dir_DOTGIT { sub do_dir_DOTGIT {
if(1){
# We are NOT going to mess with config now.
return;
} else {
my($srcdir, $targetdir) = @_; my($srcdir, $targetdir) = @_;
#warn "do_dir_DOTGIT($srcdir, $targetdir)\n"; # not currently in use so just bail
my $cname = "$srcdir/config"; return;
if(-e $cname){ # are there other files in .git that we might want to handle?
print STDERR "Appending to .git/config\n" if($opt_v); # So just in case:
open CONFIG, ">>.git/config" or die "open .git/config: $!";
open IN, "<", $cname or die "open $cname: $!";
my @data = <IN>;
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/*") ){ for my $file ( glob("$srcdir/*") ){
next if( $file =~ m!.*/TARGET$! ); next if( $file =~ m!.*/TARGET$! );
next if( $file =~ m!.*/config$! ); next if( $file =~ m!.*/config$! );
die "ERROR: no handler for $file\n"; die "ERROR: no handler for $file\n";
} }
} }
}
sub do_dir_hooksdir { sub do_dir_hooksdir {
my($srcdir, $targetdir) = @_; my($srcdir, $targetdir) = @_;
@@ -258,13 +321,11 @@ sub do_dir_hooksdir {
} }
for my $path ( glob("$srcdir$DS*") ){ for my $path ( glob("$srcdir$DS*") ){
next if( $path =~ m!.*${DS}TARGET$! ); next if( $path =~ m!.*${DS}TARGET$! );
my $file = $path; my $file = $path;
$file =~ s!.*$DS!!; $file =~ s!.*$DS!!;
$file = catfile($targetdir, $file); $file = catfile($targetdir, $file);
next if($opt_n); next if($opt_n);
@@ -308,11 +369,29 @@ nhgitset.pl).
The following options are available: The following options are available:
B<-f> Force. Do not use this unless the program requests it. =over
B<-n> Make no changes. =item B<-f>
B<-v> Verbose output. Force. Do not use this unless the program requests it or the hooks are broken.
=back
=over
=item B<-n>
Dry-run - make no changes.
=back
=over
=item B<-v>
Verbose output.
=back
=head1 CONFIG =head1 CONFIG
@@ -329,8 +408,35 @@ nethack.gitadddir
nethack.setupversion nethack.setupversion
The version for nhgitset.pl and friends; has no relationship
to NetHack version numbers.
nethack.substprefix nethack.substprefix
The prefix this repo uses for variable substitution.
nethack.projectname
The name of the game being built - see C<Project()>.
nethack.is-sourcerepo
Does this repo contain NetHack source code? (1 = yes, 0 = no)
nethack.setuppath
Path to (and including) the DEVEL directory used including the
copy of nhgitset.pl used to set up this repo.
nethack.aliashelp.*
The last element of the variable is the name used with C<git nhhelp>
and the value is the name of a file to display with C<perldoc>.
nethack.aliasdesc.*
The last element of the variable is the name used with C<git nhhelp>
and the value is short help displayed with C<git nhhelp -a>.
=head1 EXIT STATUS =head1 EXIT STATUS
+4 -3
View File
@@ -1,4 +1,4 @@
.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.574 $ $NHDT-Date: 1711040379 2024/03/21 16:59:39 $ .\" $NHDT-Branch: keni-gitset $:$NHDT-Revision: 1.593 $ $NHDT-Date: 1730681007 2024/11/04 00:43:27 $
.\" .\"
.\" This is an excerpt from the 'roff' man page from the 'groff' package. .\" This is an excerpt from the 'roff' man page from the 'groff' package.
.\"+-- .\"+--
@@ -46,8 +46,8 @@
.ds vr NetHack 3.7.0 .ds vr NetHack 3.7.0
.ds f0 \*(vr .ds f0 \*(vr
.ds f1 \" empty .ds f1 \" empty
.\"DO NOT REMOVE NH_DATESUB .ds f2 DATE(%B %-d, %Y) .\"DO NOT REMOVE NH_DATESUB .ds f2 Date(%B %-d, %Y)
.ds f2 September 13, 2024 .ds f2 November 4, 2024
. .
.\" A note on some special characters: .\" A note on some special characters:
.\" \(lq = left double quote .\" \(lq = left double quote
@@ -6671,3 +6671,4 @@ Izchak Miller Mike Stephenson
.sm "Brand and product names are trademarks or registered trademarks \ .sm "Brand and product names are trademarks or registered trademarks \
of their respective holders." of their respective holders."
.\"EOF .\"EOF
changes
+1 -1
View File
@@ -47,7 +47,7 @@
%.au %.au
\author{Original version - Eric S. Raymond\\ \author{Original version - Eric S. Raymond\\
(Edited and expanded for 3.7.0 by Mike Stephenson and others)} (Edited and expanded for 3.7.0 by Mike Stephenson and others)}
%DO NOT REMOVE NH_DATESUB \date{DATE(%B %-d, %Y)} %DO NOT REMOVE NH_DATESUB \date{Date(%B %-d, %Y)}
\date{September 13, 2024} \date{September 13, 2024}
\maketitle \maketitle
+6 -6
View File
@@ -1,16 +1,16 @@
.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ $NHDT-Date: 1693253316 2023/08/28 20:08:36 $ .\" $NHDT-Branch: keni-gitset $:$NHDT-Revision: 1.13 $ $NHDT-Date: 1730949315 2024/11/06 22:15:15 $
.\"DO NOT REMOVE NH_DATESUB .TH DLB 6 "DATE(%-d %B %Y)" NETHACK .\"DO NOT REMOVE NH_DATESUB .TH DLB 6 "DATE(%-d %B %Y)" Project(uc)
.TH DLB 6 "8 February 2022" NETHACK .TH DLB 6 "DATE(%-d %B %Y)" NETHACK
.\"DO NOT REMOVE NH_DATESUB .ds Nd DATE(%Y) .\"DO NOT REMOVE NH_DATESUB .ds Nd DATE(%Y)
.ds Nd 2022 .ds Nd DATE(%Y)
.de NB .de NB
.ds Nb \\$2 .ds Nb \\$2
.. ..
.de NR .de NR
.ds Nr \\$2 .ds Nr \\$2
.. ..
.NB $NHDT-Branch: NetHack-3.7 $ .NB $NHDT-Branch: keni-gitset $
.NR $NHDT-Revision: 1.12 $ .NR $NHDT-Revision: 1.13 $
.ds Na Kenneth Lorber .ds Na Kenneth Lorber
.SH NAME .SH NAME
dlb \- NetHack data librarian dlb \- NetHack data librarian
+1 -1
View File
@@ -1,4 +1,4 @@
.\"DO NOT REMOVE NH_DATESUB .TH MAKEDEFS 6 "DATE(%-d %B %Y)" NETHACK .\"DO NOT REMOVE NH_DATESUB .TH MAKEDEFS 6 "DATE(%-d %B %Y)" Project(uc)
.TH MAKEDEFS 6 "8 February 2022" NETHACK .TH MAKEDEFS 6 "8 February 2022" NETHACK
.\"DO NOT REMOVE NH_DATESUB .ds Nd DATE(%Y) .\"DO NOT REMOVE NH_DATESUB .ds Nd DATE(%Y)
.ds Nd 2022 .ds Nd 2022
+1 -1
View File
@@ -1,4 +1,4 @@
.\"DO NOT REMOVE NH_DATESUB .TH NETHACK 6 "DATE(%-d %B %Y)" NETHACK .\"DO NOT REMOVE NH_DATESUB .TH NETHACK 6 "DATE(%-d %B %Y)" Project(uc)
.TH NETHACK 6 "21 February 2022" NETHACK .TH NETHACK 6 "21 February 2022" NETHACK
.\"DO NOT REMOVE NH_DATESUB .ds Nd DATE(%Y) .\"DO NOT REMOVE NH_DATESUB .ds Nd DATE(%Y)
.ds Nd 2022 .ds Nd 2022
+1 -1
View File
@@ -1,4 +1,4 @@
.\"DO NOT REMOVE NH_DATESUB .TH RECOVER 6 "DATE(%-d %B %Y)" NETHACK .\"DO NOT REMOVE NH_DATESUB .TH RECOVER 6 "DATE(%-d %B %Y)" Project(uc)
.TH RECOVER 6 "8 February 2022" NETHACK .TH RECOVER 6 "8 February 2022" NETHACK
.\"DO NOT REMOVE NH_DATESUB .ds Nd DATE(%Y) .\"DO NOT REMOVE NH_DATESUB .ds Nd DATE(%Y)
.ds Nd 2022 .ds Nd 2022
+2
View File
@@ -11,6 +11,8 @@ Prerequisite Requirements:
pacman -S make pacman -S make
pacman -S vim (or your editor of choice) pacman -S vim (or your editor of choice)
pacman -S man (otherwise "git help foo" will not work) pacman -S man (otherwise "git help foo" will not work)
pacman -S perl-doc (otherwise "git nhhelp foo" will not work,
so only needed if you use nhgitset.pl)
o Lua o Lua
o pdcursesmod (Only required if curses interface support is desired) o pdcursesmod (Only required if curses interface support is desired)
Instructions for obtaining these are later in this file. Instructions for obtaining these are later in this file.