Compare commits

..

3 Commits

Author SHA1 Message Date
missytake
2521698093 XXX add merge conflict, don't merge this 2025-11-06 10:19:16 +01:00
missytake
8c85dddfa3 XXX create merge conflict 2025-11-06 10:19:16 +01:00
Alexander Dietrich
acf2bdefdf Skip www_folder if merge conflict marker found 2025-11-06 10:19:16 +01:00
5 changed files with 48 additions and 52 deletions

View File

@@ -681,7 +681,7 @@ def deploy_chatmail(config_path: Path, disable_mail: bool) -> None:
check_config(config)
mail_domain = config.mail_domain
from .www import build_webpages, get_paths
from .www import build_webpages, find_merge_conflict, get_paths
server.group(name="Create vmail group", group="vmail", system=True)
server.user(name="Create vmail user", user="vmail", group="vmail", system=True)
@@ -823,6 +823,8 @@ def deploy_chatmail(config_path: Path, disable_mail: bool) -> None:
# if www_folder was set to a non-existing folder, skip upload
if not www_path.is_dir():
logger.warning("Building web pages is disabled in chatmail.ini, skipping")
elif (path := find_merge_conflict(src_dir)) is not None:
logger.warning(f"Merge conflict found in {path}, skipping")
else:
# if www_folder is a hugo page, build it
if build_dir:

View File

@@ -73,7 +73,9 @@ def query_dns(typ, domain):
# Query authoritative nameserver directly to bypass DNS cache.
res = shell(f"dig @{ns} -r -q {domain} -t {typ} +short", print=log_progress)
return next((line for line in res.split("\n") if not line.startswith(';')), '')
if res:
return res.split("\n")[0]
return ""
def check_zonefile(zonefile, verbose=True):

View File

@@ -1,5 +1,3 @@
from copy import deepcopy
import pytest
from cmdeploy import remote
@@ -10,63 +8,38 @@ from cmdeploy.dns import check_full_zone, check_initial_remote_data
def mockdns_base(monkeypatch):
qdict = {}
def shell(command, fail_ok=False, print=print):
if command.startswith("dig"):
if command == "dig":
return "."
if "SOA" in command:
return (
"delta.chat. 21600 IN SOA ns1.first-ns.de. dns.hetzner.com."
" 2025102800 14400 1800 604800 3600"
)
command_chunks = command.split()
domain, typ = command_chunks[4], command_chunks[6]
try:
return qdict[typ][domain]
except KeyError:
return ""
return remote.rshell.shell(command=command, fail_ok=fail_ok, print=print)
def query_dns(typ, domain):
try:
return qdict[typ][domain]
except KeyError:
return ""
monkeypatch.setattr(remote.rdns, shell.__name__, shell)
monkeypatch.setattr(remote.rdns, query_dns.__name__, query_dns)
return qdict
@pytest.fixture
def mockdns_expected():
return {
"A": {"some.domain": "1.1.1.1"},
"AAAA": {"some.domain": "fde5:cd7a:9e1c:3240:5a99:936f:cdac:53ae"},
"CNAME": {
"mta-sts.some.domain": "some.domain.",
"www.some.domain": "some.domain.",
},
}
@pytest.fixture(params=["plain", "with-dns-comments"])
def mockdns(request, mockdns_base, mockdns_expected):
mockdns_base.update(deepcopy(mockdns_expected))
match request.param:
case "plain":
pass
case "with-dns-comments":
for typ, data in mockdns_base.items():
for host, result in data.items():
mockdns_base[typ][host] = (
";; some unsuccessful attempt result\n"
"; and another with a single semicolon\n"
f"{result}"
)
def mockdns(mockdns_base):
mockdns_base.update(
{
"A": {"some.domain": "1.1.1.1"},
"AAAA": {"some.domain": "fde5:cd7a:9e1c:3240:5a99:936f:cdac:53ae"},
"CNAME": {
"mta-sts.some.domain": "some.domain.",
"www.some.domain": "some.domain.",
},
}
)
return mockdns_base
class TestPerformInitialChecks:
def test_perform_initial_checks_ok1(self, mockdns, mockdns_expected):
def test_perform_initial_checks_ok1(self, mockdns):
remote_data = remote.rdns.perform_initial_checks("some.domain")
assert remote_data["A"] == mockdns_expected["A"]["some.domain"]
assert remote_data["AAAA"] == mockdns_expected["AAAA"]["some.domain"]
assert remote_data["MTA_STS"] == mockdns_expected["CNAME"]["mta-sts.some.domain"]
assert remote_data["WWW"] == mockdns_expected["CNAME"]["www.some.domain"]
assert remote_data["A"] == mockdns["A"]["some.domain"]
assert remote_data["AAAA"] == mockdns["AAAA"]["some.domain"]
assert remote_data["MTA_STS"] == mockdns["CNAME"]["mta-sts.some.domain"]
assert remote_data["WWW"] == mockdns["CNAME"]["www.some.domain"]
@pytest.mark.parametrize("drop", ["A", "AAAA"])
def test_perform_initial_checks_with_one_of_A_AAAA(self, mockdns, drop):

View File

@@ -4,6 +4,7 @@ import time
import traceback
import webbrowser
from pathlib import Path
import re
import markdown
from chatmaild.config import read_config
@@ -12,6 +13,9 @@ from jinja2 import Template
from .genqr import gen_qr_png_data
_MERGE_CONFLICT_RE = re.compile(r"^<<<<<<<.+^=======.+^>>>>>>>", re.DOTALL | re.MULTILINE)
def snapshot_dir_stats(somedir):
d = {}
for path in somedir.iterdir():
@@ -116,6 +120,17 @@ def _build_webpages(src_dir, build_dir, config):
return build_dir
def find_merge_conflict(src_dir) -> Path:
assert src_dir.exists(), src_dir
result = None
for path in src_dir.iterdir():
if path.suffix in [".css", ".html", ".md"]:
if _MERGE_CONFLICT_RE.search(path.read_text()):
result = path
break
return result
def main():
path = importlib.resources.files(__package__)
reporoot = path.joinpath("../../../").resolve()

View File

@@ -9,7 +9,11 @@
<title>{{ config.mail_domain }} {{ pagename }}</title>
<link rel="stylesheet" href="./main.css">
<link rel="icon" href="/logo.svg">
<link rel=”mask-icon” href=”/logo.svg” color=”#000000">
<<<<<<< HEAD
<link rel="mask-icon" href="/logo.svg" color="#000000">
=======
<link rel=”mask-icon” href=”/logo.svg” color=”#000001">
>>>>>>> 2da7de8 (make logo slightly brighter)
</head>
<body>