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
62 # if no version, then take the default one defined in the application
63 if isinstance(version, bool):
64 # in this case tag is mandatory, not debug, verbose, dev
65 version = config.APPLICATION.tag
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
73 if isinstance(version, src.pyconf.Mapping):
76 if not 'tag' in dic_version:
77 version = config.APPLICATION.tag
79 version = dic_version.tag
81 # Get the debug if any
82 if 'debug' in dic_version:
83 debug = dic_version.debug
84 elif 'debug' in config.APPLICATION:
85 debug = config.APPLICATION.debug
87 # Get the verbose if any
88 if 'verbose' in dic_version:
89 verbose = dic_version.verbose
90 elif 'verbose' in config.APPLICATION:
91 verbose = config.APPLICATION.verbose
94 if 'dev' in dic_version:
96 elif 'dev' in config.APPLICATION:
97 dev = config.APPLICATION.dev
100 if 'base' in dic_version:
101 base = dic_version.base
103 # Get the section if any
104 if 'section' in dic_version:
105 section = dic_version.section
107 # this case occur when version is overwritten, cf sat # 8897
108 if isinstance(version, dict):
109 dic_version = version
110 # Get the version/tag
111 if not 'tag' in dic_version:
112 version = config.APPLICATION.tag
114 version = dic_version["tag"]
116 # Get the debug if any
117 if 'debug' in dic_version:
118 debug = dic_version["debug"]
119 elif 'debug' in config.APPLICATION:
120 debug = config.APPLICATION.debug
122 # Get the verbose if any
123 if 'verbose' in dic_version:
124 verbose = dic_version["verbose"]
125 elif 'verbose' in config.APPLICATION:
126 verbose = config.APPLICATION.verbose
129 if 'dev' in dic_version:
130 dev = dic_version["dev"]
131 elif 'dev' in config.APPLICATION:
132 dev = config.APPLICATION.dev
134 # Get the base if any
135 if 'base' in dic_version:
136 base = dic_version["base"]
138 # Get the section if any
139 if 'section' in dic_version:
140 section = dic_version['section']
143 # substitute some character with _ in order to get the correct definition
144 # in config.PRODUCTS. This is done because the pyconf tool does not handle
145 # the . and - characters
146 for c in ".-": vv = vv.replace(c, "_")
149 if product_name in config.PRODUCTS:
150 # Search for the product description in the configuration
151 prod_info = get_product_section(config, product_name, vv, section)
153 # merge opt_depend in depend
154 if prod_info is not None and 'opt_depend' in prod_info:
155 for depend in prod_info.opt_depend:
156 if depend in config.APPLICATION.products:
157 prod_info.depend.append(depend,'')
159 # In case of a product get with a vcs,
160 # put the tag (equal to the version)
161 if prod_info is not None and prod_info.get_source in AVAILABLE_VCS:
163 if prod_info.get_source == 'git':
164 prod_info.git_info.tag = version
166 if prod_info.get_source == 'svn':
167 prod_info.svn_info.tag = version
169 if prod_info.get_source == 'cvs':
170 prod_info.cvs_info.tag = version
172 # In case of a fixed product,
173 # define the install_dir (equal to the version)
174 if prod_info is not None and \
175 (os.path.isdir(version) or version.startswith("/")):
176 # we consider a (fixed) path existing paths;
177 # or paths starting with '/' (the objective is to print a correct
178 # message to the user in case of non existing path.)
179 prod_info.install_dir = version
180 prod_info.get_source = "fixed"
182 # Check if the product is defined as native in the application
183 if prod_info is not None:
184 if version == "native":
185 prod_info.get_source = "native"
186 elif prod_info.get_source == "native":
187 msg = _("The product %(prod)s has version %(ver)s but is "
188 "declared as native in its definition" %
189 { 'prod': prod_info.name, 'ver': version})
190 raise src.SatException(msg)
192 # If there is no definition but the product is declared as native,
193 # construct a new definition containing only the get_source key
194 if prod_info is None and version == "native":
195 prod_info = src.pyconf.Config()
196 prod_info.name = product_name
197 prod_info.get_source = "native"
199 # If there is no definition but the product is fixed,
200 # construct a new definition containing only the product name
201 if prod_info is None and os.path.isdir(version):
202 prod_info = src.pyconf.Config()
203 prod_info.name = product_name
204 prod_info.get_source = "fixed"
205 prod_info.addMapping("environ", src.pyconf.Mapping(prod_info), "")
208 # If prod_info is still None, it means that there is no product definition
209 # in the config. The user has to provide it.
210 if prod_info is None:
211 prod_pyconf_path = src.find_file_in_lpath(product_name + ".pyconf",
212 config.PATHS.PRODUCTPATH)
213 if not prod_pyconf_path:
215 No definition found for the product %(1)s.
216 Please create a %(1)s.pyconf file somewhere in:
219 "2": PP.pformat(config.PATHS.PRODUCTPATH) }
222 No definition corresponding to the version %(1)s was found in the file:
224 Please add a section in it.""") % {"1" : vv, "2" : prod_pyconf_path}
225 raise src.SatException(msg)
227 # Set the debug, dev and version keys
228 prod_info.debug = debug
229 prod_info.verbose = verbose
231 prod_info.version = version
233 # Set the archive_info if the product is get in archive mode
234 if prod_info.get_source == "archive":
235 if not "archive_info" in prod_info:
236 prod_info.addMapping("archive_info",
237 src.pyconf.Mapping(prod_info),
239 if "archive_name" in prod_info.archive_info:
240 arch_name = prod_info.archive_info.archive_name
243 arch_name = product_name + "-" + version + ".tar.gz"
245 arch_path = src.find_file_in_lpath(arch_name,
246 config.PATHS.ARCHIVEPATH)
248 # arch_path is not found. It may generate an error in sat source,
249 # unless the archive is found in ftp serveur
250 msg = _("Archive %(1)s for %(2)s not found in config.PATHS.ARCHIVEPATH") % \
251 {"1" : arch_name, "2" : prod_info.name}
252 DBG.tofix(msg, config.PATHS.ARCHIVEPATH)
253 prod_info.archive_info.archive_name = arch_name #without path
255 prod_info.archive_info.archive_name = arch_path
258 # If the product compiles with a script, check the script existence
259 # and if it is executable
260 if product_has_script(prod_info):
261 # Check the compil_script key existence
262 if "compil_script" not in prod_info:
264 No compilation script found for the product %s.
265 Please provide a 'compil_script' key in its definition.""") % product_name
266 raise src.SatException(msg)
268 # Get the path of the script file
269 # if windows supposed '.bat', if linux supposed '.sh'
270 # but user set extension script file in his pyconf as he wants, no obligation.
271 script = prod_info.compil_script
272 script_name = os.path.basename(script)
273 if script == script_name:
274 # Only a name is given. Search in the default directory
275 script_path = src.find_file_in_lpath(script_name, config.PATHS.PRODUCTPATH, "compil_scripts")
277 msg = _("Compilation script %s not found in") % script_name
278 DBG.tofix(msg, config.PATHS.PRODUCTPATH, True) # say where searched
279 # avoid stop if sat prepare, script could be included in sources, only warning
280 # raise src.SatException(msg)
281 script_path = "*** Not Found: %s" % script_name
282 prod_info.compil_script = script_path
285 # Check that the script is executable
286 if os.path.exists(prod_info.compil_script) and not os.access(prod_info.compil_script, os.X_OK):
287 #raise src.SatException(
288 # _("Compilation script cannot be executed: %s") %
289 # prod_info.compil_script)
290 # just as warning, problem later...
291 DBG.tofix("Compilation script file is not in 'execute mode'", prod_info.compil_script, True)
293 # Get the full paths of all the patches
294 if product_has_patches(prod_info):
297 for patch in prod_info.patches:
299 # If only a filename, then search for the patch in the PRODUCTPATH
300 if os.path.basename(patch_path) == patch_path:
301 # Search in the PRODUCTPATH/patches
302 patch_path = src.find_file_in_lpath(patch,
303 config.PATHS.PRODUCTPATH,
306 msg = _("Patch %(patch_name)s for %(prod_name)s not found:"
307 "\n" % {"patch_name" : patch,
308 "prod_name" : prod_info.name})
309 raise src.SatException(msg)
310 patches.append(patch_path)
312 DBG.tofix("problem in prod_info.patches", prod_info)
313 prod_info.patches = patches
315 # Get the full paths of the environment scripts
316 if product_has_env_script(prod_info):
317 env_script_path = prod_info.environ.env_script
318 # If only a filename, then search for the environment script
319 # in the PRODUCTPATH/env_scripts
320 if os.path.basename(env_script_path) == env_script_path:
321 # Search in the PRODUCTPATH/env_scripts
322 env_script_path = src.find_file_in_lpath(
323 prod_info.environ.env_script,
324 config.PATHS.PRODUCTPATH,
326 if not env_script_path:
327 msg = _("Environment script %(env_name)s for %(prod_name)s not "
328 "found.\n" % {"env_name" : env_script_path,
329 "prod_name" : prod_info.name})
330 raise src.SatException(msg)
332 prod_info.environ.env_script = env_script_path
335 # The variable with_install_dir is at false only for internal use
336 # of the function get_install_dir
338 # Save the install_dir key if there is any
339 if "install_dir" in prod_info and not "install_dir_save" in prod_info:
340 prod_info.install_dir_save = prod_info.install_dir
342 # if it is not the first time the install_dir is computed, it means
343 # that install_dir_save exists and it has to be taken into account.
344 if "install_dir_save" in prod_info:
345 prod_info.install_dir = prod_info.install_dir_save
347 # Set the install_dir key
348 prod_info.install_dir = get_install_dir(config, base, version, prod_info)
352 def get_product_section(config, product_name, version, section=None, verbose=False):
353 """Get the product description from the configuration
355 :param config Config: The global configuration
356 :param product_name str: The product name
357 :param version str: The version of the product as 'V8_4_0', or else.
358 :param section str: The searched section (if not None, the section is
360 :return: The product description
364 # if section is not None, try to get the corresponding section
365 aProd = config.PRODUCTS[product_name]
367 versionMMP = VMMP.MinorMajorPatch(version)
368 except: # example setuptools raise "minor in major_minor_patch is not integer: '0_6c11'"
370 DBG.write("get_product_section for product %s '%s' as version '%s'" % (product_name, version, versionMMP),
371 (section, aProd.keys()), verbose)
372 # DBG.write("yoo1", aProd, True)
374 if section not in aProd:
376 # returns specific information for the given version
377 prod_info = aProd[section]
378 prod_info.section = section
379 prod_info.from_file = aProd.from_file
382 # If it exists, get the information of the product_version
383 # ex: 'version_V6_6_0' as salome version classical syntax
384 if "version_" + version in aProd:
385 DBG.write("found section for version_" + version, "", verbose)
386 # returns specific information for the given version
387 prod_info = aProd["version_" + version]
388 prod_info.section = "version_" + version
389 prod_info.from_file = aProd.from_file
392 # Else, check if there is a description for multiple versions
393 l_section_names = aProd.keys()
394 l_section_ranges = []
396 for name in l_section_names:
397 # DBG.write("name", name,True)
398 aRange = VMMP.getRange_majorMinorPatch(name)
399 if aRange is not None:
400 DBG.write("found version range for section '%s'" % name, aRange, verbose)
401 l_section_ranges.append((name, aRange))
403 if versionMMP is not None and len(l_section_ranges) > 0:
404 for name, (vmin, vmax) in l_section_ranges:
405 if versionMMP >= vmin and versionMMP <= vmax:
406 tagged.append((name, [vmin, vmax]))
409 DBG.write("multiple version ranges tagged for '%s', fix it" % version,
410 PP.pformat(tagged), True)
412 if len(tagged) == 1: # ok
413 DBG.write("one version range tagged for '%s'" % version,
414 PP.pformat(tagged), verbose)
415 name, (vmin, vmax) = tagged[0]
416 prod_info = aProd[name]
417 prod_info.section = name
418 prod_info.from_file = aProd.from_file
421 # Else, get the standard informations
422 if "default" in aProd:
423 # returns the generic information (given version not found)
424 prod_info = aProd.default
425 DBG.write("default tagged for '%s'" % version, prod_info, verbose)
426 prod_info.section = "default"
427 prod_info.from_file = aProd.from_file
430 # if noting was found, return None
433 def get_install_dir(config, base, version, prod_info):
434 """Compute the installation directory of a given product
436 :param config Config: The global configuration
437 :param base str: This corresponds to the value given by user in its
438 application.pyconf for the specific product. If "yes", the
439 user wants the product to be in base. If "no", he wants the
440 product to be in the application workdir
441 :param version str: The version of the product
442 :param product_info Config: The configuration specific to
445 :return: The path of the product installation
450 if (("install_dir" in prod_info and prod_info.install_dir == "base")
453 if (base == "no" or ("no_base" in config.APPLICATION
454 and config.APPLICATION.no_base == "yes")):
458 install_dir = get_base_install_dir(config, prod_info, version)
460 if "install_dir" not in prod_info or prod_info.install_dir == "base":
461 # Set it to the default value (in application directory)
462 install_dir = os.path.join(config.APPLICATION.workdir,
466 install_dir = prod_info.install_dir
470 def get_base_install_dir(config, prod_info, version):
471 """Compute the installation directory of a product in base
473 :param config Config: The global configuration
474 :param product_info Config: The configuration specific to
476 :param version str: The version of the product
477 :return: The path of the product installation
480 base_path = src.get_base_path(config)
481 prod_dir = os.path.join(base_path, prod_info.name + "-" + version)
482 if not os.path.exists(prod_dir):
483 return os.path.join(prod_dir, "config-1")
485 exists, install_dir = check_config_exists(config, prod_dir, prod_info)
489 # Find the first config-<i> directory that is available in the product
494 install_dir = os.path.join(prod_dir, "config-%i" % label)
495 if os.path.exists(install_dir):
502 def add_compile_config_file(p_info, config):
503 '''Execute the proper configuration command(s)
504 in the product build directory.
506 :param p_info Config: The specific config of the product
507 :param config Config: The global configuration
509 # Create the compile config
510 # DBG.write("add_compile_config_file", p_info, True)
511 res = src.pyconf.Config()
512 res.addMapping(p_info.name, src.pyconf.Mapping(res), "")
513 res[p_info.name]= p_info.version
515 for prod_name in p_info.depend:
516 if prod_name not in res:
517 res.addMapping(prod_name, src.pyconf.Mapping(res), "")
518 prod_dep_info = src.product.get_product_config(config, prod_name, False)
519 res[prod_name] = prod_dep_info.version
520 # Write it in the install directory of the product
521 # This file is for automatic reading/checking
522 # see check_config_exists method
523 aFile = os.path.join(p_info.install_dir, CONFIG_FILENAME)
524 with open(aFile, 'w') as f:
527 # this file is not mandatory, is for human eye reading
528 aFile = os.path.join(p_info.install_dir, PRODUCT_FILENAME)
530 with open(aFile, 'w') as f:
531 p_info.__save__(f, evaluated=True) # evaluated expressions mode
533 DBG.write("cannot evaluate product info - problem in file %s" % aFile, p_info, True)
534 # write DBG mode, as no problem if evaluation not possible
536 # Some informations cannot be evaluated.
538 # In the context of non VCS archives, information on git server is not available.
541 with open(aFile, 'w') as f:
543 f.write(DBG.getStrConfigDbg(p_info))
545 def check_config_exists(config, prod_dir, prod_info, verbose=False):
547 Verify that the installation directory of a product in a base exists.
548 Check all the config-<i>/sat-config.py files found for correspondence
549 with current config and prod_info depend-version-tags
551 :param config Config: The global configuration
552 :param prod_dir str: The product installation directory path
554 :param product_info Config: The configuration specific to
556 :return: True or false is the installation is found or not
557 and if it is found, the path of the found installation
558 :rtype: (boolean, str)
560 # check if the directories or files of the directory corresponds to the
561 # directory installation of the product
562 if os.path.isdir(prod_dir):
563 l_dir_and_files = os.listdir(prod_dir)
565 raise Exception("Inexisting directory '%s'" % prod_dir)
567 DBG.write("check_config_exists 000", (prod_dir, l_dir_and_files), verbose)
568 DBG.write("check_config_exists 111", prod_info, verbose)
570 for dir_or_file in l_dir_and_files:
571 oExpr = re.compile(config_expression)
572 if not(oExpr.search(dir_or_file)):
573 # in mode BASE, not config-<i>, not interesting
574 # DBG.write("not interesting", dir_or_file, True)
576 # check if there is the file sat-config.pyconf file in the installation
578 config_file = os.path.join(prod_dir, dir_or_file, CONFIG_FILENAME)
579 DBG.write("check_config_exists 222", config_file, verbose)
580 if not os.path.exists(config_file):
583 # check if there is the config described in the file corresponds the
584 # dependencies of the product
585 config_corresponds = True
586 compile_cfg = src.pyconf.Config(config_file)
587 for prod_dep in prod_info.depend:
588 # if the dependency is not in the config,
589 # the config does not correspond
590 if prod_dep not in compile_cfg:
591 config_corresponds = False
594 prod_dep_info = get_product_config(config, prod_dep, False)
595 # If the version of the dependency does not correspond,
596 # the config does not correspond
597 if prod_dep_info.version != compile_cfg[prod_dep]:
598 config_corresponds = False
601 if config_corresponds:
602 for prod_name in compile_cfg:
603 # assume new compatibility with prod_name in sat-config.pyconf files
604 if prod_name == prod_info.name:
605 if prod_info.version == compile_cfg[prod_name]:
606 DBG.write("check_config_exists OK 333", compile_cfg, verbose)
608 else: # no correspondence with newer with prod_name sat-config.pyconf files
609 config_corresponds = False
612 # as old compatibility without prod_name sat-config.pyconf files
613 if prod_name not in prod_info.depend:
614 # here there is an unexpected depend in an old compilation
615 config_corresponds = False
618 if config_corresponds: # returns (and stops) at first correspondence found
619 DBG.write("check_config_exists OK 444", dir_or_file, verbose)
620 return True, os.path.join(prod_dir, dir_or_file)
622 # no correspondence found
627 def get_products_infos(lproducts, config):
628 """Get the specific configuration of a list of products
630 :param lproducts List: The list of product names
631 :param config Config: The global configuration
632 :return: the list of tuples
633 (product name, specific configuration of the product)
634 :rtype: [(str, Config)]
637 # Loop on product names
638 for prod in lproducts:
639 # Get the specific configuration of the product
640 prod_info = get_product_config(config, prod)
641 if prod_info is not None:
642 products_infos.append((prod, prod_info))
644 msg = _("The %s product has no definition in the configuration.") % prod
645 raise src.SatException(msg)
646 return products_infos
649 def get_products_list(options, cfg, logger):
651 method that gives the product list with their informations from
652 configuration regarding the passed options.
654 :param options Options: The Options instance that stores the commands arguments
655 :param cfg Config: The global configuration
656 :param logger Logger: The logger instance to use for the display and logging
657 :return: The list of (product name, product_informations).
660 # Get the products to be prepared, regarding the options
661 if options.products is None:
662 # No options, get all products sources
663 products = cfg.APPLICATION.products
665 # if option --products, check that all products of the command line
666 # are present in the application.
667 """products = options.products
669 if p not in cfg.APPLICATION.products:
670 raise src.SatException(_("Product %(product)s "
671 "not defined in application %(application)s") %
672 { 'product': p, 'application': cfg.VARS.application} )"""
674 products = src.getProductNames(cfg, options.products, logger)
676 # Construct the list of tuple containing
677 # the products name and their definition
678 resAll = src.product.get_products_infos(products, cfg)
680 # if the property option was passed, filter the list
681 if options.properties: # existing properties
685 prop, value = options.properties # for example 'is_SALOME_module', 'yes'
686 for p_name, p_info in resAll:
688 if p_info.properties[prop] == value:
689 res.append((p_name, p_info))
696 if len(ok) != len(resAll):
697 logger.trace("on properties %s\n products accepted:\n %s\n products rejected:\n %s\n" %
698 (options.properties, PP.pformat(sorted(ok)), PP.pformat(sorted(ko))))
700 logger.warning("properties %s\n seems useless with no products rejected" %
701 (options.properties))
703 res = resAll # not existing properties as all accepted
708 def get_product_dependencies(config, product_info):
710 Get recursively the list of products that are
711 in the product_info dependencies
713 :param config Config: The global configuration
714 :param product_info Config: The configuration specific to
716 :return: the list of products in dependence
719 if "depend" not in product_info or product_info.depend == []:
722 for prod in product_info.depend:
723 if prod == product_info.name:
727 prod_info = get_product_config(config, prod)
728 dep_prod = get_product_dependencies(config, prod_info)
729 for prod_in_dep in dep_prod:
730 if prod_in_dep not in res:
731 res.append(prod_in_dep)
734 def check_installation(product_info):
736 Verify if a product is well installed. Checks install directory presence
737 and some additional files if it is defined in the config
739 :param product_info Config: The configuration specific to
741 :return: True if it is well installed
744 if not product_compiles(product_info):
746 install_dir = product_info.install_dir
747 if not os.path.exists(install_dir):
749 if ("present_files" in product_info and
750 "install" in product_info.present_files):
751 for file_relative_path in product_info.present_files.install:
752 file_path = os.path.join(install_dir, file_relative_path)
753 if not os.path.exists(file_path):
757 def check_source(product_info):
758 """Verify if a sources of product is preset. Checks source directory presence
760 :param product_info Config: The configuration specific to
762 :return: True if it is well installed
765 DBG.write("check_source product_info", product_info)
766 source_dir = product_info.source_dir
767 if not os.path.exists(source_dir):
769 if ("present_files" in product_info and
770 "source" in product_info.present_files):
771 for file_relative_path in product_info.present_files.source:
772 file_path = os.path.join(source_dir, file_relative_path)
773 if not os.path.exists(file_path):
777 def product_is_salome(product_info):
778 """Know if a product is a SALOME module
780 :param product_info Config: The configuration specific to
782 :return: True if the product is a SALOME module, else False
785 return ("properties" in product_info and
786 "is_SALOME_module" in product_info.properties and
787 product_info.properties.is_SALOME_module == "yes")
789 def product_is_fixed(product_info):
790 """Know if a product is fixed
792 :param product_info Config: The configuration specific to
794 :return: True if the product is fixed, else False
797 get_src = product_info.get_source
798 return get_src.lower() == 'fixed'
800 def product_is_native(product_info):
801 """Know if a product is native
803 :param product_info Config: The configuration specific to
805 :return: True if the product is native, else False
808 get_src = product_info.get_source
809 return get_src.lower() == 'native'
811 def product_is_dev(product_info):
812 """Know if a product is in dev mode
814 :param product_info Config: The configuration specific to
816 :return: True if the product is in dev mode, else False
819 dev = product_info.dev
820 res = (dev.lower() == 'yes')
821 DBG.write('product_is_dev %s' % product_info.name, res)
822 # if product_info.name == "XDATA": return True #test #10569
825 def product_is_debug(product_info):
826 """Know if a product is in debug mode
828 :param product_info Config: The configuration specific to
830 :return: True if the product is in debug mode, else False
833 debug = product_info.debug
834 return debug.lower() == 'yes'
836 def product_is_verbose(product_info):
837 """Know if a product is in verbose mode
839 :param product_info Config: The configuration specific to
841 :return: True if the product is in verbose mode, else False
844 verbose = product_info.verbose
845 return verbose.lower() == 'yes'
847 def product_is_autotools(product_info):
848 """Know if a product is compiled using the autotools
850 :param product_info Config: The configuration specific to
852 :return: True if the product is autotools, else False
855 build_src = product_info.build_source
856 return build_src.lower() == 'autotools'
858 def product_is_cmake(product_info):
859 """Know if a product is compiled using the cmake
861 :param product_info Config: The configuration specific to
863 :return: True if the product is cmake, else False
866 build_src = product_info.build_source
867 return build_src.lower() == 'cmake'
869 def product_is_vcs(product_info):
870 """Know if a product is download using git, svn or cvs (not archive)
872 :param product_info Config: The configuration specific to
874 :return: True if the product is vcs, else False
877 return product_info.get_source in AVAILABLE_VCS
879 def product_is_smesh_plugin(product_info):
880 """Know if a product is a SMESH plugin
882 :param product_info Config: The configuration specific to
884 :return: True if the product is a SMESH plugin, else False
887 return ("properties" in product_info and
888 "smesh_plugin" in product_info.properties and
889 product_info.properties.smesh_plugin == "yes")
891 def product_is_cpp(product_info):
892 """Know if a product is cpp
894 :param product_info Config: The configuration specific to
896 :return: True if the product is a cpp, else False
899 return ("properties" in product_info and
900 "cpp" in product_info.properties and
901 product_info.properties.cpp == "yes")
903 def product_compiles(product_info):
905 Know if a product compiles or not
906 (some products do not have a compilation procedure)
908 :param product_info Config: The configuration specific to
910 :return: True if the product compiles, else False
913 return not("properties" in product_info and
914 "compilation" in product_info.properties and
915 product_info.properties.compilation == "no")
917 def product_has_script(product_info):
918 """Know if a product has a compilation script
920 :param product_info Config: The configuration specific to
922 :return: True if the product it has a compilation script, else False
925 if "build_source" not in product_info:
928 build_src = product_info.build_source
929 return build_src.lower() == 'script'
931 def product_has_env_script(product_info):
932 """Know if a product has an environment script
934 :param product_info Config: The configuration specific to
936 :return: True if the product it has an environment script, else False
939 return "environ" in product_info and "env_script" in product_info.environ
941 def product_has_patches(product_info):
942 """Know if a product has one or more patches
944 :param product_info Config: The configuration specific to
946 :return: True if the product has one or more patches
949 res = ( "patches" in product_info and len(product_info.patches) > 0 )
950 DBG.write('product_has_patches %s' % product_info.name, res)
951 # if product_info.name == "XDATA": return True #test #10569
954 def product_has_logo(product_info):
955 """Know if a product has a logo (YACSGEN generate)
957 :param product_info Config: The configuration specific to
959 :return: The path of the logo if the product has a logo, else False
962 if ("properties" in product_info and
963 "logo" in product_info.properties):
964 return product_info.properties.logo
968 def product_has_licence(product_info, path):
969 """Find out if a product has a licence
971 :param product_info Config: The configuration specific to the product
972 :param path Str: The path where to search for the licence
973 :return: The name of the licence file (the complete path if it is found in the path, else the name, else False
976 if ("properties" in product_info and
977 "licence" in product_info.properties):
978 licence_name = product_info.properties.licence
980 # search for licence_name in path
981 # a- consolidate the path into one signe string licence_path
983 for lpath in path[1:]:
984 licence_path=licence_path+":"+lpath
985 licence_path_list=licence_path.split(":")
986 licence_fullname = src.find_file_in_lpath(licence_name, licence_path_list)
988 return licence_fullname
990 # if the search of licence in path failed, we return its name (not the full path)
994 return False # product has no licence
996 def product_has_salome_gui(product_info):
997 """Know if a product has a SALOME gui
999 :param product_info Config: The configuration specific to
1001 :return: True if the product has a SALOME gui, else False
1004 return ("properties" in product_info and
1005 "has_salome_gui" in product_info.properties and
1006 product_info.properties.has_salome_gui == "yes")
1008 def product_is_mpi(product_info):
1009 """Know if a product has openmpi in its dependencies
1011 :param product_info Config: The configuration specific to
1013 :return: True if the product has openmpi inits dependencies
1016 return "openmpi" in product_info.depend
1018 def product_is_generated(product_info):
1019 """Know if a product is generated (YACSGEN)
1021 :param product_info Config: The configuration specific to
1023 :return: True if the product is generated
1026 return ("properties" in product_info and
1027 "generate" in product_info.properties and
1028 product_info.properties.generate == "yes")
1030 def get_product_components(product_info):
1031 """Get the component list to generate with the product
1033 :param product_info Config: The configuration specific to
1035 :return: The list of names of the components
1039 if not product_is_generated(product_info):
1043 if "component_name" in product_info:
1044 compo_list = product_info.component_name
1046 if isinstance(compo_list, str):
1047 compo_list = [ compo_list ]