Skip to content

Commit

Permalink
Merge pull request #432 from acsone/towncrier-sbi
Browse files Browse the repository at this point in the history
[ADD] oca-towncrier
  • Loading branch information
sbidoul committed Mar 28, 2020
2 parents becfd07 + 8e435df commit c7ac274
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 3 deletions.
2 changes: 2 additions & 0 deletions .flake8
@@ -0,0 +1,2 @@
[flake8]
max-line-length = 88
3 changes: 3 additions & 0 deletions setup.py
Expand Up @@ -38,6 +38,8 @@
'polib',
'pygments',
'requests',
'toml>=0.10.0', # for oca-towncrier
'towncrier>=19.2', # for oca-towncrier
'twine',
'wheel',
],
Expand Down Expand Up @@ -67,6 +69,7 @@
'oca-pypi-upload = tools.pypi_upload:cli',
'oca-gen-addon-readme = tools.gen_addon_readme:gen_addon_readme',
'oca-gen-addon-icon = tools.gen_addon_icon:gen_addon_icon',
'oca-towncrier = tools.oca_towncrier:oca_towncrier',
],
},
)
43 changes: 43 additions & 0 deletions tests/test_towncrier.py
@@ -0,0 +1,43 @@
# License AGPLv3 (http://www.gnu.org/licenses/agpl-3.0-standalone.html)
# Copyright (c) 2018 ACSONE SA/NV

import toml

from tools.oca_towncrier import (
_make_issue_format,
_preserve_file,
_prepare_pyproject_toml,
)


def test_make_issue_format():
assert (
_make_issue_format("OCA", "repo")
== "`#{issue} <https://github.com/OCA/repo/issues/{issue}>`_"
)


def test_preserve_file(tmp_path):
p = tmp_path / "dummy"
with _preserve_file(str(p)):
# path does not exist
p.write_text(u"abc")
assert not p.exists()
p.write_text(u"abc")
with _preserve_file(str(p)):
p.write_text(u"xyz")
assert p.read_text() == u"abc"


def test_prepare_pyproject_toml(tmp_path):
with _prepare_pyproject_toml(str(tmp_path), "OCA", "repo"):
with open(str(tmp_path / "pyproject.toml")) as f:
pyproject = toml.load(f)
assert set(pyproject["tool"]["towncrier"].keys()) == {
"template",
"underlines",
"title_format",
"issue_format",
"directory",
"filename",
}
7 changes: 4 additions & 3 deletions tools/gitutils.py
Expand Up @@ -3,9 +3,10 @@
import subprocess


def commit_if_needed(paths, message):
cmd = ['git', 'add'] + paths
subprocess.check_call(cmd)
def commit_if_needed(paths, message, add=True):
if add:
cmd = ['git', 'add'] + paths
subprocess.check_call(cmd)
cmd = ['git', 'diff', '--quiet', '--exit-code', '--cached', '--'] + paths
r = subprocess.call(cmd)
if r != 0:
Expand Down
128 changes: 128 additions & 0 deletions tools/oca_towncrier.py
@@ -0,0 +1,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()
33 changes: 33 additions & 0 deletions tools/towncrier-template.rst
@@ -0,0 +1,33 @@
{% for section, _ in sections.items() %}
{% if section %}{{section}}
{{ '~' * section|length }}

{% endif %}

{% if sections[section] %}
{% for category, val in definitions.items() if category in sections[section]%}
**{{ definitions[category]['name'] }}**

{% if definitions[category]['showcontent'] %}
{% for text, values in sections[section][category].items() %}
- {{ text }} ({{ values|join(', ') }})
{% endfor %}

{% else %}
- {{ sections[section][category]['']|join(', ') }}

{% endif %}
{% if sections[section][category]|length == 0 %}
No significant changes.

{% else %}
{% endif %}

{% endfor %}
{% else %}
No significant changes.


{% endif %}
{% endfor %}

0 comments on commit c7ac274

Please sign in to comment.