diff --git a/repo_cloner/lib/detector.py b/repo_cloner/lib/detector.py index cf810dd..55f0ce0 100644 --- a/repo_cloner/lib/detector.py +++ b/repo_cloner/lib/detector.py @@ -3,6 +3,7 @@ from pathlib import Path import logging import json from typing import Callable +from datetime import datetime log = logging.getLogger("rc.detector") @@ -38,7 +39,8 @@ class DetectedCommit: @property def date(self) -> int: - return self._date + dt = datetime.fromtimestamp(self._date) + return dt.strftime("%d-%m-%Y, %H:%M:%S") @property def is_tag(self) -> bool: @@ -69,6 +71,7 @@ class Detector: _repo: RepoTool = None _repo_path: Path = None _detector_dir: Path = None + _detector_sum: Path = None _executed: DiskStoredList = None _branches: DiskStoredRefs = None _tags: DiskStoredRefs = None @@ -79,6 +82,7 @@ class Detector: self._repo_path = Path(repo_path) self._repo = RepoTool(repo_path) self._detector_dir = Path(cache_dir).joinpath("detector") + self._detector_sum = Path(cache_dir).joinpath("detectorSum") if not self._detector_dir.exists(): log.debug(f"Creating detector dir") self._detector_dir.mkdir() @@ -146,6 +150,22 @@ class Detector: for tag, commit in self._repo.list_tags().items(): self._tags.update(tag, commit) + """ + returns true if detector run needs to be done + """ + + def check_fingerprint(self) -> bool: + log.info(f"Checking repo-detector fingerprint") + if not self._detector_sum.exists(): + log.debug(f"Fingerprint file does not exist - run needed") + return True + old_fingerprint = self._detector_sum.read_text().strip() + return not old_fingerprint == self._repo.repo_fingerprint + + def persist_fingerprint(self): + log.debug(f"Persisting detector fingerprint") + self._detector_sum.write_text(str(self._repo.repo_fingerprint)) + def run(self, callback: Callable[[DetectedCommit], None]) -> int: log.info(f"Running commit detector") new_branches = self._repo.list_branches() @@ -207,4 +227,5 @@ class Detector: env = DetectedCommit(env) executed_count += 1 callback(env) + self.persist_fingerprint() return executed_count diff --git a/tests/lib/test_detector.py b/tests/lib/test_detector.py index ca05d20..df2e6df 100644 --- a/tests/lib/test_detector.py +++ b/tests/lib/test_detector.py @@ -2,7 +2,7 @@ import logging from repo_cloner.lib import Detector, DetectedCommit import pytest -from unittest.mock import patch, MagicMock +from unittest.mock import patch, MagicMock, PropertyMock from git import Actor from cloner_test_fixtures import cloner_dir_struct from collections import namedtuple @@ -211,6 +211,45 @@ def test_initialize_caches(tmp_path): assert dict(json.loads(cache_dir.joinpath("tags").read_text())) == tags +def test_check_fingerprint(tmp_path): + mocks = { + 'repo_fingerprint': PropertyMock(return_value = "FingerPrint"), + } + + repo = tmp_path.joinpath("repo.git") + cache_dir = tmp_path.joinpath("cache") + cache_dir.mkdir() + fp_file = cache_dir.joinpath("detectorSum") + + with patch.multiple("repo_cloner.lib.RepoTool", **mocks): + det = Detector(repo, cache_dir, "Mocked") + # file does not exist + assert det.check_fingerprint() + + fp_file.touch() + assert det.check_fingerprint() + + fp_file.write_text("FingerPrint") + + assert not det.check_fingerprint() + + +def test_persist_fingerprint(tmp_path): + mocks = { + 'repo_fingerprint': PropertyMock(return_value = "FingerPrint"), + } + + repo = tmp_path.joinpath("repo.git") + cache_dir = tmp_path.joinpath("cache") + cache_dir.mkdir() + fp_file = cache_dir.joinpath("detectorSum") + + with patch.multiple("repo_cloner.lib.RepoTool", **mocks): + det = Detector(repo, cache_dir, "Mocked") + det.persist_fingerprint() + assert fp_file.read_text().strip() == "FingerPrint" + + def test_run(tmp_path, caplog): stamp = 1659533160 executed = [] @@ -298,9 +337,10 @@ def test_run(tmp_path, caplog): for commit in commits_new] mocks = { - 'list_commits': MagicMock(return_value = commits_named_new), - 'list_branches': MagicMock(return_value = branches_new), - 'list_tags': MagicMock(return_value = tags_new), + 'list_commits': MagicMock(return_value = commits_named_new), + 'list_branches': MagicMock(return_value = branches_new), + 'list_tags': MagicMock(return_value = tags_new), + 'repo_fingerprint': PropertyMock(return_value = "some-fingerprint"), } repo = tmp_path.joinpath("repo.git")