diff options
Diffstat (limited to 'dh_elpa.in')
-rwxr-xr-x | dh_elpa.in | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/dh_elpa.in b/dh_elpa.in new file mode 100755 index 0000000..7a196e6 --- /dev/null +++ b/dh_elpa.in @@ -0,0 +1,251 @@ +#!/usr/bin/perl + +=head1 NAME + +dh_elpa - install emacs lisp packages into package build directories + +=cut + +use strict; +use Cwd qw{ getcwd }; +use File::Temp qw{tempfile}; +use IO::Handle; +use File::Path; + +use Debian::Debhelper::Dh_Lib; + +=head1 SYNOPSIS + +B<dh_elpa> [S<I<debhelper options>>] [S<I<pkg-file>>] + +=head1 DESCRIPTION + +B<dh_elpa> is a debhelper program that is responsible for installing +elpa style emacs lisp packages into package build directories. + +=head1 FILES + +=over 4 + +=item debian/I<package>.elpa + +List of files to be installed into I<package> as an elpa package. + +=back + +=cut + +init(options => { + "byte-compile!" => \$dh{BYTECOMPILE}, +}); + +=head1 OPTIONS + +=over 4 + +=item B<--byte-compile>, B<--no-byte-compile> + +Enable (default) or disable byte compilation of installed emacs lisp +files. Disabling byte compilation changes the destination directory +to one that is found by the emacs package system. + +=back + +=cut + +sub doit_quietly { + my ($handle,$tmpfile) = tempfile(UNLINK=>1); + my $exitcode; + + verbose_print(escape_shell(@_)); + open (CPERR,">&STDERR") or error "$!"; + open (CPOUT,">&STDOUT") or error "$!"; + STDOUT->fdopen($handle,'w'); + STDERR->fdopen($handle,'w'); + my $ret=doit_noerror(@_); + STDOUT->fdopen(\*CPOUT,'w'); + STDERR->fdopen(\*CPERR,'w'); + + if (!$ret){ + $exitcode=$?; + seek $handle, 0, 0 or error "$!"; + print while (<$handle>); + my $command=join(" ",@_); + error("$command returned exit code ".($exitcode >> 8)); + } + +} + +# simplified version of private sub autoscript_sed in Dh_Lib +sub sed_file { + my ($sed, $infile, $outfile) = @_; + + open(IN, $infile) or die "$infile: $!"; + open(OUT, ">>$outfile") or die "$outfile: $!"; + while (<IN>) { $sed->(); print OUT } + close(OUT) or die "$outfile: $!"; + close(IN) or die "$infile: $!"; +} + +sub read_package_desc { + my ($descdir, $package) = @_; + my %desc = (); + + my $descfile="${descdir}/${package}.desc"; + + my $fh; + + open $fh,'<', $descfile or + error "failed to open $descfile"; + + while (<$fh>) { + if (m/([^:]+):\s*(.*)\s*$/) { + $desc{$1} = $2; + } + } + return \%desc; +} + +my $templatedir = "/usr/share/debhelper/dh_elpa/emacsen-common"; + +sub maybe_install_helper{ + my ($package,$piece, $mode, $desc)=@_; + my $file=pkgfile($package,"emacsen-$piece"); + + my $tmp=tmpdir($package); + my $ecdest="$tmp/usr/lib/emacsen-common/packages"; + my $target="$ecdest/$piece/$package"; + # if there is file, leave it for dh_installemacsen + if ($file eq '') { + if (! -d "$ecdest/$piece") { + doit("install","-d","$ecdest/$piece"); + } + unlink $target; # ignore errors + + my $elpapackage = $desc->{'ELPA-Name'} or + error "elpa package name not found"; + + my $elpaversion = $desc->{'ELPA-Version'} or + error "elpa version not found"; + + sed_file (sub {s/#ELPAPACKAGE#/$elpapackage/; + s/#ELPAVERSION#/$elpaversion/; }, + "$templatedir/$piece", $target); + chmod oct($mode), $target; + } +} + +$dh{BYTECOMPILE} = 1 unless defined($dh{BYTECOMPILE}); + +my $elpadir; + +my $dhelpadir="/usr/share/emacs/site-lisp/elpa"; + +# TODO: do we really need a seperate elpa-src hierarchy? +if ($dh{BYTECOMPILE}) { + $elpadir="/usr/share/emacs/site-lisp/elpa-src"; +} else { + $elpadir=$dhelpadir; +} + +PACKAGE: +foreach my $package (@{$dh{DOPACKAGES}}) { + + my $tmp=tmpdir($package); + my $file=pkgfile($package,"elpa"); + + my $elpapkg=$package; + # TODO do this more sanely or at least allow an override + $elpapkg =~ s/^elpa-//; + verbose_print("Using elpa package name $elpapkg"); + + my @files; + + # Call isnative because it sets $dh{VERSION} + # as a side effect. + isnative($package); + if ($file) { + @files=filearray($file, "."); + scalar(@files) == 1 || grep { m/\b${elpapkg}-pkg.el$/ } @files or + error "missing ${elpapkg}-pkg.el"; + } + if (($package eq $dh{FIRSTPACKAGE} || $dh{PARAMS_ALL}) + && @ARGV) { + push @files, @ARGV; + } + + next PACKAGE if (scalar(@files) == 0); + + my $pkg_file; + my $cwd = getcwd(); + my $tempdir = "${cwd}/debian/.debhelper/elpa"; + my $helper_version = '@HELPER_VERSION@'; + + File::Path::rmtree $tempdir || + error "cleaning $tempdir"; + + File::Path::make_path $tempdir || + error "creating $tempdir"; + + addsubstvar($package,'misc:Built-Using',"dh-elpa (= ${helper_version})"); + + if (scalar(@files) == 1) { + my $pkg_file=$files[0]; + + doit_quietly(qw{emacs -batch -Q -l package}, + '--eval',"(add-to-list 'package-directory-list \"$dhelpadir\")", + '--eval',"(add-to-list 'package-directory-list \"$elpadir\")", + qw{-f package-initialize -l dh-elpa.el}, + qw{-f dhelpa-batch-install-file}, "$tmp/$elpadir", $pkg_file, $tempdir); + } else { + my $stagedir = "$tempdir/$elpapkg"; + File::Path::make_path $stagedir || + error "creating $stagedir"; + + # copy files into stagedir, flattening hierarchy + # TODO: do this more correctly + foreach my $el_file (@files) { + doit("cp", "-a", $el_file, "$stagedir"); + } + + doit_quietly(qw{emacs -batch -Q -l package}, + '--eval',"(add-to-list 'package-directory-list \"$dhelpadir\")", + '--eval',"(add-to-list 'package-directory-list \"$elpadir\")", + qw{-f package-initialize -l dh-elpa.el}, + qw{-f dhelpa-batch-install-directory}, + "$tmp/$elpadir", $stagedir, $tempdir); + + } + + if ($dh{BYTECOMPILE}) { + my $desc = read_package_desc ($tempdir,$elpapkg); + + addsubstvar($package,'misc:Depends','emacsen-common'); + maybe_install_helper($package, 'compat', '0644', $desc); + maybe_install_helper($package, 'install', '0755', $desc); + maybe_install_helper($package, 'remove', '0755', $desc); + + if (! $dh{NOSCRIPTS}) { + autoscript($package,"postinst","postinst-emacsen", + "s/#PACKAGE#/$package/"); + autoscript($package,"prerm","prerm-emacsen", + "s/#PACKAGE#/$package/"); + } + } + +} + +=head1 EXAMPLES + +Here is an example of using the helper in a dh(1) style debian/rules + +=over 4 + +override_dh_install: + dh_install + dh_elpa + +=back + +=cut + |