Skip to content

Commit 47ad7e6

Browse files
committed
Add manage cookie command and repo sandbox class
1 parent aea89aa commit 47ad7e6

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed

cookie_python/manage.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
from __future__ import annotations
2+
3+
import argparse
4+
import contextlib
5+
import subprocess
6+
import tempfile
7+
from enum import Enum
8+
from functools import cached_property, partial
9+
from pathlib import Path
10+
from types import TracebackType
11+
from typing import Any, Callable, Optional, TypeVar
12+
13+
# import semver
14+
15+
F = TypeVar("F", bound=Callable[[Any, Path], Optional[str]])
16+
A = TypeVar("A", bound=Callable[[str, argparse.Namespace], None])
17+
18+
19+
class RepoSandbox:
20+
def __init__(self, repo: str) -> None:
21+
self._stack = contextlib.ExitStack()
22+
self.repo = repo
23+
self.run: Optional[
24+
Callable[..., subprocess.CompletedProcess[str]]
25+
] = None
26+
27+
@cached_property
28+
def tempdir(self) -> Path:
29+
return Path(
30+
self._stack.enter_context(
31+
tempfile.TemporaryDirectory(suffix=".manage_cookie")
32+
)
33+
)
34+
35+
def setup_repo(self) -> None:
36+
subprocess.run(
37+
["git", "clone", self.repo, "repo"], cwd=self.tempdir, check=True
38+
)
39+
branch = "update-cookie"
40+
clonepath = self.tempdir / "repo"
41+
self.run = partial(subprocess.run, cwd=clonepath, check=True)
42+
if (
43+
self.run(
44+
["git", "ls-remote", "origin", branch],
45+
capture_output=True,
46+
) # type: ignore
47+
.stdout.decode("utf-8")
48+
.strip()
49+
):
50+
print(f'Branch "{branch}" already exists on remote')
51+
return
52+
self.run(["git", "checkout", "-b", branch])
53+
self.run(["git", "reset", "--hard", "origin/main"])
54+
55+
def __enter__(self) -> RepoSandbox:
56+
self.setup_repo()
57+
return self
58+
59+
def __exit__(
60+
self,
61+
exc_type: Optional[type[BaseException]] = None,
62+
exc_val: Optional[BaseException] = None,
63+
exc_tb: Optional[TracebackType] = None,
64+
) -> None:
65+
self._stack.close()
66+
67+
68+
class Action(str, Enum):
69+
UPDATE = "update", "test"
70+
71+
def __new__(cls, value: str, description: str = "") -> Action:
72+
obj = str.__new__(cls, value)
73+
obj._value_ = value
74+
obj.description = description # type: ignore
75+
return obj
76+
77+
78+
class ManageCookie:
79+
def __init__(self) -> None:
80+
self.args = self.parse_args()
81+
print(self.args)
82+
83+
def parse_args(self) -> argparse.Namespace:
84+
ap = argparse.ArgumentParser()
85+
ap.add_argument(
86+
"action",
87+
type=lambda value: Action(str(value)),
88+
choices=list(Action),
89+
)
90+
ap.add_argument("repo", nargs="+", help="Repository URL")
91+
ap.add_argument(
92+
"-p",
93+
"--pretend",
94+
"--dry-run",
95+
dest="dry_run",
96+
action="store_true",
97+
help="Dry run",
98+
)
99+
args = ap.parse_args()
100+
return args
101+
102+
def run(self) -> None:
103+
for repo in self.args.repo:
104+
with RepoSandbox(repo) as rs:
105+
print(f"In the sandbox for {repo}")
106+
print(rs.tempdir)
107+
print(rs)
108+
109+
@staticmethod
110+
def main() -> None:
111+
print("manage cookie main")
112+
mc = ManageCookie()
113+
mc.run()

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ types-PyYAML = "*"
4949

5050
[tool.poetry.scripts]
5151
new-cookie = "cookie_python.new:main"
52+
manage-cookie = "cookie_python.manage:ManageCookie.main"
5253

5354
[tool.poetry-dynamic-versioning]
5455
enable = false

0 commit comments

Comments
 (0)