Skip to content

Commit d746b9a

Browse files
committed
feat: rebase branching pattern on develop
1 parent d47633a commit d746b9a

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

scripts/update-demo.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
import typer
88
from cookiecutter.utils import work_in
99

10+
from util import is_ancestor
11+
from util import get_current_branch
12+
from util import get_current_commit
1013
from util import get_demo_name
14+
from util import get_last_cruft_update_commit
1115
from util import git
1216
from util import FolderOption
1317
from util import REPO_FOLDER
@@ -27,13 +31,28 @@ def update_demo(
2731
) -> None:
2832
"""Runs precommit in a generated project and matches the template to the results."""
2933
try:
30-
develop_branch: str = os.getenv("COOKIECUTTER_ROBUST_PYTHON_DEVELOP_BRANCH", "develop")
3134
demo_name: str = get_demo_name(add_rust_extension=add_rust_extension)
3235
demo_path: Path = demos_cache_folder / demo_name
36+
develop_branch: str = os.getenv("COOKIECUTTER_ROBUST_PYTHON_DEVELOP_BRANCH", "develop")
37+
38+
current_branch: str = get_current_branch()
39+
current_commit: str = get_current_commit()
40+
41+
_validate_is_feature_branch(branch=current_branch)
42+
3343
typer.secho(f"Updating demo project at {demo_path=}.", fg="yellow")
3444
with work_in(demo_path):
3545
require_clean_and_up_to_date_repo()
3646
git("checkout", develop_branch)
47+
48+
last_update_commit: str = get_last_cruft_update_commit(demo_path=demo_path)
49+
if not is_ancestor(last_update_commit, current_commit):
50+
raise ValueError(
51+
f"The last update commit '{last_update_commit}' is not an ancestor of the current commit "
52+
f"'{current_commit}'."
53+
)
54+
55+
git("checkout", "-b", current_branch)
3756
uv("python", "pin", min_python_version)
3857
uv("python", "install", min_python_version)
3958
cruft.update(
@@ -56,5 +75,11 @@ def update_demo(
5675
sys.exit(1)
5776

5877

78+
def _validate_is_feature_branch(branch: str) -> None:
79+
"""Validates that the cookiecutter has a feature branch checked out."""
80+
if not branch.startswith("feature/"):
81+
raise ValueError(f"Received branch '{branch}' is not a feature branch.")
82+
83+
5984
if __name__ == '__main__':
6085
cli()

scripts/util.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Module containing utility functions used throughout cookiecutter_robust_python scripts."""
2+
import json
23
import os
34
import shutil
45
import stat
@@ -17,6 +18,8 @@
1718
import cruft
1819
import typer
1920
from cookiecutter.utils import work_in
21+
from cruft._commands.utils.cruft import get_cruft_file
22+
from cruft._commands.utils.cruft import json_dumps
2023
from dotenv import load_dotenv
2124
from typer.models import OptionInfo
2225

@@ -106,7 +109,34 @@ def is_branch_synced_with_remote(branch: str) -> bool:
106109

107110
def is_ancestor(ancestor: str, descendent: str) -> bool:
108111
"""Checks if the branch is synced with its remote."""
109-
return git("merge-base", "--is-ancestor", ancestor, descendent).returncode == 0
112+
return git("merge-base", "--is-ancestor", ancestor, descendent, ignore_error=True) is not None
113+
114+
115+
def get_current_branch() -> str:
116+
"""Returns the current branch name."""
117+
return git("branch", "--show-current").stdout.strip()
118+
119+
120+
def get_current_commit() -> str:
121+
"""Returns the current commit reference."""
122+
return git("rev-parse", "HEAD").stdout.strip()
123+
124+
125+
def get_last_cruft_update_commit(demo_path: Path) -> str:
126+
"""Returns the commit id for the last time cruft update was ran."""
127+
existing_cruft_config: dict[str, Any] = _read_cruft_file(demo_path)
128+
last_cookiecutter_commit: Optional[str] = existing_cruft_config.get("commit", None)
129+
if last_cookiecutter_commit is None:
130+
raise ValueError("Could not find last commit id used to generate demo.")
131+
return last_cookiecutter_commit
132+
133+
134+
def _read_cruft_file(project_path: Path) -> dict[str, Any]:
135+
"""Reads the cruft file for the project path provided and returns the results."""
136+
cruft_path: Path = get_cruft_file(project_dir_path=project_path)
137+
cruft_text: str = cruft_path.read_text()
138+
cruft_config: dict[str, Any] = json.loads(cruft_text)
139+
return cruft_config
110140

111141

112142
@contextmanager

0 commit comments

Comments
 (0)