forked from PathOfBuildingCommunity/PathOfBuilding
-
Notifications
You must be signed in to change notification settings - Fork 0
/
update_manifest.py
89 lines (75 loc) · 2.94 KB
/
update_manifest.py
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
import hashlib
import logging
import pathlib
from typing import Optional
import xml.etree.ElementTree
"""This script requires at least Python 3.7.0 to run."""
logger = logging.getLogger(__name__)
logger.addHandler(logging.NullHandler())
def update_manifest(version: Optional[str] = None, replace: bool = False):
"""Update SHA1 hashes and version number for Path of Building's manifest file.
:param version: Three-part version number following https://semver.org/.
:param replace: Whether to overwrite the existing manifest file.
:return:
"""
base_path = pathlib.Path()
try:
manifest = xml.etree.ElementTree.parse(base_path / "manifest.xml")
except FileNotFoundError:
logger.critical(f"Manifest file not found in path '{base_path}'")
return
root = manifest.getroot()
base_url = min((source.get("url") for source in root.iter("Source")), key=len)
parts = {
source.get("part"): pathlib.Path(source.get("url")).relative_to(base_url)
for source in root.iter("Source")
}
for file in root.iter("File"):
name, part = file.get("name"), file.get("part")
path = parts.get(part) / name
try:
data = path.read_bytes()
except FileNotFoundError:
logger.error(f"File not found, skipping {path}")
continue
sha1_hash = hashlib.sha1(data).hexdigest()
file.set("sha1", sha1_hash)
logger.info(f"Path: {path} hash: {sha1_hash}")
if version is not None:
root.find("Version").set("number", version)
logger.info(f"Updated to version {version}")
file_name = "manifest.xml" if replace else "manifest-updated.xml"
manifest.write(base_path / file_name, encoding="UTF-8", xml_declaration=True)
def cli():
"""CLI for conveniently updating Path of Building's manifest file."""
import argparse
parser = argparse.ArgumentParser(
usage="%(prog)s [options]",
description="Update Path of Building's manifest file for a new release.",
allow_abbrev=False,
)
parser.version = "1.1.0"
parser.add_argument("--version", action="version")
logging_level = parser.add_mutually_exclusive_group()
logging_level.add_argument(
"-v", "--verbose", action="store_true", help="Print more logging information"
)
logging_level.add_argument(
"-q", "--quiet", action="store_true", help="Print no logging information"
)
parser.add_argument("--in-place", action="store_true", help="Replace original file")
parser.add_argument(
"--set-version",
action="store",
help="Set manifest version number",
metavar="SEMVER",
)
args = parser.parse_args()
logger.addHandler(logging.StreamHandler())
if args.verbose:
logger.setLevel(logging.INFO)
elif args.quiet:
logger.setLevel(logging.CRITICAL + 1)
update_manifest(args.set_version or None, args.in_place)
if __name__ == "__main__":
cli()