From b28b437fb21233c9d65f9256139b461ca6d59290 Mon Sep 17 00:00:00 2001 From: "Kenneth M. Elf Sternberg" Date: Thu, 29 Sep 2016 15:14:46 -0700 Subject: [PATCH] W00t! Working unit tests to assert things, like "That kind works" and "It doesn't die pathetically," and "It shows stuff." Fix TOX to not include you home directory, so now git_lint will only include your home directory if one exists. It turns out that shutils doesn't have 'which()' prior to Python3. Buggeration. --- git_lint/git_lint.py | 33 ++++++++++-------- tests/test_git_lint.py | 77 ++++++++++++++++++++++++++++++++++-------- tox.ini | 1 - 3 files changed, 81 insertions(+), 30 deletions(-) diff --git a/git_lint/git_lint.py b/git_lint/git_lint.py index 26701ed..634710a 100644 --- a/git_lint/git_lint.py +++ b/git_lint/git_lint.py @@ -44,11 +44,11 @@ def find_config_file(options, base): sys.exit(_('Configuration file not found: {}\n').format(config)) return configpath - home = os.environ.get('HOME') - possibles = (os.path.join(base, '.git-lint'), - os.path.join(base, '.git-lint/config'), - os.path.join(home, '.git-lint'), - os.path.join(home, '.git-lint/config')) + home = os.environ.get('HOME', None) + possibles = [os.path.join(base, '.git-lint'), + os.path.join(base, '.git-lint/config')] + ((home and [ + os.path.join(home, '.git-lint'), + os.path.join(home, '.git-lint/config')]) or []) matches = [p for p in possibles if os.path.isfile(p)] if len(matches) == 0: @@ -157,14 +157,14 @@ class MatchFilter: def __call__(self, path): return self.matcher.search(path) - + @staticmethod def make_match_filter_matcher(extensions): trimmed = [s.strip() for s in reduce(operator.add, [ex.split(',') for ex in extensions], [])] cleaned = [re.sub(r'^\.', '', s) for s in trimmed] return re.compile(r'\.' + '|'.join(cleaned) + r'$') - + # ___ _ _ _ _ _ # / __| |_ ___ __| |__ | (_)_ _| |_ ___ _ _ ___ @@ -188,7 +188,12 @@ def executable_exists(script, label): if scriptname.startswith('/'): return (is_executable(scriptname) and scriptname) or None - return shutil.which(scriptname) + possibles = [path for path in + [os.path.join(path, scriptname) + for path in os.environ.get('PATH').split(':')] + if is_executable(path)] + + return (len(possibles) and possibles.pop(0)) or False def get_working_linter_names(config): @@ -220,8 +225,8 @@ def get_filelist(options, extras): if os.path.samefile(os.getcwd(), git_base): return base_file_filter(filenames) gitcwd = os.path.join(os.path.relpath(os.getcwd(), git_base), '') - return base_file_filter([file for file in files - if file.startswith(gitcwd)]) + return base_file_filter([filename for filename in filenames + if filename.startswith(gitcwd)]) def check_for_conflicts(filesets): """ Scan list of porcelain files for merge conflic state. """ @@ -372,17 +377,17 @@ class Linters: trimmed_filename = filename.replace(git_base + '/', '', 1) if not failed: return (trimmed_filename, linter_name, 0, []) - + prefix = (((linter.get('print', 'false').strip().lower() != 'true') and ' ') or ' {}: '.format(trimmed_filename)) output = (Linters.encode_shell_messages(prefix, out) + ((err and Linters.encode_shell_messages(prefix, err)) or [])) return (trimmed_filename, linter_name, (returncode or 1), output) - + @staticmethod def run_one_linter(linter, filenames): """ Runs one linter against a set of files - + Creates a match filter for the linter, extract the files to be linted, and runs the linter against each file, returning the result as a list of successes and failures. Failures have a @@ -411,7 +416,7 @@ class Linters: match_filter = MatchFilter([linter]) files_to_check = [filename for filename in filenames if match_filter(filename)] return [dryrunonefile(filename, linter) for filename in files_to_check] - + return reduce(operator.add, [dryrunonce(linter, self.filenames) for linter in self.linters], []) diff --git a/tests/test_git_lint.py b/tests/test_git_lint.py index d63c920..81bdb2a 100644 --- a/tests/test_git_lint.py +++ b/tests/test_git_lint.py @@ -15,6 +15,7 @@ import os import shutil import subprocess import pprint +import tempfile from git_lint import git_lint environment = copy.copy(os.environ) @@ -37,24 +38,70 @@ for key in ['XDF_CONFIG_HOME', 'GITPERLLIB', 'CDPATH', environment.pop(key, None) -class TestGit_lint(object): +git_lint_src = """ +[pep8] +comment = PEP8 with some white space and line length checking turned off +output = Running pep8... +command = pep8 -r --ignore=E501,W293,W391 +match = .py +print = False +condition = error +""" - @classmethod - def setup_class(cls): - if os.path.exists('t'): - shutil.rmtree('t') - os.mkdir('t') - shutil.copy('.git-lint', 't') - os.chdir('t') - subprocess.check_output('git init', shell=True, env=environment) +# Basic TOX settings aren't good enough: we need to have something more or less guaranteed +# to not have a '.git' directory somewhere lurking in a parent folder. + +class gittemp: + def __enter__(self): + self.cwd = os.getcwd() + self.path = tempfile.mkdtemp() + return self.path + + def __exit__(self, *args): + os.chdir(self.cwd) + shutil.rmtree(self.path) - def test_itruns(self): +def test_01_not_a_repository(): + with gittemp() as path: + os.chdir(path) + p = subprocess.Popen('git lint', shell=True, env=environment, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + (stdout, stderr) = p.communicate() + assert stderr.startswith('A git repository was not found') + + +def test_02_empty_repository(): + with gittemp() as path: + os.chdir(path) + subprocess.check_call('git init', shell=True, env=environment) + p = subprocess.Popen('git lint -l', shell=True, env=environment, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + (stdout, stderr) = p.communicate() + assert stderr.startswith('No configuration file found,') + + +def test_03_simple_repository(): + with gittemp() as path: + os.chdir(path) + with open(".git-lint", "w") as f: + f.write(git_lint_src) + subprocess.check_call('git init', shell=True, env=environment) + subprocess.check_call('git add .', shell=True, env=environment) + subprocess.check_call('git commit -m "Test."', shell=True, env=environment) ret = subprocess.check_output('git lint -v', shell=True, env=environment) - assert ret.startswith('git-lint') + assert ret.index('Copyright') > 0 - @classmethod - def teardown_class(cls): - os.chdir('..') - shutil.rmtree('t') +def test_04_linters_present(): + with gittemp() as path: + os.chdir(path) + with open(".git-lint", "w") as f: + f.write(git_lint_src) + subprocess.check_call('git init', shell=True, env=environment) + subprocess.check_call('git add .', shell=True, env=environment) + subprocess.check_call('git commit -m "Test."', shell=True, env=environment) + ret = subprocess.check_output('git lint -l', shell=True, env=environment) + assert len(ret.split("\n")) == 3 + assert ret.index('pep8') > 0 + diff --git a/tox.ini b/tox.ini index 17e929c..dea556a 100644 --- a/tox.ini +++ b/tox.ini @@ -8,7 +8,6 @@ deps = -r{toxinidir}/requirements_dev.txt commands = py.test --basetemp={envtmpdir} -passenv = HOME ; If you want to make tox run the tests with the same versions, create a