| #!/usr/bin/env python3 | 
 | # Copyright 2021-2022 Efabless Corporation | 
 | # | 
 | # 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. | 
 | import os | 
 | import sys | 
 | from typing import Dict, List | 
 |  | 
 | sys.path.append(os.path.dirname(__file__)) | 
 | import includedyaml as yaml  # noqa: E402 | 
 |  | 
 |  | 
 | class Tool(object): | 
 |     by_name: Dict[str, "Tool"] | 
 |  | 
 |     def __init__( | 
 |         self, | 
 |         name, | 
 |         repo, | 
 |         commit, | 
 |         build_script="make && make install", | 
 |         default_branch=None, | 
 |         in_install=True, | 
 |         in_container=True, | 
 |         dependencies=[], | 
 |         pdk=False, | 
 |     ): | 
 |         self.name = name | 
 |         self.repo = repo | 
 |         self.commit = commit | 
 |         self.build_script = build_script | 
 |         self.default_branch = default_branch | 
 |         self.in_install = in_install | 
 |         self.in_container = in_container | 
 |         self.dependencies = dependencies | 
 |         self.pdk = pdk | 
 |  | 
 |     def __repr__(self) -> str: | 
 |         return f"<Tool {self.name} (using {self.repo_pretty or 'None'}@{self.commit or 'None'})>" | 
 |  | 
 |     @property | 
 |     def repo_pretty(self): | 
 |         gh_prefix = "https://github.com/" | 
 |         repo = self.repo | 
 |         if repo is not None and repo.startswith(gh_prefix): | 
 |             return repo[len(gh_prefix) :] | 
 |         return repo | 
 |  | 
 |     @property | 
 |     def version_string(self) -> str: | 
 |         return f"{self.repo or 'None'}:{self.commit or 'None'}" | 
 |  | 
 |     def get_docker_tag(self, for_os: str) -> str: | 
 |         return f"{self.name}-{self.commit}-{for_os}" | 
 |  | 
 |     @property | 
 |     def docker_args(self) -> List[str]: | 
 |         return [ | 
 |             "--build-arg", | 
 |             f"{self.name.upper()}_REPO={self.repo}", | 
 |             "--build-arg", | 
 |             f"{self.name.upper()}_COMMIT={self.commit}", | 
 |         ] | 
 |  | 
 |     @staticmethod | 
 |     def from_metadata_yaml(metadata_yaml: str) -> Dict[str, "Tool"]: | 
 |         final_dict = {} | 
 |         tool_list = yaml.load(metadata_yaml, Loader=yaml.SafeLoader) | 
 |         for tool in tool_list: | 
 |             final_dict[tool["name"]] = Tool( | 
 |                 name=tool["name"], | 
 |                 repo=tool["repo"], | 
 |                 commit=tool["commit"], | 
 |                 build_script=tool.get("build") or "", | 
 |                 default_branch=tool.get("default_branch") or None, | 
 |                 in_container=tool["in_container"] | 
 |                 if tool.get("in_container") is not None | 
 |                 else True, | 
 |                 in_install=tool["in_install"] | 
 |                 if tool.get("in_install") is not None | 
 |                 else True, | 
 |                 dependencies=tool.get("dependencies") or [], | 
 |                 pdk=tool.get("pdk") or False, | 
 |             ) | 
 |         return final_dict | 
 |  | 
 |  | 
 | Tool.by_name = Tool.from_metadata_yaml( | 
 |     open(os.path.join(os.path.dirname(__file__), "tool_metadata.yml")).read() | 
 | ) | 
 |  | 
 |  | 
 | def main(): | 
 |     import os | 
 |     import argparse | 
 |  | 
 |     parser = argparse.ArgumentParser(description="Get Tool Info") | 
 |     parser.add_argument("--containerized", action="store_true") | 
 |     parser.add_argument("--docker-args", action="store_true") | 
 |     parser.add_argument("--no-pdks", action="store_true") | 
 |     parser.add_argument("--docker-tag-for-os", default=None) | 
 |     parser.add_argument("--field", "-f") | 
 |     parser.add_argument("tool") | 
 |     args = parser.parse_args() | 
 |  | 
 |     if args.no_pdks: | 
 |         pdk_keys = [] | 
 |         for key, value in Tool.by_name.items(): | 
 |             if value.pdk: | 
 |                 pdk_keys.append(key) | 
 |  | 
 |         for key in pdk_keys: | 
 |             del Tool.by_name[key] | 
 |  | 
 |     if args.containerized: | 
 |         for tool in Tool.by_name.values(): | 
 |             if tool.in_container: | 
 |                 print(tool.name, end=" ") | 
 |         exit(0) | 
 |  | 
 |     try: | 
 |         tool = Tool.by_name[args.tool] | 
 |     except Exception: | 
 |         print(f"Unknown tool {args.tool}.", file=sys.stderr) | 
 |         exit(os.EX_DATAERR) | 
 |  | 
 |     if args.docker_tag_for_os: | 
 |         print(tool.get_docker_tag(for_os=args.docker_tag_for_os)) | 
 |     elif args.docker_args: | 
 |         arg_list = tool.docker_args | 
 |  | 
 |         # 1. Dependents | 
 |         dependents = [] | 
 |         for dependent in Tool.by_name.values(): | 
 |             if tool.name in dependent.dependencies: | 
 |                 dependents.append(dependent) | 
 |         for dependent in dependents: | 
 |             arg_list += dependent.docker_args | 
 |  | 
 |         # 2. Dependencies | 
 |         for dependency_name in tool.dependencies: | 
 |             dependency = Tool.by_name[dependency_name] | 
 |             arg_list += dependency.docker_args | 
 |  | 
 |         print(" ".join(arg_list), end="") | 
 |     elif args.field: | 
 |         field = tool.__dict__[args.field] | 
 |         print(field, end="") | 
 |     else: | 
 |         parser.print_help(file=sys.stderr) | 
 |         exit(os.EX_USAGE) | 
 |  | 
 |  | 
 | if __name__ == "__main__": | 
 |     main() |