diff --git a/test/test_cli.py b/test/test_cli.py deleted file mode 100644 index 0bca9e7..0000000 --- a/test/test_cli.py +++ /dev/null @@ -1,17 +0,0 @@ -from pathlib import Path -from unittest.mock import Mock, patch - -from topen import add_annotation, open_editor - - -def test_open_editor_escapes_shell(): - """Ensure filenames with spaces/metas do not allow shell injection.""" - with patch("subprocess.run") as run_mock: - open_editor(Path("my note$1.txt"), "vim") - run_mock.assert_called_once_with(["vim", "my note$1.txt"], check=True) - - -def test_add_annotation_calls_tasklib(): - task = Mock() - add_annotation(task, "hello") - task.add_annotation.assert_called_once_with("hello") diff --git a/topen.py b/topen.py index b5374e1..e04e39e 100755 --- a/topen.py +++ b/topen.py @@ -63,9 +63,11 @@ def main(cfg: "TConf | None" = None, io: "_IO | None" = None) -> int: fpath = get_notes_file(uuid, notes_dir=cfg.notes_dir, notes_ext=cfg.notes_ext) - _ensure_parent_dir(fpath) + if not fpath.parent.exists(): + fpath.parent.mkdir(parents=True, exist_ok=True) + io.out(f"Editing note: {fpath}") - open_editor(fpath, editor=cfg.notes_editor, io=io) + open_editor(fpath, editor=cfg.notes_editor) if fpath.exists(): if is_annotation_missing(task, annotation_content=cfg.notes_annot): @@ -95,13 +97,9 @@ def get_notes_file(uuid: str, notes_dir: Path, notes_ext: str) -> Path: return Path(notes_dir).joinpath(f"{uuid}.{notes_ext}") -def open_editor(file: Path, editor: str, io: "_IO | None" = None) -> None: +def open_editor(file: Path, editor: str) -> None: """Opens a file with the chosen editor.""" - try: - _ = subprocess.run([editor, str(file)], check=True) - except subprocess.CalledProcessError: - if io: - io.err("Editor exited with an error, aborting.\n") + _ = subprocess.run(f"{editor} {file}", shell=True) def is_annotation_missing(task: Task, annotation_content: str) -> bool: @@ -137,21 +135,16 @@ class Opt: is_flag: bool = False -def _expand_path(p: Path | str) -> Path: +def _real_path(p: Path | str) -> Path: return Path(os.path.expandvars(p)).expanduser() -def _ensure_parent_dir(file: Path) -> None: - if not file.parent.exists(): - file.parent.mkdir(parents=True, exist_ok=True) - - def _determine_default_task_rc() -> Path: - if _expand_path("~/.taskrc").exists(): - return _expand_path("~/.taskrc") - if _expand_path("$XDG_CONFIG_HOME/task/taskrc").exists(): - return _expand_path("$XDG_CONFIG_HOME/task/taskrc") - return _expand_path("~/.config/task/taskrc") + if _real_path("~/.taskrc").exists(): + return _real_path("~/.taskrc") + if _real_path("$XDG_CONFIG_HOME/task/taskrc").exists(): + return _real_path("$XDG_CONFIG_HOME/task/taskrc") + return _real_path("~/.config/task/taskrc") def _strtobool(val: str) -> bool: @@ -265,11 +258,11 @@ class TConf: """If set topen will give no feedback on note editing.""" def __post_init__(self): - self.task_rc = _expand_path(self.task_rc) - self.task_data = _expand_path(self.task_data) + self.task_rc = _real_path(self.task_rc) + self.task_data = _real_path(self.task_data) if self.notes_dir == NON_EXISTENT_PATH: self.notes_dir = self._default_notes_dir() - self.notes_dir = _expand_path(self.notes_dir) + self.notes_dir = _real_path(self.notes_dir) if not self.notes_editor: self.notes_editor = ( os.getenv("EDITOR")