Skip to content

Commit

Permalink
Merge pull request #9 from Moo-Ack-Productions/api-addition
Browse files Browse the repository at this point in the history
Addition of BpyBuild API
  • Loading branch information
StandingPadAnimations authored Apr 17, 2024
2 parents 9a0ebbb + cb87388 commit 12d2dbc
Show file tree
Hide file tree
Showing 34 changed files with 1,441 additions and 361 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
dist
__pycache__
build
test/deps/polib.py
34 changes: 20 additions & 14 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
repos:
- repo: local
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.9.0
hooks:
- id: mypy
name: mypy
entry: poetry run mypy --pretty
require_serial: true
language: system
types: [ python ]
- repo: https://github.com/psf/black
rev: 23.7.0
args: [--pretty]
additional_dependencies: [
"attrs==23.1.0",
"pyyaml==6.0.1",
"cattrs==23.2.3",
"rich==13.7.0",
"typeguard==4.1.5",
"types-pyyaml==6.0.12.11",
"GitPython==3.1.43"
]

- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.3.4
hooks:
- id: black
# It is recommended to specify the latest version of Python
# supported by your project here, or alternatively use
# pre-commit's default_language_version, see
# https://pre-commit.com/#top_level-default_language_version
language_version: python3.11
# Run the linter.
- id: ruff
# Run the formatter.
- id: ruff-format
12 changes: 12 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## [0.3.0] - 2024-02-02


### Fix: Fixed issue with not finding .X0 versions



### Test: Added 2.8 to test file


## [0.3.0-alpha-2] - 2023-12-19

## [0.3.0-alpha-1] - 2023-09-03


Expand Down
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ just mypy
poetry run mypy --pretty bpy_addon_build
```
# Formatting
All commits must be formatted with https://github.com/psf/black. We have a pre-commit hook for this (see the Pre-Commit Hooks section).
All commits must be formatted with https://github.com/astral-sh/ruff. We have a pre-commit hook for this (see the Pre-Commit Hooks section).

In addition, Black is a developer dependency defined in `pyproject.toml`, in case you want to run it at any moment in time, which can be done with the following:
In addition, Ruff is a developer dependency defined in `pyproject.toml`, in case you want to run it at any moment in time, which can be done with the following:
```sh
just format

# Or if you don't have just installed
poetry run black bpy_addon_build
poetry run ruff format bpy_addon_build
```

# Commits
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@ Install from PyPi:

First create a file called `bpy-build.yaml` and add the following contents:
```yaml
addon_folder: . # or the folder with the addon source code
addon_folder: my_addon # the folder with the addon source code
build_name: my_addon
```
**Note: the addon source code must be in a subfolder! BpyBuild does not support using `.` for `addon_folder`**

Then run `bab`, your addon will be built in the `build` folder!

Now let's automatically install our addon:
```yaml
addon_folder: . # or the folder with the addon source code
addon_folder: my_addon # the folder with the addon source code
build_name: my_addon
install_versions:
Expand Down
20 changes: 13 additions & 7 deletions bpy_addon_build/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,14 @@

from typing import Dict, List, Optional, Union
import yaml
from bpy_addon_build.api import Api
from bpy_addon_build.build_context import hooks
from bpy_addon_build.build_context.build import build
from bpy_addon_build.build_context.install import install

from bpy_addon_build.config import Config
from . import args
from .build_context import BuildContext
import cattrs
from .build_context.core import BuildContext
from cattrs.preconf.pyyaml import make_converter
from rich.console import Console

Expand All @@ -51,18 +54,21 @@ def main() -> None:

context: Optional[BuildContext] = None
with open(cli.path, "r") as f:
data: Dict[
str, Union[str, List[float], Dict[str, Dict[str, str]]]
] = yaml.safe_load(f)
data: Dict[str, Union[str, List[float], Dict[str, Dict[str, str]]]] = (
yaml.safe_load(f)
)
config: Config = converter.structure(data, Config)
context = BuildContext(cli.path, config, cli)
api: Api = Api(config, cli.path, cli.debug_mode)
context = BuildContext(cli.path, config, cli, api)

if cli.debug_mode:
console.print(context)
if not cli.path.parent.joinpath(config.addon_folder).exists():
print("Addon folder does not exist!")
return
context.build()
build_path = build(context)
install(context, build_path)
hooks.run_cleanup_hooks(context)


if __name__ == "__main__":
Expand Down
84 changes: 84 additions & 0 deletions bpy_addon_build/api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from types import ModuleType
from typing import Dict, Optional
from pathlib import Path
from bpy_addon_build.config import Config
from dataclasses import dataclass
import sys


@dataclass
class BpyError:
msg: str


@dataclass
class BpyWarning:
msg: str


@dataclass
class BabContext:
# Path where the action is being
# executed in. This should be
# the intended cwd
current_path: Path


class Api:
"""
API object; this holds all scripts used as modules
Attributes
----------
build_actions: Dict[str, str]
Action name to script file
action_mods: Dict[str, ModuleType]
Action name to module
"""

def __init__(self, conf: Config, config_path: Path, debug_mode: bool) -> None:
if conf.build_actions is not None:
self.build_actions = conf.build_actions
self.action_mods: Dict[str, ModuleType] = {}

for action in self.build_actions:
mod = self.add_modules(config_path, action, debug_mode)
if mod is None:
continue
self.action_mods[action] = mod

def add_modules(
self, config_path: Path, action: str, debug_mode: bool
) -> Optional[ModuleType]:
import importlib.util

path = config_path.parent.resolve().joinpath(
Path(self.build_actions[action].script)
)

# Add the parent folder of the script to the sys path
# so that we don't get module errors
#
# While we could argue that developers should at least
# opt in by calling this themselves, I think automatically
# doing this isn't a problem for now
sys.path.append(str(path.expanduser().parent))
action_spec = importlib.util.spec_from_file_location(action, path)
if action_spec is None:
if debug_mode:
print("Can not generate action spec for", action)
print("Path:", path)
return None
action_mod = importlib.util.module_from_spec(action_spec)
if action_mod is None:
if debug_mode:
print("Can not generate module from spec for", action)
print("Path:", path)
return None

sys.modules[action] = action_mod
if action_spec.loader is not None:
action_spec.loader.exec_module(action_mod)

return action_mod
9 changes: 4 additions & 5 deletions bpy_addon_build/args.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import argparse
from pathlib import Path
from typing import List, Optional, cast
from attrs import define, field, Attribute
Expand Down Expand Up @@ -41,18 +40,18 @@ class Args:
supress_messages: bool = field(default=False)

@path.validator
def path_validate(self, _: Attribute, value: Path) -> None:
def path_validate(self, _: Attribute, value: Optional[Path]) -> None:
# Assume the user did not pass
# a path in
if value is None:
return
if not value.exists():
raise FileNotFoundError("File does not exist!")
raise FileNotFoundError(f"File {value} does not exist!")
if value.is_dir():
raise IsADirectoryError("Expected a file, got a direcory!")

@versions.validator
def version_validate(self, _: Attribute, value: List[float]) -> None:
def version_validate(self, _: Attribute, value: Optional[List[float]]) -> None:
if value is None:
self.versions = []
else:
Expand All @@ -61,7 +60,7 @@ def version_validate(self, _: Attribute, value: List[float]) -> None:
raise ValueError("Expected List of floating point values!")

@actions.validator
def actions_validate(self, _: Attribute, value: List[str]) -> None:
def actions_validate(self, _: Attribute, value: Optional[List[str]]) -> None:
if value is None:
self.actions = ["default"]
else:
Expand Down
Loading

0 comments on commit 12d2dbc

Please sign in to comment.