diff --git a/beet/library/base.py b/beet/library/base.py index f7dbd6a3e..1f20636ee 100644 --- a/beet/library/base.py +++ b/beet/library/base.py @@ -775,15 +775,22 @@ def merge(self, other: "Mcmeta") -> bool: # type: ignore overlays: Any = self.data.setdefault("overlays", {}) for entry in overlays.setdefault("entries", []): if entry.get("directory") == other_entry.get("directory"): - entry["formats"] = deepcopy(other_entry.get("formats")) + if (value := deepcopy(other_entry.get("formats"))) is None: + entry.pop("formats", None) + else: + entry["formats"] = value if ( - x := deepcopy(other_entry.get("min_format")) - ) is not None: - entry["min_format"] = x + value := deepcopy(other_entry.get("min_format")) + ) is None: + entry.pop("min_format", None) + else: + entry["min_format"] = value if ( - x := deepcopy(other_entry.get("max_format")) - ) is not None: - entry["max_format"] = x + value := deepcopy(other_entry.get("max_format")) + ) is None: + entry.pop("max_format", None) + else: + entry["max_format"] = value break else: overlays["entries"].append(deepcopy(other_entry)) @@ -1188,8 +1195,8 @@ def merge( super().merge(other) # type: ignore if isinstance(self, Pack) and isinstance(other, Pack): - self.extra.merge(other.extra) # type: ignore self.overlays.merge(other.overlays) # type: ignore + self.extra.merge(other.extra) # type: ignore empty_namespaces = [key for key, value in self.items() if not value] # type: ignore for namespace in empty_namespaces: @@ -1321,14 +1328,23 @@ def supported_formats(self, value: Optional[SupportedFormats]): overlays: Any = self.overlay_parent.mcmeta.data.setdefault("overlays", {}) for entry in overlays.setdefault("entries", []): if entry.get("directory") == self.overlay_name: - entry["formats"] = value + if value is None: + entry.pop("formats", None) + else: + entry["formats"] = value break else: - overlays["entries"].append( - {"formats": value, "directory": self.overlay_name} - ) + if value is not None: + overlays["entries"].append( + {"formats": value, "directory": self.overlay_name} + ) + else: + overlays["entries"].append({"directory": self.overlay_name}) else: - self.mcmeta.data.setdefault("pack", {})["supported_formats"] = value + if value is None: + self.mcmeta.data.setdefault("pack", {}).pop("supported_formats", None) + else: + self.mcmeta.data.setdefault("pack", {})["supported_formats"] = value @property def min_format(self) -> Optional[FormatSpecifier]: @@ -1356,6 +1372,8 @@ def min_format(self, value: Optional[FormatSpecifier]): overlays["entries"].append( {"directory": self.overlay_name, "min_format": value} ) + else: + overlays["entries"].append({"directory": self.overlay_name}) pack = self.mcmeta.data.setdefault("pack", {}) if value is None: pack.pop("min_format", None) @@ -1384,9 +1402,12 @@ def max_format(self, value: Optional[FormatSpecifier]): entry["max_format"] = value break else: - overlays["entries"].append( - {"directory": self.overlay_name, "max_format": value} - ) + if value is None: + overlays["entries"].append({"directory": self.overlay_name}) + else: + overlays["entries"].append( + {"directory": self.overlay_name, "max_format": value} + ) pack = self.mcmeta.data.setdefault("pack", {}) if value is None: pack.pop("max_format", None) diff --git a/beet/toolchain/project.py b/beet/toolchain/project.py index f1c079929..2e6a94d44 100644 --- a/beet/toolchain/project.py +++ b/beet/toolchain/project.py @@ -268,7 +268,7 @@ def build(self) -> Iterator[Context]: project_root=self.root, minecraft_version=self.config.minecraft or LATEST_MINECRAFT_VERSION, directory=self.project.directory, - output_directory=self.project.output_directory, + output_directory=self.project.output_directory if self.root else None, meta=meta, cache=cache, worker=stack.enter_context(self.project.worker_pool.handle()), diff --git a/examples/load_subproject_package_overlays_formats/beet.yml b/examples/load_subproject_package_overlays_formats/beet.yml new file mode 100644 index 000000000..6a8ac58fc --- /dev/null +++ b/examples/load_subproject_package_overlays_formats/beet.yml @@ -0,0 +1,3 @@ +require: [demo] + +output: build \ No newline at end of file diff --git a/examples/load_subproject_package_overlays_formats/demo/__init__.py b/examples/load_subproject_package_overlays_formats/demo/__init__.py new file mode 100644 index 000000000..a8f0ad295 --- /dev/null +++ b/examples/load_subproject_package_overlays_formats/demo/__init__.py @@ -0,0 +1,5 @@ +from beet import Context, subproject + + +def beet_default(ctx: Context): + ctx.require(subproject("@demo")) diff --git a/examples/load_subproject_package_overlays_formats/demo/beet.yaml b/examples/load_subproject_package_overlays_formats/demo/beet.yaml new file mode 100644 index 000000000..a85cc27d5 --- /dev/null +++ b/examples/load_subproject_package_overlays_formats/demo/beet.yaml @@ -0,0 +1,15 @@ + + + +data_pack: + load: ["."] + min_format: 88 + max_format: 88 + overlays: + - directory: my_overlay + min_format: 85 + max_format: 91 + pack_format: 85 + + +output: build diff --git a/examples/load_subproject_package_overlays_formats/demo/data/test/function/hello.mcfunction b/examples/load_subproject_package_overlays_formats/demo/data/test/function/hello.mcfunction new file mode 100644 index 000000000..a1026a584 --- /dev/null +++ b/examples/load_subproject_package_overlays_formats/demo/data/test/function/hello.mcfunction @@ -0,0 +1 @@ +say HELLO \ No newline at end of file diff --git a/examples/load_subproject_package_overlays_formats/demo/data/test/worldgen/biome/test.json b/examples/load_subproject_package_overlays_formats/demo/data/test/worldgen/biome/test.json new file mode 100644 index 000000000..3ae32a222 --- /dev/null +++ b/examples/load_subproject_package_overlays_formats/demo/data/test/worldgen/biome/test.json @@ -0,0 +1,3 @@ +{ + "test": "original" +} \ No newline at end of file diff --git a/examples/load_subproject_package_overlays_formats/demo/my_overlay/data/test/function/hello.mcfunction b/examples/load_subproject_package_overlays_formats/demo/my_overlay/data/test/function/hello.mcfunction new file mode 100644 index 000000000..061123dc2 --- /dev/null +++ b/examples/load_subproject_package_overlays_formats/demo/my_overlay/data/test/function/hello.mcfunction @@ -0,0 +1 @@ +say WORLD \ No newline at end of file diff --git a/examples/load_subproject_package_overlays_formats/demo/my_overlay/data/test/worldgen/biome/test.json b/examples/load_subproject_package_overlays_formats/demo/my_overlay/data/test/worldgen/biome/test.json new file mode 100644 index 000000000..c009cf29d --- /dev/null +++ b/examples/load_subproject_package_overlays_formats/demo/my_overlay/data/test/worldgen/biome/test.json @@ -0,0 +1,3 @@ +{ + "test": "overlay" +} \ No newline at end of file diff --git a/tests/snapshots/examples__build_load_subproject_package_overlays_formats__0.data_pack/data/test/function/hello.mcfunction b/tests/snapshots/examples__build_load_subproject_package_overlays_formats__0.data_pack/data/test/function/hello.mcfunction new file mode 100644 index 000000000..a1026a584 --- /dev/null +++ b/tests/snapshots/examples__build_load_subproject_package_overlays_formats__0.data_pack/data/test/function/hello.mcfunction @@ -0,0 +1 @@ +say HELLO \ No newline at end of file diff --git a/tests/snapshots/examples__build_load_subproject_package_overlays_formats__0.data_pack/data/test/worldgen/biome/test.json b/tests/snapshots/examples__build_load_subproject_package_overlays_formats__0.data_pack/data/test/worldgen/biome/test.json new file mode 100644 index 000000000..3ae32a222 --- /dev/null +++ b/tests/snapshots/examples__build_load_subproject_package_overlays_formats__0.data_pack/data/test/worldgen/biome/test.json @@ -0,0 +1,3 @@ +{ + "test": "original" +} \ No newline at end of file diff --git a/tests/snapshots/examples__build_load_subproject_package_overlays_formats__0.data_pack/my_overlay/data/test/function/hello.mcfunction b/tests/snapshots/examples__build_load_subproject_package_overlays_formats__0.data_pack/my_overlay/data/test/function/hello.mcfunction new file mode 100644 index 000000000..061123dc2 --- /dev/null +++ b/tests/snapshots/examples__build_load_subproject_package_overlays_formats__0.data_pack/my_overlay/data/test/function/hello.mcfunction @@ -0,0 +1 @@ +say WORLD \ No newline at end of file diff --git a/tests/snapshots/examples__build_load_subproject_package_overlays_formats__0.data_pack/my_overlay/data/test/worldgen/biome/test.json b/tests/snapshots/examples__build_load_subproject_package_overlays_formats__0.data_pack/my_overlay/data/test/worldgen/biome/test.json new file mode 100644 index 000000000..c009cf29d --- /dev/null +++ b/tests/snapshots/examples__build_load_subproject_package_overlays_formats__0.data_pack/my_overlay/data/test/worldgen/biome/test.json @@ -0,0 +1,3 @@ +{ + "test": "overlay" +} \ No newline at end of file diff --git a/tests/snapshots/examples__build_load_subproject_package_overlays_formats__0.data_pack/pack.mcmeta b/tests/snapshots/examples__build_load_subproject_package_overlays_formats__0.data_pack/pack.mcmeta new file mode 100644 index 000000000..1a3b11be0 --- /dev/null +++ b/tests/snapshots/examples__build_load_subproject_package_overlays_formats__0.data_pack/pack.mcmeta @@ -0,0 +1,16 @@ +{ + "pack": { + "description": "", + "min_format": 88, + "max_format": 88 + }, + "overlays": { + "entries": [ + { + "directory": "my_overlay", + "min_format": 85, + "max_format": 91 + } + ] + } +} diff --git a/tests/snapshots/examples__build_load_subproject_package_overlays_formats__1.resource_pack/pack.mcmeta b/tests/snapshots/examples__build_load_subproject_package_overlays_formats__1.resource_pack/pack.mcmeta new file mode 100644 index 000000000..9d29a1605 --- /dev/null +++ b/tests/snapshots/examples__build_load_subproject_package_overlays_formats__1.resource_pack/pack.mcmeta @@ -0,0 +1,13 @@ +{ + "pack": { + "min_format": [ + 69, + 0 + ], + "max_format": [ + 69, + 0 + ], + "description": "" + } +} diff --git a/tests/test_data_pack.py b/tests/test_data_pack.py index 7b01d3972..496cc4d6e 100644 --- a/tests/test_data_pack.py +++ b/tests/test_data_pack.py @@ -795,6 +795,67 @@ def test_overlay(): assert s1 == s2 assert len(s1) == 6 + a, b = DataPack(min_format=(88, 0), max_format=(88, 0)), DataPack( + min_format=(99, 0), max_format=(99, 0) + ) + a.merge(b) + assert a.min_format == (99, 0) + assert a.max_format == (99, 0) + assert a.pack_format is None + + a, b = DataPack(min_format=88, max_format=88), DataPack( + min_format=99, max_format=99 + ) + a.merge(b) + assert a.min_format == 99 + assert a.max_format == 99 + assert a.pack_format is None + + a, b = DataPack(pack_format=88), DataPack(pack_format=99) + a.merge(b) + assert a.pack_format == 99 + assert a.min_format is None + assert a.max_format is None + + a, b = DataPack(min_format=(88, 0), max_format=(88, 0)), DataPack(pack_format=99) + a.merge(b) + assert a.pack_format == 99 + assert a.min_format is None + assert a.max_format is None + + a, b = DataPack(min_format=88, max_format=88), DataPack(pack_format=99) + overlay = b.overlays.setdefault("overlay") + overlay.min_format = 77 + overlay.max_format = 77 + a.merge(b) + + assert a.pack_format == 99 + assert a.min_format is None + assert a.max_format is None + assert a.overlays["overlay"].min_format == 77 + assert a.overlays["overlay"].max_format == 77 + + a, b = DataPack(min_format=88, max_format=88), DataPack( + min_format=99, max_format=99 + ) + overlayA = a.overlays.setdefault("overlay") + overlayA.min_format = 66 + overlayA.max_format = 66 + overlayA.functions.setdefault("demo:thing", Function()).append("say hi from A") + overlayB = b.overlays.setdefault("overlay") + overlayB.min_format = 77 + overlayB.max_format = 77 + overlayB.functions.setdefault("demo:thing", Function()).append("say hi from B") + a.merge(b) + assert a.pack_format is None + assert a.min_format == 99 + assert a.max_format == 99 + assert a.overlays["overlay"].min_format == 77 + assert a.overlays["overlay"].max_format == 77 + assert a.overlays["overlay"].functions["demo:thing"].lines == [ + "say hi from B", + ] + def test_merge_overlays(): m = Mcmeta()