Salome HOME
correction coquille
[tools/sat.git] / commands / package.py
index bf3fbee67c2763ae56b55503f75992263be78b77..707bbab5fc5db4c4046b19f08b37e3de2e491909 100644 (file)
@@ -23,6 +23,7 @@ import datetime
 import tarfile
 import codecs
 import string
+import glob
 import pprint as PP
 
 import src
@@ -107,8 +108,6 @@ parser.add_option('n', 'name', 'string', 'name',
     _('Optional: The name or full path of the archive.'), None)
 parser.add_option('', 'add_files', 'list2', 'add_files',
     _('Optional: The list of additional files to add to the archive.'), [])
-parser.add_option('', 'without_commercial', 'boolean', 'without_commercial',
-    _('Optional: do not add commercial licence.'), False)
 parser.add_option('', 'without_properties', 'properties', 'without_properties',
     _('Optional: Filter the products by their properties.\n\tSyntax: '
       '--without_properties <property>:<value>'))
@@ -137,6 +136,8 @@ def add_files(tar, name_archive, d_content, logger, f_exclude=None):
     names = sorted(d_content.keys())
     DBG.write("add tar names", names)
 
+    # used to avoid duplications (for pip install in python, or single_install_dir cases)
+    already_added=set() 
     for name in names:
         # display information
         len_points = max_len - len(name) + 3
@@ -147,7 +148,10 @@ def add_files(tar, name_archive, d_content, logger, f_exclude=None):
         # of the directory or file to add
         # Add it in the archive
         try:
-            tar.add(local_path, arcname=in_archive, exclude=f_exclude)
+            key=local_path+"->"+in_archive
+            if key not in already_added:
+                tar.add(local_path, arcname=in_archive, exclude=f_exclude)
+                already_added.add(key)
             logger.write(src.printcolors.printcSuccess(_("OK")), 3)
         except Exception as e:
             logger.write(src.printcolors.printcError(_("KO ")), 3)
