• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# Copyright 2020 The Pigweed Authors
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may not
5# use this file except in compliance with the License. You may obtain a copy of
6# the License at
7#
8#     https://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations under
14# the License.
15"""Generates a BUILD.gn for a Python package.
16
17Pass the script a list of paths to the root directory of a Python package (where
18setup.py is).
19
20Don't forget to add the pw_python_package to a top-level group, or it will not
21be included in the build.
22"""
23
24from datetime import datetime
25from pathlib import Path
26import sys
27from typing import Iterable, NamedTuple
28
29from pw_presubmit import git_repo
30
31_HEADER = f"""\
32# Copyright {datetime.now().year} The Pigweed Authors
33#
34# Licensed under the Apache License, Version 2.0 (the "License"); you may not
35# use this file except in compliance with the License. You may obtain a copy of
36# the License at
37#
38#     https://www.apache.org/licenses/LICENSE-2.0
39#
40# Unless required by applicable law or agreed to in writing, software
41# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
42# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
43# License for the specific language governing permissions and limitations under
44# the License.
45
46import("//build_overrides/pigweed.gni")
47
48import("$dir_pw_build/python.gni")
49"""
50
51
52class PackageFiles(NamedTuple):
53    setup: list[Path]
54    sources: list[Path]
55    tests: list[Path]
56    other: list[Path]
57
58
59def _find_package_files(root_dir: Path) -> PackageFiles:
60    files = git_repo.list_files(
61        pathspecs=('*.py', '*.toml', '*.cfg'), repo_path=root_dir
62    )
63
64    package_files = PackageFiles([], [], [], [])
65
66    for file in files:
67        if file.parent == root_dir:
68            if file.name == 'setup.py' or file.suffix != '.py':
69                package_files.setup.append(file)
70            elif file.stem.startswith('test_') or file.stem.endswith('_test'):
71                package_files.tests.append(file)
72            else:
73                package_files.other.append(file)
74        else:
75            package_files.sources.append(file)
76
77    return package_files
78
79
80def _gn_list(name: str, files: Iterable[Path], base: Path) -> Iterable[str]:
81    if files:
82        yield f'  {name} = ['
83        for file in files:
84            yield f'    "{file.relative_to(base).as_posix()}",'
85        yield '  ]'
86
87
88def generate_build_gn(root_dir: Path):
89    files = _find_package_files(root_dir)
90
91    yield _HEADER
92
93    yield 'pw_python_package("py") {'
94
95    yield from _gn_list('setup', files.setup, root_dir)
96    yield from _gn_list('sources', files.sources, root_dir)
97    yield from _gn_list('tests', files.tests, root_dir)
98
99    # Don't include the "other" files for now.
100    # yield from _gn_list('other', files.other, root_dir)
101
102    yield '}'
103
104
105def main(paths: Iterable[Path]):
106    for path in paths:
107        path.joinpath('BUILD.gn').write_text(
108            '\n'.join(generate_build_gn(path)) + '\n'
109        )
110
111
112if __name__ == '__main__':
113    if len(sys.argv) > 1:
114        main(Path(p).resolve() for p in sys.argv[1:])
115    else:
116        print(__file__, '', __doc__.strip(), sep='\n', file=sys.stderr)
117        sys.exit(1)
118