84 lines
2.6 KiB
Python
84 lines
2.6 KiB
Python
from collections import OrderedDict
|
|
from contextlib import contextmanager
|
|
import os
|
|
import sys
|
|
import subprocess
|
|
import tempfile
|
|
import zipfile
|
|
|
|
|
|
__all__ = ["BuildPlan", "BuildProducts"]
|
|
|
|
|
|
class BuildPlan:
|
|
def __init__(self, script):
|
|
self.script = script
|
|
self.files = OrderedDict()
|
|
|
|
def add_file(self, filename, content):
|
|
assert isinstance(filename, str) and filename not in self.files
|
|
# Just to make sure we don't accidentally overwrite anything.
|
|
assert not os.path.normpath(filename).startswith("..")
|
|
self.files[filename] = content
|
|
|
|
def execute(self, root="build", run_script=True):
|
|
os.makedirs(root, exist_ok=True)
|
|
cwd = os.getcwd()
|
|
try:
|
|
os.chdir(root)
|
|
|
|
for filename, content in self.files.items():
|
|
dirname = os.path.dirname(filename)
|
|
if dirname:
|
|
os.makedirs(dirname, exist_ok=True)
|
|
|
|
mode = "wt" if isinstance(content, str) else "wb"
|
|
with open(filename, mode) as f:
|
|
f.write(content)
|
|
|
|
if run_script:
|
|
if sys.platform.startswith("win32"):
|
|
subprocess.run(["cmd", "/c", "{}.bat".format(self.script)], check=True)
|
|
else:
|
|
subprocess.run(["sh", "{}.sh".format(self.script)], check=True)
|
|
|
|
return BuildProducts(os.getcwd())
|
|
|
|
finally:
|
|
os.chdir(cwd)
|
|
|
|
def archive(self, file):
|
|
with zipfile.ZipFile(file, "w") as archive:
|
|
# Write archive members in deterministic order and with deterministic timestamp.
|
|
for filename in sorted(self.files):
|
|
archive.writestr(zipfile.ZipInfo(filename), self.files[filename])
|
|
|
|
|
|
class BuildProducts:
|
|
def __init__(self, root):
|
|
self._root = root
|
|
|
|
def get(self, filename, mode="b"):
|
|
assert mode in "bt"
|
|
with open(os.path.join(self._root, filename), "r" + mode) as f:
|
|
return f.read()
|
|
|
|
@contextmanager
|
|
def extract(self, *filenames):
|
|
files = []
|
|
try:
|
|
for filename in filenames:
|
|
file = tempfile.NamedTemporaryFile(prefix="nmigen_", suffix="_" + filename)
|
|
files.append(file)
|
|
file.write(self.get(filename))
|
|
|
|
if len(files) == 0:
|
|
return (yield)
|
|
elif len(files) == 1:
|
|
return (yield files[0].name)
|
|
else:
|
|
return (yield [file.name for file in files])
|
|
finally:
|
|
for file in files:
|
|
file.close()
|