Add rename subcommand and test happy case

This commit is contained in:
Tyler Starr 2024-09-09 14:59:57 -07:00
parent 1d8008ae0b
commit 5424bc3434
9 changed files with 123 additions and 9 deletions

View File

@ -1,6 +1,7 @@
[build-system] [build-system]
requires = ["setuptools>=61.0"] requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta" build-backend = "setuptools.build_meta"
[project] [project]
name = "z-py" name = "z-py"
version = "0.0.1" version = "0.0.1"
@ -17,8 +18,13 @@ classifiers = [
] ]
dependencies = [ dependencies = [
] ]
[project.urls] [project.urls]
"Homepage" = "https://github.com/starr-dusT/z-py" "Homepage" = "https://github.com/starr-dusT/z-py"
"Repository" = "https://github.com/starr-dusT/z-py" "Repository" = "https://github.com/starr-dusT/z-py"
[project.scripts] [project.scripts]
z = "z.z:main" z = "z.z:main"
[tool.pytest.ini_options]
addopts = "--ignore=tests/helpers"

View File

@ -1,3 +1,4 @@
from .z import * from .z import *
from .create import * from .create import *
from .tags import * from .tags import *
from .rename import *

View File

@ -6,15 +6,24 @@ import datetime
import re import re
# Format: <timestamp>--<title>__<tag1>_<tag2>.<ext> # Format: <timestamp>--<title>__<tag1>_<tag2>.<ext>
def normalize_name(name: str, tags: str, time: Union[datetime.date, None] = None, ext: str ="md"): def normalize_name(name: str, tags: str, time: Union[str, None] = None, ext: str ="md"):
if "-" in name or "_" in name: if "--" in name or "__" in name:
raise ArgumentTypeError("Title cannot have '-' or '_'") raise ArgumentTypeError("Title cannot have '--' or '__'")
if "-" in name or "_" in tags: if "--" not in tags and "__" not in tags:
raise ArgumentTypeError("Note cannot have '-' or '_'") if "_" in tags and "," in tags:
raise ArgumentTypeError("Tags must be seperated by ',' or '_'")
elif "_" in tags:
tag_sep = "_"
else:
tag_sep = ","
else:
raise ArgumentTypeError("Tags cannot have '--' or '__'")
# timestamp # timestamp
if time: if time:
f = time.strftime("%Y%m%dT%H%M%S") if not re.match("[0-9]{8}T[0-9]{6}", time):
raise ArgumentTypeError("Time must be string in format: YYMMDDTHHmmSS")
f = time
else: else:
f = datetime.datetime.now().strftime("%Y%m%dT%H%M%S") f = datetime.datetime.now().strftime("%Y%m%dT%H%M%S")
@ -24,14 +33,14 @@ def normalize_name(name: str, tags: str, time: Union[datetime.date, None] = None
# tags # tags
f += "__" f += "__"
for tag in tags.split(","): for tag in tags.split(tag_sep):
tag = tag.strip() tag = tag.strip()
tag = re.sub(r" ", "-", tag) tag = re.sub(r" ", "-", tag)
f += tag + "_" f += tag + "_"
f = f[:-1] f = f[:-1]
# ext # ext
if ext[0] == ".": if ext + " "[0] == ".":
f += ext f += ext
else: else:
f += "." + ext f += "." + ext

28
src/z/rename.py Normal file
View File

@ -0,0 +1,28 @@
import os
from typing import Union
from z.create import normalize_name
from argparse import ArgumentTypeError
def rename_file(source:str, dest:str, tags:str, date:Union[str, None] = None):
ext = None
if '.' in dest:
os.rename(source, normalize_name(dest.split('.')[0], tags, time=date, ext=dest.split('.')[1]))
else:
if '.' in source:
os.rename(source, normalize_name(dest, tags, time=date, ext=source.split('.')[1]))
else:
os.rename(source, normalize_name(dest, tags, time=date, ext=""))
def main(args):
tags = args.source.split("__")[1] if "--" in args.source else ""
if args.timestamp:
date = args.source.split("--")[0] if "--" in args.source else -1
if date == -1:
raise ArgumentTypeError("Timestamp option only works for source files that are formatted like Denote files.")
rename_file(args.source, args.dest, tags, date=date)
else:
rename_file(args.source, args.dest, tags)
if __name__ == "__main__":
main(None)

View File

@ -1,6 +1,6 @@
from pathlib import Path from pathlib import Path
import argparse import argparse
from z import create, tags from z import create, tags, rename
import sys import sys
def init_parser(): def init_parser():
@ -14,6 +14,12 @@ def init_parser():
create_parser.add_argument("-s", "--silo", nargs="?", default="", const="", help="Optionally create note in silo") create_parser.add_argument("-s", "--silo", nargs="?", default="", const="", help="Optionally create note in silo")
create_parser.add_argument("-o", "--outline", nargs="?", default="", const="", help="Optionally initialize note with outline") create_parser.add_argument("-o", "--outline", nargs="?", default="", const="", help="Optionally initialize note with outline")
rename_parser = sub_parsers.add_parser("rename", help="rename note")
rename_parser.set_defaults(func=rename.main)
rename_parser.add_argument("source", help="name of note to change")
rename_parser.add_argument("dest", help="new name of note")
rename_parser.add_argument("-t", "--timestamp", action="store_true", help="don't update timestamp of note")
tags_parser = sub_parsers.add_parser("tags", help="edit tags") tags_parser = sub_parsers.add_parser("tags", help="edit tags")
tags_parser.set_defaults(func=tags.main) tags_parser.set_defaults(func=tags.main)
tags_parser.add_argument("file", help="name of file to create") tags_parser.add_argument("file", help="name of file to create")

3
tests/__init__.py Normal file
View File

@ -0,0 +1,3 @@
import sys
sys.path.append("src")

3
tests/conftest.py Normal file
View File

@ -0,0 +1,3 @@
import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), 'helpers'))

12
tests/helpers/utils.py Normal file
View File

@ -0,0 +1,12 @@
import shutil
import os
def pre_test(tmp_path):
owd = os.getcwd()
path = tmp_path / "z"
shutil.copytree("./example", path)
os.chdir(path / "test")
return owd
def post_test(owd):
os.chdir(owd)

46
tests/test_rename.py Normal file
View File

@ -0,0 +1,46 @@
from z.z import main
import glob
import utils
import sys
import os
from unittest.mock import patch
import re
from pathlib import Path
def path_search(glob_str:str):
return glob.glob(glob_str)
def read_file(file_path:str):
with open(file_path, "r") as f:
return f.read()
def test_rename_denote(tmp_path):
utils.pre_test(tmp_path)
# New timestamp
src = "19700101T000000--example-file-3__test1_test2_test3"
input = "new example file 3"
with patch("sys.argv", ["", "rename", src, input]):
main()
# original file gone
assert not path_search(src)
# new file created
files = path_search("*--new-example-file-3__test1_test2_test3")
assert len(files) == 1
# contents unchanged
assert read_file(files[0]) == "test 3"
# Keep old timestamp
src = "19700101T000000--example-file-4__test1_test2_test3"
input = "new example file 4"
with patch("sys.argv", ["", "rename", src, input, "-t"]):
main()
# original file gone
assert not path_search(src)
# new file created
files = path_search("19700101T000000--new-example-file-4__test1_test2_test3")
assert len(files) == 1
# contents unchanged
assert read_file(files[0]) == "test 4"
utils.post_test(tmp_path)