@@ -176,8 +180,7 @@ def produce_relative_launcher(config,
                               logger,
                               file_dir,
                               file_name,
-                              binaries_dir_name,
-                              with_commercial=True):
+                              binaries_dir_name):
     '''Create a specific SALOME launcher for the binary package. This launcher 
        uses relative paths.
     
@@ -222,40 +225,35 @@ def produce_relative_launcher(config,
     else:
         app_root_dir=os.path.join(binaries_dir_name, salome_application_name)
 
-    # Get the launcher template and do substitutions
+    additional_env={}
+    additional_env['sat_bin_kernel_install_dir'] = "out_dir_Path + " +\
+                                                   config.VARS.sep + bin_kernel_install_dir
     if "python3" in config.APPLICATION and config.APPLICATION.python3 == "yes":
-        withProfile = src.fileEnviron.withProfile3
+        additional_env['sat_python_version'] = 3
     else:
-        withProfile = src.fileEnviron.withProfile
-
-    withProfile = withProfile.replace(
-        "ABSOLUTE_APPLI_PATH'] = 'KERNEL_INSTALL_DIR'",
-        "ABSOLUTE_APPLI_PATH'] = out_dir_Path + '" + config.VARS.sep + app_root_dir + "'")
-    withProfile = withProfile.replace(
-        " 'BIN_KERNEL_INSTALL_DIR'",
-        " out_dir_Path + '" + config.VARS.sep + bin_kernel_install_dir + "'")
+        additional_env['sat_python_version'] = 2
 
-    before, after = withProfile.split("# here your local standalone environment\n")
+    additional_env['ABSOLUTE_APPLI_PATH'] = "out_dir_Path" + config.VARS.sep + app_root_dir
 
     # create an environment file writer
     writer = src.environment.FileEnvWriter(config,
                                            logger,
                                            file_dir,
-                                           src_root=None)
+                                           src_root=None,
+                                           env_info=None)
     
     filepath = os.path.join(file_dir, file_name)
-    # open the file and write into it
-    launch_file = open(filepath, "w")
-    launch_file.write(before)
     # Write
-    writer.write_cfgForPy_file(launch_file,
-                               for_package = binaries_dir_name,
-                               with_commercial=with_commercial)
-    launch_file.write(after)
-    launch_file.close()
+    writer.write_env_file(filepath,
+                          False,  # for launch
+                          "cfgForPy",
+                          additional_env=additional_env,
+                          no_path_init="False",
+                          for_package = binaries_dir_name)
     
     # Little hack to put out_dir_Path outside the strings
     src.replace_in_file(filepath, 'r"out_dir_Path', 'out_dir_Path + r"' )
+    src.replace_in_file(filepath, "'out_dir_Path + ", "out_dir_Path + '" )
     
     # A hack to put a call to a file for distene licence.
     # It does nothing to an application that has no distene product
@@ -342,10 +340,17 @@ def produce_relative_env_files(config,
                                            file_dir,
                                            src_root=None)
     
+    if src.architecture.is_windows():
+      shell = "bat"
+      filename  = "env_launch.bat"
+    else:
+      shell = "bash"
+      filename  = "env_launch.sh"
+
     # Write
-    filepath = writer.write_env_file("env_launch.sh",
+    filepath = writer.write_env_file(filename,
                           False, # for launch
-                          "bash",
+                          shell,
                           for_package = binaries_dir_name)
 
     # Little hack to put out_dir_Path as environment variable
@@ -388,12 +393,13 @@ def produce_install_bin_file(config,
                                         "INSTALL_BIN.template")
         
         # build the name of the directory that will contain the binaries
-        binaries_dir_name = "BINARIES-" + config.VARS.dist
+        binaries_dir_name = config.INTERNAL.config.binary_dir + config.VARS.dist
         # build the substitution loop
         loop_cmd = "for f in $(grep -RIl"
         for key in d_sub:
             loop_cmd += " -e "+ key
-        loop_cmd += ' INSTALL); do\n     sed -i "\n'
+        loop_cmd += ' ' + config.INTERNAL.config.install_dir +\
+                    '); do\n     sed -i "\n'
         for key in d_sub:
             loop_cmd += "        s?" + key + "?$(pwd)/" + d_sub[key] + "?g\n"
         loop_cmd += '            " $f\ndone'
@@ -401,6 +407,7 @@ def produce_install_bin_file(config,
         d={}
         d["BINARIES_DIR"] = binaries_dir_name
         d["SUBSTITUTION_LOOP"]=loop_cmd
+        d["INSTALL_DIR"]=config.INTERNAL.config.install_dir
         
         # substitute the template and write it in file
         content=src.template.substitute(installbin_template_path, d)
@@ -532,7 +539,7 @@ def binary_package(config, logger, options, tmp_working_dir):
                 or src.product.product_is_fixed(prod_info)
                 or not src.product.product_compiles(prod_info)):
             continue
-        if src.product.check_installation(prod_info):
+        if src.product.check_installation(config, prod_info):
             l_install_dir.append((prod_name, prod_info.install_dir))
         else:
             l_not_installed.append(prod_name)
@@ -542,7 +549,8 @@ def binary_package(config, logger, options, tmp_working_dir):
             # cpp module
             for name_cpp in src.product.get_product_components(prod_info):
                 install_dir = os.path.join(config.APPLICATION.workdir,
-                                           "INSTALL", name_cpp) 
+                                           config.INTERNAL.config.install_dir,
+                                           name_cpp) 
                 if os.path.exists(install_dir):
                     l_install_dir.append((name_cpp, install_dir))
                 else:
@@ -550,7 +558,9 @@ def binary_package(config, logger, options, tmp_working_dir):
         
     # check the name of the directory that (could) contains the binaries 
     # from previous detar
-    binaries_from_detar = os.path.join(config.APPLICATION.workdir, "BINARIES-" + config.VARS.dist)
+    binaries_from_detar = os.path.join(
+                              config.APPLICATION.workdir,
+                              config.INTERNAL.config.binary_dir + config.VARS.dist)
     if os.path.exists(binaries_from_detar):
          logger.write("""
 WARNING: existing binaries directory from previous detar installation:
@@ -598,13 +608,13 @@ WARNING: existing binaries directory from previous detar installation:
                          1)
  
     # construct the name of the directory that will contain the binaries
-    binaries_dir_name = "BINARIES-" + config.VARS.dist
+    binaries_dir_name = config.INTERNAL.config.binary_dir + config.VARS.dist
     
     # construct the correlation table between the product names, there 
     # actual install directories and there install directory in archive
     d_products = {}
     for prod_name, install_dir in l_install_dir:
-        path_in_archive = os.path.join(binaries_dir_name, prod_name)
+        path_in_archive = os.path.join(binaries_dir_name, os.path.basename(install_dir))
         d_products[prod_name + " (bin)"] = (install_dir, path_in_archive)
         
     for prod_name, source_dir in l_source_dir:
@@ -623,8 +633,7 @@ WARNING: existing binaries directory from previous detar installation:
                                                  logger,
                                                  tmp_working_dir,
                                                  launcher_name,
-                                                 binaries_dir_name,
-                                                 not(options.without_commercial))
+                                                 binaries_dir_name)
             d_products["launcher"] = (launcher_package, launcher_name)
 
             # if the application contains mesa products, we generate in addition to the 
@@ -644,8 +653,7 @@ WARNING: existing binaries directory from previous detar installation:
                                                      logger,
                                                      tmp_working_dir,
                                                      launcher_mesa_name,
-                                                     binaries_dir_name,
-                                                     not(options.without_commercial))
+                                                     binaries_dir_name)
                 d_products["launcher (mesa)"] = (launcher_package_mesa, launcher_mesa_name)
 
                 # if there was a use_mesa value, we restore it
@@ -674,8 +682,12 @@ WARNING: existing binaries directory from previous detar installation:
                                            tmp_working_dir,
                                            binaries_dir_name)
 
-    d_products["environment file"] = (env_file, "env_launch.sh")
-      
+    if src.architecture.is_windows():
+      filename  = "env_launch.bat"
+    else:
+      filename  = "env_launch.sh"
+    d_products["environment file"] = (env_file, filename)      
+
     return d_products
 
 def source_package(sat, config, logger, options, tmp_working_dir):
@@ -775,11 +787,34 @@ def get_archives(config, logger):
         if p_info.get_source == "archive":
             archive_path = p_info.archive_info.archive_name
             archive_name = os.path.basename(archive_path)
+            d_archives[p_name] = (archive_path,
+                                  os.path.join(ARCHIVE_DIR, archive_name))
+            if (src.appli_test_property(config,"pip", "yes") and 
+                src.product.product_test_property(p_info,"pip", "yes")):
+                # if pip mode is activated, and product is managed by pip
+                pip_wheels_dir=os.path.join(config.LOCAL.archive_dir,"wheels")
+                pip_wheel_pattern=os.path.join(pip_wheels_dir, 
+                    "%s-%s*" % (p_info.name, p_info.version))
+                pip_wheel_path=glob.glob(pip_wheel_pattern)
+                msg_pip_not_found="Error in get_archive, pip wheel for "\
+                                  "product %s-%s was not found in %s directory"
+                msg_pip_two_or_more="Error in get_archive, several pip wheels for "\
+                                  "product %s-%s were found in %s directory"
+                if len(pip_wheel_path)==0:
+                    raise src.SatException(msg_pip_not_found %\
+                        (p_info.name, p_info.version, pip_wheels_dir))
+                if len(pip_wheel_path)>1:
+                    raise src.SatException(msg_pip_two_or_more %\
+                        (p_info.name, p_info.version, pip_wheels_dir))
+
+                pip_wheel_name=os.path.basename(pip_wheel_path[0])
+                d_archives[p_name+" (pip wheel)"]=(pip_wheel_path[0], 
+                    os.path.join(ARCHIVE_DIR, "wheels", pip_wheel_name))
         else:
-            l_pinfo_vcs.append((p_name, p_info))
+            # this product is not managed by archive, 
+            # an archive of the vcs directory will be created by get_archive_vcs
+            l_pinfo_vcs.append((p_name, p_info)) 
             
-        d_archives[p_name] = (archive_path,
-                              os.path.join(ARCHIVE_DIR, archive_name))
     return d_archives, l_pinfo_vcs
 
 def add_salomeTools(config, tmp_working_dir):
@@ -1503,7 +1538,9 @@ Please add it in file:
         for key in d_bin_files_to_add:
             if key.endswith("(bin)"):
                 source_dir = d_bin_files_to_add[key][0]
-                path_in_archive = d_bin_files_to_add[key][1].replace("BINARIES-" + runner.cfg.VARS.dist,"INSTALL")
+                path_in_archive = d_bin_files_to_add[key][1].replace(
+                   runner.cfg.INTERNAL.config.binary_dir + runner.cfg.VARS.dist,
+                   runner.cfg.INTERNAL.config.install_dir)
                 if os.path.basename(source_dir)==os.path.basename(path_in_archive):
                     # if basename is the same we will just substitute the dirname 
                     d_paths_to_substitute[os.path.dirname(source_dir)]=\
@@ -1597,8 +1634,9 @@ Please add it in file:
         if os.path.isdir(tmp_local_working_dir):
             shutil.rmtree(tmp_local_working_dir)
 
-    # have to decide some time
-    DBG.tofix("make shutil.rmtree('%s') effective" % tmp_working_dir, "", DBG.isDeveloper())
+    # remove the tmp directory, unless user has registered as developer
+    if os.path.isdir(tmp_working_dir) and (not DBG.isDeveloper()):
+        shutil.rmtree(tmp_working_dir)
     
     # Print again the path of the package
     logger.write("\n", 2)