Mercurial > hg > octave-lyh
annotate scripts/pkg/pkg.m @ 10793:be55736a0783
Grammarcheck the documentation from m-files.
author | Rik <octave@nomad.inbox5.com> |
---|---|
date | Sun, 18 Jul 2010 20:35:16 -0700 |
parents | 81a43049dee2 |
children | 693e22af08ae |
rev | line source |
---|---|
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8942
diff
changeset
|
1 ## Copyright (C) 2005, 2006, 2007, 2008, 2009 S�ren Hauberg |
10684
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
2 ## Copyright (C) 2010 VZLU Prague, a.s. |
5801 | 3 ## |
6440 | 4 ## This file is part of Octave. |
5 ## | |
6 ## Octave is free software; you can redistribute it and/or modify it | |
7 ## under the terms of the GNU General Public License as published by | |
7016 | 8 ## the Free Software Foundation; either version 3 of the License, or (at |
9 ## your option) any later version. | |
6440 | 10 ## |
11 ## Octave is distributed in the hope that it will be useful, but | |
12 ## WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 ## General Public License for more details. | |
15 ## | |
5801 | 16 ## You should have received a copy of the GNU General Public License |
7016 | 17 ## along with Octave; see the file COPYING. If not, see |
18 ## <http://www.gnu.org/licenses/>. | |
5801 | 19 |
20 ## -*- texinfo -*- | |
9724
f22bbc5d56e9
Fix various incorrect usages of TeXinfo deffn and deftypefn macros
Rik <rdrider0-list@yahoo.com>
parents:
9307
diff
changeset
|
21 ## @deffn {Command} pkg @var{command} @var{pkg_name} |
f22bbc5d56e9
Fix various incorrect usages of TeXinfo deffn and deftypefn macros
Rik <rdrider0-list@yahoo.com>
parents:
9307
diff
changeset
|
22 ## @deffnx {Command} pkg @var{command} @var{option} @var{pkg_name} |
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8942
diff
changeset
|
23 ## This command interacts with the package manager. Different actions will |
6378 | 24 ## be taken depending on the value of @var{command}. |
6032 | 25 ## |
26 ## @table @samp | |
27 ## @item install | |
6070 | 28 ## Install named packages. For example, |
29 ## @example | |
30 ## pkg install image-1.0.0.tar.gz | |
31 ## @end example | |
32 ## @noindent | |
9307
c2923c27c877
Various documentation improvements
Rik <rdrider0-list@yahoo.com>
parents:
9258
diff
changeset
|
33 ## installs the package found in the file @file{image-1.0.0.tar.gz}. |
6070 | 34 ## |
6645 | 35 ## The @var{option} variable can contain options that affect the manner |
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8942
diff
changeset
|
36 ## in which a package is installed. These options can be one or more of |
6645 | 37 ## |
38 ## @table @code | |
39 ## @item -nodeps | |
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8942
diff
changeset
|
40 ## The package manager will disable the dependency checking. That way it |
6645 | 41 ## is possible to install a package even if it depends on another package |
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8942
diff
changeset
|
42 ## that's not installed on the system. @strong{Use this option with care.} |
6645 | 43 ## |
44 ## @item -noauto | |
45 ## The package manager will not automatically load the installed package | |
46 ## when starting Octave, even if the package requests that it is. | |
6258 | 47 ## |
6645 | 48 ## @item -auto |
49 ## The package manager will automatically load the installed package when | |
50 ## starting Octave, even if the package requests that it isn't. | |
51 ## | |
52 ## @item -local | |
53 ## A local installation is forced, even if the user has system privileges. | |
6258 | 54 ## |
6645 | 55 ## @item -global |
56 ## A global installation is forced, even if the user doesn't normally have | |
57 ## system privileges | |
6614 | 58 ## |
6645 | 59 ## @item -verbose |
60 ## The package manager will print the output of all of the commands that are | |
61 ## performed. | |
62 ## @end table | |
63 ## | |
6032 | 64 ## @item uninstall |
6070 | 65 ## Uninstall named packages. For example, |
66 ## @example | |
67 ## pkg uninstall image | |
68 ## @end example | |
69 ## @noindent | |
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8942
diff
changeset
|
70 ## removes the @code{image} package from the system. If another installed |
6070 | 71 ## package depends on the @code{image} package an error will be issued. |
10793
be55736a0783
Grammarcheck the documentation from m-files.
Rik <octave@nomad.inbox5.com>
parents:
10685
diff
changeset
|
72 ## The package can be uninstalled anyway by using the @option{-nodeps} option. |
6032 | 73 ## @item load |
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8942
diff
changeset
|
74 ## Add named packages to the path. After loading a package it is |
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8942
diff
changeset
|
75 ## possible to use the functions provided by the package. For example, |
6070 | 76 ## @example |
77 ## pkg load image | |
78 ## @end example | |
79 ## @noindent | |
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8942
diff
changeset
|
80 ## adds the @code{image} package to the path. It is possible to load all |
6070 | 81 ## installed packages at once with the command |
82 ## @example | |
83 ## pkg load all | |
84 ## @end example | |
6203 | 85 ## @item unload |
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8942
diff
changeset
|
86 ## Removes named packages from the path. After unloading a package it is |
6203 | 87 ## no longer possible to use the functions provided by the package. |
88 ## This command behaves like the @code{load} command. | |
6032 | 89 ## @item list |
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8942
diff
changeset
|
90 ## Show a list of the currently installed packages. By requesting one or two |
6070 | 91 ## output argument it is possible to get a list of the currently installed |
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8942
diff
changeset
|
92 ## packages. For example, |
6070 | 93 ## @example |
94 ## installed_packages = pkg list; | |
95 ## @end example | |
96 ## @noindent | |
97 ## returns a cell array containing a structure for each installed package. | |
98 ## The command | |
99 ## @example | |
100 ## [@var{user_packages}, @var{system_packages}] = pkg list | |
101 ## @end example | |
102 ## @noindent | |
103 ## splits the list of installed packages into those who are installed by | |
104 ## the current user, and those installed by the system administrator. | |
7497 | 105 ## @item describe |
106 ## Show a short description of the named installed packages, with the option | |
107 ## '-verbose' also list functions provided by the package, e.g.: | |
108 ## @example | |
109 ## pkg describe -verbose all | |
110 ## @end example | |
111 ## @noindent | |
112 ## will describe all installed packages and the functions they provide. | |
113 ## If one output is requested a cell of structure containing the | |
114 ## description and list of functions of each package is returned as | |
115 ## output rather than printed on screen: | |
116 ## @example | |
117 ## desc = pkg ("describe", "secs1d", "image") | |
118 ## @end example | |
119 ## @noindent | |
120 ## If any of the requested packages is not installed, pkg returns an | |
121 ## error, unless a second output is requested: | |
122 ## @example | |
123 ## [ desc, flag] = pkg ("describe", "secs1d", "image") | |
124 ## @end example | |
125 ## @noindent | |
126 ## @var{flag} will take one of the values "Not installed", "Loaded" or | |
127 ## "Not loaded" for each of the named packages. | |
6034 | 128 ## @item prefix |
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8942
diff
changeset
|
129 ## Set the installation prefix directory. For example, |
6070 | 130 ## @example |
131 ## pkg prefix ~/my_octave_packages | |
132 ## @end example | |
133 ## @noindent | |
9307
c2923c27c877
Various documentation improvements
Rik <rdrider0-list@yahoo.com>
parents:
9258
diff
changeset
|
134 ## sets the installation prefix to @file{~/my_octave_packages}. |
6070 | 135 ## Packages will be installed in this directory. |
6034 | 136 ## |
6070 | 137 ## It is possible to get the current installation prefix by requesting an |
138 ## output argument. For example, | |
139 ## @example | |
140 ## p = pkg prefix | |
141 ## @end example | |
6925 | 142 ## |
143 ## The location in which to install the architecture dependent files can be | |
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8942
diff
changeset
|
144 ## independent specified with an addition argument. For example |
6925 | 145 ## |
146 ## @example | |
9153
5247e89688e1
Eliminate most overfull errors when running texi2pdf for generating pdf documentation
Rik <rdrider0-list@yahoo.com>
parents:
9079
diff
changeset
|
147 ## pkg prefix ~/my_octave_packages ~/my_arch_dep_pkgs |
6925 | 148 ## @end example |
6189 | 149 ## @item local_list |
150 ## Set the file in which to look for information on the locally | |
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8942
diff
changeset
|
151 ## installed packages. Locally installed packages are those that are |
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8942
diff
changeset
|
152 ## typically available only to the current user. For example |
6189 | 153 ## @example |
154 ## pkg local_list ~/.octave_packages | |
155 ## @end example | |
156 ## It is possible to get the current value of local_list with the following | |
157 ## @example | |
158 ## pkg local_list | |
159 ## @end example | |
160 ## @item global_list | |
161 ## Set the file in which to look for, for information on the globally | |
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8942
diff
changeset
|
162 ## installed packages. Globally installed packages are those that are |
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8942
diff
changeset
|
163 ## typically available to all users. For example |
6189 | 164 ## @example |
165 ## pkg global_list /usr/share/octave/octave_packages | |
166 ## @end example | |
167 ## It is possible to get the current value of global_list with the following | |
168 ## @example | |
169 ## pkg global_list | |
170 ## @end example | |
6645 | 171 ## @item rebuild |
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8942
diff
changeset
|
172 ## Rebuilds the package database from the installed directories. This can |
6645 | 173 ## be used in cases where for some reason the package database is corrupted. |
10793
be55736a0783
Grammarcheck the documentation from m-files.
Rik <octave@nomad.inbox5.com>
parents:
10685
diff
changeset
|
174 ## It can also take the @option{-auto} and @option{-noauto} options to allow the |
9079
4d610aba7347
Cleanup documentation for system.texi, package.texi
Rik <rdrider0-list@yahoo.com>
parents:
9051
diff
changeset
|
175 ## autoloading state of a package to be changed. For example |
6645 | 176 ## |
177 ## @example | |
178 ## pkg rebuild -noauto image | |
179 ## @end example | |
180 ## | |
181 ## will remove the autoloading status of the image package. | |
6675 | 182 ## @item build |
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8942
diff
changeset
|
183 ## Builds a binary form of a package or packages. The binary file produced |
6675 | 184 ## will itself be an Octave package that can be installed normally with |
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8942
diff
changeset
|
185 ## @code{pkg}. The form of the command to build a binary package is |
6675 | 186 ## |
187 ## @example | |
188 ## pkg build builddir image-1.0.0.tar.gz @dots{} | |
189 ## @end example | |
190 ## | |
191 ## @noindent | |
9079
4d610aba7347
Cleanup documentation for system.texi, package.texi
Rik <rdrider0-list@yahoo.com>
parents:
9051
diff
changeset
|
192 ## where @code{builddir} is the name of a directory where the temporary |
6675 | 193 ## installation will be produced and the binary packages will be found. |
10793
be55736a0783
Grammarcheck the documentation from m-files.
Rik <octave@nomad.inbox5.com>
parents:
10685
diff
changeset
|
194 ## The options @option{-verbose} and @option{-nodeps} are respected, while |
6675 | 195 ## the other options are ignored. |
6032 | 196 ## @end table |
9724
f22bbc5d56e9
Fix various incorrect usages of TeXinfo deffn and deftypefn macros
Rik <rdrider0-list@yahoo.com>
parents:
9307
diff
changeset
|
197 ## @end deffn |
5947 | 198 |
6496 | 199 function [local_packages, global_packages] = pkg (varargin) |
8202
cf59d542f33e
replace all TODOs and XXXs with FIXMEs
Jaroslav Hajek <highegg@gmail.com>
parents:
8174
diff
changeset
|
200 ## Installation prefix (FIXME: what should these be on windows?) |
6645 | 201 persistent user_prefix = false; |
6496 | 202 persistent prefix = -1; |
6925 | 203 persistent archprefix = -1; |
7498 | 204 persistent local_list = tilde_expand (fullfile ("~", ".octave_packages")); |
6496 | 205 persistent global_list = fullfile (OCTAVE_HOME (), "share", "octave", |
10549 | 206 "octave_packages"); |
6496 | 207 mlock (); |
6189 | 208 |
6925 | 209 global_install = issuperuser (); |
6683 | 210 |
6496 | 211 if (prefix == -1) |
6645 | 212 if (global_install) |
6496 | 213 prefix = fullfile (OCTAVE_HOME (), "share", "octave", "packages"); |
7498 | 214 archprefix = fullfile (octave_config_info ("libexecdir"), |
10549 | 215 "octave", "packages"); |
6496 | 216 else |
217 prefix = fullfile ("~", "octave"); | |
6925 | 218 archprefix = prefix; |
5801 | 219 endif |
6645 | 220 prefix = tilde_expand (prefix); |
6925 | 221 archprefix = tilde_expand (archprefix); |
6496 | 222 endif |
223 | |
7498 | 224 available_actions = {"list", "install", "uninstall", "load", ... |
10549 | 225 "unload", "prefix", "local_list", ... |
226 "global_list", "rebuild", "build","describe"}; | |
6496 | 227 ## Handle input |
228 if (length (varargin) == 0 || ! iscellstr (varargin)) | |
229 print_usage (); | |
230 endif | |
231 files = {}; | |
232 deps = true; | |
233 auto = 0; | |
234 action = "none"; | |
6614 | 235 verbose = false; |
10684
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
236 octave_forge = false; |
6496 | 237 for i = 1:length (varargin) |
238 switch (varargin{i}) | |
239 case "-nodeps" | |
10549 | 240 deps = false; |
6496 | 241 case "-noauto" |
10549 | 242 auto = -1; |
6496 | 243 case "-auto" |
10549 | 244 auto = 1; |
6614 | 245 case "-verbose" |
10549 | 246 verbose = true; |
10684
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
247 case "-forge" |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
248 octave_forge = true; |
6645 | 249 case "-local" |
10549 | 250 global_install = false; |
251 if (! user_prefix) | |
252 prefix = tilde_expand (fullfile ("~", "octave")); | |
253 archprefix = prefix; | |
254 endif | |
6645 | 255 case "-global" |
10549 | 256 global_install = true; |
257 if (! user_prefix) | |
258 prefix = fullfile (OCTAVE_HOME (), "share", "octave", "packages"); | |
259 archprefix = fullfile (octave_config_info ("libexecdir"), | |
260 "octave", "packages"); | |
261 endif | |
7497 | 262 case available_actions |
10549 | 263 if (strcmp (action, "none")) |
264 action = varargin{i}; | |
265 else | |
266 error ("more than one action specified"); | |
267 endif | |
6496 | 268 otherwise |
10549 | 269 files{end+1} = varargin{i}; |
5801 | 270 endswitch |
6496 | 271 endfor |
272 | |
10685
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
273 if (octave_forge && ! any (strcmp (action, {"install", "list"}))) |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
274 error ("-forge can only be used with install or list"); |
10684
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
275 endif |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
276 |
6496 | 277 ## Take action |
278 switch (action) | |
279 case "list" | |
10685
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
280 if (octave_forge) |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
281 if (nargout > 0) |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
282 local_packages = list_forge_packages (); |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
283 else |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
284 list_forge_packages (); |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
285 endif |
6496 | 286 else |
10685
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
287 if (nargout == 0) |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
288 installed_packages (local_list, global_list); |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
289 elseif (nargout == 1) |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
290 local_packages = installed_packages (local_list, global_list); |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
291 elseif (nargout == 2) |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
292 [local_packages, global_packages] = installed_packages (local_list, |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
293 global_list); |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
294 else |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
295 error ("too many output arguments requested"); |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
296 endif |
6496 | 297 endif |
298 | |
299 case "install" | |
300 if (length (files) == 0) | |
10549 | 301 error ("you must specify at least one filename when calling 'pkg install'"); |
6496 | 302 endif |
10684
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
303 |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
304 local_files = {}; |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
305 unwind_protect |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
306 |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
307 if (octave_forge) |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
308 [urls, local_files] = cellfun (@get_forge_download, files, "uniformoutput", false); |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
309 [files, succ] = cellfun (@urlwrite, urls, local_files, "uniformoutput", false); |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
310 succ = [succ{:}]; |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
311 if (! all (succ)) |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
312 i = find (! succ, 1); |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
313 error ("could not download file %s from url %s", local_files{i}, urls{i}); |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
314 endif |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
315 endif |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
316 |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
317 install (files, deps, auto, prefix, archprefix, verbose, local_list, |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
318 global_list, global_install); |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
319 |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
320 unwind_protect_cleanup |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
321 cellfun (@unlink, local_files); |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
322 end_unwind_protect |
6496 | 323 |
324 case "uninstall" | |
325 if (length (files) == 0) | |
10549 | 326 error ("you must specify at least one package when calling 'pkg uninstall'"); |
6496 | 327 endif |
6645 | 328 uninstall (files, deps, verbose, local_list, |
10549 | 329 global_list, global_install); |
6496 | 330 |
331 case "load" | |
332 if (length (files) == 0) | |
10549 | 333 error ("you must specify at least one package, 'all' or 'auto' when calling 'pkg load'"); |
6496 | 334 endif |
335 load_packages (files, deps, local_list, global_list); | |
336 | |
337 case "unload" | |
338 if (length (files) == 0) | |
10549 | 339 error ("you must specify at least one package or 'all' when calling 'pkg unload'"); |
6496 | 340 endif |
341 unload_packages (files, deps, local_list, global_list); | |
342 | |
343 case "prefix" | |
344 if (length (files) == 0 && nargout == 0) | |
10549 | 345 printf ("Installation prefix: %s\n", prefix); |
346 printf ("Architecture dependent prefix: %s\n", archprefix); | |
6925 | 347 elseif (length (files) == 0 && nargout >= 1) |
10549 | 348 local_packages = prefix; |
349 global_packages = archprefix; | |
6925 | 350 elseif (length (files) >= 1 && nargout <= 2 && ischar (files{1})) |
10549 | 351 prefix = files{1}; |
352 prefix = absolute_pathname (prefix); | |
353 local_packages = prefix; | |
354 user_prefix = true; | |
355 if (length (files) >= 2 && ischar (files{2})) | |
356 archprefix = files{2}; | |
357 try | |
358 archprefix = absolute_pathname (archprefix); | |
6925 | 359 catch |
10549 | 360 mkdir (archprefix); |
361 warning ("creating the directory %s\n", archprefix); | |
362 archprefix = absolute_pathname (archprefix); | |
363 end_try_catch | |
364 global_packages = archprefix; | |
365 endif | |
6496 | 366 else |
10549 | 367 error ("you must specify a prefix directory, or request an output argument"); |
6496 | 368 endif |
369 | |
370 case "local_list" | |
371 if (length (files) == 0 && nargout == 0) | |
10549 | 372 disp (local_list); |
6496 | 373 elseif (length (files) == 0 && nargout == 1) |
10549 | 374 local_packages = local_list; |
6496 | 375 elseif (length (files) == 1 && nargout == 0 && ischar (files{1})) |
10549 | 376 try |
377 local_list = absolute_pathname (files{1}); | |
378 catch | |
379 ## Force file to be created | |
380 fclose (fopen (files{1}, "wt")); | |
381 local_list = absolute_pathname (files{1}); | |
382 end_try_catch | |
6496 | 383 else |
10549 | 384 error ("you must specify a local_list file, or request an output argument"); |
6496 | 385 endif |
386 | |
387 case "global_list" | |
388 if (length (files) == 0 && nargout == 0) | |
10549 | 389 disp(global_list); |
6496 | 390 elseif (length (files) == 0 && nargout == 1) |
10549 | 391 local_packages = global_list; |
6496 | 392 elseif (length (files) == 1 && nargout == 0 && ischar (files{1})) |
10549 | 393 try |
394 global_list = absolute_pathname (files{1}); | |
395 catch | |
396 ## Force file to be created | |
397 fclose (fopen (files{1}, "wt")); | |
398 global_list = absolute_pathname (files{1}); | |
399 end_try_catch | |
6496 | 400 else |
10549 | 401 error ("you must specify a global_list file, or request an output argument"); |
6496 | 402 endif |
6645 | 403 |
404 case "rebuild" | |
405 if (global_install) | |
10549 | 406 global_packages = rebuild (prefix, archprefix, global_list, files, |
407 auto, verbose); | |
408 global_packages = save_order (global_packages); | |
409 save (global_list, "global_packages"); | |
410 if (nargout > 0) | |
411 local_packages = global_packages; | |
412 endif | |
6645 | 413 else |
10549 | 414 local_packages = rebuild (prefix, archprefix, local_list, files, auto, |
415 verbose); | |
416 local_packages = save_order (local_packages); | |
417 save (local_list, "local_packages"); | |
418 if (nargout == 0) | |
419 clear ("local_packages"); | |
420 endif | |
6645 | 421 endif |
422 | |
6675 | 423 case "build" |
424 if (length (files) < 2) | |
10549 | 425 error ("you must specify at least the build directory and one filename\nwhen calling 'pkg build'"); |
6675 | 426 endif |
427 build (files, deps, auto, verbose); | |
428 | |
7497 | 429 case "describe" |
430 if (length (files) == 0) | |
10549 | 431 error ("you must specify at least one package or 'all' when calling 'pkg describe'"); |
7497 | 432 endif |
8202
cf59d542f33e
replace all TODOs and XXXs with FIXMEs
Jaroslav Hajek <highegg@gmail.com>
parents:
8174
diff
changeset
|
433 ## FIXME: the name of the output variables is inconsistent |
7497 | 434 ## with their content |
435 switch (nargout) | |
10549 | 436 case 0 |
437 describe (files, verbose, local_list, global_list); | |
438 case 1 | |
439 pkg_desc_list = describe (files, verbose, local_list, ... | |
440 global_list); | |
441 local_packages = pkg_desc_list; | |
442 case 2 | |
443 [pkg_desc_list, flag] = describe (files, verbose, local_list, ... | |
444 global_list); | |
445 local_packages = pkg_desc_list; | |
446 global_packages = flag; | |
447 otherwise | |
448 error ("you can request at most two outputs when calling 'pkg describe'"); | |
7498 | 449 endswitch |
10549 | 450 |
6496 | 451 otherwise |
452 error ("you must specify a valid action for 'pkg'. See 'help pkg' for details"); | |
453 endswitch | |
454 endfunction | |
455 | |
6925 | 456 function descriptions = rebuild (prefix, archprefix, list, files, auto, verbose) |
6645 | 457 if (isempty (files)) |
458 [dirlist, err, msg] = readdir (prefix); | |
459 if (err) | |
460 error ("couldn't read directory %s: %s", prefix, msg); | |
461 endif | |
462 ## the two first entries of dirlist are "." and ".." | |
463 dirlist([1,2]) = []; | |
464 else | |
465 old_descriptions = installed_packages (list, list); | |
466 wd = pwd (); | |
6663 | 467 unwind_protect |
468 cd (prefix); | |
7540
3422f39573b1
strcat.m: Matlab compatibility, with cstrcat.m replacing conventional strcat.m.
Ben Abbott <bpabbott@mac.com>
parents:
7498
diff
changeset
|
469 dirlist = glob (cellfun(@(x) cstrcat(x, '-*'), files, 'UniformOutput', 0)); |
6663 | 470 unwind_protect_cleanup |
471 cd (wd); | |
472 end_unwind_protect | |
6645 | 473 endif |
474 descriptions = {}; | |
475 for k = 1:length (dirlist) | |
476 descfile = fullfile (prefix, dirlist{k}, "packinfo", "DESCRIPTION"); | |
477 if (verbose) | |
478 printf ("recreating package description from %s\n", dirlist{k}); | |
479 endif | |
480 if (exist (descfile, "file")) | |
481 desc = get_description (descfile); | |
482 desc.dir = fullfile (prefix, dirlist{k}); | |
7540
3422f39573b1
strcat.m: Matlab compatibility, with cstrcat.m replacing conventional strcat.m.
Ben Abbott <bpabbott@mac.com>
parents:
7498
diff
changeset
|
483 desc.archprefix = fullfile (archprefix, cstrcat (desc.name, "-", |
10549 | 484 desc.version)); |
6645 | 485 if (auto != 0) |
10549 | 486 if (exist (fullfile (desc.dir, "packinfo", ".autoload"), "file")) |
487 unlink (fullfile (desc.dir, "packinfo", ".autoload")); | |
488 endif | |
6645 | 489 if (auto < 0) |
10549 | 490 desc.autoload = 0; |
491 elseif (auto > 0) | |
492 desc.autoload = 1; | |
493 fclose (fopen (fullfile (desc.dir, "packinfo", ".autoload"), "wt")); | |
494 endif | |
6645 | 495 else |
10549 | 496 if (exist (fullfile (desc.dir, "packinfo", ".autoload"), "file")) |
497 desc.autoload = 1; | |
498 else | |
499 desc.autoload = 0; | |
500 endif | |
6645 | 501 endif |
502 descriptions{end + 1} = desc; | |
503 elseif (verbose) | |
504 warning ("directory %s is not a valid package", dirlist{k}); | |
505 endif | |
506 endfor | |
507 | |
6663 | 508 if (! isempty (files)) |
6645 | 509 ## We are rebuilding for a particular package(s) so we should take |
510 ## care to keep the other untouched packages in the descriptions | |
6663 | 511 descriptions = {descriptions{:}, old_descriptions{:}}; |
6645 | 512 |
513 dup = []; | |
514 for i = 1:length (descriptions) | |
515 if (find (dup, i)) | |
10549 | 516 continue; |
6645 | 517 endif |
518 for j = (i+1):length (descriptions) | |
10549 | 519 if (find (dup, j)) |
520 continue; | |
521 endif | |
522 if (strcmp (descriptions{i}.name, descriptions{j}.name)) | |
523 dup = [dup, j]; | |
524 endif | |
6645 | 525 endfor |
526 endfor | |
527 if (! isempty (dup)) | |
528 descriptions (dup) = []; | |
529 endif | |
530 endif | |
531 endfunction | |
532 | |
6675 | 533 function build (files, handle_deps, autoload, verbose) |
534 if (length (files) < 1) | |
535 error ("insufficient number of files"); | |
536 endif | |
537 builddir = files{1}; | |
538 if (! exist (builddir, "dir")) | |
539 warning ("creating build directory %s", builddir); | |
540 [status, msg] = mkdir (builddir); | |
541 if (status != 1) | |
542 error ("could not create installation directory: %s", msg); | |
543 endif | |
6496 | 544 endif |
6675 | 545 builddir = absolute_pathname (builddir); |
546 installdir = fullfile (builddir, "install"); | |
547 if (! exist (installdir, "dir")) | |
548 [status, msg] = mkdir (installdir); | |
549 if (status != 1) | |
550 error ("could not create installation directory: %s", msg); | |
551 endif | |
552 endif | |
553 files(1) = []; | |
554 buildlist = fullfile (builddir, "octave_packages"); | |
6925 | 555 install (files, handle_deps, autoload, installdir, installdir, verbose, |
10549 | 556 buildlist, "", false); |
6675 | 557 unwind_protect |
558 repackage (builddir, buildlist); | |
559 unwind_protect_cleanup | |
560 unload_packages ({"all"}, handle_deps, buildlist, ""); | |
561 if (exist (installdir, "dir")) | |
562 rm_rf (installdir); | |
563 endif | |
564 if (exist (buildlist, "file")) | |
565 unlink (buildlist); | |
566 endif | |
567 end_unwind_protect | |
5801 | 568 endfunction |
569 | |
6925 | 570 function install (files, handle_deps, autoload, prefix, archprefix, verbose, |
10549 | 571 local_list, global_list, global_install) |
6496 | 572 |
8506 | 573 ## Check that the directory in prefix exist. If it doesn't: create it! |
6496 | 574 if (! exist (prefix, "dir")) |
575 warning ("creating installation directory %s", prefix); | |
576 [status, msg] = mkdir (prefix); | |
577 if (status != 1) | |
578 error ("could not create installation directory: %s", msg); | |
579 endif | |
580 endif | |
581 | |
8506 | 582 ## Get the list of installed packages. |
6496 | 583 [local_packages, global_packages] = installed_packages (local_list, |
10549 | 584 global_list); |
6496 | 585 |
6820 | 586 installed_pkgs_lst = {local_packages{:}, global_packages{:}}; |
6496 | 587 |
588 if (global_install) | |
589 packages = global_packages; | |
590 else | |
591 packages = local_packages; | |
592 endif | |
593 | |
8506 | 594 ## Uncompress the packages and read the DESCRIPTION files. |
6496 | 595 tmpdirs = packdirs = descriptions = {}; |
596 try | |
8506 | 597 ## Warn about non existent files. |
6683 | 598 for i = 1:length (files) |
599 if (isempty (glob(files{i}))) | |
10549 | 600 warning ("file %s does not exist", files{i}); |
6683 | 601 endif |
602 endfor | |
603 | |
8506 | 604 ## Unpack the package files and read the DESCRIPTION files. |
6496 | 605 files = glob (files); |
606 packages_to_uninstall = []; | |
607 for i = 1:length (files) | |
608 tgz = files{i}; | |
609 | |
6645 | 610 if (exist (tgz, "file")) |
10549 | 611 ## Create a temporary directory. |
612 tmpdir = tmpnam (); | |
613 tmpdirs{end+1} = tmpdir; | |
6645 | 614 if (verbose) |
10549 | 615 printf ("mkdir (%s)\n", tmpdir); |
616 endif | |
617 [status, msg] = mkdir (tmpdir); | |
618 if (status != 1) | |
619 error ("couldn't create temporary directory: %s", msg); | |
620 endif | |
6496 | 621 |
10549 | 622 ## Uncompress the package. |
623 if (verbose) | |
624 printf ("untar (%s, %s)\n", tgz, tmpdir); | |
625 endif | |
626 untar (tgz, tmpdir); | |
6496 | 627 |
10549 | 628 ## Get the name of the directories produced by tar. |
629 [dirlist, err, msg] = readdir (tmpdir); | |
630 if (err) | |
631 error ("couldn't read directory produced by tar: %s", msg); | |
632 endif | |
6496 | 633 |
10549 | 634 if (length (dirlist) > 3) |
635 error ("bundles of packages are not allowed") | |
636 endif | |
7632
d6e63a15cc75
Allow installation of already extracted packages
Thomas Weber <thomas.weber.mail@gmail.com>
parents:
7548
diff
changeset
|
637 endif |
6496 | 638 |
8506 | 639 ## The filename pointed to an uncompressed package to begin with. |
7632
d6e63a15cc75
Allow installation of already extracted packages
Thomas Weber <thomas.weber.mail@gmail.com>
parents:
7548
diff
changeset
|
640 if (exist (tgz, "dir")) |
10549 | 641 dirlist = {".", "..", tgz}; |
7632
d6e63a15cc75
Allow installation of already extracted packages
Thomas Weber <thomas.weber.mail@gmail.com>
parents:
7548
diff
changeset
|
642 endif |
6645 | 643 |
7632
d6e63a15cc75
Allow installation of already extracted packages
Thomas Weber <thomas.weber.mail@gmail.com>
parents:
7548
diff
changeset
|
644 if (exist (tgz, "file") || exist (tgz, "dir")) |
10549 | 645 ## The two first entries of dirlist are "." and "..". |
646 if (exist (tgz, "file")) | |
647 packdir = fullfile (tmpdir, dirlist{3}); | |
648 else | |
649 packdir = fullfile (pwd(), dirlist{3}); | |
650 endif | |
651 packdirs{end+1} = packdir; | |
652 | |
653 ## Make sure the package contains necessary files. | |
654 verify_directory (packdir); | |
655 | |
656 ## Read the DESCRIPTION file. | |
657 filename = fullfile (packdir, "DESCRIPTION"); | |
658 desc = get_description (filename); | |
659 | |
660 ## Verify that package name corresponds with filename. | |
661 [dummy, nm] = fileparts (tgz); | |
662 if ((length (nm) >= length (desc.name)) | |
663 && ! strcmp (desc.name, nm(1:length(desc.name)))) | |
664 error ("package name '%s' doesn't correspond to its filename '%s'", | |
665 desc.name, nm); | |
666 endif | |
667 | |
668 ## Set default installation directory. | |
669 desc.dir = fullfile (prefix, cstrcat (desc.name, "-", desc.version)); | |
670 | |
671 ## Set default architectire dependent installation directory. | |
672 desc.archprefix = fullfile (archprefix, cstrcat (desc.name, "-", | |
673 desc.version)); | |
674 | |
675 ## Save desc. | |
676 descriptions{end+1} = desc; | |
677 | |
678 ## Are any of the new packages already installed? | |
679 ## If so we'll remove the old version. | |
680 for j = 1:length (packages) | |
681 if (strcmp (packages{j}.name, desc.name)) | |
682 packages_to_uninstall(end+1) = j; | |
683 endif | |
684 endfor | |
6645 | 685 endif |
6496 | 686 endfor |
687 catch | |
8506 | 688 ## Something went wrong, delete tmpdirs. |
6496 | 689 for i = 1:length (tmpdirs) |
690 rm_rf (tmpdirs{i}); | |
691 endfor | |
6655 | 692 rethrow (lasterror ()); |
6496 | 693 end_try_catch |
694 | |
8506 | 695 ## Check dependencies. |
6496 | 696 if (handle_deps) |
697 ok = true; | |
698 error_text = ""; | |
699 for i = 1:length (descriptions) | |
700 desc = descriptions{i}; | |
10196
69bb6e1e10d2
complement->setdiff in pkg.m
Jaroslav Hajek <highegg@gmail.com>
parents:
9724
diff
changeset
|
701 idx2 = setdiff (1:length(descriptions), i); |
6695 | 702 if (global_install) |
10549 | 703 ## Global installation is not allowed to have dependencies on locally |
704 ## installed packages. | |
705 idx1 = setdiff (1:length(global_packages), packages_to_uninstall); | |
706 pseudo_installed_packages = {global_packages{idx1}, ... | |
707 descriptions{idx2}}; | |
6695 | 708 else |
10549 | 709 idx1 = setdiff (1:length(local_packages), packages_to_uninstall); |
710 pseudo_installed_packages = {local_packages{idx1}, ... | |
711 global_packages{:}, ... | |
712 descriptions{idx2}}; | |
6695 | 713 endif |
6496 | 714 bad_deps = get_unsatisfied_deps (desc, pseudo_installed_packages); |
715 ## Are there any unsatisfied dependencies? | |
716 if (! isempty (bad_deps)) | |
10549 | 717 ok = false; |
718 for i = 1:length (bad_deps) | |
719 dep = bad_deps{i}; | |
720 error_text = cstrcat (error_text, " ", desc.name, " needs ", | |
721 dep.package, " ", dep.operator, " ", | |
722 dep.version, "\n"); | |
723 endfor | |
6496 | 724 endif |
725 endfor | |
726 | |
727 ## Did we find any unsatisfied dependencies? | |
728 if (! ok) | |
729 error ("the following dependencies where unsatisfied:\n %s", error_text); | |
730 endif | |
731 endif | |
732 | |
8506 | 733 ## Prepare each package for installation. |
6496 | 734 try |
735 for i = 1:length (descriptions) | |
736 desc = descriptions{i}; | |
737 pdir = packdirs{i}; | |
738 prepare_installation (desc, pdir); | |
6614 | 739 configure_make (desc, pdir, verbose); |
6496 | 740 endfor |
741 catch | |
8506 | 742 ## Something went wrong, delete tmpdirs. |
6496 | 743 for i = 1:length (tmpdirs) |
744 rm_rf (tmpdirs{i}); | |
745 endfor | |
6655 | 746 rethrow (lasterror ()); |
6496 | 747 end_try_catch |
748 | |
8506 | 749 ## Uninstall the packages that will be replaced. |
6496 | 750 try |
751 for i = packages_to_uninstall | |
6695 | 752 if (global_install) |
10549 | 753 uninstall ({global_packages{i}.name}, false, verbose, local_list, |
754 global_list, global_install); | |
6695 | 755 else |
10549 | 756 uninstall ({local_packages{i}.name}, false, verbose, local_list, |
757 global_list, global_install); | |
6695 | 758 endif |
6496 | 759 endfor |
760 catch | |
8506 | 761 ## Something went wrong, delete tmpdirs. |
6496 | 762 for i = 1:length (tmpdirs) |
763 rm_rf (tmpdirs{i}); | |
764 endfor | |
6655 | 765 rethrow (lasterror ()); |
6496 | 766 end_try_catch |
767 | |
8506 | 768 ## Install each package. |
6496 | 769 try |
770 for i = 1:length (descriptions) | |
771 desc = descriptions{i}; | |
772 pdir = packdirs{i}; | |
6925 | 773 copy_files (desc, pdir, global_install); |
774 create_pkgadddel (desc, pdir, "PKG_ADD", global_install); | |
775 create_pkgadddel (desc, pdir, "PKG_DEL", global_install); | |
8575
f134925a1cfa
m-file implementation of help system
Soren Hauberg <soren@hauberg.org>
parents:
8507
diff
changeset
|
776 finish_installation (desc, pdir, global_install); |
f134925a1cfa
m-file implementation of help system
Soren Hauberg <soren@hauberg.org>
parents:
8507
diff
changeset
|
777 generate_lookfor_cache (desc); |
6496 | 778 endfor |
779 catch | |
8506 | 780 ## Something went wrong, delete tmpdirs. |
6496 | 781 for i = 1:length (tmpdirs) |
782 rm_rf (tmpdirs{i}); | |
783 endfor | |
784 for i = 1:length (descriptions) | |
785 rm_rf (descriptions{i}.dir); | |
6925 | 786 rm_rf (getarchdir (descriptions{i})); |
6496 | 787 endfor |
6655 | 788 rethrow (lasterror ()); |
6496 | 789 end_try_catch |
790 | |
791 ## Check if the installed directory is empty. If it is remove it | |
8506 | 792 ## from the list. |
6496 | 793 for i = length (descriptions):-1:1 |
6925 | 794 if (dirempty (descriptions{i}.dir, {"packinfo", "doc"}) && |
10549 | 795 dirempty (getarchdir (descriptions{i}))) |
6655 | 796 warning ("package %s is empty\n", descriptions{i}.name); |
6496 | 797 rm_rf (descriptions{i}.dir); |
6925 | 798 rm_rf (getarchdir (descriptions{i})); |
6496 | 799 descriptions(i) = []; |
800 endif | |
801 endfor | |
802 | |
803 ## If the package requested that it is autoloaded, or the installer | |
804 ## requested that it is, then mark the package as autoloaded. | |
805 for i = length (descriptions):-1:1 | |
806 if (autoload > 0 || (autoload == 0 && isautoload (descriptions(i)))) | |
807 fclose (fopen (fullfile (descriptions{i}.dir, "packinfo", | |
10549 | 808 ".autoload"), "wt")); |
6695 | 809 descriptions{i}.autoload = 1; |
6496 | 810 endif |
811 endfor | |
812 | |
8506 | 813 ## Add the packages to the package list. |
6496 | 814 try |
815 if (global_install) | |
10196
69bb6e1e10d2
complement->setdiff in pkg.m
Jaroslav Hajek <highegg@gmail.com>
parents:
9724
diff
changeset
|
816 idx = setdiff (1:length(global_packages), packages_to_uninstall); |
6695 | 817 global_packages = save_order ({global_packages{idx}, descriptions{:}}); |
6496 | 818 save (global_list, "global_packages"); |
6820 | 819 installed_pkgs_lst = {local_packages{:}, global_packages{:}}; |
6496 | 820 else |
10196
69bb6e1e10d2
complement->setdiff in pkg.m
Jaroslav Hajek <highegg@gmail.com>
parents:
9724
diff
changeset
|
821 idx = setdiff (1:length(local_packages), packages_to_uninstall); |
6695 | 822 local_packages = save_order ({local_packages{idx}, descriptions{:}}); |
6496 | 823 save (local_list, "local_packages"); |
6820 | 824 installed_pkgs_lst = {local_packages{:}, global_packages{:}}; |
6496 | 825 endif |
826 catch | |
8506 | 827 ## Something went wrong, delete tmpdirs. |
6496 | 828 for i = 1:length (tmpdirs) |
829 rm_rf (tmpdirs{i}); | |
830 endfor | |
831 for i = 1:length (descriptions) | |
832 rm_rf (descriptions{i}.dir); | |
833 endfor | |
834 if (global_install) | |
6695 | 835 printf ("error: couldn't append to %s\n", global_list); |
6496 | 836 else |
6695 | 837 printf ("error: couldn't append to %s\n", local_list); |
6496 | 838 endif |
6695 | 839 rethrow (lasterror ()); |
6496 | 840 end_try_catch |
841 | |
8506 | 842 ## All is well, let's clean up. |
6496 | 843 for i = 1:length (tmpdirs) |
844 [status, msg] = rm_rf (tmpdirs{i}); | |
845 if (status != 1) | |
846 warning ("couldn't clean up after my self: %s\n", msg); | |
847 endif | |
848 endfor | |
849 | |
850 ## Add the newly installed packages to the path, so the user | |
8506 | 851 ## can begin using them. Only load them if they are marked autoload. |
6496 | 852 if (length (descriptions) > 0) |
6695 | 853 idx = []; |
6496 | 854 for i = 1:length (descriptions) |
6695 | 855 if (isautoload (descriptions(i))) |
10549 | 856 nm = descriptions{i}.name; |
857 for j = 1:length (installed_pkgs_lst) | |
858 if (strcmp (nm, installed_pkgs_lst{j}.name)) | |
859 idx (end + 1) = j; | |
860 break; | |
861 endif | |
862 endfor | |
6614 | 863 endif |
6496 | 864 endfor |
6925 | 865 load_packages_and_dependencies (idx, handle_deps, installed_pkgs_lst, |
10549 | 866 global_install); |
6496 | 867 endif |
868 endfunction | |
869 | |
6645 | 870 function uninstall (pkgnames, handle_deps, verbose, local_list, |
10549 | 871 global_list, global_install) |
8506 | 872 ## Get the list of installed packages. |
6496 | 873 [local_packages, global_packages] = installed_packages(local_list, |
10549 | 874 global_list); |
6645 | 875 if (global_install) |
6820 | 876 installed_pkgs_lst = {local_packages{:}, global_packages{:}}; |
6496 | 877 else |
6820 | 878 installed_pkgs_lst = local_packages; |
6496 | 879 endif |
880 | |
6820 | 881 num_packages = length (installed_pkgs_lst); |
6496 | 882 delete_idx = []; |
883 for i = 1:num_packages | |
6820 | 884 cur_name = installed_pkgs_lst{i}.name; |
6496 | 885 if (any (strcmp (cur_name, pkgnames))) |
886 delete_idx(end+1) = i; | |
887 endif | |
888 endfor | |
889 | |
890 ## Are all the packages that should be uninstalled already installed? | |
891 if (length (delete_idx) != length (pkgnames)) | |
6645 | 892 if (global_install) |
8506 | 893 ## Try again for a locally installed package. |
6820 | 894 installed_pkgs_lst = local_packages; |
6496 | 895 |
6820 | 896 num_packages = length (installed_pkgs_lst); |
6496 | 897 delete_idx = []; |
898 for i = 1:num_packages | |
10549 | 899 cur_name = installed_pkgs_lst{i}.name; |
900 if (any (strcmp (cur_name, pkgnames))) | |
901 delete_idx(end+1) = i; | |
902 endif | |
6496 | 903 endfor |
904 if (length (delete_idx) != length (pkgnames)) | |
10549 | 905 ## FIXME: We should have a better error message. |
906 warning ("some of the packages you want to uninstall are not installed"); | |
6496 | 907 endif |
908 else | |
8506 | 909 ## FIXME: We should have a better error message. |
8664 | 910 warning ("some of the packages you want to uninstall are not installed"); |
6496 | 911 endif |
912 endif | |
913 | |
8506 | 914 ## Compute the packages that will remain installed. |
10196
69bb6e1e10d2
complement->setdiff in pkg.m
Jaroslav Hajek <highegg@gmail.com>
parents:
9724
diff
changeset
|
915 idx = setdiff (1:num_packages, delete_idx); |
6820 | 916 remaining_packages = {installed_pkgs_lst{idx}}; |
6496 | 917 |
8506 | 918 ## Check dependencies. |
6496 | 919 if (handle_deps) |
920 error_text = ""; | |
921 for i = 1:length (remaining_packages) | |
922 desc = remaining_packages{i}; | |
923 bad_deps = get_unsatisfied_deps (desc, remaining_packages); | |
924 | |
925 ## Will the uninstallation break any dependencies? | |
926 if (! isempty (bad_deps)) | |
10549 | 927 for i = 1:length (bad_deps) |
928 dep = bad_deps{i}; | |
929 error_text = cstrcat (error_text, " ", desc.name, " needs ", | |
930 dep.package, " ", dep.operator, " ", | |
931 dep.version, "\n"); | |
932 endfor | |
6496 | 933 endif |
934 endfor | |
935 | |
936 if (! isempty (error_text)) | |
937 error ("the following dependencies where unsatisfied:\n %s", error_text); | |
938 endif | |
939 endif | |
940 | |
8506 | 941 ## Delete the directories containing the packages. |
6496 | 942 for i = delete_idx |
6820 | 943 desc = installed_pkgs_lst{i}; |
6496 | 944 ## If an 'on_uninstall.m' exist, call it! |
945 if (exist (fullfile (desc.dir, "packinfo", "on_uninstall.m"), "file")) | |
6614 | 946 wd = pwd (); |
7498 | 947 cd (fullfile (desc.dir, "packinfo")); |
6614 | 948 on_uninstall (desc); |
949 cd (wd); | |
6496 | 950 endif |
8506 | 951 ## Do the actual deletion. |
6675 | 952 if (desc.loaded) |
953 rmpath (desc.dir); | |
6925 | 954 if (exist (getarchdir (desc))) |
10549 | 955 rmpath (getarchdir (desc)); |
6675 | 956 endif |
6614 | 957 endif |
6496 | 958 if (exist (desc.dir, "dir")) |
959 [status, msg] = rm_rf (desc.dir); | |
960 if (status != 1) | |
10549 | 961 error ("couldn't delete directory %s: %s", desc.dir, msg); |
6496 | 962 endif |
6925 | 963 [status, msg] = rm_rf (getarchdir (desc)); |
964 if (status != 1) | |
10549 | 965 error ("couldn't delete directory %s: %s", getarchdir (desc), msg); |
6925 | 966 endif |
967 if (dirempty (desc.archprefix)) | |
10549 | 968 rm_rf (desc.archprefix); |
6925 | 969 endif |
6496 | 970 else |
971 warning ("directory %s previously lost", desc.dir); | |
972 endif | |
973 endfor | |
974 | |
8506 | 975 ## Write a new ~/.octave_packages. |
6645 | 976 if (global_install) |
6496 | 977 if (length (remaining_packages) == 0) |
978 unlink (global_list); | |
979 else | |
6695 | 980 global_packages = save_order (remaining_packages); |
6496 | 981 save (global_list, "global_packages"); |
982 endif | |
983 else | |
984 if (length (remaining_packages) == 0) | |
985 unlink (local_list); | |
986 else | |
6695 | 987 local_packages = save_order (remaining_packages); |
6496 | 988 save (local_list, "local_packages"); |
989 endif | |
990 endif | |
991 | |
992 endfunction | |
993 | |
7497 | 994 function [pkg_desc_list, flag] = describe (pkgnames, verbose, |
10549 | 995 local_list, global_list) |
7497 | 996 |
8506 | 997 ## Get the list of installed packages. |
7497 | 998 installed_pkgs_lst = installed_packages(local_list, global_list); |
7498 | 999 num_packages = length (installed_pkgs_lst); |
7497 | 1000 |
1001 | |
7498 | 1002 describe_all = false; |
1003 if (any (strcmp ("all", pkgnames))) | |
1004 describe_all = true; | |
8455
fd11a08a9b31
disallow invalid {}-indexed assigments
Jaroslav Hajek <highegg@gmail.com>
parents:
8202
diff
changeset
|
1005 flag(1:num_packages) = {"Not Loaded"}; |
7498 | 1006 num_pkgnames = num_packages; |
7497 | 1007 else |
7498 | 1008 num_pkgnames = length (pkgnames); |
8455
fd11a08a9b31
disallow invalid {}-indexed assigments
Jaroslav Hajek <highegg@gmail.com>
parents:
8202
diff
changeset
|
1009 flag(1:num_pkgnames) = {"Not installed"}; |
7498 | 1010 endif |
7497 | 1011 |
1012 for i = 1:num_packages | |
8507 | 1013 curr_name = installed_pkgs_lst{i}.name; |
7497 | 1014 if (describe_all) |
1015 name_pos = i; | |
1016 else | |
1017 name_pos = find(strcmp (curr_name, pkgnames)); | |
7498 | 1018 endif |
1019 | |
1020 if (! isempty (name_pos)) | |
7497 | 1021 if (installed_pkgs_lst{i}.loaded) |
10549 | 1022 flag{name_pos} = "Loaded"; |
7497 | 1023 else |
10549 | 1024 flag{name_pos} = "Not loaded"; |
7497 | 1025 endif |
1026 | |
7498 | 1027 pkg_desc_list{name_pos}.name = installed_pkgs_lst{i}.name; |
9258
a653c61ee98c
let pkg describe return version information
Carlo de Falco <kingcrimson@tiscali.it>
parents:
9220
diff
changeset
|
1028 pkg_desc_list{name_pos}.version = installed_pkgs_lst{i}.version; |
7498 | 1029 pkg_desc_list{name_pos}.description = installed_pkgs_lst{i}.description; |
1030 pkg_desc_list{name_pos}.provides = parse_pkg_idx (installed_pkgs_lst{i}.dir); | |
7497 | 1031 |
1032 endif | |
1033 endfor | |
1034 | |
7498 | 1035 non_inst = find (strcmp (flag, "Not installed")); |
9220
70177bf9cc16
Fix bug when calling pkg describe to check whether a package is installed
Carlo de Falco <kingcrimson@tiscali.it>
parents:
9153
diff
changeset
|
1036 if (! isempty (non_inst)) |
70177bf9cc16
Fix bug when calling pkg describe to check whether a package is installed
Carlo de Falco <kingcrimson@tiscali.it>
parents:
9153
diff
changeset
|
1037 if (nargout < 2) |
70177bf9cc16
Fix bug when calling pkg describe to check whether a package is installed
Carlo de Falco <kingcrimson@tiscali.it>
parents:
9153
diff
changeset
|
1038 non_inst_str = sprintf (" %s ", pkgnames{non_inst}); |
70177bf9cc16
Fix bug when calling pkg describe to check whether a package is installed
Carlo de Falco <kingcrimson@tiscali.it>
parents:
9153
diff
changeset
|
1039 error ("some packages are not installed: %s", non_inst_str); |
70177bf9cc16
Fix bug when calling pkg describe to check whether a package is installed
Carlo de Falco <kingcrimson@tiscali.it>
parents:
9153
diff
changeset
|
1040 else |
70177bf9cc16
Fix bug when calling pkg describe to check whether a package is installed
Carlo de Falco <kingcrimson@tiscali.it>
parents:
9153
diff
changeset
|
1041 pkg_desc_list{non_inst} = struct ("name", {}, "description", |
10549 | 1042 {}, "provides", {}); |
9220
70177bf9cc16
Fix bug when calling pkg describe to check whether a package is installed
Carlo de Falco <kingcrimson@tiscali.it>
parents:
9153
diff
changeset
|
1043 endif |
7497 | 1044 endif |
1045 | |
1046 if (nargout == 0) | |
7498 | 1047 for i = 1:num_pkgnames |
9258
a653c61ee98c
let pkg describe return version information
Carlo de Falco <kingcrimson@tiscali.it>
parents:
9220
diff
changeset
|
1048 print_package_description (pkg_desc_list{i}.name, |
10549 | 1049 pkg_desc_list{i}.version, |
1050 pkg_desc_list{i}.provides, | |
1051 pkg_desc_list{i}.description, | |
1052 flag{i}, verbose); | |
7497 | 1053 endfor |
1054 endif | |
1055 | |
1056 endfunction | |
1057 | |
8506 | 1058 ## AUXILIARY FUNCTIONS |
6496 | 1059 |
8506 | 1060 ## Read an INDEX file. |
7498 | 1061 function [pkg_idx_struct] = parse_pkg_idx (packdir) |
7497 | 1062 |
7498 | 1063 index_file = fullfile (packdir, "packinfo", "INDEX"); |
1064 | |
1065 if (! exist (index_file, "file")) | |
1066 error ("could not find any INDEX file in directory %s, try 'pkg rebuild all' to generate missing INDEX files", packdir); | |
7497 | 1067 endif |
1068 | |
1069 | |
7498 | 1070 [fid, msg] = fopen (index_file, "r"); |
7497 | 1071 if (fid == -1) |
7498 | 1072 error ("the INDEX file %s could not be read: %s", |
10549 | 1073 index_file, msg); |
7497 | 1074 endif |
7498 | 1075 |
7497 | 1076 cat_num = 1; |
1077 pkg_idx_struct{1}.category = "Uncategorized"; | |
1078 pkg_idx_struct{1}.functions = {}; | |
1079 | |
7498 | 1080 line = fgetl (fid); |
1081 while (isempty (strfind (line, ">>")) && ! feof (fid)) | |
1082 line = fgetl (fid); | |
7497 | 1083 endwhile |
1084 | |
7498 | 1085 while (! feof (fid) || line != -1) |
1086 if (! any (! isspace (line)) || line(1) == "#" || any (line == "=")) | |
7497 | 1087 ## Comments, blank lines or comments about unimplemented |
1088 ## functions: do nothing | |
8202
cf59d542f33e
replace all TODOs and XXXs with FIXMEs
Jaroslav Hajek <highegg@gmail.com>
parents:
8174
diff
changeset
|
1089 ## FIXME: probably comments and pointers to external functions |
7497 | 1090 ## could be treated better when printing to screen? |
7498 | 1091 elseif (! isempty (strfind (line, ">>"))) |
8506 | 1092 ## Skip package name and description as they are in DESCRIPTION |
1093 ## already. | |
7498 | 1094 elseif (! isspace (line(1))) |
8506 | 1095 ## Category. |
7498 | 1096 if (! isempty (pkg_idx_struct{cat_num}.functions)) |
10549 | 1097 pkg_idx_struct{++cat_num}.functions = {}; |
7497 | 1098 endif |
7498 | 1099 pkg_idx_struct{cat_num}.category = deblank (line); |
7497 | 1100 else |
8506 | 1101 ## Function names. |
7498 | 1102 while (any (! isspace (line))) |
10549 | 1103 [fun_name, line] = strtok (line); |
1104 pkg_idx_struct{cat_num}.functions{end+1} = deblank (fun_name); | |
7497 | 1105 endwhile |
1106 endif | |
7498 | 1107 line = fgetl (fid); |
7497 | 1108 endwhile |
1109 fclose (fid); | |
1110 endfunction | |
1111 | |
9258
a653c61ee98c
let pkg describe return version information
Carlo de Falco <kingcrimson@tiscali.it>
parents:
9220
diff
changeset
|
1112 function print_package_description (pkg_name, pkg_ver, pkg_idx_struct, |
10549 | 1113 pkg_desc, status, verbose) |
7497 | 1114 |
7498 | 1115 printf ("---\nPackage name:\n\t%s\n", pkg_name); |
9258
a653c61ee98c
let pkg describe return version information
Carlo de Falco <kingcrimson@tiscali.it>
parents:
9220
diff
changeset
|
1116 printf ("Version:\n\t%s\n", pkg_ver); |
7498 | 1117 printf ("Short description:\n\t%s\n", pkg_desc); |
1118 printf ("Status:\n\t%s\n", status); | |
7497 | 1119 if (verbose) |
7498 | 1120 printf ("---\nProvides:\n"); |
1121 for i = 1:length(pkg_idx_struct) | |
1122 if (! isempty (pkg_idx_struct{i}.functions)) | |
10549 | 1123 printf ("%s\n", pkg_idx_struct{i}.category); |
1124 for j = 1:length(pkg_idx_struct{i}.functions) | |
1125 printf ("\t%s\n", pkg_idx_struct{i}.functions{j}); | |
1126 endfor | |
7497 | 1127 endif |
1128 endfor | |
1129 endif | |
1130 | |
1131 endfunction | |
1132 | |
1133 | |
6675 | 1134 function pth = absolute_pathname (pth) |
7498 | 1135 [status, msg, msgid] = fileattrib (pth); |
6729 | 1136 if (status != 1) |
1137 error ("could not find the file or path %s", pth); | |
1138 else | |
1139 pth = msg.Name; | |
1140 endif | |
6675 | 1141 endfunction |
1142 | |
1143 function repackage (builddir, buildlist) | |
1144 packages = installed_packages (buildlist, buildlist); | |
1145 | |
1146 wd = pwd(); | |
1147 for i = 1 : length(packages) | |
1148 pack = packages{i}; | |
1149 unwind_protect | |
1150 cd (builddir); | |
1151 mkdir (pack.name); | |
1152 mkdir (fullfile (pack.name, "inst")); | |
1153 copyfile (fullfile (pack.dir, "*"), fullfile (pack.name, "inst")); | |
1154 movefile (fullfile (pack.name, "inst","packinfo", "*"), pack.name); | |
1155 if (exist (fullfile (pack.name, "inst","packinfo", ".autoload"), "file")) | |
10549 | 1156 unlink (fullfile (pack.name, "inst","packinfo", ".autoload")); |
6675 | 1157 endif |
1158 rmdir (fullfile (pack.name, "inst", "packinfo")); | |
1159 if (exist (fullfile (pack.name, "inst", "doc"), "dir")) | |
10549 | 1160 movefile (fullfile (pack.name, "inst", "doc"), pack.name); |
6675 | 1161 endif |
1162 if (exist (fullfile (pack.name, "inst", "bin"), "dir")) | |
10549 | 1163 movefile (fullfile (pack.name, "inst", "bin"), pack.name); |
6675 | 1164 endif |
7540
3422f39573b1
strcat.m: Matlab compatibility, with cstrcat.m replacing conventional strcat.m.
Ben Abbott <bpabbott@mac.com>
parents:
7498
diff
changeset
|
1165 archdir = fullfile (pack.archprefix, cstrcat (pack.name, "-", |
10549 | 1166 pack.version), getarch ()); |
6675 | 1167 if (exist (archdir, "dir")) |
10549 | 1168 if (exist (fullfile (pack.name, "inst", "PKG_ADD"), "file")) |
1169 unlink (fullfile (pack.name, "inst", "PKG_ADD")); | |
1170 endif | |
1171 if (exist (fullfile (pack.name, "inst", "PKG_DEL"), "file")) | |
1172 unlink (fullfile (pack.name, "inst", "PKG_DEL")); | |
1173 endif | |
1174 if (exist (fullfile (archdir, "PKG_ADD"), "file")) | |
1175 movefile (fullfile (archdir, "PKG_ADD"), | |
1176 fullfile (pack.name, "PKG_ADD")); | |
1177 endif | |
1178 if (exist (fullfile (archdir, "PKG_DEL"), "file")) | |
1179 movefile (fullfile (archdir, "PKG_DEL"), | |
1180 fullfile (pack.name, "PKG_DEL")); | |
1181 endif | |
6675 | 1182 else |
10549 | 1183 if (exist (fullfile (pack.name, "inst", "PKG_ADD"), "file")) |
1184 movefile (fullfile (pack.name, "inst", "PKG_ADD"), | |
1185 fullfile (pack.name, "PKG_ADD")); | |
1186 endif | |
1187 if (exist (fullfile (pack.name, "inst", "PKG_DEL"), "file")) | |
1188 movefile (fullfile (pack.name, "inst", "PKG_DEL"), | |
1189 fullfile (pack.name, "PKG_DEL")); | |
1190 endif | |
1191 endif | |
7540
3422f39573b1
strcat.m: Matlab compatibility, with cstrcat.m replacing conventional strcat.m.
Ben Abbott <bpabbott@mac.com>
parents:
7498
diff
changeset
|
1192 tfile = cstrcat (pack.name, "-", pack.version, ".tar"); |
6675 | 1193 tar (tfile, pack.name); |
6925 | 1194 try |
10549 | 1195 gzip (tfile); |
1196 unlink (tfile); | |
6925 | 1197 catch |
10549 | 1198 warning ("failed to compress %s", tfile); |
6925 | 1199 end_try_catch |
6675 | 1200 unwind_protect_cleanup |
1201 if (exist (pack.name, "dir")) | |
10549 | 1202 rm_rf (pack.name); |
6675 | 1203 endif |
1204 cd (wd); | |
1205 end_unwind_protect | |
1206 endfor | |
1207 endfunction | |
1208 | |
1209 function auto = isautoload (desc) | |
6695 | 1210 auto = false; |
1211 if (isfield (desc{1}, "autoload")) | |
1212 a = desc{1}.autoload; | |
1213 if ((isnumeric (a) && a > 0) | |
1214 || (ischar (a) && (strcmpi (a, "true") | |
10549 | 1215 || strcmpi (a, "on") |
1216 || strcmpi (a, "yes") | |
1217 || strcmpi (a, "1")))) | |
6695 | 1218 auto = true; |
1219 endif | |
6675 | 1220 endif |
1221 endfunction | |
1222 | |
6496 | 1223 function prepare_installation (desc, packdir) |
1224 ## Is there a pre_install to call? | |
1225 if (exist (fullfile (packdir, "pre_install.m"), "file")) | |
1226 wd = pwd (); | |
1227 try | |
1228 cd (packdir); | |
1229 pre_install (desc); | |
1230 cd (wd); | |
1231 catch | |
1232 cd (wd); | |
6695 | 1233 rethrow (lasterror ()); |
6496 | 1234 end_try_catch |
1235 endif | |
1236 | |
8506 | 1237 ## If the directory "inst" doesn't exist, we create it. |
6496 | 1238 inst_dir = fullfile (packdir, "inst"); |
1239 if (! exist (inst_dir, "dir")) | |
1240 [status, msg] = mkdir (inst_dir); | |
1241 if (status != 1) | |
1242 rm_rf (desc.dir); | |
1243 error ("the 'inst' directory did not exist and could not be created: %s", | |
10549 | 1244 msg); |
6258 | 1245 endif |
1246 endif | |
1247 endfunction | |
1248 | |
6614 | 1249 function configure_make (desc, packdir, verbose) |
8506 | 1250 ## Perform ./configure, make, make install in "src". |
6496 | 1251 if (exist (fullfile (packdir, "src"), "dir")) |
1252 src = fullfile (packdir, "src"); | |
8506 | 1253 ## Configure. |
6496 | 1254 if (exist (fullfile (src, "configure"), "file")) |
7111 | 1255 flags = ""; |
1256 if (isempty (getenv ("CC"))) | |
7540
3422f39573b1
strcat.m: Matlab compatibility, with cstrcat.m replacing conventional strcat.m.
Ben Abbott <bpabbott@mac.com>
parents:
7498
diff
changeset
|
1257 flags = cstrcat (flags, " CC=\"", octave_config_info ("CC"), "\""); |
7111 | 1258 endif |
1259 if (isempty (getenv ("CXX"))) | |
7540
3422f39573b1
strcat.m: Matlab compatibility, with cstrcat.m replacing conventional strcat.m.
Ben Abbott <bpabbott@mac.com>
parents:
7498
diff
changeset
|
1260 flags = cstrcat (flags, " CXX=\"", octave_config_info ("CXX"), "\""); |
7111 | 1261 endif |
1262 if (isempty (getenv ("AR"))) | |
7540
3422f39573b1
strcat.m: Matlab compatibility, with cstrcat.m replacing conventional strcat.m.
Ben Abbott <bpabbott@mac.com>
parents:
7498
diff
changeset
|
1263 flags = cstrcat (flags, " AR=\"", octave_config_info ("AR"), "\""); |
7111 | 1264 endif |
1265 if (isempty (getenv ("RANLIB"))) | |
7540
3422f39573b1
strcat.m: Matlab compatibility, with cstrcat.m replacing conventional strcat.m.
Ben Abbott <bpabbott@mac.com>
parents:
7498
diff
changeset
|
1266 flags = cstrcat (flags, " RANLIB=\"", octave_config_info ("RANLIB"), "\""); |
7111 | 1267 endif |
8172
9ba45b125ee8
enclose building direcries in quotes in pkg.m
Benjamin Lindner <lindnerb@users.sourceforge.net>
parents:
8043
diff
changeset
|
1268 [status, output] = shell (strcat ("cd '", src, "'; ./configure --prefix=\"", |
7111 | 1269 desc.dir, "\"", flags)); |
6496 | 1270 if (status != 0) |
10549 | 1271 rm_rf (desc.dir); |
1272 error ("the configure script returned the following error: %s", output); | |
6675 | 1273 elseif (verbose) |
10549 | 1274 printf("%s", output); |
6496 | 1275 endif |
6675 | 1276 |
5801 | 1277 endif |
1278 | |
8506 | 1279 ## Make. |
6496 | 1280 if (exist (fullfile (src, "Makefile"), "file")) |
7540
3422f39573b1
strcat.m: Matlab compatibility, with cstrcat.m replacing conventional strcat.m.
Ben Abbott <bpabbott@mac.com>
parents:
7498
diff
changeset
|
1281 [status, output] = shell (cstrcat ("export INSTALLDIR=\"", desc.dir, |
10549 | 1282 "\"; make -C '", src, "'")); |
6496 | 1283 if (status != 0) |
10549 | 1284 rm_rf (desc.dir); |
1285 error ("'make' returned the following error: %s", output); | |
6675 | 1286 elseif (verbose) |
10549 | 1287 printf("%s", output); |
6496 | 1288 endif |
5801 | 1289 endif |
1290 | |
8506 | 1291 ## Copy files to "inst" and "inst/arch" (this is instead of 'make |
1292 ## install'). | |
6496 | 1293 files = fullfile (src, "FILES"); |
1294 instdir = fullfile (packdir, "inst"); | |
6614 | 1295 archdir = fullfile (packdir, "inst", getarch ()); |
6950 | 1296 |
8506 | 1297 ## Get file names. |
6496 | 1298 if (exist (files, "file")) |
1299 [fid, msg] = fopen (files, "r"); | |
1300 if (fid < 0) | |
10549 | 1301 error ("couldn't open %s: %s", files, msg); |
5971 | 1302 endif |
6496 | 1303 filenames = char (fread (fid))'; |
1304 fclose (fid); | |
1305 if (filenames(end) == "\n") | |
10549 | 1306 filenames(end) = []; |
6258 | 1307 endif |
6655 | 1308 filenames = split_by (filenames, "\n"); |
6496 | 1309 delete_idx = []; |
6655 | 1310 for i = 1:length (filenames) |
10549 | 1311 if (! all (isspace (filenames{i}))) |
1312 filenames{i} = fullfile (src, filenames{i}); | |
1313 else | |
1314 delete_idx(end+1) = i; | |
1315 endif | |
5971 | 1316 endfor |
6655 | 1317 filenames(delete_idx) = []; |
6496 | 1318 else |
1319 m = dir (fullfile (src, "*.m")); | |
1320 oct = dir (fullfile (src, "*.oct")); | |
1321 mex = dir (fullfile (src, "*.mex")); | |
8174
ea9b5f31bfac
pkg.m: better handling of filenames with spaces
John W. Eaton <jwe@octave.org>
parents:
8172
diff
changeset
|
1322 |
ea9b5f31bfac
pkg.m: better handling of filenames with spaces
John W. Eaton <jwe@octave.org>
parents:
8172
diff
changeset
|
1323 filenames = cellfun (@(x) fullfile (src, x), |
10549 | 1324 {m.name, oct.name, mex.name}, |
1325 "UniformOutput", false); | |
5971 | 1326 endif |
5801 | 1327 |
8506 | 1328 ## Split into architecture dependent and independent files. |
7024 | 1329 if (isempty (filenames)) |
1330 idx = []; | |
1331 else | |
8043
30d15ab0ce01
avoid problematic subfunction call in an anonymous function
Jaroslav Hajek <highegg@gmail.com>
parents:
7739
diff
changeset
|
1332 idx = cellfun (@is_architecture_dependent, filenames); |
7024 | 1333 endif |
6950 | 1334 archdependent = filenames (idx); |
1335 archindependent = filenames (!idx); | |
1336 | |
8506 | 1337 ## Copy the files. |
7548
9cbf1e2011a3
pkg.m: adapt to changes in isspace for cell arrays of strings.
Michael Goffioul <michael.goffioul@gmail.com>
parents:
7540
diff
changeset
|
1338 if (! all (isspace ([filenames{:}]))) |
10549 | 1339 if (! exist (instdir, "dir")) |
1340 mkdir (instdir); | |
1341 endif | |
1342 if (! all (isspace ([archindependent{:}]))) | |
1343 if (verbose) | |
1344 printf ("copyfile"); | |
1345 printf (" %s", archindependent{:}); | |
1346 printf ("%s\n", instdir); | |
1347 endif | |
1348 [status, output] = copyfile (archindependent, instdir); | |
1349 if (status != 1) | |
1350 rm_rf (desc.dir); | |
1351 error ("Couldn't copy files from 'src' to 'inst': %s", output); | |
1352 endif | |
6614 | 1353 endif |
10549 | 1354 if (! all (isspace ([archdependent{:}]))) |
1355 if (verbose) | |
1356 printf ("copyfile"); | |
1357 printf (" %s", archdependent{:}); | |
1358 printf (" %s\n", archdir); | |
1359 endif | |
1360 if (! exist (archdir, "dir")) | |
1361 mkdir (archdir); | |
1362 endif | |
1363 [status, output] = copyfile (archdependent, archdir); | |
1364 if (status != 1) | |
1365 rm_rf (desc.dir); | |
1366 error ("Couldn't copy files from 'src' to 'inst': %s", output); | |
1367 endif | |
6614 | 1368 endif |
5801 | 1369 endif |
6496 | 1370 endif |
5801 | 1371 endfunction |
1372 | |
5971 | 1373 function pkg = extract_pkg (nm, pat) |
5955 | 1374 fid = fopen (nm, "rt"); |
5971 | 1375 pkg = ""; |
5955 | 1376 if (fid >= 0) |
6496 | 1377 while (! feof (fid)) |
5955 | 1378 ln = fgetl (fid); |
1379 if (ln > 0) | |
10549 | 1380 t = regexp (ln, pat, "tokens"); |
1381 if (! isempty (t)) | |
7540
3422f39573b1
strcat.m: Matlab compatibility, with cstrcat.m replacing conventional strcat.m.
Ben Abbott <bpabbott@mac.com>
parents:
7498
diff
changeset
|
1382 pkg = cstrcat (pkg, "\n", t{1}{1}); |
10549 | 1383 endif |
5955 | 1384 endif |
1385 endwhile | |
6496 | 1386 if (! isempty (pkg)) |
7540
3422f39573b1
strcat.m: Matlab compatibility, with cstrcat.m replacing conventional strcat.m.
Ben Abbott <bpabbott@mac.com>
parents:
7498
diff
changeset
|
1387 pkg = cstrcat (pkg, "\n"); |
5955 | 1388 endif |
1389 fclose (fid); | |
1390 endif | |
1391 endfunction | |
1392 | |
6925 | 1393 function create_pkgadddel (desc, packdir, nm, global_install) |
6675 | 1394 instpkg = fullfile (desc.dir, nm); |
1395 instfid = fopen (instpkg, "wt"); | |
1396 ## If it is exists, most of the PKG_* file should go into the | |
1397 ## architecture dependent directory so that the autoload/mfilename | |
1398 ## commands work as expected. The only part that doesn't is the | |
1399 ## part in the main directory. | |
7540
3422f39573b1
strcat.m: Matlab compatibility, with cstrcat.m replacing conventional strcat.m.
Ben Abbott <bpabbott@mac.com>
parents:
7498
diff
changeset
|
1400 archdir = fullfile (getarchprefix (desc), cstrcat (desc.name, "-", |
10549 | 1401 desc.version), getarch ()); |
6925 | 1402 if (exist (getarchdir (desc, global_install), "dir")) |
1403 archpkg = fullfile (getarchdir (desc, global_install), nm); | |
1404 archfid = fopen (archpkg, "at"); | |
6675 | 1405 else |
1406 archpkg = instpkg; | |
1407 archfid = instfid; | |
1408 endif | |
6634 | 1409 |
6675 | 1410 if (archfid >= 0 && instfid >= 0) |
8506 | 1411 ## Search all dot-m files for PKG commands. |
7498 | 1412 lst = dir (fullfile (packdir, "inst", "*.m")); |
6496 | 1413 for i = 1:length (lst) |
7498 | 1414 nam = fullfile (packdir, "inst", lst(i).name); |
6675 | 1415 fwrite (instfid, extract_pkg (nam, ['^[#%][#%]* *' nm ': *(.*)$'])); |
5955 | 1416 endfor |
1417 | |
8506 | 1418 ## Search all C++ source files for PKG commands. |
7498 | 1419 lst = dir (fullfile (packdir, "src", "*.cc")); |
6496 | 1420 for i = 1:length (lst) |
7498 | 1421 nam = fullfile (packdir, "src", lst(i).name); |
6675 | 1422 fwrite (archfid, extract_pkg (nam, ['^//* *' nm ': *(.*)$'])); |
1423 fwrite (archfid, extract_pkg (nam, ['^/\** *' nm ': *(.*) *\*/$'])); | |
5955 | 1424 endfor |
1425 | |
8506 | 1426 ## Add developer included PKG commands. |
6496 | 1427 packdirnm = fullfile (packdir, nm); |
1428 if (exist (packdirnm, "file")) | |
6675 | 1429 fid = fopen (packdirnm, "rt"); |
1430 if (fid >= 0) | |
1431 while (! feof (fid)) | |
1432 ln = fgets (fid); | |
5955 | 1433 if (ln > 0) |
6675 | 1434 fwrite (archfid, ln); |
5955 | 1435 endif |
1436 endwhile | |
6675 | 1437 fclose (fid); |
5955 | 1438 endif |
1439 endif | |
5971 | 1440 |
8506 | 1441 ## If the files is empty remove it. |
6675 | 1442 fclose (instfid); |
1443 t = dir (instpkg); | |
5971 | 1444 if (t.bytes <= 0) |
6675 | 1445 unlink (instpkg); |
1446 endif | |
1447 | |
1448 if (instfid != archfid) | |
1449 fclose (archfid); | |
1450 t = dir (archpkg); | |
1451 if (t.bytes <= 0) | |
1452 unlink (archpkg); | |
1453 endif | |
5971 | 1454 endif |
5955 | 1455 endif |
1456 endfunction | |
1457 | |
6925 | 1458 function copy_files (desc, packdir, global_install) |
8506 | 1459 ## Create the installation directory. |
6496 | 1460 if (! exist (desc.dir, "dir")) |
1461 [status, output] = mkdir (desc.dir); | |
1462 if (status != 1) | |
1463 error ("couldn't create installation directory %s : %s", | |
1464 desc.dir, output); | |
6020 | 1465 endif |
6496 | 1466 endif |
6020 | 1467 |
6925 | 1468 octfiledir = getarchdir (desc); |
1469 | |
8506 | 1470 ## Copy the files from "inst" to installdir. |
6496 | 1471 instdir = fullfile (packdir, "inst"); |
1472 if (! dirempty (instdir)) | |
1473 [status, output] = copyfile (fullfile (instdir, "*"), desc.dir); | |
1474 if (status != 1) | |
1475 rm_rf (desc.dir); | |
1476 error ("couldn't copy files to the installation directory"); | |
5801 | 1477 endif |
6925 | 1478 if (exist (fullfile (desc.dir, getarch ()), "dir") && |
10549 | 1479 ! strcmp (fullfile (desc.dir, getarch ()), octfiledir)) |
6925 | 1480 if (! exist (octfiledir, "dir")) |
8506 | 1481 ## Can be required to create upto three levels of dirs. |
6925 | 1482 octm1 = fileparts (octfiledir); |
1483 if (! exist (octm1, "dir")) | |
1484 octm2 = fileparts (octm1); | |
1485 if (! exist (octm2, "dir")) | |
1486 octm3 = fileparts (octm2); | |
1487 if (! exist (octm3, "dir")) | |
1488 [status, output] = mkdir (octm3); | |
1489 if (status != 1) | |
1490 rm_rf (desc.dir); | |
1491 error ("couldn't create installation directory %s : %s", | |
1492 octm3, output); | |
1493 endif | |
1494 endif | |
1495 [status, output] = mkdir (octm2); | |
1496 if (status != 1) | |
1497 rm_rf (desc.dir); | |
1498 error ("couldn't create installation directory %s : %s", | |
1499 octm2, output); | |
1500 endif | |
1501 endif | |
1502 [status, output] = mkdir (octm1); | |
1503 if (status != 1) | |
1504 rm_rf (desc.dir); | |
1505 error ("couldn't create installation directory %s : %s", | |
1506 octm1, output); | |
1507 endif | |
1508 endif | |
1509 [status, output] = mkdir (octfiledir); | |
1510 if (status != 1) | |
1511 rm_rf (desc.dir); | |
1512 error ("couldn't create installation directory %s : %s", | |
1513 octfiledir, output); | |
1514 endif | |
1515 endif | |
1516 [status, output] = movefile (fullfile (desc.dir, getarch (), "*"), | |
10549 | 1517 octfiledir); |
6925 | 1518 rm_rf (fullfile (desc.dir, getarch ())); |
1519 | |
1520 if (status != 1) | |
1521 rm_rf (desc.dir); | |
1522 rm_rf (octfiledir); | |
1523 error ("couldn't copy files to the installation directory"); | |
1524 endif | |
1525 endif | |
1526 | |
6496 | 1527 endif |
5801 | 1528 |
8506 | 1529 ## Create the "packinfo" directory. |
6496 | 1530 packinfo = fullfile (desc.dir, "packinfo"); |
1531 [status, msg] = mkdir (packinfo); | |
1532 if (status != 1) | |
1533 rm_rf (desc.dir); | |
6925 | 1534 rm_rf (octfiledir); |
6496 | 1535 error ("couldn't create packinfo directory: %s", msg); |
1536 endif | |
5801 | 1537 |
8506 | 1538 ## Copy DESCRIPTION. |
6496 | 1539 [status, output] = copyfile (fullfile (packdir, "DESCRIPTION"), packinfo); |
1540 if (status != 1) | |
6925 | 1541 rm_rf (desc.dir); |
1542 rm_rf (octfiledir); | |
1543 error ("couldn't copy DESCRIPTION: %s", output); | |
6496 | 1544 endif |
5801 | 1545 |
8506 | 1546 ## Copy COPYING. |
6496 | 1547 [status, output] = copyfile (fullfile (packdir, "COPYING"), packinfo); |
1548 if (status != 1) | |
6925 | 1549 rm_rf (desc.dir); |
1550 rm_rf (octfiledir); | |
1551 error ("couldn't copy COPYING: %s", output); | |
6496 | 1552 endif |
5993 | 1553 |
8506 | 1554 ## If the file ChangeLog exists, copy it. |
7498 | 1555 changelog_file = fullfile (packdir, "ChangeLog"); |
1556 if (exist (changelog_file, "file")) | |
1557 [status, output] = copyfile (changelog_file, packinfo); | |
6496 | 1558 if (status != 1) |
1559 rm_rf (desc.dir); | |
6925 | 1560 rm_rf (octfiledir); |
6496 | 1561 error ("couldn't copy ChangeLog file: %s", output); |
6254 | 1562 endif |
6496 | 1563 endif |
6254 | 1564 |
6496 | 1565 ## Is there an INDEX file to copy or should we generate one? |
7498 | 1566 index_file = fullfile (packdir, "INDEX"); |
1567 if (exist(index_file, "file")) | |
1568 [status, output] = copyfile (index_file, packinfo); | |
6496 | 1569 if (status != 1) |
1570 rm_rf (desc.dir); | |
6925 | 1571 rm_rf (octfiledir); |
6496 | 1572 error ("couldn't copy INDEX file: %s", output); |
5801 | 1573 endif |
6496 | 1574 else |
1575 try | |
7498 | 1576 write_index (desc, fullfile (packdir, "inst"), |
10549 | 1577 fullfile (packinfo, "INDEX"), global_install); |
6496 | 1578 catch |
1579 rm_rf (desc.dir); | |
6925 | 1580 rm_rf (octfiledir); |
6695 | 1581 rethrow (lasterror ()); |
6496 | 1582 end_try_catch |
1583 endif | |
5971 | 1584 |
6496 | 1585 ## Is there an 'on_uninstall.m' to install? |
7498 | 1586 fon_uninstall = fullfile (packdir, "on_uninstall.m"); |
6496 | 1587 if (exist (fon_uninstall, "file")) |
1588 [status, output] = copyfile (fon_uninstall, packinfo); | |
1589 if (status != 1) | |
1590 rm_rf (desc.dir); | |
6925 | 1591 rm_rf (octfiledir); |
6496 | 1592 error ("couldn't copy on_uninstall.m: %s", output); |
5971 | 1593 endif |
6496 | 1594 endif |
5971 | 1595 |
8506 | 1596 ## Is there a doc/ directory that needs to be installed? |
6496 | 1597 docdir = fullfile (packdir, "doc"); |
1598 if (exist (docdir, "dir") && ! dirempty (docdir)) | |
6925 | 1599 [status, output] = copyfile (docdir, desc.dir); |
6496 | 1600 endif |
1601 | |
8506 | 1602 ## Is there a bin/ directory that needs to be installed? |
6950 | 1603 ## FIXME: Need to treat architecture dependent files in bin/ |
6496 | 1604 bindir = fullfile (packdir, "bin"); |
1605 if (exist (bindir, "dir") && ! dirempty (bindir)) | |
6925 | 1606 [status, output] = copyfile (bindir, desc.dir); |
6496 | 1607 endif |
5801 | 1608 endfunction |
1609 | |
6925 | 1610 function finish_installation (desc, packdir, global_install) |
6496 | 1611 ## Is there a post-install to call? |
1612 if (exist (fullfile (packdir, "post_install.m"), "file")) | |
1613 wd = pwd (); | |
1614 try | |
1615 cd (packdir); | |
1616 post_install (desc); | |
1617 cd (wd); | |
1618 catch | |
1619 cd (wd); | |
1620 rm_rf (desc.dir); | |
6925 | 1621 rm_rf (getarchdir (desc), global_install); |
6695 | 1622 rethrow (lasterror ()); |
6496 | 1623 end_try_catch |
1624 endif | |
5801 | 1625 endfunction |
1626 | |
8575
f134925a1cfa
m-file implementation of help system
Soren Hauberg <soren@hauberg.org>
parents:
8507
diff
changeset
|
1627 function generate_lookfor_cache (desc) |
8863
34a821854961
pkg.m (generate_lookfor_cache): generate a DOC file for each directory
Jason Riedy <jason@acm.org>
parents:
8746
diff
changeset
|
1628 dirs = split_by (genpath (desc.dir), pathsep ()); |
34a821854961
pkg.m (generate_lookfor_cache): generate a DOC file for each directory
Jason Riedy <jason@acm.org>
parents:
8746
diff
changeset
|
1629 for i = 1 : length (dirs) |
8942
c4383701e10d
use doc-cache instead of DOC for doc cache file name
John W. Eaton <jwe@octave.org>
parents:
8920
diff
changeset
|
1630 gen_doc_cache (fullfile (dirs{i}, "doc-cache"), dirs{i}); |
8863
34a821854961
pkg.m (generate_lookfor_cache): generate a DOC file for each directory
Jason Riedy <jason@acm.org>
parents:
8746
diff
changeset
|
1631 endfor |
8575
f134925a1cfa
m-file implementation of help system
Soren Hauberg <soren@hauberg.org>
parents:
8507
diff
changeset
|
1632 endfunction |
f134925a1cfa
m-file implementation of help system
Soren Hauberg <soren@hauberg.org>
parents:
8507
diff
changeset
|
1633 |
7498 | 1634 ## Make sure the package contains the essential files. |
6496 | 1635 function verify_directory (dir) |
1636 needed_files = {"COPYING", "DESCRIPTION"}; | |
1637 for f = needed_files | |
1638 if (! exist (fullfile (dir, f{1}), "file")) | |
1639 error ("package is missing file: %s", f{1}); | |
1640 endif | |
1641 endfor | |
5801 | 1642 endfunction |
1643 | |
8506 | 1644 ## Parse the DESCRIPTION file. |
6496 | 1645 function desc = get_description (filename) |
1646 [fid, msg] = fopen (filename, "r"); | |
1647 if (fid == -1) | |
1648 error ("the DESCRIPTION file %s could not be read: %s", filename, msg); | |
1649 endif | |
1650 | |
1651 desc = struct (); | |
5801 | 1652 |
6496 | 1653 line = fgetl (fid); |
1654 while (line != -1) | |
1655 if (line(1) == "#") | |
8506 | 1656 ## Comments, do nothing. |
6496 | 1657 elseif (isspace(line(1))) |
1658 ## Continuation lines | |
1659 if (exist ("keyword", "var") && isfield (desc, keyword)) | |
10549 | 1660 desc.(keyword) = cstrcat (desc.(keyword), " ", rstrip(line)); |
6496 | 1661 endif |
5801 | 1662 else |
6496 | 1663 ## Keyword/value pair |
1664 colon = find (line == ":"); | |
1665 if (length (colon) == 0) | |
10549 | 1666 disp ("skipping line"); |
6496 | 1667 else |
10549 | 1668 colon = colon(1); |
1669 keyword = tolower (strip (line(1:colon-1))); | |
1670 value = strip (line (colon+1:end)); | |
1671 if (length (value) == 0) | |
1672 fclose (fid); | |
1673 error ("the keyword %s has an empty value", desc.keywords{end}); | |
1674 endif | |
1675 desc.(keyword) = value; | |
6496 | 1676 endif |
5801 | 1677 endif |
6496 | 1678 line = fgetl (fid); |
1679 endwhile | |
1680 fclose (fid); | |
1681 | |
8506 | 1682 ## Make sure all is okay. |
6496 | 1683 needed_fields = {"name", "version", "date", "title", ... |
10549 | 1684 "author", "maintainer", "description"}; |
6496 | 1685 for f = needed_fields |
1686 if (! isfield (desc, f{1})) | |
1687 error ("description is missing needed field %s", f{1}); | |
1688 endif | |
1689 endfor | |
1690 desc.version = fix_version (desc.version); | |
1691 if (isfield (desc, "depends")) | |
1692 desc.depends = fix_depends (desc.depends); | |
1693 else | |
1694 desc.depends = ""; | |
1695 endif | |
1696 desc.name = tolower (desc.name); | |
5801 | 1697 endfunction |
1698 | |
7498 | 1699 ## Make sure the version string v is a valid x.y.z version string |
8506 | 1700 ## Examples: "0.1" => "0.1.0", "monkey" => error(...). |
6496 | 1701 function out = fix_version (v) |
1702 dots = find (v == "."); | |
1703 if (length (dots) == 1) | |
1704 major = str2num (v(1:dots-1)); | |
1705 minor = str2num (v(dots+1:end)); | |
1706 if (length (major) != 0 && length (minor) != 0) | |
1707 out = sprintf ("%d.%d.0", major, minor); | |
1708 return; | |
5801 | 1709 endif |
6496 | 1710 elseif (length (dots) == 2) |
1711 major = str2num (v(1:dots(1)-1)); | |
1712 minor = str2num (v(dots(1)+1:dots(2)-1)); | |
7498 | 1713 rev = str2num (v(dots(2)+1:end)); |
6496 | 1714 if (length (major) != 0 && length (minor) != 0 && length (rev) != 0) |
1715 out = sprintf ("%d.%d.%d", major, minor, rev); | |
1716 return; | |
1717 endif | |
1718 endif | |
1719 error ("bad version string: %s", v); | |
5801 | 1720 endfunction |
1721 | |
7498 | 1722 ## Make sure the depends field is of the right format. |
5801 | 1723 ## This function returns a cell of structures with the following fields: |
1724 ## package, version, operator | |
6496 | 1725 function deps_cell = fix_depends (depends) |
1726 deps = split_by (tolower (depends), ","); | |
1727 deps_cell = cell (1, length (deps)); | |
1728 | |
8506 | 1729 ## For each dependency. |
6496 | 1730 for i = 1:length (deps) |
1731 dep = deps{i}; | |
1732 lpar = find (dep == "("); | |
1733 rpar = find (dep == ")"); | |
1734 ## Does the dependency specify a version | |
8506 | 1735 ## Example: package(>= version). |
6496 | 1736 if (length (lpar) == 1 && length (rpar) == 1) |
1737 package = tolower (strip (dep(1:lpar-1))); | |
1738 sub = dep(lpar(1)+1:rpar(1)-1); | |
8900
63ad1133d0ed
fix & simplify fix_depends pkg.m
Jaroslav Hajek <highegg@gmail.com>
parents:
8877
diff
changeset
|
1739 parts = strsplit (sub, " ", true); |
63ad1133d0ed
fix & simplify fix_depends pkg.m
Jaroslav Hajek <highegg@gmail.com>
parents:
8877
diff
changeset
|
1740 if (length (parts) != 2) |
10549 | 1741 error ("incorrect syntax for dependency `%s' in the DESCRIPTION file\n", |
1742 dep); | |
6496 | 1743 endif |
8900
63ad1133d0ed
fix & simplify fix_depends pkg.m
Jaroslav Hajek <highegg@gmail.com>
parents:
8877
diff
changeset
|
1744 operator = parts{1}; |
6496 | 1745 if (! any (strcmp (operator, {">", ">=", "<=", "<", "=="}))) |
10549 | 1746 error ("unsupported operator: %s", operator); |
6496 | 1747 endif |
8900
63ad1133d0ed
fix & simplify fix_depends pkg.m
Jaroslav Hajek <highegg@gmail.com>
parents:
8877
diff
changeset
|
1748 version = fix_version (parts{2}); |
6496 | 1749 |
1750 ## If no version is specified for the dependency | |
1751 ## we say that the version should be greater than | |
8506 | 1752 ## or equal to "0.0.0". |
6496 | 1753 else |
1754 package = tolower (strip (dep)); | |
1755 operator = ">="; | |
1756 version = "0.0.0"; | |
1757 endif | |
1758 deps_cell{i} = struct ("package", package, "operator", operator, | |
10549 | 1759 "version", version); |
6496 | 1760 endfor |
5801 | 1761 endfunction |
1762 | |
7498 | 1763 ## Strip the text of spaces from the right |
8506 | 1764 ## Example: " hello world " => " hello world" |
1765 ## FIXME -- is this the same as deblank? | |
6496 | 1766 function text = rstrip (text) |
1767 chars = find (! isspace (text)); | |
1768 if (length (chars) > 0) | |
8202
cf59d542f33e
replace all TODOs and XXXs with FIXMEs
Jaroslav Hajek <highegg@gmail.com>
parents:
8174
diff
changeset
|
1769 ## FIXME: shouldn't it be text = text(1:chars(end)); |
6496 | 1770 text = text (chars(1):end); |
1771 else | |
1772 text = ""; | |
1773 endif | |
5801 | 1774 endfunction |
1775 | |
8506 | 1776 ## Strip the text of spaces from the left and the right. |
5801 | 1777 ## Example: " hello world " => "hello world" |
6496 | 1778 function text = strip (text) |
1779 chars = find (! isspace (text)); | |
1780 if (length (chars) > 0) | |
1781 text = text(chars(1):chars(end)); | |
1782 else | |
1783 text = ""; | |
1784 endif | |
5801 | 1785 endfunction |
1786 | |
8506 | 1787 ## Split the text into a cell array of strings by sep. |
5801 | 1788 ## Example: "A, B" => {"A", "B"} (with sep = ",") |
6496 | 1789 function out = split_by (text, sep) |
8877
2c8b2399247b
implement strsplit; deprecate split
Jaroslav Hajek <highegg@gmail.com>
parents:
8863
diff
changeset
|
1790 out = strtrim (strsplit (text, sep)); |
5801 | 1791 endfunction |
1792 | |
7498 | 1793 ## Create an INDEX file for a package that doesn't provide one. |
5801 | 1794 ## 'desc' describes the package. |
7498 | 1795 ## 'dir' is the 'inst' directory in temporary directory. |
1796 ## 'index_file' is the name (including path) of resulting INDEX file. | |
1797 function write_index (desc, dir, index_file, global_install) | |
6496 | 1798 ## Get names of functions in dir |
1799 [files, err, msg] = readdir (dir); | |
1800 if (err) | |
1801 error ("couldn't read directory %s: %s", dir, msg); | |
1802 endif | |
1803 | |
10401
6d1e49abf95f
pkg/pkg.m (write_index): include classes in autogenerated INDEX files
Soren Hauberg <hauberg@gmail.com>
parents:
10199
diff
changeset
|
1804 ## Get classes in dir |
6d1e49abf95f
pkg/pkg.m (write_index): include classes in autogenerated INDEX files
Soren Hauberg <hauberg@gmail.com>
parents:
10199
diff
changeset
|
1805 class_idx = strmatch ("@", files); |
6d1e49abf95f
pkg/pkg.m (write_index): include classes in autogenerated INDEX files
Soren Hauberg <hauberg@gmail.com>
parents:
10199
diff
changeset
|
1806 for k = 1:length (class_idx) |
6d1e49abf95f
pkg/pkg.m (write_index): include classes in autogenerated INDEX files
Soren Hauberg <hauberg@gmail.com>
parents:
10199
diff
changeset
|
1807 class_name = files {class_idx (k)}; |
6d1e49abf95f
pkg/pkg.m (write_index): include classes in autogenerated INDEX files
Soren Hauberg <hauberg@gmail.com>
parents:
10199
diff
changeset
|
1808 class_dir = fullfile (dir, class_name); |
6d1e49abf95f
pkg/pkg.m (write_index): include classes in autogenerated INDEX files
Soren Hauberg <hauberg@gmail.com>
parents:
10199
diff
changeset
|
1809 if (exist (class_dir, "dir")) |
6d1e49abf95f
pkg/pkg.m (write_index): include classes in autogenerated INDEX files
Soren Hauberg <hauberg@gmail.com>
parents:
10199
diff
changeset
|
1810 [files2, err, msg] = readdir (class_dir); |
6d1e49abf95f
pkg/pkg.m (write_index): include classes in autogenerated INDEX files
Soren Hauberg <hauberg@gmail.com>
parents:
10199
diff
changeset
|
1811 if (err) |
6d1e49abf95f
pkg/pkg.m (write_index): include classes in autogenerated INDEX files
Soren Hauberg <hauberg@gmail.com>
parents:
10199
diff
changeset
|
1812 error ("couldn't read directory %s: %s", class_dir, msg); |
6d1e49abf95f
pkg/pkg.m (write_index): include classes in autogenerated INDEX files
Soren Hauberg <hauberg@gmail.com>
parents:
10199
diff
changeset
|
1813 endif |
6d1e49abf95f
pkg/pkg.m (write_index): include classes in autogenerated INDEX files
Soren Hauberg <hauberg@gmail.com>
parents:
10199
diff
changeset
|
1814 files2 = strcat (class_name, filesep (), files2); |
6d1e49abf95f
pkg/pkg.m (write_index): include classes in autogenerated INDEX files
Soren Hauberg <hauberg@gmail.com>
parents:
10199
diff
changeset
|
1815 files = [files; files2]; |
6d1e49abf95f
pkg/pkg.m (write_index): include classes in autogenerated INDEX files
Soren Hauberg <hauberg@gmail.com>
parents:
10199
diff
changeset
|
1816 endif |
6d1e49abf95f
pkg/pkg.m (write_index): include classes in autogenerated INDEX files
Soren Hauberg <hauberg@gmail.com>
parents:
10199
diff
changeset
|
1817 endfor |
6d1e49abf95f
pkg/pkg.m (write_index): include classes in autogenerated INDEX files
Soren Hauberg <hauberg@gmail.com>
parents:
10199
diff
changeset
|
1818 |
8506 | 1819 ## Check for architecture dependent files. |
6925 | 1820 tmpdir = getarchdir (desc); |
6634 | 1821 if (exist (tmpdir, "dir")) |
1822 [files2, err, msg] = readdir (tmpdir); | |
1823 if (err) | |
1824 error ("couldn't read directory %s: %s", tmpdir, msg); | |
1825 endif | |
1826 files = [files; files2]; | |
1827 endif | |
1828 | |
6496 | 1829 functions = {}; |
1830 for i = 1:length (files) | |
1831 file = files{i}; | |
1832 lf = length (file); | |
1833 if (lf > 2 && strcmp (file(end-1:end), ".m")) | |
1834 functions{end+1} = file(1:end-2); | |
1835 elseif (lf > 4 && strcmp (file(end-3:end), ".oct")) | |
1836 functions{end+1} = file(1:end-4); | |
5801 | 1837 endif |
6496 | 1838 endfor |
1839 | |
1840 ## Does desc have a categories field? | |
1841 if (! isfield (desc, "categories")) | |
1842 error ("the DESCRIPTION file must have a Categories field, when no INDEX file is given"); | |
1843 endif | |
1844 categories = split_by (desc.categories, ","); | |
1845 if (length (categories) < 1) | |
1846 error ("the Category field is empty"); | |
1847 endif | |
1848 | |
8506 | 1849 ## Write INDEX. |
7498 | 1850 fid = fopen (index_file, "w"); |
6496 | 1851 if (fid == -1) |
7498 | 1852 error ("couldn't open %s for writing.", index_file); |
6496 | 1853 endif |
1854 fprintf (fid, "%s >> %s\n", desc.name, desc.title); | |
1855 fprintf (fid, "%s\n", categories{1}); | |
1856 fprintf (fid, " %s\n", functions{:}); | |
1857 fclose (fid); | |
5801 | 1858 endfunction |
1859 | |
6820 | 1860 function bad_deps = get_unsatisfied_deps (desc, installed_pkgs_lst) |
6496 | 1861 bad_deps = {}; |
5801 | 1862 |
8506 | 1863 ## For each dependency. |
6496 | 1864 for i = 1:length (desc.depends) |
1865 dep = desc.depends{i}; | |
5801 | 1866 |
6496 | 1867 ## Is the current dependency Octave? |
1868 if (strcmp (dep.package, "octave")) | |
1869 if (! compare_versions (OCTAVE_VERSION, dep.version, dep.operator)) | |
1870 bad_deps{end+1} = dep; | |
6258 | 1871 endif |
8506 | 1872 ## Is the current dependency not Octave? |
6496 | 1873 else |
1874 ok = false; | |
6820 | 1875 for i = 1:length (installed_pkgs_lst) |
10549 | 1876 cur_name = installed_pkgs_lst{i}.name; |
1877 cur_version = installed_pkgs_lst{i}.version; | |
1878 if (strcmp (dep.package, cur_name) | |
1879 && compare_versions (cur_version, dep.version, dep.operator)) | |
1880 ok = true; | |
1881 break; | |
1882 endif | |
6258 | 1883 endfor |
6496 | 1884 if (! ok) |
1885 bad_deps{end+1} = dep; | |
1886 endif | |
5801 | 1887 endif |
6496 | 1888 endfor |
1889 endfunction | |
1890 | |
1891 function [out1, out2] = installed_packages (local_list, global_list) | |
8506 | 1892 ## Get the list of installed packages. |
6496 | 1893 try |
1894 local_packages = load (local_list).local_packages; | |
1895 catch | |
1896 local_packages = {}; | |
1897 end_try_catch | |
1898 try | |
6675 | 1899 global_packages = load (global_list).global_packages; |
6496 | 1900 catch |
1901 global_packages = {}; | |
1902 end_try_catch | |
6820 | 1903 installed_pkgs_lst = {local_packages{:}, global_packages{:}}; |
6496 | 1904 |
1905 ## Eliminate duplicates in the installed package list. | |
8506 | 1906 ## Locally installed packages take precedence. |
6496 | 1907 dup = []; |
6820 | 1908 for i = 1:length (installed_pkgs_lst) |
6496 | 1909 if (find (dup, i)) |
1910 continue; | |
5801 | 1911 endif |
6820 | 1912 for j = (i+1):length (installed_pkgs_lst) |
6496 | 1913 if (find (dup, j)) |
10549 | 1914 continue; |
6496 | 1915 endif |
6820 | 1916 if (strcmp (installed_pkgs_lst{i}.name, installed_pkgs_lst{j}.name)) |
10549 | 1917 dup = [dup, j]; |
6496 | 1918 endif |
5987 | 1919 endfor |
6496 | 1920 endfor |
1921 if (! isempty(dup)) | |
6820 | 1922 installed_pkgs_lst(dup) = []; |
6496 | 1923 endif |
1924 | |
8506 | 1925 ## Now check if the package is loaded. |
6645 | 1926 tmppath = strrep (path(), "\\", "/"); |
6820 | 1927 for i = 1:length (installed_pkgs_lst) |
1928 if (findstr (tmppath, strrep (installed_pkgs_lst{i}.dir, "\\", "/"))) | |
1929 installed_pkgs_lst{i}.loaded = true; | |
6616 | 1930 else |
6820 | 1931 installed_pkgs_lst{i}.loaded = false; |
6616 | 1932 endif |
1933 endfor | |
6675 | 1934 for i = 1:length (local_packages) |
6776 | 1935 if (findstr (tmppath, strrep (local_packages{i}.dir, "\\", "/"))) |
6675 | 1936 local_packages{i}.loaded = true; |
1937 else | |
1938 local_packages{i}.loaded = false; | |
1939 endif | |
1940 endfor | |
1941 for i = 1:length (global_packages) | |
6776 | 1942 if (findstr (tmppath, strrep (global_packages{i}.dir, "\\", "/"))) |
6675 | 1943 global_packages{i}.loaded = true; |
1944 else | |
1945 global_packages{i}.loaded = false; | |
1946 endif | |
1947 endfor | |
6616 | 1948 |
6496 | 1949 ## Should we return something? |
1950 if (nargout == 2) | |
1951 out1 = local_packages; | |
1952 out2 = global_packages; | |
1953 return; | |
1954 elseif (nargout == 1) | |
6820 | 1955 out1 = installed_pkgs_lst; |
6496 | 1956 return; |
1957 endif | |
1958 | |
8506 | 1959 ## We shouldn't return something, so we'll print something. |
6820 | 1960 num_packages = length (installed_pkgs_lst); |
6496 | 1961 if (num_packages == 0) |
1962 printf ("no packages installed.\n"); | |
1963 return; | |
1964 endif | |
1965 | |
8506 | 1966 ## Compute the maximal lengths of name, version, and dir. |
6496 | 1967 h1 = "Package Name"; |
1968 h2 = "Version"; | |
1969 h3 = "Installation directory"; | |
1970 max_name_length = length (h1); | |
1971 max_version_length = length (h2); | |
1972 names = cell (num_packages, 1); | |
1973 for i = 1:num_packages | |
1974 max_name_length = max (max_name_length, | |
10549 | 1975 length (installed_pkgs_lst{i}.name)); |
6496 | 1976 max_version_length = max (max_version_length, |
10549 | 1977 length (installed_pkgs_lst{i}.version)); |
6820 | 1978 names{i} = installed_pkgs_lst{i}.name; |
6496 | 1979 endfor |
6698 | 1980 max_dir_length = terminal_size()(2) - max_name_length - ... |
10549 | 1981 max_version_length - 7; |
6698 | 1982 if (max_dir_length < 20) |
1983 max_dir_length = Inf; | |
1984 endif | |
1985 | |
6616 | 1986 h1 = postpad (h1, max_name_length + 1, " "); |
6496 | 1987 h2 = postpad (h2, max_version_length, " ");; |
1988 | |
8506 | 1989 ## Print a header. |
6496 | 1990 header = sprintf("%s | %s | %s\n", h1, h2, h3); |
1991 printf (header); | |
1992 tmp = sprintf (repmat ("-", 1, length(header)-1)); | |
1993 tmp(length(h1)+2) = "+"; | |
1994 tmp(length(h1)+length(h2)+5) = "+"; | |
1995 printf ("%s\n", tmp); | |
1996 | |
8506 | 1997 ## Print the packages. |
6616 | 1998 format = sprintf ("%%%ds %%1s| %%%ds | %%s\n", max_name_length, |
10549 | 1999 max_version_length); |
6496 | 2000 [dummy, idx] = sort (names); |
2001 for i = 1:num_packages | |
6820 | 2002 cur_name = installed_pkgs_lst{idx(i)}.name; |
2003 cur_version = installed_pkgs_lst{idx(i)}.version; | |
2004 cur_dir = installed_pkgs_lst{idx(i)}.dir; | |
6698 | 2005 if (length (cur_dir) > max_dir_length) |
2006 first_char = length (cur_dir) - max_dir_length + 4; | |
2007 first_filesep = strfind (cur_dir(first_char:end), filesep()); | |
2008 if (! isempty (first_filesep)) | |
7540
3422f39573b1
strcat.m: Matlab compatibility, with cstrcat.m replacing conventional strcat.m.
Ben Abbott <bpabbott@mac.com>
parents:
7498
diff
changeset
|
2009 cur_dir = cstrcat ("...", |
10549 | 2010 cur_dir((first_char + first_filesep(1) - 1):end)); |
6698 | 2011 else |
7540
3422f39573b1
strcat.m: Matlab compatibility, with cstrcat.m replacing conventional strcat.m.
Ben Abbott <bpabbott@mac.com>
parents:
7498
diff
changeset
|
2012 cur_dir = cstrcat ("...", cur_dir(first_char:end)); |
6698 | 2013 endif |
2014 endif | |
6820 | 2015 if (installed_pkgs_lst{idx(i)}.loaded) |
6616 | 2016 cur_loaded = "*"; |
2017 else | |
2018 cur_loaded = " "; | |
2019 endif | |
2020 printf (format, cur_name, cur_loaded, cur_version, cur_dir); | |
6496 | 2021 endfor |
5801 | 2022 endfunction |
2023 | |
6496 | 2024 function load_packages (files, handle_deps, local_list, global_list) |
6820 | 2025 installed_pkgs_lst = installed_packages (local_list, global_list); |
2026 num_packages = length (installed_pkgs_lst); | |
6496 | 2027 |
8506 | 2028 ## Read package names and installdirs into a more convenient format. |
6496 | 2029 pnames = pdirs = cell (1, num_packages); |
2030 for i = 1:num_packages | |
6820 | 2031 pnames{i} = installed_pkgs_lst{i}.name; |
2032 pdirs{i} = installed_pkgs_lst{i}.dir; | |
6496 | 2033 endfor |
2034 | |
8506 | 2035 ## Load all. |
6496 | 2036 if (length (files) == 1 && strcmp (files{1}, "all")) |
6820 | 2037 idx = [1:length(installed_pkgs_lst)]; |
8506 | 2038 ## Load auto. |
6695 | 2039 elseif (length (files) == 1 && strcmp (files{1}, "auto")) |
2040 idx = []; | |
6820 | 2041 for i = 1:length (installed_pkgs_lst) |
6496 | 2042 if (exist (fullfile (pdirs{i}, "packinfo", ".autoload"), "file")) |
10549 | 2043 idx (end + 1) = i; |
6496 | 2044 endif |
6037 | 2045 endfor |
8506 | 2046 ## Load package_name1 ... |
6496 | 2047 else |
6695 | 2048 idx = []; |
6496 | 2049 for i = 1:length (files) |
6695 | 2050 idx2 = find (strcmp (pnames, files{i})); |
2051 if (! any (idx2)) | |
10549 | 2052 error ("package %s is not installed", files{i}); |
6496 | 2053 endif |
6695 | 2054 idx (end + 1) = idx2; |
6496 | 2055 endfor |
2056 endif | |
6037 | 2057 |
8506 | 2058 ## Load the packages, but take care of the ordering of dependencies. |
6925 | 2059 load_packages_and_dependencies (idx, handle_deps, installed_pkgs_lst, true); |
5801 | 2060 endfunction |
5928 | 2061 |
6496 | 2062 function unload_packages (files, handle_deps, local_list, global_list) |
6820 | 2063 installed_pkgs_lst = installed_packages (local_list, global_list); |
2064 num_packages = length (installed_pkgs_lst); | |
6496 | 2065 |
8506 | 2066 ## Read package names and installdirs into a more convenient format. |
6496 | 2067 pnames = pdirs = cell (1, num_packages); |
2068 for i = 1:num_packages | |
6820 | 2069 pnames{i} = installed_pkgs_lst{i}.name; |
2070 pdirs{i} = installed_pkgs_lst{i}.dir; | |
2071 pdeps{i} = installed_pkgs_lst{i}.depends; | |
6496 | 2072 endfor |
2073 | |
8506 | 2074 ## Get the current octave path. |
6496 | 2075 p = split_by (path(), pathsep ()); |
6203 | 2076 |
6496 | 2077 if (length (files) == 1 && strcmp (files{1}, "all")) |
8506 | 2078 ## Unload all. |
2079 dirs = pdirs; | |
2080 desc = installed_pkgs_lst; | |
6496 | 2081 else |
8506 | 2082 ## Unload package_name1 ... |
6496 | 2083 dirs = {}; |
6925 | 2084 desc = {}; |
6496 | 2085 for i = 1:length (files) |
7208 | 2086 idx = strcmp (pnames, files{i}); |
6496 | 2087 if (! any (idx)) |
10549 | 2088 error ("package %s is not installed", files{i}); |
6496 | 2089 endif |
10549 | 2090 dirs{end+1} = pdirs{idx}; |
7208 | 2091 desc{end+1} = installed_pkgs_lst{idx}; |
6496 | 2092 endfor |
2093 endif | |
2094 | |
8506 | 2095 ## Check for architecture dependent directories. |
6614 | 2096 archdirs = {}; |
2097 for i = 1:length (dirs) | |
7208 | 2098 tmpdir = getarchdir (desc{i}); |
6614 | 2099 if (exist (tmpdir, "dir")) |
7208 | 2100 archdirs{end+1} = dirs{i}; |
2101 archdirs{end+1} = tmpdir; | |
6925 | 2102 else |
7208 | 2103 archdirs{end+1} = dirs{i}; |
6614 | 2104 endif |
2105 endfor | |
2106 | |
8506 | 2107 ## Unload the packages. |
6925 | 2108 for i = 1:length (archdirs) |
2109 d = archdirs{i}; | |
6496 | 2110 idx = strcmp (p, d); |
2111 if (any (idx)) | |
2112 rmpath (d); | |
8506 | 2113 ## FIXME: We should also check if we need to remove items from |
2114 ## EXEC_PATH. | |
6203 | 2115 endif |
6496 | 2116 endfor |
6203 | 2117 endfunction |
2118 | |
5928 | 2119 function [status_out, msg_out] = rm_rf (dir) |
6925 | 2120 if (exist (dir)) |
2121 crr = confirm_recursive_rmdir (); | |
2122 unwind_protect | |
2123 confirm_recursive_rmdir (false); | |
2124 [status, msg] = rmdir (dir, "s"); | |
2125 unwind_protect_cleanup | |
2126 confirm_recursive_rmdir (crr); | |
2127 end_unwind_protect | |
2128 else | |
2129 status = 1; | |
2130 msg = ""; | |
2131 endif | |
5928 | 2132 if (nargout > 0) |
2133 status_out = status; | |
2134 endif | |
2135 if (nargout > 1) | |
2136 msg_out = msg; | |
2137 endif | |
2138 endfunction | |
5971 | 2139 |
2140 function emp = dirempty (nm, ign) | |
6925 | 2141 if (exist (nm, "dir")) |
2142 if (nargin < 2) | |
2143 ign = {".", ".."}; | |
2144 else | |
2145 ign = [{".", ".."}, ign]; | |
2146 endif | |
2147 l = dir (nm); | |
2148 for i = 1:length (l) | |
2149 found = false; | |
2150 for j = 1:length (ign) | |
2151 if (strcmp (l(i).name, ign{j})) | |
2152 found = true; | |
2153 break; | |
2154 endif | |
2155 endfor | |
2156 if (! found) | |
2157 emp = false; | |
2158 return | |
5971 | 2159 endif |
2160 endfor | |
6925 | 2161 emp = true; |
2162 else | |
2163 emp = true; | |
2164 endif | |
5971 | 2165 endfunction |
6614 | 2166 |
2167 function arch = getarch () | |
7540
3422f39573b1
strcat.m: Matlab compatibility, with cstrcat.m replacing conventional strcat.m.
Ben Abbott <bpabbott@mac.com>
parents:
7498
diff
changeset
|
2168 persistent _arch = cstrcat (octave_config_info("canonical_host_type"), ... |
10549 | 2169 "-", octave_config_info("api_version")); |
6614 | 2170 arch = _arch; |
2171 endfunction | |
6645 | 2172 |
6925 | 2173 function archprefix = getarchprefix (desc, global_install) |
2174 if ((nargin == 2 && global_install) || (nargin < 2 && issuperuser ())) | |
2175 archprefix = fullfile (octave_config_info ("libexecdir"), "octave", | |
10549 | 2176 "packages", cstrcat(desc.name, "-", desc.version)); |
6925 | 2177 else |
2178 archprefix = desc.dir; | |
2179 endif | |
2180 endfunction | |
2181 | |
2182 function archdir = getarchdir (desc) | |
2183 archdir = fullfile (desc.archprefix, getarch()); | |
2184 endfunction | |
2185 | |
2186 function s = issuperuser () | |
2187 if ((ispc () && ! isunix ()) || (geteuid() == 0)) | |
2188 s = true; | |
2189 else | |
2190 s = false; | |
2191 endif | |
2192 endfunction | |
2193 | |
6645 | 2194 function [status, output] = shell (cmd) |
2195 persistent have_sh; | |
2196 | |
2197 cmd = strrep (cmd, "\\", "/"); | |
2198 if (ispc () && ! isunix ()) | |
2199 if (isempty(have_sh)) | |
2200 if (system("sh.exe -c \"exit\"")) | |
2201 have_sh = false; | |
2202 else | |
2203 have_sh = true; | |
2204 endif | |
2205 endif | |
2206 if (have_sh) | |
7540
3422f39573b1
strcat.m: Matlab compatibility, with cstrcat.m replacing conventional strcat.m.
Ben Abbott <bpabbott@mac.com>
parents:
7498
diff
changeset
|
2207 [status, output] = system (cstrcat ("sh.exe -c \"", cmd, "\"")); |
6645 | 2208 else |
2209 error ("Can not find the command shell") | |
2210 endif | |
2211 else | |
2212 [status, output] = system (cmd); | |
2213 endif | |
2214 endfunction | |
6695 | 2215 |
2216 function newdesc = save_order (desc) | |
2217 newdesc = {}; | |
2218 for i = 1 : length(desc) | |
2219 deps = desc{i}.depends; | |
2220 if (isempty (deps) || (length (deps) == 1 && | |
10549 | 2221 strcmp(deps{1}.package, "octave"))) |
6695 | 2222 newdesc {end + 1} = desc{i}; |
2223 else | |
2224 tmpdesc = {}; | |
2225 for k = 1 : length (deps) | |
2226 for j = 1 : length (desc) | |
2227 if (strcmp (desc{j}.name, deps{k}.package)) | |
7208 | 2228 tmpdesc{end+1} = desc{j}; |
10549 | 2229 break; |
6695 | 2230 endif |
2231 endfor | |
2232 endfor | |
10549 | 2233 if (! isempty (tmpdesc)) |
6695 | 2234 newdesc = {newdesc{:}, save_order(tmpdesc){:}, desc{i}}; |
2235 else | |
7208 | 2236 newdesc{end+1} = desc{i}; |
6695 | 2237 endif |
2238 endif | |
2239 endfor | |
8506 | 2240 ## Eliminate the duplicates. |
6695 | 2241 idx = []; |
2242 for i = 1 : length (newdesc) | |
2243 for j = (i + 1) : length (newdesc) | |
2244 if (strcmp (newdesc{i}.name, newdesc{j}.name)) | |
2245 idx (end + 1) = j; | |
2246 endif | |
2247 endfor | |
2248 endfor | |
2249 newdesc(idx) = []; | |
2250 endfunction | |
2251 | |
6925 | 2252 function load_packages_and_dependencies (idx, handle_deps, installed_pkgs_lst, |
10549 | 2253 global_install) |
6820 | 2254 idx = load_package_dirs (idx, [], handle_deps, installed_pkgs_lst); |
6695 | 2255 dirs = {}; |
2256 execpath = EXEC_PATH (); | |
2257 for i = idx; | |
6820 | 2258 ndir = installed_pkgs_lst{i}.dir; |
7208 | 2259 dirs{end+1} = ndir; |
6695 | 2260 if (exist (fullfile (dirs{end}, "bin"), "dir")) |
7540
3422f39573b1
strcat.m: Matlab compatibility, with cstrcat.m replacing conventional strcat.m.
Ben Abbott <bpabbott@mac.com>
parents:
7498
diff
changeset
|
2261 execpath = cstrcat (fullfile (dirs{end}, "bin"), ":", execpath); |
6695 | 2262 endif |
7208 | 2263 tmpdir = getarchdir (installed_pkgs_lst{i}); |
6695 | 2264 if (exist (tmpdir, "dir")) |
2265 dirs{end + 1} = tmpdir; | |
6950 | 2266 if (exist (fullfile (dirs{end}, "bin"), "dir")) |
7540
3422f39573b1
strcat.m: Matlab compatibility, with cstrcat.m replacing conventional strcat.m.
Ben Abbott <bpabbott@mac.com>
parents:
7498
diff
changeset
|
2267 execpath = cstrcat (fullfile (dirs{end}, "bin"), ":", execpath); |
6950 | 2268 endif |
6695 | 2269 endif |
2270 endfor | |
2271 | |
8506 | 2272 ## Load the packages. |
6695 | 2273 if (length (dirs) > 0) |
2274 addpath (dirs{:}); | |
2275 endif | |
2276 | |
8506 | 2277 ## Add the binaries to exec_path. |
6695 | 2278 if (! strcmp (EXEC_PATH, execpath)) |
2279 EXEC_PATH (execpath); | |
2280 endif | |
2281 endfunction | |
2282 | |
6820 | 2283 function idx = load_package_dirs (lidx, idx, handle_deps, installed_pkgs_lst) |
6695 | 2284 for i = lidx |
6820 | 2285 if (isfield (installed_pkgs_lst{i}, "loaded") && |
10549 | 2286 installed_pkgs_lst{i}.loaded) |
6695 | 2287 continue; |
2288 else | |
2289 if (handle_deps) | |
6820 | 2290 deps = installed_pkgs_lst{i}.depends; |
6695 | 2291 if ((length (deps) > 1) || (length (deps) == 1 && |
10549 | 2292 ! strcmp(deps{1}.package, "octave"))) |
6695 | 2293 tmplidx = []; |
2294 for k = 1 : length (deps) | |
6820 | 2295 for j = 1 : length (installed_pkgs_lst) |
2296 if (strcmp (installed_pkgs_lst{j}.name, deps{k}.package)) | |
6695 | 2297 tmplidx (end + 1) = j; |
10549 | 2298 break; |
6695 | 2299 endif |
2300 endfor | |
2301 endfor | |
2302 idx = load_package_dirs (tmplidx, idx, handle_deps, | |
10549 | 2303 installed_pkgs_lst); |
6695 | 2304 endif |
2305 endif | |
2306 if (isempty (find(idx == i))) | |
2307 idx (end + 1) = i; | |
2308 endif | |
2309 endif | |
2310 endfor | |
2311 endfunction | |
6950 | 2312 |
2313 function dep = is_architecture_dependent (nm) | |
7329 | 2314 persistent archdepsuffix = {".oct",".mex",".a",".lib",".so",".so.*",".dll","dylib"}; |
6950 | 2315 |
2316 dep = false; | |
2317 for i = 1 : length (archdepsuffix) | |
7208 | 2318 ext = archdepsuffix{i}; |
6950 | 2319 if (ext(end) == "*") |
2320 isglob = true; | |
2321 ext(end) = []; | |
2322 else | |
2323 isglob = false; | |
2324 endif | |
2325 pos = findstr (nm, ext); | |
2326 if (pos) | |
7208 | 2327 if (! isglob && (length(nm) - pos(end) != length(ext) - 1)) |
10549 | 2328 continue; |
6950 | 2329 endif |
2330 dep = true; | |
2331 break; | |
2332 endif | |
2333 endfor | |
2334 endfunction | |
10684
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
2335 |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
2336 function [url, local_file] = get_forge_download (name) |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
2337 [ver, url] = get_forge_pkg (name); |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
2338 local_file = [name, "-", ver, ".tar.gz"]; |
76aba4305f1f
support pkg install -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10549
diff
changeset
|
2339 endfunction |
10685
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
2340 |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
2341 function list = list_forge_packages () |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
2342 [list, succ] = urlread ("http://octave.sourceforge.net/list_packages.php"); |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
2343 if (succ) |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
2344 list = strsplit (list, " \n\t", true); |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
2345 else |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
2346 error ("pkg: could not read URL, please verify internet connection"); |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
2347 endif |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
2348 if (nargout == 0) |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
2349 page_screen_output (false, "local"); |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
2350 puts ("OctaveForge provides these packages:\n"); |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
2351 for i = 1:length (list) |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
2352 try |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
2353 ver = get_forge_pkg (list{i}); |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
2354 catch |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
2355 ver = "unknown"; |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
2356 end_try_catch |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
2357 printf (" %s %s\n", list{i}, ver); |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
2358 endfor |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
2359 endif |
81a43049dee2
support pkg list -forge
Jaroslav Hajek <highegg@gmail.com>
parents:
10684
diff
changeset
|
2360 endfunction |