Skip to content

Commit

Permalink
Make tasks work from any subpath
Browse files Browse the repository at this point in the history
Invoke is smart enough to let users execute a `tasks.py` that is found somewhere upper in the file tree. However, that would be executed under user's CWD, which is not ideal for many tasks here.

I change to use absolute paths everywhere.
  • Loading branch information
Jairo Llopis authored and github-actions[bot] committed Apr 17, 2020
1 parent 83b5ecf commit 22355ed
Show file tree
Hide file tree
Showing 10 changed files with 392 additions and 252 deletions.
119 changes: 61 additions & 58 deletions tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from invoke.util import yaml
from invoke.vendor.yaml3.reader import Reader

TEMPLATE_ROOT = Path(__file__).parent.resolve()
ESSENTIALS = ("git", "python3", "poetry")


Expand Down Expand Up @@ -48,13 +49,14 @@ def check_dependencies(c):
@task(check_dependencies)
def develop(c):
"""Set up a development environment."""
if not (Path(c.cwd) / ".venv").is_dir():
c.run("python3 -m venv .venv")
c.run("git submodule update --init --checkout --recursive")
# Use poetry to set up development environment in a local venv
c.run("poetry env use .venv/bin/python")
c.run("poetry install")
c.run("poetry run pre-commit install")
with c.cd(str(TEMPLATE_ROOT)):
if not Path(".venv").is_dir():
c.run("python3 -m venv .venv")
c.run("git submodule update --init --checkout --recursive")
# Use poetry to set up development environment in a local venv
c.run("poetry env use .venv/bin/python")
c.run("poetry install")
c.run("poetry run pre-commit install")


@task(develop)
Expand All @@ -64,7 +66,8 @@ def lint(c, verbose=False):
if verbose:
flags.append("--verbose")
flags = " ".join(flags)
c.run(f"poetry run pre-commit run {flags}")
with c.cd(str(TEMPLATE_ROOT)):
c.run(f"poetry run pre-commit run {flags}")


@task(develop)
Expand All @@ -74,7 +77,8 @@ def test(c, verbose=False):
if verbose:
flags.append("-vv")
flags = " ".join(flags)
c.run(f"poetry run pytest {flags} tests")
with c.cd(str(TEMPLATE_ROOT)):
c.run(f"poetry run pytest {flags} tests")


