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']
33 config_expression = "^config-\d+$"
34 VERSION_DELIMITER = "_to_"
36 def get_product_config(config, product_name, with_install_dir=True):
37 """Get the specific configuration of a product from the global configuration
39 :param config Config: The global configuration
40 :param product_name str: The name of the product
41 :param with_install_dir boolean: If false, do not provide an install
42 directory (at false only for internal use
43 of the function check_config_exists)
44 :return: the specific configuration of the product
48 # Get the version of the product from the application definition
49 version = config.APPLICATION.products[product_name]
50 # if no version, then take the default one defined in the application
51 if isinstance(version, bool):
52 version = config.APPLICATION.tag
54 # Define debug and dev modes
55 # Get the tag if a dictionary is given in APPLICATION.products for the
62 if isinstance(version, src.pyconf.Mapping):
65 if not 'tag' in dic_version:
66 version = config.APPLICATION.tag
68 version = dic_version.tag
70 # Get the debug if any
71 if 'debug' in dic_version:
72 debug = dic_version.debug
74 # Get the verbose if any
75 if 'verbose' in dic_version:
76 verbose = dic_version.verbose
79 if 'dev' in dic_version:
83 if 'base' in dic_version:
84 base = dic_version.base
86 # Get the section if any
87 if 'section' in dic_version:
88 section = dic_version.section
91 # substitute some character with _ in order to get the correct definition
92 # in config.PRODUCTS. This is done because the pyconf tool does not handle
93 # the . and - characters
94 for c in ".-": vv = vv.replace(c, "_")
97 if product_name in config.PRODUCTS:
98 # Search for the product description in the configuration
99 prod_info = get_product_section(config, product_name, vv, section)
101 # merge opt_depend in depend
102 if prod_info is not None and 'opt_depend' in prod_info:
103 for depend in prod_info.opt_depend:
104 if depend in config.APPLICATION.products:
105 prod_info.depend.append(depend,'')
107 # In case of a product get with a vcs,
108 # put the tag (equal to the version)
109 if prod_info is not None and prod_info.get_source in AVAILABLE_VCS:
111 if prod_info.get_source == 'git':
112 prod_info.git_info.tag = version
114 if prod_info.get_source == 'svn':
115 prod_info.svn_info.tag = version
117 if prod_info.get_source == 'cvs':
118 prod_info.cvs_info.tag = version
120 # In case of a fixed product,
121 # define the install_dir (equal to the version)
122 if prod_info is not None and os.path.isdir(version):
123 prod_info.install_dir = version
124 prod_info.get_source = "fixed"
126 # Check if the product is defined as native in the application
127 if prod_info is not None:
128 if version == "native":
129 prod_info.get_source = "native"
130 elif prod_info.get_source == "native":
131 msg = _("The product %(prod)s has version %(ver)s but is "
132 "declared as native in its definition" %
133 { 'prod': prod_info.name, 'ver': version})
134 raise src.SatException(msg)
136 # If there is no definition but the product is declared as native,
137 # construct a new definition containing only the get_source key
138 if prod_info is None and version == "native":
139 prod_info = src.pyconf.Config()
140 prod_info.name = product_name
141 prod_info.get_source = "native"
143 # If there is no definition but the product is fixed,
144 # construct a new definition containing only the product name
145 if prod_info is None and os.path.isdir(version):
146 prod_info = src.pyconf.Config()
147 prod_info.name = product_name
148 prod_info.get_source = "fixed"
149 prod_info.addMapping("environ", src.pyconf.Mapping(prod_info), "")
152 # If prod_info is still None, it means that there is no product definition
153 # in the config. The user has to provide it.
154 if prod_info is None:
155 prod_pyconf_path = src.find_file_in_lpath(product_name + ".pyconf",
156 config.PATHS.PRODUCTPATH)
157 if not prod_pyconf_path:
159 No definition found for the product %(1)s.
160 Please create a %(2)s.pyconf file somewhere in:
164 "3": config.PATHS.PRODUCTPATH }
167 No definition corresponding to the version %(1)s was found in the file:
169 Please add a section in it.""") % {"1" : vv, "2" : prod_pyconf_path}
170 raise src.SatException(msg)
172 # Set the debug, dev and version keys
173 prod_info.debug = debug
174 prod_info.verbose = verbose
176 prod_info.version = version
178 # Set the archive_info if the product is get in archive mode
179 if prod_info.get_source == "archive":
180 if not "archive_info" in prod_info:
181 prod_info.addMapping("archive_info",
182 src.pyconf.Mapping(prod_info),
184 if "archive_name" not in prod_info.archive_info:
185 arch_name = product_name + "-" + version + ".tar.gz"
186 arch_path = src.find_file_in_lpath(arch_name,
187 config.PATHS.ARCHIVEPATH)
189 msg = _("Archive %(1)s for %(2)s not found in config.PATHS.ARCHIVEPATH") % \
190 {"1" : arch_name, "2" : prod_info.name}
191 DBG.tofix(msg, config.PATHS.ARCHIVEPATH)
192 prod_info.archive_info.archive_name = arch_name #without path
193 # raise src.SatException(msg) #may be a warning, continue #8646
195 prod_info.archive_info.archive_name = arch_path
197 if (os.path.basename(prod_info.archive_info.archive_name) ==
198 prod_info.archive_info.archive_name):
199 arch_name = prod_info.archive_info.archive_name
200 arch_path = src.find_file_in_lpath(
202 config.PATHS.ARCHIVEPATH)
204 msg = _("Archive %(1)s for %(2)s not found in config.PATHS.ARCHIVEPATH") % \
205 {"1" : arch_name, "2" : prod_info.name}
206 DBG.tofix(msg, config.PATHS.ARCHIVEPATH) #avoid 2 messages in compile
207 prod_info.archive_info.archive_name = arch_name #without path
208 # raise src.SatException(msg) #may be a warning, continue #8646
210 prod_info.archive_info.archive_name = arch_path
213 # If the product compiles with a script, check the script existence
214 # and if it is executable
215 if product_has_script(prod_info):
216 # Check the compil_script key existence
217 if "compil_script" not in prod_info:
219 No compilation script found for the product %s.
220 Please provide a 'compil_script' key in its definition.""") % product_name
221 raise src.SatException(msg)
223 # Get the path of the script file
224 # if windows supposed '.bat', if linux supposed '.sh'
225 # but user set extension script file in his pyconf as he wants, no obligation.
226 script = prod_info.compil_script
227 script_name = os.path.basename(script)
228 if script == script_name:
229 # Only a name is given. Search in the default directory
230 script_path = src.find_file_in_lpath(script_name, config.PATHS.PRODUCTPATH, "compil_scripts")
232 msg = _("Compilation script %s not found in") % script_name
233 DBG.tofix(msg, config.PATHS.PRODUCTPATH, True) # say where searched
234 # avoid stop if sat prepare, script could be included in sources, only warning
235 # raise src.SatException(msg)
236 script_path = "*** Not Found: %s" % script_name
237 prod_info.compil_script = script_path
240 # Check that the script is executable
241 if os.path.exists(prod_info.compil_script) and not os.access(prod_info.compil_script, os.X_OK):
242 #raise src.SatException(
243 # _("Compilation script cannot be executed: %s") %
244 # prod_info.compil_script)
245 # just as warning, problem later...
246 DBG.tofix("Compilation script file is not in 'execute mode'", prod_info.compil_script, True)
248 # Get the full paths of all the patches
249 if product_has_patches(prod_info):
252 for patch in prod_info.patches:
254 # If only a filename, then search for the patch in the PRODUCTPATH
255 if os.path.basename(patch_path) == patch_path:
256 # Search in the PRODUCTPATH/patches
257 patch_path = src.find_file_in_lpath(patch,
258 config.PATHS.PRODUCTPATH,
261 msg = _("Patch %(patch_name)s for %(prod_name)s not found:"
262 "\n" % {"patch_name" : patch,
263 "prod_name" : prod_info.name})
264 raise src.SatException(msg)
265 patches.append(patch_path)
267 DBG.tofix("problem in prod_info.patches", prod_info)
268 prod_info.patches = patches
270 # Get the full paths of the environment scripts
271 if product_has_env_script(prod_info):
272 env_script_path = prod_info.environ.env_script
273 # If only a filename, then search for the environment script
274 # in the PRODUCTPATH/env_scripts
275 if os.path.basename(env_script_path) == env_script_path:
276 # Search in the PRODUCTPATH/env_scripts
277 env_script_path = src.find_file_in_lpath(
278 prod_info.environ.env_script,
279 config.PATHS.PRODUCTPATH,
281 if not env_script_path:
282 msg = _("Environment script %(env_name)s for %(prod_name)s not "
283 "found.\n" % {"env_name" : env_script_path,
284 "prod_name" : prod_info.name})
285 raise src.SatException(msg)
287 prod_info.environ.env_script = env_script_path
290 # The variable with_install_dir is at false only for internal use
291 # of the function get_install_dir
293 # Save the install_dir key if there is any
294 if "install_dir" in prod_info and not "install_dir_save" in prod_info:
295 prod_info.install_dir_save = prod_info.install_dir
297 # if it is not the first time the install_dir is computed, it means
298 # that install_dir_save exists and it has to be taken into account.
299 if "install_dir_save" in prod_info:
300 prod_info.install_dir = prod_info.install_dir_save
302 # Set the install_dir key
303 prod_info.install_dir = get_install_dir(config, base, version, prod_info)
307 def get_product_section(config, product_name, version, section=None, verbose=False):
308 """Get the product description from the configuration
310 :param config Config: The global configuration
311 :param product_name str: The product name
312 :param version str: The version of the product as 'V8_4_0', or else.
313 :param section str: The searched section (if not None, the section is
315 :return: The product description
319 # if section is not None, try to get the corresponding section
320 aProd = config.PRODUCTS[product_name]
321 versionMMP = VMMP.MinorMajorPatch(version)
322 DBG.write("get_product_section for product %s '%s' as '%s'" % (product_name, version, versionMMP),
323 (section, aProd.keys()), verbose)
324 # DBG.write("yoo1", aProd, True)
326 if section not in aProd:
328 # returns specific information for the given version
329 prod_info = aProd[section]
330 prod_info.section = section
331 prod_info.from_file = aProd.from_file
334 # If it exists, get the information of the product_version
335 # ex: 'version_V6_6_0' as salome version classical syntax
336 if "version_" + version in aProd:
337 DBG.write("found section for version_" + version, "", verbose)
338 # returns specific information for the given version
339 prod_info = aProd["version_" + version]
340 prod_info.section = "version_" + version
341 prod_info.from_file = aProd.from_file
344 # Else, check if there is a description for multiple versions
345 l_section_names = aProd.keys()
346 l_section_ranges = []
347 for name in l_section_names:
348 # DBG.write("name", name,True)
349 aRange = VMMP.getRange_majorMinorPatch(name)
350 if aRange is not None:
351 DBG.write("found version range for section '%s'" % name, aRange, verbose)
352 l_section_ranges.append((name, aRange))
354 if len(l_section_ranges) > 0:
356 for name, (vmin, vmax) in l_section_ranges:
357 if versionMMP >= vmin and versionMMP <= vmax:
358 tagged.append((name, [vmin, vmax]))
361 DBG.write("multiple version ranges tagged for '%s', fix it" % version,
362 PP.pformat(tagged), True)
364 if len(tagged) == 1: # ok
365 DBG.write("one version range tagged for '%s'" % version,
366 PP.pformat(tagged), verbose)
367 name, (vmin, vmax) = tagged[0]
368 prod_info = aProd[name]
369 prod_info.section = name
370 prod_info.from_file = aProd.from_file
374 l_section_name = aProd.keys()
375 l_section_ranges = [section_name for section_name in l_section_name
376 if VERSION_DELIMITER in section_name]
377 for section_range in l_section_ranges:
378 minimum, maximum = section_range.split(VERSION_DELIMITER)
379 if (src.only_numbers(version) >= src.only_numbers(minimum)
380 and src.only_numbers(version) <= src.only_numbers(maximum)):
381 # returns specific information for the versions
382 prod_info = aProd[section_range]
383 prod_info.section = section_range
384 prod_info.from_file = aProd.from_file
388 # Else, get the standard informations
389 if "default" in aProd:
390 # returns the generic information (given version not found)
391 prod_info = aProd.default
392 DBG.write("default tagged for '%s'" % version, prod_info, verbose)
393 prod_info.section = "default"
394 prod_info.from_file = aProd.from_file
397 # if noting was found, return None
400 def get_install_dir(config, base, version, prod_info):
401 """Compute the installation directory of a given product
403 :param config Config: The global configuration
404 :param base str: This corresponds to the value given by user in its
405 application.pyconf for the specific product. If "yes", the
406 user wants the product to be in base. If "no", he wants the
407 product to be in the application workdir
408 :param version str: The version of the product
409 :param product_info Config: The configuration specific to
412 :return: The path of the product installation
417 if (("install_dir" in prod_info and prod_info.install_dir == "base")
420 if (base == "no" or ("no_base" in config.APPLICATION
421 and config.APPLICATION.no_base == "yes")):
425 install_dir = get_base_install_dir(config, prod_info, version)
427 if "install_dir" not in prod_info or prod_info.install_dir == "base":
428 # Set it to the default value (in application directory)
429 install_dir = os.path.join(config.APPLICATION.workdir,
433 install_dir = prod_info.install_dir
437 def get_base_install_dir(config, prod_info, version):
438 """Compute the installation directory of a product in base
440 :param config Config: The global configuration
441 :param product_info Config: The configuration specific to
443 :param version str: The version of the product
444 :return: The path of the product installation
447 base_path = src.get_base_path(config)
448 prod_dir = os.path.join(base_path, prod_info.name + "-" + version)
449 if not os.path.exists(prod_dir):
450 return os.path.join(prod_dir, "config-1")
452 exists, install_dir = check_config_exists(config, prod_dir, prod_info)
456 # Find the first config-<i> directory that is available in the product
461 install_dir = os.path.join(prod_dir, "config-%i" % label)
462 if os.path.exists(install_dir):
469 def check_config_exists(config, prod_dir, prod_info):
471 Verify that the installation directory of a product in a base exists
472 Check all the config-<i> directory and verify the sat-config.pyconf file
475 :param config Config: The global configuration
476 :param prod_dir str: The product installation directory path
478 :param product_info Config: The configuration specific to
480 :return: True or false is the installation is found or not
481 and if it is found, the path of the found installation
482 :rtype: (boolean, str)
484 # check if the directories or files of the directory corresponds to the
485 # directory installation of the product
486 l_dir_and_files = os.listdir(prod_dir)
487 for dir_or_file in l_dir_and_files:
488 oExpr = re.compile(config_expression)
489 if not(oExpr.search(dir_or_file)):
490 # not config-<i>, not interesting
492 # check if there is the file sat-config.pyconf file in the installation
494 config_file = os.path.join(prod_dir, dir_or_file, src.CONFIG_FILENAME)
495 if not os.path.exists(config_file):
498 # If there is no dependency, it is the right path
499 if len(prod_info.depend)==0:
500 compile_cfg = src.pyconf.Config(config_file)
501 if len(compile_cfg) == 0:
502 return True, os.path.join(prod_dir, dir_or_file)
505 # check if there is the config described in the file corresponds the
506 # dependencies of the product
507 config_corresponds = True
508 compile_cfg = src.pyconf.Config(config_file)
509 for prod_dep in prod_info.depend:
510 # if the dependency is not in the config,
511 # the config does not correspond
512 if prod_dep not in compile_cfg:
513 config_corresponds = False
516 prod_dep_info = get_product_config(config, prod_dep, False)
517 # If the version of the dependency does not correspond,
518 # the config does not correspond
519 if prod_dep_info.version != compile_cfg[prod_dep]:
520 config_corresponds = False
523 for prod_name in compile_cfg:
524 if prod_name not in prod_info.depend:
525 config_corresponds = False
528 if config_corresponds:
529 return True, os.path.join(prod_dir, dir_or_file)
535 def get_products_infos(lproducts, config):
536 """Get the specific configuration of a list of products
538 :param lproducts List: The list of product names
539 :param config Config: The global configuration
540 :return: the list of tuples
541 (product name, specific configuration of the product)
542 :rtype: [(str, Config)]
545 # Loop on product names
546 for prod in lproducts:
547 # Get the specific configuration of the product
548 prod_info = get_product_config(config, prod)
549 if prod_info is not None:
550 products_infos.append((prod, prod_info))
552 msg = _("The %s product has no definition in the configuration.") % prod
553 raise src.SatException(msg)
554 return products_infos
557 def get_products_list(options, cfg, logger):
559 method that gives the product list with their informations from
560 configuration regarding the passed options.
562 :param options Options: The Options instance that stores the commands arguments
563 :param cfg Config: The global configuration
564 :param logger Logger: The logger instance to use for the display and logging
565 :return: The list of (product name, product_informations).
568 # Get the products to be prepared, regarding the options
569 if options.products is None:
570 # No options, get all products sources
571 products = cfg.APPLICATION.products
573 # if option --products, check that all products of the command line
574 # are present in the application.
575 products = options.products
577 if p not in cfg.APPLICATION.products:
578 raise src.SatException(_("Product %(product)s "
579 "not defined in application %(application)s") %
580 { 'product': p, 'application': cfg.VARS.application} )
582 # Construct the list of tuple containing
583 # the products name and their definition
584 resAll = src.product.get_products_infos(products, cfg)
586 # if the property option was passed, filter the list
587 if options.properties: # existing properties
591 prop, value = options.properties # for example 'is_SALOME_module', 'yes'
592 for p_name, p_info in resAll:
594 if p_info.properties[prop] == value:
595 res.append((p_name, p_info))
602 if len(ok) != len(resAll):
603 logger.trace("on properties %s\n products accepted:\n %s\n products rejected:\n %s\n" %
604 (options.properties, PP.pformat(sorted(ok)), PP.pformat(sorted(ko))))
606 logger.warning("properties %s\n seems useless with no products rejected" %
607 (options.properties))
609 res = resAll # not existing properties as all accepted
615 for p_name, p_info in res:
617 if src.product.product_is_native(p_info) or src.product.product_is_fixed(p_info):
620 products_infos.append((p_name, p_info))
623 msg = "problem on 'is_native' or 'is_fixed' for product %s" % p_name
627 logger.warning("on is_native or is_fixed\n products accepted:\n %s\n products rejected:\n %s\n" %
628 (PP.pformat(sorted(ok)), PP.pformat(sorted(ko))))
630 logger.debug("products selected:\n %s\n" % PP.pformat(sorted(ok)))
635 def get_product_dependencies(config, product_info):
637 Get recursively the list of products that are
638 in the product_info dependencies
640 :param config Config: The global configuration
641 :param product_info Config: The configuration specific to
643 :return: the list of products in dependence
646 if "depend" not in product_info or product_info.depend == []:
649 for prod in product_info.depend:
650 if prod == product_info.name:
654 prod_info = get_product_config(config, prod)
655 dep_prod = get_product_dependencies(config, prod_info)
656 for prod_in_dep in dep_prod:
657 if prod_in_dep not in res:
658 res.append(prod_in_dep)
661 def check_installation(product_info):
663 Verify if a product is well installed. Checks install directory presence
664 and some additional files if it is defined in the config
666 :param product_info Config: The configuration specific to
668 :return: True if it is well installed
671 if not product_compiles(product_info):
673 install_dir = product_info.install_dir
674 if not os.path.exists(install_dir):
676 if ("present_files" in product_info and
677 "install" in product_info.present_files):
678 for file_relative_path in product_info.present_files.install:
679 file_path = os.path.join(install_dir, file_relative_path)
680 if not os.path.exists(file_path):
684 def check_source(product_info):
685 """Verify if a sources of product is preset. Checks source directory presence
687 :param product_info Config: The configuration specific to
689 :return: True if it is well installed
692 DBG.write("check_source product_info", product_info)
693 source_dir = product_info.source_dir
694 if not os.path.exists(source_dir):
696 if ("present_files" in product_info and
697 "source" in product_info.present_files):
698 for file_relative_path in product_info.present_files.source:
699 file_path = os.path.join(source_dir, file_relative_path)
700 if not os.path.exists(file_path):
704 def product_is_salome(product_info):
705 """Know if a product is a SALOME module
707 :param product_info Config: The configuration specific to
709 :return: True if the product is a SALOME module, else False
712 return ("properties" in product_info and
713 "is_SALOME_module" in product_info.properties and
714 product_info.properties.is_SALOME_module == "yes")
716 def product_is_fixed(product_info):
717 """Know if a product is fixed
719 :param product_info Config: The configuration specific to
721 :return: True if the product is fixed, else False
724 get_src = product_info.get_source
725 return get_src.lower() == 'fixed'
727 def product_is_native(product_info):
728 """Know if a product is native
730 :param product_info Config: The configuration specific to
732 :return: True if the product is native, else False
735 get_src = product_info.get_source
736 return get_src.lower() == 'native'
738 def product_is_dev(product_info):
739 """Know if a product is in dev mode
741 :param product_info Config: The configuration specific to
743 :return: True if the product is in dev mode, else False
746 dev = product_info.dev
747 res = (dev.lower() == 'yes')
748 DBG.write('product_is_dev %s' % product_info.name, res)
749 # if product_info.name == "XDATA": return True #test #10569
752 def product_is_debug(product_info):
753 """Know if a product is in debug mode
755 :param product_info Config: The configuration specific to
757 :return: True if the product is in debug mode, else False
760 debug = product_info.debug
761 return debug.lower() == 'yes'
763 def product_is_verbose(product_info):
764 """Know if a product is in verbose mode
766 :param product_info Config: The configuration specific to
768 :return: True if the product is in verbose mode, else False
771 verbose = product_info.verbose
772 return verbose.lower() == 'yes'
774 def product_is_autotools(product_info):
775 """Know if a product is compiled using the autotools
777 :param product_info Config: The configuration specific to
779 :return: True if the product is autotools, else False
782 build_src = product_info.build_source
783 return build_src.lower() == 'autotools'
785 def product_is_cmake(product_info):
786 """Know if a product is compiled using the cmake
788 :param product_info Config: The configuration specific to
790 :return: True if the product is cmake, else False
793 build_src = product_info.build_source
794 return build_src.lower() == 'cmake'
796 def product_is_vcs(product_info):
797 """Know if a product is download using git, svn or cvs (not archive)
799 :param product_info Config: The configuration specific to
801 :return: True if the product is vcs, else False
804 return product_info.get_source in AVAILABLE_VCS
806 def product_is_smesh_plugin(product_info):
807 """Know if a product is a SMESH plugin
809 :param product_info Config: The configuration specific to
811 :return: True if the product is a SMESH plugin, else False
814 return ("properties" in product_info and
815 "smesh_plugin" in product_info.properties and
816 product_info.properties.smesh_plugin == "yes")
818 def product_is_cpp(product_info):
819 """Know if a product is cpp
821 :param product_info Config: The configuration specific to
823 :return: True if the product is a cpp, else False
826 return ("properties" in product_info and
827 "cpp" in product_info.properties and
828 product_info.properties.cpp == "yes")
830 def product_compiles(product_info):
832 Know if a product compiles or not
833 (some products do not have a compilation procedure)
835 :param product_info Config: The configuration specific to
837 :return: True if the product compiles, else False
840 return not("properties" in product_info and
841 "compilation" in product_info.properties and
842 product_info.properties.compilation == "no")
844 def product_has_script(product_info):
845 """Know if a product has a compilation script
847 :param product_info Config: The configuration specific to
849 :return: True if the product it has a compilation script, else False
852 if "build_source" not in product_info:
855 build_src = product_info.build_source
856 return build_src.lower() == 'script'
858 def product_has_env_script(product_info):
859 """Know if a product has an environment script
861 :param product_info Config: The configuration specific to
863 :return: True if the product it has an environment script, else False
866 return "environ" in product_info and "env_script" in product_info.environ
868 def product_has_patches(product_info):
869 """Know if a product has one or more patches
871 :param product_info Config: The configuration specific to
873 :return: True if the product has one or more patches
876 res = ( "patches" in product_info and len(product_info.patches) > 0 )
877 DBG.write('product_has_patches %s' % product_info.name, res)
878 # if product_info.name == "XDATA": return True #test #10569
881 def product_has_logo(product_info):
882 """Know if a product has a logo (YACSGEN generate)
884 :param product_info Config: The configuration specific to
886 :return: The path of the logo if the product has a logo, else False
889 if ("properties" in product_info and
890 "logo" in product_info.properties):
891 return product_info.properties.logo
895 def product_has_salome_gui(product_info):
896 """Know if a product has a SALOME gui
898 :param product_info Config: The configuration specific to
900 :return: True if the product has a SALOME gui, else False
903 return ("properties" in product_info and
904 "has_salome_gui" in product_info.properties and
905 product_info.properties.has_salome_gui == "yes")
907 def product_is_mpi(product_info):
908 """Know if a product has openmpi in its dependencies
910 :param product_info Config: The configuration specific to
912 :return: True if the product has openmpi inits dependencies
915 return "openmpi" in product_info.depend
917 def product_is_generated(product_info):
918 """Know if a product is generated (YACSGEN)
920 :param product_info Config: The configuration specific to
922 :return: True if the product is generated
925 return ("properties" in product_info and
926 "generate" in product_info.properties and
927 product_info.properties.generate == "yes")
929 def get_product_components(product_info):
930 """Get the component list to generate with the product
932 :param product_info Config: The configuration specific to
934 :return: The list of names of the components
938 if not product_is_generated(product_info):
942 if "component_name" in product_info:
943 compo_list = product_info.component_name
945 if isinstance(compo_list, str):
946 compo_list = [ compo_list ]