Skip to content

Commit

Permalink
Fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
douglaslassance committed Oct 10, 2024
1 parent ca77adb commit 8f4d8bc
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 64 deletions.
69 changes: 44 additions & 25 deletions gitalong/batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ async def get_files_last_commits(
for filename in filenames:
last_commit = {}

repository = Repository.from_filename(filename)
repository = Repository.from_filename(os.path.dirname(filename))
if not repository:
last_commits.append(last_commit)
continue
Expand Down Expand Up @@ -114,20 +114,24 @@ async def get_commits_branches(commits: List[dict], remote: bool = False) -> Lis
branches_list = []
tasks = []
for commit in commits:
args = ["git", "-C", commit.get("clone", ""), "--remote" if remote else []]
if "sha" not in commit:
branches_list.append([])
continue
args = ["git", "-C", commit.get("clone", ""), "branch"]
if remote:
args += ["--remote"]
args += ["--contains", commit.get("sha", "")]
tasks.append(run_command(args))
results = await asyncio.gather(*tasks)
for result in results:
stdout = result[0]
branches = stdout.decode("utf-8").split("\n")
branches = branches.replace("*", "")
branches = branches.replace(" ", "")
branches = branches.split("\n") if branches else []
branch_names = set()
for branch in branches:
branch_names.add(branch.split("/")[-1])
branches_list.append(list(branch_names))
results = await asyncio.gather(*tasks)
for result in results:
branches = result.split("\n")[0]
branches = branches.replace("*", "")
branches = branches.replace(" ", "")
branches = branches.split("\n") if branches else []
branch_names = set()
for branch in branches:
branch_names.add(branch.split("/")[-1])
branches_list.append(list(branch_names))
return branches_list


Expand Down Expand Up @@ -169,18 +173,34 @@ async def get_commit_changes(commits: List[git.Commit | dict]) -> List[str]:
changes_list.append(commit.get("changes", []))
continue
working_dir = commit.repo.working_dir
args = ["git", "-C", working_dir, "diff", "--numstat", "--no-renames"]
parent = commit.parents[0].hexsha if commit.parents else ""
if parent:
args += [f"{commit.hexsha}^", parent]
if not commit.parents:
# First commit, use git show
args = [
"git",
"-C",
working_dir,
"show",
"--pretty=format:",
"--name-only",
commit.hexsha,
]
else:
args += [commit.hexsha]
args += ["--"]
# Subsequent commits, use git diff-tree
args = [
"git",
"-C",
working_dir,
"diff-tree",
"--no-commit-id",
"--name-only",
"-r",
commit.hexsha,
]
tasks.append(run_command(args))
results = await asyncio.gather(*tasks)
for result in results:
stdout = result[0]
changes = stdout.decode("utf-8").split("\n")
changes = result.split("\n")
changes = [change for change in changes if change]
changes_list.append(changes)
return changes_list

Expand All @@ -207,6 +227,7 @@ async def get_commits_dicts(commits: List[git.Commit | dict]) -> List[dict]:
"changes": changes,
"date": str(commit.committed_datetime),
"author": commit.author.name,
"clone": commit.repo.working_dir,
}
)
return commit_dicts
Expand All @@ -221,9 +242,7 @@ async def claim_files(
Also makes the files writable if the configured is set to affect permissions.
Args:
filename (str):
The file to make writable. Takes a path that's absolute or relative to
the managed repository.
filename (str): The absolute filename to the file to claim.
prune (bool, optional): Prune branches if a fetch is necessary.
Returns:
Expand All @@ -234,7 +253,7 @@ async def claim_files(
for filename in filenames:
last_commits = await get_files_last_commits([filename], prune=prune)
last_commit = last_commits[0]
repository = Repository.from_filename(filename)
repository = Repository.from_filename(os.path.dirname(filename))
config = repository.config if repository else {}
modify_permissions = config.get("modify_permissions")
spread = repository.get_commit_spread(last_commit) if repository else 0
Expand Down
11 changes: 5 additions & 6 deletions gitalong/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,8 @@ def config(ctx, prop): # pylint: disable=missing-function-docstring
"files their permissions changed."
)
)
@click.argument(
"repository",
# help="The path to the repository to update."
)
@click.pass_context
def update(ctx, repository):
def update(ctx):
"""TODO: Improve error handling."""
repository = Repository.from_filename(ctx.obj.get("REPOSITORY", ""))
if not repository:
Expand Down Expand Up @@ -122,7 +118,10 @@ def update(ctx, repository):
"-p",
"--profile",
is_flag=True,
help="Will generate a profile file in the current workin directory.",
help=(
"Will generate a profile file in the current workin directory."
"The file can be open in a profiler like snakeviz."
),
)
@click.pass_context
def status(ctx, filename, profile=False): # pylint: disable=missing-function-docstring
Expand Down
21 changes: 14 additions & 7 deletions gitalong/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@

