summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Bremner <bremner@debian.org>2017-01-08 13:28:52 +0000
committerDavid Bremner <bremner@debian.org>2017-01-08 13:28:52 +0000
commit8216f75ec6442f800ff279a2336a713185ece74d (patch)
tree7278d6642ba53486cb291706feee22198a7efa5e
dh-elpa (1.6) unstable; urgency=medium
* Add an "exit 0" to xemacs case of remove script (Closes: #850036). [dgit import package dh-elpa 1.6]
-rw-r--r--README.org21
-rw-r--r--debian/NEWS21
-rw-r--r--debian/TODO5
-rw-r--r--debian/changelog252
-rw-r--r--debian/clean3
-rw-r--r--debian/compat1
-rw-r--r--debian/control31
-rw-r--r--debian/copyright22
-rw-r--r--debian/docs1
-rw-r--r--debian/elpa1
-rw-r--r--debian/install3
-rwxr-xr-xdebian/rules23
-rw-r--r--debian/source/format1
-rw-r--r--debian/source/lintian-overrides2
-rw-r--r--debian/watch3
-rw-r--r--dh-elpa.el312
-rwxr-xr-xdh_elpa.in345
-rwxr-xr-xdh_elpa_test376
-rwxr-xr-xelpa.pm29
-rw-r--r--emacsen-common/compat1
-rwxr-xr-xemacsen-common/install56
-rwxr-xr-xemacsen-common/remove38
-rw-r--r--notes.org39
23 files changed, 1586 insertions, 0 deletions
diff --git a/README.org b/README.org
new file mode 100644
index 0000000..2348ba2
--- /dev/null
+++ b/README.org
@@ -0,0 +1,21 @@
+* Intro
+
+This is a work-in progress project to generate Debian packages of
+Emacs Lisp extensions that integrate with the built in (since GNU
+Emacs 24.1) package system package.el. This means that debian packages
+built with this tool will show up in M-x list-packages, and that user
+installs of more up to date packages will override them (for that
+user!). Perhaps the most important improvement is that no file
+/etc/emacs/site-start.d is needed for such a package.
+
+* Limitations
+
+- This tool is currently not very well tested.
+
+- Currently all of the emacs lisp files are installed into one
+ directory; this might break packages that do fancier things with
+ load-path.
+
+- package.el gets confused if you have both a system and a user elpa
+ package and refuses to delete the user one unless you delete the
+ system one first.
diff --git a/debian/NEWS b/debian/NEWS
new file mode 100644
index 0000000..f9623d5
--- /dev/null
+++ b/debian/NEWS
@@ -0,0 +1,21 @@
+dh-elpa (0.0.20) unstable; urgency=medium
+
+ This version of dh_elpa will try to run any ERT and Buttercup test
+ suites that it can find if you set the debhelper compat level to 10
+ or above. If you are currently running your package's test suite
+ with a override_dh_auto_test stanza in debian/rules, or if there
+ exists an upstream test suite that you are not running, dh_elpa will
+ override any override_dh_auto_test stanza and try to run the test
+ suite. If it can't run it in its default configuration, this will
+ lead to your package failing to build from source.
+
+ The easy fix is to add a line like this to the top of your debian/rules:
+
+ export DH_AUTO_TEST_DISABLE
+
+ If instead you would like to migrate to have dh_elpa run your test
+ suite and it fails to do so in its default configuration, see
+ dh_elpa_test(1) for how to configure dh_elpa_test to run the test
+ suite successfully.
+
+ -- Sean Whitton <spwhitton@spwhitton.name> Sun, 1 May 2016 10:46:33 -0700
diff --git a/debian/TODO b/debian/TODO
new file mode 100644
index 0000000..9d18bb3
--- /dev/null
+++ b/debian/TODO
@@ -0,0 +1,5 @@
+-*- org -*-
+
+* missing features
+** info
+ - completely untested at the moment
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..295ea68
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,252 @@
+dh-elpa (1.6) unstable; urgency=medium
+
+ * Add an "exit 0" to xemacs case of remove script (Closes: #850036).
+
+ -- David Bremner <bremner@debian.org> Sun, 08 Jan 2017 09:28:52 -0400
+
+dh-elpa (1.5) unstable; urgency=high
+
+ * Add built-in packages to ${elpa:Depends} if they are also packaged
+ separately in Debian (e.g. let-alist and seq).
+
+ -- Sean Whitton <spwhitton@spwhitton.name> Sun, 01 Jan 2017 21:16:24 +0000
+
+dh-elpa (1.4) unstable; urgency=medium
+
+ * Add note to dh_elpa_test manpage about disabling its override of
+ dh_auto_test.
+ * Update Emacs dependency and build-dependency:
+ Previously: emacs24-nox | emacs24 (>=24~) | emacs24-lucid (>=24~)
+ Now: emacs25-nox | emacs25 | emacs24-nox | emacs24
+ - emacsXY-lucid has "Provides: emacsXY".
+ - Update for emacs25, but retain emacs24 for the sake of backports.
+ - Retain emacs24-nox for the sake of the backports buildds.
+ * dh_elpa_test ignores files containing ERT tests in .git.
+ In particular, don't try to load files in .git/dgit/unpack/fake.
+
+ -- Sean Whitton <spwhitton@spwhitton.name> Mon, 19 Dec 2016 07:32:34 +0000
+
+dh-elpa (1.3) unstable; urgency=medium
+
+ * Fix version comparison in elpa.pm.
+ Quote "0.90" so that the trailing 0 is not lost.
+ * Override debian-watch-file-in-native-package.
+
+ -- Sean Whitton <spwhitton@spwhitton.name> Tue, 06 Sep 2016 20:38:10 -0700
+
+dh-elpa (1.2) unstable; urgency=medium
+
+ * Add generated files to debian/clean:
+ - dh_elpa
+ - dh_elpa.1
+ - dh_elpa_test.1
+ * Add missing dependency on debhelper.
+ * Declare source format 3.0 (native).
+
+ -- Sean Whitton <spwhitton@spwhitton.name> Thu, 25 Aug 2016 07:12:14 -0700
+
+dh-elpa (1.1) unstable; urgency=medium
+
+ * Attempt to sanitise versions from DEB_* env vars so that Emacs accepts
+ them as ELPA package version strings.
+
+ -- Sean Whitton <spwhitton@spwhitton.name> Fri, 12 Aug 2016 19:51:04 -0700
+
+dh-elpa (1.0) unstable; urgency=medium
+
+ [ Sean Whitton ]
+ * dh_elpa_test should now be configured by the config file debian/elpa-test.
+ - New dependency on libconfig-tiny-perl.
+ * The old DH_ELPA_TEST_* configuration env vars are deprecated.
+ * Backport prep
+ - Add check for dh-make-perl version before invoking dh_elpa_test
+ - New dependency for this check: libdpkg-perl
+ * Globs in ert_exclude/DH_ELPA_TEST_ERT_EXCLUDE will now be matched against
+ the full paths to files (relative to the root of the source package).
+ Previously, only the basename was matched, so it was not possible to
+ use a glob like "broken-tests/*.el".
+ - New dependency on libtext-glob-perl.
+ * Add --autopkgtest switch to dh_elpa_test for autodep8.
+ * Add example usage of ert_exclude to dh_elpa_test(1).
+
+ [ David Bremner ]
+ * depend on libdebian-source-perl in preference to dh-make-perl, if the
+ former is available.
+
+ [ Rémi Vanicat & Sean Whitton ]
+ * use DEB_UPSTREAM_VERSION or DEB_VERSION_UPSTREAM as elpa version if
+ there is no version line in the main "*.el" file (Closes: #829200)
+ * add HINTS section to dh_elpa(1) documenting this
+
+ -- David Bremner <bremner@debian.org> Thu, 04 Aug 2016 13:44:50 +0900
+
+dh-elpa (0.0.21) unstable; urgency=medium
+
+ * Actually exclude .pc/ and debian/ directories from ERT tests.
+ * Fix Vcs-Git: URI.
+
+ -- Sean Whitton <spwhitton@spwhitton.name> Fri, 13 May 2016 15:33:34 -0700
+
+dh-elpa (0.0.20) unstable; urgency=medium
+
+ [ David Bremner ]
+ * Tighten versioned dependency on debhelper, needed for
+ get_source_date_epoch
+
+ [ Sean Whitton ]
+ * Add yasnippet to list of packages maintained outside of the elpa-*
+ binary package namespace.
+ * Add dh_elpa_test helper and add to elpa.pm sequencer script, plus
+ documentation, new dependencies and installation code.
+ dh_elpa can now automatically detect and run Buttercup and ERT test
+ suites.
+ * Use https for Vcs-* control file fields.
+ * Add myself as an uploader.
+ * Run wrap-and-sort -abst to deal with lengthening dependencies list.
+ * Bump standards version to 3.9.8; no changes required.
+
+ -- Sean Whitton <spwhitton@spwhitton.name> Sun, 01 May 2016 13:19:11 -0700
+
+dh-elpa (0.0.19) unstable; urgency=medium
+
+ [ Sean Whitton ]
+ * Fix generation of *-pkg.el file to not include dependencies on dash-el
+ or s-el, which are currently maintained outside of the elpa-*
+ namespace in Debian.
+
+ -- David Bremner <bremner@debian.org> Sun, 21 Feb 2016 09:17:51 -0400
+
+dh-elpa (0.0.18) unstable; urgency=low
+
+ * Document "--with elpa"
+ * Add --fix-autoload-date option (on by default) to take autoload dates
+ from changelog (Closes: #799168).
+ * Add ${elpa:Depends} substvar. Thanks to Sean Whitton for the implementation.
+
+ -- David Bremner <bremner@debian.org> Sun, 03 Jan 2016 19:26:12 -0400
+
+dh-elpa (0.0.17) unstable; urgency=medium
+
+ * Document substvars
+ * Add "--with elpa" sequencer option
+
+ -- David Bremner <bremner@debian.org> Sun, 29 Nov 2015 08:28:26 -0400
+
+dh-elpa (0.0.16) unstable; urgency=medium
+
+ * Bug fix: "Add Built-Using substvars entry", thanks to Hilko Bengen
+ (Closes: #803350).
+ * Add depends on ${perl:Depends}
+
+ -- David Bremner <bremner@debian.org> Wed, 28 Oct 2015 22:43:59 -0300
+
+dh-elpa (0.0.15) unstable; urgency=medium
+
+ * Also ignore emacs20
+ * Avoid error from find in remove script (Closes: #802963).
+
+ -- David Bremner <bremner@debian.org> Sun, 25 Oct 2015 14:31:04 -0300
+
+dh-elpa (0.0.14) unstable; urgency=medium
+
+ * Also ignore emacs21 and emacs22 in emacsen-common helper scripts
+
+ -- David Bremner <bremner@debian.org> Thu, 22 Oct 2015 23:05:11 -0300
+
+dh-elpa (0.0.13) unstable; urgency=medium
+
+ * remove /usr/share/${FLAVOUR}/site-lisp/elpa on last package removal.
+
+ -- David Bremner <bremner@debian.org> Tue, 06 Oct 2015 21:21:39 -0300
+
+dh-elpa (0.0.12) unstable; urgency=medium
+
+ * Replace use of private function `autoscript_sed' from Dh_Lib
+
+ -- David Bremner <bremner@debian.org> Fri, 25 Sep 2015 08:19:59 -0300
+
+dh-elpa (0.0.11) unstable; urgency=medium
+
+ * Fix elpa version in generated maintainer scripts (Closes: #799032)
+ (again).
+
+ -- David Bremner <bremner@debian.org> Tue, 22 Sep 2015 09:14:25 -0300
+
+dh-elpa (0.0.10) unstable; urgency=medium
+
+ * Take elpa version from lisp source (Closes: #799032).
+ Thanks to Thomas Koch for the report.
+
+ -- David Bremner <bremner@debian.org> Sat, 19 Sep 2015 10:49:28 -0300
+
+dh-elpa (0.0.9) unstable; urgency=medium
+
+ * Bug fix: "dh-elpa should provide substvar for depends field", thanks
+ to Thomas Koch (Closes: #799208). Currently we add only an unversioned
+ depends on emacsen-common.
+ * Bug fix: "an elpa package cannot require a non elpa debian package",
+ thanks to Remi Vanicat (Closes: #798576). As Remi suggests, use -q
+ instead of -Q to byte-compile files.
+
+ -- David Bremner <bremner@debian.org> Thu, 17 Sep 2015 07:45:15 -0300
+
+dh-elpa (0.0.8) unstable; urgency=medium
+
+ * Skip binary packages with no files in their package.elpa file and or
+ on the command line.
+
+ -- David Bremner <bremner@debian.org> Sat, 12 Sep 2015 20:54:05 -0300
+
+dh-elpa (0.0.7) unstable; urgency=medium
+
+ * On package uninstall remove the non-emacs-lisp symlinks as well
+ * Add Vcs-{Git,Browser} headers
+
+ -- David Bremner <bremner@debian.org> Tue, 08 Sep 2015 13:54:34 -0300
+
+dh-elpa (0.0.6) unstable; urgency=medium
+
+ * Bug fix: "maintainer address bounces", thanks to Ansgar Burchardt
+ (Closes: #797940).
+
+ -- David Bremner <bremner@debian.org> Thu, 03 Sep 2015 18:35:06 -0300
+
+dh-elpa (0.0.5) unstable; urgency=medium
+
+ * Use debian/.debhelper/elpa for temp files. This allows easier
+ debugging.
+ * Add a check for ${elpa_name}-pkg.el in multi-file packages
+ * Link all top level files/directories into flavour directory, not
+ just *.el
+
+ -- David Bremner <bremner@debian.org> Tue, 01 Sep 2015 19:09:51 -0300
+
+dh-elpa (0.0.4) unstable; urgency=medium
+
+ * Fix postinst bug: s/mkdir/mkdir -p/
+
+ -- David Bremner <bremner@debian.org> Thu, 20 Aug 2015 11:24:54 +0200
+
+dh-elpa (0.0.3) unstable; urgency=medium
+
+ * Switch to team maintenance
+ * Upload to unstable
+
+ -- David Bremner <bremner@debian.org> Thu, 20 Aug 2015 09:47:48 +0200
+
+dh-elpa (0.0.2) experimental; urgency=medium
+
+ * Clean up temporary directory
+ * By default install emacsen-common helper scripts to do byte
+ compilation and removal. It's the responsibility of packages
+ build-depending on dh-elpa to depend on emacsen-common unless they use
+ the no-byte-compile flag.
+
+ -- David Bremner <bremner@debian.org> Fri, 17 Jul 2015 19:03:42 +0200
+
+dh-elpa (0.0.1) experimental; urgency=medium
+
+ * Initial upload, early adopters only.
+
+ -- David Bremner <bremner@debian.org> Sat, 11 Jul 2015 15:24:57 +0200
+
diff --git a/debian/clean b/debian/clean
new file mode 100644
index 0000000..3c63b62
--- /dev/null
+++ b/debian/clean
@@ -0,0 +1,3 @@
+dh_elpa.1
+dh_elpa_test.1
+dh_elpa
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000..ec63514
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+9
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..24c9065
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,31 @@
+Source: dh-elpa
+Section: devel
+Priority: optional
+Maintainer: Debian Emacs addons team <pkg-emacsen-addons@lists.alioth.debian.org>
+Uploaders:
+ David Bremner <bremner@debian.org>,
+ Sean Whitton <spwhitton@spwhitton.name>,
+Build-Depends:
+ debhelper (>= 9.20151004),
+ emacs25-nox | emacs25 | emacs24-nox | emacs24,
+Standards-Version: 3.9.8
+Vcs-Git: https://anonscm.debian.org/git/pkg-emacsen/pkg/dh-elpa.git
+Vcs-Browser: https://anonscm.debian.org/cgit/pkg-emacsen/pkg/dh-elpa.git/
+
+Package: dh-elpa
+Architecture: all
+Built-Using: ${misc:Built-Using}
+Depends:
+ debhelper (>= 9.20151004),
+ libdebian-source-perl | dh-make-perl (>= 0.90),
+ emacs25-nox | emacs25 | emacs24-nox | emacs24,
+ libarray-utils-perl,
+ libconfig-tiny-perl,
+ libfile-find-rule-perl,
+ libdpkg-perl,
+ libtext-glob-perl,
+ ${misc:Depends},
+ ${perl:Depends},
+Description: Debian helper tools for packaging emacs lisp extensions
+ This package provides a helper for packaging emacs lisp extensions
+ in a way compatible with the GNU Emacs 'elpa' package repository.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000..83a9d9a
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,22 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+
+Files: *
+Copyright: © 2007-2015 Free Software Foundation Inc,
+ © 2015 David Bremner <bremner@debian.org>
+ © 2016 Sean Whitton <spwhitton@spwhitton.name>
+License: GPL-3+
+ dh-elpa is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ .
+ dh-elpa is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License
+ along with dh-elpa. If not, see <http://www.gnu.org/licenses/>.
+ .
+ On Debian systems, the complete text of the GNU General
+ Public License version 3 can be found in "/usr/share/common-licenses/GPL-3.
diff --git a/debian/docs b/debian/docs
new file mode 100644
index 0000000..f20153b
--- /dev/null
+++ b/debian/docs
@@ -0,0 +1 @@
+README.org
diff --git a/debian/elpa b/debian/elpa
new file mode 100644
index 0000000..abf136d
--- /dev/null
+++ b/debian/elpa
@@ -0,0 +1 @@
+*.el
diff --git a/debian/install b/debian/install
new file mode 100644
index 0000000..c410d21
--- /dev/null
+++ b/debian/install
@@ -0,0 +1,3 @@
+elpa.pm usr/share/perl5/Debian/Debhelper/Sequence
+emacsen-common usr/share/debhelper/dh_elpa
+usr/bin
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..554ca48
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,23 @@
+#!/usr/bin/make -f
+
+include /usr/share/dpkg/pkg-info.mk
+export DEB_VERSION_UPSTREAM
+DESTDIR=$(CURDIR)/debian/tmp
+
+%:
+ dh $@
+
+override_dh_auto_build:
+ pod2man -c Debhelper --section=1 dh_elpa.in > dh_elpa.1
+ pod2man -c Debhelper --section=1 dh_elpa_test > dh_elpa_test.1
+ sed s/@HELPER_VERSION@/${DEB_VERSION_UPSTREAM}/ < dh_elpa.in > dh_elpa
+ chmod 755 dh_elpa dh_elpa_test
+
+override_dh_install:
+ dh_install
+ dh_installman dh_elpa.1 dh_elpa_test.1
+ ./dh_elpa --no-byte-compile
+
+override_dh_auto_install:
+ install -m 755 -D dh_elpa $(DESTDIR)/usr/bin/dh_elpa
+ install -m 755 -D dh_elpa_test $(DESTDIR)/usr/bin/dh_elpa_test
diff --git a/debian/source/format b/debian/source/format
new file mode 100644
index 0000000..89ae9db
--- /dev/null
+++ b/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/debian/source/lintian-overrides b/debian/source/lintian-overrides
new file mode 100644
index 0000000..401b3e2
--- /dev/null
+++ b/debian/source/lintian-overrides
@@ -0,0 +1,2 @@
+# watch file is for use with pkg-emacsen PET
+debian-watch-file-in-native-package
diff --git a/debian/watch b/debian/watch
new file mode 100644
index 0000000..dc302f9
--- /dev/null
+++ b/debian/watch
@@ -0,0 +1,3 @@
+version=4
+opts="mode=git" https://anonscm.debian.org/git/pkg-emacsen/pkg/dh-elpa.git \
+ refs/tags/debian/([\d\.\d\.]+) debian
diff --git a/dh-elpa.el b/dh-elpa.el
new file mode 100644
index 0000000..8017851
--- /dev/null
+++ b/dh-elpa.el
@@ -0,0 +1,312 @@
+;;; dh-elpa.el --- package.el style packages for Debian -*- lexical-binding:t -*-
+
+;; Copyright (C) 2015 David Bremner & contributors
+;; Portions Copyright 2007-2015 The Free Software Foundation
+
+;; Author: David Bremner <bremner@debian.org>
+;; Created: 11 July 2015
+;; Keywords: tools
+;; Package-Requires: ((tabulated-list "1.0"))
+
+;; This file is NOT part of GNU Emacs.
+
+;; dh-elpa is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; dh-elpa is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with dh-elpa. If not, see <http://www.gnu.org/licenses/>.
+
+(require 'package)
+(require 'cl-lib)
+
+;; Originally package-unpack from package.el in Emacs 24.5
+(defun dhelpa-unpack (pkg-desc destdir &optional epoch-time)
+ "Install the contents of the current buffer into DESTDIR as a package.
+Optional argument EPOCH-TIME specifies time (as a string or
+number) to use in autoload files; if unspecifed or nil the
+current time is used."
+ (let* ((name (package-desc-name pkg-desc))
+ (dirname (package-desc-full-name pkg-desc))
+ (pkg-dir (expand-file-name dirname destdir))
+ (pkg-time (if epoch-time (seconds-to-time
+ (if (stringp epoch-time)
+ (string-to-number epoch-time)
+ epoch-time))
+ (current-time)))
+ (backup-inhibited t))
+ (make-directory pkg-dir t)
+ (pcase (package-desc-kind pkg-desc)
+ (`tar
+ (let ((default-directory (file-name-as-directory destdir)))
+ (package-untar-buffer dirname)))
+ (`single
+ (let ((el-file (expand-file-name (format "%s.el" name) pkg-dir)))
+ (package--write-file-no-coding el-file)))
+ (kind (error "Unknown package kind: %S" kind)))
+ (defun dhelpa-autoload-insert-section-header (real-fun outbuf autoloads load-name file time)
+ (funcall real-fun outbuf autoloads load-name file pkg-time))
+ (advice-add #'autoload-insert-section-header
+ :around #'dhelpa-autoload-insert-section-header)
+ (package--make-autoloads-and-stuff (dhelpa-filter-pkg-desc pkg-desc) pkg-dir)
+ (advice-remove #'autoload-insert-section-header
+ #'dhelpa-autoload-insert-section-header)
+ pkg-dir))
+
+;; Originally package-buffer-info from package.el in Emacs 24.5.1
+(defun dhelpa-buffer-info ()
+ "Return a `package-desc' describing the package in the current buffer.
+
+If the buffer does not contain a conforming package, signal an
+error. If there is a package, narrow the buffer to the file's
+boundaries.
+
+If there is no version information, try DEB_UPSTREAM_VERSION and
+then DEB_VERSION_UPSTREAM, signalling an error if they are both
+set and disagree."
+ (goto-char (point-min))
+ (unless (re-search-forward "^;;; \\([^ ]*\\)\\.el ---[ \t]*\\(.*?\\)[ \t]*\\(-\\*-.*-\\*-[ \t]*\\)?$" nil t)
+ (error "Package lacks a file header"))
+ (let ((file-name (match-string-no-properties 1))
+ (desc (match-string-no-properties 2))
+ (start (line-beginning-position)))
+ (unless (search-forward (concat ";;; " file-name ".el ends here"))
+ (error "Package lacks a terminating comment"))
+ ;; Try to include a trailing newline.
+ (forward-line)
+ (narrow-to-region start (point))
+ (require 'lisp-mnt)
+ ;; Use some headers we've invented to drive the process.
+ (let* ((requires-str (lm-header "package-requires"))
+ ;; Prefer Package-Version; if defined, the package author
+ ;; probably wants us to use it. Otherwise try Version.
+ (pkg-version
+ (or (package-strip-rcs-id (lm-header "package-version"))
+ (package-strip-rcs-id (lm-header "version"))
+ (dhelpa-getenv-version)))
+ (homepage (lm-homepage)))
+ (unless pkg-version
+ (error
+ "Package lacks a \"Version\" or \"Package-Version\"
+header, and neither of the DEB_UPSTREAM_VERSION and
+DEB_VERSION_UPSTREAM environment variables are set."))
+ (package-desc-from-define
+ file-name pkg-version desc
+ (if requires-str
+ (package--prepare-dependencies
+ (package-read-from-string requires-str)))
+ :kind 'single
+ :url homepage))))
+
+(defun dhelpa-getenv-version ()
+ "Return the package version as found in standard DEB_* environment variables.
+
+Try DEB_UPSTREAM_VERSION first, then DEB_VERSION_UPSTREAM.
+Signal an error if these are both set and they disagree.
+
+Versions taken from environment variables are run through
+`dhelpa-sanitise-version'."
+ ;; If one of these environment variables is the empty string, it's
+ ;; as good as unset, so we replace that with the nil value.
+ (let* ((upstream-version (null-empty-string
+ (getenv "DEB_UPSTREAM_VERSION")))
+ (version-upstream (null-empty-string
+ (getenv "DEB_VERSION_UPSTREAM")))
+ (version (if upstream-version upstream-version version-upstream))
+ (sanitised-version (dhelpa-sanitise-version version)))
+ ;; sanity check #1
+ (if (and upstream-version
+ version-upstream
+ (not (string= upstream-version version-upstream)))
+ (error "The DEB_UPSTREAM_VERSION and DEB_VERSION_UPSTREAM
+environment variables are both set, but they disagree.")
+ ;; sanity check #2
+ (unless (ignore-errors (version-to-list sanitised-version))
+ (error (concat "E: The Debian version " version " cannot be used as an ELPA version.
+See dh_elpa(1) HINTS for how to deal with this.")))
+ ;; if we got this far, return it
+ sanitised-version)))
+
+;;;###autoload
+(defun dhelpa-sanitise-version (version)
+ "Sanitise a Debian version VERSION such that it will work with Emacs.
+
+Our goal is to ensure that ELPA package versions are sorted
+correctly relative to other versions of the package the user
+might have installed in their home directory.
+
+To do this:
+
+- we remove all indication of backporting, since that is a matter
+ of Debian packaging and shouldn't affect the ELPA package
+ content
+
+- we replace '~' with '-' -- Emacs interprets '-rc', '-git' and
+ '-pre' similar to how dpkg interprets '~rc', '~git' and
+ '~pre' (see `version-to-list')
+
+This will not give the right answer in all cases (for example
+'~foo' where 'foo' is not one of the strings Emacs recognises as
+a pre-release). The Debian package maintainer should patch the
+upstream source to include a proper Package-Version: header in
+such a case."
+ (when version
+ (replace-regexp-in-string
+ "~" "-"
+ (replace-regexp-in-string "~bpo.*$" "" version))))
+
+(defun null-empty-string (str)
+ "If STR is a string of length zero, return nil. Otherwise, return STR."
+ (if (and (stringp str)
+ (zerop (length str)))
+ nil
+ str))
+
+(defun dhelpa-filter-deps-for-debian (deps)
+ "Filter a list of package.el deps DEPS for Debian.
+
+Remove packages that are maintained outside of the elpa-*
+namespace in Debian, plus Emacs itself.
+
+Also remove built-in packages, except those built-in packages
+that are also packaged separately in Debian.
+
+These are packaged separately for two reasons:
+
+- it allows us to provide newer versions than those in Emacs core
+
+- it permits use of addons with older versions of Emacs, for
+ which the dependency is not yet a built-in package."
+ (let ((non-elpa (list 'emacs 's 'dash 'yasnippet))
+ (packaged-separately (list 'let-alist 'seq)))
+ (cl-remove-if (lambda (dep) (let ((pkg (car dep)))
+ (or (memq pkg non-elpa)
+ (and
+ (package-built-in-p pkg)
+ (not (memq pkg packaged-separately))))))
+ deps)))
+
+(defun dhelpa-filter-pkg-desc (desc)
+ "Filter the dependencies of package description DESC for Debian."
+ (let ((our-desc (copy-package-desc desc)))
+ (cl-callf dhelpa-filter-deps-for-debian (package-desc-reqs our-desc))
+ our-desc))
+
+(defun dhelpa-debianise-deps (deps)
+ "Convert a list of package.el deps DEPS to debian/control format."
+ (mapconcat
+ (lambda (dep)
+ (let ((pkg-name (format "elpa-%s" (car dep)))
+ (pkg-ver (mapconcat 'number-to-string (car (cdr dep)) ".")))
+ (concat pkg-name " (>= " pkg-ver ")")))
+ deps ", "))
+
+;; Write out (partial) package description in a form easily parsed by
+;; non-lisp tools.
+(defun dhelpa-write-desc (desc dest)
+ (let* ((name (package-desc-name desc))
+ (version (package-version-join (package-desc-version desc)))
+ (deps (dhelpa-debianise-deps (package-desc-reqs (dhelpa-filter-pkg-desc desc))))
+ (desc-file (expand-file-name (format "%s.desc" name) dest)))
+ (with-temp-file desc-file
+ (insert (format "ELPA-Name: %s\n" name))
+ (insert (format "ELPA-Version: %s\n" version))
+ (insert (format "ELPA-Requires: %s\n" deps)))))
+
+;;;###autoload
+(defun dhelpa-install-from-buffer (destdir &optional epoch-time)
+ "Install a package from the current buffer into DESTDIR.
+The current buffer is assumed to be a single .el or .tar file
+that follows the packaging guidelines; see info
+node `(elisp)Packaging'. If EPOCH-TIME is non-nil, it specifies
+the time (in seconds since the epoch) to be used in the generated
+autoload files."
+ (interactive "D")
+ (let ((pkg-desc (if (derived-mode-p 'tar-mode)
+ (package-tar-file-info)
+ (dhelpa-buffer-info))))
+ (dhelpa-unpack pkg-desc destdir epoch-time)
+ pkg-desc))
+
+;;;###autoload
+(defun dhelpa-batch-install-file ()
+ "Install third command line argument (an emacs lisp file or tar
+file) into second command line argument (a directory). The
+optional fourth argument specifies a destination for a package
+description file."
+ (apply #'dhelpa-install-file command-line-args-left))
+
+;;;###autoload
+(defun dhelpa-batch-install-directory ()
+ "Install third command line argument (a directory containing a
+multifile elpa package) into second command line argument (a
+directory). An optional third command line argument specifies
+where to make temporary files and write a descriptor file."
+ (apply #'dhelpa-install-directory command-line-args-left))
+
+;;;###autoload
+(defun dhelpa-install-file (dest el-file &optional desc-dir epoch-time)
+ "Install EL-FILE (an emacs lisp file or tar file) into DEST (a directory).
+Optional DESC-DIR specifies where to write a simplified package description file.
+Optional EPOCH-TIME specifies time to use in the generated autoload files."
+ (with-temp-buffer
+ (insert-file-contents-literally el-file)
+ (when (string-match "\\.tar\\'" el-file) (tar-mode))
+ (let ((desc (dhelpa-install-from-buffer (expand-file-name dest) epoch-time)))
+ (when desc-dir
+ (dhelpa-write-desc desc desc-dir)))))
+
+;;;###autoload
+(defun dhelpa-install-directory (dest elpa-dir &optional work-dir epoch-time)
+ "Install ELPA-DIR (an unpacked elpa tarball) into DEST (a directory).
+The directory must either be named `package' or
+`package-version'. If a working directory WORK-DIR is specified,
+cleaning up is the caller's responsibility. Optional EPOCH-TIME
+specifies time to use in generated autoloads files."
+ (unless (file-exists-p
+ (expand-file-name (package--description-file elpa-dir) elpa-dir))
+ (dhelpa-generate-pkg-file elpa-dir))
+ (let ((desc (package-load-descriptor elpa-dir)))
+ (if (not desc)
+ (message "Could not compute version from directory %s" elpa-dir)
+ (let* ((canonical-dir (package-desc-full-name desc))
+ (base-dir (file-name-nondirectory elpa-dir))
+ (parent-dir (file-name-directory elpa-dir))
+ (temp-dir (or work-dir (make-temp-file nil t)))
+ (tar-file (concat (expand-file-name canonical-dir temp-dir) ".tar"))
+ ;; this relies on GNU tar features.
+ (transform-command (concat "--transform=s/"
+ (regexp-quote base-dir) "/" canonical-dir "/")))
+ (call-process "tar" nil nil nil "--create" "-C" parent-dir transform-command
+ "--file" tar-file base-dir)
+ (dhelpa-install-file dest tar-file work-dir epoch-time)
+ (unless work-dir
+ (delete-file tar-file)
+ (delete-directory temp-dir))))))
+
+(defun dhelpa-generate-pkg-file (pkg-dir)
+ "Generate PKG-DIR/foo-pkg.el by consulting PKG-DIR/foo.el."
+ (let* ((pkg-file (expand-file-name (package--description-file pkg-dir) pkg-dir))
+ (root-file (replace-regexp-in-string "-pkg" "" pkg-file))
+ (pkg-desc
+ (condition-case nil
+ (with-temp-buffer
+ (find-file root-file)
+ (dhelpa-buffer-info))
+ (error (progn
+ (message "dh_elpa: couldn't generate -pkg file; please write one")
+ (kill-emacs -1)))))
+ (filtered-pkg-desc (dhelpa-filter-pkg-desc pkg-desc)))
+ ;; although the docstring for `package-generate-description-file'
+ ;; says that it generates a description for single-file packages,
+ ;; there is in fact no difference between the descriptions for
+ ;; single-file and multifile packages
+ (package-generate-description-file filtered-pkg-desc pkg-file)))
+
+;;; dh-elpa.el ends here
diff --git a/dh_elpa.in b/dh_elpa.in
new file mode 100755
index 0000000..5e5828b
--- /dev/null
+++ b/dh_elpa.in
@@ -0,0 +1,345 @@
+#!/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.
+
+B<dh_elpa> will attempt to run ERT and Buttercup test suites using
+dh_elpa_test(1) if the debhelper compat level is 10 or higher. To
+disable this behaviour, or tweak it if it is failing to run the tests
+as they should be run, set environment variables in debian/rules as
+detailed in dh_elpa_test(1).
+
+=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},
+ "fix-autoload-date!" => \$dh{FIXAUTOLOADDATE},
+});
+
+=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
+
+=over 4
+
+=item B<--fix-autoload-date>, B<--no--fix-autoload-date>
+
+Enable (default) or disable munging the dates in Emacs generated
+autoload files to match debian/changelog.
+
+=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});
+$dh{FIXAUTOLOADDATE} = 1 unless defined($dh{FIXAUTOLOADDATE});
+
+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
+ warning "missing ${elpapkg}-pkg.el; will try to generate it";
+ }
+ 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@';
+
+ my @extra_args = ( $tempdir );
+
+ if ($dh{FIXAUTOLOADDATE}) {
+ push @extra_args, get_source_date_epoch();
+ }
+
+ 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, @extra_args);
+ } 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, @extra_args);
+
+ }
+
+ my $desc = read_package_desc ($tempdir,$elpapkg);
+ my $deps = $desc->{'ELPA-Requires'};
+
+ # TODO: addsubstvar fails to add a variable if its blank. So if the
+ # package has no ELPA dependencies, we should tell the user not to
+ # use this substvar in debian/control
+ addsubstvar($package, 'elpa:Depends', $deps);
+
+ if ($dh{BYTECOMPILE}) {
+ 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 SUBSTVARS
+
+dh_elpa currently defines three substvars (cf. deb-substvars(5)) that
+can be used in debian/control
+
+=over 4
+
+=item ${misc:Depends}
+
+These are dependencies needed by every dh_elpa based package.
+
+=item ${misc:Built-Using}
+
+This adds a value suitable for a Built-Using header identifying the
+version of dh_elpa used at build time.
+
+=item ${elpa:Depends}
+
+These are dependencies on other ELPA packages as given in the
+Package-Requires: line of the package's main Emacs Lisp file.
+
+Note that Emacs Lisp dependencies packaged outside the elpa-* dpkg
+namespace must be specified manually. For example, the s.el library
+is provided by the binary package s-el. If dh_elpa adds dependency
+elpa-x where x is an Emacs Lisp binary package outside the elpa-*
+namespace, please file a bug against dh_elpa to have an exclusion
+added.
+
+=back
+
+=head1 EXAMPLES
+
+Here is an example of using the helper in a dh(1) style debian/rules
+
+=over 4
+
+ #!/usr/bin/make -f
+ %:
+ dh $@ --with elpa
+
+=back
+
+Here is an example of a binary package stanza using dh_elpa generated
+substvars
+
+=over 4
+
+ Package: elpa-hello
+ Architecture: all
+ Depends: ${misc:Depends}, ${elpa:Depends}
+ Built-Using: ${misc:Built-Using}
+ Description: Emacs addon to say hello
+ The Emacs editor addon likes to wave and say hello.
+
+=back
+
+=head1 HINTS
+
+=head2 Specifying the package version
+
+If dh_elpa can't determine the package version by looking at *.el
+files (usually because upstream has failed to include the proper
+headers or *-pkg.el file), it will fallback to the
+DEB_UPSTREAM_VERSION and DEB_VERSION_UPSTREAM. An easy way to set one
+of these based on your latest Debian changelog entry is just to
+prepend the following to your rules file:
+
+=over 4
+
+ include /usr/share/dpkg/pkg-info.mk
+ export DEB_VERSION_UPSTREAM
+
+=back
+
+Certain Debian upstream version strings cannot be translated into
+version strings Emacs will accept (see the docstring for the Emacs
+function `version-to-list' for details). dh_elpa will error out if
+the version cannot be translated. You should resort to patching in a
+Package-Version header or adding a *-pkg.el file.
diff --git a/dh_elpa_test b/dh_elpa_test
new file mode 100755
index 0000000..c8ee10b
--- /dev/null
+++ b/dh_elpa_test
@@ -0,0 +1,376 @@
+#!/usr/bin/perl
+
+=head1 NAME
+
+dh_elpa_test - run ELPA package testsuites
+
+=cut
+
+use strict;
+use warnings;
+no warnings "experimental::smartmatch";
+
+=head1 SYNOPSIS
+
+B<dh_elpa_test> [S<I<debhelper options>>] [S<I<--autopkgtest>>] [S<I<pkg-file>>]
+
+=head1 DESCRIPTION
+
+B<dh_elpa_test> is a debhelper program that is responsible for running
+the testsuites of ELPA packages, when those test suites use ERT or
+buttercup(1). dh_auto_test(1) is rarely suitable.
+
+Testing with buttercup(1) will be activated if the package
+build-depends on elpa-buttercup. Testing with ERT will be activated
+if ERT test files can be found. Neither kind of test will be
+activated unless the debhelper compat level is 10 or higher.
+
+B<dh_elpa_test> overrides dh_auto_test(1). If you need to switch back
+to use dh_auto_test(1), use the B<disable> configuration key, below.
+
+=head1 FILES
+
+=over 4
+
+=item debian/elpa-test
+
+Configuration for running the package's test suite. Each line is of
+the form I<key> = I<value>, with I<key> drawn from the list of
+configuration options below.
+
+Note that you should not surround values with double quotation marks.
+This is convenient for including lisp. Configuration values cannot
+cover more than one line. Lines preceded with a # are ignored as
+comments.
+
+This configuration file is optional; in many cases, B<dh_elpa_test>
+can figure out how to run the test suite itself.
+
+=back
+
+=head1 CONFIGURATION KEYS
+
+=over 4
+
+=item B<disable>
+
+If this key is set to any value, dh_elpa(1) will not invoke
+B<dh_elpa_test>.
+
+=item B<buttercup_load_path>
+
+A comma-separated list of directories to add to the load-path when
+buttercup(1) invokes Emacs. Will be passed to buttercup(1) with its
+B<-L> command line argument.
+
+=item B<buttercup_patterns>
+
+A comma-separated list of Emacs regular expressions jointly matching
+all and only the files containing Buttercup tests that you wish to
+run. If this key is not defined, all tests that can be found
+will be run. Will be passed to buttercup(1) with its B<-p> command
+line argument.
+
+=item B<ert_exclude>
+
+A comma-separated list of file globs matching files containing ERT
+tests that should not be run.
+
+The '*' character in globs in this configuration key does NOT match
+'/' directory separators.
+
+=item B<ert_helper>
+
+The name of a *.el file containing Emacs Lisp code that will run the
+ERT test suite. When this key is not defined, B<dh_elpa_test>
+calls the function B<(ert-run-tests-batch-and-exit)>.
+
+Note that this is not the way to load test helpers that do needed work
+but don't actually run the tests. For that, you can use something like
+
+=over 4
+
+ ert_eval = (load-file "test-helper.el")
+
+=back
+
+=item B<ert_eval>
+
+Emacs Lisp code to be run prior to running ERT tests by the Emacs
+instance spawned by B<dh_elpa_test> to run those tests.
+
+=item B<ert_load_path>
+
+A comma-separated list of directories to add to the load-path when
+B<dh_elpa_test> invokes Emacs to run ERT tests.
+
+=item B<autopkgtest_keep>
+
+A comma-separated list of file globs matching files that should not be
+moved out of the source tree before running DEP8 tests (see the
+B<--autopkgtest> option below).
+
+The '*' character in globs in this configuration key matches '/'
+directory separators.
+
+=back
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<--autopkgtest>
+
+Operate in autopkgtest mode. B<dh_elpa_test> will rename non-test *.el
+files so that Emacs will not load them. This ensures that the test
+test the installed binary package rather than the unpacked source
+package.
+
+To exclude files from this removal, specify them in the
+B<autopkgtest_keep> configuration option (see above).
+
+=back
+
+=head1 ENVIRONMENT VARIABLES
+
+Older versions of B<dh_elpa_test> were configured using environment
+variables corresponding to some of the above configuration keys. For
+example, the B<ert_eval> configuration key replaced environment
+variable B<DH_ELPA_TEST_ERT_EVAL>. Their use is now deprecated. If
+the debian/elpa-test file exists, they will be ignored.
+
+=cut
+
+use File::Find::Rule;
+use Array::Utils qw{ array_minus };
+use Text::Glob qw{ glob_to_regex };
+use Config::Tiny;
+
+use Debian::Debhelper::Dh_Lib;
+use Debian::Control;
+
+# ---- Subroutines
+
+# like Find::File::Rule::name, but matches the whole path of the file
+# (relative to cwd when search was started) against the glob, rather
+# than just the basename (also, unlike Find::File::Rule::name, accepts
+# a single glob and no regexps since that's all we need here)
+sub long_name {
+ my $glob = shift;
+
+ return sub {
+ ( undef, undef, my $fullname ) = @_;
+
+ if ( $fullname =~ glob_to_regex($glob) ) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+}
+
+# ---- Script setup
+
+# check command line opts for autopkgtest mode
+my $autopkgtest = ( "--autopkgtest" ~~ @ARGV );
+
+# This checks whether the debhelper compat is 10 or above. With
+# debhelper compat below 9, dh_elpa_test will get run more in more
+# than one sequence, including inside fakeroot, which can cause tests
+# to fail
+if ( get_buildoption("nocheck") || compat(9) ) {
+ exit 0;
+}
+
+# note that we don't need package.elpa-test since we are testing all
+# lisp we can find in the *source* package
+my $options = Config::Tiny->new;
+if ( -f "debian/elpa-test") {
+ verbose_print("I: Ignoring DH_ELPA_TEST_* envvars since debian/elpa-test exists");
+ $options = Config::Tiny->read( "debian/elpa-test" );
+} else {
+ my @envvars = ("DH_ELPA_TEST_DISABLE",
+ "DH_ELPA_TEST_BUTTERCUP_LOAD_PATH",
+ "DH_ELPA_TEST_BUTTERCUP_PATTERNS",
+ "DH_ELPA_TEST_ERT_EXCLUDE",
+ "DH_ELPA_TEST_ERT_HELPER",
+ "DH_ELPA_TEST_ERT_EVAL",
+ "DH_ELPA_TEST_ERT_LOAD_PATH"
+ );
+ foreach my $envvar ( @envvars ) {
+ if (defined $ENV{$envvar}) {
+ my $short = lc(substr($envvar, 13));
+ print "W: environment variable $envvar is deprecated; see dh_elpa_test(1)\n";
+ $options->{_}->{$short} = $ENV{$envvar};
+ }
+ }
+}
+
+my @non_test_files;
+if ($autopkgtest) {
+ # Since we were not invoked by the dh sequencer, we need to check
+ # here whether tests have been disabled. Note that we can't
+ # replace the test in elpa.pm with this one because we can't
+ # (cleanly) disable dh_auto_test from within dh_elpa_test
+ if ( defined $options->{_}->{ "disable" } ) {
+ exit 0;
+ }
+
+ my $rule = File::Find::Rule->new;
+ $rule
+ ->or(File::Find::Rule
+ ->name('.pc', 'debian', '.git')
+ ->directory->prune->discard,
+ File::Find::Rule->new);
+ $rule
+ ->file()
+ ->name( '*.el' )
+ ->none(File::Find::Rule->grep( "ert-deftest" ), # ERT
+ File::Find::Rule->grep( "\\(describe \"" ) # Buttercup
+ );
+
+ if ( defined $options->{_}->{'autopkgtest_keep'} ) {
+ foreach my $glob (split(',', $options->{_}->{'autopkgtest_keep'} )) {
+ # We want the user to be able to say
+ # autopkgtest_keep = test/resources/*
+ # and have that affect all subdirs of resources
+ $Text::Glob::strict_wildcard_slash = 0;
+ # TODO should we do this for ert_exclude too?
+ $rule->not_exec( long_name($glob) );
+ }
+ }
+
+ @non_test_files = $rule->in('.');
+
+ foreach my $old ( @non_test_files ) {
+ my $new = $old =~ s|\.el$|.disabled|r;
+ rename $old, $new or die "Failed to rename: $!\n";
+ }
+}
+
+# these are from dh_elpa
+# TODO have dh_elpa export them so we can import them, instead of copy/paste
+my $dhelpadir="/usr/share/emacs/site-lisp/elpa";
+my $elpadir="/usr/share/emacs/site-lisp/elpa-src";
+
+my $control = Debian::Control->new();
+$control->read("debian/control");
+
+if ($autopkgtest) {
+ # save stderr handle for restoration
+ {
+ no warnings 'once';
+ open(OLDERR, ">&", \*STDERR);
+ }
+
+ # redirect stderr to stdout while we run our tests
+
+ # emacs --batch and ERT itself both produce a lot of output on
+ # stderr even when there has been no error, and adt-run interprets
+ # this as a test failure
+
+ # Recent autopkgtest has a 'allow-stderr' restriction prevents
+ # that interpretation. However, relying on that would require
+ # 'allow-stderr' to be specified in the d/tests/control file for
+ # every package using dh_elpa_test. It's cleaner just to redirect
+ # here.
+
+ open(STDERR, ">&STDOUT");
+ # unbuffer them to ensure lines appear in the right order
+ select STDERR; $| = 1;
+ select STDOUT; $| = 1;
+}
+
+# ---- Buttercup
+
+if ($control->source->Build_Depends->has( "elpa-buttercup" )) {
+ my @args = qw{ buttercup -L . };
+ if (defined $options->{_}->{'buttercup_load_path'}) {
+ foreach my $dir (split(',', $options->{_}->{'buttercup_load_path'})) {
+ push @args, ('-L', "$dir");
+ }
+ }
+ if (defined $options->{_}->{'buttercup_patterns'}) {
+ foreach my $pattern (split(',', $options->{_}->{'buttercup_patterns'})) {
+ push @args, ('-p', "$pattern");
+ }
+ }
+ print_and_doit(@args);
+}
+
+# ---- ERT
+
+my $rule = File::Find::Rule->new;
+$rule
+ ->or(File::Find::Rule
+ ->name('.pc', 'debian')
+ ->directory->prune->discard,
+ File::Find::Rule->new);
+$rule
+ ->file()
+ ->name( '*.el' )
+ ->grep( "ert-deftest" );
+if (defined $options->{_}->{'ert_exclude'}) {
+ foreach my $glob (split(',', $options->{_}->{'ert_exclude'})) {
+ $rule->not_exec( long_name($glob) );
+ }
+}
+my @ert_files = $rule->in('.');
+
+if (@ert_files) {
+ my @args = qw{ emacs -batch -Q -l package };
+ push @args, ("--eval", "(add-to-list 'package-directory-list \"$dhelpadir\")");
+ push @args, ("--eval", "(add-to-list 'package-directory-list \"$elpadir\")");
+ push @args, ("-f", "package-initialize");
+
+ # work around the fact that s-el and dash-el are not packaged with
+ # dh_elpa so aren't in $dhelpadir
+ push @args, ("-L", "/usr/share/emacs/site-lisp/s-el")
+ if ($control->source->Build_Depends->has( "s-el" ));
+ push @args, ("-L", "/usr/share/emacs/site-lisp/dash-el")
+ if ($control->source->Build_Depends->has( "dash-el" ));
+
+ # add the user's load-path entries
+ if (defined $options->{_}->{'ert_load_path'}) {
+ foreach my $dir (split(',', $options->{_}->{'ert_load_path'})) {
+ push @args, ('-L', "$dir");
+ }
+ }
+
+ # make some guesses about where stuff that needs to be in
+ # load-path will be
+ push @args, ("-L", ".");
+ push @args, ("-L", "test") if ( -d "test" );
+ push @args, ("-L", "tests") if ( -d "tests" );
+ # TODO maybe we should just add all dirs containing files in @ert_files?
+
+ # now finish adding the user's stuff
+ push @args, ("--eval", $options->{_}->{'ert_eval'})
+ if (defined $options->{_}->{'ert_eval'});
+ foreach my $ert_file (@ert_files) {
+ push @args, ("-l", "$ert_file");
+ }
+ if (defined $options->{_}->{'ert_helper'}) {
+ push @args, ("-l", $options->{_}->{'ert_helper'});
+ } else {
+ push @args, ("--eval", "(ert-run-tests-batch-and-exit)");
+ }
+
+ print_and_doit(@args);
+}
+
+# ---- Cleanup
+
+END {
+ if ($autopkgtest) {
+ # restore stderr now we've finished running tests
+ open(STDERR, ">&OLDERR");
+
+ # Restore files that we renamed so that we comply with DEP8
+ # rw-build-tree
+ foreach my $new ( @non_test_files ) {
+ my $old = $new =~ s|\.el$|.disabled|r;
+ rename $old, $new or die "Failed to rename: $!\n";
+ }
+ }
+}
diff --git a/elpa.pm b/elpa.pm
new file mode 100755
index 0000000..a43f395
--- /dev/null
+++ b/elpa.pm
@@ -0,0 +1,29 @@
+#!/usr/bin/perl
+# debhelper sequence file for dh_elpa script
+
+use warnings;
+use strict;
+use Debian::Debhelper::Dh_Lib;
+use Dpkg::Version;
+use Module::Metadata;
+use Config::Tiny;
+
+insert_after("dh_install", "dh_elpa");
+
+# check dh_make_perl version is new enough for dh_elpa_test
+my $info = Module::Metadata->new_from_module("Debian::Control");
+my $version = Dpkg::Version->new($info->version());
+
+my $options;
+$options = Config::Tiny->read( "debian/elpa-test" )
+ if ( -f "debian/elpa-test" );
+
+if ( $version >= "0.90"
+ && !defined $options->{_}->{ "disable" }
+ && !defined $ENV{ 'DH_ELPA_TEST_DISABLE' }
+ ) {
+ insert_after("dh_auto_test", "dh_elpa_test");
+ remove_command("dh_auto_test");
+}
+
+1;
diff --git a/emacsen-common/compat b/emacsen-common/compat
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/emacsen-common/compat
@@ -0,0 +1 @@
+2
diff --git a/emacsen-common/install b/emacsen-common/install
new file mode 100755
index 0000000..2e11984
--- /dev/null
+++ b/emacsen-common/install
@@ -0,0 +1,56 @@
+#!/bin/sh
+# /usr/lib/emacsen-common/packages/install/${PACKAGE}
+
+set -e
+
+ELPA_DIR=#ELPAPACKAGE#-#ELPAVERSION#
+
+FLAVOR=$1
+case $FLAVOR in
+ emacs)
+ exit 0
+ ;;
+ emacs2[0123]*)
+ echo install/${ELPA_DIR}: Skipping obsolete emacs ${FLAVOR}
+ exit 0
+ ;;
+ xemacs*)
+ echo install/${ELPA_DIR}: Skipping unsupported emacs ${FLAVOR}
+ exit 0
+ ;;
+ *)
+ echo install/${ELPA_DIR}: Handling install of emacsen flavor ${FLAVOR}
+esac
+
+src_dir=/usr/share/emacs/site-lisp/elpa-src
+el_dir=$src_dir/${ELPA_DIR}/
+elc_dir=/usr/share/${FLAVOR}/site-lisp/elpa/${ELPA_DIR}/
+
+export EMACSLOADPATH
+EMACSLOADPATH="/usr/share/emacs/site-lisp:"
+
+echo install/${ELPA_DIR}: byte-compiling for ${FLAVOR}
+
+[ -d ${elc_dir} ] || mkdir -p ${elc_dir}
+
+# Create symlinks to the .el files (see section 6E in debian-emacs
+# polcy). This makes complation easy, and also allows find-function
+# and find-library to work properly. Also link all other top level
+# files and directories into the flavor directory
+(cd ${elc_dir} && ln -sf ${el_dir}/* .)
+
+# Byte compile them
+(cd ${elc_dir}
+ set +e
+ ${FLAVOR} -q -batch -l package \
+ --eval "(add-to-list 'package-directory-list \"$src_dir\")" \
+ -f package-initialize -f batch-byte-compile *.el > Install.log 2>&1
+ if test $? -ne 0
+ then
+ cat Install.log
+ exit 1
+ fi
+ set -e
+ gzip -9f Install.log)
+
+exit 0;
diff --git a/emacsen-common/remove b/emacsen-common/remove
new file mode 100755
index 0000000..56ba5b6
--- /dev/null
+++ b/emacsen-common/remove
@@ -0,0 +1,38 @@
+#!/bin/sh
+# /usr/lib/emacsen-common/packages/remove/foo
+set -e
+
+ELPA_DIR=#ELPAPACKAGE#-#ELPAVERSION#
+
+FLAVOR=$1
+elpa_root="/usr/share/${FLAVOR}/site-lisp/elpa"
+elc_dir="${elpa_root}/${ELPA_DIR}"
+
+FLAVOR=$1
+case $FLAVOR in
+ emacs)
+ exit 0
+ ;;
+ emacs2[0123]*)
+ echo remove/${ELPA_DIR}: Skipping obsolete emacs ${FLAVOUR}
+ exit 0
+ ;;
+ xemacs*)
+ echo remove/${ELPA_DIR}: Skipping unsupported emacs ${FLAVOUR}
+ exit 0
+ ;;
+ *)
+ echo remove/${ELPA_DIR}: Handling removal of emacsen flavor ${FLAVOR}
+esac
+
+echo dh-elpa: purging flavor specific files for ${FLAVOR}
+rm -f ${elc_dir}/*.elc
+[ -d ${elc_dir} ] && find ${elc_dir} -type l -delete
+rm -f ${elc_dir}/Install.log*
+if test -e "${elc_dir}"
+then
+ rmdir --ignore-fail-on-non-empty "${elc_dir}"
+ rmdir --ignore-fail-on-non-empty "${elpa_root}"
+fi
+
+exit 0;
diff --git a/notes.org b/notes.org
new file mode 100644
index 0000000..5e08b7f
--- /dev/null
+++ b/notes.org
@@ -0,0 +1,39 @@
+* package.el
+
+- package-directory-list (v)
+
+ list of additional directories containing elpa packages. In
+ particular this has an emacs version specific directory where we can
+ install byte compiled files.
+
+ Note that having the same package-$version in two different
+ directories in this list seems not to work out well, since the
+ ordering of the constructed load-path is backwards from the list. Or
+ something.
+
+- package-unpack (f)
+
+ does the actual installation, using dynamically bound
+ *package-user-dir*. The current version is safe to call without
+ network access, but it's probably considered internal.
+
+* workflow
+** at package build time
+- install a copied/modified package-unpack into
+
+ $(DESTDIR)/usr/share/emacs/site-lisp/elpa-src
+
+ This is intentionally not ending in elpa, because of the problems
+ discussed immediately above with multiple versions of a package.
+
+- install emacsen-common helper scripts into
+ $(DESTDIR)/usr/lib/emacsen-common/packages/{compat,install,remove}
+
+- add postinst / prerm cookies to maintainer scripts
+
+** at package install time
+- prerm and postinst as per a normal emacsen-common using package
+- don't install a startup file into /etc; that's one of our selling
+ points.
+
+