diff --git a/pre_commit/repository.py b/pre_commit/repository.py index 165961f9..7605d837 100644 --- a/pre_commit/repository.py +++ b/pre_commit/repository.py @@ -11,7 +11,6 @@ import pkg_resources from cached_property import cached_property from pre_commit import five -from pre_commit.clientlib.validate_config import _LOCAL_HOOKS_MAGIC_REPO_STRING from pre_commit.clientlib.validate_config import is_local_hooks from pre_commit.clientlib.validate_manifest import MANIFEST_JSON_SCHEMA from pre_commit.jsonschema_extensions import apply_defaults @@ -41,9 +40,7 @@ class Repository(object): def create(cls, config, store, owner): repo_path_getter = store.get_repo_path_getter( config['repo'], - _LOCAL_HOOKS_MAGIC_REPO_STRING if - is_local_hooks(config) else config['sha'], - owner, + owner if is_local_hooks(config) else config['sha'], ) if is_local_hooks(config): return LocalRepository(config, repo_path_getter) diff --git a/pre_commit/store.py b/pre_commit/store.py index ec948310..5f767346 100644 --- a/pre_commit/store.py +++ b/pre_commit/store.py @@ -44,18 +44,7 @@ class Store(object): @cached_property def repo_path(self): - return self._store.clone(self._repo, self._ref) - - class LocalRepoPathGetter(RepoPathGetter): - def __init__(self, repo, sha, store, owner): - super(Store.LocalRepoPathGetter, self).__init__( - repo, sha, store, - ) - self._owner = owner - - @cached_property - def repo_path(self): - return self._store.initialize_local_repo(self._owner) + return self._store.initialize_repo(self._repo, self._sha) def __init__(self, directory=None): if directory is None: @@ -109,69 +98,44 @@ class Store(object): self._create() self.__created = True - def find_local_path(self, repo, ref): + def initialize_repo(self, repo, sha): + """Initializes the repository by cloning a remote or preparing an + empty local folder for local hooks. If the repo if 'local', + the sha used is the path to git_root of this repo so that several + local hooks for different projects are separated.""" + self.require_created() + + # Check if we already exist with sqlite3.connect(self.db_path) as db: result = db.execute( 'SELECT path FROM repos WHERE repo = ? AND ref = ?', - [repo, ref], + [repo, sha], ).fetchone() if result: return result[0] - def store_path(self, repo, ref, path): + logger.info('Initializing environment for {}.'.format(repo)) + + dir = tempfile.mkdtemp(prefix='repo', dir=self.directory) + if repo != _LOCAL_HOOKS_MAGIC_REPO_STRING: + with clean_path_on_failure(dir): + cmd_output( + 'git', 'clone', '--no-checkout', repo, dir, + env=no_git_env(), + ) + with cwd(dir): + cmd_output('git', 'reset', sha, '--hard', env=no_git_env()) + + # Update our db with the created repo with sqlite3.connect(self.db_path) as db: db.execute( 'INSERT INTO repos (repo, ref, path) VALUES (?, ?, ?)', - [repo, ref, path], + [repo, sha, dir], ) - - def clone(self, url, sha): - """Clone the given url and checkout the specific sha.""" - self.require_created() - - # Check if we already exist - local_path = self.find_local_path(url, sha) - if local_path: - return local_path - - logger.info('Initializing environment for {}.'.format(url)) - - dir = tempfile.mkdtemp(prefix='repo', dir=self.directory) - with clean_path_on_failure(dir): - cmd_output( - 'git', 'clone', '--no-checkout', url, dir, env=no_git_env(), - ) - with cwd(dir): - cmd_output('git', 'reset', ref, '--hard', env=no_git_env()) - - # Update our db with the created repo - self.store_path(url, sha, dir) return dir - def initialize_local_repo(self, owner): - """Initializes a repo in the default repository for the local repo""" - self.require_created() - local_path = self.find_local_path( - _LOCAL_HOOKS_MAGIC_REPO_STRING, owner, - ) - if local_path: - return local_path - - logger.info('Initializing environment for {}.'.format( - _LOCAL_HOOKS_MAGIC_REPO_STRING, - )) - - dir = tempfile.mkdtemp(prefix='repo', dir=self.directory) - - # Update our db with the created repo - self.store_path(_LOCAL_HOOKS_MAGIC_REPO_STRING, owner, dir) - return dir - - def get_repo_path_getter(self, repo, sha, owner=None): - if sha == _LOCAL_HOOKS_MAGIC_REPO_STRING: - return self.LocalRepoPathGetter(repo, sha, self, owner) - else: - return self.RepoPathGetter(repo, sha, self) + def get_repo_path_getter(self, repo, sha): + return self.RepoPathGetter(repo, sha, self) @cached_property def cmd_runner(self): diff --git a/tests/store_test.py b/tests/store_test.py index 950693cf..bba241a7 100644 --- a/tests/store_test.py +++ b/tests/store_test.py @@ -79,14 +79,14 @@ def test_does_not_recreate_if_directory_already_exists(store): assert not os.path.exists(os.path.join(store.directory, 'README')) -def test_clone(store, tempdir_factory, log_info_mock): +def test_initialize_repo(store, tempdir_factory, log_info_mock): path = git_dir(tempdir_factory) with cwd(path): cmd_output('git', 'commit', '--allow-empty', '-m', 'foo') sha = get_head_sha(path) cmd_output('git', 'commit', '--allow-empty', '-m', 'bar') - ret = store.clone(path, sha) + ret = store.initialize_repo(path, sha) # Should have printed some stuff assert log_info_mock.call_args_list[0][0][0].startswith( 'Initializing environment for ' @@ -98,7 +98,7 @@ def test_clone(store, tempdir_factory, log_info_mock): # Directory should start with `repo` _, dirname = os.path.split(ret) assert dirname.startswith('repo') - # Should be checked out to the sha we specified + # Should be checked out to the sha we specifieds assert get_head_sha(ret) == sha # Assert there's an entry in the sqlite db for this @@ -110,11 +110,11 @@ def test_clone(store, tempdir_factory, log_info_mock): assert path == ret -def test_clone_cleans_up_on_checkout_failure(store): +def test_initialize_repo_cleans_up_on_checkout_failure(store): try: # This raises an exception because you can't clone something that # doesn't exist! - store.clone('/i_dont_exist_lol', 'fake_sha') + store.initialize_repo('/i_dont_exist_lol', 'fake_sha') except Exception as e: assert '/i_dont_exist_lol' in five.text(e) @@ -130,7 +130,7 @@ def test_has_cmd_runner_at_directory(store): assert ret.prefix_dir == store.directory + os.sep -def test_clone_when_repo_already_exists(store): +def test_initialize_repo_when_repo_already_exists(store): # Create an entry in the sqlite db that makes it look like the repo has # been cloned. store.require_created() @@ -141,7 +141,7 @@ def test_clone_when_repo_already_exists(store): 'VALUES ("fake_repo", "fake_ref", "fake_path")' ) - assert store.clone('fake_repo', 'fake_ref') == 'fake_path' + assert store.initialize_repo('fake_repo', 'fake_ref') == 'fake_path' def test_require_created_when_directory_exists_but_not_db(store):