@task(develop)
Expand All @@ -89,52 +93,51 @@ def update_test_samples(c):
This job updates all those samples.
"""
# Make sure git repo is clean
try:
c.run("git diff --quiet --exit-code")
except Exception:
print("git repo is dirty; clean it and repeat")
raise
copier_conf = _load_copier_conf()
all_odoo_versions = copier_conf["odoo_version"]["choices"]
default_odoo_version = copier_conf["odoo_version"]["default"]
default_settings_path = Path("tests", "default_settings")
shutil.rmtree(default_settings_path)
default_settings_path.mkdir()
try:
c.run("git tag --force test")
for odoo_version in all_odoo_versions:
v = f"{odoo_version:.1f}"
dst = default_settings_path / f"v{v}"
c.run(f"poetry run copier -fr test -d odoo_version={v} copy . {dst}")
shutil.rmtree(dst / ".git")
finally:
c.run("git tag --delete test")
samples = Path("tests", "samples")
c.run(
"poetry run copier -fr HEAD -x '**' -x '!prod.yaml' -x '!test.yaml' "
"-d cidr_whitelist='[123.123.123.123/24, 456.456.456.456]' "
f"copy . {samples / 'cidr-whitelist'}",
warn=True,
)
for file_name in (".pylintrc", ".pylintrc-mandatory"):
with (samples / "mqt-diffs" / f"{file_name}.diff").open("w") as fd:
own = default_settings_path / f"v{default_odoo_version}" / file_name
mqt = Path(
"vendor",
"maintainer-quality-tools",
"sample_files",
f"pre-commit-{default_odoo_version}",
file_name,
)
fd.write(c.run(f"diff {own} {mqt}", warn=True).stdout)
shutil.rmtree(samples / "cidr-whitelist" / ".venv")
c.run(
"poetry run copier -fr HEAD -x '**' -x '!prod.yaml' "
"-d domain_prod=www.example.com "
"-d domain_prod_alternatives='[old.example.com, example.com, example.org, www.example.org]' "
f"copy . {samples /'alt-domains'}",
warn=True,
)
shutil.rmtree(samples / "alt-domains" / ".venv")
c.run("poetry run pre-commit run -a", warn=True)
with c.cd(str(TEMPLATE_ROOT)):
# Make sure git repo is clean
try:
c.run("git diff --quiet --exit-code")
except Exception:
print("git repo is dirty; clean it and repeat")
raise
copier_conf = _load_copier_conf()
all_odoo_versions = copier_conf["odoo_version"]["choices"]
default_odoo_version = copier_conf["odoo_version"]["default"]
default_settings_path = Path("tests", "default_settings")
shutil.rmtree(default_settings_path)
default_settings_path.mkdir()
try:
c.run("git tag --force test")
for odoo_version in all_odoo_versions:
v = f"{odoo_version:.1f}"
dst = default_settings_path / f"v{v}"
c.run(f"poetry run copier -fr test -d odoo_version={v} copy . {dst}")
shutil.rmtree(dst / ".git")
finally:
c.run("git tag --delete test")
samples = Path("tests", "samples")
c.run(
"poetry run copier -fr HEAD -x '**' -x '!prod.yaml' -x '!test.yaml' "
"-d cidr_whitelist='[123.123.123.123/24, 456.456.456.456]' "
f"copy . {samples / 'cidr-whitelist'}",
warn=True,
)
for file_name in (".pylintrc", ".pylintrc-mandatory"):
with (samples / "mqt-diffs" / f"{file_name}.diff").open("w") as fd:
own = default_settings_path / f"v{default_odoo_version}" / file_name
mqt = Path(
"vendor",
"maintainer-quality-tools",
"sample_files",
f"pre-commit-{default_odoo_version}",
file_name,
)
fd.write(c.run(f"diff {own} {mqt}", warn=True).stdout)
c.run(
"poetry run copier -fr HEAD -x '**' -x '!prod.yaml' "
"-d domain_prod=www.example.com "
"-d domain_prod_alternatives='[old.example.com, example.com, example.org, www.example.org]' "
f"copy . {samples / 'alt-domains'}",
warn=True,
)
c.run("poetry run pre-commit run -a", warn=True)
65 changes: 41 additions & 24 deletions tasks_downstream.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@

from invoke import task

SRC_PATH = Path("odoo", "custom", "src")
PROJECT_ROOT = Path(__file__).parent.absolute()
SRC_PATH = PROJECT_ROOT / "odoo" / "custom" / "src"
DEVELOP_DEPENDENCIES = (
"copier",
"docker-compose",
"pre-commit",
)
UID_ENV = {"GID": str(os.getgid()), "UID": str(os.getuid()), "UMASK": "27"}


@task
Expand All @@ -40,19 +42,23 @@ def write_code_workspace_file(c, cw_path=None):
"""
if not cw_path:
try:
cw_path = next(iglob(str(Path(c.cwd, "doodba.*.code-workspace"))))
cw_path = next(iglob(str(PROJECT_ROOT / "doodba.*.code-workspace")))
except StopIteration:
cw_path = f"doodba.{Path(c.cwd).absolute().name}.code-workspace"
cw_path = f"doodba.{PROJECT_ROOT.name}.code-workspace"
if not Path(cw_path).is_absolute():
cw_path = PROJECT_ROOT / cw_path
cw_config = {}
try:
with open(cw_path) as cw_fd:
cw_config = json.load(cw_fd)
except (FileNotFoundError, json.decoder.JSONDecodeError):
cw_config = {}
pass # Nevermind, we start with a new config
cw_config["folders"] = []
addon_repos = glob(str(Path(c.cwd, SRC_PATH, "private")))
addon_repos += glob(str(Path(c.cwd, SRC_PATH, "*", ".git", "..")))
addon_repos = glob(str(SRC_PATH / "private"))
addon_repos += glob(str(SRC_PATH / "*" / ".git" / ".."))
for subrepo in sorted(addon_repos):
cw_config["folders"].append({"path": subrepo})
subrepo = Path(subrepo)
cw_config["folders"].append({"path": str(subrepo.relative_to(PROJECT_ROOT))})
# HACK https://github.com/microsoft/vscode/issues/37947 put top folder last
cw_config["folders"].append({"path": "."})
with open(cw_path, "w") as cw_fd:
Expand All @@ -74,10 +80,11 @@ def develop(c):
c.run("python3 -m pip install --user pipx")
c.run(f"pipx install {dep}")
# Prepare environment
c.run("git init")
c.run("ln -sf devel.yaml docker-compose.yml")
write_code_workspace_file(c)
c.run("pre-commit install")
with c.cd(str(PROJECT_ROOT)):
c.run("git init")
c.run("ln -sf devel.yaml docker-compose.yml")
write_code_workspace_file(c)
c.run("pre-commit install")


