License Header change: Removed the LICENSE_END before beta
[scilab.git] / scilab / modules / atoms / macros / atoms_internals / atomsInstallList.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) 2009 - DIGITEO - Pierre MARECHAL <pierre.marechal@scilab.org>
3 //
4 // Copyright (C) 2012 - 2016 - Scilab Enterprises
5 //
6 // This file is hereby licensed under the terms of the GNU GPL v2.0,
7 // pursuant to article 5.3.4 of the CeCILL v.2.1.
8 // This file was originally licensed under the terms of the CeCILL v2.1,
9 // and continues to be available under such terms.
10 // For more information, see the COPYING file which you should have received
11 // along with this program.
12
13 // Internal function
14
15 // Output arguments :
16
17 //   insList  : . List  of the changes caused by the installation of one or
18 //                more packages
19 //              . matrix ( n x 4 )
20 //              . mandatory
21 //              . example :
22 //                 !~  U  toolbox_4  1.0  !
23 //                 !                      !
24 //                 !~     toolbox_2  1.3  !
25 //                 !                      !
26 //                 !~     toolbox_1  1.9  !
27 //                 !                      !
28 //                 !~  U  toolbox_5  1.0  !
29
30 //   tree_out : . Dependency tree of the package (returned by atomsDepTreeFlat)
31 //              . struct
32 //              . mandatory
33 //              . Example :
34 //                   tree_out  =
35 //                   toolbox_5 - 1.0: [1x1 struct]
36 //                   toolbox_4 - 1.0: [1x1 struct]
37 //                   toolbox_2 - 1.3: [1x1 struct]
38 //                   toolbox_1 - 1.9: [1x1 struct]
39
40 function [insList,depTree] = atomsInstallList(packages,section)
41
42     insList = [];
43     depTree = struct();
44
45     // Get scilab version (needed for later)
46     // =========================================================================
47     sciversion = strcat(string(getversion("scilab")) + ".");
48
49     // Check input parameters
50     // =========================================================================
51
52     rhs = argn(2);
53
54     if rhs > 2 then
55         error(msprintf(gettext("%s: Wrong number of input arguments: at most %d expected.\n"),"atomsInstallList",2))
56     end
57
58     // 1st input argument
59
60     if type(packages) <> 10 then
61         error(msprintf(gettext("%s: Wrong type for input argument #%d: String array expected.\n"),"atomsInstallList",1));
62     end
63
64     if size(packages(1,:),"*") > 2 then
65         error(msprintf(gettext("%s: Wrong size for input argument #%d: mx1 or mx2 string matrix expected.\n"),"atomsInstall",1));
66     end
67
68     packages = stripblanks(packages);
69
70     // 2nd input input argument, section management :
71     //   - 1st case: section is not specified or is equal to "all", module
72     //               is searched in both "user" and "allusers" section
73     //   - 2nd case: section is equal to "user", module is only searched in
74     //               the "user" section"
75     //   - 3rd case: section is equal to "allusers", module is only searched
76     //               in the "allusers" section"
77
78     if rhs < 2 then
79         section = "all";
80
81     else
82
83         if type(section) <> 10 then
84             error(msprintf(gettext("%s: Wrong type for input argument #%d: string expected.\n"),"atomsInstallList",2));
85         end
86
87         if and(section<>["user","allusers","all"]) then
88             error(msprintf(gettext("%s: Wrong value for input argument #%d: ''user'' or ''allusers'' expected.\n"),"atomsInstallList",2));
89         end
90
91     end
92
93     // If mx1 matrix, add a 2nd column with empty versions
94     // =========================================================================
95     if size(packages(1,:),"*") == 1 then
96         packages = [ packages emptystr(size(packages(:,1),"*"),1) ];
97     end
98
99     // Loop on packages and to build the dependency tree
100     // =========================================================================
101
102     for i=1:size(packages(:,1),"*")
103
104         this_package_name    = packages(i,1);
105         this_package_version = packages(i,2);
106
107         // Now check if it's a valid package
108         if ~ atomsIsPackage(packages(i,:)) then
109             if isempty(this_package_version) then
110                 module_full_name = this_package_name;
111             else
112                 module_full_name = this_package_name+" - "+this_package_version;
113             end
114             atomsError("error", ..
115             msprintf(gettext("%s: The package %s is not available.\n"),"atomsInstallList",module_full_name));
116         end
117
118         // Fill the version if it doesn't contain the packaging version
119         this_package_version = atomsPackagingVersion(packages(i,:));
120         packages(i,2)        = this_package_version;
121
122         // Build the depencency tree
123         [tree,version_out]  = atomsDepTreeFlat(this_package_name,this_package_version);
124
125         if (type(tree) == 4) & (~ tree) then
126             atomsError("error", ..
127             msprintf(gettext("%s: The dependency tree cannot be resolved.\n"),"atomsInstallList",1));
128         end
129
130         // Update the  package_versions(i) with the version returned by
131         // atomsDepTreeFlat
132         packages(i,2) = version_out;
133
134         // Concatenate the tree with the existing one
135         depTree = atomsCatTree( depTree , tree );
136     end
137
138     // Add a field to detect later if it's the toolbox is automatically installed
139     // or if it's a user choice
140     // =========================================================================
141
142     for i=1:size(packages(:,1),"*")
143         this_package_details                     = depTree(packages(i,1)+" - "+packages(i,2));
144         this_package_details("user_choice")      = %T;
145         depTree(packages(i,1)+" - "+packages(i,2)) = this_package_details;
146     end
147
148     // Now we have the list of package that have to be installed
149     // We have to check if
150     //  - each package is already installed
151     //  - If yes, Is it the most recent version
152     // =========================================================================
153
154     mandatory_packages      = getfield(1,depTree);
155     mandatory_packages(1:2) = [];
156
157     for i=1:size(mandatory_packages,"*")
158
159         this_package_details = depTree(mandatory_packages(i));
160
161         this_package_name    = this_package_details("Toolbox");
162         this_package_version = this_package_details("Version");
163
164         if isfield(this_package_details,"user_choice") & this_package_details("user_choice") then
165             this_package_user_choice = "U"; // stand for User Choice
166         else
167             this_package_user_choice = ""; // stand for User Choice
168         end
169
170         to_install = %F;
171
172         // Now, it's time to check if the module is installed or not :
173         //   - 1st case: section is not specified or is equal to "all", module
174         //               is searched in both "user" and "allusers" section
175         //   - 2nd case: section is equal to "user", module is only searched in
176         //               the "user" section"
177         //   - 3rd case: section is equal to "allusers", module is only searched
178         //               in the "allusers" section"
179
180         if atomsIsInstalled(this_package_name,section) then
181             vers = atomsGetInstalledVers(this_package_name,section);
182             if find( vers == this_package_version ) == [] then
183                 to_install = %T;
184             end
185         else
186             to_install = %T;
187         end
188
189         if to_install then
190             insList = [ insList ; "+" this_package_user_choice this_package_name this_package_version ];
191         else
192             insList = [ insList ; "~" this_package_user_choice this_package_name this_package_version ];
193         end
194
195     end
196
197 endfunction
198
199 // =============================================================================
200 // Return the version filled with the packaging version
201 // → The result is based on the packages struct returned by atomsDESCRIPTIONget(),
202 //   not on the installed packages.
203 // → If a package doesn't exist in the packages struct, an empty string is
204 //   returned
205 // =============================================================================
206
207 function result = atomsPackagingVersion(packages)
208
209     // Initialize
210     // =========================================================================
211     result = [];
212
213     // Check input parameters
214     // =========================================================================
215     rhs  = argn(2);
216
217     if rhs <> 1 then
218         error(msprintf(gettext("%s: Wrong number of input argument: %d expected.\n"),"atomsPackagingVersion",1));
219     end
220
221     if type(packages) <> 10 then
222         error(msprintf(gettext("%s: Wrong type for input argument #%d: String array expected.\n"),"atomsPackagingVersion",1));
223     end
224
225     if size(packages(1,:),"*") <> 2 then
226         error(msprintf(gettext("%s: Wrong size for input argument #%d: mx2 string matrix expected.\n"),"atomsPackagingVersion",1));
227     end
228
229     // Get all package description
230     // =========================================================================
231     allpackages = atomsDESCRIPTIONget();
232
233     // Loop on packages
234     // =========================================================================
235
236     for i=1:size(packages(:,1),"*")
237
238         result(i) = "",
239         name      = packages(i,1);
240         version   = packages(i,2);
241
242         // Check if the name exists in the packages struct
243         if ~ isfield(allpackages,name) then
244             result(i) = "";
245             break;
246         end
247
248         // 1st case : no version is mentioned
249         if isempty(version) then
250             result(i) = "";
251
252             // 2nd case : the packaging version is already mentioned
253         elseif ~ isempty(strindex(version,"-")) then
254             result(i) = version;
255
256             // 3rd case : the packaging version is not mentioned
257         else
258
259             // Loop on this packages versions
260             package_versions          = allpackages(name);
261             package_versions_tab      = getfield(1,package_versions);
262             package_versions_tab(1:2) = [];
263
264             for j=1:size(package_versions_tab,"*")
265
266                 if isempty( strindex(package_versions_tab(j),"-") ) then
267                     if package_versions_tab(j) == version then
268                         result(i) = version;
269                         break;
270                     end
271
272                 else
273                     if part(package_versions_tab(j), 1:strindex(package_versions_tab(j),"-")-1)==version then
274                         result(i) = package_versions_tab(j);
275                         break;
276                     end
277
278                 end
279
280             end
281         end
282
283     end
284
285 endfunction