diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 03f63036..9fbc75f5 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -25,7 +25,12 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: run init.sh - run: ./scripts/init.sh - - name: run test.sh - run: ./scripts/test.sh + + - name: create venv + run: python3 -m venv + + - name: install packages into venv + run: venv/bin/pip install chatmaild deploy_chatmail + + - name: run tests + - run: venv/bin/cmdeploy test diff --git a/README.md b/README.md index 168e3eaa..693c276c 100644 --- a/README.md +++ b/README.md @@ -36,26 +36,22 @@ DNS domain name (FQDN), for example `chat.example.org`. 3. Create chatmail configuration file `chatmail.ini`: ``` - cmdeploy init chatmail.ini CHATMAIL_DOMAIN + cmdeploy init CHATMAIL_DOMAIN ``` -4. Deploy to the remote chatmail server, pointing to the chatmail config file: +4. Deploy to the remote chatmail server: ``` - cmdeploy install chatmail.ini + cmdeploy run ``` 5. To output a DNS zone file from which you can transfer DNS records - to your DNS provider for your `CHATMAIL_DOMAIN` + to your DNS provider: ``` - cmdeploy dns chatmail.ini + cmdeploy dnszone ``` - to generate a DNS zone file from which you can transfer records to your - DNS provider. - - ### Refining the web pages diff --git a/chatmaild/src/chatmaild/config.py b/chatmaild/src/chatmaild/config.py index 446521a8..5058cc74 100644 --- a/chatmaild/src/chatmaild/config.py +++ b/chatmaild/src/chatmaild/config.py @@ -1,5 +1,3 @@ -from pathlib import Path -from fnmatch import fnmatch import iniconfig @@ -23,3 +21,31 @@ class Config: def _getbytefile(self): return open(self._inipath, "rb") + + +def write_initial_config(inipath, mailname): + from importlib.resources import files + + inidir = files(__package__).joinpath("ini") + content = inidir.joinpath("chatmail.ini.f").read_text().format(mailname=mailname) + if mailname.endswith(".testrun.org"): + override_inipath = inidir.joinpath("override-testrun.ini") + privacy = iniconfig.IniConfig(override_inipath)["privacy"] + lines = [] + for line in content.split("\n"): + for key, value in privacy.items(): + value_lines = value.strip().split("\n") + if not line.startswith(f"{key} =") or not value_lines: + continue + if len(value_lines) == 1: + lines.append(f"{key} = {value}") + else: + lines.append(f"{key} =") + for vl in value_lines: + lines.append(f" {vl}") + break + else: + lines.append(line) + content = "\n".join(lines) + + inipath.write_text(content) diff --git a/chatmaild/src/chatmaild/filtermail.py b/chatmaild/src/chatmaild/filtermail.py index c0f318f6..fdc77085 100644 --- a/chatmaild/src/chatmaild/filtermail.py +++ b/chatmaild/src/chatmaild/filtermail.py @@ -7,7 +7,6 @@ from email.parser import BytesParser from email import policy from email.utils import parseaddr -from aiosmtpd.smtp import SMTP from aiosmtpd.controller import Controller from smtplib import SMTP as SMTPClient diff --git a/deploy-chatmail/src/deploy_chatmail/ini/chatmail.ini.f b/chatmaild/src/chatmaild/ini/chatmail.ini.f similarity index 100% rename from deploy-chatmail/src/deploy_chatmail/ini/chatmail.ini.f rename to chatmaild/src/chatmaild/ini/chatmail.ini.f diff --git a/deploy-chatmail/src/deploy_chatmail/ini/override-testrun.ini b/chatmaild/src/chatmaild/ini/override-testrun.ini similarity index 100% rename from deploy-chatmail/src/deploy_chatmail/ini/override-testrun.ini rename to chatmaild/src/chatmaild/ini/override-testrun.ini diff --git a/deploy-chatmail/src/deploy_chatmail/cmdeploy.py b/deploy-chatmail/src/deploy_chatmail/cmdeploy.py index 6b465bfe..1a40900f 100644 --- a/deploy-chatmail/src/deploy_chatmail/cmdeploy.py +++ b/deploy-chatmail/src/deploy_chatmail/cmdeploy.py @@ -4,6 +4,7 @@ along with command line option and subcommand parsing. """ import importlib.resources import argparse +import shutil import subprocess import os from pathlib import Path @@ -11,7 +12,7 @@ from pathlib import Path import iniconfig from termcolor import colored -from chatmaild.config import read_config +from chatmaild.config import read_config, write_initial_config class Out: @@ -52,6 +53,7 @@ def add_subcommand(subparsers, func): doc = func.__doc__.strip() p = subparsers.add_parser(name, description=doc, help=doc) p.set_defaults(func=func) + add_config_option(p) return p @@ -63,15 +65,13 @@ def get_parser(): ) init_parser = add_subcommand(subparsers, init_cmd) - add_config_option(init_parser) init_parser.add_argument( "chatmail_domain", action="store", help="fully qualified DNS domain name for your chatmail instance", ) - install_parser = add_subcommand(subparsers, install_cmd) - add_config_option(install_parser) + install_parser = add_subcommand(subparsers, run_cmd) install_parser.add_argument( "--dry-run", dest="dry_run", @@ -80,46 +80,24 @@ def get_parser(): ) add_subcommand(subparsers, webdev_cmd) + + add_subcommand(subparsers, test_cmd) + return parser -def write_initial_config(inipath, mailname, out): - inidir = importlib.resources.files(__package__).joinpath("ini") - content = inidir.joinpath("chatmail.ini.f").read_text().format(mailname=mailname) - if mailname.endswith(".testrun.org"): - override_inipath = inidir.joinpath("override-testrun.ini") - privacy = iniconfig.IniConfig(override_inipath)["privacy"] - lines = [] - for line in content.split("\n"): - for key, value in privacy.items(): - value_lines = value.strip().split("\n") - if not line.startswith(f"{key} =") or not value_lines: - continue - if len(value_lines) == 1: - lines.append(f"{key} = {value}") - else: - lines.append(f"{key} =") - for vl in value_lines: - lines.append(f" {vl}") - break - else: - lines.append(line) - content = "\n".join(lines) - - inipath.write_text(content) - out(f"written {inipath} for chatmail domain {mailname}") - def init_cmd(args, out): """Initialize chatmail config file.""" if args.chatmail_ini.exists(): out.red(f"Path exists, not modifying: {args.chatmail_ini}") raise SystemExit(1) - write_initial_config(args.chatmail_ini, args.chatmail_domain, out) + write_initial_config(args.chatmail_ini, args.chatmail_domain) + out.green(f"created config file for {args.chatmail_domain} in {args.chatmail_ini}") -def install_cmd(args, out): - """Install or update chatmail services on the remote server.""" +def run_cmd(args, out): + """Deploy chatmail services on the remote server.""" import pyinfra try: @@ -147,6 +125,17 @@ def webdev_cmd(args, out): main() +def test_cmd(args, out): + """run Run web development loop for static local web pages.""" + + tox = shutil.which("tox") + subprocess.check_call([tox, "-c", "chatmaild"]) + subprocess.check_call([tox, "-c", "deploy-chatmail"]) + + pytest_path = shutil.which("tox") + subprocess.check_call([pytest_path, "tests/online", "-rs", "-x", "-vrx", "--durations=5"]) + + def main(args=None): """Provide main entry point for 'xdcget' CLI invocation.""" parser = get_parser() diff --git a/scripts/deploy.sh b/scripts/deploy.sh deleted file mode 100755 index e3def8ec..00000000 --- a/scripts/deploy.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -echo ----------------------------------------- -echo deploying to $CHATMAIL_DOMAIN -echo ----------------------------------------- - - -venv/bin/pyinfra --ssh-user root "$CHATMAIL_DOMAIN" \ - deploy-chatmail/src/deploy_chatmail/deploy.py run chatmail.ini diff --git a/scripts/init.sh b/scripts/init.sh deleted file mode 100755 index f658cdb0..00000000 --- a/scripts/init.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -set -e -python3 -m venv venv -pip=venv/bin/pip - -$pip install pyinfra pytest build 'setuptools>=68' tox -$pip install -e deploy-chatmail -$pip install -e chatmaild -venv/bin/deploy-chatmail init $* diff --git a/scripts/webdev.sh b/scripts/webdev.sh deleted file mode 100755 index 73e3f7d7..00000000 --- a/scripts/webdev.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -echo ----------------------------------------- -echo starting local webdev -echo ----------------------------------------- - -venv/bin/python3 -m deploy_chatmail.www - - diff --git a/tests/conftest.py b/tests/conftest.py index 686f72dc..eea5d6e3 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -409,12 +409,11 @@ class CMUser: @pytest.fixture def make_config(tmp_path): - from deploy_chatmail.cmdeploy import main - from chatmaild.config import read_config + from chatmaild.config import read_config, write_initial_config inipath = tmp_path.joinpath("chatmail.ini") def make_conf(mailname): - main(["init", "--config", str(inipath), mailname]) + write_initial_config(inipath, mailname=mailname) return read_config(inipath) return make_conf