prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Encode some sort of "version" for language-local repositories
  Without this, they'll never get upgraded if fixes are made in the pre-commit empty template
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `pre_commit/store.py`
  Content:
  ```
  1 from __future__ import unicode_literals
  2 
  3 import contextlib
  4 import io
  5 import logging
  6 import os.path
  7 import sqlite3
  8 import tempfile
  9 
  10 from cached_property import cached_property
  11 
  12 from pre_commit.prefixed_command_runner import PrefixedCommandRunner
  13 from pre_commit.util import clean_path_on_failure
  14 from pre_commit.util import cmd_output
  15 from pre_commit.util import copy_tree_to_path
  16 from pre_commit.util import cwd
  17 from pre_commit.util import no_git_env
  18 from pre_commit.util import resource_filename
  19 
  20 
  21 logger = logging.getLogger('pre_commit')
  22 
  23 
  24 def _get_default_directory():
  25     """Returns the default directory for the Store.  This is intentionally
  26     underscored to indicate that `Store.get_default_directory` is the intended
  27     way to get this information.  This is also done so
  28     `Store.get_default_directory` can be mocked in tests and
  29     `_get_default_directory` can be tested.
  30     """
  31     return os.environ.get(
  32         'PRE_COMMIT_HOME',
  33         os.path.join(os.path.expanduser('~'), '.pre-commit'),
  34     )
  35 
  36 
  37 class Store(object):
  38     get_default_directory = staticmethod(_get_default_directory)
  39 
  40     def __init__(self, directory=None):
  41         if directory is None:
  42             directory = self.get_default_directory()
  43 
  44         self.directory = directory
  45         self.__created = False
  46 
  47     def _write_readme(self):
  48         with io.open(os.path.join(self.directory, 'README'), 'w') as readme:
  49             readme.write(
  50                 'This directory is maintained by the pre-commit project.\n'
  51                 'Learn more: https://github.com/pre-commit/pre-commit\n'
  52             )
  53 
  54     def _write_sqlite_db(self):
  55         # To avoid a race where someone ^Cs between db creation and execution
  56         # of the CREATE TABLE statement
  57         fd, tmpfile = tempfile.mkstemp(dir=self.directory)
  58         # We'll be managing this file ourselves
  59         os.close(fd)
  60         # sqlite doesn't close its fd with its contextmanager >.<
  61         # contextlib.closing fixes this.
  62         # See: http://stackoverflow.com/a/28032829/812183
  63         with contextlib.closing(sqlite3.connect(tmpfile)) as db:
  64             db.executescript(
  65                 'CREATE TABLE repos ('
  66                 '    repo CHAR(255) NOT NULL,'
  67                 '    ref CHAR(255) NOT NULL,'
  68                 '    path CHAR(255) NOT NULL,'
  69                 '    PRIMARY KEY (repo, ref)'
  70                 ');'
  71             )
  72 
  73         # Atomic file move
  74         os.rename(tmpfile, self.db_path)
  75 
  76     def _create(self):
  77         if os.path.exists(self.db_path):
  78             return
  79         if not os.path.exists(self.directory):
  80             os.makedirs(self.directory)
  81             self._write_readme()
  82         self._write_sqlite_db()
  83 
  84     def require_created(self):
  85         """Require the pre-commit file store to be created."""
  86         if not self.__created:
  87             self._create()
  88             self.__created = True
  89 
  90     def _new_repo(self, repo, ref, make_strategy):
  91         self.require_created()
  92 
  93         # Check if we already exist
  94         with sqlite3.connect(self.db_path) as db:
  95             result = db.execute(
  96                 'SELECT path FROM repos WHERE repo = ? AND ref = ?',
  97                 [repo, ref],
  98             ).fetchone()
  99             if result:
  100                 return result[0]
  101 
  102         logger.info('Initializing environment for {}.'.format(repo))
  103 
  104         directory = tempfile.mkdtemp(prefix='repo', dir=self.directory)
  105         with clean_path_on_failure(directory):
  106             make_strategy(directory)
  107 
  108         # Update our db with the created repo
  109         with sqlite3.connect(self.db_path) as db:
  110             db.execute(
  111                 'INSERT INTO repos (repo, ref, path) VALUES (?, ?, ?)',
  112                 [repo, ref, directory],
  113             )
  114         return directory
  115 
  116     def clone(self, repo, ref):
  117         """Clone the given url and checkout the specific ref."""
  118         def clone_strategy(directory):
  119             cmd_output(
  120                 'git', 'clone', '--no-checkout', repo, directory,
  121                 env=no_git_env(),
  122             )
  123             with cwd(directory):
  124                 cmd_output('git', 'reset', ref, '--hard', env=no_git_env())
  125 
  126         return self._new_repo(repo, ref, clone_strategy)
  127 
  128     def make_local(self, deps):
  129         def make_local_strategy(directory):
  130             copy_tree_to_path(resource_filename('empty_template'), directory)
  131         return self._new_repo(
  132             'local:{}'.format(','.join(sorted(deps))), 'N/A',
  133             make_local_strategy,
  134         )
  135 
  136     @cached_property
  137     def cmd_runner(self):
  138         return PrefixedCommandRunner(self.directory)
  139 
  140     @cached_property
  141     def db_path(self):
  142         return os.path.join(self.directory, 'db.db')
  143
  ```
  
  Path: `pre_commit/constants.py`
  Content:
  ```
  1 from __future__ import unicode_literals
  2 
  3 import pkg_resources
  4 
  5 CONFIG_FILE = '.pre-commit-config.yaml'
  6 
  7 # In 0.12.0, the default file was changed to be namespaced
  8 MANIFEST_FILE = '.pre-commit-hooks.yaml'
  9 MANIFEST_FILE_LEGACY = 'hooks.yaml'
  10 
  11 YAML_DUMP_KWARGS = {
  12     'default_flow_style': False,
  13     # Use unicode
  14     'encoding': None,
  15     'indent': 4,
  16 }
  17 
  18 # Bump when installation changes in a backwards / forwards incompatible way
  19 INSTALLED_STATE_VERSION = '1'
  20 
  21 VERSION = pkg_resources.get_distribution('pre-commit').version
  22 VERSION_PARSED = pkg_resources.parse_version(VERSION)
  23
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/pre_commit/constants.py b/pre_commit/constants.py
  --- a/pre_commit/constants.py
  +++ b/pre_commit/constants.py
  @@ -17,6 +17,8 @@
   
   # Bump when installation changes in a backwards / forwards incompatible way
   INSTALLED_STATE_VERSION = '1'
  +# Bump when modifying `empty_template`
  +LOCAL_REPO_VERSION = '1'
   
   VERSION = pkg_resources.get_distribution('pre-commit').version
   VERSION_PARSED = pkg_resources.parse_version(VERSION)
  diff --git a/pre_commit/store.py b/pre_commit/store.py
  --- a/pre_commit/store.py
  +++ b/pre_commit/store.py
  @@ -9,6 +9,7 @@
   
   from cached_property import cached_property
   
  +import pre_commit.constants as C
   from pre_commit.prefixed_command_runner import PrefixedCommandRunner
   from pre_commit.util import clean_path_on_failure
   from pre_commit.util import cmd_output
  @@ -129,7 +130,7 @@
           def make_local_strategy(directory):
               copy_tree_to_path(resource_filename('empty_template'), directory)
           return self._new_repo(
  -            'local:{}'.format(','.join(sorted(deps))), 'N/A',
  +            'local:{}'.format(','.join(sorted(deps))), C.LOCAL_REPO_VERSION,
               make_local_strategy,
           )
  
verification_info: {"golden_diff": "diff --git a/pre_commit/constants.py b/pre_commit/constants.py\n--- a/pre_commit/constants.py\n+++ b/pre_commit/constants.py\n@@ -17,6 +17,8 @@\n \n # Bump when installation changes in a backwards / forwards incompatible way\n INSTALLED_STATE_VERSION = '1'\n+# Bump when modifying `empty_template`\n+LOCAL_REPO_VERSION = '1'\n \n VERSION = pkg_resources.get_distribution('pre-commit').version\n VERSION_PARSED = pkg_resources.parse_version(VERSION)\ndiff --git a/pre_commit/store.py b/pre_commit/store.py\n--- a/pre_commit/store.py\n+++ b/pre_commit/store.py\n@@ -9,6 +9,7 @@\n \n from cached_property import cached_property\n \n+import pre_commit.constants as C\n from pre_commit.prefixed_command_runner import PrefixedCommandRunner\n from pre_commit.util import clean_path_on_failure\n from pre_commit.util import cmd_output\n@@ -129,7 +130,7 @@\n         def make_local_strategy(directory):\n             copy_tree_to_path(resource_filename('empty_template'), directory)\n         return self._new_repo(\n-            'local:{}'.format(','.join(sorted(deps))), 'N/A',\n+            'local:{}'.format(','.join(sorted(deps))), C.LOCAL_REPO_VERSION,\n             make_local_strategy,\n         )\n", "issue": "Encode some sort of \"version\" for language-local repositories\nWithout this, they'll never get upgraded if fixes are made in the pre-commit empty template\n", "before_files": [{"content": "from __future__ import unicode_literals\n\nimport contextlib\nimport io\nimport logging\nimport os.path\nimport sqlite3\nimport tempfile\n\nfrom cached_property import cached_property\n\nfrom pre_commit.prefixed_command_runner import PrefixedCommandRunner\nfrom pre_commit.util import clean_path_on_failure\nfrom pre_commit.util import cmd_output\nfrom pre_commit.util import copy_tree_to_path\nfrom pre_commit.util import cwd\nfrom pre_commit.util import no_git_env\nfrom pre_commit.util import resource_filename\n\n\nlogger = logging.getLogger('pre_commit')\n\n\ndef _get_default_directory():\n    \"\"\"Returns the default directory for the Store.  This is intentionally\n    underscored to indicate that `Store.get_default_directory` is the intended\n    way to get this information.  This is also done so\n    `Store.get_default_directory` can be mocked in tests and\n    `_get_default_directory` can be tested.\n    \"\"\"\n    return os.environ.get(\n        'PRE_COMMIT_HOME',\n        os.path.join(os.path.expanduser('~'), '.pre-commit'),\n    )\n\n\nclass Store(object):\n    get_default_directory = staticmethod(_get_default_directory)\n\n    def __init__(self, directory=None):\n        if directory is None:\n            directory = self.get_default_directory()\n\n        self.directory = directory\n        self.__created = False\n\n    def _write_readme(self):\n        with io.open(os.path.join(self.directory, 'README'), 'w') as readme:\n            readme.write(\n                'This directory is maintained by the pre-commit project.\\n'\n                'Learn more: https://github.com/pre-commit/pre-commit\\n'\n            )\n\n    def _write_sqlite_db(self):\n        # To avoid a race where someone ^Cs between db creation and execution\n        # of the CREATE TABLE statement\n        fd, tmpfile = tempfile.mkstemp(dir=self.directory)\n        # We'll be managing this file ourselves\n        os.close(fd)\n        # sqlite doesn't close its fd with its contextmanager >.<\n        # contextlib.closing fixes this.\n        # See: http://stackoverflow.com/a/28032829/812183\n        with contextlib.closing(sqlite3.connect(tmpfile)) as db:\n            db.executescript(\n                'CREATE TABLE repos ('\n                '    repo CHAR(255) NOT NULL,'\n                '    ref CHAR(255) NOT NULL,'\n                '    path CHAR(255) NOT NULL,'\n                '    PRIMARY KEY (repo, ref)'\n                ');'\n            )\n\n        # Atomic file move\n        os.rename(tmpfile, self.db_path)\n\n    def _create(self):\n        if os.path.exists(self.db_path):\n            return\n        if not os.path.exists(self.directory):\n            os.makedirs(self.directory)\n            self._write_readme()\n        self._write_sqlite_db()\n\n    def require_created(self):\n        \"\"\"Require the pre-commit file store to be created.\"\"\"\n        if not self.__created:\n            self._create()\n            self.__created = True\n\n    def _new_repo(self, repo, ref, make_strategy):\n        self.require_created()\n\n        # Check if we already exist\n        with sqlite3.connect(self.db_path) as db:\n            result = db.execute(\n                'SELECT path FROM repos WHERE repo = ? AND ref = ?',\n                [repo, ref],\n            ).fetchone()\n            if result:\n                return result[0]\n\n        logger.info('Initializing environment for {}.'.format(repo))\n\n        directory = tempfile.mkdtemp(prefix='repo', dir=self.directory)\n        with clean_path_on_failure(directory):\n            make_strategy(directory)\n\n        # Update our db with the created repo\n        with sqlite3.connect(self.db_path) as db:\n            db.execute(\n                'INSERT INTO repos (repo, ref, path) VALUES (?, ?, ?)',\n                [repo, ref, directory],\n            )\n        return directory\n\n    def clone(self, repo, ref):\n        \"\"\"Clone the given url and checkout the specific ref.\"\"\"\n        def clone_strategy(directory):\n            cmd_output(\n                'git', 'clone', '--no-checkout', repo, directory,\n                env=no_git_env(),\n            )\n            with cwd(directory):\n                cmd_output('git', 'reset', ref, '--hard', env=no_git_env())\n\n        return self._new_repo(repo, ref, clone_strategy)\n\n    def make_local(self, deps):\n        def make_local_strategy(directory):\n            copy_tree_to_path(resource_filename('empty_template'), directory)\n        return self._new_repo(\n            'local:{}'.format(','.join(sorted(deps))), 'N/A',\n            make_local_strategy,\n        )\n\n    @cached_property\n    def cmd_runner(self):\n        return PrefixedCommandRunner(self.directory)\n\n    @cached_property\n    def db_path(self):\n        return os.path.join(self.directory, 'db.db')\n", "path": "pre_commit/store.py"}, {"content": "from __future__ import unicode_literals\n\nimport pkg_resources\n\nCONFIG_FILE = '.pre-commit-config.yaml'\n\n# In 0.12.0, the default file was changed to be namespaced\nMANIFEST_FILE = '.pre-commit-hooks.yaml'\nMANIFEST_FILE_LEGACY = 'hooks.yaml'\n\nYAML_DUMP_KWARGS = {\n    'default_flow_style': False,\n    # Use unicode\n    'encoding': None,\n    'indent': 4,\n}\n\n# Bump when installation changes in a backwards / forwards incompatible way\nINSTALLED_STATE_VERSION = '1'\n\nVERSION = pkg_resources.get_distribution('pre-commit').version\nVERSION_PARSED = pkg_resources.parse_version(VERSION)\n", "path": "pre_commit/constants.py"}], "after_files": [{"content": "from __future__ import unicode_literals\n\nimport contextlib\nimport io\nimport logging\nimport os.path\nimport sqlite3\nimport tempfile\n\nfrom cached_property import cached_property\n\nimport pre_commit.constants as C\nfrom pre_commit.prefixed_command_runner import PrefixedCommandRunner\nfrom pre_commit.util import clean_path_on_failure\nfrom pre_commit.util import cmd_output\nfrom pre_commit.util import copy_tree_to_path\nfrom pre_commit.util import cwd\nfrom pre_commit.util import no_git_env\nfrom pre_commit.util import resource_filename\n\n\nlogger = logging.getLogger('pre_commit')\n\n\ndef _get_default_directory():\n    \"\"\"Returns the default directory for the Store.  This is intentionally\n    underscored to indicate that `Store.get_default_directory` is the intended\n    way to get this information.  This is also done so\n    `Store.get_default_directory` can be mocked in tests and\n    `_get_default_directory` can be tested.\n    \"\"\"\n    return os.environ.get(\n        'PRE_COMMIT_HOME',\n        os.path.join(os.path.expanduser('~'), '.pre-commit'),\n    )\n\n\nclass Store(object):\n    get_default_directory = staticmethod(_get_default_directory)\n\n    def __init__(self, directory=None):\n        if directory is None:\n            directory = self.get_default_directory()\n\n        self.directory = directory\n        self.__created = False\n\n    def _write_readme(self):\n        with io.open(os.path.join(self.directory, 'README'), 'w') as readme:\n            readme.write(\n                'This directory is maintained by the pre-commit project.\\n'\n                'Learn more: https://github.com/pre-commit/pre-commit\\n'\n            )\n\n    def _write_sqlite_db(self):\n        # To avoid a race where someone ^Cs between db creation and execution\n        # of the CREATE TABLE statement\n        fd, tmpfile = tempfile.mkstemp(dir=self.directory)\n        # We'll be managing this file ourselves\n        os.close(fd)\n        # sqlite doesn't close its fd with its contextmanager >.<\n        # contextlib.closing fixes this.\n        # See: http://stackoverflow.com/a/28032829/812183\n        with contextlib.closing(sqlite3.connect(tmpfile)) as db:\n            db.executescript(\n                'CREATE TABLE repos ('\n                '    repo CHAR(255) NOT NULL,'\n                '    ref CHAR(255) NOT NULL,'\n                '    path CHAR(255) NOT NULL,'\n                '    PRIMARY KEY (repo, ref)'\n                ');'\n            )\n\n        # Atomic file move\n        os.rename(tmpfile, self.db_path)\n\n    def _create(self):\n        if os.path.exists(self.db_path):\n            return\n        if not os.path.exists(self.directory):\n            os.makedirs(self.directory)\n            self._write_readme()\n        self._write_sqlite_db()\n\n    def require_created(self):\n        \"\"\"Require the pre-commit file store to be created.\"\"\"\n        if not self.__created:\n            self._create()\n            self.__created = True\n\n    def _new_repo(self, repo, ref, make_strategy):\n        self.require_created()\n\n        # Check if we already exist\n        with sqlite3.connect(self.db_path) as db:\n            result = db.execute(\n                'SELECT path FROM repos WHERE repo = ? AND ref = ?',\n                [repo, ref],\n            ).fetchone()\n            if result:\n                return result[0]\n\n        logger.info('Initializing environment for {}.'.format(repo))\n\n        directory = tempfile.mkdtemp(prefix='repo', dir=self.directory)\n        with clean_path_on_failure(directory):\n            make_strategy(directory)\n\n        # Update our db with the created repo\n        with sqlite3.connect(self.db_path) as db:\n            db.execute(\n                'INSERT INTO repos (repo, ref, path) VALUES (?, ?, ?)',\n                [repo, ref, directory],\n            )\n        return directory\n\n    def clone(self, repo, ref):\n        \"\"\"Clone the given url and checkout the specific ref.\"\"\"\n        def clone_strategy(directory):\n            cmd_output(\n                'git', 'clone', '--no-checkout', repo, directory,\n                env=no_git_env(),\n            )\n            with cwd(directory):\n                cmd_output('git', 'reset', ref, '--hard', env=no_git_env())\n\n        return self._new_repo(repo, ref, clone_strategy)\n\n    def make_local(self, deps):\n        def make_local_strategy(directory):\n            copy_tree_to_path(resource_filename('empty_template'), directory)\n        return self._new_repo(\n            'local:{}'.format(','.join(sorted(deps))), C.LOCAL_REPO_VERSION,\n            make_local_strategy,\n        )\n\n    @cached_property\n    def cmd_runner(self):\n        return PrefixedCommandRunner(self.directory)\n\n    @cached_property\n    def db_path(self):\n        return os.path.join(self.directory, 'db.db')\n", "path": "pre_commit/store.py"}, {"content": "from __future__ import unicode_literals\n\nimport pkg_resources\n\nCONFIG_FILE = '.pre-commit-config.yaml'\n\n# In 0.12.0, the default file was changed to be namespaced\nMANIFEST_FILE = '.pre-commit-hooks.yaml'\nMANIFEST_FILE_LEGACY = 'hooks.yaml'\n\nYAML_DUMP_KWARGS = {\n    'default_flow_style': False,\n    # Use unicode\n    'encoding': None,\n    'indent': 4,\n}\n\n# Bump when installation changes in a backwards / forwards incompatible way\nINSTALLED_STATE_VERSION = '1'\n# Bump when modifying `empty_template`\nLOCAL_REPO_VERSION = '1'\n\nVERSION = pkg_resources.get_distribution('pre-commit').version\nVERSION_PARSED = pkg_resources.parse_version(VERSION)\n", "path": "pre_commit/constants.py"}]}