Compare commits
No commits in common. "f8745691ff238427301737ae657f62b9f349a438" and "d51a1c777f40cc3e276a07de662c0ed5e11b4e7a" have entirely different histories.
f8745691ff
...
d51a1c777f
6 changed files with 68 additions and 130 deletions
|
@ -1,15 +0,0 @@
|
||||||
---
|
|
||||||
name: Run tests
|
|
||||||
on: [push]
|
|
||||||
jobs:
|
|
||||||
test-precommit:
|
|
||||||
runs-on: docker
|
|
||||||
container:
|
|
||||||
image: docker.io/brenard/python-pre-commit:latest
|
|
||||||
steps:
|
|
||||||
- name: Check out repository code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Run pre-commit
|
|
||||||
run: pre-commit run --all-files
|
|
|
@ -1,64 +0,0 @@
|
||||||
# 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
|
|
12
.woodpecker.yml
Normal file
12
.woodpecker.yml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
pipeline:
|
||||||
|
test-pylint:
|
||||||
|
group: test
|
||||||
|
image: pipelinecomponents/pylint
|
||||||
|
commands:
|
||||||
|
- pylint check_pip_upgrade
|
||||||
|
|
||||||
|
test-flake8:
|
||||||
|
group: test
|
||||||
|
image: pipelinecomponents/flake8
|
||||||
|
commands:
|
||||||
|
- flake8 check_pip_upgrade
|
|
@ -1,7 +0,0 @@
|
||||||
---
|
|
||||||
extends: default
|
|
||||||
|
|
||||||
rules:
|
|
||||||
line-length:
|
|
||||||
max: 100
|
|
||||||
level: warning
|
|
|
@ -35,6 +35,7 @@ Copyright (c) 2022 Benjamin Renard <brenard@zionetrix.net>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 3 as published by the Free Software Foundation.
|
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 3 as published by the Free Software Foundation.
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
|
@ -18,86 +18,97 @@ along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import logging
|
|
||||||
import os
|
import os
|
||||||
import subprocess # nosec
|
import logging
|
||||||
import sys
|
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
|
||||||
# nagios exit code
|
# nagios exit code
|
||||||
STATUS = {"OK": 0, "WARNING": 1, "CRITICAL": 2, "UNKNOWN": 3}
|
STATUS = {
|
||||||
|
'OK': 0,
|
||||||
|
'WARNING': 1,
|
||||||
|
'CRITICAL': 2,
|
||||||
|
'UNKNOWN': 3
|
||||||
|
}
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("-d", "--debug", action="store_true", dest="debug", default=False)
|
parser.add_argument(
|
||||||
|
'-d', '--debug',
|
||||||
|
action="store_true",
|
||||||
|
dest="debug",
|
||||||
|
default=False
|
||||||
|
)
|
||||||
|
|
||||||
parser.add_argument("-b", "--bin", action="store", dest="bin", help="Python binary path", type=str)
|
parser.add_argument(
|
||||||
|
'-b', '--bin',
|
||||||
|
action="store",
|
||||||
|
dest="bin",
|
||||||
|
help="Python binary path",
|
||||||
|
type=str
|
||||||
|
)
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
action="store",
|
action="store",
|
||||||
dest="packages",
|
dest="packages",
|
||||||
help=("Python package(s) to check. By default, all installed" "packages are checked."),
|
help=(
|
||||||
nargs="*",
|
"Python package(s) to check. By default, all installed"
|
||||||
default=[],
|
"packages are checked."
|
||||||
|
),
|
||||||
|
nargs='*',
|
||||||
|
default=[]
|
||||||
)
|
)
|
||||||
|
|
||||||
options = parser.parse_args()
|
options = parser.parse_args()
|
||||||
|
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
level=logging.DEBUG if options.debug else logging.INFO,
|
level=logging.DEBUG if options.debug else logging.INFO,
|
||||||
format="%(asctime)s - %(levelname)s - %(message)s",
|
format='%(asctime)s - %(levelname)s - %(message)s')
|
||||||
)
|
|
||||||
|
|
||||||
if options.bin and not os.path.exists(options.bin):
|
if options.bin and not os.path.exists(options.bin):
|
||||||
print(f'UNKNOWN - python executable "{options.bin}" not found')
|
print(f'UNKNOWN - python executable "{options.bin}" not found')
|
||||||
sys.exit(STATUS["UNKNOWN"])
|
sys.exit(STATUS['UNKNOWN'])
|
||||||
|
|
||||||
cmd = [
|
cmd = [
|
||||||
options.bin if options.bin else sys.executable,
|
options.bin if options.bin else sys.executable, '-m', 'pip', 'list',
|
||||||
"-m",
|
'--format', 'json', '--outdated'
|
||||||
"pip",
|
|
||||||
"list",
|
|
||||||
"--format",
|
|
||||||
"json",
|
|
||||||
"--outdated",
|
|
||||||
]
|
]
|
||||||
logging.debug("Execute external command: %s", " ".join(cmd))
|
logging.debug('Execute external command: %s', ' '.join(cmd))
|
||||||
output = subprocess.check_output(cmd) # nosec
|
output = subprocess.check_output(cmd)
|
||||||
logging.debug("Output:\n%s", output)
|
logging.debug('Output:\n%s', output)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
outdated_packages = {
|
outdated_packages = dict(
|
||||||
package["name"]: package
|
(package['name'], package)
|
||||||
for package in json.loads(output)
|
for package in json.loads(output)
|
||||||
if not options.packages or package["name"] in options.packages
|
if not options.packages or package['name'] in options.packages
|
||||||
}
|
)
|
||||||
except Exception as exc: # pylint: disable=broad-except
|
except Exception as exc: # pylint: disable=broad-except
|
||||||
print("UNKNOWN - Exception occurred parsing pip output")
|
print('UNKNOWN - Exception occured parsing pip output')
|
||||||
traceback.print_exc(exc)
|
traceback.print_exc(exc)
|
||||||
sys.exit(STATUS["UNKNOWN"])
|
sys.exit(STATUS['UNKNOWN'])
|
||||||
|
|
||||||
if outdated_packages:
|
if outdated_packages:
|
||||||
if len(outdated_packages) > 1:
|
if len(outdated_packages) > 1:
|
||||||
print(f"WARNING - {len(outdated_packages)} upgrades available")
|
print(f'WARNING - {len(outdated_packages)} upgrades available')
|
||||||
print(
|
print('\n'.join([
|
||||||
"\n".join(
|
f' - {name} ({p["version"]} => {p["latest_version"]})'
|
||||||
[
|
for name, p in outdated_packages.items()
|
||||||
f' - {name} ({p["version"]} => {p["latest_version"]})'
|
]))
|
||||||
for name, p in outdated_packages.items()
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
name = next(iter(outdated_packages))
|
name = next(iter(outdated_packages))
|
||||||
p = outdated_packages[name]
|
p = outdated_packages[name]
|
||||||
print(
|
print(
|
||||||
f"WARNING - available upgrade for {name} " f'({p["version"]} => {p["latest_version"]})'
|
f'WARNING - available upgrade for {name} '
|
||||||
|
f'({p["version"]} => {p["latest_version"]})'
|
||||||
)
|
)
|
||||||
sys.exit(STATUS["WARNING"])
|
sys.exit(STATUS['WARNING'])
|
||||||
|
|
||||||
if options.packages and len(options.packages) == 1:
|
if options.packages and len(options.packages) == 1:
|
||||||
print(f"OK - {options.packages[0]} is up-to-date")
|
print(f'OK - {options.packages[0]} is uptodate')
|
||||||
else:
|
else:
|
||||||
print("OK - all packages is up-to-date")
|
print('OK - all packages is uptodate')
|
||||||
sys.exit(STATUS["OK"])
|
sys.exit(STATUS['OK'])
|
||||||
|
|
Loading…
Reference in a new issue