@task(develop)
Expand All @@ -86,12 +93,12 @@ def git_aggregate(c):
Executes git-aggregator from within the doodba container.
"""
c.run(
"docker-compose --file setup-devel.yaml run --rm odoo",
env={"GID": str(os.getgid()), "UID": str(os.getuid()), "UMASK": "27"},
)
with c.cd(str(PROJECT_ROOT)):
c.run(
"docker-compose --file setup-devel.yaml run --rm odoo", env=UID_ENV,
)
write_code_workspace_file(c)
for git_folder in iglob(str(Path(c.cwd, SRC_PATH, "*", ".git", ".."))):
for git_folder in iglob(str(SRC_PATH / "*" / ".git" / "..")):
action = (
"install"
if Path(git_folder, ".pre-commit-config.yaml").is_file()
Expand All @@ -107,13 +114,15 @@ def img_build(c, pull=True):
cmd = "docker-compose build"
if pull:
cmd += " --pull"
c.run(cmd, env={"UID": str(os.getuid()), "GID": str(os.getgid())})
with c.cd(str(PROJECT_ROOT)):
c.run(cmd, env=UID_ENV)


@task(develop)
def img_pull(c):
"""Pull docker images."""
c.run("docker-compose pull")
with c.cd(str(PROJECT_ROOT)):
c.run("docker-compose pull")


@task(develop)
Expand All @@ -122,7 +131,8 @@ def lint(c, verbose=False):
cmd = "pre-commit run --show-diff-on-failure --all-files --color=always"
if verbose:
cmd += " --verbose"
c.run(cmd)
with c.cd(str(PROJECT_ROOT)):
c.run(cmd)


@task(develop)
Expand All @@ -131,18 +141,23 @@ def start(c, detach=True, ptvsd=False):
cmd = "docker-compose up"
if detach:
cmd += " --detach"
c.run(cmd, env={"DOODBA_PTVSD_ENABLE": str(int(ptvsd))})
with c.cd(str(PROJECT_ROOT)):
c.run(cmd, env={"DOODBA_PTVSD_ENABLE": str(int(ptvsd))})


@task(develop, help={"purge": "Remove all related containers, images and volumes"})
@task(
develop,
help={"purge": "Remove all related containers, networks images and volumes"},
)
def stop(c, purge=False):
"""Stop and (optionally) purge environment."""
cmd = "docker-compose"
if purge:
cmd += " down --remove-orphans --rmi local --volumes"
else:
cmd += " stop"
c.run(cmd)
with c.cd(str(PROJECT_ROOT)):
c.run(cmd)


@task(develop)
Expand All @@ -152,7 +167,8 @@ def restart(c, quick=True):
if quick:
cmd = f"{cmd} -t0"
cmd = f"{cmd} odoo odoo_proxy"
c.run(cmd)
with c.cd(str(PROJECT_ROOT)):
c.run(cmd)


@task(develop)
Expand All @@ -161,4 +177,5 @@ def logs(c, tail=10):
cmd = "docker-compose logs -f"
if tail:
cmd += f" --tail {tail}"
c.run(cmd)
with c.cd(str(PROJECT_ROOT)):
c.run(cmd)
Loading

0 comments on commit 22355ed

Please sign in to comment.