Skip to content

Commit

Permalink
feat: make it possible to load data packs and resource packs from pac…
Browse files Browse the repository at this point in the history
…kages
  • Loading branch information
vberlier committed Apr 20, 2022
1 parent 2bd8775 commit 910d714
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 14 deletions.
55 changes: 48 additions & 7 deletions beet/contrib/load.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,34 @@

__all__ = [
"LoadOptions",
"LoadError",
"load",
]


from glob import glob
from typing import List, Union
from pathlib import Path
from typing import List, Tuple, Union

from pydantic import BaseModel

from beet import Context, configurable
from beet import Context, Pipeline, configurable
from beet.core.utils import import_from_string
from beet.toolchain.pipeline import FormattedPipelineException


class LoadError(FormattedPipelineException):
"""Raised when loading data packs or resource packs fails."""

def __init__(self, message: str):
super().__init__(message)
self.message = message
self.format_cause = True


class LoadOptions(BaseModel):
resource_pack: Union[str, List[str]] = []
data_pack: Union[str, List[str]] = []
resource_pack: Union[str, List[Union[str, Tuple[str, str]]]] = []
data_pack: Union[str, List[Union[str, Tuple[str, str]]]] = []


def beet_default(ctx: Context):
Expand All @@ -27,7 +40,35 @@ def beet_default(ctx: Context):
@configurable(validator=LoadOptions)
def load(ctx: Context, opts: LoadOptions):
"""Plugin that loads data packs and resource packs."""
whitelist = ctx.inject(Pipeline).whitelist

for config, pack in zip([opts.resource_pack, opts.data_pack], ctx.packs):
for pattern in [config] if isinstance(config, str) else config:
for path in glob(str(ctx.directory / pattern)):
pack.load(path)
for target in [config] if isinstance(config, str) else config:
if isinstance(target, tuple):
package_name, target = target

try:
package = import_from_string(package_name, whitelist=whitelist)
except Exception as exc:
msg = f'Couldn\'t import package "{package_name}" for loading "{target}".'
raise LoadError(msg) from exc

if filename := getattr(package, "__file__", None):
pattern = Path(filename).parent / target
else:
msg = f'Missing "__file__" attribute on package "{package_name}" for loading "{target}".'
raise LoadError(msg)

else:
package_name = None
pattern = ctx.directory / target

if paths := glob(str(pattern)):
for path in paths:
pack.load(path)
elif package_name:
msg = f'Couldn\'t load "{target}" from package "{package_name}".'
raise LoadError(msg)
else:
msg = f'Couldn\'t load "{pattern}".'
raise LoadError(msg)
12 changes: 7 additions & 5 deletions beet/toolchain/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from copy import deepcopy
from itertools import chain
from pathlib import Path
from typing import Any, Dict, Iterable, List, Literal, Optional, Union
from typing import Any, Dict, Iterable, List, Literal, Optional, Tuple, Union

import toml
import yaml
Expand Down Expand Up @@ -43,7 +43,7 @@ class PackConfig(BaseModel):
compression: Optional[Literal["none", "deflate", "bzip2", "lzma"]] = None
compression_level: Optional[int] = None

load: Union[str, List[str]] = Field(default_factory=list)
load: Union[str, List[Union[str, Tuple[str, str]]]] = Field(default_factory=list)
render: Dict[str, List[str]] = Field(default_factory=dict)

class Config:
Expand All @@ -64,8 +64,10 @@ def with_defaults(self, other: "PackConfig") -> "PackConfig":
if self.compression_level is None
else self.compression_level
),
load=([other.load] if isinstance(other.load, str) else other.load)
+ ([self.load] if isinstance(self.load, str) else self.load),
load=[
*([other.load] if isinstance(other.load, str) else other.load),
*([self.load] if isinstance(self.load, str) else self.load),
],
render={
key: other.render.get(key, []) + self.render.get(key, [])
for key in self.render.keys() | other.render.keys()
Expand Down Expand Up @@ -114,7 +116,7 @@ def resolve(self, directory: FileSystemPath) -> "ProjectConfig":

for pack_config in [self.data_pack, self.resource_pack]:
pack_config.load = [
str(path / load_path)
load_path if isinstance(load_path, tuple) else str(path / load_path)
for load_path in (
[pack_config.load]
if isinstance(pack_config.load, str)
Expand Down
3 changes: 3 additions & 0 deletions examples/load_package/beet.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
data_pack:
load:
- ["demo", "data_pack"]
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
say hello
8 changes: 8 additions & 0 deletions tests/config_examples/load_package/beet.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"data_pack": {
"load": [["demo", "my_data_pack"]]
},
"resource_pack": {
"load": [["demo", "my_resource_pack"]]
}
}
10 changes: 8 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,14 @@ def fix_paths(self, config: ProjectConfig):
if config.output:
config.output = str(Path(config.output))

config.data_pack.load = [str(Path(p)) for p in config.data_pack.load]
config.resource_pack.load = [str(Path(p)) for p in config.resource_pack.load]
config.data_pack.load = [
pattern if isinstance(pattern, tuple) else str(Path(pattern))
for pattern in config.data_pack.load
]
config.resource_pack.load = [
pattern if isinstance(pattern, tuple) else str(Path(pattern))
for pattern in config.resource_pack.load
]
config.templates = [str(Path(p)) for p in config.templates]

for entry in config.pipeline:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"id": "",
"name": "",
"description": "",
"author": "",
"version": "",
"directory": "tests/config_examples/load_package",
"extend": [],
"output": null,
"ignore": [],
"whitelist": null,
"require": [],
"templates": [],
"data_pack": {
"name": "",
"description": "",
"pack_format": 0,
"zipped": null,
"compression": null,
"compression_level": null,
"load": [
[
"demo",
"my_data_pack"
]
],
"render": {}
},
"resource_pack": {
"name": "",
"description": "",
"pack_format": 0,
"zipped": null,
"compression": null,
"compression_level": null,
"load": [
[
"demo",
"my_resource_pack"
]
],
"render": {}
},
"pipeline": [],
"meta": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
say hello
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"pack": {
"pack_format": 9,
"description": ""
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"pack": {
"pack_format": 8,
"description": ""
}
}

0 comments on commit 910d714

Please sign in to comment.