From d1c1ebc196107b1c109f652f087e843bd68813ae Mon Sep 17 00:00:00 2001 From: Frantisek Hrbata Date: Thu, 29 Jun 2023 09:56:58 +0200 Subject: [PATCH] fix(test_submodules.py): don't rely on submodule init Current version of the test is using "git-submodule foreach", which requires submodules to be initialized. Non-initialized submodules are ignored. Our CI is not performing submodule initialization, but instead it only downloads the submodule content in tools/ci/ci_fetch_submodule.py from cache and copies it into the submodule path. Since we already know the submodule path from .gitconfig, we can use it as argument to git-ls-tree and avoid calling git-submodule at all. This allows to perform the test even if the submodules are not initialization and also it makes the code simpler. Signed-off-by: Frantisek Hrbata --- tools/test_sbom/test_submodules.py | 67 +++++++++++++++--------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/tools/test_sbom/test_submodules.py b/tools/test_sbom/test_submodules.py index 364dabb9fd..7d284c52e3 100644 --- a/tools/test_sbom/test_submodules.py +++ b/tools/test_sbom/test_submodules.py @@ -14,57 +14,58 @@ def get_gitwdir(): # type: () -> str return run_cmd(['git', 'rev-parse', '--show-toplevel']) -def get_submodules_info(): # type () -> list[dict[str,str]] - """Return list of submodules, where each submodule is represented - as dictionary with name, path and hash keys.""" - cmd = ['git', 'submodule', '--quiet', 'foreach','echo "$name,$sm_path,$sha1"'] - out = run_cmd(cmd) - submodules = [] - for line in out.splitlines(): - name, sm_path, sha1 = line.split(',') - submodules += [{'name': name, 'path': sm_path, 'hash': sha1}] - - return submodules - - -def get_submodules_config(): # type () -> dict[str,str] - """Return dictionary, where key is variable name and value - is variable value in git's --list(dot) format. Only variables - starting with "submodule." are returned and this prefix is removed - to make it simple to match against the submodule info dictionary.""" +def get_submodules_config(): # type () -> dict[str,dict[str,str]] + """Return dictionary, where key is submodule name and value + is a dictionary with variable:value pairs.""" gitmodules_fn = os.path.join(get_gitwdir(), '.gitmodules') gitmodules_data = run_cmd(['git', 'config', '--list', '--file', gitmodules_fn]) prefix = 'submodule.' - config = {} + config = {} # type: dict[str, dict[str,str]] for line in gitmodules_data.splitlines(): - var, val = line.split('=', 1) - if not var.startswith(prefix): + if not line.startswith(prefix): continue + splitted = line.split('=', 1) + if len(splitted) != 2: + continue + section, val = splitted # remove "submodule." prefix - var = var[len(prefix):] - config[var] = val + section = section[len(prefix):] + # split section into module name and variable + splitted = section.rsplit('.', 1) + if len(splitted) != 2: + continue + module_name, var = splitted + if module_name not in config: + config[module_name] = {} + config[module_name][var] = val return config def test_sha(): # type: () -> None - """ Check that submodule SHA1 in git-tree and .gitmodules match + """ Check that submodule SHA in git-tree and .gitmodules match if sbom-hash variable is available in the .gitmodules file. """ - submodules = get_submodules_info() - config = get_submodules_config() + submodules = get_submodules_config() - for submodule in submodules: - sbom_hash = config.get(submodule['name'] + '.sbom-hash') + for name, variables in submodules.items(): + sbom_hash = variables.get('sbom-hash') if not sbom_hash: continue - msg = ('Submodule \"{sn}\" SHA \"{sh}\" in git ' - 'tree does not match SHA \"{h}\" recorded in .gitmodules. ' - 'Please update \"sbom-hash\" in .gitmodules for \"{sn}\" ' + module_path = variables.get('path') + if not module_path: + continue + output = run_cmd(['git', 'ls-tree', 'HEAD', module_path]) + if not output: + continue + module_hash = output.split()[2] + msg = ('Submodule \"{name}\" SHA \"{module_hash}\" in git ' + 'tree does not match SHA \"{sbom_hash}\" recorded in .gitmodules. ' + 'Please update \"sbom-hash\" in .gitmodules for \"{name}\" ' 'and also please do not forget to update version and other submodule ' 'information if necessary. It is important to keep this information ' - 'up-to-date for SBOM generation.').format(sn=submodule['name'], sh=submodule['hash'], h=sbom_hash) - assert submodule['hash'] == sbom_hash, msg + 'up-to-date for SBOM generation.').format(name=name, module_hash=module_hash, sbom_hash=sbom_hash) + assert module_hash == sbom_hash, msg if __name__ == '__main__':