From d9db4900eb7aa048a8da51c822ab6e2912e1b8c5 Mon Sep 17 00:00:00 2001 From: Tomasz Wojdat Date: Tue, 7 Nov 2023 22:43:05 +0100 Subject: [PATCH] Revert "Refactor way of parsing arguments and change way of handling ID" This reverts commit e028160bf397e2828e30647c567d38bfbd306a3e. --- src/pyzet/main.py | 249 ++++++++++++++++++++++++++++--------------- src/pyzet/show.py | 47 ++++---- src/pyzet/utils.py | 10 ++ src/pyzet/zettel.py | 151 ++++++-------------------- tests/zettel_test.py | 57 ++-------- 5 files changed, 244 insertions(+), 270 deletions(-) diff --git a/src/pyzet/main.py b/src/pyzet/main.py index f847626..40acb66 100644 --- a/src/pyzet/main.py +++ b/src/pyzet/main.py @@ -17,9 +17,9 @@ import pyzet.constants as C from pyzet import show from pyzet import utils -from pyzet import zettel from pyzet.grep import define_grep_cli from pyzet.grep import grep +from pyzet.grep import parse_grep_patterns from pyzet.sample_config import define_sample_config_cli from pyzet.sample_config import sample_config from pyzet.utils import add_pattern_args @@ -27,8 +27,8 @@ from pyzet.utils import Config from pyzet.utils import get_git_output from pyzet.utils import get_git_remote_url -from pyzet.zettel import get from pyzet.zettel import get_all +from pyzet.zettel import get_zettel from pyzet.zettel import get_zettel_repr @@ -96,7 +96,24 @@ def _get_parser() -> tuple[ArgumentParser, dict[str, ArgumentParser]]: subparsers.add_parser('add', help='add a new zettel') edit_parser = subparsers.add_parser('edit', help='edit an existing zettel') - add_pattern_args(edit_parser) + edit_parser.add_argument( + '-i', + '--ignore-case', + action='store_true', + help='case insensitive matching', + ) + edit_parser.add_argument( + '-p', + '--pretty', + action='store_true', + help='use prettier format for printing date and time', + ) + edit_parser.add_argument( + '--tags', + action='store_true', + help='show tags for each zettel', + ) + edit_parser.add_argument('patterns', nargs='*', help='grep patterns') remove_parser = subparsers.add_parser('rm', help='remove a zettel') add_pattern_args(remove_parser) @@ -203,52 +220,20 @@ def _add_git_cmd_options(parser: ArgumentParser, cmd_name: str) -> None: def _parse_args(args: Namespace) -> int: if args.command == 'sample-config': return sample_config(args.kind) - config = _get_config(args) - - if args.command == 'show': - return show.command(args, config) - - if args.command == 'rm': - return remove_zettel(args, config) - - if args.command == 'init': - return init_repo(config, args.initial_branch) - - if args.command == 'add': - return add_zettel(config) - - if args.command == 'edit': - return edit_zettel(args, config) - - if args.command == 'list': - return list_zettels(args, config.repo) - - if args.command == 'tags': - if args.count: - return count_tags(config.repo) - return list_tags(config.repo, is_reversed=args.reverse) - - if args.command == 'grep': - return grep(args, config) - - if args.command in {'status', 'push'}: - return call_git(config, args.command, args.options) - - if args.command == 'remote': - return get_remote_url(args, config) - - if args.command == 'pull': - # --rebase is used to maintain a linear history without merges, - # as this seems to be a reasonable approach in ZK repo that is - # usually personal. - return call_git(config, 'pull', ('--rebase',)) - - if args.command == 'clean': - return clean_zet_repo( - config.repo, is_dry_run=args.dry_run, is_force=args.force - ) - raise NotImplementedError + id_: str | None + try: + # show & edit commands use nargs="?" which makes + # args.command str rather than single element list. + if args.command in {'show'}: + id_ = args.id + else: + id_ = args.id[0] + except AttributeError: + pass # command that doesn't use 'id' was executed + else: + return _parse_args_with_id(id_, args, config) + return _parse_args_without_id(args, config) def _get_config(args: Namespace) -> Config: @@ -310,14 +295,90 @@ def process_yaml( ) +def _parse_args_with_id( + id_: str | None, args: Namespace, config: Config +) -> int: + if id_ is None: + id_ = _get_last_zettel_id(config.repo) + + command = args.command + _validate_id(id_, command, config) + + if command == 'show': + return show.command(args, config, id_) + + if command == 'rm': + return remove_zettel(id_, config) + + raise NotImplementedError + + +def _get_last_zettel_id(repo_path: Path) -> str: + return get_all(Path(repo_path, C.ZETDIR), is_reversed=True)[0].id_ + + +def _parse_args_without_id(args: Namespace, config: Config) -> int: + if args.command == 'init': + return init_repo(config, args.initial_branch) + + if args.command == 'add': + return add_zettel(config) + + if args.command == 'edit': + return edit_zettel(args, config) + + if args.command == 'list': + return list_zettels(args, config.repo) + + if args.command == 'tags': + if args.count: + return count_tags(config.repo) + return list_tags(config.repo, is_reversed=args.reverse) + + if args.command == 'grep': + return grep(args, config) + + if args.command in {'status', 'push'}: + return call_git(config, args.command, args.options) + + if args.command == 'remote': + return get_remote_url(args, config) + + if args.command == 'pull': + # --rebase is used to maintain a linear history without merges, + # as this seems to be a reasonable approach in ZK repo that is + # usually personal. + return call_git(config, 'pull', ('--rebase',)) + + if args.command == 'clean': + return clean_zet_repo( + config.repo, is_dry_run=args.dry_run, is_force=args.force + ) + + raise NotImplementedError + + def get_remote_url(args: Namespace, config: Config) -> int: print(get_git_remote_url(config, args.origin, args.options)) return 0 +def _validate_id(id_: str, command: str, config: Config) -> None: + zettel_dir = Path(config.repo, C.ZETDIR, id_) + if not zettel_dir.is_dir(): + raise SystemExit(f"ERROR: folder {id_} doesn't exist") + if not Path(zettel_dir, C.ZETTEL_FILENAME).is_file(): + if command == 'rm': + raise SystemExit( + f"ERROR: {C.ZETTEL_FILENAME} in {id_} doesn't exist. " + "Use 'pyzet clean' to remove empty folder" + ) + raise SystemExit(f"ERROR: {C.ZETTEL_FILENAME} in {id_} doesn't exist") + + def list_zettels(args: Namespace, path: Path) -> int: - for zet in get_all(Path(path, C.ZETDIR), args.reverse): - print(get_zettel_repr(zet, args)) + for zettel in get_all(Path(path, C.ZETDIR), args.reverse): + print(get_zettel_repr(zettel, args)) return 0 @@ -328,7 +389,6 @@ def list_tags(path: Path, is_reversed: bool) -> int: ) # Chain is reverse sorted for the correct alphabetical displaying of # tag counts. This is because Counter's most_common() method - # remembers the insertion order. tags = Counter(sorted(all_tags, reverse=True)) target = ( @@ -405,7 +465,7 @@ def add_zettel(config: Config) -> int: _open_file(zettel_path, config) try: - zet = zettel.get(zettel_path) + zettel = get_zettel(zettel_path.parent) except ValueError: logging.info( f"add: zettel creation aborted '{zettel_path.absolute()}'" @@ -414,7 +474,7 @@ def add_zettel(config: Config) -> int: zettel_path.unlink() zettel_dir.rmdir() else: - _commit_zettel(config, zettel_path, zet.title) + _commit_zettel(config, zettel_path, zettel.title) logging.info(f"add: zettel created '{zettel_path.absolute()}'") print(f'{id_} was created') return 0 @@ -422,45 +482,70 @@ def add_zettel(config: Config) -> int: def edit_zettel(args: Namespace, config: Config) -> int: """Edits zettel and commits changes with 'ED:' in the message.""" - if args.patterns: - zet = zettel.get_from_grep(args, config) - elif args.id is not None: - zet = zettel.get_from_id(args.id, config.repo) - else: - zet = zettel.get_last(config.repo) + opts = ['-I', '--all-match', '--name-only'] + if args.ignore_case: + opts.append('--ignore-case') + opts.extend( + [*parse_grep_patterns(args.patterns), '--', f'*/{C.ZETTEL_FILENAME}'] + ) + try: + out = get_git_output(config, 'grep', opts).decode() + except subprocess.CalledProcessError: + raise SystemExit('ERROR: no zettels found') + + matches = {} + for idx, filename in enumerate(out.splitlines(), start=1): + path = Path(config.repo, filename) + matches[idx] = get_zettel(path) - _open_file(zet.path, config) + print(f'Found {len(matches)} matches:') + for idx, zettel in matches.items(): + print(f'[{idx}] {get_zettel_repr(zettel, args)}') try: - zet = get(zet.path) + user_input = input('Open (press enter to cancel): ') + except KeyboardInterrupt: + raise SystemExit('\naborting') + + if user_input == '': + raise SystemExit('aborting') + try: + zettel = matches[int(user_input)] + except KeyError: + raise SystemExit('ERROR: wrong zettel ID') + + _open_file(zettel.path, config) + + try: + zettel = get_zettel(zettel.path) except ValueError: logging.info( - f"edit: zettel modification aborted '{zet.path.absolute()}'" + f"edit: zettel modification aborted '{zettel.path.absolute()}'" ) print('Editing zettel aborted, restoring the version from git...') - call_git(config, 'restore', (zet.path.as_posix(),)) + call_git(config, 'restore', (zettel.path.as_posix(),)) else: - if _file_was_modified(zet.path, config): + if _file_was_modified(zettel.path, config): output = _get_files_touched_last_commit(config).decode('utf-8') - if output == f'{C.ZETDIR}/{zet.id}/{C.ZETTEL_FILENAME}\n': + if output == f'{C.ZETDIR}/{zettel.id_}/{C.ZETTEL_FILENAME}\n': # If we touch the same zettel as in the last commit, # than we automatically squash the new changes with the # last commit, so the Git history can be simplified. - call_git(config, 'add', (zet.path.as_posix(),)) + call_git(config, 'add', (zettel.path.as_posix(),)) call_git(config, 'commit', ('--amend', '--no-edit')) print( - f'{zet.id} was edited and auto-squashed with the last' + f'{zettel.id_} was edited and auto-squashed with the last' ' commit\nForce push might be required' ) else: _commit_zettel( config, - zet.path, - _get_edit_commit_msg(zet.path, zet.title, config), + zettel.path, + _get_edit_commit_msg(zettel.path, zettel.title, config), ) - print(f'{zet.id} was edited') + print(f'{zettel.id_} was edited') else: - print(f"{zet.id} wasn't modified") + print(f"{zettel.id_} wasn't modified") return 0 @@ -510,36 +595,32 @@ def _open_file(filename: Path, config: Config) -> None: ) -def remove_zettel(args: Namespace, config: Config) -> int: +def remove_zettel(id_: str, config: Config) -> int: """Removes zettel and commits changes with 'RM:' in the message.""" - if args.patterns: - zet = zettel.get_from_grep(args, config) - elif args.id is not None: - zet = zettel.get_from_id(args.id, config.repo) - else: - raise SystemExit prompt = ( - f'{zet.id} will be deleted including all files ' + f'{id_} will be deleted including all files ' 'that might be inside. Are you sure? (y/N): ' ) if input(prompt) != 'y': raise SystemExit('aborting') + zettel_path = Path(config.repo, C.ZETDIR, id_, C.ZETTEL_FILENAME) + zettel = get_zettel(zettel_path.parent) # All files in given zettel folder are removed one by one. This # might be slower than shutil.rmtree() but gives nice log entry for # each file. - for file in zet.path.parent.iterdir(): + for file in zettel_path.parent.iterdir(): file.unlink() logging.info(f"remove: delete '{file}'") print(f'{file} was removed') - _commit_zettel(config, zet.path, f'RM: {zet.title}') + _commit_zettel(config, zettel_path, f'RM: {zettel.title}') # If dir is removed before committing, git raises a warning that dir # doesn't exist. - zet.path.parent.rmdir() - logging.info(f"remove: delete folder '{zet.path.parent}'") - print(f'{zet.id} was removed') + zettel_path.parent.rmdir() + logging.info(f"remove: delete folder '{zettel_path.parent}'") + print(f'{zettel_path.parent} was removed') return 0 diff --git a/src/pyzet/show.py b/src/pyzet/show.py index 023b21a..dd817af 100644 --- a/src/pyzet/show.py +++ b/src/pyzet/show.py @@ -3,14 +3,14 @@ from argparse import _SubParsersAction from argparse import ArgumentParser from argparse import Namespace +from pathlib import Path import pyzet.constants as C -from pyzet import zettel from pyzet.utils import add_pattern_args from pyzet.utils import Config from pyzet.utils import get_git_remote_url -from pyzet.zettel import get_md_link -from pyzet.zettel import Zettel +from pyzet.utils import get_md_relative_link +from pyzet.zettel import get_zettel def get_parser( @@ -48,37 +48,38 @@ def get_parser( return show_parser -def command(args: Namespace, config: Config) -> int: - if args.patterns: - zet = zettel.get_from_grep(args, config) - elif args.id is not None: - zet = zettel.get_from_id(args.id, config.repo) - else: - zet = zettel.get_last(config.repo) - +def command(args: Namespace, config: Config, id_: str) -> int: if args.show_cmd == 'text': - return show_zettel(zet) - + return show_zettel(id_, config.repo) if args.show_cmd == 'mdlink': - print(get_md_link(zet)) - return 0 - + return show_zettel_as_md_link(id_, config.repo) if args.show_cmd == 'url': - remote = _remote_dot_git(get_git_remote_url(config, args.origin)) - print(_get_zettel_url(remote, args.branch, zet.id)) - return 0 - + return show_zettel_as_url(id_, args, config) raise NotImplementedError -def show_zettel(zet: Zettel) -> int: +def show_zettel(id_: str, repo_path: Path) -> int: """Prints zettel text prepended with centered ID as a header.""" - print(f' {zet.id} '.center(C.ZETTEL_WIDTH, '=')) - with open(zet.path, encoding='utf-8') as file: + print(f' {id_} '.center(C.ZETTEL_WIDTH, '=')) + zettel_path = Path(repo_path, C.ZETDIR, id_, C.ZETTEL_FILENAME) + with open(zettel_path, encoding='utf-8') as file: print(file.read(), end='') return 0 +def show_zettel_as_md_link(id_: str, repo_path: Path) -> int: + zettel_path = Path(repo_path, C.ZETDIR, id_) + zettel = get_zettel(zettel_path) + print(get_md_relative_link(zettel.id_, zettel.title)) + return 0 + + +def show_zettel_as_url(id_: str, args: Namespace, config: Config) -> int: + remote = _remote_dot_git(get_git_remote_url(config, args.origin)) + print(_get_zettel_url(remote, args.branch, id_)) + return 0 + + def _remote_dot_git(remote: str) -> str: """Remove '.git' suffix from remote URL.""" return remote.partition('.git')[0] diff --git a/src/pyzet/utils.py b/src/pyzet/utils.py index cc83410..fd1292e 100644 --- a/src/pyzet/utils.py +++ b/src/pyzet/utils.py @@ -73,6 +73,16 @@ def _convert_ssh_to_https(remote: str) -> str: return 'https://' + remote.partition('git@')[-1].replace(':', '/') +def get_md_relative_link(id_: str, title: str) -> str: + """Returns a representation of a zettel that is a relative Markdown link. + + Asterisk at the beginning is a Markdown syntax for an unordered list, + as links to zettels are usually just used in references section of a + zettel. + """ + return f'* [{id_}](../{id_}) {title}' + + @functools.lru_cache(maxsize=1) def _get_git_bin() -> str: if (git := shutil.which('git')) is None: diff --git a/src/pyzet/zettel.py b/src/pyzet/zettel.py index 24cd050..ba24c54 100644 --- a/src/pyzet/zettel.py +++ b/src/pyzet/zettel.py @@ -3,17 +3,12 @@ import logging import os import re -import subprocess from argparse import Namespace from datetime import datetime from pathlib import Path from typing import NamedTuple import pyzet.constants as C -from pyzet import zettel -from pyzet.grep import parse_grep_patterns -from pyzet.utils import Config -from pyzet.utils import get_git_output class Zettel(NamedTuple): @@ -23,7 +18,7 @@ class Zettel(NamedTuple): """ title: str - id: str + id_: str tags: tuple[str, ...] path: Path @@ -36,7 +31,7 @@ def get_all(path: Path, is_reversed: bool = False) -> list[Zettel]: for item in sorted(path.iterdir(), reverse=is_reversed): if item.is_dir(): try: - items.append(get_from_dir(item)) + items.append(get_zettel(item)) logging.debug( f"get_zettels: zettel appended '{item.absolute()}'" ) @@ -54,97 +49,40 @@ def get_all(path: Path, is_reversed: bool = False) -> list[Zettel]: return items -def get_from_grep(args: Namespace, config: Config) -> Zettel: - if _patterns_empty(args.patterns): - msg = 'ERROR: provided patterns are incorrect (empty or whitespace)' - raise SystemExit(msg) - opts = ['-I', '--all-match', '--name-only'] - if args.ignore_case: - opts.append('--ignore-case') - opts.extend( - [*parse_grep_patterns(args.patterns), '--', f'*/{C.ZETTEL_FILENAME}'] - ) - try: - out = get_git_output(config, 'grep', opts).decode() - except subprocess.CalledProcessError: - raise SystemExit('ERROR: no zettels found') - - matches: dict[int, Zettel] = {} - for idx, filename in enumerate(out.splitlines(), start=1): - matches[idx] = zettel.get(Path(config.repo, filename)) - - confirmation_threshold = 50 - if len(matches) > confirmation_threshold: - prompt = f'Found {len(matches)} matching zettels. Continue? (y/N): ' - try: - if input(prompt) != 'y': - raise SystemExit('aborting') - except KeyboardInterrupt: - raise SystemExit('\naborting') - - print(f'Found {len(matches)} matches:') - for idx, zet in matches.items(): - print(f'[{idx}] {get_zettel_repr(zet, args)}') - - try: - user_input = input('Open (press enter to cancel): ') - except KeyboardInterrupt: - raise SystemExit('\naborting') - - if user_input == '': - raise SystemExit('aborting') - - try: - return matches[int(user_input)] - except KeyError: - raise SystemExit('ERROR: wrong zettel ID') - - -def _patterns_empty(patterns: list[str]) -> bool: - """Returns True if all provided patterns are empty str or whitespace.""" - return all('' == s or s.isspace() for s in patterns) - - -def get_from_id(id_: str, repo: Path) -> Zettel: - """Gets zettel from its ID given repo path.""" - try: - return get_from_dir(Path(repo, C.ZETDIR, id_)) - except FileNotFoundError: - raise SystemExit(f"ERROR: zettel '{id_}' doesn't exist.") - - -def get_last(repo: Path) -> Zettel: - """Gets the last zettel from a given repo.""" - return get_all(Path(repo, C.ZETDIR), is_reversed=True)[0] - - -def get_from_dir(dirpath: Path) -> Zettel: - """Gets zettel from a directory named after its ID.""" - return get(Path(dirpath, C.ZETTEL_FILENAME)) - +def get_zettel(path: Path) -> Zettel: + if path.name == C.ZETTEL_FILENAME: + md_path = path + id_ = path.parent.name + else: + md_path = Path(path, C.ZETTEL_FILENAME) + id_ = path.name -def get(path: Path) -> Zettel: - """Gets zettel from a full path.""" - if path.is_dir(): - raise ValueError + title_line, tags_line = _get_first_and_last_line(md_path) + title = get_markdown_title(title_line.strip(), md_path.name) + tags = get_tags(tags_line.strip()) if tags_line.startswith(4 * ' ') else () + logging.debug(f"get_zettel: '{md_path.name}' with title '{title}'") + return Zettel(title=title, id_=id_, tags=tags, path=md_path) - title_line, tags_line = _get_first_and_last_line(path) - if title_line == '': - raise ValueError - if tags_line.startswith(4 * ' '): - tags = get_tags(tags_line.strip()) - else: - tags = tuple() +def _get_first_and_last_line(path: Path) -> tuple[str, str]: + """Gets the first and the last line from a given file. - id_ = path.parent.name + It uses file.seek() to look from the end of the file. It's fast but + requires the file to be opened in binary mode. - return Zettel( - id=id_, - title=get_markdown_title(title_line, id_), - path=path, - tags=tags, - ) + Reference: + https://stackoverflow.com/a/54278929/14458327 + """ + with open(path, 'rb') as file: + title_line = file.readline().decode('utf-8') + try: + file.seek(-2, os.SEEK_END) + while file.read(1) != b'\n': + file.seek(-2, os.SEEK_CUR) + except OSError: # file has only a single line + file.seek(0) + tags_line = file.readline().decode('utf-8') + return title_line, tags_line def get_zettel_repr(zet: Zettel, args: Namespace) -> str: @@ -155,13 +93,13 @@ def get_zettel_repr(zet: Zettel, args: Namespace) -> str: except ValueError: # No tags found pass if args.pretty: - return f'{get_timestamp(zet.id)} -- {zet.title}{tags}' + return f'{get_timestamp(zet.id_)} -- {zet.title}{tags}' try: if args.link: return get_md_link(zet) except AttributeError: # 'Namespace' object has no attribute 'link' pass - return f'{zet.id} -- {zet.title}{tags}' + return f'{zet.id_} -- {zet.title}{tags}' def get_timestamp(id_: str) -> datetime: @@ -176,7 +114,7 @@ def get_md_link(zet: Zettel) -> str: as links to zettels are usually just used in references section of a zettel. """ - return f'* [{zet.id}](../{zet.id}) {zet.title}' + return f'* [{zet.id_}](../{zet.id_}) {zet.title}' def get_markdown_title(title_line: str, id_: str) -> str: @@ -212,24 +150,3 @@ def get_tags_str(zettel: Zettel) -> str: raise ValueError else: return '#' + ' #'.join(zettel.tags) - - -def _get_first_and_last_line(path: Path) -> tuple[str, str]: - """Gets the first and the last line from a given file. - - It uses file.seek() to look from the end of the file. It's fast but - requires the file to be opened in binary mode. - - Reference: - https://stackoverflow.com/a/54278929/14458327 - """ - with open(path, 'rb') as file: - title_line = file.readline().decode('utf-8') - try: - file.seek(-2, os.SEEK_END) - while file.read(1) != b'\n': - file.seek(-2, os.SEEK_CUR) - except OSError: # file has only a single line - file.seek(0) - tags_line = file.readline().decode('utf-8') - return title_line, tags_line diff --git a/tests/zettel_test.py b/tests/zettel_test.py index 607d844..1b86e36 100644 --- a/tests/zettel_test.py +++ b/tests/zettel_test.py @@ -6,9 +6,9 @@ import pytest import pyzet.constants as C -from pyzet import zettel from pyzet.zettel import get_all from pyzet.zettel import get_markdown_title +from pyzet.zettel import get_zettel from pyzet.zettel import Zettel @@ -17,19 +17,19 @@ def test_get_all(): expected = [ Zettel( title='Zet test entry', - id='20211016205158', + id_='20211016205158', tags=('another-tag', 'tag-after-two-spaces', 'test-tag'), path=Path('testing/zet/zettels/20211016205158/README.md'), ), Zettel( title='Another zet test entry', - id='20211016223643', + id_='20211016223643', tags=('test-tag',), path=Path('testing/zet/zettels/20211016223643/README.md'), ), Zettel( title='Zettel with UTF-8', - id='20220101220852', + id_='20220101220852', tags=(), path=Path('testing/zet/zettels/20220101220852/README.md'), ), @@ -42,19 +42,19 @@ def test_get_all_reverse(): expected = [ Zettel( title='Zettel with UTF-8', - id='20220101220852', + id_='20220101220852', tags=(), path=Path('testing/zet/zettels/20220101220852/README.md'), ), Zettel( title='Another zet test entry', - id='20211016223643', + id_='20211016223643', tags=('test-tag',), path=Path('testing/zet/zettels/20211016223643/README.md'), ), Zettel( title='Zet test entry', - id='20211016205158', + id_='20211016205158', tags=('another-tag', 'tag-after-two-spaces', 'test-tag'), path=Path('testing/zet/zettels/20211016205158/README.md'), ), @@ -75,7 +75,7 @@ def test_get_all_skip_file(tmp_path): expected = [ Zettel( title='Zettel with UTF-8', - id='20220101220852', + id_='20220101220852', tags=(), path=Path(tmp_path, 'zettels/20220101220852/README.md'), ) @@ -90,49 +90,14 @@ def test_get_all_dir_not_found(): assert msg == "ERROR: folder fooBarNonexistent doesn't exist." -def test_get(): +def test_open_zettel(): expected = Zettel( title='Zet test entry', - id='20211016205158', + id_='20211016205158', tags=('another-tag', 'tag-after-two-spaces', 'test-tag'), path=Path('testing/zet/zettels/20211016205158/README.md'), ) - dir = Path(f'testing/zet/{C.ZETDIR}/20211016205158/{C.ZETTEL_FILENAME}') - actual = zettel.get(dir) - assert actual == expected - - -def test_get_from_dir(): - expected = Zettel( - title='Zet test entry', - id='20211016205158', - tags=('another-tag', 'tag-after-two-spaces', 'test-tag'), - path=Path('testing/zet/zettels/20211016205158/README.md'), - ) - dir = Path(f'testing/zet/{C.ZETDIR}/20211016205158') - actual = zettel.get_from_dir(dir) - assert actual == expected - - -def test_get_from_id(): - expected = Zettel( - title='Zet test entry', - id='20211016205158', - tags=('another-tag', 'tag-after-two-spaces', 'test-tag'), - path=Path('testing/zet/zettels/20211016205158/README.md'), - ) - actual = zettel.get_from_id('20211016205158', repo=Path('testing/zet')) - assert actual == expected - - -def test_get_last(): - expected = Zettel( - title='Zettel with UTF-8', - id='20220101220852', - tags=(), - path=Path('testing/zet/zettels/20220101220852/README.md'), - ) - actual = zettel.get_last(Path('testing/zet')) + actual = get_zettel(Path(f'testing/zet/{C.ZETDIR}/20211016205158')) assert actual == expected