You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			108 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
			
		
		
	
	
			108 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
#!/usr/bin/env python3
 | 
						|
# Copyright 2023 The Chromium Authors. All rights reserved.
 | 
						|
# Use of this source code is governed by a BSD-style license that can be
 | 
						|
# found in the LICENSE file.
 | 
						|
 | 
						|
import argparse
 | 
						|
from collections import defaultdict
 | 
						|
import os
 | 
						|
import sys
 | 
						|
 | 
						|
_THIS_DIR = os.path.abspath(os.path.dirname(__file__))
 | 
						|
# The repo's root directory.
 | 
						|
_ROOT_DIR = os.path.abspath(os.path.join(_THIS_DIR, ".."))
 | 
						|
 | 
						|
# Add the repo's root directory for clearer imports.
 | 
						|
sys.path.insert(0, _ROOT_DIR)
 | 
						|
 | 
						|
import metadata.discover
 | 
						|
import metadata.validate
 | 
						|
 | 
						|
 | 
						|
def parse_args() -> argparse.Namespace:
 | 
						|
    """Helper to parse args to this script."""
 | 
						|
    parser = argparse.ArgumentParser()
 | 
						|
    repo_root_dir = parser.add_argument(
 | 
						|
        "repo_root_dir",
 | 
						|
        help=("The path to the repository's root directory, which will be "
 | 
						|
              "scanned for Chromium metadata files, e.g. '~/chromium/src'."),
 | 
						|
    )
 | 
						|
 | 
						|
    args = parser.parse_args()
 | 
						|
 | 
						|
    # Check the repo root directory exists.
 | 
						|
    src_dir = os.path.abspath(args.repo_root_dir)
 | 
						|
    if not os.path.exists(src_dir) or not os.path.isdir(src_dir):
 | 
						|
        raise argparse.ArgumentError(
 | 
						|
            repo_root_dir,
 | 
						|
            f"Invalid repository root directory '{src_dir}' - not found",
 | 
						|
        )
 | 
						|
 | 
						|
    return args
 | 
						|
 | 
						|
 | 
						|
def main() -> None:
 | 
						|
    """Runs validation on all metadata files within the directory
 | 
						|
    specified by the repo_root_dir arg.
 | 
						|
    """
 | 
						|
    config = parse_args()
 | 
						|
    src_dir = os.path.abspath(config.repo_root_dir)
 | 
						|
 | 
						|
    metadata_files = metadata.discover.find_metadata_files(src_dir)
 | 
						|
    file_count = len(metadata_files)
 | 
						|
    print(f"Found {file_count} metadata files.")
 | 
						|
 | 
						|
    invalid_file_count = 0
 | 
						|
 | 
						|
    # Key is constructed from the result severity and reason;
 | 
						|
    # Value is a dict for:
 | 
						|
    #  * list of files affected by that reason at that severity; and
 | 
						|
    #  * list of validation result strings for that reason and severity.
 | 
						|
    all_reasons = defaultdict(lambda: {"files": [], "results": set()})
 | 
						|
    for filepath in metadata_files:
 | 
						|
        file_results = metadata.validate.validate_file(filepath,
 | 
						|
                                                       repo_root_dir=src_dir)
 | 
						|
        invalid = False
 | 
						|
        if file_results:
 | 
						|
            relpath = os.path.relpath(filepath, start=src_dir)
 | 
						|
            print(f"\n{len(file_results)} problem(s) in {relpath}:")
 | 
						|
            for result in file_results:
 | 
						|
                print(f"    {result}")
 | 
						|
                summary_key = "{severity} - {reason}".format(
 | 
						|
                    severity=result.get_severity_prefix(),
 | 
						|
                    reason=result.get_reason())
 | 
						|
                all_reasons[summary_key]["files"].append(relpath)
 | 
						|
                all_reasons[summary_key]["results"].add(str(result))
 | 
						|
                if result.is_fatal():
 | 
						|
                    invalid = True
 | 
						|
 | 
						|
        if invalid:
 | 
						|
            invalid_file_count += 1
 | 
						|
 | 
						|
    print("\n\nDone.")
 | 
						|
 | 
						|
    print("\nSummary of files:")
 | 
						|
    for summary_key, data in all_reasons.items():
 | 
						|
        affected_files = data["files"]
 | 
						|
        count = len(affected_files)
 | 
						|
        plural = "s" if count > 1 else ""
 | 
						|
        print(f"\n  {count} file{plural}: {summary_key}")
 | 
						|
        for affected_file in affected_files:
 | 
						|
            print(f"    {affected_file}")
 | 
						|
 | 
						|
    print("\nSummary of results:")
 | 
						|
    for summary_key, data in all_reasons.items():
 | 
						|
        results = data["results"]
 | 
						|
        count = len(results)
 | 
						|
        plural = "s" if count > 1 else ""
 | 
						|
        print(f"\n  {count} issue{plural}: {summary_key}")
 | 
						|
        for result in sorted(results):
 | 
						|
            print(f"    {result}")
 | 
						|
 | 
						|
    print(f"\n\n{invalid_file_count} / {file_count} metadata files are "
 | 
						|
          "invalid, i.e. the file has at least one fatal validation issue.")
 | 
						|
 | 
						|
 | 
						|
if __name__ == "__main__":
 | 
						|
    main()
 |