[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Proposal: emacsen and add-on package handling



I'm posting this to both debian-devel and debian-policy because I'm
fairly certain that I won't catch all the relevant people if I just
post it to debian-policy where it belongs.  Please redirect *all*
followups to debian-policy.

[Mark and James, I've made a few modifications to simplify which
 add-on scripts get called when, but essentially this is the same
 thing I showed you before. ]

Sorry for the length, but this is a non-trivial issue to explain...

Without further delay, there was some discussion a while ago about
what to do about add-on packages, auto-compilation, etc.  The goal
here is clean support of the simultaneous install of the various
emacsen and their add-on packages.  There seemed like three primary
solutions along a spectrum:

  1) Require every package that's not completely emacsen independent
     to have multiple versions: tm-emacs19, tm-emacs20, tm-xemacs, or
     just have one version containing all the files for all the
     flavors of emacs.  This was "foolproof" but a huge waste of
     space, and it required every maintainer to have all the flavors
     installed.

  2) Have an auto-compilation mechanism that allows packages to
     register .el files so that the .elc files would be automatically
     handled whenever an emacsen was installed or removed.  This
     didn't provide enough sophistication for a number of important
     and complex packages, and people complained about byte compiling
     at install time being too expensive.

  3) Punt.  Provide enough structure so that add-on package
     maintainers can find out when the various emacsen are installed
     or removed, and provide them with a set of "load" locations that
     will allow them to control which emacs flavor loads what things
     when in cases where it's important.  This is both the most
     flexible and the least hassle to implement (i.e. I've nearly
     finished it :>).

If you hadn't guessed, I'm proposing an implementation of 3.

First, some terminology: when I say <emacs> below I mean
{emacs,xemacs20,emacs19,emacs20}.  When I say <flavor>, I mean just
one of (xemacs20 emacs19 emacs20).

1) New common package.

   There will be a new package, emacsen-common, which all of the
   various flavors of emacs will depend on, and which will contain
   emacs flavor independent files like debian-rundir and all the
   infrastructure implementing our mechanism for dealing with all the
   various emacsen.

2) Flavor indication

   Each emacs binary will set the variable debian-flavor to be the
   same as the name of the debian-package.  For example, the emacs20
   package would do this in startup.el: (setq debian-flavor 'emacs20).

3) Emacs startup strategy

  We'll have the following startup files/directories:

  emacsen-common: /etc/emacs/site-start.{el,d}
  xemacs20:       /etc/xemacs20/site-start.d
  emacs19:        /etc/emacs19/site-start.d
  emacs20:        /etc/emacs20/site-start.d

  /etc/emacs/site-start.el will now be a conffile, and will be owned
  by a new package emacsen-common.  It will no longer have anything in
  it at all by default, and the local admin can use it for whatever.

  The load-path for a given emacs flavor will include /etc/<flavor>
  and /etc/emacs in that order, and on startup each emacsen will call
  (debian-startup) and then load "site-start".  This means that
  /etc/emacs/site-start.el will be loaded if it exists, unless there's
  an /etc/<flavor>/site-start.el{,c} or /etc/emacs/site-start.elc
  which will take precedence.

  debian-startup will, for now, just turn into a call to
  debian-run-directories whose behavior is slightly different from the
  current debian-run-directory.

  debian-run-directories will take the union of all the file base
  names (i.e. without any .el or .elc extension, and without the
  directory component: i.e. /etc/xemacs/site-start.d/50foo.elc =>
  foo).  Then then emacs load-path will be temporarily augmented to
  include /etc/<flavor>/site-start.d and /etc/emacs/site-start.d in
  that order.  Once the list of file base names has been determined,
  emacs will call (load base-name) on each of them in alphabetical
  order.  This means that .elc files will take precedence over .el
  files in a given directory, and files in the <flavor> site-start.d
  directory will take precedence over those in the emacs common
  directory.

4) Code locations

  In addition to the /etc/<emacs>/site-start* directories, we'll have
  the following directories (their use will be described shortly).

  emacsen-common: /usr/lib/emacs/site-lisp/
  xemacs20:       /usr/lib/xemacs20/site-lisp/
  emacs19:        /usr/lib/emacs19/site-lisp/
  emacs20:        /usr/lib/emacs20/site-lisp/

  These will be treated as part of the normal emacsen load path with
  the <flavor> dir taking precedence over the emacs (common) dir.

