Skip to content

Commit

Permalink
merge recipe changes to .status.el on update too
Browse files Browse the repository at this point in the history
Previously, the recipe in .status.el was only updated on init, since
only some properties are safe for change on init the unsafe ones were
never updated.  Therefore, we classify addtional properties as safe fo
change on update, and update .status.el after el-get-update too.

* el-get-core.el (el-get-as-string): Handle number argument.
* el-get-status.el (el-get-status-init-whitelist): Rename from
  el-get-status-recipe-update-whitelist.
(el-get-status-update-whitelist): New constant.
(el-get-classify-new-properties): Add OPERATION argument to choose white
whitelist to use.  The :builtin property is safe to change if it doesn't
change the :type.
(el-get-diagnosis-properties, el-get-merge-properties-into-status): Add
OPERATION argument.
* el-get.el (el-get-do-init): Call el-get-merge-properties-into-status
  with OPERATION 'init.
(el-get-post-update-build): Call el-get-merge-properties-into-status
  with OPERATION 'update.
  • Loading branch information
npostavs committed Sep 5, 2015
1 parent 4aa5cdc commit cf1d2f9
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 16 deletions.
12 changes: 7 additions & 5 deletions el-get-core.el
Expand Up @@ -140,11 +140,13 @@ already-defined method DERIVED-FROM-NAME."
;; interface to write such structures as raw elisp.
;;
;;; "Fuzzy" data structure conversion utilities
(defun el-get-as-string (symbol-or-string)
"If STRING-OR-SYMBOL is already a string, return it. Otherwise
convert it to a string and return that."
(if (stringp symbol-or-string) symbol-or-string
(symbol-name symbol-or-string)))
(defun el-get-as-string (obj)
"Return OBJ as a string."
(cond
((stringp obj) obj)
((symbolp obj) (symbol-name obj))
((numberp obj) (number-to-string obj))
(t (error "Can't convert %S to string." obj))))

(defun el-get-as-symbol (string-or-symbol)
"If STRING-OR-SYMBOL is already a symbol, return it. Otherwise
Expand Down
43 changes: 33 additions & 10 deletions el-get-status.el
Expand Up @@ -230,7 +230,7 @@
(progn ,@body)))


