From 64980e46acbb822d53596619437fa9f9f4d9512b Mon Sep 17 00:00:00 2001 From: Jon Michael Aanes Date: Sun, 25 Aug 2024 23:39:40 +0200 Subject: [PATCH] Restructure to split sources into own submodule. Preparation for addition of extra sources. --- git_time_tracker/__init__.py | 64 +++-------------------------- git_time_tracker/data.py | 15 +++++++ git_time_tracker/source/__init__.py | 0 git_time_tracker/source/git_repo.py | 56 +++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 58 deletions(-) create mode 100644 git_time_tracker/data.py create mode 100644 git_time_tracker/source/__init__.py create mode 100644 git_time_tracker/source/git_repo.py diff --git a/git_time_tracker/__init__.py b/git_time_tracker/__init__.py index 3f36a80..509b850 100644 --- a/git_time_tracker/__init__.py +++ b/git_time_tracker/__init__.py @@ -26,66 +26,18 @@ And the ([Hamster](https://github.com/projecthamster/hamster)) manual time track """ import argparse -import dataclasses import datetime import logging import sys -import time -from collections.abc import Iterator, Sequence +from collections.abc import Iterator from pathlib import Path -import git +from .data import WorkSample, HIDDEN_LABEL_PREFIX, HIDDEN_LABEL_TOTAL +from .source import git_repo logger = logging.getLogger(__name__) -@dataclasses.dataclass(frozen=True, order=True) -class WorkSample: - registered_at: datetime.datetime - labels: Sequence[str] - - -def determine_default(repo: git.Repo): - try: - repo.commit('main') - return 'main' - except: - return 'master' - - -HIDDEN_LABEL_PREFIX = '__' -HIDDEN_LABEL_TOTAL = HIDDEN_LABEL_PREFIX + 'TOTAL' - - -def determine_project_name(repo: git.Repo) -> str: - remotes = repo.remotes - if len(remotes) > 0: - return remotes.origin.url.removeprefix('git@gitfub.space:') - return Path(repo.working_tree_dir).name - - -def get_samples_from_project(repo: git.Repo) -> Iterator[WorkSample]: - project_name = determine_project_name(repo) - assert project_name is not None - - # TODO: Branch on main or master or default - - repo.commit() - - for commit in repo.iter_commits(determine_default(repo)): - labels = [HIDDEN_LABEL_TOTAL] - labels.append('project:' + project_name) - labels.append('author:' + commit.author.email) - yield WorkSample( - datetime.datetime.fromtimestamp(commit.authored_date, tz=datetime.UTC), - tuple(labels), - ) - yield WorkSample( - datetime.datetime.fromtimestamp(commit.committed_date, tz=datetime.UTC), - tuple(labels), - ) - del labels - DEFAULT_EST_TIME = datetime.timedelta(hours=1) @@ -171,9 +123,10 @@ def generate_report(samples: list[WorkSample], sample_filter = frozenset()) -> I yield '\n' + def parse_arguments(): parser = argparse.ArgumentParser() - parser.add_argument('repositories', action='extend', nargs='+', type=Path) + parser.add_argument('--git-repo', action='extend', nargs='+', type=Path, dest='repositories') parser.add_argument('--filter', action='extend', nargs='+', type=str, dest='sample_filter', default=[]) return parser.parse_args() @@ -185,13 +138,8 @@ def main(): shared_time_stamps: set[WorkSample] = set() for repo_path in args.repositories: - try: - repo = git.Repo(repo_path) - except git.exc.InvalidGitRepositoryError: - logger.warning('Ignoring non-repo %s', repo_path) - continue logger.warning('Visit %s', repo_path) - shared_time_stamps |= set(get_samples_from_project(repo)) + shared_time_stamps |= set(git_repo.iterate_samples_from_git_repository(repo_path)) shared_time_stamps = sorted(shared_time_stamps) diff --git a/git_time_tracker/data.py b/git_time_tracker/data.py new file mode 100644 index 0000000..e27c5a4 --- /dev/null +++ b/git_time_tracker/data.py @@ -0,0 +1,15 @@ +import argparse +import dataclasses +import datetime +import logging +import sys +from collections.abc import Iterator, Sequence +from pathlib import Path + +HIDDEN_LABEL_PREFIX = '__' +HIDDEN_LABEL_TOTAL = HIDDEN_LABEL_PREFIX + 'TOTAL' + +@dataclasses.dataclass(frozen=True, order=True) +class WorkSample: + registered_at: datetime.datetime + labels: Sequence[str] diff --git a/git_time_tracker/source/__init__.py b/git_time_tracker/source/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/git_time_tracker/source/git_repo.py b/git_time_tracker/source/git_repo.py new file mode 100644 index 0000000..7a10223 --- /dev/null +++ b/git_time_tracker/source/git_repo.py @@ -0,0 +1,56 @@ +import git +import argparse +import dataclasses +import datetime +import logging +import sys +from collections.abc import Iterator, Sequence +from pathlib import Path + +from ..data import WorkSample, HIDDEN_LABEL_PREFIX, HIDDEN_LABEL_TOTAL + +logger = logging.getLogger(__name__) + +def determine_default_branch(repo: git.Repo): + try: + repo.commit('main') + return 'main' + except: + return 'master' + +def determine_project_name(repo: git.Repo) -> str: + remotes = repo.remotes + if len(remotes) > 0: + return remotes.origin.url.removeprefix('git@gitfub.space:') + return Path(repo.working_tree_dir).name + +def get_samples_from_project(repo: git.Repo) -> Iterator[WorkSample]: + project_name = determine_project_name(repo) + assert project_name is not None + + # TODO: Branch on main or master or default + + repo.commit() + + for commit in repo.iter_commits(determine_default_branch(repo)): + labels = [HIDDEN_LABEL_TOTAL] + labels.append('project:' + project_name) + labels.append('author:' + commit.author.email) + yield WorkSample( + datetime.datetime.fromtimestamp(commit.authored_date, tz=datetime.UTC), + tuple(labels), + ) + yield WorkSample( + datetime.datetime.fromtimestamp(commit.committed_date, tz=datetime.UTC), + tuple(labels), + ) + del labels + + +def iterate_samples_from_git_repository(repo_path: Path) -> Iterator[WorkSample]: + try: + yield from get_samples_from_project(git.Repo(repo_path)) + except git.exc.InvalidGitRepositoryError: + logger.warning('Ignoring non-repo %s', repo_path) + +