Introduce pre-commit hooks

This commit is contained in:
Benjamin Renard 2024-03-13 23:37:29 +01:00
parent d7d54cb25f
commit f4f87fccd3
5 changed files with 112 additions and 83 deletions

64
.pre-commit-config.yaml Normal file
View file

@ -0,0 +1,64 @@
# Pre-commit hooks to run tests and ensure code is cleaned.
# See https://pre-commit.com for more information
---
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.6
hooks:
- id: ruff
args: ["--fix"]
- repo: https://github.com/asottile/pyupgrade
rev: v3.15.0
hooks:
- id: pyupgrade
args: ["--keep-percent-format", "--py37-plus"]
- repo: https://github.com/psf/black
rev: 23.11.0
hooks:
- id: black
args: ["--target-version", "py37", "--line-length", "100"]
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort
args: ["--profile", "black", "--line-length", "100"]
- repo: https://github.com/PyCQA/flake8
rev: 6.1.0
hooks:
- id: flake8
args: ["--max-line-length=100"]
- repo: https://github.com/codespell-project/codespell
rev: v2.2.2
hooks:
- id: codespell
args:
- --ignore-words-list=exten
- --skip="./.*,*.csv,*.json,*.ini,*.subject,*.txt,*.html,*.log,*.conf"
- --quiet-level=2
- --ignore-regex=.*codespell-ignore$
# - --write-changes # Uncomment to write changes
exclude_types: [csv, json]
- repo: https://github.com/adrienverge/yamllint
rev: v1.32.0
hooks:
- id: yamllint
ignore: .github/
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v2.7.1
hooks:
- id: prettier
args: ["--print-width", "100"]
- repo: local
hooks:
- id: pylint
name: pylint
entry: pylint
language: system
types: [python]
require_serial: true
- repo: https://github.com/PyCQA/bandit
rev: 1.7.5
hooks:
- id: bandit
args: [--skip, "B101", --recursive]
minimum_pre_commit_version: 3.2.0

View file

@ -23,7 +23,7 @@ pipeline:
commands: commands:
- echo "$GPG_KEY"|base64 -d|gpg --import - echo "$GPG_KEY"|base64 -d|gpg --import
- ./build.sh --quiet - ./build.sh --quiet
secrets: [ maintainer_name, maintainer_email, gpg_key, debian_codename ] secrets: [maintainer_name, maintainer_email, gpg_key, debian_codename]
publish-dryrun: publish-dryrun:
group: publish group: publish

View file

@ -1,10 +1,10 @@
# OpenLDAP tool to check CRC32 of LDIF files of slapd.d directory # OpenLDAP tool to check CRC32 of LDIF files of slapd.d directory
This script permit to check (and eventually fix) CRC32 value of the LDIF files of OpenLDAP slapd.d configuration directory. This script permit to check (and eventually fix) CRC32 value of the LDIF files of OpenLDAP slapd.d configuration directory.
## Requirements ## Requirements
This script only used common __python3__ modules _(no additionnal package to install on Debian based systems)_. This script only used common **python3** modules _(no additional package to install on Debian based systems)_.
## Installation ## Installation
@ -43,4 +43,3 @@ This program is free software; you can redistribute it and/or modify it under th
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

View file

@ -24,7 +24,7 @@ sed -i "s/^version *=.*$/version = '$VERSION'/" $BDIR/check_slapdd_crc32
if [ -z "$DEBIAN_CODENAME" ] if [ -z "$DEBIAN_CODENAME" ]
then then
echo "Retreive debian codename using lsb_release..." echo "Retrieve debian codename using lsb_release..."
DEBIAN_CODENAME=$( lsb_release -c -s ) DEBIAN_CODENAME=$( lsb_release -c -s )
else else
echo "Use debian codename from environment ($DEBIAN_CODENAME)" echo "Use debian codename from environment ($DEBIAN_CODENAME)"

View file