from git.repo import Repo

# Deliberatedly import the module to avoid circular imports.
from . import batch

from .store import Store
from .enums import CommitSpread
from .stores.git_store import GitStore
Expand Down Expand Up @@ -166,8 +163,8 @@ def from_filename(cls, filename: str) -> Optional["Repository"]:
"""
Args:
filename (str):
The absolute path to the clone or either the relative or
absolute path to one of its files.
Existing absolute path to a file or folder in the managed repository.
That inclused the managed repository itself.
Returns:
Optional[Repository]: The repository or None.
Expand Down Expand Up @@ -433,10 +430,10 @@ def _accumulate_local_only_commits(self, start: git.Commit, local_commits: list)
if self._managed_repository.git.branch("--remotes", "--contains", start.hexsha):
return
# TODO: These call to batch functions are expensive for a single file.
commits = asyncio.run(batch.get_commits_dicts([start]))
commits = asyncio.run(self.batch.get_commits_dicts([start]))
commit = commits[0] if commits else {}
commit.update(self.context_dict)
branches_list = asyncio.run(batch.get_commits_branches([commit]))
branches_list = asyncio.run(self.batch.get_commits_branches([commit]))
branches = branches_list[0] if branches_list else []
commit["branches"] = {"local": branches}
# Maybe we should compare the SHA here.
Expand Down Expand Up @@ -658,3 +655,13 @@ def git(self) -> git.Git:
git.cmd.Git: The Git command line interface for the managed repository.
"""
return self._managed_repository.git

@property
def batch(self):
"""
Returns:
Batch: The batch object for the managed repository.
"""
from . import batch # pylint: disable=import-outside-toplevel

return batch
18 changes: 11 additions & 7 deletions tests/cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@

from gitalong import Repository, CommitSpread, RepositoryNotSetup, cli
from gitalong.functions import is_read_only
from gitalong.batch import claim_files, get_files_last_commits

# Deliberatedly import the module to avoid circular imports.
import gitalong.batch as batch

from .functions import save_image

Expand Down Expand Up @@ -86,14 +88,14 @@ def test_lib(self):
self.assertEqual(1, len(local_only_commits))
self.assertEqual(3, len(local_only_commits[0]["changes"]))

image_path = os.path.join(working_dir, "staged_image_02.jpg")
save_image(image_path)
staged_image_02_path = os.path.join(working_dir, "staged_image_02.jpg")
save_image(staged_image_02_path)
# Simulating the application syncing when saving the file.
self.repository.update_tracked_commits()
# print("POST-SAVE TRACKED COMMITS")
# pprint(self.repository.get_tracked_commits())

self._managed_clone.index.add(image_path)
self._managed_clone.index.add(staged_image_02_path)
self._managed_clone.index.commit(message="Add staged_image_02.jpg")
# Simulating the post-commit hook.
self.repository.update_tracked_commits()
Expand All @@ -108,7 +110,7 @@ def test_lib(self):
# pprint(self.repository.get_tracked_commits())

