Last active
May 8, 2024 03:22
-
-
Save thehappycheese/3733d3420fb0eb30575f5b1fbbd1afe4 to your computer and use it in GitHub Desktop.
A simple python wrapper for git that helps build synthetic repos based on snapshots of some folder
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import annotations | |
import subprocess | |
from pathlib import Path | |
from typing import Optional | |
import os | |
from dataclasses import dataclass | |
from deprecated import deprecated | |
from pandas import Timestamp | |
@dataclass | |
class RepoInstructions: | |
actions: list[Action] | |
@dataclass | |
class Action: | |
pass | |
@dataclass | |
@deprecated(reason="No longer needed") | |
class RawCommand(Action): | |
command: str | |
@dataclass | |
class ChangeAndCommit(Action): | |
pickle_name: str | |
message: str | |
date: Timestamp | |
class GitInit(Action): | |
pass | |
@dataclass | |
class GitRenameBranch(Action): | |
old_name: str | |
new_name: str | |
@dataclass | |
class GitSwitchBranch(Action): | |
branch_name: str | |
create: bool = False | |
class GitSubprocessWrapper: | |
cwd: Path | |
def __init__(self, cwd: Path): | |
self.cwd = cwd | |
def run(self, command: str, environment=None): | |
print(f"Running {command}") | |
result = subprocess.run( | |
command, | |
text=True, | |
capture_output=True, | |
env=environment, | |
cwd=self.cwd, | |
check=False, | |
) | |
if result.returncode != 0: | |
raise Exception(f"Error running {command}: {result.stderr}") | |
print(result.stdout) | |
return result.stdout | |
def has_changes(self): | |
status_output = self.run("git status --porcelain") | |
return bool(status_output.strip()) | |
def commit(self, message: str, commit_date: Optional[Timestamp] = None): | |
environment = {**os.environ} | |
if commit_date is not None: | |
date_str = commit_date.strftime("%Y-%m-%dT%H:%M:%S") | |
environment = { | |
**environment, | |
"GIT_AUTHOR_DATE": date_str, | |
"GIT_COMMITTER_DATE": date_str, | |
} | |
self.run("git add .") | |
if self.has_changes(): | |
date_part = "" | |
if commit_date is not None: | |
author_date = commit_date.strftime("%Y-%m-%dT%H:%M:%S") | |
date_part = f" --date={author_date}" | |
self.run(f'git commit -m "{message}"'+date_part, environment=environment) | |
else: | |
print("No changes detected, skipping commit.") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ... | |
git = GitSubprocessWrapper(output_path) | |
for action in instructions.actions: | |
match action: | |
case GitInit(): | |
git.run("git init") | |
case GitSwitchBranch(branch_name, create): | |
if create: | |
git.run(f"git switch -c {branch_name}") | |
else: | |
git.run(f"git switch {branch_name}") | |
case GitRenameBranch(old_name, new_name): | |
git.run(f"git branch -M {old_name} {new_name}") | |
case ChangeAndCommit(pickle_name, message, date): | |
with (pickle_base_path / pickle_name).open("rb") as f: | |
data:SearchSets = pickle.load(f) | |
dump_data(data, output_path) | |
git.run(f"git add .") | |
git.commit(message, date) | |
case GitMerge(branch_name): | |
git.run(f"git merge {branch_name}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment