Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(git): Add
pyff-git
to compare git repo revisions
- Loading branch information
1 parent
69c5410
commit 08e0471
Showing
9 changed files
with
156 additions
and
11 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
"""This module contains code that handles comparing revisions in Git repository""" | ||
|
||
import tempfile | ||
import shutil | ||
import pathlib | ||
from typing import Optional | ||
import git | ||
|
||
|
||
import pyff.directories as pd | ||
import pyff.packages as pp | ||
|
||
|
||
class RevisionsPyfference: # pylint: disable=too-few-public-methods | ||
"""Represents a difference between two revisions""" | ||
|
||
# RevisionsPyfference is basically the same as DirectoryPyfference, so we | ||
# embed DirectoryPyfference and delegate everything to it | ||
def __init__(self, change: pd.DirectoryPyfference) -> None: | ||
self._change: pd.DirectoryPyfference = change | ||
|
||
def __str__(self): | ||
return str(self._change) | ||
|
||
@property | ||
def packages(self) -> Optional[pp.PackagesPyfference]: | ||
"""Return what Python packages differ between revisions""" | ||
return self._change.packages | ||
|
||
|
||
def pyff_git_revision(repository: str, old: str, new: str) -> Optional[RevisionsPyfference]: | ||
"""Compare two revisions in a Git repository""" | ||
with tempfile.TemporaryDirectory() as temporary_wd: | ||
working_directory = pathlib.Path(temporary_wd) | ||
source_dir = working_directory / "source" | ||
old_dir = working_directory / "old" | ||
new_dir = working_directory / "new" | ||
|
||
repo = git.Repo.clone_from(repository, source_dir) | ||
|
||
repo.git.checkout(old) | ||
shutil.copytree(source_dir, old_dir) | ||
|
||
repo.git.checkout(new) | ||
shutil.copytree(source_dir, new_dir) | ||
|
||
change = pd.pyff_directory(old_dir, new_dir) | ||
if change: | ||
return RevisionsPyfference(change) | ||
|
||
return None |
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
colorama==0.3.9 | ||
GitPython==2.1.10 |
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# pylint: disable=missing-docstring, no-self-use, too-few-public-methods | ||
|
||
import os | ||
import pathlib | ||
from unittest.mock import MagicMock, patch | ||
|
||
import pyff.directories as pd | ||
import pyff.repositories as pr | ||
|
||
|
||
class TestRevisionsPyfference: | ||
def test_sanity(self): | ||
directory_change = MagicMock(spec=pd.DirectoryPyfference) | ||
directory_change.__str__.return_value = "le change" | ||
change = pr.RevisionsPyfference(change=directory_change) | ||
|
||
assert str(change) == "le change" | ||
|
||
|
||
class TestPyffGitRevision: | ||
@staticmethod | ||
def _make_fake_clone(fs, revisions): # pylint: disable=invalid-name | ||
def _fake_clone_method(_, directory): | ||
fs.create_dir(directory) | ||
fake_repo = MagicMock() | ||
|
||
def _fake_checkout(revision): | ||
if revision in revisions: | ||
oldcwd = os.getcwd() | ||
os.chdir(directory) | ||
revisions[revision]() | ||
os.chdir(oldcwd) | ||
|
||
fake_repo.git.checkout = _fake_checkout | ||
return fake_repo | ||
|
||
return _fake_clone_method | ||
|
||
def test_difference(self, fs): # pylint: disable=invalid-name | ||
def checkout_old(): | ||
fs.create_file("old_package/__init__.py") | ||
|
||
def checkout_new(): | ||
fs.create_file("package/__init__.py") | ||
|
||
with patch("git.Repo.clone_from") as fake_clone: | ||
|
||
fake_clone.side_effect = self._make_fake_clone( | ||
fs, {"old": checkout_old, "new": checkout_new} | ||
) | ||
change = pr.pyff_git_revision("repo", "old", "new") | ||
assert change is not None | ||
assert pathlib.Path("package") in change.packages.new | ||
|
||
def test_identical(self, fs): # pylint: disable=invalid-name | ||
def checkout_old(): | ||
fs.create_file("package/__init__.py") | ||
|
||
with patch("git.Repo.clone_from") as fake_clone: | ||
fake_clone.side_effect = self._make_fake_clone(fs, {"old": checkout_old}) | ||
change = pr.pyff_git_revision("repo", "old", "new") | ||
assert change is None |