Commit c7bf39c5 authored by Pietro Albini's avatar Pietro Albini

Use a managetests.json file in the repository to customize managetests

This allows different branches to use different commands to build,
install and run. Branches directory version changed to "2".
parent 9d6fde94
......@@ -18,9 +18,10 @@ import sys
import subprocess
import os
import shutil
import json
BRANCH_DIR_VERSION = "1"
BRANCH_DIR_VERSION = "2"
class Branch:
......@@ -37,11 +38,13 @@ class Branch:
self.author_url = None
self.assignee = None
self.assignee_url = None
self.config = None
self.pinned = name in manager.config["keep-branches"]
self.check_remote_status()
self.check_local_status()
self.load_config()
def check_remote_status(self):
"""Check the branch merging status on GitLab"""
......@@ -82,15 +85,8 @@ class Branch:
if not (root.exists() and root.is_dir()):
return False
# All the subdirectories must be present
dirs = ["env", "public", "data"]
for dir in dirs:
dir = root / dir
if not (dir.exists() and dir.is_dir()):
return False
# All the files must be be present
files = ["version"]
files = ["version", "config.json"]
for file in files:
file = root / file
if not (file.exists() and file.is_file()):
......@@ -103,6 +99,45 @@ class Branch:
return True
def load_config(self):
"""Load the configuration of this branch"""
file = self.manager.root / "branches" / self.name / "config.json"
self.config = None
# Load the configuration only if this branch exists
if file.exists():
with file.open() as f:
self.config = json.load(f)
def exec_command(self, raw_command, replaces=None, build=False):
"""Exec a command in the context of the branch"""
args, kwargs = self.command_popen_args(raw_command, replaces, build)
return subprocess.call(*args, **kwargs)
def command_popen_args(self, raw_command, replaces=None, build=False):
"""Get the Popen arguments for exec_command"""
base = self.manager.root / "branches" / self.name
home = base
if build:
home /= "build"
env = dict(os.environ)
env["HOME"] = str(home)
if replaces is None:
replaces = {}
replaces.setdefault("base", str(base))
command = []
for part in raw_command:
for key, value in replaces.items():
part = part.replace("{{%s}}" % key, value)
command.append(part)
return [command], {"env": env, "cwd": str(home)}
def deploy(self):
"""Deploy the branch"""
self.check_local_status()
......@@ -111,6 +146,8 @@ class Branch:
if self.present:
return
print("[i] Started a build of '%s'" % self.name)
# Start from a fresh branch dir
branch = self.manager.root / "branches" / self.name
if branch.exists():
......@@ -121,9 +158,7 @@ class Branch:
build_dir = branch / "build"
# Create subdirectories
subdirs = ["env", "public", "data", "build"]
for dir in subdirs:
(branch / dir).mkdir()
build_dir.mkdir()
# Create the version file
with (branch / "version").open("w") as f:
......@@ -136,33 +171,39 @@ class Branch:
"checkout", "-f", self.name,
])
# Build the website
env = dict(os.environ)
env["HOME"] = str(build_dir)
subprocess.call(["invoke", "build"], cwd=str(build_dir), env=env)
# Check if the build results exists
results = list(build_dir.glob("build/packages/*.whl"))
if not results:
# Copy and load the configuration file
if not (build_dir / "managetests.json").exists():
print("[!] No managetests.json found in the branch!")
print("[!] Aborting!")
return False
# Create a new environment and install all the results in it
subprocess.call(["virtualenv", "-p", "python3", str(branch / "env")])
for result in results:
subprocess.call([
"%s/bin/pip" % str(branch / "env"), "install", str(result)
])
# Calculate the static files directory
py_version = ".".join(str(i) for i in tuple(sys.version_info)[:2])
static_dir = (
branch / "env" / "lib" / ("python%s" % py_version) /
"site-packages" / "uitwww" / "static"
shutil.copy(
str(build_dir / "managetests.json"),
str(branch / "config.json")
)
self.load_config()
# Link the assets directory to the static files one
assets = branch / "public" / "+assets"
assets.symlink_to(static_dir)
# Build the website
for cmd in self.config["build"]:
self.exec_command(cmd, build=True)
# Execute the pre-install commands
for cmd in self.config["before_install"]:
self.exec_command(cmd, build=True)
# Install the builded artifacts
total = 0
for part in self.config["install"]:
artifacts = list(build_dir.glob(part["artifacts"]))
total += len(artifacts)
for artifact in artifacts:
self.exec_command(part["command"], {
"artifact": str(artifact),
}, build=True)
if total == 0:
print("[!] Warning: no artifact was installed!")
# Delete the build directory
shutil.rmtree(str(build_dir))
......
......@@ -79,16 +79,16 @@ class InstancesManager:
def _run_branch(self, branch):
"""Run a single branch"""
branch_dir = self.manager.root / "branches" / branch.name
command_path = str(branch_dir / "env" / "bin" / "uitwww")
command = [
command_path, "run", "-g",
"%s.py" % self.manager.gunicorn_config_file,
str(branch_dir / "data")
]
if branch.config is None:
print("[!] No build found for branch '%s'" % branch.name)
return
args, kwargs = branch.command_popen_args(branch.config["run"], {
"gunicorn_config_file": "%s.py" % self.manager.gunicorn_config_file,
})
try:
process = subprocess.Popen(command)
process = subprocess.Popen(*args, **kwargs)
except FileNotFoundError:
print("managetests: error: can't start the %s branch: executable "
"not found" % branch.name)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment