diff --git a/.lock b/.lock new file mode 100644 index 000000000..06de5f6cf --- /dev/null +++ b/.lock @@ -0,0 +1,19 @@ +;; -*- mode: emacs-lisp -*- + +(setq configuration-layer--stable-elpa-name "spacelpa") +(setq configuration-layer--stable-elpa-version "0.300") + +(setq configuration-layer--elpa-archives + `(("melpa" . "melpa.org/packages/") + ("org" . "orgmode.org/elpa/") + ("gnu" . "elpa.gnu.org/packages/") + ("spacelpa" . ,(concat configuration-layer--stable-elpa-directory + "spacelpa-" + configuration-layer--stable-elpa-version)))) + +(setq package-archive-priorities + '(("spacelpa" . 8) + ("melpa" . 4) + ("org" . 2) + ("gnu" . 1))) + diff --git a/core/core-configuration-layer.el b/core/core-configuration-layer.el index 688e0ba3f..3e67e3fe6 100644 --- a/core/core-configuration-layer.el +++ b/core/core-configuration-layer.el @@ -46,20 +46,48 @@ configuration-layer-private-directory)) "Spacemacs default directory for private layers.") +(defconst configuration-layer-lock-file + (concat spacemacs-start-directory ".lock") + "Absolute path to the lock file.") + +(defconst configuration-layer--stable-elpa-name "spacelpa" + "Name of the stable ELPA repository. Should be fixed by the lock file.") + +(defconst configuration-layer--stable-elpa-tarball-directory + "https://github.com/syl20bnr/spacelpa/archive/" + "Remote location of the tarball for the ELPA stable directory") + +(defconst configuration-layer--stable-elpa-directory + (expand-file-name + (concat spacemacs-cache-directory "stable-elpa/" emacs-version "/")) + "Remote location of the tarball for the ELPA stable directory") + +(defconst configuration-layer--stable-elpa-version-file + (concat configuration-layer--stable-elpa-directory "version") + "Absolute path to the file containing the current stable elpa repository +version") + +(defvar configuration-layer--stable-elpa-version spacemacs-version + "Version of ELPA stable repository. This value is aimed to be overwritten by +the .lock file at the root of the repository.") + (defun configuration-layer/elpa-directory (root) "Evaluate the correct package subdirectory of ROOT. This is done according to the value of `dotspacemacs-elpa-subdirectory'. -If it is nil, then ROOT is returned. Otherwise a subdirectory of -ROOT is returned." - (if (not dotspacemacs-elpa-subdirectory) - root - (let ((subdir (if (eq 'emacs-version dotspacemacs-elpa-subdirectory) - (format "%d%s%d" - emacs-major-version - version-separator - emacs-minor-version) - (eval dotspacemacs-elpa-subdirectory)))) - (file-name-as-directory (expand-file-name subdir root))))) +This function also appends the name of the current branch of Spacemacs. +If `dotspacemacs-elpa-subdirectory' is nil, then ROOT is used. Otherwise the +subdirectory of ROOT is used." + (concat + (if (not dotspacemacs-elpa-subdirectory) + root + (let ((subdir (if (eq 'emacs-version dotspacemacs-elpa-subdirectory) + (format "%d%s%d" + emacs-major-version + version-separator + emacs-minor-version) + (eval dotspacemacs-elpa-subdirectory)))) + (file-name-as-directory (expand-file-name subdir root)))) + (spacemacs//git-get-current-branch))) (defun configuration-layer/get-elpa-package-install-directory (pkg) "Return the install directory of elpa PKG. Return nil if it is not found." @@ -294,12 +322,9 @@ is not set for the given SLOT." (unless configuration-layer--package-properties-read-onlyp (eval `(oset pkg ,slot value)))) -(defvar configuration-layer--elpa-archives - '(("melpa" . "melpa.org/packages/") - ("org" . "orgmode.org/elpa/") - ("gnu" . "elpa.gnu.org/packages/")) - ;; '(("spacelpa" . "~/.emacs.d/.cache/spacelpa/")) - "List of ELPA archives required by Spacemacs.") +(defvar configuration-layer--elpa-archives nil + "List of ELPA archives required by Spacemacs. This value is set by the lock +file.") (defvar configuration-layer-exclude-all-layers nil "If non nil then only the distribution layer is loaded.") @@ -356,12 +381,17 @@ directory with a name starting with `+'.") "Used to collect information about rollback packages in the cache folder.") +(defun configuration-layer/load-lock-file () + "Load the .lock file" + (load-file configuration-layer-lock-file)) + (defun configuration-layer/initialize () "Initialize `package.el'." (setq configuration-layer--refresh-package-timeout dotspacemacs-elpa-timeout) (unless package--initialized (setq configuration-layer-rollback-directory - (configuration-layer/elpa-directory configuration-layer-rollback-directory)) + (configuration-layer/elpa-directory + configuration-layer-rollback-directory)) (setq package-user-dir (configuration-layer/elpa-directory package-user-dir)) (setq package-archives (configuration-layer//resolve-package-archives @@ -480,6 +510,7 @@ refreshed during the current session." "Load layers declared in dotfile and install associated packages. To prevent package from being installed or uninstalled set the variable `spacemacs-sync-packages' to nil." + (message "%s" (configuration-layer//stable-elpa-directory)) (run-hooks 'configuration-layer-pre-load-hook) (dotspacemacs|call-func dotspacemacs/layers "Calling dotfile layers...") (setq dotspacemacs--configuration-layers-saved @@ -2306,8 +2337,13 @@ depends on it." ,(package-desc-kind obj) ,(package-desc-extras obj)]))) +(defun configuration-layer//patch-package-descriptor (desc) + "Return a patched DESC. +The URL of the descriptor is patched to be the passed URL" + ) + (defun configuration-layer//download-elpa-file - (pkg-name filename archive-url output-dir + (pkg-name filename archive-url output-dirkkj &optional signaturep readmep) "Download FILENAME from distant ELPA repository to OUTPUT-DIR. @@ -2367,7 +2403,7 @@ Original code from dochang at https://github.com/dochang/elpa-clone" (archive-contents (mapcar 'configuration-layer//create-archive-contents-item packages)) - (path (file-name-as-directory (concat output-dir name)))) + (path (file-name-as-directory (concat output-dir "/" name)))) (unless (file-exists-p path) (make-directory path 'create-parents)) (configuration-layer//sync-elpa-packages-files packages path) (push 1 archive-contents) @@ -2377,6 +2413,71 @@ Original code from dochang at https://github.com/dochang/elpa-clone" (prin1 archive-contents (current-buffer)) (save-buffer))))) +(defun configuration-layer/stable-elpa-version () + "Set and return the current version of the ELPA repository. +Returns nil if the version is unknown." + (when (file-exists-p configuration-layer--stable-elpa-version-file) + (with-current-buffer (find-file-noselect + configuration-layer--stable-elpa-version-file) + (buffer-string)))) + +(defun configuration-layer//stable-elpa-tarball-distant-file () + "Return the distant file path of the downloaded tarball of ELPA stable +repository." + (format "%sv%s.tar.gz" + configuration-layer--stable-elpa-tarball-directory + configuration-layer--stable-elpa-version)) + +(defun configuration-layer//stable-elpa-directory () + "Return the local absolute path of the ELPA stable repository." + (cdr (assoc configuration-layer--stable-elpa-name + configuration-layer--elpa-archives))) + +(defun configuration-layer//stable-elpa-tarball-local-file () + "Return the local absolute path for the file of the downloaded tarball of +ELPA stable repository." + (format "%s.tar.gz" (configuration-layer//stable-elpa-directory))) + +(defun configuration-layer//stable-elpa-untar-archive () + "Untar the downloaded archive of stable ELPA." + (require 'tar-mode) + (let (large-file-warning-threshold) + (with-current-buffer (find-file-noselect + (configuration-layer//stable-elpa-tarball-local-file)) + (tar-mode) + (tar-untar-buffer)))) + +(defun configuration-layer/stable-elpa-download-tarball () + "Download and extract the tarball of the stable ELPA repository if it used." + (when (and (assoc configuration-layer--stable-elpa-name + configuration-layer--elpa-archives) + (not (string-equal (configuration-layer/stable-elpa-version) + configuration-layer--stable-elpa-version))) + (let ((address (configuration-layer//stable-elpa-tarball-distant-file)) + (local (configuration-layer//stable-elpa-tarball-local-file))) + (spacemacs-buffer/set-mode-line + (format "Downloading stable ELPA repository: %s..." + configuration-layer--stable-elpa-name)) + (spacemacs//redisplay) + ;; download + (make-directory configuration-layer--stable-elpa-directory t) + (url-copy-file address local 'ok-if-already-exists) + ;; extract + (configuration-layer//stable-elpa-untar-archive) + ;; delete archive + (delete-file local) + ;; update version file + (with-current-buffer (find-file-noselect + configuration-layer--stable-elpa-version-file) + (erase-buffer) + (beginning-of-buffer) + (insert (format "%s" configuration-layer--stable-elpa-version)) + (save-buffer))))) + +;; (configuration-layer/create-elpa-repository +;; "spacelpa" +;; spacemacs-cache-directory) + (defun configuration-layer//package-install-org (func &rest args) "Advice around `package-install' to patch package name and dependencies at install time in order to replace all `org' package installation by diff --git a/core/core-spacemacs-buffer.el b/core/core-spacemacs-buffer.el index b827838ee..0ecf0d41c 100644 --- a/core/core-spacemacs-buffer.el +++ b/core/core-spacemacs-buffer.el @@ -13,7 +13,7 @@ ;; ;;; Code: -(defconst spacemacs-buffer-version-info "0.200.9" +(defconst spacemacs-buffer-version-info "0.300" "Current version used to display addition release information.") (defconst spacemacs-buffer-name "*spacemacs*" diff --git a/core/core-spacemacs.el b/core/core-spacemacs.el index 17f31e677..f5a262289 100644 --- a/core/core-spacemacs.el +++ b/core/core-spacemacs.el @@ -15,6 +15,7 @@ (require 'page-break-lines) (require 'core-debug) (require 'core-command-line) +(require 'core-configuration-layer) (require 'core-dotspacemacs) (require 'core-custom-settings) (require 'core-release-management) @@ -79,7 +80,6 @@ the final step of executing code in `emacs-startup-hook'.") ;; instead. evil-want-C-i-jump nil) (dotspacemacs/load-file) - (require 'core-configuration-layer) (dotspacemacs|call-func dotspacemacs/init "Calling dotfile init...") (when dotspacemacs-maximized-at-startup (unless (frame-parameter nil 'fullscreen) diff --git a/core/info/release-notes/0.300.txt b/core/info/release-notes/0.300.txt new file mode 100644 index 000000000..074635f61 --- /dev/null +++ b/core/info/release-notes/0.300.txt @@ -0,0 +1,40 @@ + ╭───────────────────────────────────────────────────────────╮ + + VERSION 0.300 IS ALMOST OUT! + + ╰───────────────────────────────────────────────────────────╯ + +The long awaited feature to have stable ELPA packages is now available in the +develop branch and we need to test it out before we release the 0.300 version. + +The stable ELPA repository is a Git repository, the official one is called +Spacelpa and it is hosted on GitHub here: + + https://github.com/syl20bnr/spacelpa + +In the end only the master branch will use the stable ELPA repository and the +develop branch will continue to use bleeding edge packages from MELPA +essentially. + +Unfortunately this new feature requires at least Emacs 25.1 to work correctly as +we need the archive priority feature of package.el that shipped with this +version of Emacs. + +The ELPA repository configuration is set in a new immutable file called .lock +that sits at the root of the Spacemacs git repository. + +Spacemacs downloads the whole ELPA stable repository locally so it means that +once it is installed you don't need an Internet connection anymore to install +any packages covered by Spacemacs layers! + +Default installation location of the ELPA stable repository is in: + + ~/.emacs.d/.cache/stable-elpa + +If you want to disable the ELPA stable repository put this in your dotfile in +the user-init function: + + (setq configuration-layer--elpa-archives + '(("melpa" . "melpa.org/packages/") + ("org" . "orgmode.org/elpa/") + ("gnu" . "elpa.gnu.org/packages/"))) diff --git a/init.el b/init.el index 68588b42a..88f30d884 100644 --- a/init.el +++ b/init.el @@ -26,7 +26,9 @@ (load-file (concat (file-name-directory load-file-name) "core/core-load-paths.el")) (require 'core-spacemacs) + (configuration-layer/load-lock-file) (spacemacs/init) + (configuration-layer/stable-elpa-download-tarball) (configuration-layer/load) (spacemacs-buffer/display-startup-note) (spacemacs/setup-startup-hook)