2021-11-30 14:51:24 +01:00

132 lines
3.9 KiB
Python

# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
"""Methods of manipulating the templates repository."""
import logging
import os
import shutil
REPOSITORY_TEMPLATES = "template-for-repository"
PROOF_TEMPLATES = "template-for-proof"
PROOF_DIR = "proofs"
# There are some files that we should copy to the project repository rather than
# symlinking. This is because users are expected to modify these files. If the
# files were symlinks, then modifying them would dirty up this submodule, which
# would prevent project owners from cleanly updating it.
COPY_INSTEAD = [
"Makefile-project-defines",
"Makefile-project-targets",
"Makefile-project-testing",
".gitignore",
"run-cbmc-proofs.py",
]
################################################################
def script_dir():
"""Directory containing setup scripts."""
return os.path.dirname(os.path.abspath(__file__))
def templates_root():
"""Directory containing the AWS-templates-for-CBMC repository."""
return os.path.dirname(script_dir())
################################################################
# Read configuration information from the standard input
def read_from_stdin():
return input().strip()
def read_path_from_stdin(description):
print("What is the path to {}? ".format(description), end="")
return os.path.abspath(os.path.expanduser(read_from_stdin()))
def read_source_root_path():
return read_path_from_stdin("the source root")
def read_proof_root_path():
return read_path_from_stdin("the 'proofs' directory (usually '.')")
def read_litani_path():
return read_path_from_stdin("the litani script")
def read_source_path():
return read_path_from_stdin("the source file defining the function")
def read_function_name():
print("What is the function name? ", end="")
return read_from_stdin()
def read_project_name():
print("What is the project name? ", end="")
return read_from_stdin()
################################################################
def files_under_root(root):
"""The list of files in the filesystem under root."""
cwd = os.getcwd()
try:
os.chdir(root)
return [os.path.join(path, name)
for path, _, files in os.walk('.') for name in files]
finally:
os.chdir(cwd)
def link_files(name, src, dst):
"""Link file dst/name to file src/name, return number skipped"""
src_name = os.path.normpath(os.path.join(src, name))
dst_name = os.path.normpath(os.path.join(dst, name))
os.makedirs(os.path.dirname(dst_name), exist_ok=True)
src_link = os.path.relpath(src_name, os.path.dirname(dst_name))
if os.path.basename(name) in COPY_INSTEAD:
install_method = ("copy", shutil.copyfile)
src_link = src_name
else:
install_method = ("symlink", os.symlink)
if os.path.exists(dst_name):
logging.warning("Skipping %s %s -> %s: file exists",
install_method[0], name, src_link)
return 1
logging.warning(
"Creating %s %s -> %s", install_method[0], name, src_link)
install_method[1](src_link, dst_name)
return 0
def copy_directory_contents(src, dst):
"""Link the contents of one directory into another."""
src = os.path.normpath(src)
dst = os.path.normpath(dst)
assert os.path.isdir(src)
assert os.path.isdir(dst)
skipped = 0
for name in files_under_root(src):
name = os.path.normpath(name)
skipped += link_files(name, src, dst)
if skipped:
logging.warning("To overwrite a skipped file, "
"delete the file and rerun the script.")
def copy_repository_templates(cbmc_root):
"""Copy the files in the repository template into the CBMC root."""
copy_directory_contents(os.path.join(templates_root(),
REPOSITORY_TEMPLATES),
cbmc_root)