xref: /aosp_15_r20/external/pigweed/pw_package/py/pw_package/packages/zephyr.py (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1# Copyright 2023 The Pigweed Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4# use this file except in compliance with the License. You may obtain a copy of
5# the License at
6#
7#     https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations under
13# the License.
14"""Install and check status of Zephyr."""
15import importlib.resources
16import json
17import pathlib
18import subprocess
19import sys
20import tempfile
21
22from typing import Sequence
23
24import pw_env_setup.virtualenv_setup
25
26import pw_package.git_repo
27import pw_package.package_manager
28
29# Main branch, this commit is close to the v3.6 RC3 tag which contains some
30# bug fixes for Twister and support for GTEST_SKIP()
31_ZEPHYR_COMMIT_SHA = 'f9778472105d756fff7d1e5b54353421d356ed43'
32
33
34class Zephyr(pw_package.git_repo.GitRepo):
35    """Install and check status of Zephyr."""
36
37    def __init__(self, *args, **kwargs):
38        super().__init__(
39            *args,
40            name='zephyr',
41            url=(
42                'https://pigweed.googlesource.com/third_party/'
43                'github/zephyrproject-rtos/zephyr'
44            ),
45            commit=_ZEPHYR_COMMIT_SHA,
46            **kwargs,
47        )
48
49    def info(self, path: pathlib.Path) -> Sequence[str]:
50        return (
51            f'{self.name} installed in: {path}',
52            'Enable by running "gn args out" and adding this line:',
53            f'  dir_pw_third_party_zephyr = "{path}"',
54        )
55
56    @staticmethod
57    def __populate_download_cache_from_cipd(path: pathlib.Path) -> None:
58        """Check for Zephyr SDK in cipd"""
59        package_path = path.parent.resolve()
60        core_cache_path = package_path / 'zephyr_sdk'
61        core_cache_path.mkdir(parents=True, exist_ok=True)
62
63        cipd_package_subpath = 'infra/3pp/tools/zephyr_sdk/${platform}'
64
65        # Check if the zephyr_sdk cipd package is readable
66        with tempfile.NamedTemporaryFile(
67            prefix='cipd', delete=True
68        ) as temp_json:
69            temp_json_path = pathlib.Path(temp_json.name)
70            cipd_acl_check_command = [
71                'cipd',
72                'acl-check',
73                cipd_package_subpath,
74                '-reader',
75                '-json-output',
76                str(temp_json_path),
77            ]
78            subprocess.run(cipd_acl_check_command, capture_output=True)
79
80            # Return if no packages are readable.
81            if not temp_json_path.is_file():
82                raise RuntimeError(
83                    'Failed to verify zephyr_sdk cipd package is readable.'
84                )
85            result_text = temp_json_path.read_text()
86            result_dict = json.loads(result_text)
87            if 'result' not in result_dict:
88                raise RuntimeError(
89                    'Failed to verify zephyr_sdk cipd package is readable.'
90                )
91
92        # Initialize cipd
93        subprocess.check_call(
94            [
95                'cipd',
96                'init',
97                '-force',
98                str(core_cache_path),
99            ]
100        )
101        # Install the Zephyr SDK
102        subprocess.check_call(
103            [
104                'cipd',
105                'install',
106                cipd_package_subpath,
107                '-root',
108                str(core_cache_path),
109                '-force',
110            ]
111        )
112        # Setup Zephyr SDK
113        subprocess.check_call(
114            [
115                'cmake',
116                '-P',
117                str(core_cache_path / 'cmake' / 'zephyr_sdk_export.cmake'),
118            ]
119        )
120
121    def install(self, path: pathlib.Path) -> None:
122        super().install(path)
123
124        self.__populate_download_cache_from_cipd(path)
125        with importlib.resources.path(
126            pw_env_setup.virtualenv_setup, 'constraint.list'
127        ) as constraint:
128            subprocess.check_call(
129                [
130                    sys.executable,
131                    '-m',
132                    'pip',
133                    'install',
134                    '-r',
135                    f'{path}/scripts/requirements.txt',
136                    '-c',
137                    str(constraint),
138                ]
139            )
140
141
142pw_package.package_manager.register(Zephyr)
143