Skip to content

Commit

Permalink
[pkg_deb] Fix multiline fields in changes file (#691)
Browse files Browse the repository at this point in the history
* fix multiline fields in changes files

* multiline is an enum now
  • Loading branch information
Homulvas authored Jun 5, 2023
1 parent ec4ad13 commit 5932519
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 17 deletions.
40 changes: 27 additions & 13 deletions pkg/private/deb/make_deb.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"""A simple cross-platform helper to create a debian package."""

import argparse
from enum import Enum
import gzip
import hashlib
import io
Expand All @@ -30,6 +31,8 @@

from pkg.private import helpers

Multiline = Enum('Multiline', ['NO', 'YES', 'YES_ADD_NEWLINE'])

# list of debian fields : (name, mandatory, is_multiline[, default])
# see http://www.debian.org/doc/debian-policy/ch-controlfields.html

Expand Down Expand Up @@ -118,7 +121,7 @@ def AddArFileEntry(fileobj, filename,
fileobj.write(b'\n') # 2-byte alignment padding


def MakeDebianControlField(name: str, value: str, is_multiline:bool=False) -> str:
def MakeDebianControlField(name: str, value: str, multiline:Multiline=Multiline.NO) -> str:
"""Add a field to a debian control file.
https://www.debian.org/doc/debian-policy/ch-controlfields.html#syntax-of-control-files
Expand All @@ -132,15 +135,20 @@ def MakeDebianControlField(name: str, value: str, is_multiline:bool=False) -> st
if isinstance(value, list):
value = u', '.join(value)
value = value.rstrip()
if not is_multiline:
if multiline == Multiline.NO:
value = value.strip()
if '\n' in value:
raise ValueError(
'\\n is not allowed in simple control fields (%s)' % value)

lines = value.split('\n')
result = name + ': ' +lines[0].strip() + '\n'
for line in lines[1:]:
i = 0
if multiline != Multiline.YES_ADD_NEWLINE:
result = name + ': ' + lines[i].strip() + '\n'
i = 1
else:
result = name + ':\n'
for line in lines[i:]:
if not line.startswith(' '):
result += ' '
result += line
Expand All @@ -155,10 +163,10 @@ def CreateDebControl(extrafiles=None, **kwargs):
for values in DEBIAN_FIELDS:
fieldname = values[0]
mandatory = values[1]
is_multiline = values[2]
multiline = Multiline.YES if values[2] else Multiline.NO
key = fieldname[0].lower() + fieldname[1:].replace('-', '')
if mandatory or (key in kwargs and kwargs[key]):
controlfile += MakeDebianControlField(fieldname, kwargs[key], is_multiline)
controlfile += MakeDebianControlField(fieldname, kwargs[key], multiline)
# Create the control.tar file
tar = io.BytesIO()
with gzip.GzipFile('control.tar.gz', mode='w', fileobj=tar, mtime=0) as gz:
Expand Down Expand Up @@ -290,21 +298,27 @@ def CreateChanges(output,
MakeDebianControlField('Maintainer', maintainer),
MakeDebianControlField('Changed-By', maintainer),
# The description in the changes file is strange
'Description:\n %s - %s\n' % (package, description.split('\n')[0]),
MakeDebianControlField('Description', (
'%s - %s\n') % (
package, description.split('\n')[0]),
multiline=Multiline.YES_ADD_NEWLINE),
MakeDebianControlField('Changes', (
'\n %s (%s) %s; urgency=%s'
'%s (%s) %s; urgency=%s'
'\n Changes are tracked in revision control.') % (
package, version, distribution, urgency),
is_multiline=True),
multiline=Multiline.YES_ADD_NEWLINE),
MakeDebianControlField(
'Files', '\n ' + ' '.join(
[checksums['md5'], debsize, section, priority, deb_basename])),
'Files', ' '.join(
[checksums['md5'], debsize, section, priority, deb_basename]),
multiline=Multiline.YES_ADD_NEWLINE),
MakeDebianControlField(
'Checksums-Sha1',
'\n ' + ' '.join([checksums['sha1'], debsize, deb_basename])),
' '.join([checksums['sha1'], debsize, deb_basename]),
multiline=Multiline.YES_ADD_NEWLINE),
MakeDebianControlField(
'Checksums-Sha256',
'\n ' + ' '.join([checksums['sha256'], debsize, deb_basename]))
' '.join([checksums['sha256'], debsize, deb_basename]),
multiline=Multiline.YES_ADD_NEWLINE)
])
with open(output, 'wb') as changes_fh:
changes_fh.write(changesdata.encode('utf-8'))
Expand Down
16 changes: 12 additions & 4 deletions tests/deb/control_field_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,23 +52,31 @@ def test_multiline(self):
self.assertEqual(
'Description: fizzbuzz\n',
make_deb.MakeDebianControlField(
'Description', 'fizzbuzz', is_multiline=True))
'Description', 'fizzbuzz', multiline=make_deb.Multiline.YES))
self.assertEqual(
'Description: fizz\n buzz\n',
make_deb.MakeDebianControlField(
'Description', 'fizz\n buzz\n', is_multiline=True))
'Description', 'fizz\n buzz\n', multiline=make_deb.Multiline.YES))
self.assertEqual(
'Description:\n fizz\n buzz\n',
make_deb.MakeDebianControlField(
'Description', ' fizz\n buzz\n', multiline=make_deb.Multiline.YES_ADD_NEWLINE))

def test_multiline_add_required_space(self):
self.assertEqual(
'Description: fizz\n buzz\n',
make_deb.MakeDebianControlField(
'Description', 'fizz\nbuzz', is_multiline=True))
'Description', 'fizz\nbuzz', multiline=make_deb.Multiline.YES))
self.assertEqual(
'Description:\n fizz\n buzz\n',
make_deb.MakeDebianControlField(
'Description', 'fizz\nbuzz\n', multiline=make_deb.Multiline.YES_ADD_NEWLINE))

def test_multiline_add_trailing_newline(self):
self.assertEqual(
'Description: fizz\n buzz\n baz\n',
make_deb.MakeDebianControlField(
'Description', 'fizz\n buzz\n baz', is_multiline=True))
'Description', 'fizz\n buzz\n baz', multiline=make_deb.Multiline.YES))


if __name__ == '__main__':
Expand Down
26 changes: 26 additions & 0 deletions tests/deb/pkg_deb_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,32 @@ def test_changes(self):
content[d_start + len(d_expect)].isupper(),
'Description has unexpected characters at end (%s)' % content)

self.maxDiff = None
expect = '''Format: 1\.8
Date: Thu Jan 1 \d{2}:00:00 1970
Source: fizzbuzz
Binary: fizzbuzz
Architecture: all
Version: 4\.5\.6
Distribution: trusty
Urgency: low
Maintainer: soméone@somewhere.com
Changed-By: soméone@somewhere.com
Description:
fizzbuzz - toto ®, Й, ק ,م, ๗, あ, 叶, 葉, 말, ü and é
Changes:
fizzbuzz \(4\.5\.6\) trusty; urgency=low
Changes are tracked in revision control\.
Files:
[a-f0-9]{32} \d{4} contrib/devel optional fizzbuzz_4\.5\.6_all\.deb
Checksums-Sha1:
[a-f0-9]{40} \d{4} fizzbuzz_4\.5\.6_all\.deb
Checksums-Sha256:
[a-f0-9]{64} \d{4} fizzbuzz_4\.5\.6_all\.deb
'''

self.assertRegex(content, expect)


if __name__ == '__main__':
unittest.main()

0 comments on commit 5932519

Please sign in to comment.