Repository: pre-commit/pre-commit

Issue:
pre-commit autoupdate fails when config is empty
Running `pre-commit autoupdate` with an empty `.pre-commit-config.yaml` results in the below error:
```An unexpected error has occurred: IndexError: list index out of range
Traceback (most recent call last):
  File "/usr/local/Cellar/pre-commit/1.14.2/libexec/lib/python3.7/site-packages/pre_commit/error_handler.py", line 46, in error_handler
    yield
  File "/usr/local/Cellar/pre-commit/1.14.2/libexec/lib/python3.7/site-packages/pre_commit/main.py", line 286, in main
    repos=args.repos,
  File "/usr/local/Cellar/pre-commit/1.14.2/libexec/lib/python3.7/site-packages/pre_commit/commands/autoupdate.py", line 117, in autoupdate
    migrate_config(config_file, quiet=True)
  File "/usr/local/Cellar/pre-commit/1.14.2/libexec/lib/python3.7/site-packages/pre_commit/commands/migrate_config.py", line 52, in migrate_config
    contents = _migrate_map(contents)
  File "/usr/local/Cellar/pre-commit/1.14.2/libexec/lib/python3.7/site-packages/pre_commit/commands/migrate_config.py", line 24, in _migrate_map
    while _is_header_line(lines[i]):
IndexError: list index out of range
```


Discussion:
Confirmed, thanks!
I hope this isn't a stupid question but judging by the documentation an empty config file is not a situation the code should continue with? i.e. It should throw an exception and stop?
nope, not a stupid question at all!  this is a very minor bug in an edge case.  The acceptable fixes for this are either "do nothing" or produce an error message similar to to the one when attempting to run with an empty configuration.

The ~probable fix here is `i < len(lines) and ...` and let the rest of the machinery handle / produce an error message.  The way `autoupdate` is written happens to defer configuration loading as long as possible iirc
I mean I like to think I could put a simple if i < len around the while loop if you'd like me to give it a crack. 
go for it!  I left this one [good-first-issue] because it's probably an easy fix :)

Resolving patch:
diff --git a/pre_commit/commands/migrate_config.py b/pre_commit/commands/migrate_config.py
--- a/pre_commit/commands/migrate_config.py
+++ b/pre_commit/commands/migrate_config.py
@@ -21,7 +21,8 @@ def _migrate_map(contents):
     # Find the first non-header line
     lines = contents.splitlines(True)
     i = 0
-    while _is_header_line(lines[i]):
+    # Only loop on non empty configuration file
+    while i < len(lines) and _is_header_line(lines[i]):
         i += 1
 
     header = ''.join(lines[:i])


Test patch:
diff --git a/tests/commands/migrate_config_test.py b/tests/commands/migrate_config_test.py
--- a/tests/commands/migrate_config_test.py
+++ b/tests/commands/migrate_config_test.py
@@ -147,3 +147,13 @@ def test_migrate_config_sha_to_rev(tmpdir):
         '    rev: v1.2.0\n'
         '    hooks: []\n'
     )
+
+
+@pytest.mark.parametrize('contents', ('', '\n'))
+def test_empty_configuration_file_user_error(tmpdir, contents):
+    cfg = tmpdir.join(C.CONFIG_FILE)
+    cfg.write(contents)
+    with tmpdir.as_cwd():
+        assert not migrate_config(C.CONFIG_FILE)
+    # even though the config is invalid, this should be a noop
+    assert cfg.read() == contents