Mercurial > hg > xemacs-beta
annotate lisp/package-get.el @ 5613:a944c124b2d3
Be more careful about what we shadow, #'byte-compile-eval.
2011-12-13 Aidan Kehoe <kehoea@parhasard.net>
* bytecomp.el (byte-compile-eval):
When evaluating code at compile time, don't put those macros in
the macro environment that only make sense when creating
byte-compiled output.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Tue, 13 Dec 2011 20:42:30 +0000 |
parents | 4dee0387b9de |
children | bbe4146603db |
rev | line source |
---|---|
428 | 1 ;;; package-get.el --- Retrieve XEmacs package |
2 | |
3 ;; Copyright (C) 1998 by Pete Ware | |
793 | 4 ;; Copyright (C) 2002 Ben Wing. |
1410 | 5 ;; Copyright (C) 2003, Steve Youngs |
428 | 6 |
7 ;; Author: Pete Ware <ware@cis.ohio-state.edu> | |
8 ;; Heavy-Modifications: Greg Klanderman <greg@alphatech.com> | |
9 ;; Jan Vroonhof <vroonhof@math.ethz.ch> | |
1410 | 10 ;; Steve Youngs <youngs@xemacs.org> |
428 | 11 ;; Keywords: internal |
12 | |
13 ;; This file is part of XEmacs. | |
14 | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4787
diff
changeset
|
15 ;; XEmacs is free software: you can redistribute it and/or modify it |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4787
diff
changeset
|
16 ;; under the terms of the GNU General Public License as published by the |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4787
diff
changeset
|
17 ;; Free Software Foundation, either version 3 of the License, or (at your |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4787
diff
changeset
|
18 ;; option) any later version. |
428 | 19 |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4787
diff
changeset
|
20 ;; XEmacs is distributed in the hope that it will be useful, but WITHOUT |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4787
diff
changeset
|
21 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4787
diff
changeset
|
22 ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4787
diff
changeset
|
23 ;; for more details. |
428 | 24 |
25 ;; You should have received a copy of the GNU General Public License | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4787
diff
changeset
|
26 ;; along with XEmacs. If not, see <http://www.gnu.org/licenses/>. |
428 | 27 |
28 ;;; Synched up with: Not in FSF | |
29 | |
30 ;;; Commentary: | |
31 | |
32 ;; package-get - | |
33 ;; Retrieve a package and any other required packages from an archive | |
34 ;; | |
35 ;; | |
440 | 36 ;; Note (JV): Most of this no longer applies! |
428 | 37 ;; |
38 ;; The idea: | |
39 ;; A new XEmacs lisp-only release is generated with the following steps: | |
40 ;; 1. The maintainer runs some yet to be written program that | |
41 ;; generates all the dependency information. This should | |
42 ;; determine all the require and provide statements and associate | |
43 ;; them with a package. | |
44 ;; 2. All the packages are then bundled into their own tar balls | |
45 ;; (or whatever format) | |
46 ;; 3. Maintainer automatically generates a new `package-get-base' | |
47 ;; data structure which contains information such as the | |
48 ;; package name, the file to be retrieved, an md5 checksum, | |
49 ;; etc (see `package-get-base'). | |
50 ;; 4. The maintainer posts an announcement with the new version | |
51 ;; of `package-get-base'. | |
52 ;; 5. A user/system manager saves this posting and runs | |
53 ;; `package-get-update' which uses the previously saved list | |
54 ;; of packages, `package-get-here' that the user/site | |
55 ;; wants to determine what new versions to download and | |
56 ;; install. | |
57 ;; | |
58 ;; A user/site manager can generate a new `package-get-here' structure | |
59 ;; by using `package-get-setup' which generates a customize like | |
60 ;; interface to the list of packages. The buffer looks something | |
61 ;; like: | |
62 ;; | |
63 ;; gnus - a mail and news reader | |
64 ;; [] Always install | |
65 ;; [] Needs updating | |
66 ;; [] Required by other [packages] | |
67 ;; version: 2.0 | |
68 ;; | |
69 ;; vm - a mail reader | |
70 ;; [] Always install | |
71 ;; [] Needs updating | |
442 | 72 ;; [] Required by other [packages] |
428 | 73 ;; |
74 ;; Where `[]' indicates a toggle box | |
75 ;; | |
76 ;; - Clicking on "Always install" puts this into | |
77 ;; `package-get-here' list. "Needs updating" indicates a new | |
78 ;; version is available. Anything already in | |
79 ;; `package-get-here' has this enabled. | |
80 ;; - "Required by other" means some other packages are going to force | |
81 ;; this to be installed. Clicking on [packages] gives a list | |
82 ;; of packages that require this. | |
442 | 83 ;; |
428 | 84 ;; The `package-get-base' should be installed in a file in |
85 ;; `data-directory'. The `package-get-here' should be installed in | |
86 ;; site-lisp. Both are then read at run time. | |
87 ;; | |
88 ;; TODO: | |
89 ;; - Implement `package-get-setup' | |
90 ;; - Actually put `package-get-base' and `package-get-here' into | |
91 ;; files that are read. | |
92 ;; - Allow users to have their own packages that they want installed | |
93 ;; in ~/.xemacs/. | |
94 ;; - SOMEONE needs to write the programs that generate the | |
95 ;; provides/requires database and makes it into a lisp data | |
96 ;; structure suitable for `package-get-base' | |
97 ;; - Handle errors such as no package providing a required symbol. | |
98 ;; - Tie this into the `require' function to download packages | |
99 ;; transparently. | |
100 | |
101 ;;; Change Log | |
102 | |
103 ;;; Code: | |
104 | |
105 (require 'package-admin) | |
106 ;; (require 'package-get-base) | |
107 | |
108 (defgroup package-tools nil | |
109 "Tools to manipulate packages." | |
110 :group 'emacs) | |
111 | |
112 (defgroup package-get nil | |
113 "Automatic Package Fetcher and Installer." | |
114 :prefix "package-get" | |
115 :group 'package-tools) | |
116 | |
442 | 117 ;;;###autoload |
428 | 118 (defvar package-get-base nil |
119 "List of packages that are installed at this site. | |
120 For each element in the alist, car is the package name and the cdr is | |
121 a plist containing information about the package. Typical fields | |
122 kept in the plist are: | |
123 | |
124 version - version of this package | |
125 provides - list of symbols provided | |
126 requires - list of symbols that are required. | |
127 These in turn are provided by other packages. | |
128 filename - name of the file. | |
129 size - size of the file (aka the bundled package) | |
130 md5sum - computed md5 checksum | |
131 description - What this package is for. | |
132 type - Whether this is a 'binary (default) or 'single file package | |
133 | |
134 More fields may be added as needed. An example: | |
135 | |
136 '( | |
137 (name | |
138 (version \"<version 2>\" | |
139 file \"filename\" | |
140 description \"what this package is about.\" | |
141 provides (<list>) | |
142 requires (<list>) | |
143 size <integer-bytes> | |
144 md5sum \"<checksum\" | |
145 type single | |
146 ) | |
147 (version \"<version 1>\" | |
148 file \"filename\" | |
149 description \"what this package is about.\" | |
150 provides (<list>) | |
151 requires (<list>) | |
152 size <integer-bytes> | |
153 md5sum \"<checksum\" | |
154 type single | |
155 ) | |
156 ... | |
157 )) | |
158 | |
159 For version information, it is assumed things are listed in most | |
160 recent to least recent -- in other words, the version names don't have to | |
161 be lexically ordered. It is debatable if it makes sense to have more than | |
162 one version of a package available.") | |
163 | |
164 (defcustom package-get-dir (temp-directory) | |
165 "*Where to store temporary files for staging." | |
166 :tag "Temporary directory" | |
167 :type 'directory | |
168 :group 'package-get) | |
169 | |
1378 | 170 ;;;###autoload |
1483 | 171 (defcustom package-get-package-index-file-location |
3179 | 172 (cond |
173 ;; historical backage | |
174 ((getenv "EMACSPACKAGEPATH") | |
175 (split-path (getenv "EMACSPACKAGEPATH"))) | |
176 ((getenv "EMACSEARLYPACKAGES") | |
177 (split-path (getenv "EMACSEARLYPACKAGES"))) | |
178 (configure-early-package-directories | |
179 (car configure-early-package-directories)) | |
180 (t | |
181 user-init-directory)) | |
1483 | 182 "*The directory where the package-index file can be found." |
183 :type 'directory | |
184 :group 'package-get) | |
185 | |
186 ;;;###autoload | |
1378 | 187 (defcustom package-get-install-to-user-init-directory nil |
188 "*If non-nil install packages under `user-init-directory'." | |
189 :type 'boolean | |
190 :group 'package-get) | |
191 | |
428 | 192 (define-widget 'host-name 'string |
193 "A Host name." | |
194 :tag "Host") | |
195 | |
196 (defcustom package-get-remote nil | |
1365 | 197 "*The remote site to contact for downloading packages. |
198 Format is '(site-name directory-on-site). As a special case, `site-name' | |
199 can be `nil', in which case `directory-on-site' is treated as a local | |
200 directory." | |
428 | 201 :tag "Package repository" |
1365 | 202 :type '(set (choice (const :tag "None" nil) |
203 (list :tag "Local" (const :tag "Local" nil) directory) | |
204 (list :tag "Remote" host-name directory))) | |
428 | 205 :group 'package-get) |
206 | |
207 ;;;###autoload | |
208 (defcustom package-get-download-sites | |
209 '( | |
1365 | 210 ;; Main XEmacs Site (ftp.xemacs.org) |
1368 | 211 ("US (Main XEmacs Site)" |
1365 | 212 "ftp.xemacs.org" "pub/xemacs/packages") |
213 ;; In alphabetical order of Country, our mirrors... | |
3013 | 214 ("Argentina (xmundo.net)" "xemacs.xmundo.net" "pub/mirrors/xemacs/packages") |
1365 | 215 ("Australia (aarnet.edu.au)" "mirror.aarnet.edu.au" "pub/xemacs/packages") |
216 ("Australia (au.xemacs.org)" "ftp.au.xemacs.org" "pub/xemacs/packages") | |
217 ("Austria (at.xemacs.org)" "ftp.at.xemacs.org" "editors/xemacs/packages") | |
218 ("Belgium (be.xemacs.org)" "ftp.be.xemacs.org" "xemacs/packages") | |
219 ("Brazil (br.xemacs.org)" "ftp.br.xemacs.org" "pub/xemacs/packages") | |
220 ("Canada (ca.xemacs.org)" "ftp.ca.xemacs.org" "pub/Mirror/xemacs/packages") | |
3013 | 221 ("Canada (nrc.ca)" "ftp.nrc.ca" "pub/packages/editors/xemacs/packages") |
4120 | 222 ;; no anonymous ftp available, uncomment when updating website |
223 ;; with | |
224 ;; xemacs-builds/adrian/website/package-get-2-download-sites.el | |
4082 | 225 ; ("Chile (cl.xemacs.org)" "ftp.cl.xemacs.org" "packages") |
4188 | 226 ("China (ftp.cn.xemacs.org)" "ftp.cn.xemacs.org" "pub/xemacs/packages") |
1365 | 227 ("Czech Republic (cz.xemacs.org)" "ftp.cz.xemacs.org" "MIRRORS/ftp.xemacs.org/pub/xemacs/packages") |
228 ("Finland (fi.xemacs.org)" "ftp.fi.xemacs.org" "pub/mirrors/ftp.xemacs.org/pub/tux/xemacs/packages") | |
229 ("France (fr.xemacs.org)" "ftp.fr.xemacs.org" "pub/xemacs/packages") | |
1368 | 230 ("France (mirror.cict.fr)" "mirror.cict.fr" "xemacs/packages") |
1365 | 231 ("France (pasteur.fr)" "ftp.pasteur.fr" "pub/computing/xemacs/packages") |
232 ("Germany (de.xemacs.org)" "ftp.de.xemacs.org" "pub/ftp.xemacs.org/tux/xemacs/packages") | |
4034 | 233 ("Greece (gr.xemacs.org)" "ftp.gr.xemacs.org" "mirrors/XEmacs/ftp/packages") |
3141 | 234 ("Hong Kong (hk.xemacs.org)" "ftp.hk.xemacs.org" "pub/xemacsftp/packages") |
1365 | 235 ("Ireland (ie.xemacs.org)" "ftp.ie.xemacs.org" "mirrors/ftp.xemacs.org/pub/xemacs/packages") |
3013 | 236 ("Ireland (heanet.ie)" "ftp.heanet.ie" "mirrors/ftp.xemacs.org/packages") |
1365 | 237 ("Italy (it.xemacs.org)" "ftp.it.xemacs.org" "unix/packages/XEMACS/packages") |
238 ("Japan (dti.ad.jp)" "ftp.dti.ad.jp" "pub/unix/editor/xemacs/packages") | |
3116 | 239 ; ("Japan (jaist.ac.jp)" "ftp.jaist.ac.jp" "pub/GNU/xemacs/packages") |
4132 | 240 ("Japan (jp.xemacs.org)" "ftp.jp.xemacs.org" "pub/text/xemacs/packages") |
3013 | 241 ; ("Japan (nucba.ac.jp)" "mirror.nucba.ac.jp" "mirror/xemacs/packages") |
1374 | 242 ("Korea (kr.xemacs.org)" "ftp.kr.xemacs.org" "pub/tools/emacs/xemacs/packages") |
3438 | 243 ("Netherlands (nl.xemacs.org)" "ftp.nl.xemacs.org" "pub/xemacs/ftp/packages") |
4184 | 244 ;; no anonymous ftp available, uncomment when updating website |
245 ;; with | |
246 ;; xemacs-builds/adrian/website/package-get-2-download-sites.el | |
247 ; ("Netherlands (xemacsftp.digimirror.nl)" "xemacsftp.digimirror.nl" "packages") | |
1365 | 248 ("Norway (no.xemacs.org)" "ftp.no.xemacs.org" "pub/xemacs/packages") |
3193 | 249 ("Portugal (pt.xemacs.org)" "ftp.pt.xemacs.org" "pub/MIRRORS/ftp.xemacs.org/packages") |
3116 | 250 ("Russia (ru.xemacs.org)" "ftp.ru.xemacs.org" "pub/emacs/xemacs/packages") |
4009 | 251 ("Saudi Arabia (sa.xemacs.org)" "ftp.sa.xemacs.org" "pub/xemacs.org/packages") |
1365 | 252 ("Sweden (se.xemacs.org)" "ftp.se.xemacs.org" "pub/gnu/xemacs/packages") |
253 ("Switzerland (ch.xemacs.org)" "ftp.ch.xemacs.org" "mirror/xemacs/packages") | |
3021 | 254 ("Taiwan (ftp.tw.xemacs.org)" "ftp.tw.xemacs.org" "Unix/Editors/XEmacs/packages") |
1365 | 255 ("UK (uk.xemacs.org)" "ftp.uk.xemacs.org" "sites/ftp.xemacs.org/pub/xemacs/packages") |
3021 | 256 ("US (ibiblio.org)" "mirrors.ibiblio.org" "pub/mirrors/xemacs/packages") |
4120 | 257 ("US (us.xemacs.org)" "ftp.us.xemacs.org" "pub/mirrors/xemacs/packages") |
3116 | 258 ) |
428 | 259 "*List of remote sites available for downloading packages. |
260 List format is '(site-description site-name directory-on-site). | |
261 SITE-DESCRIPTION is a textual description of the site. SITE-NAME | |
262 is the internet address of the download site. DIRECTORY-ON-SITE | |
263 is the directory on the site in which packages may be found. | |
264 This variable is used to initialize `package-get-remote', the | |
265 variable actually used to specify package download sites." | |
266 :tag "Package download sites" | |
442 | 267 :type '(repeat (list (string :tag "Name") host-name directory)) |
428 | 268 :group 'package-get) |
269 | |
1365 | 270 ;;;###autoload |
271 (defcustom package-get-pre-release-download-sites | |
272 '( | |
273 ;; Main XEmacs Site (ftp.xemacs.org) | |
3116 | 274 ("US Pre-Releases (Main XEmacs Site)" "ftp.xemacs.org" |
1365 | 275 "pub/xemacs/beta/experimental/packages") |
276 ;; In alphabetical order of Country, our mirrors... | |
3013 | 277 ("Argentina Pre-Releases (xmundo.net)" "xemacs.xmundo.net" |
278 "pub/mirrors/xemacs/beta/experimental/packages") | |
1368 | 279 ("Australia Pre-Releases (aarnet.edu.au)" "mirror.aarnet.edu.au" |
1365 | 280 "pub/xemacs/beta/experimental/packages") |
1368 | 281 ("Australia Pre-Releases (au.xemacs.org)" "ftp.au.xemacs.org" |
1365 | 282 "pub/xemacs/beta/experimental/packages") |
1368 | 283 ("Austria Pre-Releases (at.xemacs.org)" "ftp.at.xemacs.org" |
3013 | 284 "editors/xemacs/beta/experimental/packages") |
4184 | 285 ("Belgium Pre-Releases (be.xemacs.org)" "ftp.be.xemacs.org" |
3013 | 286 "xemacs/beta/experimental/packages") |
1368 | 287 ("Brazil Pre-Releases (br.xemacs.org)" "ftp.br.xemacs.org" |
1365 | 288 "pub/xemacs/xemacs-21.5/experimental/packages") |
1368 | 289 ("Canada Pre-Releases (ca.xemacs.org)" "ftp.ca.xemacs.org" |
1365 | 290 "pub/Mirror/xemacs/beta/experimental/packages") |
3013 | 291 ("Canada Pre-Releases (nrc.ca)" "ftp.nrc.ca" |
292 "pub/packages/editors/xemacs/beta/experimental/packages") | |
4120 | 293 ;; no anonymous ftp available, uncomment when updating website |
294 ;; with | |
295 ;; xemacs-builds/adrian/website/package-get-2-download-sites.el | |
4082 | 296 ; ("Chile Pre-Releases (cl.xemacs.org)" "ftp.cl.xemacs.org" |
297 ; "beta/experimental/packages") | |
4188 | 298 ("China Pre-Releases (ftp.cn.xemacs.org)" "ftp.cn.xemacs.org" |
4184 | 299 "pub/xemacs/beta/experimental/packages") |
1368 | 300 ("Czech Republic Pre-Releases (cz.xemacs.org)" "ftp.cz.xemacs.org" |
1365 | 301 "MIRRORS/ftp.xemacs.org/pub/xemacs/xemacs-21.5/experimental/packages") |
1368 | 302 ("Finland Pre-Releases (fi.xemacs.org)" "ftp.fi.xemacs.org" |
1365 | 303 "pub/mirrors/ftp.xemacs.org/pub/tux/xemacs/beta/experimental/packages") |
1368 | 304 ("France Pre-Releases (fr.xemacs.org)" "ftp.fr.xemacs.org" |
1365 | 305 "pub/xemacs/beta/experimental/packages") |
1368 | 306 ("France Pre-Releases (mirror.cict.fr)" "mirror.cict.fr" |
307 "xemacs/beta/experimental/packages") | |
308 ("France Pre-Releases (pasteur.fr)" "ftp.pasteur.fr" | |
1365 | 309 "pub/computing/xemacs/beta/experimental/packages") |
1368 | 310 ("Germany Pre-Releases (de.xemacs.org)" "ftp.de.xemacs.org" |
1365 | 311 "pub/ftp.xemacs.org/tux/xemacs/beta/experimental/packages") |
4034 | 312 ("Greece Pre-Releases (gr.xemacs.org)" "ftp.gr.xemacs.org" |
313 "mirrors/XEmacs/ftp/beta/experimental/packages") | |
3141 | 314 ("Hong Kong Pre-Releases (hk.xemacs.org)" "ftp.hk.xemacs.org" |
315 "pub/xemacsftp/beta/experimental/packages") | |
1368 | 316 ("Ireland Pre-Releases (ie.xemacs.org)" "ftp.ie.xemacs.org" |
1365 | 317 "mirrors/ftp.xemacs.org/pub/xemacs/beta/experimental/packages") |
3013 | 318 ("Ireland Pre-Releases (heanet.ie)" "ftp.heanet.ie" |
319 "mirrors/ftp.xemacs.org/beta/experimental/packages") | |
1368 | 320 ("Italy Pre-Releases (it.xemacs.org)" "ftp.it.xemacs.org" |
1365 | 321 "unix/packages/XEMACS/beta/experimental/packages") |
1368 | 322 ("Japan Pre-Releases (dti.ad.jp)" "ftp.dti.ad.jp" |
1365 | 323 "pub/unix/editor/xemacs/beta/experimental/packages") |
3116 | 324 ; ("Japan Pre-Releases (jaist.ac.jp)" "ftp.jaist.ac.jp" |
325 ; "pub/GNU/xemacs/beta/experimental/packages") | |
4132 | 326 ("Japan Pre-Releases (jp.xemacs.org)" "ftp.jp.xemacs.org" |
327 "pub/text/xemacs/beta/experimental/packages") | |
4184 | 328 ("Korea Pre-Releases (kr.xemacs.org)" "ftp.kr.xemacs.org" |
3013 | 329 "pub/tools/emacs/xemacs/beta/experimental/packages") |
4184 | 330 ("Netherlands Pre-Releases (nl.xemacs.org)" "ftp.nl.xemacs.org" |
3438 | 331 "pub/xemacs/ftp/beta/experimental/packages") |
4184 | 332 ;; no anonymous ftp available, uncomment when updating website |
333 ;; with | |
334 ;; xemacs-builds/adrian/website/package-get-2-download-sites.el | |
335 ; ("Netherlands Pre-Releases (xemacsftp.digimirror.nl)" "xemacsftp.digimirror.nl" | |
336 ; "beta/experimental/packages") | |
1368 | 337 ("Norway Pre-Releases (no.xemacs.org)" "ftp.no.xemacs.org" |
1365 | 338 "pub/xemacs/beta/experimental/packages") |
3193 | 339 ("Portugal Pre-Releases (pt.xemacs.org)" "ftp.pt.xemacs.org" |
340 "pub/MIRRORS/ftp.xemacs.org/beta/experimental/packages") | |
1368 | 341 ("Russia Pre-Releases (ru.xemacs.org)" "ftp.ru.xemacs.org" |
3116 | 342 "pub/emacs/xemacs/beta/experimental/packages") |
4184 | 343 ("Saudi Arabia Pre-Releases (sa.xemacs.org)" "ftp.sa.xemacs.org" |
4009 | 344 "pub/xemacs.org/beta/experimental/packages") |
1368 | 345 ("Sweden Pre-Releases (se.xemacs.org)" "ftp.se.xemacs.org" |
1365 | 346 "pub/gnu/xemacs/beta/experimental/packages") |
1368 | 347 ("Switzerland Pre-Releases (ch.xemacs.org)" "ftp.ch.xemacs.org" |
1365 | 348 "mirror/xemacs/beta/experimental/packages") |
3021 | 349 ("Taiwan Pre-Releases (ftp.tw.xemacs.org)" "ftp.tw.xemacs.org" |
350 "Unix/Editors/XEmacs/beta/experimental/packages") | |
1368 | 351 ("UK Pre-Releases (uk.xemacs.org)" "ftp.uk.xemacs.org" |
1365 | 352 "sites/ftp.xemacs.org/pub/xemacs/beta/experimental/packages") |
3021 | 353 ("US Pre-Releases (ibiblio.org)" "mirrors.ibiblio.org" |
354 "pub/mirrors/xemacs/beta/experimental/packages") | |
1368 | 355 ("US Pre-Releases (us.xemacs.org)" "ftp.us.xemacs.org" |
4120 | 356 "pub/mirrors/xemacs/beta/experimental/packages") |
4132 | 357 ) |
1365 | 358 "*List of remote sites available for downloading \"Pre-Release\" packages. |
359 List format is '(site-description site-name directory-on-site). | |
360 SITE-DESCRIPTION is a textual description of the site. SITE-NAME | |
361 is the internet address of the download site. DIRECTORY-ON-SITE | |
362 is the directory on the site in which packages may be found. | |
363 This variable is used to initialize `package-get-remote', the | |
364 variable actually used to specify package download sites." | |
365 :tag "Pre-Release Package download sites" | |
366 :type '(repeat (list (string :tag "Name") host-name directory)) | |
367 :group 'package-get) | |
368 | |
1374 | 369 ;;;###autoload |
370 (defcustom package-get-site-release-download-sites | |
371 nil | |
372 "*List of remote sites available for downloading \"Site Release\" packages. | |
373 List format is '(site-description site-name directory-on-site). | |
374 SITE-DESCRIPTION is a textual description of the site. SITE-NAME | |
375 is the internet address of the download site. DIRECTORY-ON-SITE | |
376 is the directory on the site in which packages may be found. | |
377 This variable is used to initialize `package-get-remote', the | |
378 variable actually used to specify package download sites." | |
379 :tag "Site Release Package download sites" | |
380 :type '(repeat (list (string :tag "Name") host-name directory)) | |
381 :group 'package-get) | |
382 | |
428 | 383 (defcustom package-get-remove-copy t |
384 "*After copying and installing a package, if this is t, then remove the | |
385 copy. Otherwise, keep it around." | |
386 :type 'boolean | |
387 :group 'package-get) | |
388 | |
389 ;; #### it may make sense for this to be a list of names. | |
390 ;; #### also, should we rename "*base*" to "*index*" or "*db*"? | |
391 ;; "base" is a pretty poor name. | |
681 | 392 (defcustom package-get-base-filename "package-index.LATEST.gpg" |
428 | 393 "*Name of the default package-get database file. |
394 This may either be a relative path, in which case it is interpreted | |
395 with respect to `package-get-remote', or an absolute path." | |
396 :type 'file | |
397 :group 'package-get) | |
398 | |
399 (defcustom package-get-always-update nil | |
400 "*If Non-nil always make sure we are using the latest package index (base). | |
401 Otherwise respect the `force-current' argument of `package-get-require-base'." | |
402 :type 'boolean | |
403 :group 'package-get) | |
404 | |
681 | 405 (defvar package-get-continue-update-base nil |
406 "Non-nil update the index even if it hasn't been signed.") | |
407 | |
428 | 408 (defvar package-get-was-current nil |
409 "Non-nil we did our best to fetch a current database.") | |
410 | |
411 ;;;###autoload | |
412 (defun package-get-require-base (&optional force-current) | |
413 "Require that a package-get database has been loaded. | |
414 If the optional FORCE-CURRENT argument or the value of | |
415 `package-get-always-update' is Non-nil, try to update the database | |
416 from a location in `package-get-remote'. Otherwise a local copy is used | |
417 if available and remote access is never done. | |
418 | |
5384
3889ef128488
Fix misspelled words, and some grammar, across the entire source tree.
Jerry James <james@xemacs.org>
parents:
5344
diff
changeset
|
419 Please use FORCE-CURRENT only when the user is explicitly dealing with packages |
428 | 420 and remote access is likely in the near future." |
421 (setq force-current (or force-current package-get-always-update)) | |
422 (unless (and (boundp 'package-get-base) | |
423 package-get-base | |
424 (or (not force-current) package-get-was-current)) | |
425 (package-get-update-base nil force-current)) | |
426 (if (or (not (boundp 'package-get-base)) | |
427 (not package-get-base)) | |
1410 | 428 (error 'void-variable |
429 "Package-get database not loaded") | |
428 | 430 (setq package-get-was-current force-current))) |
431 | |
432 ;;;###autoload | |
433 (defun package-get-update-base-entry (entry) | |
434 "Update an entry in `package-get-base'." | |
435 (let ((existing (assq (car entry) package-get-base))) | |
436 (if existing | |
437 (setcdr existing (cdr entry)) | |
824 | 438 (setq package-get-base (cons entry package-get-base))))) |
428 | 439 |
440 (defun package-get-locate-file (file &optional nil-if-not-found no-remote) | |
441 "Locate an existing FILE with respect to `package-get-remote'. | |
442 If FILE is an absolute path or is not found, simply return FILE. | |
443 If optional argument NIL-IF-NOT-FOUND is non-nil, return nil | |
444 if FILE can not be located. | |
445 If NO-REMOTE is non-nil never search remote locations." | |
446 (if (file-name-absolute-p file) | |
447 file | |
1365 | 448 (let ((site package-get-remote) |
428 | 449 (expanded nil)) |
1365 | 450 (when site |
451 (unless (and no-remote (caar (list site))) | |
452 (let ((expn (package-get-remote-filename (car (list site)) file))) | |
428 | 453 (if (and expn (file-exists-p expn)) |
1365 | 454 (setq site nil |
455 expanded expn))))) | |
428 | 456 (or expanded |
457 (and (not nil-if-not-found) | |
458 file))))) | |
459 | |
460 (defun package-get-locate-index-file (no-remote) | |
1483 | 461 "Locate the package-get index file. |
462 | |
463 Do not return remote paths if NO-REMOTE is non-nil. If the index | |
464 file doesn't exist in `package-get-package-index-file-location', ask | |
465 the user if one should be created using the index file in core as a | |
466 template." | |
428 | 467 (or (package-get-locate-file package-get-base-filename t no-remote) |
1483 | 468 (if (file-exists-p (expand-file-name package-get-base-filename |
469 package-get-package-index-file-location)) | |
470 (expand-file-name package-get-base-filename | |
471 package-get-package-index-file-location) | |
472 (if (y-or-n-p (format "No index file, shall I create one in %s? " | |
473 package-get-package-index-file-location)) | |
474 (progn | |
475 (save-excursion | |
476 (set-buffer | |
477 (find-file-noselect (expand-file-name | |
478 package-get-base-filename | |
479 package-get-package-index-file-location))) | |
480 (let ((coding-system-for-write 'binary)) | |
481 (erase-buffer) | |
482 (insert-file-contents-literally | |
483 (locate-data-file package-get-base-filename)) | |
484 (save-buffer (current-buffer)) | |
485 (kill-buffer (current-buffer)))) | |
486 (expand-file-name package-get-base-filename | |
487 package-get-package-index-file-location)) | |
488 (error 'search-failed | |
489 "Can't locate a package index file."))))) | |
428 | 490 |
491 (defun package-get-maybe-save-index (filename) | |
492 "Offer to save the current buffer as the local package index file, | |
493 if different." | |
494 (let ((location (package-get-locate-index-file t))) | |
495 (unless (and filename (equal filename location)) | |
496 (unless (and location | |
497 (equal (md5 (current-buffer)) | |
498 (with-temp-buffer | |
499 (insert-file-contents-literally location) | |
500 (md5 (current-buffer))))) | |
1483 | 501 (when (not (file-writable-p location)) |
502 (if (y-or-n-p (format "Sorry, %s is read-only, can I use %s? " | |
503 location user-init-directory)) | |
504 (setq location (expand-file-name | |
505 package-get-base-filename | |
506 package-get-package-index-file-location)) | |
507 (error 'file-error | |
508 (format "%s is read-only" location)))) | |
434 | 509 (when (y-or-n-p (concat "Update package index in " location "? ")) |
442 | 510 (let ((coding-system-for-write 'binary)) |
511 (write-file location))))))) | |
512 | |
428 | 513 ;;;###autoload |
514 (defun package-get-update-base (&optional db-file force-current) | |
515 "Update the package-get database file with entries from DB-FILE. | |
516 Unless FORCE-CURRENT is non-nil never try to update the database." | |
517 (interactive | |
518 (let ((dflt (package-get-locate-index-file nil))) | |
519 (list (read-file-name "Load package-get database: " | |
520 (file-name-directory dflt) | |
521 dflt | |
522 t | |
523 (file-name-nondirectory dflt))))) | |
524 (setq db-file (expand-file-name (or db-file | |
525 (package-get-locate-index-file | |
526 (not force-current))))) | |
527 (if (not (file-exists-p db-file)) | |
1410 | 528 (error 'file-error |
529 (format "Package-get database file `%s' does not exist" db-file))) | |
428 | 530 (if (not (file-readable-p db-file)) |
1410 | 531 (error 'file-error |
532 (format "Package-get database file `%s' not readable" db-file))) | |
428 | 533 (let ((buf (get-buffer-create "*package database*"))) |
534 (unwind-protect | |
535 (save-excursion | |
536 (set-buffer buf) | |
537 (erase-buffer buf) | |
442 | 538 (insert-file-contents-literally db-file) |
428 | 539 (package-get-update-base-from-buffer buf) |
540 (if (file-remote-p db-file) | |
541 (package-get-maybe-save-index db-file))) | |
542 (kill-buffer buf)))) | |
543 | |
544 ;;;###autoload | |
545 (defun package-get-update-base-from-buffer (&optional buf) | |
546 "Update the package-get database with entries from BUFFER. | |
547 BUFFER defaults to the current buffer. This command can be | |
548 used interactively, for example from a mail or news buffer." | |
549 (interactive) | |
550 (setq buf (or buf (current-buffer))) | |
1937 | 551 (let ((coding-system-for-read 'binary) |
552 (coding-system-for-write 'binary) | |
553 content-beg content-end) | |
428 | 554 (save-excursion |
555 (set-buffer buf) | |
556 (goto-char (point-min)) | |
557 (setq content-beg (point)) | |
558 (setq content-end (save-excursion (goto-char (point-max)) (point))) | |
4160 | 559 (package-get-update-base-entries content-beg content-end) |
560 (message "Updated package database")))) | |
428 | 561 |
444 | 562 (defun package-get-update-base-entries (start end) |
428 | 563 "Update the package-get database with the entries found between |
444 | 564 START and END in the current buffer." |
428 | 565 (save-excursion |
444 | 566 (goto-char start) |
428 | 567 (if (not (re-search-forward "^(package-get-update-base-entry" nil t)) |
1410 | 568 (error 'search-failed |
569 "Buffer does not contain package-get database entries")) | |
428 | 570 (beginning-of-line) |
571 (let ((count 0)) | |
572 (while (and (< (point) end) | |
573 (re-search-forward "^(package-get-update-base-entry" nil t)) | |
574 (beginning-of-line) | |
575 (let ((entry (read (current-buffer)))) | |
576 (if (or (not (consp entry)) | |
577 (not (eq (car entry) 'package-get-update-base-entry))) | |
1410 | 578 (error 'syntax-error |
579 "Invalid package-get database entry found")) | |
428 | 580 (package-get-update-base-entry |
581 (car (cdr (car (cdr entry))))) | |
582 (setq count (1+ count)))) | |
583 (message "Got %d package-get database entries" count)))) | |
584 | |
585 ;;;###autoload | |
586 (defun package-get-save-base (file) | |
587 "Write the package-get database to FILE. | |
588 | |
589 Note: This database will be unsigned of course." | |
590 (interactive "FSave package-get database to: ") | |
591 (package-get-require-base t) | |
592 (let ((buf (get-buffer-create "*package database*"))) | |
593 (unwind-protect | |
594 (save-excursion | |
595 (set-buffer buf) | |
596 (erase-buffer buf) | |
597 (goto-char (point-min)) | |
598 (let ((entries package-get-base) entry plist) | |
599 (insert ";; Package Index file -- Do not edit manually.\n") | |
600 (insert ";;;@@@\n") | |
601 (while entries | |
602 (setq entry (car entries)) | |
603 (setq plist (car (cdr entry))) | |
604 (insert "(package-get-update-base-entry (quote\n") | |
605 (insert (format "(%s\n" (symbol-name (car entry)))) | |
606 (while plist | |
607 (insert (format " %s%s %S\n" | |
608 (if (eq plist (car (cdr entry))) "(" " ") | |
609 (symbol-name (car plist)) | |
610 (car (cdr plist)))) | |
611 (setq plist (cdr (cdr plist)))) | |
612 (insert "))\n))\n;;;@@@\n") | |
613 (setq entries (cdr entries)))) | |
614 (insert ";; Package Index file ends here\n") | |
615 (write-region (point-min) (point-max) file)) | |
616 (kill-buffer buf)))) | |
617 | |
618 (defun package-get-interactive-package-query (get-version package-symbol) | |
619 "Perform interactive querying for package and optional version. | |
620 Query for a version if GET-VERSION is non-nil. Return package name as | |
621 a symbol instead of a string if PACKAGE-SYMBOL is non-nil. | |
622 The return value is suitable for direct passing to `interactive'." | |
623 (package-get-require-base t) | |
442 | 624 (let ((table (mapcar #'(lambda (item) |
625 (let ((name (symbol-name (car item)))) | |
626 (cons name name))) | |
627 package-get-base)) | |
628 package package-symbol default-version version) | |
428 | 629 (save-window-excursion |
630 (setq package (completing-read "Package: " table nil t)) | |
631 (setq package-symbol (intern package)) | |
632 (if get-version | |
633 (progn | |
442 | 634 (setq default-version |
635 (package-get-info-prop | |
428 | 636 (package-get-info-version |
637 (package-get-info-find-package package-get-base | |
638 package-symbol) nil) | |
639 'version)) | |
640 (while (string= | |
641 (setq version (read-string "Version: " default-version)) | |
1365 | 642 "")) |
428 | 643 (if package-symbol |
644 (list package-symbol version) | |
1365 | 645 (list package version))) |
428 | 646 (if package-symbol |
647 (list package-symbol) | |
442 | 648 (list package)))))) |
428 | 649 |
650 ;;;###autoload | |
651 (defun package-get-delete-package (package &optional pkg-topdir) | |
652 "Delete an installation of PACKAGE below directory PKG-TOPDIR. | |
653 PACKAGE is a symbol, not a string. | |
654 This is just an interactive wrapper for `package-admin-delete-binary-package'." | |
655 (interactive (package-get-interactive-package-query nil t)) | |
656 (package-admin-delete-binary-package package pkg-topdir)) | |
657 | |
658 ;;;###autoload | |
659 (defun package-get-update-all () | |
660 "Fetch and install the latest versions of all currently installed packages." | |
661 (interactive) | |
662 (package-get-require-base t) | |
663 ;; Load a fresh copy | |
664 (catch 'exit | |
4783
e29fcfd8df5f
Eliminate most core code byte-compile warnings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4188
diff
changeset
|
665 (mapc (lambda (pkg) |
e29fcfd8df5f
Eliminate most core code byte-compile warnings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4188
diff
changeset
|
666 (if (not (package-get (car pkg) nil 'never)) |
e29fcfd8df5f
Eliminate most core code byte-compile warnings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4188
diff
changeset
|
667 (throw 'exit nil))) ;; Bail out if error detected |
e29fcfd8df5f
Eliminate most core code byte-compile warnings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4188
diff
changeset
|
668 packages-package-list)) |
707 | 669 (package-net-update-installed-db)) |
428 | 670 |
671 ;;;###autoload | |
672 (defun package-get-all (package version &optional fetched-packages install-dir) | |
673 "Fetch PACKAGE with VERSION and all other required packages. | |
674 Uses `package-get-base' to determine just what is required and what | |
675 package provides that functionality. If VERSION is nil, retrieves | |
676 latest version. Optional argument FETCHED-PACKAGES is used to keep | |
677 track of packages already fetched. Optional argument INSTALL-DIR, | |
678 if non-nil, specifies the package directory where fetched packages | |
679 should be installed. | |
680 | |
681 Returns nil upon error." | |
682 (interactive (package-get-interactive-package-query t nil)) | |
683 (let* ((the-package (package-get-info-find-package package-get-base | |
684 package)) | |
685 (this-package (package-get-info-version | |
686 the-package version)) | |
1365 | 687 (this-requires (package-get-info-prop this-package 'requires))) |
428 | 688 (catch 'exit |
689 (setq version (package-get-info-prop this-package 'version)) | |
690 (unless (package-get-installedp package version) | |
691 (if (not (package-get package version nil install-dir)) | |
692 (progn | |
693 (setq fetched-packages nil) | |
694 (throw 'exit nil)))) | |
695 (setq fetched-packages | |
696 (append (list package) | |
697 (package-get-info-prop this-package 'provides) | |
698 fetched-packages)) | |
699 ;; grab everything that this package requires plus recursively | |
700 ;; grab everything that the requires require. Keep track | |
701 ;; in `fetched-packages' the list of things provided -- this | |
702 ;; keeps us from going into a loop | |
703 (while this-requires | |
704 (if (not (member (car this-requires) fetched-packages)) | |
705 (let* ((reqd-package (package-get-package-provider | |
706 (car this-requires) t)) | |
707 (reqd-version (cadr reqd-package)) | |
708 (reqd-name (car reqd-package))) | |
709 (if (null reqd-name) | |
1410 | 710 (error 'search-failed |
711 (format "Unable to find a provider for %s" | |
712 (car this-requires)))) | |
428 | 713 (if (not (setq fetched-packages |
714 (package-get-all reqd-name reqd-version | |
715 fetched-packages | |
716 install-dir))) | |
1365 | 717 (throw 'exit nil)))) |
718 (setq this-requires (cdr this-requires)))) | |
719 fetched-packages)) | |
428 | 720 |
721 ;;;###autoload | |
722 (defun package-get-dependencies (packages) | |
723 "Compute dependencies for PACKAGES. | |
724 Uses `package-get-base' to determine just what is required and what | |
725 package provides that functionality. Returns the list of packages | |
726 required by PACKAGES." | |
727 (package-get-require-base t) | |
728 (let ((orig-packages packages) | |
729 dependencies provided) | |
730 (while packages | |
731 (let* ((package (car packages)) | |
732 (the-package (package-get-info-find-package | |
733 package-get-base package)) | |
734 (this-package (package-get-info-version | |
735 the-package nil)) | |
736 (this-requires (package-get-info-prop this-package 'requires)) | |
737 (new-depends (set-difference | |
738 (mapcar | |
739 #'(lambda (reqd) | |
740 (let* ((reqd-package (package-get-package-provider reqd)) | |
741 (reqd-name (car reqd-package))) | |
742 (if (null reqd-name) | |
1410 | 743 (error 'search-failed |
744 (format "Unable to find a provider for %s" reqd))) | |
428 | 745 reqd-name)) |
746 this-requires) | |
747 dependencies)) | |
748 (this-provides (package-get-info-prop this-package 'provides))) | |
749 (setq dependencies | |
750 (union dependencies new-depends)) | |
751 (setq provided | |
752 (union provided (union (list package) this-provides))) | |
753 (setq packages | |
754 (union new-depends (cdr packages))))) | |
755 (set-difference dependencies orig-packages))) | |
756 | |
757 (defun package-get-load-package-file (lispdir file) | |
758 (let (pathname) | |
759 (setq pathname (expand-file-name file lispdir)) | |
793 | 760 (with-trapping-errors |
761 :operation (format "loading package file \"%s\"" pathname) | |
762 :error-form nil | |
763 (load pathname t) | |
764 t))) | |
428 | 765 |
766 (defun package-get-init-package (lispdir) | |
767 "Initialize the package. | |
768 This really assumes that the package has never been loaded. Updating | |
769 a newer package can cause problems, due to old, obsolete functions in | |
770 the old package. | |
771 | |
772 Return `t' upon complete success, `nil' if any errors occurred." | |
773 (progn | |
774 (if (and lispdir | |
775 (file-accessible-directory-p lispdir)) | |
776 (progn | |
777 ;; Add lispdir to load-path if it doesn't already exist. | |
778 ;; NOTE: this does not take symlinks, etc., into account. | |
2802 | 779 (add-to-list 'load-path (file-name-as-directory lispdir)) |
428 | 780 (if (not (package-get-load-package-file lispdir "auto-autoloads")) |
781 (package-get-load-package-file lispdir "_pkg")) | |
782 t) | |
1365 | 783 nil))) |
784 | |
2151 | 785 (defun package-get-info-name-array () |
786 "Internal, used by `package-get-info'." | |
787 (let ((pkgs package-get-base) | |
788 names) | |
789 (while pkgs | |
790 (setq names (let ((name (caar pkgs))) | |
791 (push (cons (format "%s" name) name) names))) | |
792 (setq pkgs (cdr pkgs))) | |
793 names)) | |
794 | |
795 (defconst package-get-info-info-array | |
796 '(("standards-version" . standards-version) | |
797 ("version" . version) | |
798 ("author-version" . author-version) | |
799 ("date" . date) | |
800 ("build-date" . build-date) | |
801 ("maintainer" . maintainer) | |
802 ("distribution" . distribution) | |
803 ("priority" . priority) | |
804 ("category" . category) | |
805 ("dump" . dump) | |
806 ("description" . description) | |
807 ("filename" . filename) | |
808 ("md5sum" . md5sum) | |
809 ("size" . size) | |
810 ("provides" . provides) | |
811 ("requires" . requires) | |
812 ("type" . type)) | |
813 "Internal, used by `package-get-info'.") | |
814 | |
1365 | 815 ;;;###autoload |
816 (defun package-get-info (package information &optional arg remote) | |
817 "Get information about a package. | |
818 | |
819 Quite similar to `package-get-info-prop', but can retrieve a lot more | |
820 information. | |
821 | |
822 Argument PACKAGE is the name of an XEmacs package (a symbol). It must | |
823 be a valid package, ie, a member of `package-get-base'. | |
824 | |
825 Argument INFORMATION is a symbol that can be any one of: | |
826 | |
827 standards-version Package system version (not used). | |
828 version Version of the XEmacs package. | |
829 author-version The upstream version of the package. | |
830 date The date the package was last modified. | |
831 build-date The date the package was last built. | |
832 maintainer The maintainer of the package. | |
833 distribution Will always be \"xemacs\" (not used). | |
834 priority \"low\", \"medium\", or \"high\" (not used). | |
835 category Either \"standard\", \"mule\", or \"unsupported\".. | |
836 dump Is the package dumped (not used). | |
837 description A description of the package. | |
838 filename The filename of the binary tarball of the package. | |
839 md5sum The md5sum of filename. | |
840 size The size in bytes of filename. | |
841 provides A list of symbols that this package provides. | |
842 requires A list of packages that this package requires. | |
843 type Can be either \"regular\" or \"single-file\". | |
844 | |
2151 | 845 Optional argument ARG is a prefix arg. Without a value, ie, just |
846 doing `C-u M-x package-get-info' will insert the information at point | |
847 in the current buffer using a local package list. | |
848 | |
849 ARG can also be given a value of 2 or 3. If 2, use a remote package | |
850 list, displaying the information in the minubuffer. If 3, use a remote | |
851 package list and insert the information at point in the current buffer. | |
1365 | 852 |
853 If optional argument REMOTE is non-nil use a package list from a | |
2151 | 854 remote site. |
855 | |
856 To use a remote package list, either via the prefix argument ARG or | |
857 via the REMOTE argument `package-get-remote' must be non-nil. If | |
858 `package-get-remote' is nil, the local package list will be used. | |
1365 | 859 |
860 If this function is called interactively it will display INFORMATION | |
861 in the minibuffer." | |
2151 | 862 (interactive "i\ni\np") |
863 (if (and package-get-remote | |
864 (or (eq arg 2) | |
865 (eq arg 3) | |
866 remote)) | |
867 (package-get-require-base t) | |
868 (package-get-require-base nil)) | |
869 (let ((all-pkgs package-get-base) | |
870 (package (or package | |
871 (intern (completing-read | |
872 "Package: " | |
873 (package-get-info-name-array) nil t)))) | |
874 (information (or information | |
875 (intern (completing-read | |
876 "Info: " | |
877 package-get-info-info-array nil t)))) | |
878 info) | |
1365 | 879 (loop until (equal package (caar all-pkgs)) |
880 do (setq all-pkgs (cdr all-pkgs)) | |
881 do (if (not all-pkgs) | |
1410 | 882 (error 'invalid-argument |
883 (format "%s is not a valid package" package)))) | |
1365 | 884 (setq info (plist-get (cadar all-pkgs) information)) |
885 (if (interactive-p) | |
2151 | 886 (if (or (eq arg 3) |
887 (eq arg 4)) | |
1365 | 888 (insert (format "%s" info)) |
889 (if (package-get-key package :version) | |
890 (message "%s" info) | |
891 (message "%s (Package: %s is not installed)" info package))) | |
2151 | 892 info))) |
428 | 893 |
894 ;;;###autoload | |
1832 | 895 (defun package-get-list-packages-where (item field &optional arg) |
896 "Return a list of packages that fulfill certain criteria. | |
897 | |
898 Argument ITEM, a symbol, is what you want to check for. ITEM must be a | |
899 symbol even when it doesn't make sense to be a symbol \(think, searching | |
900 maintainers, descriptions, etc\). The function will convert the symbol | |
901 to a string if a string is what is needed. The downside to this is that | |
902 ITEM can only ever be a single word. | |
903 | |
904 Argument FIELD, a symbol, is the field to check in. You can specify | |
905 any one of: | |
906 | |
907 Field Sane or Allowable Content | |
908 description any single word | |
909 category `standard' or `mule' | |
910 maintainer any single word | |
911 build-date yyyy-mm-dd | |
912 date yyyy-mm-dd | |
913 type `regular' or `single' | |
914 requires any package name | |
915 provides any symbol | |
916 priority `low', `medium', or `high' | |
917 | |
918 Optional Argument ARG, a prefix arg, insert output at point in the | |
919 current buffer." | |
2151 | 920 (interactive |
921 (list (intern (read-string "List packages that contain (text): ")) | |
922 (intern (completing-read "in their package-info field (completion available): " | |
923 '(("description" . description) | |
924 ("category" . category) | |
925 ("maintainer" . maintainer) | |
926 ("build-date" . build-date) | |
927 ("date" . date) | |
928 ("type" . type) | |
929 ("requires" . requires) | |
930 ("provides" . provides) | |
931 ("priority" . priority)) nil t)) | |
932 current-prefix-arg)) | |
1832 | 933 (package-get-require-base nil) |
934 (let ((pkgs package-get-base) | |
935 (strings '(description category maintainer build-date date)) | |
936 (symbols '(type requires provides priority)) | |
937 results) | |
938 (cond ((memq field strings) | |
939 (setq item (symbol-name item)) | |
940 (while pkgs | |
941 (when (string-match item (package-get-info (caar pkgs) field)) | |
942 (setq results (push (caar pkgs) results))) | |
943 (setq pkgs (cdr pkgs)))) | |
944 ((memq field symbols) | |
945 (if (or (eq field 'type) | |
946 (eq field 'priority)) | |
947 (while pkgs | |
948 (when (eq item (package-get-info (caar pkgs) field)) | |
949 (setq results (push (caar pkgs) results))) | |
950 (setq pkgs (cdr pkgs))) | |
951 (while pkgs | |
952 (when (memq item (package-get-info (caar pkgs) field)) | |
953 (setq results (push (caar pkgs) results))) | |
954 (setq pkgs (cdr pkgs))))) | |
955 (t | |
956 (error 'wrong-type-argument field))) | |
957 (if (interactive-p) | |
958 (if arg | |
959 (insert (format "%s" results)) | |
960 (message "%s" results))) | |
961 results)) | |
962 | |
963 ;;;###autoload | |
428 | 964 (defun package-get (package &optional version conflict install-dir) |
965 "Fetch PACKAGE from remote site. | |
966 Optional arguments VERSION indicates which version to retrieve, nil | |
967 means most recent version. CONFLICT indicates what happens if the | |
968 package is already installed. Valid values for CONFLICT are: | |
969 'always always retrieve the package even if it is already installed | |
970 'never do not retrieve the package if it is installed. | |
971 INSTALL-DIR, if non-nil, specifies the package directory where | |
972 fetched packages should be installed. | |
973 | |
442 | 974 The value of `package-get-base' is used to determine what files should |
428 | 975 be retrieved. The value of `package-get-remote' is used to determine |
1365 | 976 where a package should be retrieved from. |
428 | 977 |
978 Once the package is retrieved, its md5 checksum is computed. If that | |
979 sum does not match that stored in `package-get-base' for this version | |
980 of the package, an error is signalled. | |
981 | |
982 Returns `t' upon success, the symbol `error' if the package was | |
983 successfully installed but errors occurred during initialization, or | |
984 `nil' upon error." | |
985 (interactive (package-get-interactive-package-query nil t)) | |
986 (catch 'skip-update | |
987 (let* ((this-package | |
988 (package-get-info-version | |
989 (package-get-info-find-package package-get-base | |
990 package) version)) | |
991 (latest (package-get-info-prop this-package 'version)) | |
992 (installed (package-get-key package :version)) | |
993 (found nil) | |
1365 | 994 (search-dir package-get-remote) |
428 | 995 (base-filename (package-get-info-prop this-package 'filename)) |
996 (package-status t) | |
997 filenames full-package-filename) | |
1365 | 998 (if (and (equal (package-get-info package 'category) "mule") |
999 (not (featurep 'mule))) | |
1410 | 1000 (error 'invalid-state |
1001 "Mule packages can't be installed with a non-Mule XEmacs")) | |
428 | 1002 (if (null this-package) |
1003 (if package-get-remote | |
1410 | 1004 (error 'search-failed |
1005 (format "Couldn't find package %s with version %s" | |
1006 package version)) | |
1007 (error 'syntax-error | |
1008 "No download site or local package location specified."))) | |
428 | 1009 (if (null base-filename) |
1410 | 1010 (error 'syntax-error |
1011 (format "No filename associated with package %s, version %s" | |
1012 package version))) | |
1378 | 1013 (setq install-dir (package-admin-get-install-dir package install-dir)) |
428 | 1014 |
1015 ;; If they asked for the latest using version=nil, don't get an older | |
1016 ;; version than we already have. | |
1017 (if installed | |
1018 (if (> (if (stringp installed) | |
1019 (string-to-number installed) | |
1020 installed) | |
1021 (if (stringp latest) | |
1022 (string-to-number latest) | |
1023 latest)) | |
1024 (if (not (null version)) | |
825 | 1025 (warn "Installing %s package version %s, you had a newer version %s" |
793 | 1026 package latest installed) |
825 | 1027 (warn "Skipping %s package, you have a newer version %s" |
793 | 1028 package installed) |
428 | 1029 (throw 'skip-update t)))) |
1030 | |
1031 ;; Contrive a list of possible package filenames. | |
1032 ;; Ugly. Is there a better way to do this? | |
1033 (setq filenames (cons base-filename nil)) | |
1034 (if (string-match "^\\(..*\\)\.tar\.gz$" base-filename) | |
1035 (setq filenames (append filenames | |
1036 (list (concat (match-string 1 base-filename) | |
1037 ".tgz"))))) | |
1038 | |
1039 (setq version latest) | |
1040 (unless (and (eq conflict 'never) | |
1041 (package-get-installedp package version)) | |
1042 ;; Find the package from the search list in package-get-remote | |
1043 ;; and copy it into the staging directory. Then validate | |
1044 ;; the checksum. Finally, install the package. | |
1045 (catch 'done | |
1365 | 1046 (let (search-filenames host dir current-filename dest-filename) |
428 | 1047 ;; In each search directory ... |
1365 | 1048 (when search-dir |
1049 (setq host (car search-dir) | |
1050 dir (car (cdr search-dir)) | |
1051 search-filenames filenames) | |
428 | 1052 |
1053 ;; Look for one of the possible package filenames ... | |
1054 (while search-filenames | |
1055 (setq current-filename (car search-filenames) | |
1056 dest-filename (package-get-staging-dir current-filename)) | |
1057 (cond | |
1058 ;; No host means look on the current system. | |
1365 | 1059 ((null host) |
1060 (setq full-package-filename | |
1061 (substitute-in-file-name | |
1062 (expand-file-name current-filename | |
1063 (file-name-as-directory dir))))) | |
428 | 1064 |
1065 ;; If it's already on the disk locally, and the size is | |
1365 | 1066 ;; correct |
1067 ((and (file-exists-p dest-filename) | |
1068 (eq (nth 7 (file-attributes dest-filename)) | |
1069 (package-get-info package 'size))) | |
1070 (setq full-package-filename dest-filename)) | |
428 | 1071 |
1072 ;; If the file exists on the remote system ... | |
1365 | 1073 ((file-exists-p (package-get-remote-filename |
1074 search-dir current-filename)) | |
1075 ;; Get it | |
1076 (setq full-package-filename dest-filename) | |
1077 (message "Retrieving package `%s' ..." | |
1078 current-filename) | |
1079 (sit-for 0) | |
1080 (copy-file (package-get-remote-filename search-dir | |
1081 current-filename) | |
1082 full-package-filename t))) | |
428 | 1083 |
1084 ;; If we found it, we're done. | |
1085 (if (and full-package-filename | |
1086 (file-exists-p full-package-filename)) | |
1087 (throw 'done nil)) | |
1088 ;; Didn't find it. Try the next possible filename. | |
1365 | 1089 (setq search-filenames (cdr search-filenames)))))) |
428 | 1090 |
1091 (if (or (not full-package-filename) | |
1092 (not (file-exists-p full-package-filename))) | |
1093 (if package-get-remote | |
1410 | 1094 (error 'search-failed |
1095 (format "Unable to find file %s" base-filename)) | |
1096 (error 'syntax-error | |
1097 "No download sites or local package locations specified."))) | |
428 | 1098 ;; Validate the md5 checksum |
1099 ;; Doing it with XEmacs removes the need for an external md5 program | |
1100 (message "Validating checksum for `%s'..." package) (sit-for 0) | |
1101 (with-temp-buffer | |
442 | 1102 (insert-file-contents-literally full-package-filename) |
428 | 1103 (if (not (string= (md5 (current-buffer)) |
1104 (package-get-info-prop this-package | |
1105 'md5sum))) | |
1365 | 1106 (progn |
1107 (delete-file full-package-filename) | |
1410 | 1108 (error 'process-error |
1109 (format "Package %s does not match md5 checksum %s has been deleted" | |
1110 base-filename full-package-filename))))) | |
428 | 1111 |
1112 (package-admin-delete-binary-package package install-dir) | |
1113 | |
1114 (message "Installing package `%s' ..." package) (sit-for 0) | |
1115 (let ((status | |
1116 (package-admin-add-binary-package full-package-filename | |
1117 install-dir))) | |
1118 (if (= status 0) | |
1119 (progn | |
1120 ;; clear messages so that only messages from | |
1121 ;; package-get-init-package are seen, below. | |
1122 (clear-message) | |
1123 (if (package-get-init-package (package-admin-get-lispdir | |
1124 install-dir package)) | |
1125 (progn | |
628 | 1126 (run-hook-with-args 'package-install-hook package install-dir) |
428 | 1127 (message "Added package `%s'" package) |
1365 | 1128 (sit-for 0)) |
428 | 1129 (progn |
1130 ;; display message only if there isn't already one. | |
1131 (if (not (current-message)) | |
1132 (progn | |
1133 (message "Added package `%s' (errors occurred)" | |
1134 package) | |
1365 | 1135 (sit-for 0))) |
428 | 1136 (if package-status |
1365 | 1137 (setq package-status 'errors))))) |
428 | 1138 (message "Installation of package %s failed." base-filename) |
1139 (sit-for 0) | |
1140 (switch-to-buffer package-admin-temp-buffer) | |
1365 | 1141 (delete-file full-package-filename) |
1142 (setq package-status nil))) | |
428 | 1143 (setq found t)) |
1144 (if (and found package-get-remove-copy) | |
1145 (delete-file full-package-filename)) | |
1365 | 1146 package-status))) |
428 | 1147 |
1148 (defun package-get-info-find-package (which name) | |
1149 "Look in WHICH for the package called NAME and return all the info | |
1150 associated with it. See `package-get-base' for info on the format | |
1151 returned. | |
1152 | |
1153 To access fields returned from this, use | |
1154 `package-get-info-version' to return information about particular a | |
442 | 1155 version. Use `package-get-info-find-prop' to find particular property |
428 | 1156 from a version returned by `package-get-info-version'." |
1157 (interactive "xPackage list: \nsPackage Name: ") | |
1158 (if which | |
1159 (if (eq (caar which) name) | |
1160 (cdar which) | |
1161 (if (cdr which) | |
1162 (package-get-info-find-package (cdr which) name))))) | |
1163 | |
1164 (defun package-get-info-version (package version) | |
1165 "In PACKAGE, return the plist associated with a particular VERSION of the | |
1166 package. PACKAGE is typically as returned by | |
442 | 1167 `package-get-info-find-package'. If VERSION is nil, then return the |
428 | 1168 first (aka most recent) version. Use `package-get-info-find-prop' |
1169 to retrieve a particular property from the value returned by this." | |
1170 (interactive (package-get-interactive-package-query t t)) | |
1171 (while (and version package (not (string= (plist-get (car package) 'version) version))) | |
1172 (setq package (cdr package))) | |
1173 (if package (car package))) | |
1174 | |
1175 (defun package-get-info-prop (package-version property) | |
1176 "In PACKAGE-VERSION, return the value associated with PROPERTY. | |
1177 PACKAGE-VERSION is typically returned by `package-get-info-version' | |
1178 and PROPERTY is typically (although not limited to) one of the | |
1179 following: | |
1180 | |
1181 version - version of this package | |
1182 provides - list of symbols provided | |
1183 requires - list of symbols that are required. | |
1184 These in turn are provided by other packages. | |
1185 size - size of the bundled package | |
1186 md5sum - computed md5 checksum" | |
1187 (interactive "xPackage Version: \nSProperty") | |
1188 (plist-get package-version property)) | |
1189 | |
1190 (defun package-get-info-version-prop (package-list package version property) | |
1191 "In PACKAGE-LIST, search for PACKAGE with this VERSION and return | |
1192 PROPERTY value." | |
1193 (package-get-info-prop | |
1194 (package-get-info-version | |
1195 (package-get-info-find-package package-list package) version) property)) | |
1196 | |
1197 (defun package-get-staging-dir (filename) | |
1198 "Return a good place to stash FILENAME when it is retrieved. | |
1199 Use `package-get-dir' for directory to store stuff. | |
629 | 1200 Creates `package-get-dir' if it doesn't exist." |
428 | 1201 (interactive "FPackage filename: ") |
1202 (if (not (file-exists-p package-get-dir)) | |
1203 (make-directory package-get-dir)) | |
1204 (expand-file-name | |
776 | 1205 (file-name-nondirectory (or (and-fboundp 'efs-ftp-path |
1206 (nth 2 (efs-ftp-path filename))) | |
428 | 1207 filename)) |
1208 (file-name-as-directory package-get-dir))) | |
1209 | |
1210 (defun package-get-remote-filename (search filename) | |
1211 "Return FILENAME as a remote filename. | |
1212 It first checks if FILENAME already is a remote filename. If it is | |
1213 not, then it uses the (car search) as the remote site-name and the (cadr | |
1214 search) as the remote-directory and concatenates filename. In other | |
1215 words | |
1216 site-name:remote-directory/filename. | |
1217 | |
1218 If (car search) is nil, (cadr search is interpreted as a local directory). | |
1219 " | |
1220 (if (file-remote-p filename) | |
1221 filename | |
1222 (let ((dir (cadr search))) | |
1223 (concat (when (car search) | |
1224 (concat | |
1225 (if (string-match "@" (car search)) | |
1226 "/" | |
1227 "/anonymous@") | |
1228 (car search) ":")) | |
1229 (if (string-match "/$" dir) | |
1230 dir | |
1231 (concat dir "/")) | |
1232 filename)))) | |
1233 | |
1234 (defun package-get-installedp (package version) | |
1235 "Determine if PACKAGE with VERSION has already been installed. | |
442 | 1236 I'm not sure if I want to do this by searching directories or checking |
428 | 1237 some built in variables. For now, use packages-package-list." |
1238 ;; Use packages-package-list which contains name and version | |
1239 (equal (plist-get | |
1240 (package-get-info-find-package packages-package-list | |
5344
2a54dfbe434f
Don't quote keywords, they've been self-quoting for well over a decade.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4787
diff
changeset
|
1241 package) :version) |
1368 | 1242 (if (floatp version) |
1243 version | |
1365 | 1244 (string-to-number version)))) |
428 | 1245 |
1246 ;;;###autoload | |
1247 (defun package-get-package-provider (sym &optional force-current) | |
1248 "Search for a package that provides SYM and return the name and | |
1249 version. Searches in `package-get-base' for SYM. If SYM is a | |
442 | 1250 consp, then it must match a corresponding (provide (SYM VERSION)) from |
428 | 1251 the package. |
1252 | |
1253 If FORCE-CURRENT is non-nil make sure the database is up to date. This might | |
1254 lead to Emacs accessing remote sites." | |
1255 (interactive "SSymbol: ") | |
1256 (package-get-require-base force-current) | |
1257 (let ((packages package-get-base) | |
1258 (done nil) | |
1259 (found nil)) | |
1260 (while (and (not done) packages) | |
1261 (let* ((this-name (caar packages)) | |
1262 (this-package (cdr (car packages)))) ;strip off package name | |
1263 (while (and (not done) this-package) | |
1264 (if (or (eq this-name sym) | |
1265 (eq (cons this-name | |
1266 (package-get-info-prop (car this-package) 'version)) | |
1267 sym) | |
1268 (member sym | |
1269 (package-get-info-prop (car this-package) 'provides))) | |
1270 (progn (setq done t) | |
1271 (setq found | |
1272 (list (caar packages) | |
1273 (package-get-info-prop (car this-package) 'version)))) | |
1274 (setq this-package (cdr this-package))))) | |
1275 (setq packages (cdr packages))) | |
1276 (when (interactive-p) | |
1277 (if found | |
1278 (message "%S" found) | |
1279 (message "No appropriate package found"))) | |
1280 found)) | |
1281 | |
1282 (defun package-get-ever-installed-p (pkg &optional notused) | |
1283 (string-match "-package$" (symbol-name pkg)) | |
442 | 1284 (custom-initialize-set |
1285 pkg | |
1286 (if (package-get-info-find-package | |
1287 packages-package-list | |
428 | 1288 (intern (substring (symbol-name pkg) 0 (match-beginning 0)))) |
1289 t))) | |
1290 | |
1291 (provide 'package-get) | |
1292 ;;; package-get.el ends here |