From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Stephen Leake Newsgroups: gmane.emacs.devel Subject: Re: installed packages long description. Date: Thu, 13 Dec 2018 06:49:59 -0800 Message-ID: <86mup9eb1k.fsf@stephe-leake.org> References: <868t14kazo.fsf@stephe-leake.org> <86k1kiilm0.fsf@stephe-leake.org> <86efapi3lt.fsf@stephe-leake.org> <86r2enecto.fsf@stephe-leake.org> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1544712676 12892 195.159.176.226 (13 Dec 2018 14:51:16 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Thu, 13 Dec 2018 14:51:16 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.0.90 (windows-nt) To: emacs-devel Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu Dec 13 15:51:12 2018 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gXSKV-0003GU-Tv for ged-emacs-devel@m.gmane.org; Thu, 13 Dec 2018 15:51:12 +0100 Original-Received: from localhost ([::1]:53052 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXSMc-0002kj-HX for ged-emacs-devel@m.gmane.org; Thu, 13 Dec 2018 09:53:22 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:33546) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXSJY-0000BH-AM for emacs-devel@gnu.org; Thu, 13 Dec 2018 09:50:13 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXSJV-0007Zc-2R for emacs-devel@gnu.org; Thu, 13 Dec 2018 09:50:12 -0500 Original-Received: from smtp121.ord1d.emailsrvr.com ([184.106.54.121]:44248) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXSJU-0007Kk-Ri for emacs-devel@gnu.org; Thu, 13 Dec 2018 09:50:09 -0500 Original-Received: from smtp24.relay.ord1d.emailsrvr.com (localhost [127.0.0.1]) by smtp24.relay.ord1d.emailsrvr.com (SMTP Server) with ESMTP id 91481A0188 for ; Thu, 13 Dec 2018 09:50:01 -0500 (EST) X-Auth-ID: board-president@tomahawk-creek-hoa.com Original-Received: by smtp24.relay.ord1d.emailsrvr.com (Authenticated sender: board-president-AT-tomahawk-creek-hoa.com) with ESMTPSA id 1C359A046F for ; Thu, 13 Dec 2018 09:50:01 -0500 (EST) X-Sender-Id: board-president@tomahawk-creek-hoa.com Original-Received: from Takver4 ([UNAVAILABLE]. [76.77.182.20]) (using TLSv1.2 with cipher AES256-GCM-SHA384) by 0.0.0.0:25 (trex/5.7.12); Thu, 13 Dec 2018 09:50:01 -0500 In-Reply-To: (Stefan Monnier's message of "Tue, 11 Dec 2018 21:02:30 -0500") X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 184.106.54.121 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 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" Xref: news.gmane.org gmane.emacs.devel:231796 Archived-At: --=-=-= Content-Type: text/plain Stefan Monnier writes: >> I'll submit a patch for review before committing anything. > > Thanks. Attached. I'm not clear if this rates a NEWS entry? -- -- Stephe --=-=-= Content-Type: text/x-patch; charset=utf-8 Content-Disposition: inline; filename=pkg-long-desc.diff Content-Transfer-Encoding: quoted-printable diff --git a/doc/lispref/package.texi b/doc/lispref/package.texi index 37c1ee6697..730decc378 100644 --- a/doc/lispref/package.texi +++ b/doc/lispref/package.texi @@ -22,6 +22,7 @@ Packaging * Simple Packages:: How to package a single .el file. * Multi-file Packages:: How to package multiple files. * Package Archives:: Maintaining package archives. +* Archive Web Server:: Interfacing to an archive web server. @end menu =20 @node Packaging Basics @@ -249,7 +250,8 @@ Multi-file Packages @end defun =20 If the content directory contains a file named @file{README}, this -file is used as the long description. +file is used as the long description (overriding any @samp{;;; +Commentary:} section). =20 If the content directory contains a file named @file{dir}, this is assumed to be an Info directory file made with @command{install-info}. @@ -311,8 +313,8 @@ Package Archives =20 A package archive is simply a directory in which the package files, and associated files, are stored. If you want the archive to be -reachable via HTTP, this directory must be accessible to a web server. -How to accomplish this is beyond the scope of this manual. +reachable via HTTP, this directory must be accessible to a web server; +@xref{Archive Web Server}. =20 A convenient way to set up and update a package archive is via the @code{package-x} library. This is included with Emacs, but not loaded @@ -393,3 +395,28 @@ Package Archives @pxref{Top,, GnuPG, gnupg, The GNU Privacy Guard Manual}. Emacs comes with an interface to GNU Privacy Guard, @pxref{Top,, EasyPG, epa, Emacs EasyPG Assistant Manual}. + +@node Archive Web Server +@section Interfacing to an archive web server +@cindex archive web server + +A web server providing access to a package archive must support the +following queries: + +@table @asis +@item archive-contents +Return a lisp form describing the archive contents. The form is a list +of 'package-desc' structures (see @file{package.el}), except the first +element of the list is the archive version. + +@item -readme.txt +Return the long description of the package. + +@item .sig +Return the signature for the file. + +@item +Return the file. This will be the tarball for a multi-file +package, or the single file for a simple package. + +@end table diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index dcede1a5b2..1752c7e9fe 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -2123,6 +2123,9 @@ package-delete (add-hook 'post-command-hook #'package-menu--post-refresh) (delete-directory dir t) ;; Remove NAME-VERSION.signed and NAME-readme.txt files. + ;; + ;; NAME-readme.txt files are no longer created, but they + ;; may be left around from an earlier install. (dolist (suffix '(".signed" "readme.txt")) (let* ((version (package-version-join (package-desc-version p= kg-desc))) (file (concat (if (string=3D suffix ".signed") @@ -2233,6 +2236,45 @@ package--print-help-section =20 (declare-function lm-commentary "lisp-mnt" (&optional file)) =20 +(defun package--get-description (desc) + "Return a string containing the long description of the package DESC. +The description is read from the installed package files." + ;; Installed packages have nil for kind, so we look for README + ;; first, then fall back to the Commentary header. + + ;; We don=E2=80=99t include README.md here, because that is often the ho= me + ;; page on a site like github, and not suitable as the package long + ;; description. + (let ((files '("README-elpa" "README-elpa.md" "README" "README.rst" "REA= DME.org")) + file + (srcdir (package-desc-dir desc)) + result) + (while (and files + (not result)) + (setq file (pop files)) + (when (file-readable-p (expand-file-name file srcdir)) + ;; Found a README. + (with-temp-buffer + (insert-file-contents (expand-file-name file srcdir)) + (setq result (buffer-string))))) + + (or + result + + ;; Look for Commentary header. + (let ((mainsrcfile (expand-file-name (format "%s.el" (package-desc-na= me desc)) + srcdir))) + (when (file-readable-p mainsrcfile) + (with-temp-buffer + (insert (or (lm-commentary mainsrcfile) "")) + (goto-char (point-min)) + (when (re-search-forward "^;;; Commentary:\n" nil t) + (replace-match "")) + (while (re-search-forward "^\\(;+ ?\\)" nil t) + (replace-match "")) + (buffer-string)))) + ))) + (defun describe-package-1 (pkg) (require 'lisp-mnt) (let* ((desc (or @@ -2406,7 +2448,8 @@ describe-package-1 (insert "\n") =20 (if built-in - ;; For built-in packages, insert the commentary. + ;; For built-in packages, get the description from the + ;; Commentary header. (let ((fn (locate-file (format "%s.el" name) load-path load-file-rep-suffixes)) (opoint (point))) @@ -2417,27 +2460,25 @@ describe-package-1 (replace-match "")) (while (re-search-forward "^\\(;+ ?\\)" nil t) (replace-match "")))) - (let* ((basename (format "%s-readme.txt" name)) - (readme (expand-file-name basename package-user-dir)) - readme-string) - ;; For elpa packages, try downloading the commentary. If that - ;; fails, try an existing readme file in `package-user-dir'. - (cond ((and (package-desc-archive desc) - (package--with-response-buffer (package-archive-base d= esc) - :file basename :noerror t - (save-excursion - (goto-char (point-max)) - (unless (bolp) - (insert ?\n))) - (write-region nil nil - (expand-file-name readme package-user-= dir) - nil 'silent) - (setq readme-string (buffer-string)) - t)) - (insert readme-string)) - ((file-readable-p readme) - (insert-file-contents readme) - (goto-char (point-max)))))))) + + (if (package-installed-p desc) + ;; For installed packages, get the description from the installe= d files. + (insert (package--get-description desc)) + + ;; For non-built-in, non-installed packages, get description from = the archive. + (let* ((basename (format "%s-readme.txt" name)) + readme-string) + + (package--with-response-buffer (package-archive-base desc) + :file basename :noerror t + (save-excursion + (goto-char (point-max)) + (unless (bolp) + (insert ?\n))) + (setq readme-string (buffer-string)) + t) + (insert readme-string)) + )))) =20 (defun package-install-button-action (button) (let ((pkg-desc (button-get button 'package-desc))) diff --git a/test/lisp/emacs-lisp/package-tests.el b/test/lisp/emacs-lisp/p= ackage-tests.el index f08bc92ff2..17431f31f8 100644 --- a/test/lisp/emacs-lisp/package-tests.el +++ b/test/lisp/emacs-lisp/package-tests.el @@ -435,11 +435,24 @@ package-test-desc-version-string (save-excursion (should (search-forward "Summary: A single-file packa= ge with no dependencies" nil t))) (save-excursion (should (search-forward "Homepage: http://doodles.au"= nil t))) (save-excursion (should (re-search-forward "Keywords: \\[?frobnicate\= \]?" nil t))) - ;; No description, though. Because at this point we don't know - ;; what archive the package originated from, and we don't have - ;; its readme file saved. + (save-excursion (should (search-forward "This package provides a mino= r mode to frobnicate" + nil t))) ))) =20 +(ert-deftest package-test-describe-installed-multi-file-package () + "Test displaying of the readme for installed multi-file package." + + (with-package-test () + (package-initialize) + (package-refresh-contents) + (package-install 'multi-file) + (with-fake-help-buffer + (describe-package 'multi-file) + (goto-char (point-min)) + (should (search-forward "Homepage: http://puddles.li" nil t)) + (should (search-forward "This is a bare-bones readme file for the mul= ti-file" + nil t))))) + (ert-deftest package-test-describe-non-installed-package () "Test displaying of the readme for non-installed package." =20 --=-=-=--