From 4d77560285e306a82790357bb45e39fdb854b9f5 Mon Sep 17 00:00:00 2001 From: RitikShah Date: Sun, 9 Apr 2023 18:06:56 -0700 Subject: [PATCH] feat: `beet.contrib.resource_generator` `ResourceGenerator` is a sugar-y wrapper around `ctx.generate` --- bolt/contrib/resource_generator.py | 82 +++++++++++++++++++ examples/bolt_resource_generator/beet.yml | 15 ++++ .../src/data/demo/modules/foo.bolt | 16 ++++ ...__build_bolt_resource_generator__0.pack.md | 41 ++++++++++ 4 files changed, 154 insertions(+) create mode 100644 bolt/contrib/resource_generator.py create mode 100644 examples/bolt_resource_generator/beet.yml create mode 100644 examples/bolt_resource_generator/src/data/demo/modules/foo.bolt create mode 100644 tests/snapshots/examples__build_bolt_resource_generator__0.pack.md diff --git a/bolt/contrib/resource_generator.py b/bolt/contrib/resource_generator.py new file mode 100644 index 0000000..aacef71 --- /dev/null +++ b/bolt/contrib/resource_generator.py @@ -0,0 +1,82 @@ +from dataclasses import dataclass, replace +from functools import cache +from typing import Self + +from beet import Context, Generator + +from bolt import Runtime + + +@dataclass +class ResourceGenerator: + """Helpful sugar for generating resource locations and paths + + Adds some python data model functions to provide easier access to + :class:`~beet.Generator` functions. + + - `__truediv__` lets you define paths similar to :class:`~pathlib.Path` + - `__getattr__` lets you define namespaced paths easily + - `__neg__` makes it cleaner to convert a :class:`ResourceGenerator` into a string + + ```py + pack = ctx.inject(ResourceGenerator) + function (pack / "load"): + say "Loaded" + + pack.entity == "namespace.entity" + + tick = pack / "tick" + + function_tag minecraft:tick { + "values": [-(tick)] # unfortuntely need parens here + } + + function tick: + as @r say hi + ``` + """ + + _generator: Generator + + def __init__(self, _generator: Generator | Context): + match _generator: + case Generator(): + self._generator = _generator + case Context(): + self._generator = _generator.generate + + def __truediv__(self, path: str): + """Allows you to define subpaths based on the root generator""" + return replace(self, _generator=self._generator[path]) + + @cache + def __getattr__(self, key: str): + """Produce a namespaced id""" + return self.__getitem__(key) + + @cache + def __getitem__(self, key: str): + """Produce a namespaced id""" + return self._generator.id(key) + + def __neg__(self): + """Simplfied sugar for `__str__`""" + return str(self) + + def __str__(self): + return self._generator.format("{namespace}:{path}")[:-1] + + def __eq__(self, other: Self): + return str(self) == str(other) + + def __repr__(self): + return f"{self.__class__.__name__}({self})" + + def __hash__(self): + return hash(str(self)) + + +def beet_default(ctx: Context): + """Adds `ctx.inject(ResourceGenerator)` as `pack` to runtime globals""" + runtime = ctx.inject(Runtime) + runtime.globals["pack"] = ctx.inject(ResourceGenerator) diff --git a/examples/bolt_resource_generator/beet.yml b/examples/bolt_resource_generator/beet.yml new file mode 100644 index 0000000..c7210b7 --- /dev/null +++ b/examples/bolt_resource_generator/beet.yml @@ -0,0 +1,15 @@ +id: demo +require: + - bolt + - bolt.contrib.resource_generator + +data_pack: + load: "src" + +pipeline: + - mecha + +meta: + bolt: + entrypoint: + - "*" diff --git a/examples/bolt_resource_generator/src/data/demo/modules/foo.bolt b/examples/bolt_resource_generator/src/data/demo/modules/foo.bolt new file mode 100644 index 0000000..00d32af --- /dev/null +++ b/examples/bolt_resource_generator/src/data/demo/modules/foo.bolt @@ -0,0 +1,16 @@ +function (pack / "load"): + say hello + +tick = pack / "tick" + +function_tag minecraft:tick { + "values": [ + (-tick) + ] +} + +function tick: + say tick + + as @e[tag=pack.entity] + say entity diff --git a/tests/snapshots/examples__build_bolt_resource_generator__0.pack.md b/tests/snapshots/examples__build_bolt_resource_generator__0.pack.md new file mode 100644 index 0000000..85fac8a --- /dev/null +++ b/tests/snapshots/examples__build_bolt_resource_generator__0.pack.md @@ -0,0 +1,41 @@ +# Lectern snapshot + +## Data pack + +`@data_pack pack.mcmeta` + +```json +{ + "pack": { + "pack_format": 10, + "description": "" + } +} +``` + +### demo + +`@function demo:load` + +```mcfunction +say hello +``` + +`@function demo:tick` + +```mcfunction +say demo:tick +execute as @e[tag=demo.entity] run say entity +``` + +### minecraft + +`@function_tag minecraft:tick` + +```json +{ + "values": [ + "demo:tick" + ] +} +```