Use pluggy for fetching mod version
This commit is contained in:
parent
6493f56b83
commit
1e64a589a9
10 changed files with 84 additions and 33 deletions
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
|
@ -16,7 +16,7 @@
|
|||
"name": "Python: Generate Docs",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"module": "hexdoc.hexdoc",
|
||||
"module": "hexdoc.scripts.hexdoc",
|
||||
"args": [
|
||||
"doc/properties.toml", "-o", "out", "--lang", "en_us",
|
||||
],
|
||||
|
|
7
doc/src/hexdoc/hexcasting/hooks.py
Normal file
7
doc/src/hexdoc/hexcasting/hooks.py
Normal file
|
@ -0,0 +1,7 @@
|
|||
from hexdoc.__gradle_version__ import GRADLE_VERSION
|
||||
from hexdoc.plugin import hookimpl
|
||||
|
||||
|
||||
@hookimpl
|
||||
def hexdoc_mod_version():
|
||||
return GRADLE_VERSION
|
5
doc/src/hexdoc/plugin/__init__.py
Normal file
5
doc/src/hexdoc/plugin/__init__.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
__all__ = ["hookimpl"]
|
||||
|
||||
from pluggy import HookimplMarker
|
||||
|
||||
hookimpl = HookimplMarker("hexdoc")
|
10
doc/src/hexdoc/plugin/helpers.py
Normal file
10
doc/src/hexdoc/plugin/helpers.py
Normal file
|
@ -0,0 +1,10 @@
|
|||
from pluggy import PluginManager
|
||||
|
||||
|
||||
def name_hook_caller(pm: PluginManager, method_name: str, plugin_name: str):
|
||||
return pm.subset_hook_caller(
|
||||
name=method_name,
|
||||
remove_plugins=(
|
||||
plugin for name, plugin in pm.list_name_plugin() if name != plugin_name
|
||||
),
|
||||
)
|
8
doc/src/hexdoc/plugin/hookspecs.py
Normal file
8
doc/src/hexdoc/plugin/hookspecs.py
Normal file
|
@ -0,0 +1,8 @@
|
|||
from pluggy import HookspecMarker
|
||||
|
||||
hookspec = HookspecMarker("hexdoc")
|
||||
|
||||
|
||||
@hookspec(firstresult=True)
|
||||
def hexdoc_mod_version():
|
||||
"""Return the mod version (aka `GRADLE_VERSION`) from `__gradle_version__.py`."""
|
|
@ -6,6 +6,7 @@ import shutil
|
|||
import sys
|
||||
from argparse import ArgumentParser
|
||||
from pathlib import Path
|
||||
from types import NoneType
|
||||
from typing import Self, Sequence
|
||||
|
||||
from jinja2 import (
|
||||
|
@ -16,13 +17,16 @@ from jinja2 import (
|
|||
Template,
|
||||
)
|
||||
from jinja2.sandbox import SandboxedEnvironment
|
||||
from pluggy import PluginManager
|
||||
from pydantic import model_validator
|
||||
|
||||
from hexdoc.__gradle_version__ import GRADLE_VERSION
|
||||
from hexdoc.hexcasting.hex_book import load_hex_book
|
||||
from hexdoc.minecraft import I18n
|
||||
from hexdoc.patchouli import Book
|
||||
from hexdoc.plugin import hookspecs
|
||||
from hexdoc.plugin.helpers import name_hook_caller
|
||||
from hexdoc.utils import HexdocModel, ModResourceLoader, Properties
|
||||
from hexdoc.utils.deserialize import cast_or_raise, isinstance_or_raise
|
||||
from hexdoc.utils.jinja_extensions import IncludeRawExtension, hexdoc_block, hexdoc_wrap
|
||||
from hexdoc.utils.path import write_to_path
|
||||
|
||||
|
@ -113,15 +117,15 @@ class SitemapMarker(HexdocModel):
|
|||
|
||||
|
||||
def main(args: Args | None = None) -> None:
|
||||
# set stdout to utf-8 so printing to pipe or redirect doesn't break on Windows
|
||||
# (common windows L)
|
||||
cast_or_raise(sys.stdout, io.TextIOWrapper).reconfigure(encoding="utf-8")
|
||||
cast_or_raise(sys.stderr, io.TextIOWrapper).reconfigure(encoding="utf-8")
|
||||
|
||||
# allow passing Args for test cases, but parse by default
|
||||
if args is None:
|
||||
args = Args.parse_args()
|
||||
|
||||
# set stdout to utf-8 so printing to pipe or redirect doesn't break on Windows
|
||||
# (common windows L)
|
||||
assert isinstance(sys.stdout, io.TextIOWrapper)
|
||||
sys.stdout.reconfigure(encoding="utf-8")
|
||||
|
||||
# set up logging
|
||||
logging.basicConfig(
|
||||
style="{",
|
||||
|
@ -130,18 +134,34 @@ def main(args: Args | None = None) -> None:
|
|||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Properties is the main config file for hexdoc
|
||||
props = Properties.load(args.properties_file)
|
||||
logger.debug(props)
|
||||
|
||||
# load plugins
|
||||
# load entry points for props.modid first to make sure its version is added last
|
||||
pm = PluginManager("hexdoc")
|
||||
pm.add_hookspecs(hookspecs)
|
||||
pm.load_setuptools_entrypoints("hexdoc")
|
||||
pm.check_pending()
|
||||
|
||||
# get the current mod version
|
||||
version = name_hook_caller(pm, "hexdoc_mod_version", props.modid)()
|
||||
assert isinstance_or_raise(version, (str, NoneType))
|
||||
if version is None:
|
||||
raise ValueError(f"Missing hexdoc_mod_version hookimpl for {props.modid}")
|
||||
|
||||
print(f"Building docs for {props.modid} {version}")
|
||||
|
||||
# just list the languages and exit
|
||||
if args.list_langs:
|
||||
with ModResourceLoader.load_all(props, export=False) as loader:
|
||||
with ModResourceLoader.load_all(props, version, export=False) as loader:
|
||||
langs = sorted(I18n.list_all(loader))
|
||||
print(json.dumps(langs))
|
||||
return
|
||||
|
||||
# load everything
|
||||
with ModResourceLoader.clean_and_load_all(props) as loader:
|
||||
with ModResourceLoader.clean_and_load_all(props, version) as loader:
|
||||
books = dict[str, Book]()
|
||||
|
||||
if args.lang:
|
||||
|
@ -181,7 +201,8 @@ def main(args: Args | None = None) -> None:
|
|||
if args.export_only:
|
||||
return
|
||||
|
||||
# set up Jinja environment
|
||||
# set up Jinja
|
||||
|
||||
env = SandboxedEnvironment(
|
||||
# search order: template_dirs, template_packages
|
||||
loader=ChoiceLoader(
|
||||
|
@ -204,6 +225,8 @@ def main(args: Args | None = None) -> None:
|
|||
|
||||
template = env.get_template(props.template.main)
|
||||
|
||||
# render everything
|
||||
|
||||
assert (output_dir := args.output_dir)
|
||||
if args.clean:
|
||||
shutil.rmtree(output_dir, ignore_errors=True)
|
||||
|
@ -212,11 +235,11 @@ def main(args: Args | None = None) -> None:
|
|||
render_books(props, books, template, output_dir, "latest")
|
||||
|
||||
if args.is_release:
|
||||
render_books(props, books, template, output_dir, GRADLE_VERSION)
|
||||
render_books(props, books, template, output_dir, version)
|
||||
|
||||
# the default book should be the latest released version
|
||||
if args.update_latest and args.is_release:
|
||||
render_books(props, books, template, output_dir, GRADLE_VERSION, is_root=True)
|
||||
render_books(props, books, template, output_dir, version, is_root=True)
|
||||
|
||||
|
||||
def render_books(
|
||||
|
|
|
@ -6,7 +6,6 @@ from typing import Self, Sequence
|
|||
|
||||
from pydantic import Field, TypeAdapter
|
||||
|
||||
from hexdoc.__gradle_version__ import GRADLE_VERSION
|
||||
from hexdoc.utils import DEFAULT_CONFIG, HexdocModel
|
||||
from hexdoc.utils.path import write_to_path
|
||||
|
||||
|
@ -57,10 +56,11 @@ def main():
|
|||
args = Args.parse_args()
|
||||
|
||||
# ensure at least the default language was built successfully
|
||||
if args.is_release:
|
||||
assert_version_exists(args.src, GRADLE_VERSION)
|
||||
if args.update_latest:
|
||||
assert_version_exists(args.src, "latest")
|
||||
# TODO: figure out how to do this with pluggy
|
||||
# if args.is_release:
|
||||
# assert_version_exists(args.src, GRADLE_VERSION)
|
||||
|
||||
args.dst.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ from enum import Enum
|
|||
from functools import total_ordering
|
||||
from typing import Any, Callable, Self
|
||||
|
||||
from hexdoc.__gradle_version__ import GRADLE_VERSION
|
||||
from hexdoc.__gradle_version__ import GRADLE_VERSION as HEX_VERSION
|
||||
|
||||
|
||||
@total_ordering
|
||||
|
@ -14,9 +14,9 @@ class HexVersion(Enum):
|
|||
@classmethod
|
||||
def get(cls):
|
||||
for version in cls:
|
||||
if GRADLE_VERSION.startswith(version.value):
|
||||
if HEX_VERSION.startswith(version.value):
|
||||
return version
|
||||
raise ValueError(f"Unknown mod version: {GRADLE_VERSION}")
|
||||
raise ValueError(f"Unknown mod version: {HEX_VERSION}")
|
||||
|
||||
@classmethod
|
||||
def check(cls, version: Self | Callable[[Self], bool] | bool, typ: type[Any] | str):
|
||||
|
@ -33,7 +33,7 @@ class HexVersion(Enum):
|
|||
|
||||
if not isinstance(typ, str):
|
||||
typ = typ.__name__
|
||||
raise ValueError(f"{typ} is not supported in {GRADLE_VERSION}")
|
||||
raise ValueError(f"{typ} is not supported in {HEX_VERSION}")
|
||||
|
||||
@property
|
||||
def _sort_by(self):
|
||||
|
|
|
@ -9,7 +9,6 @@ from typing import Callable, Literal, Self, TypeVar, overload
|
|||
|
||||
from pydantic.dataclasses import dataclass
|
||||
|
||||
from hexdoc.__gradle_version__ import GRADLE_VERSION
|
||||
from hexdoc.utils.deserialize import JSONDict, decode_json_dict
|
||||
from hexdoc.utils.model import DEFAULT_CONFIG, HexdocModel, ValidationContext
|
||||
from hexdoc.utils.path import strip_suffixes, write_to_path
|
||||
|
@ -45,19 +44,21 @@ class ModResourceLoader:
|
|||
def clean_and_load_all(
|
||||
cls,
|
||||
props: Properties,
|
||||
version: str,
|
||||
*,
|
||||
export: bool = True,
|
||||
):
|
||||
# clear the export dir so we start with a clean slate
|
||||
if props.export_dir and export:
|
||||
subprocess.run(["git", "clean", "-fdX", props.export_dir])
|
||||
return cls.load_all(props, export=export)
|
||||
return cls.load_all(props, version, export=export)
|
||||
|
||||
@classmethod
|
||||
@contextmanager
|
||||
def load_all(
|
||||
cls,
|
||||
props: Properties,
|
||||
version: str,
|
||||
*,
|
||||
export: bool = True,
|
||||
) -> Iterator[Self]:
|
||||
|
@ -78,7 +79,7 @@ class ModResourceLoader:
|
|||
loader.export(
|
||||
path=HexdocMetadata.path(props.modid),
|
||||
data=HexdocMetadata(
|
||||
book_url=f"{props.url}/v/{GRADLE_VERSION}",
|
||||
book_url=f"{props.url}/v/{version}",
|
||||
).model_dump_json(),
|
||||
)
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
requires = ["hatchling", "hatch-gradle-version>=0.6.0"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
# project metadata
|
||||
|
@ -8,7 +8,7 @@ build-backend = "hatchling.build"
|
|||
name = "hexdoc"
|
||||
dynamic = ["version"]
|
||||
authors = [
|
||||
{ name="object-Object", email="object@objectobject.ca" },
|
||||
{ name="object-Object" },
|
||||
{ name="Alwinfy" },
|
||||
]
|
||||
readme = "doc/README.md"
|
||||
|
@ -17,18 +17,15 @@ classifiers = [
|
|||
]
|
||||
requires-python = ">=3.11"
|
||||
dependencies = [
|
||||
"hexdoc[build]", # required optional dependency i guess
|
||||
"typing_extensions>=4.6.1",
|
||||
"importlib_resources>=6.0.1",
|
||||
"pydantic>=2.3.0",
|
||||
"Jinja2>=3.1.2",
|
||||
"pyjson5>=1.6.3",
|
||||
"pluggy>=1.3.0",
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
build = [ # need these for build AND runtime
|
||||
"hatch-gradle-version>=0.6.0",
|
||||
]
|
||||
dev = [
|
||||
"black==23.7.0",
|
||||
"isort==5.12.0",
|
||||
|
@ -52,9 +49,6 @@ py-path = "doc/src/hexdoc/__version__.py"
|
|||
# directory inclusion
|
||||
|
||||
[tool.hatch.build]
|
||||
require-runtime-features = [
|
||||
"build",
|
||||
]
|
||||
artifacts = [
|
||||
"/doc/src/hexdoc/_export/generated",
|
||||
"/doc/src/hexdoc/__gradle_version__.py",
|
||||
|
@ -73,6 +67,9 @@ packages = [
|
|||
|
||||
# hexdoc entry points
|
||||
|
||||
[project.entry-points.hexdoc]
|
||||
hexcasting = "hexdoc.hexcasting.hooks"
|
||||
|
||||
[project.entry-points."hexdoc.export"]
|
||||
hexcasting = "hexdoc._export:__resources__"
|
||||
|
||||
|
@ -110,8 +107,8 @@ known_first_party = ["hexdoc"]
|
|||
pythonVersion = "3.11"
|
||||
pythonPlatform = "All"
|
||||
|
||||
include = [
|
||||
"doc/src/hexdoc",
|
||||
extraPaths = [
|
||||
"doc/src",
|
||||
]
|
||||
|
||||
# mostly we use strict mode
|
||||
|
|
Loading…
Reference in a new issue