Subject: Re: bug#13291: The package description buffer needs an URL button

From: Dmitry Gutov <[email-masked]>
Date: Sat, 12 Jan 2013 11:41:04 +0400

On 12.01.2013 7:28, Stefan Monnier wrote:
> I don't see any problem with this idea.

Terrific. Patch attached.

Note that I haven't tested it with an actual package repository 
supporting this extension, just with modified -pkg.el and 
archive-contents files.

>> Elpa can at least show links to the repository browser.
>> Or maybe to the pages at elpa.gnu.org.
>
> It should point to the pages at elpa.gnu.org.
>
>> They basically contain the same information as the description buffer,
>> though, so probably not.
>
> The are meant to be the "canonical page" for the package.  Admittedly,
> they seem to contain the same info as the description buffer, but they
> already contain a bit more info (a pointer to the repository browser, a list
> of past revisions) and that could grow over time.

Sounds good to me.

Hopefully, the code responsible for it will take care of the case when 
those pages are not in fact canonical, like org, auctex, etc.
=== modified file 'lisp/ChangeLog'
--- lisp/ChangeLog	2013-01-11 23:24:52 +0000
+++ lisp/ChangeLog	2013-01-12 07:33:28 +0000
@@ -1,3 +1,16 @@
+2013-01-12  Dmitry Gutov  <gutov@vbx>
+
+	* emacs-lisp/package.el (package-desc-kind): Get the kind from the
+	metadata plist.
+	(package-desc-meta): Return metadata plist.
+	(define-package): Store EXTRA-PROPERTIES as the 4th element of
+	the package data vector.
+	(package--add-to-archive-contents): Instead of just package kind,
+	use the 4th element of the vector for the matadata.  Include kind
+	in the metadata.
+	(describe-package-1): When the package metadata includes
+	`:homepage', display a link button for it (bug#13291).
+
 2013-01-11  Felix H. Dahlke  <[email-masked]>
 
 	* progmodes/js.el: Fix multiline declarations's indentation (bug#8576).

=== modified file 'lisp/emacs-lisp/package.el'
--- lisp/emacs-lisp/package.el	2013-01-01 09:11:05 +0000
+++ lisp/emacs-lisp/package.el	2013-01-12 07:23:54 +0000
@@ -302,12 +302,13 @@
 Each element has the form (PKG . DESC), where PKG is a package
 name (a symbol) and DESC is a vector that describes the package.
 
-The vector DESC has the form [VERSION-LIST REQS DOCSTRING].
+The vector DESC has the form [VERSION-LIST REQS DOCSTRING META].
   VERSION-LIST is a version list.
   REQS is a list of packages required by the package, each
    requirement having the form (NAME VL) where NAME is a string
    and VL is a version list.
   DOCSTRING is a brief description of the package.
+  META is a property list mapping metadata keywords to values.
 
 This variable is set automatically by `package-load-descriptor',
 called via `package-initialize'.  To change which packages are
@@ -426,6 +427,10 @@
 
 (defsubst package-desc-kind (desc)
   "Extract the kind of download from an archive package description vector."
+  (plist-get (package-desc-meta desc) :kind))
+
+(defsubst package-desc-meta (desc)
+  "Extract the metadata property list from a package description vector."
   (aref desc 3))
 
 (defun package--dir (name version)
@@ -525,7 +530,7 @@
 
 (defun define-package (name-string version-string
 				&optional docstring requirements
-				&rest _extra-properties)
+				&rest extra-properties)
   "Define a new package.
 NAME-STRING is the name of the package, as a string.
 VERSION-STRING is the version of the package, as a string.
@@ -533,8 +538,8 @@
 REQUIREMENTS is a list of dependencies on other packages.
  Each requirement is of the form (OTHER-PACKAGE OTHER-VERSION),
  where OTHER-VERSION is a string.
-
-EXTRA-PROPERTIES is currently unused."
+EXTRA-PROPERTIES is a property list mapping additional metadata
+keywords (e.g. `:homepage') to values."
   (let* ((name (intern name-string))
 	 (version (version-to-list version-string))
 	 (new-pkg-desc
@@ -545,7 +550,8 @@
 			   (list (car elt)
 				 (version-to-list (car (cdr elt)))))
 			 requirements)
-			docstring)))
+			docstring
+			extra-properties)))
 	 (old-pkg (assq name package-alist)))
     (cond
      ;; If there's no old package, just add this to `package-alist'.
@@ -853,8 +859,15 @@
 Also, add the originating archive to the end of the package vector."
   (let* ((name    (car package))
          (version (package-desc-vers (cdr package)))
+         (data    (append (cdr package) nil))
+         (ex-len  (- (length data) 3))
+         (extras  (last data ex-len))
          (entry   (cons name
-			(vconcat (cdr package) (vector archive))))
+                        (vconcat (nbutlast data ex-len)
+                                 ;; Save the kind and any following
+                                 ;; keyword-value pairs as metadata.
+                                 (vector (cons :kind extras)
+                                         archive))))
          (existing-package (assq name package-archive-contents)))
     (cond ((not existing-package)
 	   (add-to-list 'package-archive-contents entry))
@@ -1261,7 +1274,13 @@
 	  (help-insert-xref-button text 'help-package name))
 	(insert "\n")))
     (insert "    " (propertize "Summary" 'font-lock-face 'bold)
-	    ": " (if desc (package-desc-doc desc)) "\n\n")
+	    ": " (if desc (package-desc-doc desc)) "\n")
+    (let ((homepage (plist-get (package-desc-meta desc) :homepage)))
+      (when homepage
+        (insert "   " (propertize "Homepage" 'font-lock-face 'bold) ": ")
+        (help-insert-xref-button homepage 'help-url homepage)
+        (insert "\n")))
+    (insert "\n")
 
     (if built-in
 	;; For built-in packages, insert the commentary.