From e06d9a603359f19e1d1ac5af37a6579b49691f75 Mon Sep 17 00:00:00 2001 From: Christian Van Wambeke Date: Tue, 6 Nov 2018 11:05:32 +0100 Subject: [PATCH] imp #12887 create sat-config.pyconf and sat-product.pyconf --- commands/compile.py | 27 ++----------- src/__init__.py | 2 - src/product.py | 95 ++++++++++++++++++++++++++++++++++++--------- src/pyconf.py | 33 +++++++++------- 4 files changed, 98 insertions(+), 59 deletions(-) diff --git a/commands/compile.py b/commands/compile.py index 67209bb..4cb7586 100644 --- a/commands/compile.py +++ b/commands/compile.py @@ -282,7 +282,9 @@ def compile_all_products(sat, config, options, products_infos, logger): batch=True, verbose=0, logger_add_link = logger) - + + # DBG.write("Only for test of check_config_exists", src.product.check_config_exists(config, "/volatile/wambeke/SAT5/MATIX_V24_S840/INSTALL/PACKAGESPY", p_info, verbose=True), True) + # Clean the the install directory # if the corresponding option was called if options.clean_install and not options.clean_all: @@ -463,7 +465,7 @@ def compile_product(sat, p_name_info, config, options, logger, header, len_end): # product that have been successfully compiled if res==0: logger.write(_("Add the config file in installation directory\n"), 5) - add_compile_config_file(p_info, config) + src.product.add_compile_config_file(p_info, config) if options.check: # Do the unit tests (call the check command) @@ -591,27 +593,6 @@ def compile_product_script(sat, return res, len_end_line, error_step -def add_compile_config_file(p_info, config): - '''Execute the proper configuration command(s) - in the product build directory. - - :param p_info Config: The specific config of the product - :param config Config: The global configuration - ''' - # Create the compile config - compile_cfg = src.pyconf.Config() - for prod_name in p_info.depend: - if prod_name not in compile_cfg: - compile_cfg.addMapping(prod_name, - src.pyconf.Mapping(compile_cfg), - "") - prod_dep_info = src.product.get_product_config(config, prod_name, False) - compile_cfg[prod_name] = prod_dep_info.version - # Write it in the install directory of the product - compile_cfg_path = os.path.join(p_info.install_dir, src.CONFIG_FILENAME) - f = open(compile_cfg_path, 'w') - compile_cfg.__save__(f) - f.close() def description(): '''method that is called when salomeTools is called with --help option. diff --git a/src/__init__.py b/src/__init__.py index f2ad0ec..789e230 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -52,8 +52,6 @@ NA_STATUS = "NA" KNOWNFAILURE_STATUS = "KF" TIMEOUT_STATUS = "TIMEOUT" -CONFIG_FILENAME = "sat-config.pyconf" - class SatException(Exception): """rename Exception Class""" pass diff --git a/src/product.py b/src/product.py index f139b7c..f1fa34b 100644 --- a/src/product.py +++ b/src/product.py @@ -30,8 +30,10 @@ import src.debug as DBG import src.versionMinorMajorPatch as VMMP AVAILABLE_VCS = ['git', 'svn', 'cvs'] + +CONFIG_FILENAME = "sat-config.pyconf" # trace product depends version(s) +PRODUCT_FILENAME = "sat-product.pyconf" # trace product compile config config_expression = "^config-\d+$" -VERSION_DELIMITER = "_to_" def get_product_config(config, product_name, with_install_dir=True): """Get the specific configuration of a product from the global configuration @@ -44,7 +46,7 @@ def get_product_config(config, product_name, with_install_dir=True): :return: the specific configuration of the product :rtype: Config """ - + # Get the version of the product from the application definition version = config.APPLICATION.products[product_name] # if no version, then take the default one defined in the application @@ -92,7 +94,7 @@ def get_product_config(config, product_name, with_install_dir=True): # in config.PRODUCTS. This is done because the pyconf tool does not handle # the . and - characters for c in ".-": vv = vv.replace(c, "_") - + prod_info = None if product_name in config.PRODUCTS: # Search for the product description in the configuration @@ -173,7 +175,7 @@ Please add a section in it.""") % {"1" : vv, "2" : prod_pyconf_path} prod_info.verbose = verbose prod_info.dev = dev prod_info.version = version - + # Set the archive_info if the product is get in archive mode if prod_info.get_source == "archive": if not "archive_info" in prod_info: @@ -453,11 +455,43 @@ def get_base_install_dir(config, prod_info, version): return install_dir -def check_config_exists(config, prod_dir, prod_info): +def add_compile_config_file(p_info, config): + '''Execute the proper configuration command(s) + in the product build directory. + + :param p_info Config: The specific config of the product + :param config Config: The global configuration + ''' + # Create the compile config + # DBG.write("add_compile_config_file", p_info, True) + res = src.pyconf.Config() + res.addMapping(p_info.name, src.pyconf.Mapping(res), "") + res[p_info.name]= p_info.version + + for prod_name in p_info.depend: + if prod_name not in res: + res.addMapping(prod_name, src.pyconf.Mapping(res), "") + prod_dep_info = src.product.get_product_config(config, prod_name, False) + res[prod_name] = prod_dep_info.version + # Write it in the install directory of the product + # This file is for automatic reading/checking + # see check_config_exists method + aFile = os.path.join(p_info.install_dir, CONFIG_FILENAME) + with open(aFile, 'w') as f: + res.__save__(f) + + # this file is for human eye reading + aFile = os.path.join(p_info.install_dir, PRODUCT_FILENAME) + with open(aFile, 'w') as f: + # f.write(DBG.getStrConfigDbg(p_info)) # debug mode + p_info.__save__(f, evaluated=True) # evaluated expressions mode + + +def check_config_exists(config, prod_dir, prod_info, verbose=False): """\ - Verify that the installation directory of a product in a base exists - Check all the config- directory and verify the sat-config.pyconf file - that is in it + Verify that the installation directory of a product in a base exists. + Check all the config-/sat-config.py files found for correspondence + with current config and prod_info depend-version-tags :param config Config: The global configuration :param prod_dir str: The product installation directory path @@ -467,18 +501,27 @@ def check_config_exists(config, prod_dir, prod_info): :return: True or false is the installation is found or not and if it is found, the path of the found installation :rtype: (boolean, str) - """ - # check if the directories or files of the directory corresponds to the + """ + # check if the directories or files of the directory corresponds to the # directory installation of the product - l_dir_and_files = os.listdir(prod_dir) + if os.path.isdir(prod_dir): + l_dir_and_files = os.listdir(prod_dir) + else: + raise Exception("Inexisting directory '%s'" % prod_dir) + + DBG.write("check_config_exists 000", (prod_dir, l_dir_and_files), verbose) + DBG.write("check_config_exists 111", prod_info, verbose) + for dir_or_file in l_dir_and_files: oExpr = re.compile(config_expression) if not(oExpr.search(dir_or_file)): - # not config-, not interesting + # in mode BASE, not config-, not interesting + # DBG.write("not interesting", dir_or_file, True) continue # check if there is the file sat-config.pyconf file in the installation # directory - config_file = os.path.join(prod_dir, dir_or_file, src.CONFIG_FILENAME) + config_file = os.path.join(prod_dir, dir_or_file, CONFIG_FILENAME) + DBG.write("check_config_exists 222", config_file, verbose) if not os.path.exists(config_file): continue @@ -488,7 +531,7 @@ def check_config_exists(config, prod_dir, prod_info): if len(compile_cfg) == 0: return True, os.path.join(prod_dir, dir_or_file) continue - + # check if there is the config described in the file corresponds the # dependencies of the product config_corresponds = True @@ -506,15 +549,29 @@ def check_config_exists(config, prod_dir, prod_info): if prod_dep_info.version != compile_cfg[prod_dep]: config_corresponds = False break - - for prod_name in compile_cfg: - if prod_name not in prod_info.depend: + + if config_corresponds: + for prod_name in compile_cfg: + # assume new compatibility with prod_name in sat-config.pyconf files + if prod_name == prod_info.name: + if prod_info.version == compile_cfg[prod_name]: + DBG.write("check_config_exists OK 333", compile_cfg, verbose) + pass + else: # no correspondence with newer with prod_name sat-config.pyconf files + config_corresponds = False + break + else: + # as old compatibility without prod_name sat-config.pyconf files + if prod_name not in prod_info.depend: + # here there is an unexpected depend in an old compilation config_corresponds = False break - if config_corresponds: + if config_corresponds: # returns (and stops) at first correspondence found + DBG.write("check_config_exists OK 444", dir_or_file, verbose) return True, os.path.join(prod_dir, dir_or_file) - + + # no correspondence found return False, None diff --git a/src/pyconf.py b/src/pyconf.py index 68b9174..7f2838f 100644 --- a/src/pyconf.py +++ b/src/pyconf.py @@ -416,7 +416,7 @@ class Container(object): item = item.evaluate(self) return item - def writeToStream(self, stream, indent, container): + def writeToStream(self, stream, indent, container, evaluated=False): """ Write this instance to a stream at the specified indentation level. @@ -432,13 +432,16 @@ class Container(object): """ raise NotImplementedError - def writeValue(self, value, stream, indent): + def writeValue(self, value, stream, indent, evaluated=False): if isinstance(self, Mapping): indstr = ' ' else: indstr = indent * ' ' if isinstance(value, Reference) or isinstance(value, Expression): - stream.write('%s%r%s' % (indstr, value, NEWLINE)) + if not evaluated: + stream.write('%s%r%s' % (indstr, value, NEWLINE)) + else: + stream.write('%s%r%s' % (indstr, self.evaluate(value), NEWLINE)) else: if isinstance(value, str): # and not isWord(value): value = repr(value) @@ -573,7 +576,7 @@ class Mapping(Container): order = object.__getattribute__(self, 'order') return order.__iter__() - def writeToStream(self, stream, indent, container): + def writeToStream(self, stream, indent, container, evaluated=False): """ Write this instance to a stream at the specified indentation level. @@ -593,10 +596,10 @@ class Mapping(Container): if isinstance(container, Mapping): stream.write(NEWLINE) stream.write('%s{%s' % (indstr, NEWLINE)) - self.__save__(stream, indent + 1) + self.__save__(stream, indent + 1, evaluated=evaluated) stream.write('%s}%s' % (indstr, NEWLINE)) - def __save__(self, stream, indent=0): + def __save__(self, stream, indent=0, evaluated=False): """ Save this configuration to the specified stream. @param stream: A stream to which the configuration is written. @@ -621,9 +624,9 @@ class Mapping(Container): stream.write('%s%-*s :' % (indstr, maxlen, skey)) value = data[key] if isinstance(value, Container): - value.writeToStream(stream, indent, self) + value.writeToStream(stream, indent, self, evaluated=evaluated) else: - self.writeValue(value, stream, indent) + self.writeValue(value, stream, indent, evaluated=evaluated) class Config(Mapping): """ @@ -724,7 +727,7 @@ class Config(Mapping): else: delattr(namespaces[0], name) - def __save__(self, stream, indent=0, no_close=False): + def __save__(self, stream, indent=0, no_close=False, evaluated=False): """ Save this configuration to the specified stream. The stream is closed if this is the top-level configuration in the hierarchy. @@ -734,7 +737,7 @@ class Config(Mapping): @param indent: The indentation level for the output. @type indent: int """ - Mapping.__save__(self, stream, indent) + Mapping.__save__(self, stream, indent, evaluated=evaluated) if indent == 0 and not no_close: stream.close() @@ -837,7 +840,7 @@ class Sequence(Container): def __len__(self): return len(object.__getattribute__(self, 'data')) - def writeToStream(self, stream, indent, container): + def writeToStream(self, stream, indent, container, evaluated=False): """ Write this instance to a stream at the specified indentation level. @@ -857,10 +860,10 @@ class Sequence(Container): if isinstance(container, Mapping): stream.write(NEWLINE) stream.write('%s[%s' % (indstr, NEWLINE)) - self.__save__(stream, indent + 1) + self.__save__(stream, indent + 1, evaluated=evaluated) stream.write('%s]%s' % (indstr, NEWLINE)) - def __save__(self, stream, indent): + def __save__(self, stream, indent, evaluated=False): """ Save this instance to the specified stream. @param stream: A stream to which the configuration is written. @@ -879,9 +882,9 @@ class Sequence(Container): if comment: stream.write('%s#%s' % (indstr, comment)) if isinstance(value, Container): - value.writeToStream(stream, indent, self) + value.writeToStream(stream, indent, self, evaluated=evaluated) else: - self.writeValue(value, stream, indent) + self.writeValue(value, stream, indent, evaluated=evaluated) class Reference(object): """ -- 2.39.2