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.content import Content, ContentError
|
||||||
from omicron.ssg.output.factory import create_content, is_content
|
from omicron.ssg.output.factory import create_content, is_content
|
||||||
from omicron.ssg.output.file import File
|
from omicron.ssg.output.file import File
|
||||||
from omicron.ssg.output.index import Index, discover_index
|
from omicron.ssg.output.index import Index, discover_index
|
||||||
from omicron.ssg.output.memory import Memory
|
from omicron.ssg.output.memory import Memory
|
||||||
|
from omicron.ssg.output.symlink import Symlink
|
||||||
from omicron.ssg.output.tags import Tags, discover_tags
|
from omicron.ssg.output.tags import Tags, discover_tags
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"Output",
|
"Output",
|
||||||
|
"OutputError",
|
||||||
"Content",
|
"Content",
|
||||||
"ContentError",
|
"ContentError",
|
||||||
"create_content",
|
"create_content",
|
||||||
@@ -16,6 +18,7 @@ __all__ = [
|
|||||||
"Index",
|
"Index",
|
||||||
"discover_index",
|
"discover_index",
|
||||||
"Memory",
|
"Memory",
|
||||||
|
"Symlink",
|
||||||
"Tags",
|
"Tags",
|
||||||
"discover_tags",
|
"discover_tags",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import re
|
import re
|
||||||
from typing import TYPE_CHECKING
|
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 pathlib import Path
|
||||||
from datetime import date
|
from datetime import date
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ else:
|
|||||||
Site = "omicron.ssg.site.Site"
|
Site = "omicron.ssg.site.Site"
|
||||||
|
|
||||||
|
|
||||||
class ContentError(RuntimeError):
|
class ContentError(OutputError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,10 @@ else:
|
|||||||
Site = "omicron.ssg.site.Site" # for runtime checking with beartype
|
Site = "omicron.ssg.site.Site" # for runtime checking with beartype
|
||||||
|
|
||||||
|
|
||||||
|
class OutputError(RuntimeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Output(ABC):
|
class Output(ABC):
|
||||||
def __init__(self, site: Site, destination: Path):
|
def __init__(self, site: Site, destination: Path):
|
||||||
self._site_ref = weakref.ref(site)
|
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