diff options
Diffstat (limited to 'src/xpit_/list_.py')
| -rw-r--r-- | src/xpit_/list_.py | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/xpit_/list_.py b/src/xpit_/list_.py new file mode 100644 index 0000000..fe281c2 --- /dev/null +++ b/src/xpit_/list_.py @@ -0,0 +1,104 @@ +import os +from sys import argv, stdout, stderr +from . import args_helpers, issue, issue_tracker + +DEFAULT_ORDER: list[bytes] = [b"ID", b"POST_COUNT", b"TITLE", b"status", b"labels"] + +help_text = f"""\ +Usage: xpit list [options] +Examples: + xpit list -d , -f TITLE,POST_COUNT +Options: + -d, --delimiter <str> + Delimiter used to separate the fields. + Defaults to '|' (pipe). + -f, --fields <FIELD,...> + Defaults to '{b','.join(DEFAULT_ORDER).decode("utf-8")}'. + Guaranteed fields: + ID - ID of the issue + TITLE - Title of the issue + AUTHOR - Author of the issue + POST_COUNT - Total number of posts in the issue, including the initial post + PATH_ABS - absolute path to issue.md file + PATH_REL - relative path to issue.md file + Other fields are optional and parsed in issues' INI headers. + The fields are printed in order and the same field can be printed more than once. + -h, --help + Print this help text. +""" + +class Args: + def __init__(self) -> None: + self.order = DEFAULT_ORDER + self.delimiter = '|' + + def parse(self) -> bool: + flag_value_map = { + "help|h": 0, + "delimiter|d": 1, + "fields|f": 1, + } + res = args_helpers.parse_generic(flag_value_map, argv, 2) + if res is None: + return False + if "help" in res: + stdout.write(help_text) + return False + if "delimiter" in res: + self.delimiter = res["delimiter"][0] + if "fields" in res: + self.order = [field.encode("utf-8") for field in res["fields"][0].split(',')] + + return True +args = Args() + +def main() -> int: + if len(argv) < 2: + stdout.write(help_text) + return 1 + + if not args.parse(): + return 1 + + cwd = os.getcwd() + issue_tracker_dir = issue_tracker.find_dir(cwd) + if issue_tracker_dir is None: + return 1 + for file_name in os.listdir(issue_tracker_dir): + if not os.path.isdir(os.path.join(issue_tracker_dir, file_name)): + continue + + file_path = os.path.join(issue_tracker_dir, file_name, "issue.md") + with open(file_path, "rb") as f: + src = f.read() + info, err = issue.parse(src) + if err is not None: + stderr.write(err.msg) + return 1 + i = 0 + while True: + key = args.order[i] + if key == b"ID": + stdout.write(file_name) + elif key == b"TITLE": + stdout.write(info.title.decode("utf-8")) + elif key == b"POST_COUNT": + stdout.write(str(info.post_count())) + elif key == b"AUTHOR": + stdout.write(info.meta[b"author"].decode("utf-8")) + elif key == b"PATH_ABS": + stdout.write(file_path) + elif key == b"PATH_REL": + stdout.write(os.path.relpath(file_path, start=cwd)) + else: + if key in info.meta: + stdout.write(info.meta[key].decode("utf-8")) + + i += 1 + if i >= len(args.order): + break + stdout.write(args.delimiter) + stdout.write('\n') + + return 0 + |
