Skip to content

Commit

Permalink
Move bumpversion cfg into github template
Browse files Browse the repository at this point in the history
  • Loading branch information
mdellweg committed Nov 19, 2024
1 parent c4460b7 commit de50fc9
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 98 deletions.
79 changes: 23 additions & 56 deletions plugin-template
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import os
import pprint
import shlex
import shutil
import stat
import subprocess
import sys
import textwrap
Expand Down Expand Up @@ -80,6 +79,7 @@ DEFAULT_SETTINGS = {

DEPRECATED_FILES = {
"github": [
".bumpversion.cfg",
".ci/assets/bindings/.gitkeep",
".ci/scripts/changelog.py",
".ci/scripts/calc_deps_lowerbounds.py",
Expand Down Expand Up @@ -308,16 +308,13 @@ def main():
return 2

if args.latest_release_branch:
write_new_config = True
config["latest_release_branch"] = str(args.latest_release_branch)
write_new_config = True

# Config key is used by the template_config.yml.j2 template to dump
# the config. (note: uses .copy() to avoid a self reference)
config["config"] = config.copy()

config["current_version"] = utils.current_version(plugin_root_dir)
config["is_pulpdocs_member"] = config["plugin_name"] in utils.get_pulpdocs_members()

sections = [
section
for section in ["generate_config", "bootstrap", "github", "docs", "test"]
Expand Down Expand Up @@ -377,15 +374,11 @@ def append_releasing_to_manifest(plugin_root):
manifest_file.write_text(manifest_text + "exclude releasing.md\n")


def to_nice_yaml(data):
"""Implement a filter for Jinja 2 templates to render human readable YAML."""
return yaml.dump(data, indent=2, allow_unicode=True, default_flow_style=False)


def write_template_section(config, name, plugin_root_dir, verbose=False):
"""
Template or copy all files for the section.
"""
plugin_root_path = Path(plugin_root_dir)
section_template_dir = "templates/{name}".format(name=name)
env = Environment(
loader=FileSystemLoader(
Expand All @@ -402,7 +395,7 @@ def write_template_section(config, name, plugin_root_dir, verbose=False):
env.filters["caps"] = utils.to_caps
env.filters["dash"] = utils.to_dash
env.filters["snake"] = utils.to_snake
env.filters["to_yaml"] = to_nice_yaml
env.filters["to_yaml"] = utils.to_nice_yaml
env.filters["shquote"] = shlex.quote

files_templated = 0
Expand All @@ -413,22 +406,15 @@ def write_template_section(config, name, plugin_root_dir, verbose=False):
except Exception:
gitref = "unknown"

setup_py = os.path.exists(os.path.join(plugin_root_dir, "setup.py"))
ci_update_branches = [config["plugin_default_branch"]]
latest_release_branch = config["latest_release_branch"]
if latest_release_branch is not None:
if latest_release_branch not in config["supported_release_branches"]:
ci_update_branches.append(latest_release_branch)
ci_update_branches.extend(config["supported_release_branches"])
ci_update_hour = sum((ord(c) for c in config["plugin_app_label"])) % 24

template_vars = {
"section": name,
"gitref": gitref,
"setup_py": setup_py,
"ci_update_branches": ci_update_branches,
"setup_py": (plugin_root_path / "setup.py").exists(),
"ci_update_branches": utils.ci_update_branches(config),
"python_version": "3.11",
"ci_update_hour": ci_update_hour,
"ci_update_hour": sum((ord(c) for c in config["plugin_app_label"])) % 24,
"current_version": utils.current_version(plugin_root_path),
"is_pulpdocs_member": config["plugin_name"] in utils.get_pulpdocs_members(),
**config,
}

Expand All @@ -450,12 +436,20 @@ def write_template_section(config, name, plugin_root_dir, verbose=False):
if relative_path.endswith(".j2"):
template = env.get_template(relative_path)
destination = destination_relative_path[: -len(".j2")]
write_template_to_file(
template,
plugin_root_dir,
destination,
template_vars,
)
if destination.startswith("pyproject.toml."):
utils.merge_toml(
template,
plugin_root_path,
destination,
template_vars,
)
else:
utils.template_to_file(
template,
plugin_root_path,
destination,
template_vars,
)
files_templated += 1
if verbose:
print(f"Templated file: {relative_path}")
Expand Down Expand Up @@ -487,33 +481,6 @@ def generate_relative_path_set(root_dir):
return applicable_paths


def write_template_to_file(template, plugin_root_dir, relative_path, config):
"""
Render template with values from the config and write it to the target plugin directory.
"""

destination_path = os.path.normpath(os.path.join(plugin_root_dir, relative_path))
data = template.render(**config)
with open(destination_path, "w") as fd_out:
fd_out.write(data)
fd_out.write("\n")

if destination_path.endswith(".sh") or destination_path.endswith(".py"):
mode = (
stat.S_IRUSR
| stat.S_IWUSR
| stat.S_IXUSR
| stat.S_IRGRP
| stat.S_IWGRP
| stat.S_IXGRP
| stat.S_IROTH
| stat.S_IXOTH
)
else:
mode = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IROTH
os.chmod(destination_path, mode)


def generate_config(plugin_name, plugin_app_label):
"""
Generates a default config for a plugin
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ jinja2
pyyaml
requests~=2.32.3
requests_cache
tomlkit
20 changes: 0 additions & 20 deletions templates/bootstrap/.bumpversion.cfg.j2

This file was deleted.

2 changes: 1 addition & 1 deletion templates/bootstrap/plugin_name/app/__init__.py.j2
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ class {{ plugin_name | camel }}PluginAppConfig(PulpPluginAppConfig):

name = "{{ plugin_name | snake }}.app"
label = "{{ plugin_app_label }}"
version = "0.1.0a1.dev"
version = "{{ current_version }}"
python_package_name = "{{ plugin_name }}"
domain_compatible = True
2 changes: 1 addition & 1 deletion templates/bootstrap/setup.py.j2
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ with open("requirements.txt") as requirements:

setup(
name="{{ plugin_name | dash }}",
version="0.1.0a1.dev",
version="{{ current_version }}",
description="{{ plugin_name | dash }} plugin for the Pulp Project",
long_description="{{ plugin_name | dash }} plugin for the Pulp Project",
long_description_content_type="text/markdown",
Expand Down
42 changes: 42 additions & 0 deletions templates/github/pyproject.toml.tool.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
[tool.bumpversion]
# This section is managed by the plugin template. Do not edit manually.

current_version = "{{ current_version }}"
commit = false
tag = false
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)(\\.(?P<release>[a-z]+))?"
serialize = [
"{major}.{minor}.{patch}.{release}",
"{major}.{minor}.{patch}",
]

[tool.bumpversion.parts.release]
# This section is managed by the plugin template. Do not edit manually.

optional_value = "prod"
values = [
"dev",
"prod",
]
{%- for plugin in plugins %}

[[tool.bumpversion.files]]
# This section is managed by the plugin template. Do not edit manually.

filename = "./{{ plugin.name }}/app/{% if plugin.name == "pulpcore" %}apps{% else %}__init__{% endif %}.py"
search = "version = \"{current_version}\""
replace = "version = \"{new_version}\""
{%- endfor %}
{%- if setup_py %}

[[tool.bumpversion.files]]
filename = "./setup.py"
{%- else %}

[[tool.bumpversion.files]]
# This section is managed by the plugin template. Do not edit manually.

filename = "./pyproject.toml"
search = "version = \"{current_version}\""
replace = "version = \"{new_version}\""
{%- endif %}
4 changes: 1 addition & 3 deletions test_requirements.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
-r requirements.txt
black
check-manifest
flake8
jinja2
mock
git+https://github.com/pulp/pulp-smash.git#egg=pulp-smash
pytest
pyyaml
requests_cache
100 changes: 83 additions & 17 deletions utils.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,14 @@
from datetime import timedelta
import itertools
import pathlib
import re
import requests_cache
import stat
import tomlkit
import tomllib
import yaml


def current_version(plugin_root_dir):
plugin_root_dir = pathlib.Path(plugin_root_dir)
try:
path = plugin_root_dir / "pyproject.toml"
pyproject_toml = tomllib.loads(path.read_text())
current_version = pyproject_toml["project"]["version"]
except Exception:
try:
path = plugin_root_dir / ".bumpversion.cfg"
for line in path.read_text().splitlines():
if line.startswith("current_version = "):
current_version = line[18:].strip()
break
except Exception:
current_version = "0.1.0a1.dev"
return current_version
# Jinja tests and filters


def is_valid(name):
Expand Down Expand Up @@ -64,6 +50,41 @@ def to_snake(name):
return name.replace("-", "_")


def to_nice_yaml(data):
"""Implement a filter for Jinja 2 templates to render human readable YAML."""
return yaml.dump(data, indent=2, allow_unicode=True, default_flow_style=False)


# Information gathering


def ci_update_branches(config):
release_branches = set()
release_branches.add(config["latest_release_branch"])
release_branches.update(config["supported_release_branches"])

return [config["plugin_default_branch"]] + sorted(
[branch for branch in release_branches if branch is not None]
)


def current_version(plugin_root_path):
try:
path = plugin_root_path / "pyproject.toml"
pyproject_toml = tomllib.loads(path.read_text())
current_version = pyproject_toml["project"]["version"]
except Exception:
try:
path = plugin_root_path / ".bumpversion.cfg"
for line in path.read_text().splitlines():
if line.startswith("current_version = "):
current_version = line[18:].strip()
break
except Exception:
current_version = "0.0.0.dev"
return current_version


def get_pulpdocs_members() -> list[str]:
"""
Get repositories which are members of the Pulp managed documentation.
Expand All @@ -86,3 +107,48 @@ def get_pulpdocs_members() -> list[str]:
for repo in itertools.chain(*repolist["repos"].values())
if "subpackage_of" not in repo
]


# Utilities for templating


def template_to_file(template, plugin_root_path, relative_path, template_vars):
"""
Render template with values from the config and write it to the target plugin directory.
"""

destination_path = plugin_root_path / relative_path
data = template.render(**template_vars)
destination_path.write_text(data + "\n")

if destination_path.suffix in [".sh", ".py"]:
mode = (
stat.S_IRUSR
| stat.S_IWUSR
| stat.S_IXUSR
| stat.S_IRGRP
| stat.S_IWGRP
| stat.S_IXGRP
| stat.S_IROTH
| stat.S_IXOTH
)
else:
mode = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IROTH
destination_path.chmod(mode)


def merge_toml(template, plugin_root_path, relative_path, template_vars):
"""
Template a file of the form 'basename.toml.merge_key' and combine its content beneath
'merge_key' with the actual 'basename.toml' file.
"""
basename, merge_key = relative_path.split(".toml.", maxsplit=1)
data = tomlkit.loads(template.render(**template_vars))
if merge_key in data:
path = plugin_root_path / f"{basename}.toml"
old_toml = tomlkit.load(path.open())
if merge_key not in old_toml:
old_toml[merge_key] = data[merge_key]
else:
old_toml[merge_key].update(data[merge_key])
tomlkit.dump(old_toml, path.open("w"))

0 comments on commit de50fc9

Please sign in to comment.