From 7c0dde7dca016177ba05c04632a470a06f1daccd Mon Sep 17 00:00:00 2001 From: Simeon Simeonov Date: Mon, 17 Sep 2018 00:01:46 +0200 Subject: Added new options -m -r. Some code restructuring --- pygitchecker.py | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 114 insertions(+), 6 deletions(-) diff --git a/pygitchecker.py b/pygitchecker.py index 77f85ec..d826084 100755 --- a/pygitchecker.py +++ b/pygitchecker.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import argparse +import os import sys import pygit2 @@ -8,13 +9,83 @@ import pygit2 from flake8.api import legacy as flake8_legacy +def is_git_repo(abspath): + """ + True of abspath points to a git repo, False otherwise + """ + if not os.path.isdir(abspath): + return False + try: + pygit2.Repository(abspath) + return True + except pygit2.GitError: + return False + + +def modifications_exist(abspath): + """ + True if modifications exist for git repo representing abspath + False if no modifications exist + + pygit2.GitError raised if abspath points to illegal repo + """ + repo = pygit2.Repository(abspath) + status = repo.status() + for gfile, state in status.items(): + if ( + state in (pygit2.GIT_STATUS_WT_MODIFIED, + pygit2.GIT_STATUS_WT_NEW, + pygit2.GIT_STATUS_INDEX_NEW, + pygit2.GIT_STATUS_INDEX_MODIFIED) + ): + return True + return False + + +def print_modification_status(abspath, status, args): + """ + Prints the modification status for the give abspath + """ + if status: + if args.verbose: + print(f'{abspath} -> modified') + else: + print(abspath) + return status + if args.verbose: + print(f'{abspath} -> unchanged') + return status + + +def fetch_git_repos(abspath): + """ + Returns a list of git repo paths under abspath + """ + repo_list = list() + for root, dirs, files in os.walk(abspath): + if '.git' in dirs: + try: + pygit2.Repository(root) + repo_list.append(root) + except pygit2.GitError: + continue + return repo_list + + def fetch_git_files(args): """ Fetches new and modified .py-files using pygit2 """ - repo = pygit2.Repository(args.repo_path) - status = repo.status() git_files_list = list() + try: + repo = pygit2.Repository(args.repo_path) + status = repo.status() + except pygit2.GitError: + print('{repo_path} is not a valid git repository'.format( + repo_path=args.repo_path), + file=sys.stderr, + flush=True) + sys.exit(1) if not status: return git_files_list for gfile, state in status.items(): @@ -25,6 +96,8 @@ def fetch_git_files(args): pygit2.GIT_STATUS_INDEX_MODIFIED) and gfile.lower().endswith('.py') ): + if args.verbose: + print(gfile) git_files_list.append(gfile) return git_files_list @@ -35,16 +108,51 @@ if __name__ == '__main__': parser.add_argument( 'repo_path', metavar='REPO', - default='.', + default=os.getcwd(), type=str, help='Git repo path (default: cwd)') parser.add_argument( - '--disable-pep8-checks', + '-m', '--modifications-only', + action='store_true', + dest='mod_only', + default=False, + help='Only check for git modifications') + parser.add_argument( + '-r', '--recursive', action='store_true', - dest='disable_pep8', + dest='recursive', default=False, - help='Disable pep8 checks') + help='Look for several repos recursively') + parser.add_argument( + '-v', '--verbose', + action='store_true', + dest='verbose', + default=False, + help='Verbosity') args = parser.parse_args() + abs_repo_path = os.path.abspath(os.path.expanduser(args.repo_path)) + if args.mod_only: + if not args.recursive: + if not is_git_repo(abs_repo_path): + print(f'{abs_repo_path} is not a valid git repository', + file=sys.stderr, + flush=True) + sys.exit(1) + print_modification_status(abs_repo_path, + modifications_exist(abs_repo_path), + args) + sys.exit(0) + # resursive + repo_list = fetch_git_repos(abs_repo_path) + if not repo_list: + print('No git-repos found') + sys.exit(0) + repo_list.sort() + for repo_path in repo_list: + print_modification_status(repo_path, + modifications_exist(repo_path), + args) + sys.exit(0) git_files = fetch_git_files(args) if not git_files: print('No modifications') -- cgit v1.3