Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / pigweed / repo / pw_package / py / pw_package / packages / arduino_core.py
1 # Copyright 2020 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 teensy-core."""
15
16 import json
17 import logging
18 import re
19 import subprocess
20 import tempfile
21 from pathlib import Path
22 from typing import Sequence
23
24 from pw_arduino_build import core_installer
25
26 import pw_package.package_manager
27
28 _LOG: logging.Logger = logging.getLogger(__name__)
29
30
31 class ArduinoCore(pw_package.package_manager.Package):
32     """Install and check status of arduino cores."""
33     def __init__(self, core_name, *args, **kwargs):
34         super().__init__(*args, name=core_name, **kwargs)
35
36     def status(self, path: Path) -> bool:
37         return (path / 'hardware').is_dir()
38
39     def populate_download_cache_from_cipd(self, path: Path) -> None:
40         """Check for arduino core availability in pigweed_internal cipd."""
41         package_path = path.parent.resolve()
42         core_name = self.name
43         core_cache_path = package_path / ".cache" / core_name
44         core_cache_path.mkdir(parents=True, exist_ok=True)
45
46         cipd_package_subpath = "pigweed_internal/third_party/"
47         cipd_package_subpath += core_name
48         cipd_package_subpath += "/${platform}"
49
50         # Check if teensy cipd package is readable
51
52         with tempfile.NamedTemporaryFile(prefix='cipd',
53                                          delete=True) as temp_json:
54             cipd_acl_check_command = [
55                 "cipd",
56                 "acl-check",
57                 cipd_package_subpath,
58                 "-reader",
59                 "-json-output",
60                 temp_json.name,
61             ]
62             subprocess.run(cipd_acl_check_command, capture_output=True)
63             # Return if no packages are readable.
64             if not json.load(temp_json)['result']:
65                 return
66
67         def _run_command(command):
68             _LOG.debug("Running: `%s`", " ".join(command))
69             result = subprocess.run(command, capture_output=True)
70             _LOG.debug("Output:\n%s",
71                        result.stdout.decode() + result.stderr.decode())
72
73         _run_command(["cipd", "init", "-force", core_cache_path.as_posix()])
74         _run_command([
75             "cipd", "install", cipd_package_subpath, "-root",
76             core_cache_path.as_posix(), "-force"
77         ])
78
79         _LOG.debug(
80             "Available Cache Files:\n%s",
81             "\n".join([p.as_posix() for p in core_cache_path.glob("*")]))
82
83     def install(self, path: Path) -> None:
84         self.populate_download_cache_from_cipd(path)
85
86         if self.status(path):
87             return
88         # Otherwise delete current version and reinstall
89         core_installer.install_core(path.parent.resolve().as_posix(),
90                                     self.name)
91
92     def info(self, path: Path) -> Sequence[str]:
93         packages_root = path.parent.resolve()
94         arduino_package_path = path
95         arduino_package_name = None
96
97         message = [
98             f'{self.name} currently installed in: {path}',
99         ]
100         # Make gn args sample copy/paste-able by omitting the starting timestamp
101         # and INF log on each line.
102         message_gn_args = [
103             'Enable by running "gn args out" and adding these lines:',
104             f'  pw_arduino_build_CORE_PATH = "{packages_root}"',
105             f'  pw_arduino_build_CORE_NAME = "{self.name}"'
106         ]
107
108         # Search for first valid 'package/version' directory
109         for hardware_dir in [
110                 path for path in (path / 'hardware').iterdir()
111                 if path.is_dir()
112         ]:
113             if path.name in ["arduino", "tools"]:
114                 continue
115             for subdir in [
116                     path for path in hardware_dir.iterdir() if path.is_dir()
117             ]:
118                 if subdir.name == 'avr' or re.match(r'[0-9.]+', subdir.name):
119                     arduino_package_name = f'{hardware_dir.name}/{subdir.name}'
120                     break
121
122         if arduino_package_name:
123             message_gn_args += [
124                 f'  pw_arduino_build_PACKAGE_NAME = "{arduino_package_name}"',
125                 '  pw_arduino_build_BOARD = "BOARD_NAME"'
126             ]
127             message += ["\n".join(message_gn_args)]
128             message += [
129                 'Where BOARD_NAME is any supported board.',
130                 # Have arduino_builder command appear on it's own line.
131                 'List available boards by running:\n'
132                 '  arduino_builder '
133                 f'--arduino-package-path {arduino_package_path} '
134                 f'--arduino-package-name {arduino_package_name} list-boards'
135             ]
136         return message
137
138
139 for arduino_core_name in core_installer.supported_cores():
140     pw_package.package_manager.register(ArduinoCore, name=arduino_core_name)