1#!/usr/bin/env python3
2#
3# Copyright (C) 2022 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16"""
17Checks and generates a report for gts modules that should be open-sourced.
18
19Usage:
20  generate_gts_open_source_report.py
21    --gts-test-metalic [android-gts meta_lic]
22    --checkshare [COMPLIANCE_CHECKSHARE]
23    --gts-test-dir [directory of android-gts]
24    --output [output file]
25
26Output example:
27  GTS-Modules: PASS/FAIL
28    GtsIncrementalInstallTestCases_BackgroundProcess
29    GtsUnsignedNetworkStackTestCases
30"""
31import sys
32import argparse
33import subprocess
34import re
35
36def _get_args():
37    """Parses input arguments."""
38    parser = argparse.ArgumentParser()
39    parser.add_argument(
40        '--gts-test-metalic', required=True,
41        help='license meta_lic file path of android-gts.zip')
42    parser.add_argument(
43        '--checkshare', required=True,
44        help='path of the COMPLIANCE_CHECKSHARE tool')
45    parser.add_argument(
46        '--gts-test-dir', required=True,
47        help='directory of android-gts')
48    parser.add_argument(
49        '-o', '--output', required=True,
50        help='file path of the output report')
51    return parser.parse_args()
52
53def _check_gts_test(checkshare: str, gts_test_metalic: str,
54                    gts_test_dir: str) -> tuple[str, set[str]]:
55    """Checks android-gts license.
56
57    Args:
58      checkshare: path of the COMPLIANCE_CHECKSHARE tool
59      gts_test_metalic: license meta_lic file path of android-gts.zip
60      gts_test_dir: directory of android-gts
61
62    Returns:
63      Check result (PASS when android-gts doesn't need to be shared,
64      FAIL when some gts modules need to be shared) and gts modules
65      that need to be shared.
66    """
67    cmd = f'{checkshare} {gts_test_metalic}'
68    proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
69                            stderr=subprocess.PIPE)
70    _, str_stderr = map(lambda b: b.decode(), proc.communicate())
71    if proc.returncode == 0:
72        return 'PASS', []
73    open_source_modules = set()
74    for error_line in str_stderr.split('\n'):
75        # Skip the empty liness
76        if not error_line:
77            continue
78        module_meta_lic = error_line.strip().split()[0]
79        groups = re.fullmatch(
80            re.compile(f'.*/{gts_test_dir}/(.*)'), module_meta_lic)
81        if groups:
82            open_source_modules.add(
83                groups[1].removesuffix('.meta_lic'))
84    return 'FAIL', open_source_modules
85
86
87def main(argv):
88    args = _get_args()
89
90    gts_test_metalic = args.gts_test_metalic
91    output_file = args.output
92    checkshare = args.checkshare
93    gts_test_dir = args.gts_test_dir
94
95    with open(output_file, 'w') as file:
96        result, open_source_modules = _check_gts_test(
97            checkshare, gts_test_metalic, gts_test_dir)
98        file.write(f'GTS-Modules: {result}\n')
99        for open_source_module in open_source_modules:
100            file.write(f'\t{open_source_module}\n')
101
102if __name__ == "__main__":
103    main(sys.argv)
104