]> gitweb @ CieloNegro.org - stowinstall.git/commitdiff
Initial revision
authorPHO <pho@cielonegro.org>
Fri, 20 Feb 2009 10:00:41 +0000 (19:00 +0900)
committerPHO <pho@cielonegro.org>
Fri, 20 Feb 2009 10:00:41 +0000 (19:00 +0900)
stowinstall [new file with mode: 0755]

diff --git a/stowinstall b/stowinstall
new file mode 100755 (executable)
index 0000000..72bde31
--- /dev/null
@@ -0,0 +1,134 @@
+#!/usr/bin/perl
+# -*- cperl -*-
+use strict;
+use warnings;
+use File::Spec;
+
+if (!@ARGV) {
+    print "This is stowinstall,\n";
+    print " does `make install DESTDIR=...' for the GNU stow.\n";
+    print "\n";
+    print "  Usage: stowinstall [-f] [stow-dir]\n";
+    print "  (e.g. stowinstall /usr/local/stow/emacs)\n";
+    print "\n";
+    print "  Options:\n";
+    print "    -f --force      force install even if the Makefile\n";
+    print "                    doesn't have any \$(DESTDIR)\n";
+    print "    --file=<file>   specify the name of Makefile explicitly\n";
+    print "    --prefix=<dir>  specify the prefix instead of scanning Makefile\n";
+    print "    --target=<targ> specify the target instead of `install'\n";
+    print "\n";
+    print "stowinstall can only install packages whose Makefile corresponds:\n";
+    print " * file name is exactly `Makefile'\n";
+    print " * the Makefile has target `install'\n";
+    print " * the Makefile has `prefix = ...' form\n";
+    print " * the Makefile has at least one `\$(DESTDIR)' form\n";
+    print "autotools is our friend; it generates such Makefile:s.\n";
+}
+
+my $stowdir;
+my $opt_force;
+my $opt_prefix;
+my $opt_file = 'Makefile';
+my $opt_target = 'install';
+foreach (@ARGV) {
+    if (/^-f$/ or /^--force$/) {
+       $opt_force = 1;
+    }
+    elsif (/^--prefix=(.+)$/) {
+       $opt_prefix = $1;
+    }
+    elsif (/^--file=(.+)$/) {
+       $opt_file = $1;
+    }
+    elsif (/^--target=(.+)$/) {
+       $opt_target = $1;
+    }
+    else {
+       $stowdir = $_;
+    }
+}
+
+if (-r $opt_file) {
+    print "stowinstall: $opt_file exists.\n";
+}
+else {
+    die "stowinstall: $opt_file doesn't exist.\n";
+}
+
+my $makefile = do {
+    local $/ = undef;
+    open my $fh, '<', $opt_file;
+    <$fh>;
+};
+
+my ($prefix, $destdir, $target_install);
+$prefix = $opt_prefix;
+do {
+    foreach my $line (split /\r?\n/, $makefile) {
+       if (!$prefix and
+             $line =~ /^prefix\s*=\s*(.+?)\s*$/) {
+           $prefix = $1;
+           if ($prefix =~ /^(["'])(.+?)\1$/) {
+               $prefix = $2;
+           }
+       }
+       elsif ($line =~ /\$\(DESTDIR\)/) {
+           $destdir = 1;
+       }
+       elsif ($line =~ /^\Q$opt_target\E\s*:/) {
+           $target_install = 1;
+       }
+    }
+};
+
+if ($prefix) {
+    print "stowinstall: found prefix $prefix\n";
+}
+else {
+    die "stowinstall: prefix not found...\n";
+}
+
+if ($destdir) {
+    print "stowinstall: found \$(DESTDIR).\n";
+}
+else {
+    if ($opt_force) {
+       print "stowinstall: \$(DESTDIR) not found; doing force install. THIS IS DANGEROUS.\n";
+    }
+    else {
+       die "stowinstall: \$(DESTDIR) not found; this $opt_file seems not to support DESTDIR.\n";
+    }
+}
+
+if ($target_install) {
+    print "stowinstall: found target $opt_target.\n";
+}
+else {
+    die "stowinstall: $opt_target target not found; this $opt_file seems not to support $opt_target!\n";
+}
+
+if (!-d $stowdir) {
+    mkdir $stowdir or
+      die "stowinstall: failed to mkdir $stowdir\n";
+}
+
+my @destdir = File::Spec->splitdir(
+    File::Spec->canonpath("/tmp/stowinstall-$$/".$prefix));
+my $linkname = pop @destdir;
+
+my $path = '';
+foreach (@destdir) {
+    $path .= '/'.$_;
+    if (!-d $path) {
+       mkdir $path or
+         die "stowinstall: failed to mkdir $path\n";
+    }
+}
+
+my $linktarget = File::Spec->catdir(@destdir, $linkname);
+symlink $stowdir => $linktarget or
+  die "stowinstall: failed to symlink $stowdir => $linktarget\n";
+
+system("make $opt_target DESTDIR=/tmp/stowinstall-$$");
+system("rm -rf /tmp/stowinstall-$$");