This commit is contained in:
parent
3d053d532a
commit
d9eb99b72e
9 changed files with 71 additions and 28 deletions
|
|
@ -53,6 +53,7 @@ steps:
|
||||||
image: git.roboces.dev/catalin/poetry:beta
|
image: git.roboces.dev/catalin/poetry:beta
|
||||||
commands:
|
commands:
|
||||||
- apk add --no-cache age openssh
|
- apk add --no-cache age openssh
|
||||||
|
- ssh-keygen -t ed25519 -C "" -N "" -f /root/.ssh/id_ed25519
|
||||||
- .venv/bin/pytest
|
- .venv/bin/pytest
|
||||||
depends_on:
|
depends_on:
|
||||||
- install_deps
|
- install_deps
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,7 @@ from pydantic import (
|
||||||
Field,
|
Field,
|
||||||
)
|
)
|
||||||
|
|
||||||
from halig import exceptions
|
from halig.exceptions import ConfigFileIsInvalid, ConfigFileDoesNotExist
|
||||||
from halig.exceptions import ConfigFileIsInvalid
|
|
||||||
|
|
||||||
DEFAULT_CONFIGURATION_PATH = Path("~/.config/halig/halig.yml").expanduser()
|
DEFAULT_CONFIGURATION_PATH = Path("~/.config/halig/halig.yml").expanduser()
|
||||||
|
|
||||||
|
|
@ -27,7 +26,7 @@ class EncryptionKeysConfig(BaseSettings):
|
||||||
return Path(v).expanduser()
|
return Path(v).expanduser()
|
||||||
if isinstance(v, Path):
|
if isinstance(v, Path):
|
||||||
return v.expanduser()
|
return v.expanduser()
|
||||||
return v
|
return v # pragma: no cover
|
||||||
|
|
||||||
|
|
||||||
class Config(BaseSettings):
|
class Config(BaseSettings):
|
||||||
|
|
@ -52,11 +51,7 @@ version: 1.0.0
|
||||||
return Path(v).expanduser()
|
return Path(v).expanduser()
|
||||||
if isinstance(v, Path):
|
if isinstance(v, Path):
|
||||||
return v.expanduser()
|
return v.expanduser()
|
||||||
return v
|
return v # pragma: no cover
|
||||||
|
|
||||||
def dict(self, *args, **kwargs):
|
|
||||||
values = super().dict()
|
|
||||||
return {k: str(v) for k, v in values.items()}
|
|
||||||
|
|
||||||
|
|
||||||
def get_config(config_path: Path = DEFAULT_CONFIGURATION_PATH) -> Config:
|
def get_config(config_path: Path = DEFAULT_CONFIGURATION_PATH) -> Config:
|
||||||
|
|
@ -64,8 +59,7 @@ def get_config(config_path: Path = DEFAULT_CONFIGURATION_PATH) -> Config:
|
||||||
the default config initialization will be provided
|
the default config initialization will be provided
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
config_path (Path): The path to the config, defaults to
|
config_path (Path): The config path, defaults to DEFAULT_CONFIGURATION_PATH
|
||||||
DEFAULT_CONFIGURATION_PATH
|
|
||||||
Returns:
|
Returns:
|
||||||
a Config object
|
a Config object
|
||||||
Raises:
|
Raises:
|
||||||
|
|
@ -74,10 +68,10 @@ def get_config(config_path: Path = DEFAULT_CONFIGURATION_PATH) -> Config:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not config_path:
|
if not config_path:
|
||||||
return Config()
|
return Config() # pragma: no cover
|
||||||
|
|
||||||
if not config_path.exists():
|
if not config_path.exists():
|
||||||
raise exceptions.ConfigFileDoesNotExist
|
raise ConfigFileDoesNotExist
|
||||||
|
|
||||||
with open(config_path, "r") as f:
|
with open(config_path, "r") as f:
|
||||||
yml = yaml.load(f, Loader=yaml.SafeLoader)
|
yml = yaml.load(f, Loader=yaml.SafeLoader)
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ from halig import logger
|
||||||
class HaligError(Exception, ABC):
|
class HaligError(Exception, ABC):
|
||||||
@property
|
@property
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def msg(self) -> str:
|
def msg(self) -> str: # pragma: no cover
|
||||||
...
|
...
|
||||||
|
|
||||||
error_code = 1
|
error_code = 1
|
||||||
|
|
@ -55,7 +55,7 @@ class InvalidNotePath(HaligError):
|
||||||
error_code = 7
|
error_code = 7
|
||||||
|
|
||||||
|
|
||||||
def handle_errors(func):
|
def handle_errors(func): # pragma: no cover
|
||||||
# TODO: parse age/sh errors
|
# TODO: parse age/sh errors
|
||||||
@wraps(func)
|
@wraps(func)
|
||||||
def inner_function(*args, **kwargs):
|
def inner_function(*args, **kwargs):
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,17 @@ import seedir as sd
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
def info(text: str):
|
def info(text: str): # pragma: no cover
|
||||||
print(text)
|
print(text)
|
||||||
|
|
||||||
|
|
||||||
def error(text: str):
|
def error(text: str): # pragma: no cover
|
||||||
rich.print(f"[red]{text}")
|
rich.print(f"[red]{text}")
|
||||||
|
|
||||||
|
|
||||||
def tree(dir_path: Path, print_files: bool = False, print_hidden: bool = False):
|
def tree(
|
||||||
|
dir_path: Path, print_files: bool = False, print_hidden: bool = False
|
||||||
|
): # pragma: no cover
|
||||||
def mask(x: str) -> bool:
|
def mask(x: str) -> bool:
|
||||||
path = Path(x)
|
path = Path(x)
|
||||||
if path.name.startswith(".") and not print_hidden:
|
if path.name.startswith(".") and not print_hidden:
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ from halig.edit_note import edit_note
|
||||||
from halig.exceptions import InvalidNotePath
|
from halig.exceptions import InvalidNotePath
|
||||||
from halig.exceptions import handle_errors
|
from halig.exceptions import handle_errors
|
||||||
from halig.new_note import new_note
|
from halig.new_note import new_note
|
||||||
|
from halig.utils import resolve_path
|
||||||
|
|
||||||
app = Typer(pretty_exceptions_enable=False)
|
app = Typer(pretty_exceptions_enable=False)
|
||||||
|
|
||||||
|
|
@ -66,7 +67,7 @@ def edit(path: Path, configuration_path: Path = DEFAULT_CONFIGURATION_PATH):
|
||||||
if path.is_absolute():
|
if path.is_absolute():
|
||||||
raise InvalidNotePath
|
raise InvalidNotePath
|
||||||
|
|
||||||
full_path = (config.notes_root_path / path).expanduser().resolve()
|
full_path = resolve_path(path)
|
||||||
|
|
||||||
if full_path.is_dir():
|
if full_path.is_dir():
|
||||||
return new_note(full_path / f"{datetime.now():%Y-%m-%d}.age", config)
|
return new_note(full_path / f"{datetime.now():%Y-%m-%d}.age", config)
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,7 @@ def resolve_path(path: Path) -> Path:
|
||||||
Returns:
|
Returns:
|
||||||
Path: The resolved path
|
Path: The resolved path
|
||||||
"""
|
"""
|
||||||
path = Path("~/.config/halig/halig.yml").expanduser()
|
return Path(os.path.expandvars(path)).expanduser().resolve()
|
||||||
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def get_template_data(path: Path) -> str | None:
|
def get_template_data(path: Path) -> str | None:
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
name = "halig"
|
name = "halig"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
description = ""
|
description = ""
|
||||||
authors = ["cătălin <catalin@roboces.dev>"]
|
authors = ["cătălin <185504a9@duck.com>"]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
||||||
[tool.poetry.scripts]
|
[tool.poetry.scripts]
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ from tempfile import NamedTemporaryFile
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import yaml
|
import yaml
|
||||||
|
from pydantic import ValidationError
|
||||||
|
|
||||||
from halig.config import get_config, Config, EncryptionKeysConfig
|
from halig.config import get_config, Config, EncryptionKeysConfig
|
||||||
from halig.exceptions import ConfigFileDoesNotExist, ConfigFileIsInvalid
|
from halig.exceptions import ConfigFileDoesNotExist, ConfigFileIsInvalid
|
||||||
|
|
@ -26,9 +27,9 @@ def test_get_config_raises_invalid_config_file_00(tmpfile): # noqa: F811
|
||||||
get_config(Path(tmpfile.name))
|
get_config(Path(tmpfile.name))
|
||||||
|
|
||||||
|
|
||||||
def test_get_config_raises_invalid_config_file_01(tmpfile): # noqa: F811
|
def test_get_config_raises_validation_error(tmpfile): # noqa: F811
|
||||||
yaml.dump({"foo": "bar"}, tmpfile, Dumper=yaml.SafeDumper)
|
yaml.dump({"foo": "bar"}, tmpfile, Dumper=yaml.SafeDumper)
|
||||||
with pytest.raises(ConfigFileIsInvalid):
|
with pytest.raises(ValidationError):
|
||||||
get_config(Path(tmpfile.name))
|
get_config(Path(tmpfile.name))
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -50,7 +51,20 @@ def test_get_config(tmpdir): # noqa: F811
|
||||||
public_key_path=public_key_path, private_key_path=private_key_path
|
public_key_path=public_key_path, private_key_path=private_key_path
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
assert config.notes_root_path == notes_root_path
|
raw_config = config.dict()
|
||||||
assert config.age_binary_path == age_binary_path
|
assert (
|
||||||
assert config.encryption_keys.public_key_path == public_key_path
|
config.notes_root_path == notes_root_path == Path(raw_config["notes_root_path"])
|
||||||
assert config.encryption_keys.private_key_path == private_key_path
|
)
|
||||||
|
assert (
|
||||||
|
config.age_binary_path == age_binary_path == Path(raw_config["age_binary_path"])
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
config.encryption_keys.public_key_path
|
||||||
|
== public_key_path
|
||||||
|
== Path(raw_config["encryption_keys"]["public_key_path"])
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
config.encryption_keys.private_key_path
|
||||||
|
== private_key_path
|
||||||
|
== Path(raw_config["encryption_keys"]["private_key_path"])
|
||||||
|
)
|
||||||
|
|
|
||||||
33
tests/test_utils.py
Normal file
33
tests/test_utils.py
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from halig.utils import resolve_path
|
||||||
|
|
||||||
|
|
||||||
|
def test_resolve_absolute_path():
|
||||||
|
path = Path("/foo/bar/baz")
|
||||||
|
assert resolve_path(path) == path
|
||||||
|
|
||||||
|
|
||||||
|
def test_resolve_user_path():
|
||||||
|
path = Path("~/foo/bar/baz")
|
||||||
|
assert resolve_path(path) == path.expanduser()
|
||||||
|
|
||||||
|
|
||||||
|
def test_resolve_path_with_envvars():
|
||||||
|
os.environ["FOO"] = "foo"
|
||||||
|
os.environ["BAR"] = "bar"
|
||||||
|
path = Path("/${FOO}/${BAR}")
|
||||||
|
assert resolve_path(path) == Path("/foo/bar")
|
||||||
|
|
||||||
|
|
||||||
|
def test_resolve_relative_path():
|
||||||
|
path = Path("foo/bar/baz")
|
||||||
|
assert resolve_path(path) == path.resolve()
|
||||||
|
|
||||||
|
|
||||||
|
def test_resolve_path_all():
|
||||||
|
os.environ["FOO"] = "foo"
|
||||||
|
os.environ["BAR"] = "bar"
|
||||||
|
path = Path("foo/bar/$FOO/../$BAR")
|
||||||
|
assert resolve_path(path) == Path(os.path.expandvars(path)).resolve().expanduser()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue