Bug 1234439 - Add support for files with a given content to install manifests. r=gps

This will be used for chrome manifests in the faster make backend.
This commit is contained in:
Mike Hommey 2015-12-23 15:47:11 +09:00
Родитель ec5f249440
Коммит 4e978ebeda
2 изменённых файлов: 43 добавлений и 9 удалений

Просмотреть файл

@ -12,6 +12,7 @@ from .files import (
ExistingFile,
File,
FileFinder,
GeneratedFile,
PreprocessedFile,
)
import mozpack.path as mozpath
@ -75,13 +76,16 @@ class InstallManifest(object):
the preprocessor, and the output will be written to the destination
path.
content -- The destination file will be created with the given content.
Version 1 of the manifest was the initial version.
Version 2 added optional path support
Version 3 added support for pattern entries.
Version 4 added preprocessed file support.
Version 5 added content support.
"""
CURRENT_VERSION = 4
CURRENT_VERSION = 5
FIELD_SEPARATOR = '\x1f'
@ -94,6 +98,7 @@ class InstallManifest(object):
PATTERN_SYMLINK = 5
PATTERN_COPY = 6
PREPROCESS = 7
CONTENT = 8
def __init__(self, path=None, fileobj=None):
"""Create a new InstallManifest entry.
@ -116,7 +121,7 @@ class InstallManifest(object):
def _load_from_fileobj(self, fileobj):
version = fileobj.readline().rstrip()
if version not in ('1', '2', '3', '4'):
if version not in ('1', '2', '3', '4', '5'):
raise UnreadableInstallManifest('Unknown manifest version: %s' %
version)
@ -165,6 +170,13 @@ class InstallManifest(object):
silence_missing_directive_warnings=bool(int(warnings)))
continue
if record_type == self.CONTENT:
dest, content = fields[1:]
self.add_content(
self._decode_field_entry(content).encode('utf-8'), dest)
continue
# Don't fail for non-actionable items, allowing
# forward-compatibility with those we will add in the future.
if record_type >= 0:
@ -304,6 +316,13 @@ class InstallManifest(object):
'1' if silence_missing_directive_warnings else '0',
))
def add_content(self, content, dest):
"""Add a file with the given content."""
self._add_entry(dest, (
self.CONTENT,
self._encode_field_entry(content),
))
def _add_entry(self, dest, entry):
if dest in self._dests:
raise ValueError('Item already in manifest: %s' % dest)
@ -369,5 +388,12 @@ class InstallManifest(object):
continue
if install_type == self.CONTENT:
# GeneratedFile expect the buffer interface, which the unicode
# type doesn't have, so encode to a str.
content = self._decode_field_entry(entry[1]).encode('utf-8')
registry.add(dest, GeneratedFile(content))
continue
raise Exception('Unknown install type defined in manifest: %d' %
install_type)

Просмотреть файл

@ -39,13 +39,15 @@ class TestInstallManifest(TestWithTmpDir):
m.add_pattern_symlink('ps_base', 'ps/*', 'ps_dest')
m.add_pattern_copy('pc_base', 'pc/**', 'pc_dest')
m.add_preprocess('p_source', 'p_dest', 'p_source.pp')
m.add_content('content', 'content')
self.assertEqual(len(m), 7)
self.assertEqual(len(m), 8)
self.assertIn('s_dest', m)
self.assertIn('c_dest', m)
self.assertIn('p_dest', m)
self.assertIn('e_dest', m)
self.assertIn('o_dest', m)
self.assertIn('content', m)
with self.assertRaises(ValueError):
m.add_symlink('s_other', 's_dest')
@ -68,6 +70,9 @@ class TestInstallManifest(TestWithTmpDir):
with self.assertRaises(ValueError):
m.add_pattern_copy('pc_base', 'pc/**', 'pc_dest')
with self.assertRaises(ValueError):
m.add_content('content', 'content')
def _get_test_manifest(self):
m = InstallManifest()
m.add_symlink(self.tmppath('s_source'), 's_dest')
@ -77,6 +82,7 @@ class TestInstallManifest(TestWithTmpDir):
m.add_optional_exists('o_dest')
m.add_pattern_symlink('ps_base', '*', 'ps_dest')
m.add_pattern_copy('pc_base', '**', 'pc_dest')
m.add_content('the content\non\nmultiple lines', 'content')
return m
@ -90,12 +96,12 @@ class TestInstallManifest(TestWithTmpDir):
with open(p, 'rb') as fh:
c = fh.read()
self.assertEqual(c.count('\n'), 8)
self.assertEqual(c.count('\n'), 9)
lines = c.splitlines()
self.assertEqual(len(lines), 8)
self.assertEqual(len(lines), 9)
self.assertEqual(lines[0], '4')
self.assertEqual(lines[0], '5')
m2 = InstallManifest(path=p)
self.assertEqual(m, m2)
@ -112,8 +118,9 @@ class TestInstallManifest(TestWithTmpDir):
r = FileRegistry()
m.populate_registry(r)
self.assertEqual(len(r), 5)
self.assertEqual(r.paths(), ['c_dest', 'e_dest', 'o_dest', 'p_dest', 's_dest'])
self.assertEqual(len(r), 6)
self.assertEqual(r.paths(), ['c_dest', 'content', 'e_dest', 'o_dest',
'p_dest', 's_dest'])
def test_pattern_expansion(self):
source = self.tmppath('source')
@ -182,6 +189,7 @@ class TestInstallManifest(TestWithTmpDir):
self.assertTrue(os.path.exists(self.tmppath('dest/p_dest')))
self.assertTrue(os.path.exists(self.tmppath('dest/e_dest')))
self.assertTrue(os.path.exists(self.tmppath('dest/o_dest')))
self.assertTrue(os.path.exists(self.tmppath('dest/content')))
self.assertFalse(os.path.exists(to_delete))
with open(self.tmppath('dest/s_dest'), 'rt') as fh:
@ -194,7 +202,7 @@ class TestInstallManifest(TestWithTmpDir):
self.assertEqual(fh.read(), 'preprocess!')
self.assertEqual(result.updated_files, set(self.tmppath(p) for p in (
'dest/s_dest', 'dest/c_dest', 'dest/p_dest')))
'dest/s_dest', 'dest/c_dest', 'dest/p_dest', 'dest/content')))
self.assertEqual(result.existing_files,
set([self.tmppath('dest/e_dest'), self.tmppath('dest/o_dest')]))
self.assertEqual(result.removed_files, {to_delete})