Commit 60c35890 authored by Dom Sekotill's avatar Dom Sekotill
Browse files

Add support for dependency files and skipping pip

parent 1e38a7bc
Loading
Loading
Loading
Loading
+67 −8
Original line number Diff line number Diff line
@@ -3,13 +3,25 @@ Run pylint from pre-commit with project dependencies installed
"""

import argparse
import hashlib
import subprocess
from pathlib import Path

from pylint import lint

__version__ = '0.2'


HASH_FILE = Path(__file__).parent / 'hash.txt'

TRY_DEP_FILES = [
	Path.cwd() / 'pyproject.toml',
	Path.cwd() / 'setup.py',
	Path.cwd() / 'setup.cfg',
	Path.cwd() / 'requirements.txt',
]


def argument_parser():
	parser = argparse.ArgumentParser(description=__doc__)
	parser.add_argument(
@@ -18,12 +30,14 @@ def argument_parser():
		help="The names of optional requirements sets to install",
	)
	parser.add_argument(
		'--cache-file', '-c',
		'--dependencies-file', '-d',
		dest='dep_files',
		action='append',
		help="""
		The names of files to use for keying the environment cache: if these files change 
		a new environment is created. Defaults to any that exist of the following:
		pyproject.toml, setup.py, setup.cfg, requirements.txt
		The names of files to hash to check for updates: if these files change the 
		dependencies are updated. Defaults to any that exist of the following:
		pyproject.toml, setup.py, setup.cfg, requirements.txt.  This option can be provided 
		multiple times.
		""",
	)
	parser.add_argument(
@@ -32,7 +46,7 @@ def argument_parser():
		type=float,
		help="""
		If the score is below the given threshold a non-zero exit code will be returned
		"""
		""",
	)
	parser.add_argument(
		'files',
@@ -42,9 +56,47 @@ def argument_parser():
	return parser


def main():
	ap = argument_parser()
	opts = ap.parse_args()
def find_dep_files(opts):
	if opts.dep_files:
		opts.dep_files.sort()
		for filename in opts.dep_files:
			path = Path(filename)
			if not path.exists():
				raise FileNotFoundError(path)
			yield path
	else:
		for path in TRY_DEP_FILES:
			if path.exists():
				yield path


def check_deps(opts) -> bool:
	"""
	Check for possible changes to the dependencies, return True if a re-install is suggested
	"""
	# Generate a check hash from all/any dependencies files
	hash = hashlib.sha256()
	for path in find_dep_files(opts):
		with path.open('rb') as file:
			hash.update(file.read())
	else:
		# Nothing found to hashing
		return True

	digest = hash.hexdigest()
	with HASH_FILE.open('a+') as file:
		file.seek(0)
		if digest == file.read().strip():
			return False
		file.seek(0)
		file.truncate()
		file.write(digest)

	return True

def install_deps(opts):
	if not check_deps(opts):
		return

	join = ','.join
	cmd = [
@@ -56,6 +108,13 @@ def main():
	if proc.returncode:
		ap.exit(3, proc.stdout)


def main():
	ap = argument_parser()
	opts = ap.parse_args()

	install_deps(opts, ap)

	run = lint.Run(opts.files, do_exit=False)
	score = run.linter.stats['global_note']