Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/actions/setup-python/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ runs:
- uses: actions/setup-python@v5
with:
python-version: ${{ inputs.python-version }}
architecture: "x64"
cache: "poetry"

- run: poetry install
Expand Down
41 changes: 41 additions & 0 deletions .github/workflows/codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Code Coverage

on:
push:
branches:
- "main"
pull_request:

jobs:
test:
name: Test Coverage
runs-on: ${{ matrix.os }}
concurrency:
group: test-coverage-${{ github.ref }}-${{ matrix.os }}-${{ matrix.python-version }}
cancel-in-progress: true
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
os: [ubuntu-latest, windows-latest, macos-latest]
env:
OS: ${{ matrix.os }}
PYTHON_VERSION: ${{ matrix.python-version }}

steps:
- uses: actions/checkout@v4

- name: Setup Python environment
uses: ./.github/actions/setup-python
with:
python-version: ${{ matrix.python-version }}

- name: Run Pytest
run: |
poetry run pytest -n auto --cov-append --cov-report xml

- name: Upload coverage report
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
env_vars: OS,PYTHON_VERSION
28 changes: 13 additions & 15 deletions nonebot_plugin_localstore/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,33 +93,31 @@ def get_data_file(plugin_name: Optional[str], filename: str) -> Path:
return get_data_dir(plugin_name) / filename


def _get_caller_plugin(depth: int = 0) -> Optional[Plugin]:
def _get_caller_plugin() -> Optional[Plugin]:
current_frame = inspect.currentframe()
if current_frame is None:
return None

# skip depth of frames
frame = current_frame
while depth > 0:
frame = frame.f_back
if frame is None:
raise ValueError("Depth out of range")
depth -= 1

# find plugin
frame = current_frame
while frame := frame.f_back:
module_name = (module := inspect.getmodule(frame)) and module.__name__
if module_name is None:
return None

if plugin := get_plugin_by_module_name(module_name):
# skip nonebot_plugin_localstore it self
if module_name.split(".", maxsplit=1)[0] == "nonebot_plugin_localstore":
continue

plugin = get_plugin_by_module_name(module_name)
if plugin and plugin.id_ != "nonebot_plugin_localstore":
return plugin

return None


def _try_get_caller_plugin(depth: int = 0) -> Plugin:
if plugin := _get_caller_plugin(depth + 1):
def _try_get_caller_plugin() -> Plugin:
if plugin := _get_caller_plugin():
return plugin
raise RuntimeError("Cannot detect caller plugin")

Expand All @@ -131,7 +129,7 @@ def _get_plugin_path(base_dir: Path, plugin: Plugin) -> Path:

@_auto_create_dir
def get_plugin_cache_dir() -> Path:
plugin = _try_get_caller_plugin(1)
plugin = _try_get_caller_plugin()
return _get_plugin_path(BASE_CACHE_DIR, plugin)


Expand All @@ -141,7 +139,7 @@ def get_plugin_cache_file(filename: str) -> Path:

@_auto_create_dir
def get_plugin_config_dir() -> Path:
plugin = _try_get_caller_plugin(1)
plugin = _try_get_caller_plugin()
return _get_plugin_path(BASE_CONFIG_DIR, plugin)


Expand All @@ -151,7 +149,7 @@ def get_plugin_config_file(filename: str) -> Path:

@_auto_create_dir
def get_plugin_data_dir() -> Path:
plugin = _try_get_caller_plugin(1)
plugin = _try_get_caller_plugin()
return _get_plugin_path(BASE_DATA_DIR, plugin)


Expand Down
464 changes: 421 additions & 43 deletions poetry.lock

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,18 @@ pydantic = ">=1.10.0,<3.0.0,!=2.5.0,!=2.5.1"
ruff = "^0.5.0"
isort = "^5.10.1"
black = "^24.0.0"
nonebug = "^0.3.7"
nonemoji = "^0.1.2"
pre-commit = "^3.5.0"
pytest-cov = "^5.0.0"
pytest-xdist = "^3.6.1"

[tool.poetry.plugins.nb_scripts]
localstore = "nonebot_plugin_localstore.script:main"

[tool.pytest.ini_options]
addopts = "--cov=./nonebot_plugin_localstore --cov-report=term-missing"

