From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Artur Malabarba Newsgroups: gmane.emacs.devel Subject: [ELPA] New package: package-fixes Date: Sat, 12 Dec 2015 23:07:43 +0000 Message-ID: <87zixfmfk0.fsf@gmail.com> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1449961697 4255 80.91.229.3 (12 Dec 2015 23:08:17 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 12 Dec 2015 23:08:17 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sun Dec 13 00:08:10 2015 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1a7tGp-0004KM-RG for ged-emacs-devel@m.gmane.org; Sun, 13 Dec 2015 00:08:08 +0100 Original-Received: from localhost ([::1]:53285 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a7tGo-00078i-SJ for ged-emacs-devel@m.gmane.org; Sat, 12 Dec 2015 18:08:06 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:46087) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a7tGb-00078R-9R for emacs-devel@gnu.org; Sat, 12 Dec 2015 18:07:54 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a7tGW-00066P-Jk for emacs-devel@gnu.org; Sat, 12 Dec 2015 18:07:53 -0500 Original-Received: from mail-wm0-x235.google.com ([2a00:1450:400c:c09::235]:36258) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a7tGW-00066D-9m for emacs-devel@gnu.org; Sat, 12 Dec 2015 18:07:48 -0500 Original-Received: by mail-wm0-x235.google.com with SMTP id n186so74672372wmn.1 for ; Sat, 12 Dec 2015 15:07:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:subject:date:message-id:mime-version:content-type; bh=ZNFW24zp0DvTsbAN0M9UfbvBbiwx6PuSV9ZYQ8HsDKo=; b=wfzEt+0L5f6hg+6Qm4Rmu8I6Z5BiAvOtPsXsO1MckD0ukFiHxxOrUfwXQErHFoszKN nYrXyHANFrSCs8OGRmmI9TpaK1uOIh4FK6yWt2txC7ot2mbERSuAdSWLQEl0TEkA4v57 owpcFLJSrES38/75ttCDMtBA2WUFTBdEM8OBLlaAtEDxJylEVTnh1y3j2nbqik47PGO0 9Z+nJU9M8FbSqEyTYIE5VtRA8OR5bqLlGlatloAJbm0H8QuZPQyNnRjyZpYuz4u576KN NWg5mg+NQ9qhWzUL6vs/sW+XcpVo8jXTium3kkqVppsJ4B4BgbPeFuIlFfedcj4PnEtR iisA== X-Received: by 10.28.215.211 with SMTP id o202mr14212090wmg.85.1449961667302; Sat, 12 Dec 2015 15:07:47 -0800 (PST) Original-Received: from Gandalf-Linux.gmail.com (host-78-151-181-176.as13285.net. [78.151.181.176]) by smtp.gmail.com with ESMTPSA id q4sm22955118wja.6.2015.12.12.15.07.45 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 12 Dec 2015 15:07:45 -0800 (PST) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:400c:c09::235 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:196177 Archived-At: I've pushed some code to elpa.git (also below) for a package that should fix a rather aggravating bug in package.el. Namely, that changing the behaviour of macros (or even just defining new macros) can lead to bad compilation issues during upgrades. I'll bump its version to 0.1 (thus releasing it) if noone sees any issues. This bug is fixed in emacs-25, package-fixes.el backports this fix to Emacs 24.x. There will be plenty of users of Emacs 24.x for years to come, so I wanted to provide packages with a way around this issue (specially because some packages are already finding worryingly hacky ways around it). The goal here is that a package can add (package-fixes "0.1") to its dependencies and rest assured that this bug won't happen anymore (package-fixes.el does nothing if the user is running emacs-25). This can futurely be used to fix new package.el bugs we encounter. ------------------------------ ;;; package-fixes.el --- package.el bug fixes ported to older Emacsen -*- lexical-binding: t; -*- ;; Copyright (C) 2015 Free Software Foundation, Inc. ;; Author: Artur Malabarba ;; Keywords: tools ;; Version: 0 ;; This program 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. ;; This program 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 this program. If not, see . ;;; Commentary: ;; This package fixes some critical bugs in package.el 1.0.1 which ;; cause bad .elc files to be created during package upgrades when a ;; macro changes. It is designed to be required as a dependency by ;; packages whose installation is affected by these bugs. ;; This package can be safely installed on Emacs >= 25, in which ;; case it does nothing. ;;; Code: ;;; Emacs < 25 (unless (fboundp 'package--list-loaded-files) (require 'package) (require 'find-func) (declare-function package-fixes--autoloads-file-name "package-fixes") (declare-function find-library-name "find-func") (declare-function package-fixes--list-loaded-files "package-fixes") (declare-function package-fixes--activate-autoloads-and-load-path "package-fixes") ;; None of these functions are defined in Emacs < 25.1. Defining ;; them here doesn't actually do anything yet, they will be used by ;; the advices below. (defun package-fixes--autoloads-file-name (pkg-desc) "Return the absolute name of the autoloads file, sans extension. PKG-DESC is a `package-desc' object." (expand-file-name (format "%s-autoloads" (package-desc-name pkg-desc)) (package-desc-dir pkg-desc))) (defun package-fixes--activate-autoloads-and-load-path (pkg-desc) "Load the autoloads file and add package dir to `load-path'. PKG-DESC is a `package-desc' object." (let* ((old-lp load-path) (pkg-dir (package-desc-dir pkg-desc)) (pkg-dir-dir (file-name-as-directory pkg-dir))) (with-demoted-errors "Error loading autoloads: %s" (load (package-fixes--autoloads-file-name pkg-desc) nil t)) (when (and (eq old-lp load-path) (not (or (member pkg-dir load-path) (member pkg-dir-dir load-path)))) ;; Old packages don't add themselves to the `load-path', so we have to ;; do it ourselves. (push pkg-dir load-path)))) (defun package-fixes--list-loaded-files (dir) "Recursively list all files in DIR which correspond to loaded features. Returns the `file-name-sans-extension' of each file, relative to DIR, sorted by most recently loaded last." (let* ((history (delq nil (mapcar (lambda (x) (let ((f (car x))) (and f (file-name-sans-extension f)))) load-history))) (dir (file-truename dir)) ;; List all files that have already been loaded. (list-of-conflicts (delq nil (mapcar (lambda (x) (let* ((file (file-relative-name x dir)) ;; Previously loaded file, if any. (previous (ignore-errors (file-name-sans-extension (file-truename (find-library-name file))))) (pos (when previous (member previous history)))) ;; Return (RELATIVE-FILENAME . HISTORY-POSITION) (when pos (cons (file-name-sans-extension file) (length pos))))) (directory-files-recursively dir "\\`[^\\.].*\\.el\\'"))))) ;; Turn the list of (FILENAME . POS) back into a list of features. Files in ;; subdirectories are returned relative to DIR (so not actually features). (let ((default-directory (file-name-as-directory dir))) (mapcar (lambda (x) (file-truename (car x))) (sort list-of-conflicts ;; Sort the files by ascending HISTORY-POSITION. (lambda (x y) (< (cdr x) (cdr y)))))))) (defun package-fixes--load-files-for-activation (pkg-desc reload) "Load files for activating a package given by PKG-DESC. Load the autoloads file, and ensure `load-path' is setup. If RELOAD is non-nil, also load all files in the package that correspond to previously loaded files." (let* ((loaded-files-list (when reload (package-fixes--list-loaded-files (package-desc-dir pkg-desc))))) ;; Add to load path, add autoloads, and activate the package. (package-fixes--activate-autoloads-and-load-path pkg-desc) ;; Call `load' on all files in `package-desc-dir' already present in ;; `load-history'. This is done so that macros in these files are updated ;; to their new definitions. If another package is being installed which ;; depends on this new definition, not doing this update would cause ;; compilation errors and break the installation. (with-demoted-errors "Error in package--load-files-for-activation: %s" (mapc (lambda (feature) (load feature nil t)) ;; Skip autoloads file since we already evaluated it above. (remove (file-truename (package-fixes--autoloads-file-name pkg-desc)) loaded-files-list))))) ;;; 24.1, 24.2, 24.3 (defadvice package--make-autoloads-and-compile (around fix-package--make-autoloads-and-compile (name pkg-dir) activate) "Fixed `package--make-autoloads-and-compile'. Behave the same as `package--make-autoloads-and-compile', except it uses `package-fixes--load-files-for-activation' instead of just loading the autoloads file." (package-generate-autoloads name pkg-dir) (package-fixes--load-files-for-activation pkg-desc :reload) (let ((load-path (cons pkg-dir load-path))) ;; We must load the autoloads file before byte compiling, in ;; case there are magic cookies to set up non-trivial paths. (byte-recompile-directory pkg-dir 0 t))) ;;; 24.4, 24.5 (defadvice package--compile (after fix-package--compile (pkg-desc) activate) "Like `package--compile', but reload package first. Uses `package-fixes--load-files-for-activation' to reload files." (package-activate-1 pkg-desc) (package-fixes--load-files-for-activation pkg-desc :reload) (byte-recompile-directory (package-desc-dir pkg-desc) 0 t))) (provide 'package-fixes) ;;; package-fixes.el ends here