1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
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
|