(defvar el-get-status-recipe-update-whitelist
(defconst el-get-status-init-whitelist
'(:load-path
:info
:load
Expand All @@ -243,13 +243,24 @@
:lazy
:website
:description)
"Properties that can be updated without `el-get-update'/`el-get-reinstall'.
"Properties that can be updated with only `el-get-init'.
If any of these properties change on the recipe for an installed
package, the changes may be merged into the cached version of
that recipe in the el-get status file.")

(defun el-get-classify-new-properties (source newprops)
(defconst el-get-status-update-whitelist
`(:depends
:build
:build/system-type
:compile
:checksum
:checkout
:options
,@el-get-status-init-whitelist)
"Properties than can be updated by `el-get-update'.")

(defun el-get-classify-new-properties (operation source newprops)
"Classify NEWPROPS into two groups: need update/disallowed.
Return a list (UPDATE DISALLOWED). Both UPDATE and NEWPROPS are
Expand All @@ -258,25 +269,34 @@ Elements in UPDATE are whitelisted whereas elements in DISALLOWED
are not."
(loop with update
with disallowed
with whitelist = el-get-status-recipe-update-whitelist
with whitelist = (if (eq operation 'update)
el-get-status-update-whitelist
el-get-status-init-whitelist)
for (k v) on newprops by 'cddr
;; Not a change, so ignore it
if (equal v (plist-get source k)) do (ignore)
;; whitelisted
else if (memq k whitelist) do (setq update (plist-put update k v))
else if
(or (memq k whitelist) ; whitelisted
(and (eq k :builtin)
;; Check if `:builtin' change is safe.
(eq (version<= emacs-version (el-get-as-string v))
(version<= emacs-version (el-get-as-string
(plist-get source k))))))
do (setq update (plist-put update k v))
;; Trying to change non-whitelisted property
else do (setq disallowed (plist-put disallowed k v))
finally return (list update disallowed)))

(defun el-get-diagnosis-properties (old-source new-source)
(defun el-get-diagnosis-properties (operation old-source new-source)
"Diagnosis difference between OLD-SOURCE and NEW-SOURCE.
Return a list (UPDATE-P ADDED-DISALLOWED REMOVED-DISALLOWED).
UPDATE-P is non-nil when OLD-SOURCE and NEW-SOURCE are different.
ADDED-DISALLOWED and REMOVED-DISALLOWED are added and removed
properties, respectively."
(let ((added (el-get-classify-new-properties old-source new-source))
(removed (el-get-classify-new-properties new-source old-source)))
(let ((added (el-get-classify-new-properties operation old-source new-source))
(removed (el-get-classify-new-properties operation new-source old-source)))
(list (or (car added) (car removed))
(cadr added)
(cadr removed))))
Expand All @@ -303,6 +323,7 @@ properties, respectively."
package))))

(defun el-get-merge-properties-into-status (package-or-source
operation
&rest keys)
"Merge updatable properties for package into package status alist (or status file).
Expand All @@ -323,6 +344,7 @@ t', this error is suppressed (but nothing is updated).
\(fn PACKAGE-OR-SOURCE &key NOERROR)"
(interactive
(list (el-get-read-package-with-status "Update cached recipe" "installed")
'init
:noerror current-prefix-arg))
(let* ((noerror (cadr (memq :noerror keys)))
(source (el-get-package-or-source package-or-source))
Expand All @@ -332,7 +354,7 @@ t', this error is suppressed (but nothing is updated).
(unless (el-get-package-is-installed package)
(error "Package %s is not installed. Cannot update recipe." package))
(destructuring-bind (update-p added-disallowed removed-disallowed)
(el-get-diagnosis-properties cached-recipe source)
(el-get-diagnosis-properties operation cached-recipe source)
(if (or added-disallowed removed-disallowed)
;; Emit a verbose message if `noerror' is t (but still quit
;; the function).
Expand All @@ -348,10 +370,11 @@ and remove non-whitelisted properties:
into/from source:
%s
Maybe you should use `el-get-update' or `el-get-reinstall' on %s instead?"
Maybe you should use %s`el-get-reinstall' on %s instead?"
(if added-disallowed (pp-to-string added-disallowed) "()")
(if removed-disallowed (pp-to-string removed-disallowed) "()")
(pp-to-string cached-recipe)
(if (eq operation 'update) "" "`el-get-update' or")
(el-get-source-name cached-recipe))
(when update-p
(el-get-save-package-status package "installed" source))))))
Expand Down
3 changes: 2 additions & 1 deletion el-get.el
Expand Up @@ -383,7 +383,7 @@ this warning either uninstall one of the el-get or package.el
version of %s, or call `el-get' before `package-initialize' to
prevent package.el from loading it." package package)))
(when el-get-auto-update-cached-recipes
(el-get-merge-properties-into-status package () :noerror t))
(el-get-merge-properties-into-status package 'init :noerror t))
(condition-case err
(let* ((el-get-sources (el-get-package-status-recipes))
(source (el-get-read-package-status-recipe package))
Expand Down Expand Up @@ -641,6 +641,7 @@ PACKAGE may be either a string or the corresponding symbol."
(defun el-get-post-update-build (package)
"Function to call after building the package while updating it."
;; fix trailing failed installs
(el-get-merge-properties-into-status package 'update :noerror t)
(when (string= (el-get-read-package-status package) "required")
(el-get-save-package-status package "installed"))
(el-get-invalidate-autoloads package)
Expand Down

0 comments on commit cf1d2f9

Please sign in to comment.