Add Symlink(Output) class

This commit is contained in:
2026-08-14 23:55:48 +02:00
parent 1a5f3bfc67
commit 5660ef2974
4 changed files with 48 additions and 3 deletions
+4 -1
View File
@@ -1,13 +1,15 @@
from omicron.ssg.output.output import Output
from omicron.ssg.output.output import Output, OutputError
from omicron.ssg.output.content import Content, ContentError
from omicron.ssg.output.factory import create_content, is_content
from omicron.ssg.output.file import File
from omicron.ssg.output.index import Index, discover_index
from omicron.ssg.output.memory import Memory
from omicron.ssg.output.symlink import Symlink
from omicron.ssg.output.tags import Tags, discover_tags
__all__ = [
"Output",
"OutputError",
"Content",
"ContentError",
"create_content",
@@ -16,6 +18,7 @@ __all__ = [
"Index",
"discover_index",
"Memory",
"Symlink",
"Tags",
"discover_tags",
]
+2 -2
View File
@@ -1,6 +1,6 @@
import re
from typing import TYPE_CHECKING
from omicron.ssg.output.output import Output
from omicron.ssg.output.output import Output, OutputError
from pathlib import Path
from datetime import date
@@ -10,7 +10,7 @@ else:
Site = "omicron.ssg.site.Site"
class ContentError(RuntimeError):
class ContentError(OutputError):
pass
+4
View File
@@ -9,6 +9,10 @@ else:
Site = "omicron.ssg.site.Site" # for runtime checking with beartype
class OutputError(RuntimeError):
pass
class Output(ABC):
def __init__(self, site: Site, destination: Path):
self._site_ref = weakref.ref(site)
+38
View File
@@ -0,0 +1,38 @@
import logging
import os
from typing import TYPE_CHECKING
from omicron.ssg.output.output import Output, OutputError
from pathlib import Path
log = logging.getLogger(__name__)
if TYPE_CHECKING:
from omicron.ssg.site import Site # for static checking with mypy
else:
Site = "omicron.ssg.site.Site" # for runtime checking with beartype
class Symlink(Output):
def __init__(self, site: Site, link: Path, target: Path):
if target.is_absolute():
raise ValueError("Symlinks must be relative")
if (
not (site.output_path / target)
.resolve()
.is_relative_to(site.output_path.resolve())
):
raise ValueError("Symlink target escapes the output directory")
super().__init__(site, link)
self.target = target
def write(self) -> None:
site = self.site
if self.target not in site.by_path:
raise OutputError(f"Symlink target '{self.target}' is not a known output")
link = site.output_path / self.destination
link.parent.mkdir(parents=True, exist_ok=True)
if link.exists() or link.is_symlink():
link.unlink()
rel_target = os.path.relpath(site.output_path / self.target, link.parent)
link.symlink_to(rel_target)
log.debug("Symlinked %s -> %s", link, rel_target)