unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Achim Gratz <Stromeko@nexgo.de>
To: emacs-devel@gnu.org
Subject: Re: Elpa packages and macro dependencies.
Date: Thu, 16 Oct 2014 23:05:31 +0200	[thread overview]
Message-ID: <8761fjsp2c.fsf@Rainer.invalid> (raw)
In-Reply-To: jwv61fjrjwy.fsf-monnier+emacs@gnu.org

Stefan Monnier writes:
> Indeed.  I think your situation could also be handled correctly by my
> suggestion:
>
>    E.g. we could add to bytecomp.el the ability to force `require' to
>    reload a package if it's not already loaded from the file that
>    locate-library returns.

That doesn't work when defcustoms, autoloads and defvars change in the
new version.  I've been through this in my attempts to make Org more
resistant to such mishaps.  In a proper package system there was a way
to unload a package cleanly, then fly in the new package and plug it in.
We don't have that now, instead we have "packages" that really aren't
(because they are still built-in) and some infrastructure is missing to
unload and reload a complete package cleanly.

This is what is used in Org to get rid of any built-in stuff that might
be delivered with the Emacs before running batch tests:

--8<---------------cut here---------------start------------->8---
;;
;; Remove Org remnants built into Emacs
;;

;; clean load-path
(setq load-path
      (delq nil (mapcar
                 (function (lambda (p)
                             (unless (string-match "lisp\\(/packages\\)?/org$" p)
                               p)))
                 load-path)))
;; remove property list to defeat cus-load and remove autoloads
(mapatoms (function  (lambda (s)
                       (let ((sn (symbol-name s)))
                         (when (string-match "^\\(org\\|ob\\|ox\\)\\(-.*\\)?$" sn)
                           (setplist s nil)
                           (when (eq 'autoload (car-safe s))
                             (unintern s)))))))

;; we should now start from a clean slate
--8<---------------cut here---------------end--------------->8---

This has had little exposure beyond actual batch testing, but something
very close to this might actually work in most cases.  For bytecomp the
critical part would be to know which features and namespaces to nuke,
but if it's only used for packages the information could be delivered
with the package metadata perhaps.

Here's an experimental advice (not currently implemented in Org) to
recognize a changed load-path and re-load a feature in this case to take
care of some issues at runtime:

--8<---------------cut here---------------start------------->8---
;; some parts of Org might already have been used from a different
;; place, try to reload these parts from the current load-path
(require 'loadhist)
(defadvice require (before org-require-reload-when-shadowed
			   (feature &optional filename noerror)
			   activate compile preactivate)
  "Check whether a required feature has been shadowed by changing
`load-path' after it has been loaded and reload that feature from
current load-path in this case."
  (when (featurep feature)
    (let ((feature-name (or filename (symbol-name feature))))
      (when (string-match "^\\(org\\|ob\\)\\(-.*\\)?$" feature-name)
	(let ((feature-lib  (file-name-directory (or (locate-library feature-name) "")))
	      (feature-dir  (file-name-directory (feature-file feature))))
	  ;(message "require-reload-when shadowed %s\n\t%s\n\t%s" feature-name feature-lib feature-dir)
	  (when (not (string= feature-lib feature-dir))
	    (message "Reloading %s" feature-name)
	    (unload-feature feature t)))))))
--8<---------------cut here---------------end--------------->8---

Using just unload it doesn't catch some corner cases with defcustom and
autoloads as mentioned before so it would likely not be good enough for
byte-compiling, but for "close enough" versions in the load-path this
actually fixes up things without getting in the way.

And finally org-reload (as currently implemented in Org) that tries to
do the right thing or at least warn if the load-path is set up in
strange ways so that not all features from Org are found in the same
place:

