ATOMS: homogenize function's profile
[scilab.git] / scilab / modules / atoms / macros / atomsInstall.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 // This file must be used under the terms of the CeCILL.
5 // This source file is licensed as described in the file COPYING, which
6 // you should have received as part of this distribution.  The terms
7 // are also available at
8 // http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
9
10 // End user function
11
12 // Installation of a toolbox
13
14 function result = atomsInstall(packages,section)
15         
16         // Load Atoms Internals lib if it's not already loaded
17         // =========================================================================
18         if ~ exists("atomsinternalslib") then
19                 load("SCI/packages/atoms/macros/atoms_internals/lib");
20         end
21         
22         result = [];
23         
24         // Save the initial path
25         // =========================================================================
26         initialpath = pwd();
27         
28         // Get scilab version (needed for later)
29         // =========================================================================
30         sciversion = strcat(string(getversion("scilab")) + ".");
31         
32         // Check input parameters
33         // =========================================================================
34         
35         rhs = argn(2);
36         
37         if rhs < 1 | rhs > 2 then
38                 error(msprintf(gettext("%s: Wrong number of input arguments: %d to %d expected.\n"),"atomsInstall",1,2))
39         end
40         
41         if type(packages) <> 10 then
42                 error(msprintf(gettext("%s: Wrong type for input argument #%d: String array expected.\n"),"atomsInstall",1));
43         end
44         
45         if size(packages(1,:),"*") > 2 then
46                 error(msprintf(gettext("%s: Wrong size for input argument #%d: mx1 or mx2 string matrix expected.\n"),"atomsInstall",1));
47         end
48         
49         // Remove leading and trailing whitespace
50         // =========================================================================
51         packages = stripblanks(packages);
52         
53         // Operating system detection
54         // =========================================================================
55         
56         if ~MSDOS then
57                 OSNAME = unix_g('uname');
58                 MACOSX = (strcmpi(OSNAME,"darwin") == 0);
59                 LINUX  = (strcmpi(OSNAME,"linux") == 0);
60         else
61                 MACOSX = %F;
62                 LINUX  = %F;
63         end
64         
65         if MSDOS then
66                 OSNAME = "windows";
67         elseif LINUX then
68                 OSNAME = "linux";
69         elseif MACOSX then
70                 OSNAME = "macosx";
71         end
72         
73         // Architecture detection
74         // =========================================================================
75         
76         [dynamic_info,static_info] = getdebuginfo();
77         arch_info  = static_info(grep(static_info,"/^Compiler Architecture:/","r"))
78         
79         if ~isempty(arch_info) & (regexp(arch_info,"/\sX64$/","o") <> []) then
80                 ARCH = "64";
81         else
82                 ARCH = "32";
83         end
84         
85         // Verbose Mode ?
86         // =========================================================================
87         if strcmpi(atomsGetConfig("Verbose"),"True") == 0 then
88                 ATOMSVERBOSE = %T;
89         else
90                 ATOMSVERBOSE = %F;
91         end
92         
93         // Allusers/user management
94         //   - If Allusers is equal to "allusers", packages will installed in the "allusers" section :
95         //       → SCI/contrib    : location of the packages
96         //       → SCI/.atoms     : ATOMS system files
97         //   - Otherwise, packages will installed in the "user" section :
98         //       → SCIHOME/atoms  : location of the packages
99         //       → SCIHOME/.atoms : location of the packages & ATOMS system files
100         // =========================================================================
101         
102         if rhs <= 1 then
103                 
104                 // By default: 
105                 //  → Install in the "allusers" section if we have the write access to
106                 //    SCI directory
107                 //  → Install in the "user" otherwise
108                 
109                 if atomsAUWriteAccess() then
110                         section = "allusers"; 
111                 else
112                         section = "user";
113                 end
114                 
115         else
116                 
117                 // Process the 2nd input argument : section
118                 // Allusers can be a boolean or equal to "user" or "allusers"
119                 
120                 if type(section) <> 10 then
121                         chdir(initialpath);
122                         error(msprintf(gettext("%s: Wrong type for input argument #%d: A single-string expected.\n"),"atomsInstall",2));
123                 end
124                 
125                 if and(section<>["user","allusers"]) then
126                         chdir(initialpath);
127                         error(msprintf(gettext("%s: Wrong value for input argument #%d: ''user'' or ''allusers'' expected.\n"),"atomsInstall",2));
128                 end
129                 
130                 // Check if we have the write access
131                 if (section=="allusers") & ~ atomsAUWriteAccess() then
132                         chdir(initialpath);
133                         error(msprintf(gettext("%s: You haven''t write access on this directory : %s.\n"),"atomsInstall",2,pathconvert(SCI+"/.atoms")));
134                 end
135         end
136         
137         // Create needed directories
138         // =========================================================================
139         atoms_system_directory  = atomsPath("system" ,section);
140         atoms_install_directory = atomsPath("install",section);
141         atoms_tmp_directory     = atomsPath("system" ,"session");
142         
143         if ~ isdir( atoms_system_directory ) & (mkdir( atoms_system_directory ) <> 1) then
144                 error(msprintf( ..
145                         gettext("%s: The directory ''%s'' cannot been created, please check if you have write access on this directory.\n"),..
146                         atoms_system_directory));
147         end
148         
149         if ~ isdir( atoms_install_directory ) & (mkdir( atoms_install_directory ) <> 1) then
150                 error(msprintf( ..
151                         gettext("%s: The directory ''%s'' cannot been created, please check if you have write access on this directory.\n"),..
152                         atoms_install_directory));
153         end
154         
155         if ~ isdir(atoms_tmp_directory) & (mkdir(atoms_tmp_directory) <> 1) then
156                 error(msprintf( ..
157                         gettext("%s: The directory ''%s'' cannot been created, please check if you have write access on this directory.\n"),..
158                         atoms_tmp_directory));
159         end
160         
161         // Define the "archives" directory path
162         // Create it if it's not exist
163         // =========================================================================
164         archives_directory = atoms_install_directory + "archives";
165         
166         if ~ isdir( archives_directory ) & (mkdir( archives_directory ) <> 1) then
167                 error(msprintf( ..
168                         gettext("%s: The directory ''%s'' cannot been created, please check if you have write access on this directory.\n"),..
169                         "atomsInstall", ..
170                         archives_directory));
171         end
172         
173         // "Archive" installation
174         // =========================================================================
175         
176         for i=1:size(packages(:,1),"*")
177                 
178                 this_package = packages(i,1);
179                 
180                 if ~ isempty(regexp(this_package,"/(\.tar\.gz|\.tgz|\.zip)$/","o")) then
181                         
182                         if fileinfo( this_package ) then
183                                 error(msprintf(gettext("%s: The file ''%s'' doesn''t exist or is not read accessible\n"),"atomsInstall",this_package));
184                         end
185                         
186                         tmp_dir = atomsExtract(this_package,atoms_tmp_directory);
187                         tmp_dir = pathconvert(atoms_tmp_directory+tmp_dir);
188                         
189                         if fileinfo( tmp_dir + "DESCRIPTION" ) then
190                                 error(msprintf(gettext("%s: DESCRIPTION file cannot be found in the package ''%s''\n"),"atomsInstall",this_package));
191                         end
192                         
193                         this_package_description = atomsDESCRIPTIONread(tmp_dir + "DESCRIPTION");
194                         
195                         // Get package name and version
196                         // -----------------------------------------------------------------
197                         
198                         this_package_name    = getfield(1,this_package_description);
199                         this_package_name    = this_package_name(3);
200                         
201                         this_package_version = getfield(1,this_package_description(this_package_name));
202                         this_package_version = this_package_version(3);
203                         
204                         // Save the extracted directory
205                         // -----------------------------------------------------------------
206                         
207                         this_package_description = atomsDESCRIPTIONaddField( .. 
208                                 this_package_description, ..
209                                 this_package_name,        ..
210                                 this_package_version,     ..
211                                 "extractedDirectory",     ..
212                                 tmp_dir);
213                         
214                         this_package_description = atomsDESCRIPTIONaddField( .. 
215                                 this_package_description, ..
216                                 this_package_name,        ..
217                                 this_package_version,     ..
218                                 "archiveFile",            ..
219                                 this_package);
220                                 
221                         this_package_description = atomsDESCRIPTIONaddField( .. 
222                                 this_package_description, ..
223                                 this_package_name,        ..
224                                 this_package_version,     ..
225                                 "fromRepository",         ..
226                                 "0");
227                         
228                         // Save the DESCRIPTION_archives
229                         // -----------------------------------------------------------------
230                         
231                         if fileinfo( atoms_tmp_directory + "DESCRIPTION_archives" )<>[] then
232                                 packages_description = atomsDESCRIPTIONread(atoms_tmp_directory+"DESCRIPTION_archives");
233                                 packages_description = atomsDESCRIPTIONcat(packages_description,this_package_description);
234                         else
235                                 packages_description = this_package_description;
236                         end
237                         
238                         atomsDESCRIPTIONwrite(packages_description,atoms_tmp_directory+"DESCRIPTION_archives");
239                         
240                         // change the packages var
241                         // -----------------------------------------------------------------
242                         packages(i,:) = [ this_package_name this_package_version ];
243                         
244                 end
245                 
246         end
247         
248         // Force update the system informations
249         // =========================================================================
250         atomsGetTOOLBOXES(%T)
251         
252         // Get the install list
253         // =========================================================================
254         [install_package_list,dependency_tree] = atomsInstallList(packages,section);
255         
256         // Loop on install_package_list to print if a package has to be installed
257         // or not
258         // =========================================================================
259         for i=1:size(install_package_list(:,1),"*")
260                 if install_package_list(i,1) == "+" then
261                         atomsDisp(msprintf("\t%s (%s) will be installed\n\n",install_package_list(i,3),install_package_list(i,4)));
262                 elseif install_package_list(i,1) == "~" then
263                         atomsDisp(msprintf("\t%s (%s) is already installed and up-to-date\n\n",install_package_list(i,3),install_package_list(i,4)));
264                 end
265         end
266         
267         // Now really install the packages
268         // =========================================================================
269         
270         for i=1:size(install_package_list(:,1),"*")
271                 
272                 this_package_name    = install_package_list(i,3);
273                 this_package_version = install_package_list(i,4);
274                 
275                 this_package_details = dependency_tree(this_package_name+" - "+this_package_version);
276                 
277                 if install_package_list(i,1) <> "+" then
278                         continue;
279                 end
280                 
281                 atomsDisp(msprintf("\tInstalling %s (%s) ...",this_package_name,this_package_version));
282                 
283                 // Define the path of the directory where will be installed this toolbox
284                 // =====================================================================
285                 this_package_directory = atomsPath("install",section) + this_package_name + filesep();
286                 
287                 // Create the parent directory of this toolbox if it's not already exist
288                 // =====================================================================
289                 
290                 if ~isdir(this_package_directory) & (mkdir(this_package_directory)<>1) then
291                         chdir(initialpath);
292                         error(msprintf( ..
293                                 gettext("%s: The directory ""%s"" cannot been created, please check if you have write access on this directory.\n"),..
294                                 this_package_directory));
295                 end
296                 
297                 // "Repository" installation ; Download and Extract
298                 // =====================================================================
299                 
300                 if this_package_details("fromRepository") == "1" then
301                         
302                         // Define the path of the downloaded file
303                         // =================================================================
304                         
305                         if isfield(this_package_details,OSNAME+ARCH+"Name") then
306                                 OSTYPE = OSNAME+ARCH;
307                         else
308                                 OSTYPE = OSNAME;
309                         end
310                         
311                         fileout = pathconvert(this_package_directory+this_package_details(OSTYPE+"Name"),%F);
312                         filein  = this_package_details(OSTYPE+"Url");
313                         filemd5 = this_package_details(OSTYPE+"Md5");
314                         
315                         // Launch the download
316                         // =================================================================
317                         atomsDownload(filein,fileout,filemd5);
318                         
319                         // unarchive it
320                         // =================================================================
321                         this_package_details("extractedDirectory") = this_package_directory + atomsExtract(fileout,this_package_directory);
322                 end
323                 
324                 // Rename the created directory
325                 // =====================================================================
326                 
327                 if MSDOS then
328                         rename_cmd = "rename """+this_package_details("extractedDirectory")+""" """+this_package_version+"""";
329                 else
330                         rename_cmd = "mv """+this_package_details("extractedDirectory")+""" """+this_package_directory+this_package_version+"""";
331                 end
332                 
333                 [rep,stat]=unix_g(rename_cmd)
334                 
335                 if stat <> 0 then
336                         disp(rename_cmd);
337                         chdir(initialpath);
338                         error(msprintf(gettext("%s: Error while creating the directory ''%s''.\n"),"atomsInstall",pathconvert(this_package_directory+this_package_version)));
339                 end
340                 
341                 // Register the successfully installed package
342                 // =====================================================================
343                 
344                 if install_package_list(i,2) == "U" then
345                         // Intentionnaly Installed
346                         this_package_status = "I";
347                 else
348                         // Automaticaly installed
349                         this_package_status = "A";
350                 end
351                 
352                 atomsInstallRegister(this_package_name,this_package_version,this_package_status,section);
353                 
354                 // Autoload the toolbox unless precised
355                 // =====================================================================
356                 
357                 if ~ (atomsGetConfig("autoload") == "False") then
358                         // Add a package to the autoload list only if it's intentionnaly
359                         // installed
360                         if this_package_status=="I" then
361                                 atomsAutoloadAdd(this_package_name,this_package_version,section);
362                         end
363                 end
364                 
365                 // Move the archive file (.tar.gz or .zip file) to the archive directory
366                 // =====================================================================
367                 
368                 if this_package_details("fromRepository")=="1" then
369                         this_package_archive = fileout;
370                 else
371                         this_package_archive = this_package_details("archiveFile");
372                 end
373                 
374                 if copyfile( this_package_archive , archives_directory ) <> 1 then
375                         chdir(initialpath);
376                         error(msprintf(gettext("%s: Error while copying the file ''%s'' to the directory ''%s''.\n"),"atomsInstall",this_package_archive,archives_directory));
377                 end
378                 
379                 if this_package_details("fromRepository")=="1" then
380                         mdelete( fileout );
381                 end
382                 
383                 // Fill the result matrix
384                 // =====================================================================
385                 result = [ result ; atomsGetInstalledDetails([this_package_name this_package_version]) ];
386                 
387                 // "archive" installation : Save the description
388                 // =====================================================================
389                 
390                 if this_package_details("fromRepository")=="0" then
391                         
392                         DESCRIPTION_file = atoms_directory+"DESCRIPTION_archives";
393                         
394                         if isempty(fileinfo(atoms_directory+"DESCRIPTION_archives")) then
395                                 DESCRIPTION = struct();
396                         else
397                                 DESCRIPTION = atomsDESCRIPTIONread(DESCRIPTION_file);
398                         end
399                         
400                         DESCRIPTION = atomsDESCRIPTIONadd(DESCRIPTION,this_package_name,this_package_version,this_package_details);
401                         atomsDESCRIPTIONwrite(DESCRIPTION,DESCRIPTION_file);
402                         
403                 end
404                 
405                 // Sucess message if needed
406                 // =====================================================================
407                 
408                 atomsDisp(msprintf(" success\n\n"));
409                 
410         end
411         
412         // The TMPDIR DESCRIPTION_archives is no more needed
413         // =========================================================================
414         
415         if ~ isempty(fileinfo(atoms_tmp_directory + "DESCRIPTION_archives")) then
416                 mdelete(atoms_tmp_directory + "DESCRIPTION_archives");
417         end
418         
419         // Update the dependencies of packages that use another version of packages
420         // that have been installed
421         // =========================================================================
422         
423         for i=1:size( result(:,1) , "*" )
424                 
425                 packages_out = atomsUpdateDeps([result(i,1) result(i,2)],section);
426                 
427                 if ATOMSVERBOSE then
428                         for j=1:size(packages_out(:,1),"*")
429                                 atomsDisp(msprintf("\t%s (%s) will now use the version %s of the package %s\n\n",packages_out(j,1),packages_out(j,2),result(i,1),result(i,2)));
430                         end
431                 end
432                 
433         end
434         
435         // Remove orphan packages
436         // =========================================================================
437         
438         orphan_list = atomsOrphanList(section);
439         if ~ isempty(orphan_list) then
440                 atomsRemove( [ orphan_list(:,1) orphan_list(:,2) ] );
441         end
442         
443         // Go to the initial location
444         // =========================================================================
445         chdir(initialpath);
446         
447 endfunction