Mercurial > hg > fetch
comparison fetch.py @ 29:1c963875e6cd
add a test for manifest and fix resulting bugs
author | Jeff Hammel <jhammel@mozilla.com> |
---|---|
date | Tue, 15 Nov 2011 10:13:47 -0800 |
parents | 5ecb6507931b |
children | 60e0e932570e |
comparison
equal
deleted
inserted
replaced
28:5ecb6507931b | 29:1c963875e6cd |
---|---|
58 from StringIO import StringIO | 58 from StringIO import StringIO |
59 | 59 |
60 class FileFetcher(Fetcher): | 60 class FileFetcher(Fetcher): |
61 """fetch a single file""" | 61 """fetch a single file""" |
62 # Note: subpath and clobber for single files are ignored | 62 # Note: subpath and clobber for single files are ignored |
63 | 63 |
64 type = 'file' | 64 type = 'file' |
65 | 65 |
66 @classmethod | 66 @classmethod |
67 def download(cls, url): | 67 def download(cls, url): |
68 return urllib2.urlopen(url).read() | 68 return urllib2.urlopen(url).read() |
128 self.clobber(dest) | 128 self.clobber(dest) |
129 if self.subpath or self.export: | 129 if self.subpath or self.export: |
130 # can only export with a subpath | 130 # can only export with a subpath |
131 self.export(dest, subpath=self.subpath) | 131 self.export(dest, subpath=self.subpath) |
132 return | 132 return |
133 | 133 |
134 if os.path.exists(dest): | 134 if os.path.exists(dest): |
135 assert os.path.isdir(dest) | 135 assert os.path.isdir(dest) |
136 else: | 136 else: |
137 self.clone(dest) | 137 self.clone(dest) |
138 | 138 |
177 raise NotImplementedError("Abstract base class") | 177 raise NotImplementedError("Abstract base class") |
178 | 178 |
179 def versioned(self, directory): | 179 def versioned(self, directory): |
180 return os.path.exists(os.path.join(directory, self.vcs_dir)) | 180 return os.path.exists(os.path.join(directory, self.vcs_dir)) |
181 | 181 |
182 | 182 |
183 if which('hg'): | 183 if which('hg'): |
184 | 184 |
185 class HgFetcher(VCSFetcher): | 185 class HgFetcher(VCSFetcher): |
186 """checkout a mercurial repository""" | 186 """checkout a mercurial repository""" |
187 type = 'hg' | 187 type = 'hg' |
193 | 193 |
194 def clone(self, dest): | 194 def clone(self, dest): |
195 if os.path.exists(dest): | 195 if os.path.exists(dest): |
196 assert os.path.isdir(dest) | 196 assert os.path.isdir(dest) |
197 call([self.hg, 'clone', self.url, dest]) | 197 call([self.hg, 'clone', self.url, dest]) |
198 | 198 |
199 def update(self, dest): | 199 def update(self, dest): |
200 assert os.path.versioned(dest) | 200 assert os.path.versioned(dest) |
201 assert os.path.exists(dest) | 201 assert os.path.exists(dest) |
202 call([self.hg, 'pull', self.url], cwd=dest) | 202 call([self.hg, 'pull', self.url], cwd=dest) |
203 call([self.hg, 'update', '-C'], cwd=dest) | 203 call([self.hg, 'update', '-C'], cwd=dest) |
230 fetchers.append(GitFetcher) | 230 fetchers.append(GitFetcher) |
231 | 231 |
232 __all__ += [i.__name__ for i in fetchers] | 232 __all__ += [i.__name__ for i in fetchers] |
233 | 233 |
234 class Fetch(object): | 234 class Fetch(object): |
235 | 235 |
236 def __init__(self, fetchers=fetchers[:], relative_to=None, strict=True): | 236 def __init__(self, fetchers=fetchers[:], relative_to=None, strict=True): |
237 self.fetchers = fetchers | 237 self.fetchers = fetchers |
238 self.relative_to = relative_to | 238 self.relative_to = relative_to |
239 self.strict = strict | 239 self.strict = strict |
240 | 240 |
254 | 254 |
255 if self.strict: | 255 if self.strict: |
256 # ensure all the required fetchers are available | 256 # ensure all the required fetchers are available |
257 types = set([i['type'] for i in items]) | 257 types = set([i['type'] for i in items]) |
258 assert not [i for i in types | 258 assert not [i for i in types |
259 if [True for fetcher in fetchers if fetcher.match(i)]] | 259 if not [True for fetcher in fetchers |
260 if fetcher.match(i)]] | |
260 | 261 |
261 for item in items: | 262 for item in items: |
262 | 263 |
263 # fix up relative paths | 264 # fix up relative paths |
264 dest = item['dest'] | 265 dest = item['dest'] |
272 | 273 |
273 format_string = "[URL] [destination] [type] <options>" | 274 format_string = "[URL] [destination] [type] <options>" |
274 def read_manifests(*manifests): | 275 def read_manifests(*manifests): |
275 """ | 276 """ |
276 read some manifests and return the items | 277 read some manifests and return the items |
277 | 278 |
278 Format: | 279 Format: |
279 %s | 280 %s |
280 """ % format_string | 281 """ % format_string |
281 | 282 |
282 # sanity check | |
283 assert not [i for i in manifests if not os.path.exists(i)] | |
284 | |
285 retval = [] | 283 retval = [] |
286 | 284 |
287 for manifest in manifests: | 285 for manifest in manifests: |
288 for line in file(i).readlines(): | 286 if isinstance(manifest, basestring): |
287 assert os.path.exists(manifest), "manifest '%s' not found" % manifest | |
288 f = file(manifest) | |
289 else: | |
290 f = manifest | |
291 | |
292 for line in f.readlines(): | |
289 line = line.strip() | 293 line = line.strip() |
290 if line.startswith('#') or not line: | 294 if line.startswith('#') or not line: |
291 continue | 295 continue |
292 line = line.split() | 296 line = line.split() |
293 if len(line) not in (3,4): | 297 if len(line) not in (3,4): |
314 def format_description(self, description): | 318 def format_description(self, description): |
315 if description: | 319 if description: |
316 return description + '\n' | 320 return description + '\n' |
317 else: | 321 else: |
318 return '' | 322 return '' |
319 | 323 |
320 parser = optparse.OptionParser(usage=usage, description=__doc__, formatter=PlainDescriptionFormatter()) | 324 parser = optparse.OptionParser(usage=usage, description=__doc__, formatter=PlainDescriptionFormatter()) |
321 parser.add_option('-o', '--output', | 325 parser.add_option('-o', '--output', |
322 help="output relative to this location vs. the manifest location") | 326 help="output relative to this location vs. the manifest location") |
323 parser.add_option('-d', '--dest', # XXX unused | 327 parser.add_option('-d', '--dest', # XXX unused |
324 action='append', | 328 action='append', |
343 if not args: | 347 if not args: |
344 # TODO: could read from stdin | 348 # TODO: could read from stdin |
345 parser.print_help() | 349 parser.print_help() |
346 parser.exit() | 350 parser.exit() |
347 | 351 |
352 # sanity check | |
353 assert not [i for i in args if not os.path.exists(i)] | |
354 | |
348 items = read_manifests(*args) | 355 items = read_manifests(*args) |
349 fetch = Fetch(fetchers, strict=options.strict) | 356 fetch = Fetch(fetchers, strict=options.strict) |
350 | 357 |
351 # download the files | 358 # download the files |
352 fetch.fetch(*items) | 359 fetch.fetch(*items) |
353 | 360 |
354 if __name__ == '__main__': | 361 if __name__ == '__main__': |
355 main() | 362 main() |
356 | 363 |