@ -10,54 +10,37 @@ import os
import re import re
import sys import sys
version = '0.0' version = "0.0"
default_slapdd_path = '/etc/ldap/slapd.d' default_slapdd_path = "/etc/ldap/slapd.d"
# Main # Main
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(description=f"{__doc__} (version: {version})")
description=f'{__doc__} (version: {version})'
parser.add_argument("-d", "--debug", action="store_true", help="Show debug messages")
parser.add_argument("-v", "--verbose", action="store_true", help="Show verbose messages")
parser.add_argument(
"-l", "--log-file", action="store", type=str, dest="logfile", help="Log file path"
) )
parser.add_argument( parser.add_argument(
'-d', '--debug', "-C",
action='store_true', "--console",
help='Show debug messages' action="store_true",
help="Also log on console (even if log file is provided)",
) )
parser.add_argument( parser.add_argument("-f", "--fix", action="store_true", help="Fix CRC32 value in LDIF files")
'-v', '--verbose',
action='store_true',
help='Show verbose messages'
)
parser.add_argument( parser.add_argument(
'-l', "-p",
'--log-file', "--path",
action="store", action="store",
type=str, type=str,
dest="logfile", dest="slapdd_path",
help="Log file path" help=f"Default slapd.d directory path (default: {default_slapdd_path}",
) default=default_slapdd_path,
parser.add_argument(
'-C', '--console',
action='store_true',
help='Also log on console (even if log file is provided)'
)
parser.add_argument(
'-f', '--fix',
action='store_true',
help='Fix CRC32 value in LDIF files'
)
parser.add_argument(
'-p', '--path',
action='store',
type=str,
dest='slapdd_path',
help=f'Default slapd.d directory path (default: {default_slapdd_path}',
default=default_slapdd_path
) )
@ -66,8 +49,8 @@ options = parser.parse_args()
# Initialize log # Initialize log
log = logging.getLogger() log = logging.getLogger()
logformat = logging.Formatter( logformat = logging.Formatter(
f'%(asctime)s - {os.path.basename(sys.argv[0])} - %(levelname)s - ' f"%(asctime)s - {os.path.basename(sys.argv[0])} - %(levelname)s - " "%(message)s"
'%(message)s') )
if options.debug: if options.debug:
log.setLevel(logging.DEBUG) log.setLevel(logging.DEBUG)
@ -99,50 +82,33 @@ def check_file(dir_path, file_name):
lines = [] lines = []
current_crc32 = None current_crc32 = None
try: try:
with open(path, 'rb') as fd: with open(path, "rb") as fd:
for line in fd.readlines(): for line in fd.readlines():
if line.startswith( if line.startswith(b"# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify."):
b'# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify.' logging.debug("%s: AUTO-GENERATED line detected, pass (%s)", path, line)
):
logging.debug(
'%s: AUTO-GENERATED line detected, pass (%s)',
path, line)
continue continue
if line.startswith(b'# CRC32 '): if line.startswith(b"# CRC32 "):
logging.debug( logging.debug(
'%s: CRC32 line detected, retreive current CRC32 ' "%s: CRC32 line detected, retrieve current CRC32 value (%s)", path, line
'value (%s)', )
path, line) current_crc32 = re.match("^# CRC32 (.*)$", line.decode()).group(1)
current_crc32 = re.match( logging.debug('%s: current CRC32 found is "%s"', path, current_crc32)
'^# CRC32 (.*)$', line.decode()
).group(1)
logging.debug(
'%s: current CRC32 found is "%s"',
path, current_crc32)
continue continue
lines.append(line) lines.append(line)
except IOError as err: except OSError as err:
logging.error('%s: fail to read file content (%s)', path, err) logging.error("%s: fail to read file content (%s)", path, err)
return False return False
# pylint: disable=consider-using-f-string # pylint: disable=consider-using-f-string
crc32 = ( crc32 = ("%08X" % ((binascii.crc32(b"".join(lines)) & 0xFFFFFFFF) % (1 << 32))).lower()
"%08X" % (
(binascii.crc32(b"".join(lines)) & 0xFFFFFFFF) % (1 << 32)
)
).lower()
if current_crc32: if current_crc32:
if current_crc32 == crc32: if current_crc32 == crc32:
log.info('%s: current CRC32 value is correct (%s)', path, crc32) log.info("%s: current CRC32 value is correct (%s)", path, crc32)
else: else:
log.warning( log.warning("%s: invalid CRC32 value found (%s != %s)", path, current_crc32, crc32)
'%s: invalid CRC32 value found (%s != %s)',
path, current_crc32, crc32)
fix_crc32(path, crc32, lines) fix_crc32(path, crc32, lines)
else: else:
log.warning( log.warning('%s: no CRC32 value found. Correct CRC32 value is "%s".', path, crc32)
'%s: no CRC32 value found. Correct CRC32 value is "%s".',
path, crc32)
fix_crc32(path, crc32, lines) fix_crc32(path, crc32, lines)
return True return True
@ -159,14 +125,14 @@ def fix_crc32(path, crc32, lines):
return True return True
try: try:
headers_lines = [ headers_lines = [
b'# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify.\n', b"# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify.\n",
b'# CRC32 ' + crc32.encode() + b'\n', b"# CRC32 " + crc32.encode() + b"\n",
] ]
with open(path, 'wb') as fd: with open(path, "wb") as fd:
for line in headers_lines + lines: for line in headers_lines + lines:
fd.write(line) fd.write(line)
except IOError as err: except OSError as err:
logging.error('%s: fail to write new file content (%s)', path, err) logging.error("%s: fail to write new file content (%s)", path, err)
return False return False
return True return True
@ -174,8 +140,8 @@ def fix_crc32(path, crc32, lines):
log.info('Checking CRC32 in slapd directory "%s"', options.slapdd_path) log.info('Checking CRC32 in slapd directory "%s"', options.slapdd_path)
for dirpath, dnames, fnames in os.walk(options.slapdd_path): for dirpath, dnames, fnames in os.walk(options.slapdd_path):
log.debug( log.debug(
'%s: sub-dirs = "%s", files = "%s"', '%s: sub-dirs = "%s", files = "%s"', dirpath, '", "'.join(dnames), '", "'.join(fnames)
dirpath, '", "'.join(dnames), '", "'.join(fnames)) )
for fname in fnames: for fname in fnames:
if fname.endswith('.ldif'): if fname.endswith(".ldif"):
check_file(dirpath, fname) check_file(dirpath, fname)