-
-
Notifications
You must be signed in to change notification settings - Fork 446
/
oca_towncrier.py
128 lines (113 loc) · 3.84 KB
/
oca_towncrier.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/usr/bin/env python
# Copyright (c) 2019 ACSONE SA/NV
# License AGPLv3 (http://www.gnu.org/licenses/agpl-3.0-standalone.html)
import contextlib
import datetime
import os
import shutil
import subprocess
import sys
import click
import toml
from .gitutils import commit_if_needed
from .manifest import read_manifest
def _make_issue_format(org, repo):
return "`#{{issue}} <https://github.com/{org}/{repo}/issues/{{issue}}>`_".format(
org=org, repo=repo
)
def _get_towncrier_template():
return os.path.join(os.path.dirname(__file__), "towncrier-template.rst")
@contextlib.contextmanager
def _preserve_file(path):
if not os.path.exists(path):
try:
yield
finally:
os.unlink(path)
else:
save_path = path + ".save"
assert not os.path.exists(save_path)
try:
shutil.copy2(path, save_path)
yield
finally:
shutil.copy2(save_path, path)
os.unlink(save_path)
@contextlib.contextmanager
def _prepare_pyproject_toml(addon_dir, org, repo):
"""Inject towncrier options in pyproject.toml"""
pyproject_path = os.path.join(addon_dir, "pyproject.toml")
with _preserve_file(pyproject_path):
pyproject = {}
if os.path.exists(pyproject_path):
with open(pyproject_path) as f:
pyproject = toml.load(f)
if "tool" not in pyproject:
pyproject["tool"] = {}
pyproject["tool"]["towncrier"] = {
"template": _get_towncrier_template(),
"underlines": ["~"],
"title_format": "{version} ({project_date})",
"issue_format": _make_issue_format(org, repo),
"directory": "readme/newsfragments",
"filename": "readme/HISTORY.rst",
}
with open(pyproject_path, "w") as f:
toml.dump(pyproject, f)
yield
@click.command(
help=(
"Generate readme/HISTORY.rst from towncrier newsfragments "
"stored in readme/newfragments/. This script is meant to be run "
"before oca-gen-addon-readme. See https://pypi.org/project/towncrier/ "
"for more information and the naming and format of newfragment files."
)
)
@click.option(
"--addon-dir",
"addon_dirs",
type=click.Path(dir_okay=True, file_okay=False, exists=True),
multiple=True,
help="Directory where addon manifest is located. This option " "may be repeated.",
)
@click.option("--version")
@click.option("--date")
@click.option(
"--org", default="OCA", help="GitHub organization name.", show_default=True
)
@click.option("--repo", required=True, help="GitHub repository name.")
@click.option(
"--commit/--no-commit",
help="git commit changes, if any (a git add is done in any case).",
)
def oca_towncrier(addon_dirs, version, date, org, repo, commit):
if not date:
date = datetime.date.today().isoformat()
paths = []
for addon_dir in addon_dirs:
news_dir = os.path.join(addon_dir, "readme", "newsfragments")
if not os.path.isdir(news_dir):
continue
if not any(not f.startswith(".") for f in os.listdir(news_dir)):
continue
addon_version = version or read_manifest(addon_dir)["version"]
with _prepare_pyproject_toml(addon_dir, org, repo):
subprocess.call(
[
sys.executable,
"-m",
"towncrier",
"--version",
addon_version,
"--date",
date,
"--yes",
],
cwd=addon_dir,
)
paths.append(news_dir)
paths.append(os.path.join(addon_dir, "readme", "HISTORY.rst"))
if commit:
commit_if_needed(paths, message="[UPD] changelog", add=False)
if __name__ == "__main__":
oca_towncrier()