3 # Copyright (C) 2010-2012 CEA/DEN
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2.1 of the License.
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # Lesser General Public License for more details.
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 In this file are implemented the methods
21 relative to the product notion of salomeTools
29 import src.debug as DBG
30 import src.versionMinorMajorPatch as VMMP
32 AVAILABLE_VCS = ['git', 'svn', 'cvs']
34 CONFIG_FILENAME = "sat-config.pyconf" # trace product depends version(s)
35 PRODUCT_FILENAME = "sat-product.pyconf" # trace product compile config
36 config_expression = "^config-\d+$"
38 def get_product_config(config, product_name, with_install_dir=True):
39 """Get the specific configuration of a product from the global configuration
41 :param config Config: The global configuration
42 :param product_name str: The name of the product
43 :param with_install_dir boolean: If false, do not provide an install
44 directory (at false only for internal use
45 of the function check_config_exists)
46 :return: the specific configuration of the product
50 # Get the version of the product from the application definition
51 version = config.APPLICATION.products[product_name]
53 # Define debug and dev modes
54 # Get the tag if a dictionary is given in APPLICATION.products for the
63 # if no version, then take the default one defined in the application
64 if isinstance(version, bool) or isinstance(version, str):
65 # in this case tag is mandatory, not debug, verbose, dev
66 if 'debug' in config.APPLICATION:
67 debug = config.APPLICATION.debug
68 if 'verbose' in config.APPLICATION:
69 verbose = config.APPLICATION.verbose
70 if 'dev' in config.APPLICATION:
71 dev = config.APPLICATION.dev
72 if 'hpc' in config.APPLICATION:
73 hpc = config.APPLICATION.hpc
75 # special case for which only the product name is mentionned
76 if isinstance(version, bool):
77 version = config.APPLICATION.tag
79 if isinstance(version, src.pyconf.Mapping):
82 if not 'tag' in dic_version:
83 version = config.APPLICATION.tag
85 version = dic_version.tag
87 # Get the debug if any
88 if 'debug' in dic_version:
89 debug = dic_version.debug
90 elif 'debug' in config.APPLICATION:
91 debug = config.APPLICATION.debug
93 # Get the verbose if any
94 if 'verbose' in dic_version:
95 verbose = dic_version.verbose
96 elif 'verbose' in config.APPLICATION:
97 verbose = config.APPLICATION.verbose
100 if 'dev' in dic_version:
101 dev = dic_version.dev
102 elif 'dev' in config.APPLICATION:
103 dev = config.APPLICATION.dev
106 if 'hpc' in dic_version:
107 hpc = dic_version.hpc
108 elif 'hpc' in config.APPLICATION:
109 hpc = config.APPLICATION.hpc
111 # Get the base if any
112 if 'base' in dic_version:
113 base = dic_version.base
115 # Get the section if any
116 if 'section' in dic_version:
117 section = dic_version.section
119 # this case occur when version is overwritten, cf sat # 8897
120 if isinstance(version, dict):
121 dic_version = version
122 # Get the version/tag
123 if not 'tag' in dic_version:
124 version = config.APPLICATION.tag
126 version = dic_version["tag"]
128 # Get the debug if any
129 if 'debug' in dic_version:
130 debug = dic_version["debug"]
131 elif 'debug' in config.APPLICATION:
132 debug = config.APPLICATION.debug
134 # Get the verbose if any
135 if 'verbose' in dic_version:
136 verbose = dic_version["verbose"]
137 elif 'verbose' in config.APPLICATION:
138 verbose = config.APPLICATION.verbose
141 if 'dev' in dic_version:
142 dev = dic_version["dev"]
143 elif 'dev' in config.APPLICATION:
144 dev = config.APPLICATION.dev
147 if 'hpc' in dic_version:
148 hpc = dic_version.hpc
149 elif 'hpc' in config.APPLICATION:
150 hpc = config.APPLICATION.hpc
152 # Get the base if any
153 if 'base' in dic_version:
154 base = dic_version["base"]
156 # Get the section if any
157 if 'section' in dic_version:
158 section = dic_version['section']
161 # substitute some character with _ in order to get the correct definition
162 # in config.PRODUCTS. This is done because the pyconf tool does not handle
163 # the . and - characters
164 for c in ".-": vv = vv.replace(c, "_")
167 if product_name in config.PRODUCTS:
168 # Search for the product description in the configuration
169 prod_info = get_product_section(config, product_name, vv, section)
171 # get salomeTool version
172 prod_info.sat_version = src.get_salometool_version(config)
174 # get the product project git tag, if any
175 product_project_git_tag = src.system.git_describe(os.path.dirname(prod_info.from_file))
176 if product_project_git_tag:
177 prod_info.sat_project_tag = product_project_git_tag
179 prod_info.sat_project_tag = "unknown"
181 # merge opt_depend in depend
182 if prod_info is not None and 'opt_depend' in prod_info:
183 for depend in prod_info.opt_depend:
184 if depend in config.APPLICATION.products:
185 prod_info.depend.append(depend,'')
187 # In case of a product get with a vcs,
188 # put the tag (equal to the version)
189 if prod_info is not None and prod_info.get_source in AVAILABLE_VCS:
191 if prod_info.get_source == 'git':
192 prod_info.git_info.tag = version
194 if prod_info.get_source == 'svn':
195 prod_info.svn_info.tag = version
197 if prod_info.get_source == 'cvs':
198 prod_info.cvs_info.tag = version
200 # In case of a fixed product,
201 # define the install_dir (equal to the version)
202 if prod_info is not None and \
203 (os.path.isdir(version) or version.startswith("/")):
204 # we consider a (fixed) path existing paths;
205 # or paths starting with '/' (the objective is to print a correct
206 # message to the user in case of non existing path.)
207 prod_info.install_dir = version
208 prod_info.get_source = "fixed"
210 # Check if the product is defined as native in the application
211 if prod_info is not None:
212 if version == "native":
213 prod_info.get_source = "native"
214 elif prod_info.get_source == "native":
215 msg = _("The product %(prod)s has version %(ver)s but is "
216 "declared as native in its definition" %
217 { 'prod': prod_info.name, 'ver': version})
218 raise src.SatException(msg)
220 # If there is no definition but the product is declared as native,
221 # construct a new definition containing only the get_source key
222 if prod_info is None and version == "native":
223 prod_info = src.pyconf.Config()
224 prod_info.name = product_name
225 prod_info.get_source = "native"
227 # If there is no definition but the product is fixed,
228 # construct a new definition containing only the product name
229 if prod_info is None and os.path.isdir(version):
230 prod_info = src.pyconf.Config()
231 prod_info.name = product_name
232 prod_info.get_source = "fixed"
233 prod_info.addMapping("environ", src.pyconf.Mapping(prod_info), "")
236 # If prod_info is still None, it means that there is no product definition
237 # in the config. The user has to provide it.
238 if prod_info is None:
239 prod_pyconf_path = src.find_file_in_lpath(product_name + ".pyconf",
240 config.PATHS.PRODUCTPATH)
241 if not prod_pyconf_path:
243 No definition found for the product %(1)s.
244 Please create a %(1)s.pyconf file somewhere in:
247 "2": PP.pformat(config.PATHS.PRODUCTPATH) }
250 No definition corresponding to the version %(1)s was found in the file:
252 Please add a section in it.""") % {"1" : vv, "2" : prod_pyconf_path}
253 raise src.SatException(msg)
255 # Set the debug, dev and version keys
256 prod_info.debug = debug
257 prod_info.verbose = verbose
260 prod_info.version = version
262 # Set the archive_info if the product is get in archive mode
263 if prod_info.get_source == "archive":
264 if not "archive_info" in prod_info:
265 prod_info.addMapping("archive_info",
266 src.pyconf.Mapping(prod_info),
268 if "archive_name" in prod_info.archive_info:
269 arch_name = prod_info.archive_info.archive_name
272 arch_name = product_name + "-" + version + ".tar.gz"
274 arch_path = src.find_file_in_lpath(arch_name,
275 config.PATHS.ARCHIVEPATH)
277 # arch_path is not found. It may generate an error in sat source,
278 # unless the archive is found in ftp serveur
279 msg = _("Archive %(1)s for %(2)s not found in config.PATHS.ARCHIVEPATH") % \
280 {"1" : arch_name, "2" : prod_info.name}
281 DBG.tofix(msg, config.PATHS.ARCHIVEPATH)
282 prod_info.archive_info.archive_name = arch_name #without path
284 prod_info.archive_info.archive_name = arch_path
287 # If the product compiles with a script, check the script existence
288 # and if it is executable
289 if product_has_script(prod_info):
290 # Check the compil_script key existence
291 if "compil_script" not in prod_info:
293 No compilation script found for the product %s.
294 Please provide a 'compil_script' key in its definition.""") % product_name
295 raise src.SatException(msg)
297 # Get the path of the script file
298 # if windows supposed '.bat', if linux supposed '.sh'
299 # but user set extension script file in his pyconf as he wants, no obligation.
300 script = prod_info.compil_script
301 script_name = os.path.basename(script)
302 if script == script_name:
303 # Only a name is given. Search in the default directory
304 script_path = src.find_file_in_lpath(script_name, config.PATHS.PRODUCTPATH, "compil_scripts")
306 msg = _("Compilation script %s not found in") % script_name
307 DBG.tofix(msg, config.PATHS.PRODUCTPATH, True) # say where searched
308 script_path = "%s_(Not_Found_by_Sat!!)" % script_name
309 prod_info.compil_script = script_path
312 # Check that the script is executable
313 if os.path.exists(prod_info.compil_script) and not os.access(prod_info.compil_script, os.X_OK):
314 DBG.tofix("Compilation script file is not in 'execute mode'", prod_info.compil_script, True)
316 # Get the full paths of all the patches
317 if product_has_patches(prod_info):
320 for patch in prod_info.patches:
322 # If only a filename, then search for the patch in the PRODUCTPATH
323 if os.path.basename(patch_path) == patch_path:
324 # Search in the PRODUCTPATH/patches
325 patch_path = src.find_file_in_lpath(patch,
326 config.PATHS.PRODUCTPATH,
329 msg = _("Patch %(patch_name)s for %(prod_name)s not found:"
330 "\n" % {"patch_name" : patch,
331 "prod_name" : prod_info.name})
332 raise src.SatException(msg)
333 patches.append(patch_path)
335 DBG.tofix("problem in prod_info.patches", prod_info)
336 prod_info.patches = patches
338 # Get the full paths of the environment scripts
339 if product_has_env_script(prod_info):
340 env_script_path = prod_info.environ.env_script
341 # If only a filename, then search for the environment script
342 # in the PRODUCTPATH/env_scripts
343 if os.path.basename(env_script_path) == env_script_path:
344 # Search in the PRODUCTPATH/env_scripts
345 env_script_path = src.find_file_in_lpath(
346 prod_info.environ.env_script,
347 config.PATHS.PRODUCTPATH,
349 if not env_script_path:
350 msg = _("Environment script %(env_name)s for %(prod_name)s not "
351 "found.\n" % {"env_name" : env_script_path,
352 "prod_name" : prod_info.name})
353 raise src.SatException(msg)
355 prod_info.environ.env_script = env_script_path
358 # The variable with_install_dir is at false only for internal use
359 # of the function get_install_dir
361 # Save the install_dir key if there is any
362 if "install_dir" in prod_info and not "install_dir_save" in prod_info:
363 prod_info.install_dir_save = prod_info.install_dir
365 # if it is not the first time the install_dir is computed, it means
366 # that install_dir_save exists and it has to be taken into account.
367 if "install_dir_save" in prod_info:
368 prod_info.install_dir = prod_info.install_dir_save
370 # Set the install_dir key
371 prod_info.install_dir = get_install_dir(config, base, version, prod_info)
375 def get_product_section(config, product_name, version, section=None, verbose=False):
376 """Get the product description from the configuration
378 :param config Config: The global configuration
379 :param product_name str: The product name
380 :param version str: The version of the product as 'V8_4_0', or else.
381 :param section str: The searched section (if not None, the section is
383 :return: The product description
387 # if section is not None, try to get the corresponding section
388 aProd = config.PRODUCTS[product_name]
390 versionMMP = VMMP.MinorMajorPatch(version)
391 except: # example setuptools raise "minor in major_minor_patch is not integer: '0_6c11'"
393 DBG.write("get_product_section for product %s '%s' as version '%s'" % (product_name, version, versionMMP),
394 (section, aProd.keys()), verbose)
395 # DBG.write("yoo1", aProd, True)
397 if section not in aProd:
399 # returns specific information for the given version
400 prod_info = aProd[section]
401 prod_info.section = section
402 prod_info.from_file = aProd.from_file
405 # If it exists, get the information of the product_version
406 # ex: 'version_V6_6_0' as salome version classical syntax
407 if "version_" + version in aProd:
408 DBG.write("found section for version_" + version, "", verbose)
409 # returns specific information for the given version
410 prod_info = aProd["version_" + version]
411 prod_info.section = "version_" + version
412 prod_info.from_file = aProd.from_file
415 # Else, check if there is a description for multiple versions
416 l_section_names = aProd.keys()
417 l_section_ranges = []
419 for name in l_section_names:
420 # DBG.write("name", name,True)
421 aRange = VMMP.getRange_majorMinorPatch(name)
422 if aRange is not None:
423 DBG.write("found version range for section '%s'" % name, aRange, verbose)
424 l_section_ranges.append((name, aRange))
426 if versionMMP is not None and len(l_section_ranges) > 0:
427 for name, (vmin, vmax) in l_section_ranges:
428 if versionMMP >= vmin and versionMMP <= vmax:
429 tagged.append((name, [vmin, vmax]))
432 DBG.write("multiple version ranges tagged for '%s', fix it" % version,
433 PP.pformat(tagged), True)
435 if len(tagged) == 1: # ok
436 DBG.write("one version range tagged for '%s'" % version,
437 PP.pformat(tagged), verbose)
438 name, (vmin, vmax) = tagged[0]
439 prod_info = aProd[name]
440 prod_info.section = name
441 prod_info.from_file = aProd.from_file
444 # Else, get the standard informations
445 if "default" in aProd:
446 # returns the generic information (given version not found)
447 prod_info = aProd.default
448 DBG.write("default tagged for '%s'" % version, prod_info, verbose)
449 prod_info.section = "default"
450 prod_info.from_file = aProd.from_file
453 # if noting was found, return None
456 def get_install_dir(config, base, version, prod_info):
457 """Compute the installation directory of a given product
459 :param config Config: The global configuration
460 :param base str: This corresponds to the value given by user in its
461 application.pyconf for the specific product. If "yes", the
462 user wants the product to be in base. If "no", he wants the
463 product to be in the application workdir
464 :param version str: The version of the product
465 :param product_info Config: The configuration specific to
468 :return: The path of the product installation
473 if (("install_dir" in prod_info and prod_info.install_dir == "base")
476 if (base == "no" or ("no_base" in config.APPLICATION
477 and config.APPLICATION.no_base == "yes")):
481 install_dir = get_base_install_dir(config, prod_info, version)
483 if "install_dir" not in prod_info or prod_info.install_dir == "base":
484 # Set it to the default value (in application directory)
485 install_dir = os.path.join(config.APPLICATION.workdir,
489 install_dir = prod_info.install_dir
493 def get_base_install_dir(config, prod_info, version):
494 """Compute the installation directory of a product in base
496 :param config Config: The global configuration
497 :param product_info Config: The configuration specific to
499 :param version str: The version of the product
500 :return: The path of the product installation
503 base_path = src.get_base_path(config)
504 prod_dir = os.path.join(base_path, prod_info.name + "-" + version)
505 if not os.path.exists(prod_dir):
506 return os.path.join(prod_dir, "config-1")
508 exists, install_dir = check_config_exists(config, prod_dir, prod_info)
512 # Find the first config-<i> directory that is available in the product
517 install_dir = os.path.join(prod_dir, "config-%i" % label)
518 if os.path.exists(install_dir):
525 def add_compile_config_file(p_info, config):
526 '''Execute the proper configuration command(s)
527 in the product build directory.
529 :param p_info Config: The specific config of the product
530 :param config Config: The global configuration
532 # Create the compile config
533 # DBG.write("add_compile_config_file", p_info, True)
534 res = src.pyconf.Config()
535 res.addMapping(p_info.name, src.pyconf.Mapping(res), "")
536 res[p_info.name]= p_info.version
538 for prod_name in p_info.depend:
539 if prod_name not in res:
540 res.addMapping(prod_name, src.pyconf.Mapping(res), "")
541 prod_dep_info = src.product.get_product_config(config, prod_name, False)
542 res[prod_name] = prod_dep_info.version
543 # Write it in the install directory of the product
544 # This file is for automatic reading/checking
545 # see check_config_exists method
546 aFile = os.path.join(p_info.install_dir, CONFIG_FILENAME)
547 with open(aFile, 'w') as f:
550 # this file is not mandatory, is for human eye reading
551 aFile = os.path.join(p_info.install_dir, PRODUCT_FILENAME)
553 with open(aFile, 'w') as f:
554 p_info.__save__(f, evaluated=True) # evaluated expressions mode
556 DBG.write("cannot evaluate product info - problem in file %s" % aFile, p_info, True)
557 # write DBG mode, as no problem if evaluation not possible
559 # Some informations cannot be evaluated.
561 # In the context of non VCS archives, information on git server is not available.
564 with open(aFile, 'w') as f:
566 f.write(DBG.getStrConfigDbg(p_info))
568 def check_config_exists(config, prod_dir, prod_info, verbose=False):
570 Verify that the installation directory of a product in a base exists.
571 Check all the config-<i>/sat-config.py files found for correspondence
572 with current config and prod_info depend-version-tags
574 :param config Config: The global configuration
575 :param prod_dir str: The product installation directory path
577 :param product_info Config: The configuration specific to
579 :return: True or false is the installation is found or not
580 and if it is found, the path of the found installation
581 :rtype: (boolean, str)
583 # check if the directories or files of the directory corresponds to the
584 # directory installation of the product
585 if os.path.isdir(prod_dir):
586 l_dir_and_files = os.listdir(prod_dir)
588 raise Exception("Inexisting directory '%s'" % prod_dir)
590 DBG.write("check_config_exists 000", (prod_dir, l_dir_and_files), verbose)
591 DBG.write("check_config_exists 111", prod_info, verbose)
593 for dir_or_file in l_dir_and_files:
594 oExpr = re.compile(config_expression)
595 if not(oExpr.search(dir_or_file)):
596 # in mode BASE, not config-<i>, not interesting
597 # DBG.write("not interesting", dir_or_file, True)
599 # check if there is the file sat-config.pyconf file in the installation
601 config_file = os.path.join(prod_dir, dir_or_file, CONFIG_FILENAME)
602 DBG.write("check_config_exists 222", config_file, verbose)
603 if not os.path.exists(config_file):
606 # check if there is the config described in the file corresponds the
607 # dependencies of the product
608 config_corresponds = True
609 compile_cfg = src.pyconf.Config(config_file)
610 for prod_dep in prod_info.depend:
611 # if the dependency is not in the config,
612 # the config does not correspond
613 if prod_dep not in compile_cfg:
614 config_corresponds = False
617 prod_dep_info = get_product_config(config, prod_dep, False)
618 # If the version of the dependency does not correspond,
619 # the config does not correspond
620 if prod_dep_info.version != compile_cfg[prod_dep]:
621 config_corresponds = False
624 if config_corresponds:
625 for prod_name in compile_cfg:
626 # assume new compatibility with prod_name in sat-config.pyconf files
627 if prod_name == prod_info.name:
628 if prod_info.version == compile_cfg[prod_name]:
629 DBG.write("check_config_exists OK 333", compile_cfg, verbose)
631 else: # no correspondence with newer with prod_name sat-config.pyconf files
632 config_corresponds = False
635 # as old compatibility without prod_name sat-config.pyconf files
636 if prod_name not in prod_info.depend:
637 # here there is an unexpected depend in an old compilation
638 config_corresponds = False
641 if config_corresponds: # returns (and stops) at first correspondence found
642 DBG.write("check_config_exists OK 444", dir_or_file, verbose)
643 return True, os.path.join(prod_dir, dir_or_file)
645 # no correspondence found
650 def get_products_infos(lproducts, config):
651 """Get the specific configuration of a list of products
653 :param lproducts List: The list of product names
654 :param config Config: The global configuration
655 :return: the list of tuples
656 (product name, specific configuration of the product)
657 :rtype: [(str, Config)]
660 # Loop on product names
661 for prod in lproducts:
662 # Get the specific configuration of the product
663 prod_info = get_product_config(config, prod)
664 if prod_info is not None:
665 products_infos.append((prod, prod_info))
667 msg = _("The %s product has no definition in the configuration.") % prod
668 raise src.SatException(msg)
669 return products_infos
672 def get_products_list(options, cfg, logger):
674 method that gives the product list with their informations from
675 configuration regarding the passed options.
677 :param options Options: The Options instance that stores the commands arguments
678 :param cfg Config: The global configuration
679 :param logger Logger: The logger instance to use for the display and logging
680 :return: The list of (product name, product_informations).
683 # Get the products to be prepared, regarding the options
684 if options.products is None:
685 # No options, get all products sources
686 products = cfg.APPLICATION.products
688 # if option --products, check that all products of the command line
689 # are present in the application.
690 """products = options.products
692 if p not in cfg.APPLICATION.products:
693 raise src.SatException(_("Product %(product)s "
694 "not defined in application %(application)s") %
695 { 'product': p, 'application': cfg.VARS.application} )"""
697 products = src.getProductNames(cfg, options.products, logger)
699 # Construct the list of tuple containing
700 # the products name and their definition
701 resAll = src.product.get_products_infos(products, cfg)
703 # if the property option was passed, filter the list
704 if options.properties: # existing properties
708 prop, value = options.properties # for example 'is_SALOME_module', 'yes'
709 for p_name, p_info in resAll:
711 if p_info.properties[prop] == value:
712 res.append((p_name, p_info))
719 if len(ok) != len(resAll):
720 logger.trace("on properties %s\n products accepted:\n %s\n products rejected:\n %s\n" %
721 (options.properties, PP.pformat(sorted(ok)), PP.pformat(sorted(ko))))
723 logger.warning("properties %s\n seems useless with no products rejected" %
724 (options.properties))
726 res = resAll # not existing properties as all accepted
731 def get_product_dependencies(config, product_info):
733 Get recursively the list of products that are
734 in the product_info dependencies
736 :param config Config: The global configuration
737 :param product_info Config: The configuration specific to
739 :return: the list of products in dependence
742 if "depend" not in product_info or product_info.depend == []:
745 for prod in product_info.depend:
746 if prod == product_info.name:
750 prod_info = get_product_config(config, prod)
751 dep_prod = get_product_dependencies(config, prod_info)
752 for prod_in_dep in dep_prod:
753 if prod_in_dep not in res:
754 res.append(prod_in_dep)
757 def check_installation(product_info):
759 Verify if a product is well installed. Checks install directory presence
760 and some additional files if it is defined in the config
762 :param product_info Config: The configuration specific to
764 :return: True if it is well installed
767 if not product_compiles(product_info):
769 install_dir = product_info.install_dir
770 if not os.path.exists(install_dir):
772 if ("present_files" in product_info and
773 "install" in product_info.present_files):
774 for file_relative_path in product_info.present_files.install:
775 file_path = os.path.join(install_dir, file_relative_path)
776 if not os.path.exists(file_path):
780 def check_source(product_info):
781 """Verify if a sources of product is preset. Checks source directory presence
783 :param product_info Config: The configuration specific to
785 :return: True if it is well installed
788 DBG.write("check_source product_info", product_info)
789 source_dir = product_info.source_dir
790 if not os.path.exists(source_dir):
792 if ("present_files" in product_info and
793 "source" in product_info.present_files):
794 for file_relative_path in product_info.present_files.source:
795 file_path = os.path.join(source_dir, file_relative_path)
796 if not os.path.exists(file_path):
800 def product_is_salome(product_info):
801 """Know if a product is a SALOME module
803 :param product_info Config: The configuration specific to
805 :return: True if the product is a SALOME module, else False
808 return ("properties" in product_info and
809 "is_SALOME_module" in product_info.properties and
810 product_info.properties.is_SALOME_module == "yes")
812 def product_is_fixed(product_info):
813 """Know if a product is fixed
815 :param product_info Config: The configuration specific to
817 :return: True if the product is fixed, else False
820 get_src = product_info.get_source
821 return get_src.lower() == 'fixed'
823 def product_is_native(product_info):
824 """Know if a product is native
826 :param product_info Config: The configuration specific to
828 :return: True if the product is native, else False
831 get_src = product_info.get_source
832 return get_src.lower() == 'native'
834 def product_is_dev(product_info):
835 """Know if a product is in dev mode
837 :param product_info Config: The configuration specific to
839 :return: True if the product is in dev mode, else False
842 dev = product_info.dev
843 res = (dev.lower() == 'yes')
844 DBG.write('product_is_dev %s' % product_info.name, res)
845 # if product_info.name == "XDATA": return True #test #10569
848 def product_is_hpc(product_info):
849 """Know if a product is in hpc mode
851 :param product_info Config: The configuration specific to
853 :return: True if the product is in hpc mode, else False
856 hpc = product_info.hpc
857 res = (hpc.lower() == 'yes')
860 def product_is_debug(product_info):
861 """Know if a product is in debug mode
863 :param product_info Config: The configuration specific to
865 :return: True if the product is in debug mode, else False
868 debug = product_info.debug
869 return debug.lower() == 'yes'
871 def product_is_verbose(product_info):
872 """Know if a product is in verbose mode
874 :param product_info Config: The configuration specific to
876 :return: True if the product is in verbose mode, else False
879 verbose = product_info.verbose
880 return verbose.lower() == 'yes'
882 def product_is_autotools(product_info):
883 """Know if a product is compiled using the autotools
885 :param product_info Config: The configuration specific to
887 :return: True if the product is autotools, else False
890 build_src = product_info.build_source
891 return build_src.lower() == 'autotools'
893 def product_is_cmake(product_info):
894 """Know if a product is compiled using the cmake
896 :param product_info Config: The configuration specific to
898 :return: True if the product is cmake, else False
901 build_src = product_info.build_source
902 return build_src.lower() == 'cmake'
904 def product_is_vcs(product_info):
905 """Know if a product is download using git, svn or cvs (not archive)
907 :param product_info Config: The configuration specific to
909 :return: True if the product is vcs, else False
912 return product_info.get_source in AVAILABLE_VCS
914 def product_is_smesh_plugin(product_info):
915 """Know if a product is a SMESH plugin
917 :param product_info Config: The configuration specific to
919 :return: True if the product is a SMESH plugin, else False
922 return ("properties" in product_info and
923 "smesh_plugin" in product_info.properties and
924 product_info.properties.smesh_plugin == "yes")
926 def product_is_cpp(product_info):
927 """Know if a product is cpp
929 :param product_info Config: The configuration specific to
931 :return: True if the product is a cpp, else False
934 return ("properties" in product_info and
935 "cpp" in product_info.properties and
936 product_info.properties.cpp == "yes")
938 def product_compiles(product_info):
940 Know if a product compiles or not
941 (some products do not have a compilation procedure)
943 :param product_info Config: The configuration specific to
945 :return: True if the product compiles, else False
948 return not("properties" in product_info and
949 "compilation" in product_info.properties and
950 product_info.properties.compilation == "no")
952 def product_has_script(product_info):
953 """Know if a product has a compilation script
955 :param product_info Config: The configuration specific to
957 :return: True if the product it has a compilation script, else False
960 if "build_source" not in product_info:
963 build_src = product_info.build_source
964 return build_src.lower() == 'script'
966 def product_has_env_script(product_info):
967 """Know if a product has an environment script
969 :param product_info Config: The configuration specific to
971 :return: True if the product it has an environment script, else False
974 return "environ" in product_info and "env_script" in product_info.environ
976 def product_has_patches(product_info):
977 """Know if a product has one or more patches
979 :param product_info Config: The configuration specific to
981 :return: True if the product has one or more patches
984 res = ( "patches" in product_info and len(product_info.patches) > 0 )
985 DBG.write('product_has_patches %s' % product_info.name, res)
986 # if product_info.name == "XDATA": return True #test #10569
989 def product_has_logo(product_info):
990 """Know if a product has a logo (YACSGEN generate)
992 :param product_info Config: The configuration specific to
994 :return: The path of the logo if the product has a logo, else False
997 if ("properties" in product_info and
998 "logo" in product_info.properties):
999 return product_info.properties.logo
1003 def product_has_licence(product_info, path):
1004 """Find out if a product has a licence
1006 :param product_info Config: The configuration specific to the product
1007 :param path Str: The path where to search for the licence
1008 :return: The name of the licence file (the complete path if it is found in the path, else the name, else False
1011 if ("properties" in product_info and
1012 "licence" in product_info.properties):
1013 licence_name = product_info.properties.licence
1015 # search for licence_name in path
1016 # a- consolidate the path into one signe string licence_path
1017 licence_path=path[0]
1018 for lpath in path[1:]:
1019 licence_path=licence_path+":"+lpath
1020 licence_path_list=licence_path.split(":")
1021 licence_fullname = src.find_file_in_lpath(licence_name, licence_path_list)
1022 if licence_fullname:
1023 return licence_fullname
1025 # if the search of licence in path failed, we return its name (not the full path)
1029 return False # product has no licence
1031 def product_has_salome_gui(product_info):
1032 """Know if a product has a SALOME gui
1034 :param product_info Config: The configuration specific to
1036 :return: True if the product has a SALOME gui, else False
1039 return ("properties" in product_info and
1040 "has_salome_gui" in product_info.properties and
1041 product_info.properties.has_salome_gui == "yes")
1043 def product_is_mpi(product_info):
1044 """Know if a product has openmpi in its dependencies
1046 :param product_info Config: The configuration specific to
1048 :return: True if the product has openmpi inits dependencies
1051 return "openmpi" in product_info.depend
1053 def product_is_generated(product_info):
1054 """Know if a product is generated (YACSGEN)
1056 :param product_info Config: The configuration specific to
1058 :return: True if the product is generated
1061 return ("properties" in product_info and
1062 "generate" in product_info.properties and
1063 product_info.properties.generate == "yes")
1065 def get_product_components(product_info):
1066 """Get the component list to generate with the product
1068 :param product_info Config: The configuration specific to
1070 :return: The list of names of the components
1074 if not product_is_generated(product_info):
1078 if "component_name" in product_info:
1079 compo_list = product_info.component_name
1081 if isinstance(compo_list, str):
1082 compo_list = [ compo_list ]