Merge branch 'bugfix/sbom_hash_check' into 'master'

fix(test_submodules.py): don't rely on submodule init

Closes IDF-7662

See merge request espressif/esp-idf!24492
This commit is contained in:
Roland Dobai 2023-07-26 18:50:15 +08:00
commit 21b75790ee

View File

@ -16,57 +16,58 @@ def get_gitwdir() -> str:
return run_cmd(['git', 'rev-parse', '--show-toplevel']) return run_cmd(['git', 'rev-parse', '--show-toplevel'])
def get_submodules_info() -> List[Dict[str,str]]: def get_submodules_config() -> Dict[str,Dict[str,str]]:
"""Return list of submodules, where each submodule is represented """Return dictionary, where key is submodule name and value
as dictionary with name, path and hash keys.""" is a dictionary with variable:value pairs."""
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() -> 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."""
gitmodules_fn = os.path.join(get_gitwdir(), '.gitmodules') gitmodules_fn = os.path.join(get_gitwdir(), '.gitmodules')
gitmodules_data = run_cmd(['git', 'config', '--list', '--file', gitmodules_fn]) gitmodules_data = run_cmd(['git', 'config', '--list', '--file', gitmodules_fn])
prefix = 'submodule.' prefix = 'submodule.'
config = {} config: Dict[str, Dict[str,str]] = {}
for line in gitmodules_data.splitlines(): for line in gitmodules_data.splitlines():
var, val = line.split('=', maxsplit=1) if not line.startswith(prefix):
if not var.startswith(prefix):
continue continue
splitted = line.split('=', maxsplit=1)
if len(splitted) != 2:
continue
section, val = splitted
# remove "submodule." prefix # remove "submodule." prefix
var = var[len(prefix):] section = section[len(prefix):]
config[var] = val # split section into module name and variable
splitted = section.rsplit('.', maxsplit=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 return config
def test_sha() -> None: def test_sha() -> 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. if sbom-hash variable is available in the .gitmodules file.
""" """
submodules = get_submodules_info() submodules = get_submodules_config()
config = get_submodules_config()
for submodule in submodules: for name, variables in submodules.items():
sbom_hash = config.get(submodule['name'] + '.sbom-hash') sbom_hash = variables.get('sbom-hash')
if not sbom_hash: if not sbom_hash:
continue continue
msg = (f'Submodule \"{submodule["name"]}\" SHA \"{submodule["hash"]}\" in git ' 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 = (f'Submodule \"{name}\" SHA \"{module_hash}\" in git '
f'tree does not match SHA \"{sbom_hash}\" recorded in .gitmodules. ' f'tree does not match SHA \"{sbom_hash}\" recorded in .gitmodules. '
f'Please update \"sbom-hash\" in .gitmodules for \"{submodule["name"]}\" ' f'Please update \"sbom-hash\" in .gitmodules for \"{name}\" '
f'and also please do not forget to update version and other submodule ' f'and also please do not forget to update version and other submodule '
f'information if necessary. It is important to keep this information ' f'information if necessary. It is important to keep this information '
f'up-to-date for SBOM generation.') f'up-to-date for SBOM generation.')
assert submodule['hash'] == sbom_hash, msg assert module_hash == sbom_hash, msg
if __name__ == '__main__': if __name__ == '__main__':