Commit 2aa8a438 authored by Jelmer Vernooij's avatar Jelmer Vernooij

Add support for a certainty tag in fixer output.

parent d25b722f
......@@ -72,3 +72,7 @@ It can include optional metadata in its output::
links to documentation about the fixed lintian tags. In the future,
it may also support building the package to verify the lintian tag
is actually resolved.
* ``Certainty:`` followed by ``certain`` or ``possible``,
indicating how certain the fixer is that the fix was the right
one.
......@@ -2,6 +2,7 @@ lintian-brush (0.6) UNRELEASED; urgency=medium
* useless-autoreconf-build-depends: Actually require changes, don't
just update debhelper build-depends.
* Add support for a certainty tag in fixer output.
-- Jelmer Vernooij <jelmer@debian.org> Mon, 05 Nov 2018 19:31:02 +0000
......
......@@ -19,6 +19,7 @@ def bump_debhelper(control):
control["Build-Depends"],
"dh-autoreconf")
changed = False
outf = StringIO()
with open('debian/rules', 'r') as f:
......
......@@ -44,6 +44,7 @@ from debian.deb822 import Deb822
__version__ = (0, 1)
version_string = '.'.join(map(str, __version__))
SUPPORTED_CERTAINTIES = ['certain', 'possible']
class NoChanges(Exception):
......@@ -54,6 +55,10 @@ class FixerFailed(Exception):
"""Base class for fixer script failures."""
class UnsupportedCertainty(Exception):
"""Unsupported certainty."""
class FixerScriptFailed(FixerFailed):
"""Script failed to run."""
......@@ -89,9 +94,22 @@ class PendingChanges(Exception):
class FixerResult(object):
"""Result of a fixer run."""
def __init__(self, description, fixed_lintian_tags=[]):
def __init__(self, description, fixed_lintian_tags=[],
certainty=None):
self.description = description
self.fixed_lintian_tags = fixed_lintian_tags
self.certainty = certainty
def __repr__(self):
return "%s(%r, fixed_lintian_tags=%r, certainty=%r)" % (
self.description, self.fixed_lintian_tags, self.certainty)
def __eq__(self, other):
if type(other) != type(self):
return False
return ((self.description == other.description) and
(self.fixed_lintian_tags == other.fixed_lintian_tags) and
(self.certainty == other.certainty))
class Fixer(object):
......@@ -146,13 +164,19 @@ class ScriptFixer(Fixer):
description = description.decode('utf-8')
lines = []
fixed_tags = []
certainty = None
for line in description.splitlines():
# TODO(jelmer): Do this in a slighly less hackish manner
if line.startswith('Fixed-Lintian-Tags: '):
fixed_tags = line.split(':', 1)[1].strip().split(',')
(key, value) = line.split(':', 1)
if key == 'Fixed-Lintian-Tags':
fixed_tags = value.strip().split(',')
elif key == 'Certainty':
certainty = value.strip()
else:
lines.append(line)
return FixerResult('\n'.join(lines), fixed_tags)
if certainty not in SUPPORTED_CERTAINTIES:
raise UnsupportedCertainty(certainty)
return FixerResult('\n'.join(lines), fixed_tags, certainty)
def find_fixers_dir():
......@@ -271,7 +295,7 @@ def run_lintian_fixer(local_tree, fixer, committer=None,
committer: Optional committer (name and email)
update_changelog: Whether to add a new entry to the changelog
Returns:
summary of the changes
tuple with set of FixerResult, summary of the changes
"""
# Just check there are no changes to begin with
if list(local_tree.iter_changes(local_tree.basis_tree())):
......@@ -324,7 +348,7 @@ def run_lintian_fixer(local_tree, fixer, committer=None,
reporter=NullCommitReporter(),
committer=committer)
# TODO(jelmer): Run sbuild & verify lintian warning is gone?
return result.fixed_lintian_tags, summary
return result, summary
def run_lintian_fixers(local_tree, fixers, update_changelog=True,
......@@ -339,19 +363,18 @@ def run_lintian_fixers(local_tree, fixers, update_changelog=True,
committer: Optional committer (name and email)
Returns:
Tuple with two lists:
list of tuples with (lintian-tag, description) of fixers that ran
list of script names for fixers that failed to run
list of tuples with (lintian-tag, certainty, description) of fixers
that ran list of script names for fixers that failed to run
"""
failed_fixers = []
fixers = list(fixers)
ret = []
pb = ui.ui_factory.nested_progress_bar()
try:
with ui.ui_factory.nested_progress_bar() as pb:
for i, fixer in enumerate(fixers):
pb.update('Running fixer %r on %s' % (fixer, local_tree.basedir),
i, len(fixers))
try:
fixed_lintian_tags, summary = run_lintian_fixer(
result, summary = run_lintian_fixer(
local_tree, fixer, update_changelog=update_changelog,
committer=committer)
except FixerFailed as e:
......@@ -365,7 +388,5 @@ def run_lintian_fixers(local_tree, fixers, update_changelog=True,
else:
if verbose:
note('Fixer %r made changes.', fixer)
ret.append((fixed_lintian_tags, summary))
finally:
pb.finished()
ret.append((result, summary))
return ret, failed_fixers
......@@ -105,8 +105,8 @@ def main(argv=None):
return 1
if applied:
all_tags = set()
for tags, summary in applied:
all_tags.update(tags)
for result, summary in applied:
all_tags.update(result.fixed_lintian_tags)
note("Lintian tags fixed: %r" % all_tags)
else:
note("No changes made.")
......
......@@ -79,7 +79,7 @@ class DummyFixer(Fixer):
with open(os.path.join(basedir, 'debian/control'), 'a') as f:
f.write('a new line\n')
return FixerResult("Fixed some tag.\nExtended description.",
['some-tag'])
['some-tag'], "certain")
class FailingFixer(Fixer):
......@@ -140,11 +140,12 @@ Arch: all
def test_simple_modify(self):
with self.tree.lock_write():
fixed_tags, summary = run_lintian_fixer(
result, summary = run_lintian_fixer(
self.tree, DummyFixer('dummy', 'some-tag'),
update_changelog=False)
self.assertEqual(summary, "Fixed some tag.")
self.assertEqual(['some-tag'], fixed_tags)
self.assertEqual(['some-tag'], result.fixed_lintian_tags)
self.assertEqual('certain', result.certainty)
self.assertEqual(2, self.tree.branch.revno())
self.assertEqual(
self.tree.get_file_lines('debian/control')[-1],
......@@ -157,11 +158,12 @@ Arch: all
f.write("test")
return FixerResult("Created new file.", ['some-tag'])
with self.tree.lock_write():
fixed_tags, summary = run_lintian_fixer(
result, summary = run_lintian_fixer(
self.tree, NewFileFixer('new-file', 'some-tag'),
update_changelog=False)
self.assertEqual(summary, "Created new file.")
self.assertEqual(['some-tag'], fixed_tags)
self.assertIs(None, result.certainty)
self.assertEqual(['some-tag'], result.fixed_lintian_tags)
rev = self.tree.branch.repository.get_revision(
self.tree.last_revision())
self.assertEqual(rev.message, (
......@@ -185,11 +187,12 @@ Arch: all
return FixerResult("Renamed a file.")
orig_basis_tree = self.tree.branch.basis_tree()
with self.tree.lock_write():
fixed_tags, summary = run_lintian_fixer(
result, summary = run_lintian_fixer(
self.tree, RenameFileFixer('rename', 'some-tag'),
update_changelog=False)
self.assertEqual(summary, "Renamed a file.")
self.assertEqual([], fixed_tags)
self.assertIs(None, result.certainty)
self.assertEqual([], result.fixed_lintian_tags)
self.assertEqual(2, self.tree.branch.revno())
basis_tree = self.tree.branch.basis_tree()
with basis_tree.lock_read(), orig_basis_tree.lock_read():
......@@ -272,7 +275,11 @@ Arch: all
applied, failed = run_lintian_fixers(
self.tree, [DummyFixer('dummy', 'some-tag')],
update_changelog=False)
self.assertEqual([(['some-tag'], 'Fixed some tag.')], applied)
self.assertEqual(
[(FixerResult("Fixed some tag.\nExtended description.",
['some-tag'], 'certain'),
'Fixed some tag.')],
applied)
self.assertEqual([], failed)
self.assertEqual(2, self.tree.branch.revno())
self.assertEqual(
......@@ -302,11 +309,12 @@ Arch: all
def make_change(self, tree, committer=None):
with tree.lock_write():
fixed_tags, summary = run_lintian_fixer(
result, summary = run_lintian_fixer(
tree, DummyFixer('dummy', 'some-tag'),
update_changelog=False, committer=committer)
self.assertEqual(summary, "Fixed some tag.")
self.assertEqual(['some-tag'], fixed_tags)
self.assertEqual(['some-tag'], result.fixed_lintian_tags)
self.assertEqual('certain', result.certainty)
self.assertEqual(2, tree.branch.revno())
self.assertEqual(
tree.get_file_lines('debian/control')[-1],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment