# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: MIT-0 """Methods of manipulating the templates repository.""" import importlib.util from pathlib import Path from cbmc_starter_kit import repository REPOSITORY_TEMPLATES = "template-for-repository" PROOF_TEMPLATES = "template-for-proof" CI_WORKFLOW_TEMPLATES = "template-for-ci-workflow" PROOF_DIR = "proofs" LIB_MODULE = "lib" NEGATIVE_TESTS = "negative_tests" COMMON_MAKEFILE = "Makefile.common" TEMPLATE_DEFINES = "Makefile-template-defines" PROJECT_DEFINES = "Makefile-project-defines" RUN_SCRIPT = "run-cbmc-proofs.py" GITHUB_ACTIONS_PROOF_CI = "proof_ci.yaml" CFN_STACK_OIDC = "proof-ci-Oidc" CFN_STACK_PIPELINE = "proof-ci-Pipeline" ################################################################ def package_root(): """Directory containing the package.""" # There are so many incompatible, deprecated ways of doing this # available in Python version 3.6 through 3.10, and the right # solution is in question. # # The right solution is actually # # importlib.resources.files(__package__) # # but importlib.resources appears in 3.7 (with a backport # importlib_resources available before 3.7) and files itself # appears in 3.9 # # The next solution is # # importlib.resources.path(__package__, resource_name) # # but the resource_name must be a string and can't be a directory # or a path, and this deprecated after 3.9 in favor of files(). # # The next solution is # # pkgutil.get_data(__package__, resource_path) # # but this returns contents and not a path. But, amazing, this # works even if the package is an egg or a zipfile! # # The next solution is # # pkg_resources.resource_filename(__package__, resource_path) # # but pkg_resources is slow and distributed with setuptools and # not a standard module. # this gives the path to the package __init__.py init = importlib.util.find_spec(__package__).origin # this gives the path to the package directory return Path(init).parent def package_repository_template_root(): return package_root() / REPOSITORY_TEMPLATES def package_proof_template_root(): return package_root() / PROOF_TEMPLATES def package_ci_workflow_template_root(): return package_root() / CI_WORKFLOW_TEMPLATES ################################################################ # Ask the user for set up information def ask_for_project_name(): """Ask user for project name.""" return input("What is the project name? ").strip() def ask_for_function_name(): """Ask user for function name.""" return input("What is the function name? ").strip() def ask_for_source_file(func, cwd=None, repo=None): """Ask user to select path to source file defining function func.""" cwd = Path(cwd or Path.cwd()).resolve() repo = Path(repo or repository.repository_root(cwd=cwd)).resolve() sources = repository.function_sources(func, cwd=cwd, repo=repo) options = sources + ["The source file is not listed here"] choices = [str(idx) for idx in range(len(options))] index = choices[-1] if sources: print(f"These source files define a function '{func}':") for idx, src in enumerate(options): print(f" {idx:3} {src}") index = input( f"Select a source file (the options are {', '.join(choices)}): " ).strip() or choices[-1] if index not in choices: raise UserWarning(f"{index} is not in {', '.join(choices)}") if index == choices[-1]: src = input(f"Enter path to source file defining {func}: ").strip() else: src = sources[int(index)] src = Path(src).expanduser().resolve() if not src.is_file(): raise UserWarning(f"Source file '{src}' does not exist") return src ################################################################