5) add-on package support (there are examples later which make this
   much clearer)

  A) Each package may place a file named the same as the package into
     /usr/lib/<emacs>/packages/emacsen-install/ and another into
     /usr/lib/<emacs>/packages/emacsen-remove/ and the package must
     call
  
       /usr/lib/emacsen-common/emacs-package-install foo

     in the postinst and 

       /usr/lib/emacsen-common/emacs-package-remove foo

     in the prerm (or do I mean postrm?).

     For now, "emacs-package-install foo" will conceptually just turn
     into a call for each installed flavor to

       /usr/lib/emacsen-common/packages/<flavor>/install/foo

     if it exists, or

       /usr/lib/emacsen-common/packages/emacs/install/foo

     otherwise.  The arguments to these scripts will be the flavor
     being installed followed by a list of other flavors already
     installed, potentially including the current one.

     emacs-package remove would do the symmetric thing.

  B) Each emacsen main package will have a call to 
     "/usr/lib/emacsen-common/emacs-install <flavor> in its postinst
     and a call to "/usr/lib/emacsen-common/emacs-remove <flavor> in
     it's prerm.

     The emacs-install script (for now) will be conceptually similar to

       /usr/lib/emacsen-common/emacs-package-install <pkg>

     for each installed <pkg>, but might do more later.  Similarly,
     emacs-remove would just be the same as

       /usr/lib/emacsen-common/emacs-package-install <pkg>

     for now.  Don't forget that the argument list to the add-on
     package install scripts will indicate both the flavor being
     installed, and the flavors already installed.  In this case,
     since we're actually installing a flavor, the first argument
     won't appear in the subsequent arguments.

     emacs-remove will just do the reverse of emacs-install.

  C) Each add-on package has the right to place files into the
     following directories:

       /etc/<emacs>/site-start.d
       /usr/lib/<emacs>/site-lisp/<package-name>

6) Mandatory binary symlink

   Each emacsen main package will have a symlink
   /usr/bin/<package-name> to /usr/bin/<emacs-binary> so that when
   add-on package install/remove scripts are called, they can just use
   /usr/bin/$ARGV[0] to get the right binary for byte-compilation.

7) Virtual package

   Each emacsen main package will "Provides: emacsen".  It would be
   nice to use "emacs", but for historical reasons, and given the
   nature of the packaging system, we can't.

   Packages that just need to make sure some flavor of emacs is
   installed will just "Depends: emacsen".

That's it.  I think this gives the add-on package maintainers the
flexibility they need to be able to DTRT, and I think the common case
won't be all that difficult.

Examples:

1) Xemacs20 and the add-on packages tm and auctex are already installed,
   and now someone installs emacs20.

   In it's postinst, emacs20 would make this call:
     /usr/lib/emacsen-common/emacs-install emacs20
   which would result in a call to
     /usr/lib/emacsen-common/packages/emacs20/install/auctex emacs20 xemacs20
   if it exists, and
     /usr/lib/emacsen-common/packages/emacs/install/auctex emacs20 xemacs20
   otherwise, and a call to
     /usr/lib/emacsen-common/packages/emacs20/install/tm emacs20 xemacs20
   if it exists, and
     /usr/lib/emacsen-common/packages/emacs/install/tm emacs20 xemacs20
   otherwise.
    
2) Now, given (1), assume that someone removes xemacs20.

   In it's postinst, xemacs20 would make this call:
     /usr/lib/emacsen-common/emacs-remove xemacs20
   which would result in a call to
     /usr/lib/emacsen-common/packages/emacs20/remove/auctex xemacs20 \
       emacs20 xemacs20
   if it exists, and
     /usr/lib/emacsen-common/packages/emacs/remove/auctex xemacs20 \
       emacs20 xemacs20
   otherwise, and a call to
     /usr/lib/emacsen-common/packages/emacs20/remove/tm xemacs20 \
       emacs20 xemacs20
   if it exists, and
     /usr/lib/emacsen-common/packages/emacs/remove/tm xemacs20 \
       emacs20 xemacs20
   otherwise.
    
3) Assume (1) again, and that someone removes tm.

   Nothing particular happens, but tm is responsible for cleaning up
   any files it put into it's allowed locations:

     /etc/<emacs>/site-start.d/
     /usr/lib/<emacs>/site-lisp/tm

Thanks for your patience.

-- 
Rob Browning <rlb@cs.utexas.edu>
PGP fingerprint = E8 0E 0D 04 F5 21 A0 94  53 2B 97 F5 D6 4E 39 30


--
TO UNSUBSCRIBE FROM THIS MAILING LIST: e-mail the word "unsubscribe" to
debian-devel-request@lists.debian.org . 
Trouble?  e-mail to templin@bucknell.edu .


Reply to: