mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 05:35:20 +00:00
scripts: Add consistency check script
Add `package-consistency-check.py` script to prevent #6809 and #6815 from happening. This script takes a string present in the repository field of packages to identify pacakges from a specific source. Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
This commit is contained in:
parent
675140f627
commit
337cbf3d33
83
scripts/package-consistency-check.py
Executable file
83
scripts/package-consistency-check.py
Executable file
@ -0,0 +1,83 @@
|
|||||||
|
#!/bin/env python3
|
||||||
|
#
|
||||||
|
# Copyright © 2024 Institute of Software, CAS. All rights reserved.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import json
|
||||||
|
from argparse import ArgumentParser
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
def get_cargo_metadata():
|
||||||
|
result = subprocess.run(
|
||||||
|
['cargo', 'metadata', '--format-version=1'],
|
||||||
|
capture_output=True,
|
||||||
|
text=True
|
||||||
|
)
|
||||||
|
if result.returncode != 0:
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
metadata = json.loads(result.stdout)
|
||||||
|
return metadata
|
||||||
|
|
||||||
|
def find_dependents_of_package(metadata, package_source):
|
||||||
|
"""Find dependencies based on the provided source identifier and return related package info."""
|
||||||
|
packages = defaultdict(list)
|
||||||
|
direct_dependents = defaultdict(list)
|
||||||
|
|
||||||
|
# Identify packages from the given package source and record version
|
||||||
|
for pkg in metadata['packages']:
|
||||||
|
repository = pkg['repository'] or ''
|
||||||
|
if package_source in repository:
|
||||||
|
packages[pkg['name']].append(pkg['version'])
|
||||||
|
|
||||||
|
# Find packages that immediately depend on the identified source packages
|
||||||
|
for node in metadata['resolve']['nodes']:
|
||||||
|
current_pkg = next(pkg for pkg in metadata['packages'] if pkg['id'] == node['id'])
|
||||||
|
current_pkg_name = current_pkg['name']
|
||||||
|
current_pkg_version = current_pkg['version']
|
||||||
|
|
||||||
|
for dep_id in node['dependencies']:
|
||||||
|
dep_pkg = next(pkg for pkg in metadata['packages'] if pkg['id'] == dep_id)
|
||||||
|
dep_name = dep_pkg['name']
|
||||||
|
dep_version = dep_pkg['version']
|
||||||
|
|
||||||
|
if dep_name in packages:
|
||||||
|
direct_dependents[(dep_name, dep_version)].append((current_pkg_name, current_pkg_version))
|
||||||
|
|
||||||
|
return packages, direct_dependents
|
||||||
|
|
||||||
|
def check_for_version_conflicts(packages, direct_dependents):
|
||||||
|
"""Check if there are multiple versions of dependencies, and return True if conflicts are found."""
|
||||||
|
has_conflicts = False
|
||||||
|
|
||||||
|
for pkg_name, versions in packages.items():
|
||||||
|
if len(set(versions)) > 1:
|
||||||
|
has_conflicts = True
|
||||||
|
print(f"Error: Multiple versions detected for {pkg_name}: {set(versions)}")
|
||||||
|
for version in set(versions):
|
||||||
|
print(f" Version {version} used by:")
|
||||||
|
for dependent, dep_version in direct_dependents[(pkg_name, version)]:
|
||||||
|
print(f" - {dependent} v{dep_version}")
|
||||||
|
|
||||||
|
return has_conflicts
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parser = ArgumentParser(description='Cargo dependency conflict checker.')
|
||||||
|
parser.add_argument('package_source', type=str, help='A keyword used to match the repository URL field')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
metadata = get_cargo_metadata()
|
||||||
|
if metadata is None:
|
||||||
|
print("Error: Metadata is empty")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
packages, direct_dependents = find_dependents_of_package(metadata, args.package_source)
|
||||||
|
|
||||||
|
has_conflicts = check_for_version_conflicts(packages, direct_dependents)
|
||||||
|
|
||||||
|
if has_conflicts:
|
||||||
|
exit(1)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user