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

Side by Side Diff: mojo/public/tools/mojom_fetcher/mojom_fetcher.py

Issue 1709333002: Remove mojom_fetcher. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 years, 10 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 unified diff | Download patch
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright 2015 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 """Tool to manage external mojom interfaces."""
7
8 import argparse
9 import errno
10 import logging
11 import os
12 import sys
13 import urllib2
14
15 # Local library
16 sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
17 "pylib"))
18 # Bindings library
19 sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
20 "..", "bindings", "pylib"))
21 # Requests library
22 sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
23 "..", "..", "..", "..", "third_party",
24 "requests", "src"))
25
26 import requests
27
28 from fetcher.repository import Repository
29 from fetcher.dependency import Dependency
30 from mojom.parse.parser import Parse, ParseError
31
32
33 class UrlRewriterException(Exception):
34 """Exception when processing URL rewrite rules."""
35 pass
36
37 class UrlRewriter(object):
38 """UrlRewriter rewrites URLs according to the provided mappings.
39
40 Note that mappings are not followed transitively. If mappings contains
41 {"a": "b", "b": "c"}, then UrlRewriter.rewrite("a") will return "b", not "c".
42 """
43
44 def __init__(self, mappings):
45 self._mappings = mappings
46 for target in self._mappings.values():
47 for source in self._mappings.keys():
48 if source in target or target in source:
49 raise UrlRewriterException(
50 "%s and %s share a common subpath" % (source, target))
51
52 def rewrite(self, path):
53 for origin, destination in self._mappings.items():
54 if path.startswith(origin):
55 return destination + path[len(origin):]
56 return path
57
58
59 class MojomFetcher(object):
60 def __init__(self, repository, url_rewriter):
61 self._repository = repository
62 self._url_rewriter = url_rewriter
63
64 def _requests_get(self, url):
65 return requests.get(url, verify=True)
66
67 def _os_makedirs(self, dirs):
68 try:
69 os.makedirs(dirs)
70 except OSError as e:
71 # The directory may already exist, we don't care.
72 if e.errno != errno.EEXIST:
73 raise
74
75 def _open(self, f, mode="r"):
76 return open(f, mode)
77
78 def _download_dependencies(self, dependencies):
79 """Takes the list of mojom dependencies and download the external ones.
80 Returns the number of successfully downloaded dependencies."""
81
82 downloaded = 0
83 for dep in dependencies:
84 if self._maybe_download_dep(dep):
85 downloaded += 1
86 return downloaded
87
88 def _maybe_download_dep(self, dep):
89 if not dep.maybe_is_a_url():
90 return False
91
92 for candidate in dep.generate_candidate_urls():
93 url = self._url_rewriter.rewrite(candidate)
94 response = self._requests_get("https://" + url)
95 if not response.ok:
96 # If we get an error, it just mean that this candidate URL is not
97 # correct. We must try the other ones before giving up.
98 logging.debug("Error while downloading %s (%s)", candidate, url)
99 continue
100 # This is an external dependency
101 directory = os.path.dirname(candidate)
102 full_directory = os.path.join(self._repository.get_external_directory(),
103 directory)
104 try:
105 self._os_makedirs(full_directory)
106 except OSError as e:
107 # The directory may already exist, we don't care.
108 if e.errno != errno.EEXIST:
109 raise
110 with self._open(os.path.join(self._repository.get_external_directory(),
111 candidate), "w") as f:
112 data = response.content
113 try:
114 Parse(data, candidate)
115 except ParseError:
116 logging.warn("File at %s is not a mojom", url)
117 break
118 f.write(data)
119 return True
120 return False
121
122 def discover(self):
123 """Discover missing .mojom dependencies and download them."""
124 while True:
125 missing_deps = self._repository.get_missing_dependencies()
126 downloaded = self._download_dependencies(missing_deps)
127 if downloaded == 0:
128 return 0
129
130 def get(self, dep):
131 dependency = Dependency(self._repository, ".", dep)
132 downloaded = self._download_dependencies([dependency])
133 if downloaded != 0:
134 return self.discover()
135 else:
136 return -1
137
138 def update(self):
139 dependencies = [Dependency(self._repository, ".", f)
140 for f in self._repository.get_external_urls()]
141 # TODO(etiennej): We may want to suggest to the user to delete
142 # un-downloadable dependencies.
143 downloaded = self._download_dependencies(dependencies)
144 if downloaded != 0:
145 return self.discover()
146 else:
147 return -1
148
149 def _main(args):
150 if args.prefix_rewrite:
151 rewrite_rules = dict([x.split(':', 1) for x in args.prefix_rewrite])
152 else:
153 rewrite_rules = {}
154 rewriter = UrlRewriter(rewrite_rules)
155 repository_path = os.path.abspath(args.repository_path)
156 repository = Repository(repository_path, args.external_dir)
157 fetcher = MojomFetcher(repository, rewriter)
158 if args.action == 'discover':
159 return fetcher.discover()
160 elif args.action == 'get':
161 return fetcher.get(args.url)
162 elif args.action == 'update':
163 return fetcher.update()
164 else:
165 logging.error("No matching action %s", args.action[0])
166 return -1
167
168 def main():
169 logging.basicConfig(level=logging.ERROR)
170 parser = argparse.ArgumentParser(description='Download mojom dependencies.')
171 parser.add_argument('--repository-path', type=str, action='store',
172 default='.', help='The path to the client repository.')
173 parser.add_argument('--external-dir', type=str, action='store',
174 default='external',
175 help='Directory for external interfaces')
176 parser.add_argument('--prefix-rewrite', type=str, action='append',
177 help='If present, "origin:destination" pairs. "origin" '
178 'prefixes will be rewritten as "destination". May be '
179 'used several times. Rewrites are not transitive.')
180
181 subparsers = parser.add_subparsers(dest='action', help='action')
182 parser_get = subparsers.add_parser(
183 'get', help='Get the specified URL and all its transitive dependencies')
184 parser_get.add_argument('url', type=str, nargs=1,
185 help='URL to download for get action')
186 subparsers.add_parser(
187 'discover',
188 help='Recursively discover and download new external dependencies')
189 subparsers.add_parser('update', help='Update all external dependencies')
190
191 args = parser.parse_args()
192 return _main(args)
193
194
195 if __name__ == '__main__':
196 sys.exit(main())
OLDNEW
« no previous file with comments | « mojo/public/tools/mojom_fetcher/build_gn.tmpl ('k') | mojo/public/tools/mojom_fetcher/mojom_gn.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698