# We just pushed the changes therefore there should be no missing commit.
last_commits = asyncio.run(get_files_last_commits(["staged_image_02.jpg"]))
last_commits = asyncio.run(batch.get_files_last_commits([staged_image_02_path]))
last_commit = last_commits[0] if last_commits else {}
spread = self.repository.get_commit_spread(last_commit)
self.assertEqual(
Expand All @@ -124,7 +126,7 @@ def test_lib(self):
# pprint(self.repository.get_tracked_commits())

# As a result it should be a commit we do no have locally.
last_commits = asyncio.run(get_files_last_commits(["staged_image_02.jpg"]))
last_commits = asyncio.run(batch.get_files_last_commits([staged_image_02_path]))
last_commit = last_commits[0] if last_commits else {}
spread = self.repository.get_commit_spread(last_commit)
self.assertEqual(CommitSpread.REMOTE_MATCHING_BRANCH, spread)
Expand All @@ -138,7 +140,9 @@ def test_lib(self):

self.repository.update_tracked_commits()

claims = asyncio.run(claim_files([staged_image_01_path, image_path]))
claims = asyncio.run(
batch.claim_files([staged_image_01_path, staged_image_02_path])
)
missing_commit = claims[0]
self.assertEqual(False, bool(missing_commit))
missing_commit = claims[1]
Expand Down
32 changes: 13 additions & 19 deletions tests/test_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
from git.repo import Repo
from gitalong import Repository, RepositoryNotSetup, CommitSpread

from gitalong.batch import claim_files, get_files_last_commits


def test_example():
"""Testing example code featured in README.md."""
Expand Down Expand Up @@ -44,20 +42,14 @@ def test_example():
)

# Creating some files.
open(
os.path.join(project_clone.working_dir, "uncommitted.png"),
"w",
encoding="utf-8",
).close()
open(
os.path.join(project_clone.working_dir, "local.gif"), "w", encoding="utf-8"
).close()
open(
os.path.join(project_clone.working_dir, "remote.jpg"), "w", encoding="utf-8"
).close()
open(
os.path.join(project_clone.working_dir, "untracked.txt"), "w", encoding="utf-8"
).close()
uncomitted = os.path.join(project_clone.working_dir, "uncommitted.png")
local = os.path.join(project_clone.working_dir, "local.gif")
remote = os.path.join(project_clone.working_dir, "remote.jpg")
untracked = os.path.join(project_clone.working_dir, "untracked.txt")
open(uncomitted, "w", encoding="utf-8").close()
open(local, "w", encoding="utf-8").close()
open(remote, "w", encoding="utf-8").close()
open(untracked, "w", encoding="utf-8").close()

# Spreading them across branches.
project_clone.index.add("untracked.txt")
Expand All @@ -74,14 +66,16 @@ def test_example():
repository.update_tracked_commits()

# Update permissions of all files based on track commits. Because
# `modify_permssions` was passed this will update all permissions of tracked files.
# `modify_permissions` was passed this will update all permissions of tracked files.
# Permission updates currently comes at high performance cost and is not
# recommended.
locally_changed_files = repository.locally_changed_files
for filename in repository.files:
repository.update_file_permissions(filename, locally_changed_files)

last_commits = asyncio.run(get_files_last_commits(repository.files))
last_commits = asyncio.run(
repository.batch.get_files_last_commits([uncomitted, local, remote, untracked])
)

# Now we'll get the last commit for our files.
# This could return a dummy commit representing uncommitted changes.
Expand All @@ -106,7 +100,7 @@ def test_example():

# Trying to claim the files.
claims = asyncio.run(
claim_files(["uncommitted.png", "local.gif", "remote.jpg", "untracked.txt"])
repository.batch.claim_files([uncomitted, local, remote, untracked])
)

assert bool(claims[0]) is False
Expand Down

0 comments on commit 8f4d8bc

Please sign in to comment.