summaryrefslogtreecommitdiff
path: root/Master/tlpkg/libexec/place
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2011-03-06 22:31:53 +0000
committerKarl Berry <karl@freefriends.org>2011-03-06 22:31:53 +0000
commit0e6e50ca2549504070b29679d6159236bdf1b308 (patch)
tree0171343229c3531b47eefd984597c35b86922078 /Master/tlpkg/libexec/place
parent876cc70b39dad10fa8b3e5d2d600e0bad3c48f8d (diff)
adding biber, including binaries in both Master/bin and Build
git-svn-id: svn://tug.org/texlive/trunk@21617 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/tlpkg/libexec/place')
-rwxr-xr-xMaster/tlpkg/libexec/place303
1 files changed, 166 insertions, 137 deletions
diff --git a/Master/tlpkg/libexec/place b/Master/tlpkg/libexec/place
index 89fd94e90cc..6da0194d942 100755
--- a/Master/tlpkg/libexec/place
+++ b/Master/tlpkg/libexec/place
@@ -33,43 +33,45 @@ print "place: chicken mode = $chicken\n";
die "usage: $0 PKGNAME\n" unless @ARGV == 1;
$package = $ARGV[0];
-$newpackage = 0;
+my $is_new_package = 0;
%dirs = (); # dirs we make changes in
$TMP = $ENV{"TMPDIR"} || "/tmp";
$tmpfile = "$TMP/$>.tlplace"; # use effective uid in temp file names
-$cooked = getcwd(); # ctan2tl invokes us in the cooked dire
--d "$cooked/$package" || die "$0: No such package in $cooked: $package\n";
+$cooked_top = getcwd (); # ctan2tl invokes us in the top-level cooked dir
&xchdir ("$mydir/../..");
-$M = getcwd();
-
-xchdir ("$cooked/$package");
-if (-d "texmf-dist") {$Root="texmf-dist"; }
-elsif (-d "texmf-doc") {$Root="texmf-doc"; }
-elsif (-d "texmf") {$Root="texmf"; }
-else { die ("no top level texmf in " . `pwd`); }
-
-if ($Root eq 'texmf-doc') {
- $Type = 'Documentation';
-} elsif ($Root eq 'texmf-dist') {
- $Type = 'Package';
-} elsif ($Root eq 'texmf') {
- # can't handle binary stuff yet, but can do some hyphenations.
- $Type = 'TLCore';
-} else {
- die "cannot handle Root=$Root";
+my $M = $DEST = getcwd (); # svn Master, ordinarily where we write
+#
+&xchdir ("..");
+
+# top-level. for historical reasons, is usually just relative to
+# Master, e.g., has texmf-dist. But when a package has to write to both
+# Master and Build (e.g., biber), it will have Master and Build subdirs.
+my $TOP = getcwd ();
+
+&xchdir ("$cooked_top/$package");
+my $cooked_pkg = getcwd ();
+
+if (-d "Master") { # maybe have both Build and Master
+ &xchdir ("Master");
+ $DEST = $TOP;
}
+my $cooked_master = getcwd ();
+
+if (-d "texmf-dist") { $Type = "Package"; }
+elsif (-d "texmf") { $Type = "TLCore"; }
+else { die "$cooked_master: no top level texmf or texmf-dist"; }
-die "top-level README in $Root, that can't be right" if -e "$Root/README";
+die "top-level README in $Root, that can't be right" if <*/README>;
# initialize TLPDB.
my $tlpdb = new TeXLive::TLPDB ("root" => $M);
-# create TLTREE from stuff in cooked/$pkg
-my $tltree = TeXLive::TLTREE->new ("svnroot" => "$cooked/$package");
+# create TLTREE from stuff in cooked
+my $tltree = TeXLive::TLTREE->new ("svnroot" => $cooked_master);
$tltree->init_from_files;
-# get package from TLPDB.
+# get existing package from TLPDB.
my %Old;
my $tlpold = $tlpdb->get_package ($package);
if (defined($tlpold)) {
@@ -77,7 +79,7 @@ if (defined($tlpold)) {
$Old{$_} = 1;
}
} else {
- $newpackage = 1;
+ $is_new_package = 1;
}
# create new tlpsrc.
@@ -86,14 +88,14 @@ my $tlpsrcfile = "$M/tlpkg/tlpsrc/$package.tlpsrc";
if (! -r $tlpsrcfile) {
$tlpsrc->name($package);
$tlpsrc->category($Type);
- if (!$chicken) {
+ if (! $chicken) {
local *TLPSRC;
$TLPSRC = ">$tlpsrcfile";
open (TLPSRC) || die "open($TLPSRC) failed: $!";
# not needed, we only set name and category which are taken
# be default from the file name, so do not create useless entries
# but only empty files
- # $tlpsrc->writeout(\*TLPSRC);
+ # $tlpsrc->writeout (\*TLPSRC);
close TLPSRC;
}
} else {
@@ -103,72 +105,24 @@ if (! -r $tlpsrcfile) {
# make the new tlpobj.
my $tlpnew = $tlpsrc->make_tlpobj($tltree, $M);
+
# show comparison of old and new.
print "\n\f ";
-&compare_disk_vs_tlpobj ("$cooked/$package", $tlpnew);
-
-if (!defined($tlpold)) {
- print "place: $package not present in $M/$InfraLocation/$DatabaseName\n\n";
-} else {
- print "new vs. present $package (present is indented)\n";
- my @oldfiles = keys %Old;
- `rm -f $tmpfile.old`;
- foreach (sort @oldfiles) {
- `echo $_ >>$tmpfile.old`;
- }
- my @newfiles = $tlpnew->all_files;
- `rm -f $tmpfile.new`;
- foreach (sort @newfiles) {
- `echo $_ >>$tmpfile.new`;
- }
- print `comm -3 $tmpfile.new $tmpfile.old`;
- my @difffiles = `comm -12 $tmpfile.new $tmpfile.old`;
- chomp (@difffiles);
- my $sum = 0;
- my $identical = 0;
- #
- my $diff_file = "$tmpfile.diff";
- unlink ($diff_file);
- #
- # The --text is because we want to see the real changes, always.
- # The space-related options are because those changes aren't real.
- # (The diff is only run if the files are different according to our
- # own test, so it's ok if the options eliminate all the diffs; it'll
- # still get reported as needing an update.)
- # The -s reports identical files.
- #
- my $diff_cmd = "diff --text --strip-trailing-cr --ignore-all-space -U 0 -s";
- #
- for my $f (@difffiles) {
- my $master_file = "$M/$f";
- my $cooked_file = "$cooked/$package/$f";
- # diff has no options for handling Mac line endings,
- # so use our own script for the initial comparison.
- if (system ("cmp-textfiles '$master_file' '$cooked_file'") == 0) {
- $identical++;
- } else {
- my @diff_out = `$diff_cmd $master_file $cooked_file | tee -a $diff_file`;
- $sum += $#diff_out - 2; # zero-based, so first line doesn't count.
- # subtract another two lines for the heading
- # and at least one hunk marker.
- }
- }
- my $nrcommfiles = @difffiles;
- #
- my $changed = $nrcommfiles - $identical;
- print "$nrcommfiles common files, $changed changed, ~$sum lines different ($diff_file)\n\n\f\n";
- #`rm -f $tmpfile.*`
-}
+&compare_disk_vs_tlpobj ($cooked_master, $tlpnew);
+&show_tlp_diffs ($tlpnew, %Old);
-&xchdir ("$cooked/$package");
+my @new_build_files = &handle_build_files ($cooked_pkg, $DEST);
+&xchdir ($cooked_pkg);
print "place: checking for case-insensitive clashes\n";
-print `find . '(' -name .svn ')' -prune -o -print | sort | uniq -i -d`;
+print `find . -prune -o -print | sort | uniq -i -d`;
print "\n";
-find (\&files, ".");
+# Figure out removals relative to old package.
+&xchdir ($cooked_master);
+find (\&files, "."); # sets %New (= all files under Master)
foreach $file (sort keys %Old) {
my $status = $New{$file} ? "retained" : "removed";
print "* $file\t[$status]\n";
@@ -177,7 +131,7 @@ foreach $file (sort keys %Old) {
# probably did so by hand and didn't bother to update.
next unless -e "$M/$file";
- # remove old files.
+ # remove no longer existing files.
if (! $New{$file}) {
&xsystem ("svn remove $M/$file");
}
@@ -186,21 +140,25 @@ foreach $file (sort keys %Old) {
$dirs{$dname}++;
}
-# copy files
-my $job = "tar cf - . | (cd $M && tar xf - )";
-&xsystem ($job);
+
+# Copy files.
+&xchdir ($cooked_pkg);
+&xsystem ("tar cf - . | (cd $DEST && tar xf - )");
+
+# Processed everything out of the tmp cooked dir now, mv it aside.
+&xchdir ($cooked_top);
+&xsystem ("mv $package $package.done");
# sort so dirs will be added before subdirs.
+for my $build_file (sort @new_build_files) { # usually none
+ &add_file ($build_file);
+}
+#
for my $file (sort keys %New) {
- if (! $Old{$file}) {
- &add_file ("$M/$file");
- }
+ &add_file ("$M/$file") if ! $Old{$file};
}
-&xchdir ($cooked);
-&xsystem ("mv $package $package.done");
-
-if ($newpackage) {
+if ($is_new_package) {
&add_file ("$M/tlpkg/tlpsrc/$package.tlpsrc");
}
@@ -236,51 +194,22 @@ exit (0);
-sub dirs
-{
- local @filenames;
- if (-d) {
- @filenames=&buildfilelist($File::Find::name);
- if (!@filenames) { rmdir $File::Find::name;}
- }}
-
-sub buildfilelist
-{
- my($me) = @_;
- my @files;
- opendir(DIR,$me) || cleanup ("cannot open directory $me");
- @files =grep(!/^\.\.?/,readdir(DIR));
- closedir(DIR);
- return @files;
-}
-
-
-sub files
-{
- if (-f || -l) { # consider files or symlinks
- $This = $File::Find::name;
- $This =~ s/^\.\///;
- $New{$This} = 1;
- }
-}
-
-
# add a file to the repository. for svn, we also have to add the
# containing dir, and the parent of that dir, if they are new.
-# (Should really just traverse )
#
-sub add_file
-{
+sub add_file {
my ($newfile) = @_;
-
- # when it's needed, (grand)parents must come first, else have svn "not
- # working copy".
+#warn "adding file $newfile";
+
+ # when it's needed, (grand*)parents must come first, else have svn
+ # "not working copy" error.
my $newdir = $dir = dirname ($newfile);
my $needed_dirs = "";
until (-d "$dir/.svn") {
$needed_dirs = "$dir $needed_dirs"; # parents first
$dirs{$dir}++;
$dir = dirname ($dir);
+ die "no .svn dir found above $newdir? (in `pwd`)" if $dir eq ".";
}
&xsystem ("svn add -N $needed_dirs") if $needed_dirs;
@@ -298,12 +227,12 @@ sub add_file
$dirs{$newdir}++;
}
-
+
# compare against independent list of files in the new hierarchy, in
# case some of them did not get matched by the patterns.
-sub compare_disk_vs_tlpobj
-{
+#
+sub compare_disk_vs_tlpobj {
my ($diskdir,$tlp) = @_;
chomp (my @files_on_disk = `cd $diskdir && find \! -type d`);
s,^\./,, foreach @files_on_disk; # remove leading ./
@@ -325,8 +254,109 @@ sub compare_disk_vs_tlpobj
-sub xchdir
-{
+# write summary of changes to stdout and full diffs to a temp file so
+# humans can inspect if desired.
+#
+sub show_tlp_diffs {
+ my ($tlpnew, %Old) = @_;
+ if (!defined ($tlpold)) {
+ print "place: $package not present in $M/$InfraLocation/$DatabaseName\n\n";
+ } else {
+ print "new vs. present $package (present is indented)\n";
+ my @oldfiles = keys %Old;
+ unlink ("$tmpfile.old");
+ foreach (sort @oldfiles) {
+ `echo $_ >>$tmpfile.old`;
+ }
+ my @newfiles = $tlpnew->all_files;
+ unlink ("$tmpfile.new");
+ foreach (sort @newfiles) {
+ `echo $_ >>$tmpfile.new`;
+ }
+ print `comm -3 $tmpfile.new $tmpfile.old`;
+ my @difffiles = `comm -12 $tmpfile.new $tmpfile.old`;
+ chomp (@difffiles);
+ my $sum = 0;
+ my $identical = 0;
+ #
+ my $diff_file = "$tmpfile.diff";
+ unlink ($diff_file);
+ #
+ # The --text is because we want to see the real changes, always.
+ # The space-related options are because those changes aren't real.
+ # (The diff is only run if the files are different according to our
+ # own test, so it's ok if the options eliminate all the diffs; it'll
+ # still get reported as needing an update.)
+ # The -s reports identical files.
+ #
+ my $diff_cmd ="diff --text --strip-trailing-cr --ignore-all-space -U 0 -s";
+ #
+ for my $f (@difffiles) {
+ my $master_file = "$M/$f";
+ my $cooked_file = "$cooked_master/$f";
+ # diff has no options for handling Mac line endings,
+ # so use our own script for the initial comparison.
+ if (system ("cmp-textfiles '$master_file' '$cooked_file'") == 0) {
+ $identical++;
+ } else {
+ my $tee = "tee -a $diff_file";
+ my @diff_out = `$diff_cmd $master_file $cooked_file | $tee`;
+ $sum += $#diff_out - 2; # zero-based, so first line doesn't count.
+ # subtract another two lines for the heading
+ # and at least one hunk marker.
+ }
+ }
+ my $nrcommfiles = @difffiles;
+ #
+ my $changed = $nrcommfiles - $identical;
+ print "$nrcommfiles common files, $changed changed, ~$sum lines different"
+ . " ($diff_file)\n\n\f\n";
+ }
+}
+
+
+
+# return list of new files under Build, if any.
+# do nothing to try to remove files under Build, that doesn't make sense.
+#
+sub handle_build_files {
+ my ($cooked_pkg, $svn_dest) = @_;
+ my @ret = ();
+
+ return unless -d "$cooked_pkg/Build";
+ die "no Build subdir in $svn_dest?!" if ! -d "$svn_dest/Build";
+
+ # get list of files in cooked Build dir.
+ &xchdir ("$cooked_pkg");
+ local %New; # dynamically hide global %New.
+ find (\&files, "Build");
+
+ # compare against the svn Build dir; we only want the new files.
+ for my $file (keys %New) {
+ my $dest_file = "$svn_dest/$file";
+ my $status = -e $dest_file ? "existing" : "new";
+ print "* $file\t[$status]\n";
+ if ($status eq "new") {
+ push (@ret, $dest_file);
+ }
+ }
+
+ return @ret;
+}
+
+
+
+sub files { # subroutine for &find, updating %New.
+ if (-f || -l) { # consider files and symlinks
+ my $This = $File::Find::name;
+ $This =~ s,^\./,,; # omit leading ./
+ $New{$This} = 1;
+ }
+}
+
+
+
+sub xchdir {
my ($dir) = @_;
chomp (my $pwd = `pwd`);
chdir ($dir) || die "chdir($dir) failed: $!\n(cwd=$pwd)";
@@ -334,8 +364,7 @@ sub xchdir
}
-sub xsystem
-{
+sub xsystem {
my ($cmd) = @_;
print "place: SYSTEM $cmd\n";