From 9dbb20bd14792bc8932b87a1818c60de80930709 Mon Sep 17 00:00:00 2001
From: object-Object
# hexdoc
diff --git a/cookiecutter.json b/cookiecutter.json
index 06126e816..91da05012 100644
--- a/cookiecutter.json
+++ b/cookiecutter.json
@@ -2,9 +2,15 @@
"output_directory": "",
"modid": "",
+ "book_id": "hexcasting:thehexbook",
"mod_display_name": "{{ cookiecutter.modid|capitalize }}",
"plugin_classname": "{{ cookiecutter.modid|capitalize }}Plugin",
+
"gradle_mod_version_key": "modVersion",
+ "multiloader": true,
+ "java_lang": ["java", "kotlin"],
+ "java_package": "com/example/{{ cookiecutter.modid }}",
+ "pattern_registry": "registry/{{ cookiecutter.modid|capitalize }}PatternRegistry.{{ 'java' if cookiecutter.java_lang == 'java' else 'kt' }}",
"github_repo": "{{ cookiecutter.modid|capitalize }}",
"author": "TODO",
diff --git a/noxfile.py b/noxfile.py
new file mode 100644
index 000000000..e0b4ca9e8
--- /dev/null
+++ b/noxfile.py
@@ -0,0 +1,19 @@
+import nox
+
+
+@nox.session
+def lint(session: nox.Session):
+ session.install("favicons") # TODO: remove
+ session.install(".[test]", "nox", "pyright")
+
+ session.run("pyright", "--warnings")
+
+
+@nox.session
+def tests(session: nox.Session):
+ session.install("favicons") # TODO: remove
+ session.install(".[test]", "./test/_submodules/HexMod")
+
+ # test cookiecutter last so the extra package install doesn't interfere
+ session.run("pytest", "-k", "not test_cookiecutter")
+ session.run("pytest", "-k", "test_cookiecutter")
diff --git a/pyproject.toml b/pyproject.toml
index bbb0851a6..b77ce4b14 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -70,7 +70,7 @@ dev = [
"black==23.7.0",
"isort==5.12.0",
"hatch",
- "build",
+ "nox",
]
[project.urls]
diff --git a/src/hexdoc/minecraft/assets/textures.py b/src/hexdoc/minecraft/assets/textures.py
index fc8a339f4..15195d475 100644
--- a/src/hexdoc/minecraft/assets/textures.py
+++ b/src/hexdoc/minecraft/assets/textures.py
@@ -86,7 +86,7 @@ def find(
for missing_id in props.textures.missing:
for id in ids:
if id.match(missing_id):
- logging.getLogger(__name__).warn(message)
+ logging.getLogger(__name__).warning(message)
return Texture(file_id=id, url=MISSING_TEXTURE)
raise KeyError(message)
diff --git a/test/test_cookiecutter.py b/test/test_cookiecutter.py
index bfecdeed1..5f2e9b46d 100644
--- a/test/test_cookiecutter.py
+++ b/test/test_cookiecutter.py
@@ -1,21 +1,117 @@
# pyright: reportUnknownMemberType=false
+import json
+import subprocess
+import sys
+from pathlib import Path
+from textwrap import dedent
+
from pytest import MonkeyPatch
from pytest_cookies.plugin import Cookies
+from hexdoc._cli.app import render
+
+from .conftest import longrun
+
+@longrun
def test_cookiecutter(cookies: Cookies, monkeypatch: MonkeyPatch):
result = cookies.bake(
{
"output_directory": "output",
"modid": "mod",
"pattern_regex": "hex_latest",
+ "multiloader": False,
+ "java_package": "com/package",
+ "pattern_registry": "Patterns.java",
}
)
assert result.exception is None
assert result.project_path is not None
+ monkeypatch.chdir(result.project_path)
+ subprocess.run(["git", "init"], check=True)
+
+ Path("gradle.properties").write_text(
+ dedent(
+ f"""\
+ modVersion=1.0.0
+ hexcastingVersion=0.11.1-7
+ minecraftVersion=1.20.1
+ """
+ )
+ )
+
+ java_root = Path("src/main/java/com/package")
+ java_root.mkdir(parents=True)
+ (java_root / "Patterns.java").touch()
+
+ Path("src/generated/resources").mkdir(parents=True)
+
+ book_root = Path(
+ "src/main/resources/assets/hexcasting/patchouli_books/thehexbook/en_us"
+ )
+ book_root.mkdir(parents=True)
+
+ category_root = book_root / "categories"
+ category_root.mkdir(parents=True)
+ with open(category_root / "foo.json", "w") as f:
+ json.dump(
+ {
+ "name": "hexdoc.mod.title",
+ "icon": "minecraft:amethyst_shard",
+ "description": "hexcasting.category.basics.desc",
+ "sortnum": 0,
+ },
+ f,
+ )
+
+ entry_root = book_root / "entries"
+ (entry_root / "foo").mkdir(parents=True)
+ with open(entry_root / "foo" / "bar.json", "w") as f:
+ json.dump(
+ {
+ "name": "hexdoc.welcome.header",
+ "category": "hexcasting:foo",
+ "icon": "minecraft:textures/mob_effect/nausea.png",
+ "sortnum": 0,
+ "advancement": "hexcasting:y_u_no_cast_angy",
+ "pages": [
+ {
+ "type": "patchouli:text",
+ "text": "hexcasting.page.couldnt_cast.1",
+ },
+ ],
+ },
+ f,
+ )
+
+ (result.project_path / ".env").write_text(
+ dedent(
+ f"""\
+ GITHUB_REPOSITORY=GITHUB/REPOSITORY
+ GITHUB_SHA=GITHUB_SHA
+ GITHUB_PAGES_URL=GITHUB_PAGES_URL"""
+ )
+ )
+
+ # TODO: remove when textures stop being broken
+ with open(result.project_path / "doc" / "properties.toml", "a") as f:
+ f.write(
+ dedent(
+ """
+ [textures]
+ missing = [
+ "minecraft:*",
+ "hexcasting:*",
+ ]
+ """
+ )
+ )
+
monkeypatch.syspath_prepend(result.project_path / "doc" / "src")
- import hexdoc_mod # type: ignore
+ subprocess.run([sys.executable, "-m", "pip", "install", "-e", "."])
+
+ render()
diff --git a/{{cookiecutter.output_directory}}/doc/static/icon.png b/{{cookiecutter.output_directory}}/doc/icon.png
similarity index 100%
rename from {{cookiecutter.output_directory}}/doc/static/icon.png
rename to {{cookiecutter.output_directory}}/doc/icon.png
diff --git a/{{cookiecutter.output_directory}}/doc/nodemon.json b/{{cookiecutter.output_directory}}/doc/nodemon.json
index d136273b7..abf20eb06 100644
--- a/{{cookiecutter.output_directory}}/doc/nodemon.json
+++ b/{{cookiecutter.output_directory}}/doc/nodemon.json
@@ -3,7 +3,7 @@
"doc/src",
"doc/resources",
"doc/properties.toml",
- "Common/src/main/resources/assets/*/lang"
+ "{{ 'common/src' if cookiecutter.multiloader else 'src' }}/main/resources/assets/*/lang"
],
"ignore": ["**/generated/**"],
"ext": "jinja,html,css,js,ts,toml,json,json5,py",
diff --git a/{{cookiecutter.output_directory}}/doc/properties.toml b/{{cookiecutter.output_directory}}/doc/properties.toml
index 6722b777a..18d99da1e 100644
--- a/{{cookiecutter.output_directory}}/doc/properties.toml
+++ b/{{cookiecutter.output_directory}}/doc/properties.toml
@@ -1,65 +1,73 @@
modid = "{{ cookiecutter.modid }}"
-book = "hexcasting:thehexbook"
+book = "{{ cookiecutter.book_id }}"
default_lang = "en_us"
-_export_root = "{{ cookiecutter.__export_root }}"
resource_dirs = [ # top takes priority
- { path="{^_export_root}/resources", reexport=false },
+ "resources",
"{_common.src}/main/resources",
"{_common.src}/generated/resources",
+ {% if cookiecutter.multiloader -%}
"{_fabric.src}/main/resources",
"{_fabric.src}/generated/resources",
"{_forge.src}/main/resources",
"{_forge.src}/generated/resources",
+ {%- endif %}
{ modid="hexcasting" },
+ { modid="hexdoc" },
]
-export_dir = "{_export_root}/generated"
+export_dir = "{{ cookiecutter.__export_root }}/generated"
-{# beware of eldritch abombinations lurking beneath these waters -#}
+[extra.hexcasting]
+# regexes for parsing pattern registry files - try uncommenting a different one if your patterns aren't loading
# NOTE: "!Raw" means "don't apply variable interpolation to this value"
-{% if cookiecutter.pattern_regex == "hex_latest" -%}
-_pattern_regex = { "!Raw"='make\(\s*"(?P[a-zA-Z0-9_\/]+)",\s*(?:new )?(?:ActionRegistryEntry|OperationAction)\(\s*HexPattern\.fromAngles\(\s*"(?P[aqweds]+)",\s*HexDir.(?P\w+)\)' }
-{% elif cookiecutter.pattern_regex == "hex_0.10.3" -%}
-_pattern_regex = { "!Raw"='HexPattern\.fromAngles\("(?P[qweasd]+)", HexDir\.(?P\w+)\),\s*modLoc\("(?P[^"]+)"\)[^;]+?(?:makeConstantOp|Op\w+|Widget\.\w+)(?:[^;]*(?Ptrue)\);)?' }
-{% elif cookiecutter.pattern_regex == "hexal_0.3.0" -%}
-_pattern_regex = { "!Raw"='make\(\s*"(?P[a-zA-Z0-9_\/]+)",\s*HexPattern\.fromAngles\(\s*"(?P[aqweds]+)",\s*HexDir.(?P\w+)\)' }
-{% elif cookiecutter.pattern_regex == "hexal_0.2.18" -%}
-{#- :yea: -#}
-_pattern_regex = { "!Raw"='(?s-m:HexPattern\.fromAngles\("(?P[qweasd]+)", HexDir\.(?P\w+)\),\s*modLoc\("(?P[^"]+)"\),[^,]+?(?:makeConstantOp|Op\w+).*?(?P\btrue)?\)(?:[^\)]+?\bval\b|(?:(?!\bval\b)(?:.))+$))' }
-{% else %}
-{# intentionally crash the template because we got an unhandled value #}
-{{ 0/0 }}
-{% endif %}
-[[pattern_stubs]]
-path = "{^_common.package}/TODO/TODO.java"
+# Hex Casting (0.11.0)
+{{ "# " if cookiecutter.pattern_regex != "hex_latest" }}_pattern_regex = { "!Raw"='make\(\s*"(?P[a-zA-Z0-9_\/]+)",\s*(?:new )?(?:ActionRegistryEntry|OperationAction)\(\s*HexPattern\.fromAngles\(\s*"(?P[aqweds]+)",\s*HexDir.(?P\w+)\)' }
+
+# Hex Casting (0.10.3)
+{{ "# " if cookiecutter.pattern_regex != "hex_0.10.3" }}_pattern_regex = { "!Raw"='HexPattern\.fromAngles\("(?P[qweasd]+)", HexDir\.(?P\w+)\),\s*modLoc\("(?P[^"]+)"\)[^;]+?(?:makeConstantOp|Op\w+|Widget\.\w+)(?:[^;]*(?Ptrue)\);)?' }
+
+# Hexal (0.3.0)
+{{ "# " if cookiecutter.pattern_regex != "hexal_0.3.0" }}_pattern_regex = { "!Raw"='make\(\s*"(?P[a-zA-Z0-9_\/]+)",\s*HexPattern\.fromAngles\(\s*"(?P[aqweds]+)",\s*HexDir.(?P\w+)\)' }
+
+# Hexal (0.2.18)
+{{ "# " if cookiecutter.pattern_regex != "hexal_0.2.18" }}_pattern_regex = { "!Raw"='(?s-m:HexPattern\.fromAngles\("(?P[qweasd]+)", HexDir\.(?P\w+)\),\s*modLoc\("(?P[^"]+)"\),[^,]+?(?:makeConstantOp|Op\w+).*?(?P\btrue)?\)(?:[^\)]+?\bval\b|(?:(?!\bval\b)(?:.))+$))' }
+
+[[extra.hexcasting.pattern_stubs]]
+path = "{^^^_common.package}/{{ cookiecutter.pattern_registry }}"
regex = "{^_pattern_regex}"
+[minecraft_assets]
+# https://github.com/PrismarineJS/minecraft-assets/tree/83e2169afbbce40990d69fc53e5962e4a793d467/data/1.19.1
+ref = "83e2169afbbce40990d69fc53e5962e4a793d467"
+version = "1.19.1"
+
[template]
-static_dir = "static"
+icon = "icon.png"
include = [
"{{ cookiecutter.modid }}",
"hexcasting",
"patchouli",
+ "hexdoc",
]
[template.args]
mod_name = "{{ cookiecutter.mod_display_name }}"
author = "{{ cookiecutter.author }}"
-icon_href = "icon.png"
show_landing_text = false
-
# platforms
[_common]
-src = "../Common/src"
-package = "{src}/main/java/TODO/{{ cookiecutter.modid }}"
+src = "../{{ 'common/src' if cookiecutter.multiloader else 'src' }}"
+package = "{src}/main/{{ cookiecutter.java_lang }}/{{ cookiecutter.java_package }}"
+{% if cookiecutter.multiloader -%}
[_fabric]
-src = "../Fabric/src"
-package = "{src}/main/java/TODO/{{ cookiecutter.modid }}/fabric"
+src = "../fabric/src"
+package = "{src}/main/{{ cookiecutter.java_lang }}/{{ cookiecutter.java_package }}/fabric"
[_forge]
-src = "../Forge/src"
-package = "{src}/main/java/TODO/{{ cookiecutter.modid }}/forge"
+src = "../forge/src"
+package = "{src}/main/{{ cookiecutter.java_lang }}/{{ cookiecutter.java_package }}/forge"
+{%- endif %}
diff --git a/{{cookiecutter.output_directory}}/doc/src/{{cookiecutter.__project_slug}}/_export/resources/assets/hexcasting/lang/en_us.flatten.json5 b/{{cookiecutter.output_directory}}/doc/resources/assets/hexcasting/lang/en_us.flatten.json5
similarity index 100%
rename from {{cookiecutter.output_directory}}/doc/src/{{cookiecutter.__project_slug}}/_export/resources/assets/hexcasting/lang/en_us.flatten.json5
rename to {{cookiecutter.output_directory}}/doc/resources/assets/hexcasting/lang/en_us.flatten.json5
diff --git a/{{cookiecutter.output_directory}}/doc/src/{{cookiecutter.__project_slug}}/_export/resources/__init__.py b/{{cookiecutter.output_directory}}/doc/src/{{cookiecutter.__project_slug}}/_export/resources/__init__.py
deleted file mode 100644
index d7a48f963..000000000
--- a/{{cookiecutter.output_directory}}/doc/src/{{cookiecutter.__project_slug}}/_export/resources/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# You can add extra resources in this directory for hexdoc to load.
-# For example, hexdoc uses this for translations which are only needed for the web book.
diff --git a/{{cookiecutter.output_directory}}/doc/src/{{cookiecutter.__project_slug}}/_hooks.py b/{{cookiecutter.output_directory}}/doc/src/{{cookiecutter.__project_slug}}/_hooks.py
index 80be7478c..3813adcdb 100644
--- a/{{cookiecutter.output_directory}}/doc/src/{{cookiecutter.__project_slug}}/_hooks.py
+++ b/{{cookiecutter.output_directory}}/doc/src/{{cookiecutter.__project_slug}}/_hooks.py
@@ -5,32 +5,39 @@
LoadJinjaTemplatesImpl,
LoadResourceDirsImpl,
ModVersionImpl,
+ MinecraftVersionImpl,
hookimpl,
)
import {{ cookiecutter.__project_slug }}
-from .__gradle_version__ import GRADLE_VERSION
+from .__gradle_version__ import GRADLE_VERSION, MINECRAFT_VERSION
class {{ cookiecutter.plugin_classname }}(
LoadJinjaTemplatesImpl,
LoadResourceDirsImpl,
ModVersionImpl,
+ MinecraftVersionImpl,
):
@staticmethod
@hookimpl
def hexdoc_mod_version() -> str:
return GRADLE_VERSION
+ @staticmethod
+ @hookimpl
+ def hexdoc_minecraft_version() -> str:
+ return MINECRAFT_VERSION
+
@staticmethod
@hookimpl
def hexdoc_load_resource_dirs() -> HookReturn[Package]:
# This needs to be a lazy import because they may not exist when this file is
# first loaded, eg. when generating the contents of generated.
- from ._export import generated, resources
+ from ._export import generated
- return [generated, resources]
+ return generated
@staticmethod
@hookimpl