mirror of
https://github.com/PyCQA/flake8.git
synced 2026-03-29 10:36:53 +00:00
Start fleshing out mercurial hook
This also reports errors with hook installation using exceptions and includes far more exceptions for mercurial since it has more failure modes.
This commit is contained in:
parent
53438fca1d
commit
6dca1d6fd7
4 changed files with 152 additions and 7 deletions
|
|
@ -43,10 +43,52 @@ class InvalidSyntax(Flake8Exception):
|
|||
super(InvalidSyntax, self).__init__(*args, **kwargs)
|
||||
|
||||
|
||||
class GitHookAlreadyExists(Flake8Exception):
|
||||
class HookInstallationError(Flake8Exception):
|
||||
"""Parent exception for all hooks errors."""
|
||||
pass
|
||||
|
||||
|
||||
class GitHookAlreadyExists(HookInstallationError):
|
||||
"""Exception raised when the git pre-commit hook file already exists."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the path attribute."""
|
||||
self.path = kwargs.pop('path')
|
||||
super(GitHookAlreadyExists, self).__init__(*args, **kwargs)
|
||||
|
||||
def __str__(self):
|
||||
"""Provide a nice message regarding the exception."""
|
||||
msg = ('The Git pre-commit hook ({0}) already exists. To convince '
|
||||
'Flake8 to install the hook, please remove the existing '
|
||||
'hook.')
|
||||
return msg.format(self.path)
|
||||
|
||||
|
||||
class MercurialHookAlreadyExists(HookInstallationError):
|
||||
"""Exception raised when a mercurial hook is already configured."""
|
||||
|
||||
hook_name = None
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the relevant attributes."""
|
||||
self.path = kwargs.pop('path')
|
||||
self.value = kwargs.pop('value')
|
||||
super(MercurialHookAlreadyExists, self).__init__(*args, **kwargs)
|
||||
|
||||
def __str__(self):
|
||||
msg = ('The Mercurial {0} hook already exists with "{1}" in {2}. '
|
||||
'To convince Flake8 to install the hook, please remove the '
|
||||
'{0} configuration from the [hooks] section of your hgrc.')
|
||||
return msg.format(self.hook_name, self.value, self.path)
|
||||
|
||||
|
||||
class MercurialCommitHookAlreadyExists(MercurialHookAlreadyExists):
|
||||
"""Exception raised when the hg commit hook is already configured."""
|
||||
|
||||
hook_name = 'commit'
|
||||
|
||||
|
||||
class MercurialQRefreshHookAlreadyExists(MercurialHookAlreadyExists):
|
||||
"""Exception raised when the hg commit hook is already configured."""
|
||||
|
||||
hook_name = 'qrefresh'
|
||||
|
|
|
|||
|
|
@ -71,7 +71,9 @@ def install():
|
|||
if not os.path.exists(hooks_directory):
|
||||
os.mkdir(hooks_directory)
|
||||
|
||||
pre_commit_file = os.path.join(hooks_directory, 'hooks', 'pre-commit')
|
||||
pre_commit_file = os.path.abspath(
|
||||
os.path.join(hooks_directory, 'pre-commit')
|
||||
)
|
||||
if os.path.exists(pre_commit_file):
|
||||
raise exceptions.GitHookAlreadyExists(
|
||||
'File already exists',
|
||||
|
|
|
|||
|
|
@ -4,13 +4,106 @@
|
|||
.. autofunction:: install
|
||||
|
||||
"""
|
||||
import configparser
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from flake8 import exceptions as exc
|
||||
|
||||
__all__ = ('hook', 'install')
|
||||
|
||||
|
||||
def hook(lazy=False, strict=False):
|
||||
pass
|
||||
def hook(ui, repo, **kwargs):
|
||||
"""Execute Flake8 on the repository provided by Mercurial.
|
||||
|
||||
To understand the parameters read more of the Mercurial documentation
|
||||
around Hooks: https://www.mercurial-scm.org/wiki/Hook.
|
||||
|
||||
We avoid using the ``ui`` attribute because it can cause issues with
|
||||
the GPL license tha Mercurial is under. We don't import it, but we
|
||||
avoid using it all the same.
|
||||
"""
|
||||
from flake8.main import application
|
||||
hgrc = find_hgrc(create_if_missing=False)
|
||||
if hgrc is None:
|
||||
print('Cannot locate your root mercurial repository.')
|
||||
raise SystemExit(True)
|
||||
|
||||
hgconfig = configparser_for(hgrc)
|
||||
strict = hgconfig.get('flake8', 'strict', fallback=True)
|
||||
|
||||
app = application.Application()
|
||||
app.run()
|
||||
|
||||
if strict:
|
||||
return app.result_count
|
||||
return 0
|
||||
|
||||
|
||||
def install():
|
||||
pass
|
||||
"""Ensure that the mercurial hooks are installed."""
|
||||
hgrc = find_hgrc(create_if_missing=True)
|
||||
if hgrc is None:
|
||||
print('Could not locate your root mercurial repository.')
|
||||
raise SystemExit(True)
|
||||
|
||||
hgconfig = configparser_for(hgrc)
|
||||
|
||||
if not hgconfig.has_section('hooks'):
|
||||
hgconfig.add_section('hooks')
|
||||
|
||||
if hgconfig.has_option('hooks', 'commit'):
|
||||
raise exc.MercurialCommitHookAlreadyExists(
|
||||
path=hgrc,
|
||||
value=hgconfig.get('hooks', 'commit'),
|
||||
)
|
||||
|
||||
if hgconfig.has_option('hooks', 'qrefresh'):
|
||||
raise exc.MercurialQRefreshHookAlreadyExists(
|
||||
path=hgrc,
|
||||
value=hgconfig.get('hooks', 'qrefresh'),
|
||||
)
|
||||
|
||||
hgconfig.set('hooks', 'commit', 'python:flake8.main.mercurial.hook')
|
||||
hgconfig.set('hooks', 'qrefresh', 'python:flake8.main.mercurial.hook')
|
||||
|
||||
if not hgconfig.has_section('flake8'):
|
||||
hgconfig.add_section('flake8')
|
||||
|
||||
if not hgconfig.has_option('flake8', 'strict'):
|
||||
hgconfig.set('flake8', 'strict', False)
|
||||
|
||||
with open(hgrc, 'w') as fd:
|
||||
hgconfig.write(fd)
|
||||
|
||||
|
||||
def find_hgrc(create_if_missing=False):
|
||||
root = subprocess.Popen(
|
||||
['hg', 'root'],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
)
|
||||
|
||||
(hg_directory, _) = root.communicate()
|
||||
if callable(getattr(hg_directory, 'decode', None)):
|
||||
hg_directory = hg_directory.decode('utf-8')
|
||||
|
||||
if not os.path.isdir(hg_directory):
|
||||
return None
|
||||
|
||||
hgrc = os.path.abspath(
|
||||
os.path.join(hg_directory, '.hg', 'hgrc')
|
||||
)
|
||||
if not os.path.exists(hgrc):
|
||||
if create_if_missing:
|
||||
open(hgrc, 'w').close()
|
||||
else:
|
||||
return None
|
||||
|
||||
return hgrc
|
||||
|
||||
|
||||
def configparser_for(path):
|
||||
parser = configparser.ConfigParser(interpolation=None)
|
||||
parser.read(path)
|
||||
return parser
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
"""Module containing some of the logic for our VCS installation logic."""
|
||||
from flake8 import exceptions as exc
|
||||
from flake8.main import git
|
||||
from flake8.main import mercurial
|
||||
|
||||
|
|
@ -20,8 +21,15 @@ def install(option, option_string, value, parser):
|
|||
https://docs.python.org/2/library/optparse.html#optparse-option-callbacks
|
||||
"""
|
||||
installer = _INSTALLERS.get(value)
|
||||
installer()
|
||||
errored = False
|
||||
try:
|
||||
installer()
|
||||
except exc.HookInstallationError as hook_error:
|
||||
print(str(hook_error))
|
||||
errored = True
|
||||
raise SystemExit(errored)
|
||||
|
||||
|
||||
def choices():
|
||||
return _INSTALLERS.keys()
|
||||
"""Return the list of VCS choices."""
|
||||
return list(_INSTALLERS.keys())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue