From: Philip Kaludercic <philipk@posteo.net>
To: Eli Zaretskii <eliz@gnu.org>
Cc: Tony Zorman <soliditsallgood@mailbox.org>,
John Wiegley <johnw@gnu.org>,
felician.nemeth@gmail.com, 60418@debbugs.gnu.org,
stefankangas@gmail.com
Subject: bug#60418: [PATCH] Add :vc keyword to use-package
Date: Sat, 22 Apr 2023 11:34:10 +0000 [thread overview]
Message-ID: <874jp82lsd.fsf@posteo.net> (raw)
In-Reply-To: <83sfcs1d4o.fsf@gnu.org> (Eli Zaretskii's message of "Sat, 22 Apr 2023 12:26:31 +0300")
Eli Zaretskii <eliz@gnu.org> writes:
>> From: Tony Zorman <soliditsallgood@mailbox.org>
>> Cc: philipk@posteo.net, 60418@debbugs.gnu.org, felician.nemeth@gmail.com,
>> stefankangas@gmail.com
>> Date: Wed, 19 Apr 2023 19:38:10 +0200
>
> John, any comments to this changeset?
>
> Philip, will you install this when you think it's ready?
Can do, I just had a few more comments in my other message.
>> On Tue, Apr 18 2023 15:13, Eli Zaretskii wrote:
>> >> From: Tony Zorman <soliditsallgood@mailbox.org>
>> >> Cc: philipk@posteo.net, 60418@debbugs.gnu.org, felician.nemeth@gmail.com,
>> >> stefankangas@gmail.com
>> >> Date: Mon, 17 Apr 2023 21:39:47 +0200
>> >>
>> >> >> +(defun use-package-handler/:vc (name _keyword arg rest state)
>> >> >> + "Generate code for the :vc keyword."
>> >> >
>> >> > I don't think this is an accurate description of what the function
>> >> > does. Also, we try very hard to mention at least the mandatory
>> >> > arguments in the first line of the doc strings.
>> >>
>> >> I think I initially copied this from the handler for ":custom" (where
>> >> it's perhaps more applicable) and then forgot to change it. Still, I'm
>> >> not totally sure what to write here without assuming that the reader
>> >> already knows what the handler for a use-package keyword does (which is,
>> >> I guess, why none of the other handlers have much in the way of
>> >> documentation). Would it be a good idea to link to a relevant entry in
>> >> the info manual ((use-package) > Keyword extensions > Creating an
>> >> extension)?
>> >
>> > You could say something short on the first line assuming the reader
>> > knows, then explain a bit more in the subsequent lines. And yes,
>> > pointing to the Info manual is also an option, but something should
>> > still be in the doc string.
>>
>> I've now attached revised patches that should hopefully contain some
>> more useful documentation.
>>
>> >From c3c026655f372d84c9da4281d1a230629d13b55f Mon Sep 17 00:00:00 2001
>> From: Tony Zorman <soliditsallgood@mailbox.org>
>> Date: Thu, 29 Dec 2022 11:05:04 +0100
>> Subject: [PATCH 1/2] Add :vc keyword to use-package
>>
>> * lisp/use-package/use-package-core.el (use-package-keywords): Add :vc.
>> (use-package-handler/:load-path): Insert 'load-path' into 'state'.
>> (use-package-vc-install): Install the package with package-vc.el.
>> (use-package-handler/:vc): Handler for the :vc keyword.
>> (use-package-normalize--vc-arg): Normalization for more complex
>> arguments to 'use-package-normalize/:vc', in order to make them
>> compatible with the specification of 'package-vc-selected-packages'.
>> (use-package-normalize/:vc): Normalizer for the :vc keyword.
>> (use-package): Document :vc.
>>
>> * lisp/use-package/use-package-ensure.el (use-package-handler/:ensure):
>> Do not ensure a package when :vc is used in the declaration.
>>
>> * test/lisp/use-package/use-package-tests.el (use-package-test/:vc-1):
>> (use-package-test/:vc-2):
>> (use-package-test/:vc-3):
>> (use-package-test/:vc-4):
>> (use-package-test/:vc-5):
>> (use-package-test-normalize/:vc):
>> Add tests for :vc.
>> ---
>> lisp/use-package/use-package-core.el | 111 ++++++++++++++++++++-
>> lisp/use-package/use-package-ensure.el | 3 +-
>> test/lisp/use-package/use-package-tests.el | 49 +++++++++
>> 3 files changed, 160 insertions(+), 3 deletions(-)
>>
>> diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el
>> index 7ab5bdc276..0067ffc4f0 100644
>> --- a/lisp/use-package/use-package-core.el
>> +++ b/lisp/use-package/use-package-core.el
>> @@ -76,6 +76,7 @@ use-package-keywords
>> :functions
>> :preface
>> :if :when :unless
>> + :vc
>> :no-require
>> :catch
>> :after
>> @@ -1151,7 +1152,8 @@ use-package-normalize/:load-path
>> #'use-package-normalize-paths))
>>
>> (defun use-package-handler/:load-path (name _keyword arg rest state)
>> - (let ((body (use-package-process-keywords name rest state)))
>> + (let ((body (use-package-process-keywords name rest
>> + (plist-put state :load-path arg))))
>> (use-package-concat
>> (mapcar #'(lambda (path)
>> `(eval-and-compile (add-to-list 'load-path ,path)))
>> @@ -1577,6 +1579,109 @@ use-package-handler/:config
>> (when use-package-compute-statistics
>> `((use-package-statistics-gather :config ',name t))))))
>>
>> +;;;; :vc
>> +
>> +(defun use-package-vc-install (arg &optional local-path)
>> + "Install a package with `package-vc.el'.
>> +ARG is a list of the form (NAME OPTIONS REVISION), as returned by
>> +`use-package-normalize--vc-arg'. If LOCAL-PATH is non-nil, call
>> +`package-vc-install-from-checkout'; otherwise, indicating a
>> +remote host, call `package-vc-install' instead."
>> + (pcase-let* ((`(,name ,opts ,rev) arg)
>> + (spec (if opts (cons name opts) name)))
>> + (unless (package-installed-p name)
>> + (if local-path
>> + (package-vc-install-from-checkout local-path (symbol-name name))
>> + (package-vc-install spec rev)))))
>> +
>> +(defun use-package-handler/:vc (name _keyword arg rest state)
>> + "Generate code to install package NAME, or do so directly.
>> +When the use-package declaration is part of a byte-compiled file,
>> +install the package during compilation; otherwise, add it to the
>> +macro expansion and wait until runtime. The remaining arguments
>> +are as follows:
>> +
>> +_KEYWORD is ignored.
>> +
>> +ARG is the normalized input to the `:vc' keyword, as returned by
>> +the `use-package-normalize/:vc' function.
>> +
>> +REST is a plist of other (following) keywords and their
>> +arguments, each having already been normalised by the respective
>> +function.
>> +
>> +STATE is a plist of any state that keywords processed before
>> +`:vc' (see `use-package-keywords') may have accumulated.
>> +
>> +Also see (info \"(use-package) Creating an extension\")."
>> + (let ((body (use-package-process-keywords name rest state))
>> + (local-path (car (plist-get state :load-path))))
>> + ;; See `use-package-handler/:ensure' for an explanation.
>> + (if (bound-and-true-p byte-compile-current-file)
>> + (funcall #'use-package-vc-install arg local-path) ; compile time
>> + (push `(use-package-vc-install ',arg ,local-path) body)))) ; runtime
>> +
>> +(defun use-package-normalize--vc-arg (arg)
>> + "Normalize possible arguments to the `:vc' keyword.
>> +ARG is a cons-cell of approximately the form that
>> +`package-vc-selected-packages' accepts, plus an additional `:rev'
>> +keyword. If `:rev' is not given, it defaults to `:last-release'.
>> +
>> +Returns a list (NAME SPEC REV), where (NAME . SPEC) is compliant
>> +with `package-vc-selected-packages' and REV is a (possibly nil,
>> +indicating the latest commit) revision."
>> + (cl-flet* ((mk-string (s)
>> + (if (and s (stringp s)) s (symbol-name s)))
>> + (mk-sym (s)
>> + (if (and s (stringp s)) (intern s) s))
>> + (normalize (k v)
>> + (pcase k
>> + (:rev (cond ((or (eq v :last-release) (not v)) :last-release)
>> + ((eq v :head) nil)
>> + (t (mk-string v))))
>> + (:vc-backend (mk-sym v))
>> + (_ (mk-string v)))))
>> + (pcase-let ((valid-kws '(:url :branch :lisp-dir :main-file :vc-backend :rev))
>> + (`(,name . ,opts) arg))
>> + (if (stringp opts) ; (NAME . VERSION-STRING) ?
>> + (list name opts)
>> + ;; Error handling
>> + (cl-loop for (k _) on opts by #'cddr
>> + if (not (member k valid-kws))
>> + do (use-package-error
>> + (format "Keyword :vc received unknown argument: %s. Supported keywords are: %s"
>> + k valid-kws)))
>> + ;; Actual normalization
>> + (list name
>> + (cl-loop for (k v) on opts by #'cddr
>> + if (not (eq k :rev))
>> + nconc (list k (normalize k v)))
>> + (normalize :rev (plist-get opts :rev)))))))
>> +
>> +(defun use-package-normalize/:vc (name _keyword args)
>> + "Normalize possible arguments to the `:vc' keyword.
>> +NAME is the name of the `use-package' declaration, _KEYWORD is
>> +ignored, and ARGS it a list of arguments given to the `:vc'
>> +keyword, the cdr of which is ignored.
>> +
>> +See `use-package-normalize--vc-arg' for most of the actual
>> +normalization work. Also see (info \"(use-package) Creating an
>> +extension\")."
>> + (let ((arg (car args)))
>> + (pcase arg
>> + ((or 'nil 't) (list name)) ; guess name
>> + ((pred symbolp) (list arg)) ; use this name
>> + ((pred stringp) (list name arg)) ; version string + guess name
>> + ((pred plistp) ; plist + guess name
>> + (use-package-normalize--vc-arg (cons name arg)))
>> + (`(,(pred symbolp) . ,(or (pred plistp) ; plist/version string + name
>> + (pred stringp)))
>> + (use-package-normalize--vc-arg arg))
>> + (_ (use-package-error "Unrecognised argument to :vc.\
>> + The keyword wants an argument of nil, t, a name of a package,\
>> + or a cons-cell as accepted by `package-vc-selected-packages', where \
>> + the accepted plist is augmented by a `:rev' keyword.")))))
>> +
>> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>> ;;
>> ;;; The main macro
>> @@ -1666,7 +1771,9 @@ use-package
>> (compare with `custom-set-variables').
>> :custom-face Call `custom-set-faces' with each face definition.
>> :ensure Loads the package using package.el if necessary.
>> -:pin Pin the package to an archive."
>> +:pin Pin the package to an archive.
>> +:vc Install the package directly from a version control system
>> + (using `package-vc.el')."
>> (declare (indent defun))
>> (unless (memq :disabled args)
>> (macroexp-progn
>> diff --git a/lisp/use-package/use-package-ensure.el b/lisp/use-package/use-package-ensure.el
>> index e0ea982594..425a3e8917 100644
>> --- a/lisp/use-package/use-package-ensure.el
>> +++ b/lisp/use-package/use-package-ensure.el
>> @@ -182,7 +182,8 @@ use-package-ensure-elpa
>>
>> ;;;###autoload
>> (defun use-package-handler/:ensure (name _keyword ensure rest state)
>> - (let* ((body (use-package-process-keywords name rest state)))
>> + (let* ((body (use-package-process-keywords name rest state))
>> + (ensure (unless (plist-member rest :vc) ensure)))
>> ;; We want to avoid installing packages when the `use-package' macro is
>> ;; being macro-expanded by elisp completion (see `lisp--local-variables'),
>> ;; but still install packages when byte-compiling, to avoid requiring
>> diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el
>> index 6374a0d103..b04d087e65 100644
>> --- a/test/lisp/use-package/use-package-tests.el
>> +++ b/test/lisp/use-package/use-package-tests.el
>> @@ -1951,6 +1951,55 @@ bind-key/845
>> (should (eq (nth 1 binding) 'ignore))
>> (should (eq (nth 2 binding) nil))))
>>
>> +(ert-deftest use-package-test/:vc-1 ()
>> + (match-expansion
>> + (use-package foo :vc (:url "bar"))
>> + '(use-package-vc-install '(foo (:url "bar") :last-release) nil)))
>> +
>> +(ert-deftest use-package-test/:vc-2 ()
>> + (match-expansion
>> + (use-package foo
>> + :vc (baz . (:url "baz" :vc-backend "Git"
>> + :main-file qux.el :rev "rev-string")))
>> + `(use-package-vc-install '(baz
>> + (:url "baz" :vc-backend Git :main-file "qux.el")
>> + "rev-string")
>> + nil)))
>> +
>> +(ert-deftest use-package-test/:vc-3 ()
>> + (match-expansion
>> + (use-package foo :vc (bar . "baz"))
>> + `(use-package-vc-install '(bar "baz") nil)))
>> +
>> +(ert-deftest use-package-test/:vc-4 ()
>> + (match-expansion
>> + (use-package foo :vc (bar . (:url "baz" :rev :head)))
>> + '(use-package-vc-install '(bar (:url "baz") nil) nil)))
>> +
>> +(ert-deftest use-package-test/:vc-5 ()
>> + (let ((load-path? '(pred (apply-partially
>> + #'string=
>> + (expand-file-name "bar" user-emacs-directory)))))
>> + (match-expansion
>> + (use-package foo :vc other-name :load-path "bar")
>> + `(progn (eval-and-compile
>> + (add-to-list 'load-path ,load-path?))
>> + (use-package-vc-install '(other-name) ,load-path?)))))
>> +
>> +(ert-deftest use-package-test-normalize/:vc ()
>> + (should (equal '(foo "version-string")
>> + (use-package-normalize/:vc 'foo :vc '("version-string"))))
>> + (should (equal '(bar "version-string")
>> + (use-package-normalize/:vc 'foo :vc '((bar . "version-string")))))
>> + (should (equal '(foo (:url "bar") "baz")
>> + (use-package-normalize/:vc 'foo :vc '((:url "bar" :rev "baz")))))
>> + (should (equal '(foo)
>> + (use-package-normalize/:vc 'foo :vc '(t))))
>> + (should (equal '(foo)
>> + (use-package-normalize/:vc 'foo :vc nil)))
>> + (should (equal '(bar)
>> + (use-package-normalize/:vc 'foo :vc '(bar)))))
>> +
>> ;; Local Variables:
>> ;; no-byte-compile: t
>> ;; no-update-autoloads: t
>> --
>> 2.40.0
>>
>>
>> >From 652bb5b80c57f9891f74c48f66e96fba29007f44 Mon Sep 17 00:00:00 2001
>> From: Tony Zorman <soliditsallgood@mailbox.org>
>> Date: Thu, 29 Dec 2022 12:23:56 +0100
>> Subject: [PATCH 2/2] ; Document use-package's :vc keyword
>>
>> * doc/misc/use-package.texi (Installing packages):
>> (Install package):
>> Add documentation for :vc and link to the related chapter in the Emacs
>> manual.
>>
>> * etc/NEWS: Mention :vc keyword
>> ---
>> doc/misc/use-package.texi | 45 +++++++++++++++++++++++++++++++++++++--
>> etc/NEWS | 13 +++++++++++
>> 2 files changed, 56 insertions(+), 2 deletions(-)
>>
>> diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi
>> index 87105c4db0..d1d847c0e0 100644
>> --- a/doc/misc/use-package.texi
>> +++ b/doc/misc/use-package.texi
>> @@ -1554,8 +1554,11 @@ Installing packages
>> (@pxref{Package Installation,,, emacs, GNU Emacs Manual}). The
>> @code{use-package} macro provides the @code{:ensure} and @code{:pin}
>> keywords that interface with that package manager to automatically
>> -install packages. This is particularly useful if you use your init
>> -file on more than one system.
>> +install packages. The @code{:vc} keyword may be used to control how
>> +package sources are downloaded (e.g., from remote hosts)
>> +(@pxref{Fetching Package Sources,,, emacs, GNU Emacs Manual}). This
>> +is particularly useful if you use your init file on more than one
>> +system.
>>
>> @menu
>> * Install package::
>> @@ -1607,6 +1610,44 @@ Install package
>> You can override the above setting for a single package by adding
>> @w{@code{:ensure nil}} to its declaration.
>>
>> +@findex :vc
>> +The @code{:vc} keyword can be used to control how packages are
>> +downloaded and/or installed. It accepts the same arguments as
>> +@code{package-vc-selected-packages} (@pxref{Specifying Package
>> +Sources,,, emacs, GNU Emacs Manual}), except that a name need not
>> +explicitly be given: it is inferred from the declaration. The
>> +accepted property list is augmented by a @code{:rev} keyword, which
>> +has the same shape as the @code{REV} argument to
>> +@code{package-vc-install}. Notably -- even when not specified --
>> +@code{:rev} defaults to checking out the last release of the package.
>> +You can use @code{:rev :head} to check out the latest commit.
>> +
>> +For example,
>> +
>> +@lisp
>> +@group
>> +(use-package foo
>> + :vc (:url "https://bar.com/foo" :rev :head))
>> +@end group
>> +@end lisp
>> +
>> +would try -- by invoking @code{package-vc-install} -- to install the
>> +latest commit of the package @code{foo} from the specified remote.
>> +
>> +This can also be used for local packages, by combining it with the
>> +@code{:load-path} (@pxref{Load path}) keyword:
>> +
>> +@lisp
>> +@group
>> +(use-package foo
>> + :vc t
>> + :load-path "/path/to/foo/)
>> +@end group
>> +@end lisp
>> +
>> +The above dispatches to @code{package-vc-install-from-checkout}
>> +(@pxref{Fetching Package Sources,,, emacs, GNU Emacs Manual}).
>> +
>> @node Pinning packages
>> @section Pinning packages using @code{:pin}
>> @cindex installing package from specific archive
>> diff --git a/etc/NEWS b/etc/NEWS
>> index b121002b24..c63bd42fc8 100644
>> --- a/etc/NEWS
>> +++ b/etc/NEWS
>> @@ -276,6 +276,19 @@ distracting and easily confused with actual code, or a significant
>> early aid that relieves you from moving the buffer or reaching for the
>> mouse to consult an error message.
>>
>> +** use-package
>> +
>> ++++
>> +*** New ':vc' keyword.
>> +This keyword enables the user to control how packages are fetched by
>> +utilising 'package-vc.el'. By default, it relays its arguments to
>> +'package-vc-install', but -- when combined with the ':load-path'
>> +keyword -- it can also call upon 'package-vc-install-from-checkout'
>> +instead. If no revision is given via the ':rev' argument, use-package
>> +falls back to the last release (via 'package-vc-install's
>> +':last-release' argument). To check out the last commit, use ':rev
>> +:head'.
>> +
>> \f
>> * New Modes and Packages in Emacs 30.1
>>
>> --
>> 2.40.0
--
Philip Kaludercic
next prev parent reply other threads:[~2023-04-22 11:34 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-29 18:43 bug#60418: [PATCH] Add :vc keyword to use-package Tony Zorman via Bug reports for GNU Emacs, the Swiss army knife of text editors
[not found] ` <handler.60418.B.167238381823776.ack@debbugs.gnu.org>
2023-01-14 12:48 ` Tony Zorman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-03-31 14:13 ` Felician Nemeth
2023-03-31 15:38 ` Philip Kaludercic
2023-04-07 14:11 ` Philip Kaludercic
2023-04-08 8:48 ` Felician Nemeth
2023-04-08 9:06 ` Philip Kaludercic
2023-04-08 9:25 ` Felician Nemeth
2023-04-08 10:41 ` Philip Kaludercic
2023-04-11 14:10 ` Felician Nemeth
2023-04-12 7:12 ` Tony Zorman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-04-12 7:34 ` Philip Kaludercic
2023-04-12 9:00 ` Tony Zorman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-04-16 15:43 ` Tony Zorman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-04-16 16:10 ` Eli Zaretskii
2023-04-17 19:39 ` Tony Zorman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-04-18 12:13 ` Eli Zaretskii
2023-04-19 17:38 ` Tony Zorman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-04-22 9:26 ` Eli Zaretskii
2023-04-22 11:34 ` Philip Kaludercic [this message]
2023-04-23 5:51 ` John Wiegley
2023-04-22 11:32 ` Philip Kaludercic
2023-04-23 6:07 ` Tony Zorman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-04-23 12:35 ` Philip Kaludercic
2023-04-24 12:36 ` Tony Zorman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-05-01 19:43 ` Tony Zorman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-05-01 20:01 ` Philip Kaludercic
2023-05-02 13:18 ` Ruijie Yu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-05-02 13:59 ` Robert Pluim
2023-05-02 15:09 ` Eli Zaretskii
2023-05-02 14:36 ` Tony Zorman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-05-02 12:40 ` Eli Zaretskii
2023-05-02 14:22 ` Tony Zorman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-05-02 15:16 ` Eli Zaretskii
2023-05-04 8:13 ` Tony Zorman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-05-04 10:39 ` Eli Zaretskii
2023-05-05 5:04 ` Philip Kaludercic
2023-05-05 5:36 ` Eli Zaretskii
2023-05-05 5:49 ` Philip Kaludercic
2023-05-05 6:53 ` Eli Zaretskii
2023-05-05 17:15 ` Philip Kaludercic
2023-05-05 18:45 ` Eli Zaretskii
2023-05-06 18:50 ` Philip Kaludercic
2023-05-06 19:13 ` Eli Zaretskii
2023-05-07 7:34 ` Philip Kaludercic
2023-05-06 19:39 ` Tony Zorman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-05-07 8:52 ` Philip Kaludercic
2023-05-16 19:30 ` Philip Kaludercic
2023-05-17 5:42 ` Tony Zorman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-04-16 16:18 ` Ruijie Yu via Bug reports for GNU Emacs, the Swiss army knife of text editors
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=874jp82lsd.fsf@posteo.net \
--to=philipk@posteo.net \
--cc=60418@debbugs.gnu.org \
--cc=eliz@gnu.org \
--cc=felician.nemeth@gmail.com \
--cc=johnw@gnu.org \
--cc=soliditsallgood@mailbox.org \
--cc=stefankangas@gmail.com \
/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).