clang 20.0.0 (based on r547379) from build 12806354. Bug: http://b/379133546 Test: N/A Change-Id: I2eb8938af55d809de674be63cb30cf27e801862b Upstream-Commit: ad834e67b1105d15ef907f6255d4c96e8e733f57
129 lines
4.6 KiB
Python
129 lines
4.6 KiB
Python
#!/usr/bin/env python3
|
|
#
|
|
# Copyright (C) 2023 The Android Open Source Project
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
# Sample Usage:
|
|
# $ python3 validate_orderfile.py --order-file ../orderfiles/test/example.orderfile
|
|
#
|
|
# Try '-h' for a full list of command line arguments.
|
|
#
|
|
# Currently, we check four things in an orderfile:
|
|
# - A partial order is maintained in the orderfile
|
|
# - All symbols in allowlist must be present in the orderfile
|
|
# - No symbol in denylist should be present in the orderfile
|
|
# - The orderfile has a minimum number of symbols
|
|
|
|
import argparse
|
|
import orderfile_utils
|
|
|
|
def parse_args():
|
|
"""Parses and returns command line arguments."""
|
|
parser = argparse.ArgumentParser(prog="validate_orderfile",
|
|
description="Validates the orderfile is correct and useful based on flag conditions")
|
|
|
|
parser.add_argument(
|
|
"--order-file",
|
|
required=True,
|
|
help="Orderfile that needs to be validated")
|
|
|
|
parser.add_argument(
|
|
"--partial",
|
|
default="",
|
|
help=f"A partial order of symbols that need to hold in the orderfile."
|
|
f"Format: A symbol-per-line file with @ or comma separarted values within a quotation."
|
|
f"For example, you can say @file.txt or 'main,bar,foo'.")
|
|
|
|
parser.add_argument(
|
|
"--allowlist",
|
|
default="",
|
|
help=f"Symbols that have to be present in the orderfile."
|
|
f"Format: A symbol-per-line file with @ or comma separarted values within a quotation."
|
|
f"For example, you can say @file.txt or 'main,bar,foo'.")
|
|
|
|
parser.add_argument(
|
|
"--denylist",
|
|
default="",
|
|
help=f"Symbols that should not be in orderfile. Denylist flag has priority over allowlist."
|
|
f"Format: A symbol-per-line file with @ or comma separarted values within a quotation."
|
|
f"For example, you can say @file.txt or 'main,bar,foo'.")
|
|
|
|
parser.add_argument(
|
|
"--min",
|
|
type=int,
|
|
default=0,
|
|
help="Minimum number of entires needed for an orderfile")
|
|
|
|
return parser.parse_args()
|
|
|
|
def main():
|
|
args = parse_args()
|
|
|
|
allowlist = orderfile_utils.parse_set(args.allowlist)
|
|
partial = orderfile_utils.parse_list(args.partial)
|
|
denylist = orderfile_utils.parse_set(args.denylist)
|
|
|
|
# Check if there are symbols common to both allowlist and denylist
|
|
# We give priority to denylist so the symbols in the intersection
|
|
# will be removed from allowlist
|
|
inter = allowlist.intersection(denylist)
|
|
allowlist = allowlist.difference(inter)
|
|
|
|
num_entries = 0
|
|
file_indices = {}
|
|
file_present = set()
|
|
|
|
# Read the orderfile
|
|
with open(args.order_file, "r") as f:
|
|
for line in f:
|
|
line = line.strip()
|
|
|
|
# Check if a symbol not allowed is within the orderfile
|
|
if line in denylist:
|
|
raise RuntimeError(f"Orderfile should not contain {line}")
|
|
|
|
if line in allowlist:
|
|
file_present.add(line)
|
|
|
|
file_indices[line] = num_entries
|
|
num_entries += 1
|
|
|
|
# Check if there are not a minimum number of symbols in orderfile
|
|
if num_entries < args.min:
|
|
raise RuntimeError(f"The orderfile has {num_entries} symbols but it "
|
|
f"needs at least {args.min} symbols")
|
|
|
|
# Check if all symbols allowed must be allowlist
|
|
if len(allowlist) != len(file_present):
|
|
raise RuntimeError("Some symbols in allow-list are not in the orderfile")
|
|
|
|
# Check if partial order passed with flag is maintained within orderfile
|
|
# The partial order might contain symbols not in the orderfile which we allow
|
|
# because the order is still maintained.
|
|
old_index = None
|
|
curr_symbol = None
|
|
for symbol in partial:
|
|
new_index = file_indices.get(symbol)
|
|
if new_index is not None:
|
|
if old_index is not None:
|
|
if new_index < old_index:
|
|
raise RuntimeError(f"`{curr_symbol}` must be before `{symbol}` in orderfile")
|
|
old_index = new_index
|
|
curr_symbol = symbol
|
|
|
|
print("Order file is valid")
|
|
|
|
if __name__ == '__main__':
|
|
main()
|