Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(272)

Unified Diff: third_party/mojo/src/mojo/public/tools/mojom_fetcher/mojom_fetcher.py

Issue 1058033002: NOT TO COMMITTED: Update mojo sdk to rev 0018e6a91b75bcb941c867f8a7aa1753c3b53a13 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/mojo/src/mojo/public/tools/mojom_fetcher/mojom_fetcher.py
diff --git a/third_party/mojo/src/mojo/public/tools/mojom_fetcher/mojom_fetcher.py b/third_party/mojo/src/mojo/public/tools/mojom_fetcher/mojom_fetcher.py
new file mode 100755
index 0000000000000000000000000000000000000000..b0283e36d2ba78f15ea806433d70f20b78a445fc
--- /dev/null
+++ b/third_party/mojo/src/mojo/public/tools/mojom_fetcher/mojom_fetcher.py
@@ -0,0 +1,196 @@
+#!/usr/bin/env python
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Tool to manage external mojom interfaces."""
+
+import argparse
+import errno
+import logging
+import os
+import sys
+import urllib2
+
+# Local library
+sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
+ "pylib"))
+# Bindings library
+sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
+ "..", "bindings", "pylib"))
+# Requests library
+sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
+ "..", "..", "..", "..", "third_party",
+ "requests", "src"))
+
+import requests
+
+from fetcher.repository import Repository
+from fetcher.dependency import Dependency
+from mojom.parse.parser import Parse, ParseError
+
+
+class UrlRewriterException(Exception):
+ """Exception when processing URL rewrite rules."""
+ pass
+
+class UrlRewriter(object):
+ """UrlRewriter rewrites URLs according to the provided mappings.
+
+ Note that mappings are not followed transitively. If mappings contains
+ {"a": "b", "b": "c"}, then UrlRewriter.rewrite("a") will return "b", not "c".
+ """
+
+ def __init__(self, mappings):
+ self._mappings = mappings
+ for target in self._mappings.values():
+ for source in self._mappings.keys():
+ if source in target or target in source:
+ raise UrlRewriterException(
+ "%s and %s share a common subpath" % (source, target))
+
+ def rewrite(self, path):
+ for origin, destination in self._mappings.items():
+ if path.startswith(origin):
+ return destination + path[len(origin):]
+ return path
+
+
+class MojomFetcher(object):
+ def __init__(self, repository, url_rewriter):
+ self._repository = repository
+ self._url_rewriter = url_rewriter
+
+ def _requests_get(self, url):
+ return requests.get(url, verify=True)
+
+ def _os_makedirs(self, dirs):
+ try:
+ os.makedirs(dirs)
+ except OSError as e:
+ # The directory may already exist, we don't care.
+ if e.errno != errno.EEXIST:
+ raise
+
+ def _open(self, f, mode="r"):
+ return open(f, mode)
+
+ def _download_dependencies(self, dependencies):
+ """Takes the list of mojom dependencies and download the external ones.
+ Returns the number of successfully downloaded dependencies."""
+
+ downloaded = 0
+ for dep in dependencies:
+ if self._maybe_download_dep(dep):
+ downloaded += 1
+ return downloaded
+
+ def _maybe_download_dep(self, dep):
+ if not dep.maybe_is_a_url():
+ return False
+
+ for candidate in dep.generate_candidate_urls():
+ url = self._url_rewriter.rewrite(candidate)
+ response = self._requests_get("https://" + url)
+ if not response.ok:
+ # If we get an error, it just mean that this candidate URL is not
+ # correct. We must try the other ones before giving up.
+ logging.debug("Error while downloading %s (%s)", candidate, url)
+ continue
+ # This is an external dependency
+ directory = os.path.dirname(candidate)
+ full_directory = os.path.join(self._repository.get_external_directory(),
+ directory)
+ try:
+ self._os_makedirs(full_directory)
+ except OSError as e:
+ # The directory may already exist, we don't care.
+ if e.errno != errno.EEXIST:
+ raise
+ with self._open(os.path.join(self._repository.get_external_directory(),
+ candidate), "w") as f:
+ data = response.content
+ try:
+ Parse(data, candidate)
+ except ParseError:
+ logging.warn("File at %s is not a mojom", url)
+ break
+ f.write(data)
+ return True
+ return False
+
+ def discover(self):
+ """Discover missing .mojom dependencies and download them."""
+ while True:
+ missing_deps = self._repository.get_missing_dependencies()
+ downloaded = self._download_dependencies(missing_deps)
+ if downloaded == 0:
+ return 0
+
+ def get(self, dep):
+ dependency = Dependency(self._repository, ".", dep)
+ downloaded = self._download_dependencies([dependency])
+ if downloaded != 0:
+ return self.discover()
+ else:
+ return -1
+
+ def update(self):
+ dependencies = [Dependency(self._repository, ".", f)
+ for f in self._repository.get_external_urls()]
+ # TODO(etiennej): We may want to suggest to the user to delete
+ # un-downloadable dependencies.
+ downloaded = self._download_dependencies(dependencies)
+ if downloaded != 0:
+ return self.discover()
+ else:
+ return -1
+
+def _main(args):
+ if args.prefix_rewrite:
+ rewrite_rules = dict([x.split(':', 1) for x in args.prefix_rewrite])
+ else:
+ rewrite_rules = {}
+ rewriter = UrlRewriter(rewrite_rules)
+ repository_path = os.path.abspath(args.repository_path)
+ repository = Repository(repository_path, args.external_dir)
+ fetcher = MojomFetcher(repository, rewriter)
+ if args.action == 'discover':
+ return fetcher.discover()
+ elif args.action == 'get':
+ return fetcher.get(args.url)
+ elif args.action == 'update':
+ return fetcher.update()
+ else:
+ logging.error("No matching action %s", args.action[0])
+ return -1
+
+def main():
+ logging.basicConfig(level=logging.ERROR)
+ parser = argparse.ArgumentParser(description='Download mojom dependencies.')
+ parser.add_argument('--repository-path', type=str, action='store',
+ default='.', help='The path to the client repository.')
+ parser.add_argument('--external-dir', type=str, action='store',
+ default='external',
+ help='Directory for external interfaces')
+ parser.add_argument('--prefix-rewrite', type=str, action='append',
+ help='If present, "origin:destination" pairs. "origin" '
+ 'prefixes will be rewritten as "destination". May be '
+ 'used several times. Rewrites are not transitive.')
+
+ subparsers = parser.add_subparsers(dest='action', help='action')
+ parser_get = subparsers.add_parser(
+ 'get', help='Get the specified URL and all its transitive dependencies')
+ parser_get.add_argument('url', type=str, nargs=1,
+ help='URL to download for get action')
+ subparsers.add_parser(
+ 'discover',
+ help='Recursively discover and download new external dependencies')
+ subparsers.add_parser('update', help='Update all external dependencies')
+
+ args = parser.parse_args()
+ return _main(args)
+
+
+if __name__ == '__main__':
+ sys.exit(main())

Powered by Google App Engine
This is Rietveld 408576698