--8<---------------cut here---------------start------------->8---
;;;###autoload
(defun org-reload (&optional uncompiled)
  "Reload all org lisp files.
With prefix arg UNCOMPILED, load the uncompiled versions."
  (interactive "P")
  (require 'loadhist)
  (let* ((org-dir     (org-find-library-dir "org"))
	 (contrib-dir (or (org-find-library-dir "org-contribdir") org-dir))
	 (feature-re "^\\(org\\|ob\\|ox\\)\\(-.*\\)?")
	 (remove-re (mapconcat 'identity
			       (mapcar (lambda (f) (concat "^" f "$"))
				       (list (if (featurep 'xemacs)
						 "org-colview"
					       "org-colview-xemacs")
					     "org" "org-loaddefs" "org-version"))
			       "\\|"))
	 (feats (delete-dups
		 (mapcar 'file-name-sans-extension
			 (mapcar 'file-name-nondirectory
				 (delq nil
				       (mapcar 'feature-file
					       features))))))
	 (lfeat (append
		 (sort
		  (setq feats
			(delq nil (mapcar
				   (lambda (f)
				     (if (and (string-match feature-re f)
					      (not (string-match remove-re f)))
					 f nil))
				   feats)))
		  'string-lessp)
		 (list "org-version" "org")))
	 (load-suffixes (when (boundp 'load-suffixes) load-suffixes))
	 (load-suffixes (if uncompiled (reverse load-suffixes) load-suffixes))
	 load-uncore load-misses)
    (setq load-misses
	  (delq 't
		(mapcar (lambda (f)
			  (or (org-load-noerror-mustsuffix (concat org-dir f))
			      (and (string= org-dir contrib-dir)
				   (org-load-noerror-mustsuffix (concat contrib-dir f)))
			      (and (org-load-noerror-mustsuffix (concat (org-find-library-dir f) f))
				   (add-to-list 'load-uncore f 'append)
				   't)
			      f))
			lfeat)))
    (if load-uncore
	(message "The following feature%s found in load-path, please check if that's correct:\n%s"
		 (if (> (length load-uncore) 1) "s were" " was") load-uncore))
    (if load-misses
	(message "Some error occurred while reloading Org feature%s\n%s\nPlease check *Messages*!\n%s"
		 (if (> (length load-misses) 1) "s" "") load-misses (org-version nil 'full))
      (message "Successfully reloaded Org\n%s" (org-version nil 'full)))))
--8<---------------cut here---------------end--------------->8---


Regards,
Achim.
-- 
+<[Q+ Matrix-12 WAVE#46+305 Neuron microQkb Andromeda XTk Blofeld]>+

Wavetables for the Waldorf Blofeld:
http://Synth.Stromeko.net/Downloads.html#BlofeldUserWavetables




  parent reply	other threads:[~2014-10-16 21:05 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-16 16:06 Elpa packages and macro dependencies bruce.connor.am
2014-10-16 16:09 ` Glenn Morris
2014-10-16 16:56   ` bruce.connor.am
2014-10-16 16:59   ` Thierry Volpiatto
2014-10-16 17:44   ` Stefan Monnier
2014-10-16 17:57     ` bruce.connor.am
2014-10-16 19:57       ` Stefan Monnier
2014-10-17  8:28         ` bruce.connor.am
2014-10-17 15:54           ` bruce.connor.am
2014-10-17 16:36             ` Stefan Monnier
2014-10-17 21:24               ` bruce.connor.am
2014-10-18 21:41                 ` Stefan Monnier
2014-10-20  8:58                   ` Nicolas Richard
2014-10-20  9:33                     ` Artur Malabarba
2014-10-20 19:04                       ` Stefan Monnier
2014-10-20 20:25                         ` Artur Malabarba
2014-10-20 20:40                           ` Stefan Monnier
2014-11-13 11:57                       ` Artur Malabarba
2014-11-13 17:34                         ` Stefan Monnier
2014-12-10 18:38                           ` Artur Malabarba
2014-12-10 19:14                             ` Stefan Monnier
2014-10-19  6:57               ` Achim Gratz
2014-10-20 15:29                 ` Stefan Monnier
2014-10-20 16:34                   ` Achim Gratz
2014-10-20 18:00                     ` Stefan Monnier
2014-10-20 19:16                       ` Achim Gratz
2014-10-20 21:04                         ` Stefan Monnier
2014-10-21 17:41                           ` Achim Gratz
2014-10-16 21:05     ` Achim Gratz [this message]
2014-10-17  3:03       ` Stefan Monnier
2014-10-17  8:01         ` Achim Gratz
2014-10-17 12:03           ` Phillip Lord
2014-10-17 13:51             ` Tom Tromey
2014-10-17 12:39           ` Stefan Monnier
2014-10-17  8:39       ` bruce.connor.am

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8761fjsp2c.fsf@Rainer.invalid \
    --to=stromeko@nexgo.de \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).