[tool.black]
line-length = 88
target-version = ["py39", "py310", "py311", "py312"]
Expand Down
27 changes: 27 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from pathlib import Path

import pytest
import nonebot
from nonebug import NONEBOT_INIT_KWARGS


def pytest_configure(config: pytest.Config) -> None:
config.stash[NONEBOT_INIT_KWARGS] = {"driver": "~none"}


@pytest.fixture(scope="session")
def tmp_path(tmp_path_factory: pytest.TempPathFactory) -> Path:
return tmp_path_factory.mktemp("nonebot_plugin_localstore")


@pytest.fixture(scope="session", autouse=True)
def _load_plugin(nonebug_init: None, tmp_path: Path):
nonebot.load_plugin("nonebot_plugin_localstore")

with pytest.MonkeyPatch.context() as m:
m.setattr("nonebot_plugin_localstore.BASE_DATA_DIR", tmp_path / "data")
m.setattr("nonebot_plugin_localstore.BASE_CACHE_DIR", tmp_path / "cache")
m.setattr("nonebot_plugin_localstore.BASE_CONFIG_DIR", tmp_path / "config")

nonebot.load_plugin("tests.plugin")
yield
23 changes: 23 additions & 0 deletions tests/plugin/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from pathlib import Path

import nonebot

from nonebot_plugin_localstore import (
get_plugin_data_dir,
get_plugin_cache_dir,
get_plugin_data_file,
get_plugin_cache_file,
get_plugin_config_dir,
get_plugin_config_file,
)

data_dir = get_plugin_data_dir()
cache_dir = get_plugin_cache_dir()
config_dir = get_plugin_config_dir()

data_file = get_plugin_data_file("data_file")
cache_file = get_plugin_cache_file("cache_file")
config_file = get_plugin_config_file("config_file")

_sub_plugins = set()
_sub_plugins |= nonebot.load_plugins(str((Path(__file__).parent / "plugins").resolve()))
16 changes: 16 additions & 0 deletions tests/plugin/plugins/sub_plugin/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from nonebot_plugin_localstore import (
get_plugin_data_dir,
get_plugin_cache_dir,
get_plugin_data_file,
get_plugin_cache_file,
get_plugin_config_dir,
get_plugin_config_file,
)

data_dir = get_plugin_data_dir()
cache_dir = get_plugin_cache_dir()
config_dir = get_plugin_config_dir()

data_file = get_plugin_data_file("data_file")
cache_file = get_plugin_cache_file("cache_file")
config_file = get_plugin_config_file("config_file")
23 changes: 23 additions & 0 deletions tests/test_get_plugin_dir.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from pathlib import Path


def test_plugin_dir(tmp_path: Path):
from tests.plugin import data_dir, cache_dir, config_dir

assert data_dir == tmp_path / "data" / "plugin"
assert data_dir.is_dir()
assert cache_dir == tmp_path / "cache" / "plugin"
assert cache_dir.is_dir()
assert config_dir == tmp_path / "config" / "plugin"
assert config_dir.is_dir()


def test_sub_plugin_dir(tmp_path: Path):
from tests.plugin.plugins.sub_plugin import data_dir, cache_dir, config_dir

assert data_dir == tmp_path / "data" / "plugin" / "sub_plugin"
assert data_dir.is_dir()
assert cache_dir == tmp_path / "cache" / "plugin" / "sub_plugin"
assert cache_dir.is_dir()
assert config_dir == tmp_path / "config" / "plugin" / "sub_plugin"
assert config_dir.is_dir()
17 changes: 17 additions & 0 deletions tests/test_get_plugin_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from pathlib import Path


def test_plugin_file(tmp_path: Path):
from tests.plugin import data_file, cache_file, config_file

assert data_file == tmp_path / "data" / "plugin" / "data_file"
assert cache_file == tmp_path / "cache" / "plugin" / "cache_file"
assert config_file == tmp_path / "config" / "plugin" / "config_file"


def test_sub_plugin_file(tmp_path: Path):
from tests.plugin.plugins.sub_plugin import data_file, cache_file, config_file

assert data_file == tmp_path / "data" / "plugin" / "sub_plugin" / "data_file"
assert cache_file == tmp_path / "cache" / "plugin" / "sub_plugin" / "cache_file"
assert config_file == tmp_path / "config" / "plugin" / "sub_plugin" / "config_file"