From 80b467d9def50a58e243b53edb260fc01fbe6165 Mon Sep 17 00:00:00 2001 From: Bertrand Benjamin Date: Sun, 16 Aug 2020 10:06:14 +0200 Subject: [PATCH] Feat: add hooks --- hooks/pre-commit | 143 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100755 hooks/pre-commit diff --git a/hooks/pre-commit b/hooks/pre-commit new file mode 100755 index 0000000..642969d --- /dev/null +++ b/hooks/pre-commit @@ -0,0 +1,143 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# vim:fenc=utf-8 +# +# Copyright © 2017 lafrite +# +# Distributed under terms of the MIT license. + +""" +Git hook to ensure validity of all rst files +""" + +from git import Repo +from pathlib import Path +import re +import time +import restructuredtext_lint +import sys + +import logging + +formatter = logging.Formatter('%(name)s :: %(levelname)s :: %(message)s') +steam_handler = logging.StreamHandler() +#steam_handler = logging.FileHandler('logging.conf') +steam_handler.setLevel(logging.DEBUG) +steam_handler.setFormatter(formatter) + +# création de l'objet logger qui va nous servir à écrire dans les logs +logger = logging.getLogger("precommit") +# on met le niveau du logger à DEBUG, comme ça il écrit tout +logger.setLevel(logging.WARNING) +logger.addHandler(steam_handler) + +# Files selection + +def get_commited_files(repo): + hdiff = repo.head.commit.diff() + diff = {"A":[], "M":[]} + for f in hdiff.iter_change_type("A"): + diff["A"].append(f.b_path) + for f in hdiff.iter_change_type("M"): + diff["M"].append(f.b_path) + + return diff + +def select_by_extension(files, ext="rst"): + return [i for i in files if i.split(".")[-1] == ext] + +# Rst linter + +def rst_lint(filename): + with open(filename, 'r') as f: + errors = restructuredtext_lint.lint(f.read()) + for e in errors: + logger.warning(f"{filename} \n{e.full_message}\n") + return errors + + +# Rst parameters normalize + +def normalize_file(filename, normalizers = {}): + logger.debug(f"Normalizing {filename}") + logger.debug(f"With {normalizers}") + new_file = "" + modified_lines = [] + with open(filename, 'r') as f: + for l in f.readlines(): + new_line = run_normalizers(l, normalizers) + if new_line != l: + modified_lines.append(f"{l}") + logger.warning(f"{filename}\n\t{l}\t{new_line}") + new_file += new_line + + with open(filename, "w") as f: + f.write(new_file) + logger.debug(f"{filename} written") + + return modified_lines + +def run_normalizers(line, normalizers): + for c in normalizers: + obs = re.search(c, line) + if obs: + logger.debug(f"Find for {c}") + return normalizers[c](line) + return line + +# Rst function tools + +def update_date(line): + date = time.strftime("%Y-%m-%d") + logger.debug(f"Update Date to: {date}") + return f":date: {date}\n" + +def update_modified(line): + modified = time.strftime("%Y-%m-%d") + logger.debug(f"Update modified to: {modified}") + return f":modified: {modified}\n" + +def normalize_tags(line): + logger.debug(f"Normaizing tags") + tags = line.split(":")[-1] + tags = [i.strip().capitalize() for i in tags.split(",")] + tags_str = ", ".join(tags) + return f":tags: {tags_str}\n" + +NORMALIZERS_MODIFIED = {":modified:.*": update_modified, + ":tags:.*": normalize_tags, + } + +NORMALIZERS_NEW = {":date:.*": update_date, + ":modified:.*": update_modified, + ":tags:.*": normalize_tags, + } + +if __name__ == "__main__": + r = Repo() + diff = get_commited_files(r) + + errors = [] + modified = [] + + # New files + for f in select_by_extension(diff["A"], "rst"): + errors += rst_lint(f) + modified += normalize_file(f, NORMALIZERS_NEW) + r.index.add([f]) + # Modified files + for f in select_by_extension(diff["M"], "rst"): + errors += rst_lint(f) + modified += normalize_file(f, NORMALIZERS_MODIFIED) + r.index.add([f]) + + if len(errors) > 0: + logger.warning("Errors in rst formating, commit aborted") + sys.exit(1) + + + +# ----------------------------- +# Reglages pour 'vim' +# vim:set autoindent expandtab tabstop=4 shiftwidth=4: +# cursor: 16 del