diff options
author | Alan Pearce | 2014-07-19 13:23:56 +0100 |
---|---|---|
committer | Alan Pearce | 2014-07-19 13:24:29 +0100 |
commit | 641f304fb878ecfb0a1afe2d6e62281d0e3e94ab (patch) | |
tree | 9ebc0654172c4350e05af6ef11ed378c5eac3674 /content | |
parent | df381720a8be75415b163fc8ecbd9a237ecdc4cc (diff) | |
download | website-641f304fb878ecfb0a1afe2d6e62281d0e3e94ab.tar.xz website-641f304fb878ecfb0a1afe2d6e62281d0e3e94ab.zip |
Write post about Emacs package archive statistics
Diffstat (limited to 'content')
-rw-r--r-- | content/post/emacs-package-archive-statistics.md | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/content/post/emacs-package-archive-statistics.md b/content/post/emacs-package-archive-statistics.md new file mode 100644 index 0000000..b610011 --- /dev/null +++ b/content/post/emacs-package-archive-statistics.md | |||
@@ -0,0 +1,168 @@ | |||
1 | +++ | ||
2 | Categories = ["Emacs"] | ||
3 | Description = "Working out which package archives I'm using" | ||
4 | Tags = ["Emacs"] | ||
5 | title = "Emacs Package Archive Statistics" | ||
6 | date = 2014-07-19T13:19:54Z | ||
7 | +++ | ||
8 | |||
9 | I use [cask][] for managing the dependencies of my Emacs | ||
10 | configuration. Whenever I opened my `Cask` file, I wondered if I | ||
11 | really was using all the sources I had defined: | ||
12 | |||
13 | {{% highlight cl %}} | ||
14 | (source gnu) | ||
15 | (source marmalade) | ||
16 | (source melpa) | ||
17 | (source melpa-stable) | ||
18 | (source org) | ||
19 | {{% /highlight %}} | ||
20 | |||
21 | It seemed quite strange that we have so many package repositories in | ||
22 | the Emacs world and I'm not even using all of them. I find this state | ||
23 | less than ideal, much as | ||
24 | [Jorgen Schäfer details][state of emacs package archives]. My ideal | ||
25 | package repository would be once that works with VCS releases, mostly | ||
26 | because it's a much simpler process to work with than having to sign | ||
27 | up to yet another website just to upload a package, then ensure it's | ||
28 | kept up-to-date on every release. | ||
29 | |||
30 | As such, I prefer the concepts behing [MELPA][] and [MELPA Stable][] to | ||
31 | those of [Marmalade][]. [GNU ELPA][] doesn't appear to allow any | ||
32 | submissions and [org][org archive] is specific to [org-mode]. I've | ||
33 | also noticed that many packages I find and use are on github and so | ||
34 | work with the [MELPA][] system. However, I don't like [MELPA's][MELPA] | ||
35 | versioning: it just gets the latest code and puts the build date in | ||
36 | the version, meaning that packages could break at any time. | ||
37 | |||
38 | So, ideally I would use [MELPA Stable][] as much as possible and reduce my | ||
39 | usage of [Marmalade][] and [MELPA][]. [GNU ELPA][] doesn't appear to have | ||
40 | many packages, but I wasn't sure if I was using any. | ||
41 | I couldn't see the information listed in the `*Packages*` buffer, so I | ||
42 | decided to try to figure out how to generate some usage statistics. | ||
43 | |||
44 | I found [how to get a list of installed packages][], but that just gives | ||
45 | a list: | ||
46 | |||
47 | {{% highlight cl %}} | ||
48 | (ace-jump-mode ag auto-compile auto-indent-mode autopair ...) | ||
49 | {{% /highlight %}} | ||
50 | |||
51 | I needed to get more information about those packages. I looked at | ||
52 | where `list-packages` gets that information from. It seems that | ||
53 | `package-archive-contents` is a list of cons cells: | ||
54 | |||
55 | {{% highlight cl %}} | ||
56 | (org-plus-contrib . | ||
57 | [(20140714) | ||
58 | nil "Outline-based notes management and organizer" tar "org"]) | ||
59 | {{% /highlight %}} | ||
60 | |||
61 | Then created a function to loop over the contents of | ||
62 | `package-activated-list`, retrieving the corresponding contents of | ||
63 | `package-archive-contents`: | ||
64 | |||
65 | {{% highlight cl %}} | ||
66 | (defun package-list-installed () | ||
67 | (loop for pkg in package-activated-list | ||
68 | collect (assq pkg package-archive-contents))) | ||
69 | {{% /highlight %}} | ||
70 | |||
71 | This generates a list of arrays from `package-archive-contents`. | ||
72 | There are some helper functions in package.el such as | ||
73 | `package-desc-kind`. `package-desc-archive` was exactly what I | ||
74 | needed. I happened to be using a pretest version of Emacs at the time | ||
75 | and didn't know that it's not in 24.3, so I just made sure it was defined: | ||
76 | |||
77 | {{% highlight cl %}} | ||
78 | (if (not (fboundp #'package-desc-archive)) | ||
79 | (defsubst package-desc-archive (desc) | ||
80 | (aref desc (1- (length desc))))) | ||
81 | {{% /highlight %}} | ||
82 | |||
83 | Weirdly, some of the arrays (seemingly the ones from the | ||
84 | [org archive][]) had a different length, but the repository/archive was | ||
85 | always the last element, which is why I used `(1- (length ))` and not | ||
86 | a constant, like the other `package-desc-*` functions. | ||
87 | |||
88 | To generate a list of statistics, I just needed to loop over the | ||
89 | installed packages from `package-list-installed` and update a count | ||
90 | for each archive: | ||
91 | |||
92 | {{% highlight cl %}} | ||
93 | (defun package-archive-stats () | ||
94 | (let ((archives (makehash)) | ||
95 | (assoc '())) | ||
96 | (dolist (arc package-archives) | ||
97 | (puthash (car arc) 0 archives)) | ||
98 | (maphash (lambda (k v) | ||
99 | (setq assoc (cons (cons k v) assoc))) | ||
100 | (dolist (pkg (-filter #'identity (package-list-installed)) archives) | ||
101 | (let ((pkg-arc (package-desc-archive (cdr pkg)))) | ||
102 | (incf (gethash pkg-arc archives))))) | ||
103 | assoc)) | ||
104 | {{% /highlight %}} | ||
105 | |||
106 | Running this gives a list of cons cells: | ||
107 | |||
108 | {{% highlight cl %}} | ||
109 | (("gnu" . 0) | ||
110 | ("org" . 1) | ||
111 | ("melpa-stable" . 2) | ||
112 | ("melpa" . 106) | ||
113 | ("marmalade" . 1)) | ||
114 | {{% /highlight %}} | ||
115 | |||
116 | I wrapped it in an interactive function so that I could check the | ||
117 | numbers quickly: | ||
118 | |||
119 | {{% highlight cl %}} | ||
120 | (defun package-show-archive-stats () | ||
121 | (interactive) | ||
122 | (message "%s" (package-archive-stats))) | ||
123 | {{% /highlight %}} | ||
124 | |||
125 | With that, I removed `(source gnu)` from my `Cask` file. Now I had | ||
126 | another question. What package was installed from [marmalade][]? In | ||
127 | the lisp fashion, I created yet another function: | ||
128 | |||
129 | {{% highlight cl %}} | ||
130 | (defun package-show-installed-from-archive (archive) | ||
131 | (interactive (list (helm-comp-read "Archive: " (mapcar #'car package-archives) | ||
132 | :must-match t))) | ||
133 | (let ((from-arc (mapcar #'car | ||
134 | (--filter (equalp (package-desc-archive (cdr it)) archive) | ||
135 | (package-list-installed))))) | ||
136 | (if (called-interactively-p) | ||
137 | (message "%s" from-arc) | ||
138 | from-arc))) | ||
139 | {{% /highlight %}} | ||
140 | (Non-helm users can replace `helm-comp-read` with | ||
141 | `ido-completing-read` or similar) | ||
142 | |||
143 | Running this with the argument `"marmalade"` gives: | ||
144 | |||
145 | {{% highlight cl %}} | ||
146 | (php-extras) | ||
147 | {{% /highlight %}} | ||
148 | |||
149 | I checked on [MELPA Stable][] and [MELPA][], but it's not available | ||
150 | there. Given that I use [php-extras][] quite a bit at work, I can't remove | ||
151 | [marmalade][] just yet. However, as it's a git repository, it should be | ||
152 | easy for me to create a recipe for MELPA. Then I can remove marmalade | ||
153 | from my [cask][] configuration. Hooray for simplification! | ||
154 | |||
155 | Hopefully, packaging in Emacs will become simpler in the future. | ||
156 | There are some interesting things in 24.4 like pinning packages to a | ||
157 | repository, which would allow [MELPA Stable][] to be used even when | ||
158 | [MELPA][] defines the same package with a higher "version". | ||
159 | |||
160 | [cask]: https://github.com/cask/cask/ | ||
161 | [state of emacs package archives]: http://blog.jorgenschaefer.de/2014/06/the-sorry-state-of-emacs-lisp-package.html | ||
162 | [marmalade]: http://marmalade-repo.org/ | ||
163 | [GNU ELPA]: http://elpa.gnu.org/packages/ | ||
164 | [MELPA]: http://hiddencameras.milkbox.net/ | ||
165 | [MELPA Stable]: http://melpa-stable.milkbox.net/ | ||
166 | [org archive]: http://orgmode.org/elpa.html | ||
167 | [how to get a list of installed packages]: http://stackoverflow.com/questions/13866848/how-to-save-a-list-of-all-the-installed-packages-in-emacs-24 | ||
168 | [php-extras]: https://github.com/arnested/php-extras | ||