Commit bdd55484 authored by Jelmer Vernooij's avatar Jelmer Vernooij

Don't complain about reformatting issues if no changes have been made.

parent ea0ec1dc
Pipeline #63861 canceled with stages
......@@ -7,6 +7,8 @@ lintian-brush (0.22) UNRELEASED; urgency=medium
* Add fixer for debian-watch-file-uses-deprecated-githubredir.
* Don't attempt to upgrade cdbs packages to anything over debhelper
10.
* Don't complain about reformatting issues if no changes have been
made.
-- Jelmer Vernooij <jelmer@debian.org> Sat, 10 Aug 2019 16:49:28 +0000
......
......@@ -27,7 +27,7 @@ from ._deb822 import PkgRelation
from .reformatting import (
check_generated_file,
check_preserve_formatting,
edit_formatted_file,
)
......@@ -35,6 +35,25 @@ class FormattingUnpreservable(Exception):
"""Formatting unpreservable."""
def dump_paragraphs(paragraphs):
"""Dump a set of deb822 paragraphs to a file.
Args:
paragraphs: iterable over paragraphs
Returns:
formatted text (as bytes)
"""
outf = BytesIO()
first = True
for paragraph in paragraphs:
if paragraph:
if not first:
outf.write(b'\n')
paragraph.dump(fd=outf, encoding='utf-8')
first = False
return outf.getvalue()
def reformat_deb822(contents):
"""Check whether it's possible to preserve a control file.
......@@ -43,12 +62,8 @@ def reformat_deb822(contents):
Returns:
New contents
"""
outf = BytesIO()
for paragraph in Deb822.iter_paragraphs(BytesIO(contents),
encoding='utf-8'):
paragraph.dump(fd=outf, encoding='utf-8')
outf.write(b'\n')
return outf.getvalue()
return dump_paragraphs(
Deb822.iter_paragraphs(BytesIO(contents), encoding='utf-8'))
def update_control(path='debian/control', **kwargs):
......@@ -68,17 +83,11 @@ def update_control(path='debian/control', **kwargs):
with open(path, 'rb') as f:
original_contents = f.read()
rewritten_contents = reformat_deb822(original_contents)
check_preserve_formatting(
rewritten_contents.strip(), original_contents.strip(),
path)
outf = BytesIO()
update_control_file(BytesIO(original_contents), outf, **kwargs)
updated_contents = outf.getvalue()
if updated_contents.strip() != original_contents.strip():
with open(path, 'wb') as f:
f.write(updated_contents)
return True
return False
return edit_formatted_file(
path, original_contents, rewritten_contents, updated_contents)
def update_control_file(inf, outf, source_package_cb=None,
......@@ -94,7 +103,7 @@ def update_control_file(inf, outf, source_package_cb=None,
source_package_cb: Called on source package paragraph (optional)
binary_package_cb: Called on each binary package paragraph (optional)
"""
first = True
paragraphs = []
for paragraph in Deb822.iter_paragraphs(inf, encoding='utf-8'):
if paragraph.get("Source"):
if source_package_cb is not None:
......@@ -102,11 +111,8 @@ def update_control_file(inf, outf, source_package_cb=None,
else:
if binary_package_cb is not None:
binary_package_cb(paragraph)
if paragraph:
if not first:
outf.write(b'\n')
paragraph.dump(fd=outf, encoding='utf-8')
first = False
paragraphs.append(paragraph)
outf.write(dump_paragraphs(paragraphs))
def parse_relations(text):
......
......@@ -27,25 +27,19 @@ from debian.copyright import (
NotMachineReadableError,
)
from .reformatting import check_preserve_formatting
from .reformatting import edit_formatted_file
def update_copyright(update_cb):
with open('debian/copyright', 'r') as f:
def update_copyright(update_cb, path='debian/copyright'):
with open(path, 'r') as f:
orig_content = f.read()
copyright = Copyright(orig_content)
rewritten_content = copyright.dump()
check_preserve_formatting(
rewritten_content.rstrip('\n'), orig_content.rstrip('\n'),
'debian/copyright')
update_cb(copyright)
new_content = copyright.dump()
updated_content = copyright.dump()
if new_content.rstrip('\n') != rewritten_content.rstrip('\n'):
with open('debian/copyright', 'w') as f:
f.write(new_content)
return True
return False
return edit_formatted_file(
path, orig_content, rewritten_content, updated_content)
......@@ -15,7 +15,11 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
__all__ = ['check_preserve_formatting', 'check_generated_file']
__all__ = [
'check_preserve_formatting',
'check_generated_file',
'edit_formatted_file',
]
import os
......@@ -73,3 +77,29 @@ def check_generated_file(path):
return
if b"DO NOT EDIT" in original_contents:
raise GeneratedFile(path)
def edit_formatted_file(
path, original_contents, rewritten_contents,
updated_contents):
"""Edit a formatted file.
Args:
path: path to the file
original_contents: The original contents of the file
rewritten_contents: The contents rewritten with our parser/serializer
updated_contents: Updated contents rewritten with our parser/serializer
after changes were made.
"""
if type(updated_contents) != type(rewritten_contents):
raise TypeError('inconsistent types: %r, %r' % (
type(updated_contents), type(rewritten_contents)))
if updated_contents in (rewritten_contents, original_contents):
return False
check_preserve_formatting(
rewritten_contents.strip(),
original_contents.strip(), path)
mode = 'w' + ('b' if isinstance(updated_contents, bytes) else '')
with open(path, mode) as f:
f.write(updated_contents)
return True
......@@ -22,9 +22,12 @@ from breezy.tests import (
TestCaseWithTransport,
)
from debian.deb822 import Deb822
from lintian_brush.control import (
add_dependency,
drop_dependency,
dump_paragraphs,
ensure_exact_version,
ensure_minimum_version,
ensure_some_version,
......@@ -52,7 +55,6 @@ Testsuite: autopkgtest
"""), b"""\
Source: blah
Testsuite: autopkgtest
""")
def test_fine(self):
......@@ -67,6 +69,31 @@ Testsuite: autogpktest
""")
class DumpParagraphsTests(TestCase):
def test_simple(self):
self.assertEqual(dump_paragraphs([Deb822({
'Source': 'blah',
'Testsuite': 'autopkgtest'
})]), b"""\
Source: blah
Testsuite: autopkgtest
""")
def test_multi(self):
self.assertEqual(dump_paragraphs([
Deb822({
'Source': 'blah',
'Testsuite': 'autopkgtest'
}),
Deb822({'Package': 'bloe'})]), b"""\
Source: blah
Testsuite: autopkgtest
Package: bloe
""")
class UpdateControlTests(TestCaseWithTransport):
def test_do_not_edit(self):
......@@ -87,7 +114,12 @@ Source: blah
Testsuite: autopkgtest
""")])
self.assertRaises(FormattingUnpreservable, update_control)
def update_source(control):
control["NewField"] = "New Field"
self.assertRaises(
FormattingUnpreservable, update_control,
source_package_cb=update_source)
def test_modify_source(self):
self.build_tree_contents([('debian/', ), ('debian/control', """\
......
......@@ -48,7 +48,10 @@ Files: *
License: GPL
Copyright: 2012...
""")])
self.assertRaises(FormattingUnpreservable, update_copyright, None)
def dummy(cb):
cb.header.upstream_name = 'llintian-brush'
self.assertRaises(FormattingUnpreservable, update_copyright, dummy)
def test_old_style(self):
self.build_tree_contents([('debian/', ), ('debian/copyright', """\
......
......@@ -26,6 +26,7 @@ from lintian_brush.reformatting import (
FormattingUnpreservable,
check_generated_file,
check_preserve_formatting,
edit_formatted_file,
GeneratedFile,
)
......@@ -70,3 +71,31 @@ Testsuite: autopkgtest
""")])
self.assertRaises(
GeneratedFile, check_generated_file, 'debian/control')
class EditFormattedFileTests(TestCaseWithTransport):
def test_unchanged(self):
self.build_tree_contents([('a', 'some content\n')])
self.assertFalse(edit_formatted_file(
'a', 'some content\n', 'some content reformatted\n',
'some content\n'))
self.assertFalse(edit_formatted_file(
'a', 'some content\n', 'some content\n',
'some content\n'))
self.assertFalse(edit_formatted_file(
'a', 'some content\n', 'some content reformatted\n',
'some content reformatted\n'))
def test_changed(self):
self.build_tree_contents([('a', 'some content\n')])
self.assertTrue(edit_formatted_file(
'a', 'some content\n', 'some content\n',
'new content\n'))
self.assertFileEqual('new content\n', 'a')
def test_unformattable(self):
self.assertRaises(
FormattingUnpreservable, edit_formatted_file,
'a', 'some content\n', 'reformatted content\n',
'new content\n')
......@@ -22,7 +22,7 @@ import re
from lintian_brush.reformatting import (
check_generated_file,
check_preserve_formatting,
edit_formatted_file,
)
......@@ -179,17 +179,12 @@ def update_watch(update_entry=None, path='debian/watch'):
wf = parse_watch_file(original_contents.splitlines())
nf = StringIO()
wf.dump(nf)
check_preserve_formatting(
nf.getvalue().strip(), original_contents.strip(),
path)
rewritten_contents = nf.getvalue()
for entry in wf.entries:
if update_entry is not None:
update_entry(entry)
nf = StringIO()
wf.dump(nf)
updated_contents = nf.getvalue()
if updated_contents.strip() != original_contents.strip():
with open(path, 'w') as f:
f.write(updated_contents)
return True
return False
return edit_formatted_file(
path, original_contents, rewritten_contents, updated_contents)
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