def parse_chrome_manifest(path, base_path, chrome_entries): for entry in parse_manifest(None, path): if isinstance(entry, Manifest): parse_chrome_manifest( os.path.join(os.path.dirname(path), entry.relpath), base_path, chrome_entries ) elif isinstance(entry, ManifestLocale): entry_path = os.path.join( os.path.relpath( os.path.dirname(path), base_path ), entry.relpath ) chrome_entries.append({ 'type': 'locale', 'alias': entry.name, 'locale': entry.id, 'platforms': convert_entry_flags_to_platform_codes(entry.flags), 'path': mozpath.normsep(entry_path) }) else: raise Exception('Unknown type {0}'.format(entry.name))
def handle_manifest_entry(self, entry): format_strings = { "content": "chrome://%s/content/", "resource": "resource://%s/", "locale": "chrome://%s/locale/", "skin": "chrome://%s/skin/", } if isinstance(entry, (ManifestChrome, ManifestResource)): if isinstance(entry, ManifestResource): dest = entry.target url = urlparse.urlparse(dest) if not url.scheme: dest = mozpath.normpath(mozpath.join(entry.base, dest)) if url.scheme == 'file': dest = mozpath.normpath(url.path) else: dest = mozpath.normpath(entry.path) base_uri = format_strings[entry.type] % entry.name self.chrome_mapping[base_uri].add(dest) if isinstance(entry, ManifestOverride): self.overrides[entry.overloaded] = entry.overload if isinstance(entry, Manifest): for e in parse_manifest(None, entry.path): self.handle_manifest_entry(e)
def _add_manifest_file(self, path, file): ''' Add the given BaseFile with manifest file contents with the given path. ''' self._manifests.add(path) base = '' if hasattr(file, 'path'): # Find the directory the given path is relative to. b = mozpath.normsep(file.path) if b.endswith('/' + path) or b == path: base = os.path.normpath(b[:-len(path)]) for e in parse_manifest(base, path, file.open()): # ManifestResources need to be given after ManifestChrome, so just # put all ManifestChrome in a separate queue to make them first. if isinstance(e, ManifestChrome): # e.move(e.base) just returns a clone of the entry. self._chrome_queue.append(self.formatter.add_manifest, e.move(e.base)) elif not isinstance(e, (Manifest, ManifestInterfaces)): self._queue.append(self.formatter.add_manifest, e.move(e.base)) # If a binary component is added to an addon, prevent the addon # from being packed. if isinstance(e, ManifestBinaryComponent): addon = mozpath.basedir(e.base, self._addons) if addon: self._addons[addon] = 'unpacked' if isinstance(e, Manifest): if e.flags: errors.fatal('Flags are not supported on ' + '"manifest" entries') self._included_manifests[e.path] = path
def _populate_chrome(self, manifests): handler = ChromeManifestHandler() for m in manifests: path = os.path.abspath(m) for e in parse_manifest(None, path): handler.handle_manifest_entry(e) self._url_overrides.update(handler.overrides) self._url_prefixes.update(handler.chrome_mapping)
def __init__(self, source, omnijar_name=None, unpack_xpi=True): if isinstance(source, BaseFinder): self._finder = source else: self._finder = FileFinder(source) self.base = self._finder.base self.files = FileRegistry() self.kind = "flat" if omnijar_name: self.omnijar = omnijar_name else: # Can't include globally because of bootstrapping issues. from buildconfig import substs self.omnijar = substs.get("OMNIJAR_NAME", "omni.ja") self.jarlogs = {} self.compressed = False self._unpack_xpi = unpack_xpi jars = set() for p, f in self._finder.find("*"): # Skip the precomplete file, which is generated at packaging time. if p == "precomplete": continue base = mozpath.dirname(p) # If the file matches the omnijar pattern, it is an omnijar. # All the files it contains go in the directory containing the full # pattern. Manifests are merged if there is a corresponding manifest # in the directory. if self._maybe_zip(f) and mozpath.match(p, "**/%s" % self.omnijar): jar = self._open_jar(p, f) if "chrome.manifest" in jar: self.kind = "omni" self._fill_with_jar(p[: -len(self.omnijar) - 1], jar) continue # If the file is a manifest, scan its entries for some referencing # jar: urls. If there are some, the files contained in the jar they # point to, go under a directory named after the jar. if is_manifest(p): m = self.files[p] if self.files.contains(p) else ManifestFile(base) for e in parse_manifest( self.base, p, codecs.getreader("utf-8")(f.open()) ): m.add(self._handle_manifest_entry(e, jars)) if self.files.contains(p): continue f = m # If we're unpacking packed addons and the file is a packed addon, # unpack it under a directory named after the xpi. if self._unpack_xpi and p.endswith(".xpi") and self._maybe_zip(f): self._fill_with_jar(p[:-4], self._open_jar(p, f)) continue if p not in jars: self.files.add(p, f)
def _fill_with_omnijar(self, base, jar): for j in jar: path = mozpack.path.join(base, j.filename) if is_manifest(j.filename): m = self.files[path] if self.files.contains(path) \ else ManifestFile(mozpack.path.dirname(path)) for e in parse_manifest(None, path, j): m.add(e) if not self.files.contains(path): self.files.add(path, m) continue else: self.files.add(path, DeflatedFile(j))
def __init__(self, source): if isinstance(source, BaseFinder): self._finder = source else: self._finder = FileFinder(source) self.base = self._finder.base self.files = FileRegistry() self.kind = 'flat' self.omnijar = None self.jarlogs = {} self.optimizedjars = False self.compressed = False jars = set() for p, f in self._finder.find('*'): # Skip the precomplete file, which is generated at packaging time. if p == 'precomplete': continue base = mozpath.dirname(p) # If the file is a zip/jar that is not a .xpi, and contains a # chrome.manifest, it is an omnijar. All the files it contains # go in the directory containing the omnijar. Manifests are merged # if there is a corresponding manifest in the directory. if not p.endswith('.xpi') and self._maybe_zip(f) and \ (mozpath.basename(p) == self.omnijar or not self.omnijar): jar = self._open_jar(p, f) if 'chrome.manifest' in jar: self.kind = 'omni' self.omnijar = mozpath.basename(p) self._fill_with_jar(base, jar) continue # If the file is a manifest, scan its entries for some referencing # jar: urls. If there are some, the files contained in the jar they # point to, go under a directory named after the jar. if is_manifest(p): m = self.files[p] if self.files.contains(p) \ else ManifestFile(base) for e in parse_manifest(self.base, p, f.open()): m.add(self._handle_manifest_entry(e, jars)) if self.files.contains(p): continue f = m # If the file is a packed addon, unpack it under a directory named # after the xpi. if p.endswith('.xpi') and self._maybe_zip(f): self._fill_with_jar(p[:-4], self._open_jar(p, f)) continue if not p in jars: self.files.add(p, f)
def __init__(self, source): if isinstance(source, BaseFinder): self._finder = source else: self._finder = FileFinder(source) self.base = self._finder.base self.files = FileRegistry() self.kind = 'flat' self.omnijar = None self.jarlogs = {} self.optimizedjars = False self.compressed = True jars = set() for p, f in self._finder.find('*'): # Skip the precomplete file, which is generated at packaging time. if p == 'precomplete': continue base = mozpath.dirname(p) # If the file is a zip/jar that is not a .xpi, and contains a # chrome.manifest, it is an omnijar. All the files it contains # go in the directory containing the omnijar. Manifests are merged # if there is a corresponding manifest in the directory. if not p.endswith('.xpi') and self._maybe_zip(f) and \ (mozpath.basename(p) == self.omnijar or not self.omnijar): jar = self._open_jar(p, f) if 'chrome.manifest' in jar: self.kind = 'omni' self.omnijar = mozpath.basename(p) self._fill_with_jar(base, jar) continue # If the file is a manifest, scan its entries for some referencing # jar: urls. If there are some, the files contained in the jar they # point to, go under a directory named after the jar. if is_manifest(p): m = self.files[p] if self.files.contains(p) \ else ManifestFile(base) for e in parse_manifest(self.base, p, f.open()): m.add(self._handle_manifest_entry(e, jars)) if self.files.contains(p): continue f = m # If the file is a packed addon, unpack it under a directory named # after the xpi. if p.endswith('.xpi') and self._maybe_zip(f): self._fill_with_jar(p[:-4], self._open_jar(p, f)) continue if not p in jars: self.files.add(p, f)
def test_parse_manifest_errors(self): manifest = [ 'skin global classic/1.0 content/skin/classic/ platform', '', 'binary-component bar.so', 'unsupported foo', ] with mozunit.MockedOpen({'manifest': '\n'.join(manifest)}): with self.assertRaises(AccumulatedErrors): with errors.accumulate(): list(parse_manifest(os.curdir, 'manifest')) out = self.get_output() # Expecting 2 errors self.assertEqual(len(out), 2) path = os.path.abspath('manifest') # First on line 1 self.assertTrue(out[0].startswith('Error: %s:1: ' % path)) # Second on line 4 self.assertTrue(out[1].startswith('Error: %s:4: ' % path))
def test_parse_manifest_errors(self): manifest = [ "skin global classic/1.0 content/skin/classic/ platform", "", "binary-component bar.so", "unsupported foo", ] with mozunit.MockedOpen({"manifest": "\n".join(manifest)}): with self.assertRaises(AccumulatedErrors): with errors.accumulate(): list(parse_manifest(os.curdir, "manifest")) out = self.get_output() # Expecting 2 errors self.assertEqual(len(out), 2) path = os.path.abspath("manifest") # First on line 1 self.assertTrue(out[0].startswith("Error: %s:1: " % path)) # Second on line 4 self.assertTrue(out[1].startswith("Error: %s:4: " % path))
def _add_manifest_file(self, path, file): ''' Add the given BaseFile with manifest file contents with the given path. ''' self._manifests.add(path) base = '' if hasattr(file, 'path'): # Find the directory the given path is relative to. b = mozpack.path.normsep(file.path) if b.endswith('/' + path) or b == path: base = os.path.normpath(b[:-len(path)]) for e in parse_manifest(base, path, file.open()): if not isinstance(e, (Manifest, ManifestInterfaces)): # e.move(e.base) just returns a clone of the entry. self._queue.append(self.formatter.add_manifest, e.move(e.base)) if isinstance(e, Manifest): if e.flags: errors.fatal('Flags are not supported on ' + '"manifest" entries') self._included_manifests.add(e.path)
def parse_chrome_manifest(path, base_path, chrome_entries): for entry in parse_manifest(None, path): if isinstance(entry, Manifest): parse_chrome_manifest( os.path.join(os.path.dirname(path), entry.relpath), base_path, chrome_entries) elif isinstance(entry, ManifestLocale): chrome_entries.append({ 'type': 'locale', 'alias': entry.name, 'locale': entry.id, 'platforms': convert_entry_flags_to_platform_codes(entry.flags), 'path': os.path.join(os.path.relpath(os.path.dirname(path), base_path), entry.relpath) }) else: raise Exception('Unknown type {0}'.format(entry.name))
def test_parse_manifest(self): manifest = [ 'content global content/global/', 'content global content/global/ application=foo application=bar' + ' platform', 'locale global en-US content/en-US/', 'locale global en-US content/en-US/ application=foo', 'skin global classic/1.0 content/skin/classic/', 'skin global classic/1.0 content/skin/classic/ application=foo' + ' os=WINNT', '', 'manifest pdfjs/chrome.manifest', 'resource gre-resources toolkit/res/', 'override chrome://global/locale/netError.dtd' + ' chrome://browser/locale/netError.dtd', '# Comment', 'component {b2bba4df-057d-41ea-b6b1-94a10a8ede68} foo.js', 'contract @mozilla.org/foo;1' + ' {b2bba4df-057d-41ea-b6b1-94a10a8ede68}', 'interfaces foo.xpt', 'binary-component bar.so', 'category command-line-handler m-browser' + ' @mozilla.org/browser/clh;1' + ' application={ec8030f7-c20a-464f-9b0e-13a3a9e97384}', 'style chrome://global/content/viewSource.xul' + ' chrome://browser/skin/', 'overlay chrome://global/content/viewSource.xul' + ' chrome://browser/content/viewSourceOverlay.xul', ] other_manifest = ['content global content/global/'] expected_result = [ ManifestContent('', 'global', 'content/global/'), ManifestContent('', 'global', 'content/global/', 'application=foo', 'application=bar', 'platform'), ManifestLocale('', 'global', 'en-US', 'content/en-US/'), ManifestLocale('', 'global', 'en-US', 'content/en-US/', 'application=foo'), ManifestSkin('', 'global', 'classic/1.0', 'content/skin/classic/'), ManifestSkin('', 'global', 'classic/1.0', 'content/skin/classic/', 'application=foo', 'os=WINNT'), Manifest('', 'pdfjs/chrome.manifest'), ManifestResource('', 'gre-resources', 'toolkit/res/'), ManifestOverride('', 'chrome://global/locale/netError.dtd', 'chrome://browser/locale/netError.dtd'), ManifestComponent('', '{b2bba4df-057d-41ea-b6b1-94a10a8ede68}', 'foo.js'), ManifestContract('', '@mozilla.org/foo;1', '{b2bba4df-057d-41ea-b6b1-94a10a8ede68}'), ManifestInterfaces('', 'foo.xpt'), ManifestBinaryComponent('', 'bar.so'), ManifestCategory( '', 'command-line-handler', 'm-browser', '@mozilla.org/browser/clh;1', 'application=' + '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}'), ManifestStyle('', 'chrome://global/content/viewSource.xul', 'chrome://browser/skin/'), ManifestOverlay('', 'chrome://global/content/viewSource.xul', 'chrome://browser/content/viewSourceOverlay.xul'), ] with mozunit.MockedOpen({ 'manifest': '\n'.join(manifest), 'other/manifest': '\n'.join(other_manifest) }): # Ensure we have tests for all types of manifests. self.assertEqual(set(type(e) for e in expected_result), set(MANIFESTS_TYPES.values())) self.assertEqual(list(parse_manifest(os.curdir, 'manifest')), expected_result) self.assertEqual( list(parse_manifest(os.curdir, 'other/manifest')), [ManifestContent('other', 'global', 'content/global/')])
def test_parse_manifest(self): manifest = [ 'content global content/global/', 'content global content/global/ application=foo application=bar' + ' platform', 'locale global en-US content/en-US/', 'locale global en-US content/en-US/ application=foo', 'skin global classic/1.0 content/skin/classic/', 'skin global classic/1.0 content/skin/classic/ application=foo' + ' os=WINNT', '', 'manifest pdfjs/chrome.manifest', 'resource gre-resources toolkit/res/', 'override chrome://global/locale/netError.dtd' + ' chrome://browser/locale/netError.dtd', '# Comment', 'component {b2bba4df-057d-41ea-b6b1-94a10a8ede68} foo.js', 'contract @mozilla.org/foo;1' + ' {b2bba4df-057d-41ea-b6b1-94a10a8ede68}', 'interfaces foo.xpt # Inline comment', 'binary-component bar.so', 'category command-line-handler m-browser' + ' @mozilla.org/browser/clh;1' + ' application={ec8030f7-c20a-464f-9b0e-13a3a9e97384}', 'style chrome://global/content/customizeToolbar.xul' + ' chrome://browser/skin/', 'overlay chrome://global/content/viewSource.xul' + ' chrome://browser/content/viewSourceOverlay.xul', ] other_manifest = [ 'content global content/global/' ] expected_result = [ ManifestContent('', 'global', 'content/global/'), ManifestContent('', 'global', 'content/global/', 'application=foo', 'application=bar', 'platform'), ManifestLocale('', 'global', 'en-US', 'content/en-US/'), ManifestLocale('', 'global', 'en-US', 'content/en-US/', 'application=foo'), ManifestSkin('', 'global', 'classic/1.0', 'content/skin/classic/'), ManifestSkin('', 'global', 'classic/1.0', 'content/skin/classic/', 'application=foo', 'os=WINNT'), Manifest('', 'pdfjs/chrome.manifest'), ManifestResource('', 'gre-resources', 'toolkit/res/'), ManifestOverride('', 'chrome://global/locale/netError.dtd', 'chrome://browser/locale/netError.dtd'), ManifestComponent('', '{b2bba4df-057d-41ea-b6b1-94a10a8ede68}', 'foo.js'), ManifestContract('', '@mozilla.org/foo;1', '{b2bba4df-057d-41ea-b6b1-94a10a8ede68}'), ManifestInterfaces('', 'foo.xpt'), ManifestBinaryComponent('', 'bar.so'), ManifestCategory('', 'command-line-handler', 'm-browser', '@mozilla.org/browser/clh;1', 'application=' + '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}'), ManifestStyle('', 'chrome://global/content/customizeToolbar.xul', 'chrome://browser/skin/'), ManifestOverlay('', 'chrome://global/content/viewSource.xul', 'chrome://browser/content/viewSourceOverlay.xul'), ] with mozunit.MockedOpen({'manifest': '\n'.join(manifest), 'other/manifest': '\n'.join(other_manifest)}): # Ensure we have tests for all types of manifests. self.assertEqual(set(type(e) for e in expected_result), set(MANIFESTS_TYPES.values())) self.assertEqual(list(parse_manifest(os.curdir, 'manifest')), expected_result) self.assertEqual(list(parse_manifest(os.curdir, 'other/manifest')), [ManifestContent('other', 'global', 'content/global/')])
def test_parse_manifest(self): manifest = [ "content global content/global/", "content global content/global/ application=foo application=bar" + " platform", "locale global en-US content/en-US/", "locale global en-US content/en-US/ application=foo", "skin global classic/1.0 content/skin/classic/", "skin global classic/1.0 content/skin/classic/ application=foo" + " os=WINNT", "", "manifest pdfjs/chrome.manifest", "resource gre-resources toolkit/res/", "override chrome://global/locale/netError.dtd" + " chrome://browser/locale/netError.dtd", "# Comment", "component {b2bba4df-057d-41ea-b6b1-94a10a8ede68} foo.js", "contract @mozilla.org/foo;1" + " {b2bba4df-057d-41ea-b6b1-94a10a8ede68}", "interfaces foo.xpt", "binary-component bar.so", "category command-line-handler m-browser" + " @mozilla.org/browser/clh;1" + " application={ec8030f7-c20a-464f-9b0e-13a3a9e97384}", "style chrome://global/content/viewSource.xul" + " chrome://browser/skin/", "overlay chrome://global/content/viewSource.xul" + " chrome://browser/content/viewSourceOverlay.xul", ] other_manifest = ["content global content/global/"] expected_result = [ ManifestContent("", "global", "content/global/"), ManifestContent( "", "global", "content/global/", "application=foo", "application=bar", "platform", ), ManifestLocale("", "global", "en-US", "content/en-US/"), ManifestLocale("", "global", "en-US", "content/en-US/", "application=foo"), ManifestSkin("", "global", "classic/1.0", "content/skin/classic/"), ManifestSkin( "", "global", "classic/1.0", "content/skin/classic/", "application=foo", "os=WINNT", ), Manifest("", "pdfjs/chrome.manifest"), ManifestResource("", "gre-resources", "toolkit/res/"), ManifestOverride( "", "chrome://global/locale/netError.dtd", "chrome://browser/locale/netError.dtd", ), ManifestComponent("", "{b2bba4df-057d-41ea-b6b1-94a10a8ede68}", "foo.js"), ManifestContract( "", "@mozilla.org/foo;1", "{b2bba4df-057d-41ea-b6b1-94a10a8ede68}" ), ManifestInterfaces("", "foo.xpt"), ManifestBinaryComponent("", "bar.so"), ManifestCategory( "", "command-line-handler", "m-browser", "@mozilla.org/browser/clh;1", "application=" + "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}", ), ManifestStyle( "", "chrome://global/content/viewSource.xul", "chrome://browser/skin/" ), ManifestOverlay( "", "chrome://global/content/viewSource.xul", "chrome://browser/content/viewSourceOverlay.xul", ), ] with mozunit.MockedOpen( { "manifest": "\n".join(manifest), "other/manifest": "\n".join(other_manifest), } ): # Ensure we have tests for all types of manifests. self.assertEqual( set(type(e) for e in expected_result), set(MANIFESTS_TYPES.values()) ) self.assertEqual( list(parse_manifest(os.curdir, "manifest")), expected_result ) self.assertEqual( list(parse_manifest(os.curdir, "other/manifest")), [ManifestContent("other", "global", "content/global/")], )