From a46b3a123146fea14fb25e16a4fe1d5bcf52994a Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Sat, 21 Oct 2017 02:12:29 +0300 Subject: [PATCH] Add PoC for on-demand hooks repo download This makes pre-commit skip all config entries not listing certain hook Resolves #637 --- pre_commit/main.py | 8 +++++++- pre_commit/runner.py | 23 ++++++++++++++++++----- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/pre_commit/main.py b/pre_commit/main.py index 1405203c..6b339d5f 100644 --- a/pre_commit/main.py +++ b/pre_commit/main.py @@ -57,6 +57,8 @@ def _add_hook_type_option(parser): def _add_run_options(parser): parser.add_argument('hook', nargs='?', help='A single hook-id to run') parser.add_argument('--verbose', '-v', action='store_true', default=False) + parser.add_argument('--only', '-i', action='store_true', default=False, + help='Save some bandwidth') parser.add_argument( '--origin', '-o', help="The origin branch's commit_id when using `git push`.", @@ -227,7 +229,11 @@ def main(argv=None): with error_handler(): add_logging_handler(args.color) - runner = Runner.create(args.config) + runner = Runner.create( + args.config, + filter_repos=args.only, + filter_hook=args.hook, + ) git.check_for_cygwin_mismatch() if args.command == 'install': diff --git a/pre_commit/runner.py b/pre_commit/runner.py index 420c62df..7a9bf578 100644 --- a/pre_commit/runner.py +++ b/pre_commit/runner.py @@ -15,20 +15,26 @@ class Runner(object): repository under test. """ - def __init__(self, git_root, config_file, store_dir=None): + def __init__(self, git_root, config_file, store_dir=None, + filter_repos=False, filter_hook=None): self.git_root = git_root self.config_file = config_file self._store_dir = store_dir + self._filter_repos = filter_repos + self._filter_hook = filter_hook @classmethod - def create(cls, config_file): + def create(cls, config_file, filter_repos=False, filter_hook=None): """Creates a Runner by doing the following: - Finds the root of the current git repository - chdir to that directory """ root = git.get_root() os.chdir(root) - return cls(root, config_file) + return cls( + root, config_file, + filter_repos=filter_repos, filter_hook=filter_hook + ) @cached_property def git_dir(self): @@ -45,8 +51,15 @@ class Runner(object): @cached_property def repositories(self): """Returns a tuple of the configured repositories.""" - repos = self.config['repos'] - return tuple(Repository.create(x, self.store) for x in repos) + filtered_repos = repos = self.config['repos'] + if self._filter_repos and self._filter_hook: + filtered_repos = ( + r for r in repos + if self._filter_hook in ( + h['id'] for h in r['hooks'] + ) + ) + return tuple(Repository.create(x, self.store) for x in filtered_repos) def get_hook_path(self, hook_type): return os.path.join(self.git_dir, 'hooks', hook_type)