Skip to content

Commit

Permalink
fix: Ensure back-sync does not sync the forward-sync commits. Also su…
Browse files Browse the repository at this point in the history
…pport multiple user commits in one server cycle
  • Loading branch information
nickderobertis committed Aug 14, 2022
1 parent 5f773ce commit f4242a0
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 19 deletions.
44 changes: 44 additions & 0 deletions flexlate_dev/ext_flexlate.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
from pathlib import Path
from typing import List

from flexlate.config_manager import ConfigManager
from flexlate.exc import CannotParseCommitMessageFlexlateTransaction
from flexlate.ext_git import get_commits_between_two_commits
from flexlate.transactions.transaction import (
FlexlateTransaction,
_is_flexlate_merge_commit,
)
from git import Commit, Repo
from pydantic import BaseModel


def get_render_relative_root_in_template_from_project_path(project_path: Path) -> Path:
Expand All @@ -12,3 +21,38 @@ def get_render_relative_root_in_template_from_project_path(project_path: Path) -
)
ts = config.template_sources[0]
return ts.render_relative_root_in_template


def get_non_flexlate_commits_between_commits(
repo: Repo,
start: Commit,
end: Commit,
merged_branch_name: str,
template_branch_name: str,
) -> List[Commit]:
between_commits = get_commits_between_two_commits(repo, start, end)
non_flexlate_commits: List[Commit] = []
for commit in between_commits:
if _is_flexlate_merge_commit(commit, merged_branch_name, template_branch_name):
continue
try:
FlexlateTransaction.parse_commit_message(commit.message)
except CannotParseCommitMessageFlexlateTransaction:
non_flexlate_commits.append(commit)
return non_flexlate_commits


class FlexlateBranchNames(BaseModel):
merged_branch_name: str
template_branch_name: str


def get_flexlate_branch_names_from_project_path(
project_path: Path,
) -> FlexlateBranchNames:
config_manager = ConfigManager()
config = config_manager.load_project_config(project_path)
return FlexlateBranchNames(
merged_branch_name=config.merged_branch_name,
template_branch_name=config.template_branch_name,
)
37 changes: 36 additions & 1 deletion flexlate_dev/gitutils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,41 @@
from git import Repo
import contextlib
from typing import Iterator, List

from git import Commit, Repo
from pydantic import BaseModel


def stage_and_commit_all(repo: Repo, commit_message: str):
repo.git.add("-A")
repo.git.commit("-m", commit_message)


def create_branch_from_commits_get_new_shas(
repo: Repo, branch_name: str, base_commit: Commit, commits: List[Commit]
) -> List[str]:
repo.git.checkout(base_commit, b=branch_name)
new_shas: List[str] = []
for commit in commits:
repo.git.cherry_pick(commit.hexsha)
new_shas.append(repo.head.commit.hexsha)
return new_shas


class BranchInfo(BaseModel):
name: str
commit_shas: List[str]


@contextlib.contextmanager
def temporary_branch_from_commits(
repo: Repo, base_commit: Commit, commits: List[Commit]
) -> Iterator[BranchInfo]:
current_branch = repo.active_branch.name
branch_name = "-".join(["temp", *[commit.hexsha for commit in commits]])
new_shas = create_branch_from_commits_get_new_shas(
repo, branch_name, base_commit, commits
)
repo.git.checkout(current_branch)
yield BranchInfo(name=branch_name, commit_shas=new_shas)
# Delete the created branch
repo.git.branch(branch_name, D=True)
61 changes: 43 additions & 18 deletions flexlate_dev/server/back_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@

from flexlate_dev.dirutils import change_directory_to
from flexlate_dev.ext_flexlate import (
get_flexlate_branch_names_from_project_path,
get_non_flexlate_commits_between_commits,
get_render_relative_root_in_template_from_project_path,
)
from flexlate_dev.ext_threading import PropagatingThread
from flexlate_dev.gitutils import stage_and_commit_all
from flexlate_dev.gitutils import stage_and_commit_all, temporary_branch_from_commits
from flexlate_dev.logger import log
from flexlate_dev.server.sync import SyncServerManager, pause_sync
from flexlate_dev.styles import INFO_STYLE, print_styled
Expand Down Expand Up @@ -166,6 +168,9 @@ def __init__(
self.project_folder
)
)
self.branch_names = get_flexlate_branch_names_from_project_path(
self.project_folder
)

def start(self):
if self.thread is not None:
Expand All @@ -186,13 +191,14 @@ def start_sync(self):
if self.last_commit == new_commit:
self._sleep()
continue
self.sync(new_commit)
self.sync()
self.last_commit = new_commit
self._sleep()

def sync(self, new_commit: Optional[str] = None):
def sync(self):
self.is_syncing = True
try:
self._sync(new_commit)
self._sync()
finally:
self.is_syncing = False

Expand All @@ -201,21 +207,40 @@ def _sleep(self):
time.sleep(self.check_interval_seconds)
self.is_sleeping = False

def _sync(self, new_commit: Optional[str] = None):
new_commit = new_commit or get_last_commit_sha(self.project_repo)
print_styled(f"Back-syncing to commit {new_commit}", INFO_STYLE)
def _sync(self):
last_commit = self.project_repo.commit(self.last_commit)
new_commit = self.project_repo.commit(get_last_commit_sha(self.project_repo))
new_commits = get_non_flexlate_commits_between_commits(
self.project_repo,
last_commit,
new_commit,
self.branch_names.merged_branch_name,
self.branch_names.template_branch_name,
)
if not new_commits:
log.debug("Skipping back-sync as there are no non-flexlate commits")
return
print_styled(
f"Back-syncing commits: {[f'{commit.hexsha}: {commit.message}' for commit in new_commits]}",
INFO_STYLE,
)
with pause_sync(self.sync_manager):
apply_diff_between_commits_to_separate_project(
self.project_repo,
self.last_commit,
new_commit,
self.template_output_path,
)
self.last_commit = new_commit
if self.auto_commit:
commit_in_one_repo_with_another_repo_commit_message(
self.project_repo, self.template_repo, new_commit
)
with temporary_branch_from_commits(
self.project_repo, last_commit, new_commits
) as branch_info:
last_commit_sha = self.last_commit
for new_commit_sha in branch_info.commit_shas:
apply_diff_between_commits_to_separate_project(
self.project_repo,
last_commit_sha,
new_commit_sha,
self.template_output_path,
)
if self.auto_commit:
commit_in_one_repo_with_another_repo_commit_message(
self.project_repo, self.template_repo, new_commit_sha
)
last_commit_sha = new_commit_sha

def __enter__(self) -> "BackSyncServer":
self.start()
Expand Down

0 comments on commit f4242a0

Please sign in to comment.