diff --git a/git_lint/__main__.py b/git_lint/__main__.py index 7e8ae40..5e8ff6c 100644 --- a/git_lint/__main__.py +++ b/git_lint/__main__.py @@ -5,7 +5,17 @@ from .option_handler import cleanup_options from .reporters import print_report, print_help, print_linters from .git_lint import load_config, run_linters, git_base from getopt import GetoptError +import os.path import sys +import time + +watchdog = False +try: + import watchdog + from watchdog.observers import Observer + from watchdog.events import RegexMatchingEventHandler +except Exception as e: + pass import gettext _ = gettext.gettext @@ -14,11 +24,56 @@ NAME = 'git-lint' VERSION = '0.0.4' +def remove_unavailable_options(options): + failures = [] + ((watchdog == False and ['monitor']) or []) + return filter(lambda i: i[1] not in failures, options) + + +def monitor(options, config, filenames): + + observer = watchdog.observers.Observer() + skip = ['\.git/'] + + def run_monitor_linters(): + (results, + unlintable_filenames, + cant_lint_filenames, + broken_linter_names, + unfindable_filenames) = run_linters(options, config, filenames) + + print_report(results, + unlintable_filenames, + cant_lint_filenames, + broken_linter_names, + unfindable_filenames, + options) + + class LintMonitor(RegexMatchingEventHandler): + def __init__(self): + super(LintMonitor, self).__init__(ignore_regexes=skip) + + def on_created(self, event): + run_monitor_linters() + + def on_modified(self, event): + run_monitor_linters() + + observer.schedule(LintMonitor(), git_base, recursive=True) + observer.start() + try: + while True: + time.sleep(1) + except KeyboardInterrupt: + observer.stop() + observer.join() + + def main(): if git_base is None: sys.exit(_('A git repository was not found.')) - (options, filenames, excluded_commands) = cleanup_options(OPTIONS, sys.argv) + initial_options = remove_unavailable_options(OPTIONS) + (options, filenames, excluded_commands) = cleanup_options(initial_options, sys.argv) if len(excluded_commands) > 0: print(_('These command line options were ignored due to option precedence.')) @@ -29,7 +84,7 @@ def main(): config = load_config(options, git_base) if 'help' in options: - print_help(OPTIONS, NAME) + print_help(initial_options, NAME) return 0 if 'version' in options: @@ -43,6 +98,9 @@ def main(): print_linters(config, broken_linter_names) return 0 + if 'monitor' in options: + return monitor(options, config, filenames) + (results, unlintable_filenames, cant_lint_filenames, @@ -62,7 +120,7 @@ def main(): return max([i[2] for i in results if len(i)]) except GetoptError as err: - print_help(OPTIONS) + print_help(initial_options) return 1 diff --git a/git_lint/options.py b/git_lint/options.py index 4de6235..807fc36 100644 --- a/git_lint/options.py +++ b/git_lint/options.py @@ -17,7 +17,7 @@ OPTIONS = [ ('w', 'workspace', False, _('Scan the workspace'), ['staging']), ('s', 'staging', False, - _('Scan the staging area (useful for pre-commit).'), []), + _('Scan the staging area (useful for pre-commit).'), ['monitor']), ('g', 'changes', False, _("Report lint failures only for diff'd sections"), ['complete']), ('p', 'complete', False, @@ -28,6 +28,8 @@ OPTIONS = [ _('Group the reports by file first'), []), ('d', 'dryrun', False, _('Dry run - report what would be done, but do not run linters'), []), + ('m', 'monitor', False, + _('Run continuously, monitoring filesytem for changes'), []), ('c', 'config', True, _('Path to config file'), []), ('h', 'help', False, @@ -35,3 +37,4 @@ OPTIONS = [ ('v', 'version', False, _('Version information'), []) ] +