Add Symlink(Output) class
This commit is contained in:
@@ -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",
|
||||
]
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user