|
10 | 10 |
|
11 | 11 | import sys |
12 | 12 | from pathlib import Path |
| 13 | +from subprocess import CompletedProcess |
13 | 14 | from typing import Annotated |
| 15 | +from typing import Optional |
14 | 16 |
|
15 | 17 | import cruft |
16 | 18 | import typer |
17 | 19 | from cookiecutter.utils import work_in |
18 | 20 |
|
| 21 | +from scripts.util import TEMPLATE |
| 22 | +from util import DEMO |
19 | 23 | from util import is_ancestor |
20 | 24 | from util import get_current_branch |
21 | 25 | from util import get_current_commit |
@@ -46,9 +50,10 @@ def update_demo( |
46 | 50 | current_branch: str = get_current_branch() |
47 | 51 | template_commit: str = get_current_commit() |
48 | 52 |
|
49 | | - _validate_is_feature_branch(branch=current_branch) |
50 | | - _set_demo_to_clean_develop(demo_path=demo_path) |
51 | | - last_update_commit: str = _get_last_demo_develop_cruft_update(demo_path=demo_path) |
| 53 | + _validate_template_main_not_checked_out(branch=current_branch) |
| 54 | + require_clean_and_up_to_date_repo(demo_path=demo_path) |
| 55 | + _checkout_demo_develop_or_existing_branch(demo_path=demo_path, branch=current_branch) |
| 56 | + last_update_commit: str = get_last_cruft_update_commit(demo_path=demo_path) |
52 | 57 |
|
53 | 58 | if not is_ancestor(last_update_commit, template_commit): |
54 | 59 | raise ValueError( |
@@ -83,23 +88,53 @@ def update_demo( |
83 | 88 | sys.exit(1) |
84 | 89 |
|
85 | 90 |
|
86 | | -def _set_demo_to_clean_develop(demo_path: Path) -> None: |
87 | | - """Checks out the demo development branch and validates it is up to date.""" |
| 91 | +def _checkout_demo_develop_or_existing_branch(demo_path: Path, branch: str) -> None: |
| 92 | + """Checkout either develop or an existing demo branch.""" |
88 | 93 | with work_in(demo_path): |
89 | | - require_clean_and_up_to_date_repo() |
| 94 | + if __has_existing_local_demo_branch(demo_path=demo_path, branch=branch): |
| 95 | + typer.secho(f"Local demo found, updating demo from base {branch}") |
| 96 | + git("checkout", branch) |
| 97 | + return |
| 98 | + |
| 99 | + if __has_existing_remote_demo_branch(demo_path=demo_path, branch=branch): |
| 100 | + remote_branch: str = f"{DEMO.remote}/{branch}" |
| 101 | + typer.secho(f"Remote demo found, updating demo from base {remote_branch}") |
| 102 | + git("checkout", "-b", branch, remote_branch) |
| 103 | + return |
| 104 | + |
90 | 105 | git("checkout", "develop") |
91 | 106 |
|
92 | 107 |
|
93 | | -def _get_last_demo_develop_cruft_update(demo_path: Path) -> str: |
94 | | - """Gets the last cruft update commit for the demo project's develop branch.""" |
95 | | - last_update_commit: str = get_last_cruft_update_commit(demo_path=demo_path) |
96 | | - return last_update_commit |
| 108 | +def __has_existing_local_demo_branch(demo_path: Path, branch: str) -> bool: |
| 109 | + """Returns whether a local branch has been made for the given branch.""" |
| 110 | + with work_in(demo_path): |
| 111 | + local_result: Optional[CompletedProcess] = git("branch", "--list", branch, text=True) |
| 112 | + return local_result is not None and branch in local_result.stdout |
| 113 | + |
| 114 | + |
| 115 | +def __has_existing_remote_demo_branch(demo_path: Path, branch: str) -> bool: |
| 116 | + """Returns whether a remote branch has been made for the given branch.""" |
| 117 | + with work_in(demo_path): |
| 118 | + remote_result: Optional[CompletedProcess] = git("ls-remote", DEMO.remote, branch, text=True) |
| 119 | + return remote_result is not None and branch in remote_result.stdout |
| 120 | + |
| 121 | + |
| 122 | +def _set_demo_to_clean_branch(demo_path: Path, branch: str) -> None: |
| 123 | + """Checks out the demo branch and validates it is up to date.""" |
| 124 | + with work_in(demo_path): |
| 125 | + git("checkout", "develop") |
| 126 | + |
97 | 127 |
|
| 128 | +def _validate_template_main_not_checked_out(branch: str) -> None: |
| 129 | + """Validates that the cookiecutter isn't currently on main. |
98 | 130 |
|
99 | | -def _validate_is_feature_branch(branch: str) -> None: |
100 | | - """Validates that the cookiecutter has a feature branch checked out.""" |
101 | | - if not branch.startswith("feature/"): |
102 | | - raise ValueError(f"Received branch '{branch}' is not a feature branch.") |
| 131 | + We allow direct develop commits (although avoid it usually), but never direct main. This may change later if the |
| 132 | + template moves to a trunk based structure, but for now options are being kept open due to the possibility of a |
| 133 | + package release handling demo creation one day. |
| 134 | + """ |
| 135 | + main_like_names: list[str] = ["main", "master"] |
| 136 | + if branch == TEMPLATE.main_branch or branch in main_like_names: |
| 137 | + raise ValueError(f"Updating demos directly to main is not allowed currently.") |
103 | 138 |
|
104 | 139 |
|
105 | 140 | if __name__ == '__main__': |
|
0 commit comments