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

Side by Side Diff: tools/telemetry/telemetry_bootstrap.py

Issue 11741030: Add telemetry_bootstrap module (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « tools/telemetry/DEPS ('k') | tools/telemetry/third_party/davclient/README.chromium » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:executable
+ *
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright (c) 2012 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 """Bootstrap Chrome Telemetry by downloading all its files from SVN servers.
7
8 Requires a DEPS file to specify which directories on which SVN servers
9 are required to run Telemetry. Format of that DEPS file is a subset of the
10 normal DEPS file format[1]; currently only only the "deps" dictionary is
11 supported and nothing else.
12
13 DEPS can be specified with --deps or defaults to ./DEPS
14
15 Fetches all files in the specified directories using WebDAV (SVN is WebDAV under
16 the hood).
17
18 [1] http://dev.chromium.org/developers/how-tos/depottools#TOC-DEPS-file
19 """
20
21 import imp
22 import logging
23 from optparse import OptionParser
nduca 2013/01/05 01:28:19 I think you can ditch main() entirely and thus Opt
wiltzius 2013/01/08 02:53:34 Done.
24 import os
25 import urllib
26 import urlparse
27
28 # default DEPS filename
29 DEPS_FILE = "DEPS"
nduca 2013/01/05 01:28:19 This can go away
wiltzius 2013/01/08 02:53:34 Done.
wiltzius 2013/01/08 02:53:34 Done.
30 # link to file containing the 'davclient' WebDAV client library
nduca 2013/01/05 01:28:19 # Comments start with capitals end and end with a
wiltzius 2013/01/08 02:53:34 Done.
31 #TODO(wiltzius) change this to point at Chromium SVN server after checkin
nduca 2013/01/05 01:28:19 # TODO(wiltzius):
32 DAVCLIENT_URL = 'http://svn.osafoundation.org/tools/davclient/trunk/src/davclien t/davclient.py'
nduca 2013/01/05 01:28:19 _DAVCLIENT_URL since its private to the module. _-
wiltzius 2013/01/08 02:53:34 Done.
33
34 def bootstrap_davclient():
nduca 2013/01/05 01:28:19 _bootstrap_davclient since this shouldn't be calle
wiltzius 2013/01/08 02:53:34 Done.
35 """Dynamically import davclient helper library."""
nduca 2013/01/05 01:28:19 _download_and_import_davclient_module()?
wiltzius 2013/01/08 02:53:34 Done.
36 global davclient
37 davclient_txt = urllib.urlopen(DAVCLIENT_URL).read()
nduca 2013/01/05 01:28:19 txt -> source?
wiltzius 2013/01/08 02:53:34 Done.
wiltzius 2013/01/08 02:53:34 Done.
38 davclient = imp.new_module('davclient')
39 exec davclient_txt in davclient.__dict__
40
41
42 class DAVClientWrapper():
43 """Knows how to retrieve subdirectories and files from WebDAV/SVN servers."""
44
45 def __init__(self, root_url):
46 """Initialize SVN server root_url, save files to local dest_dir.
47
48 Args:
49 root_url: string url of SVN/WebDAV server
50 """
51 self.root_url = root_url
52 self.client = davclient.DAVClient(root_url)
53
54 def GetSubdirs(self, path):
55 """Returns string names of all subdirs of this path on the SVN server."""
56 props = self.client.propfind(path, depth=1)
57 return map(os.path.basename, props.keys())
58
59 def IsFile(self, path):
60 """Returns True if the path is a file on the server, False if directory."""
61 props = self.client.propfind(path, depth=1)
62 # build up normalized path list since paths to directories may or may not
63 # have trailing slashes
64 norm_keys = {}
65 for entry in props.keys():
66 norm_keys[os.path.normpath(entry)] = entry
67 return props[norm_keys[os.path.normpath(path)]]['resourcetype'] is None
68
69 def Traverse(self, src_path, dst_path):
70 """Walks the directory hierarchy pointed to by src_path download all files.
71
72 Recursively walks src_path and saves all files and subfolders into
73 dst_path.
74
75 Args:
76 src_path: string path on SVN server to save (absolute path on server).
77 dest_path: string local path (relative or absolute) to save to.
78 """
79 if self.IsFile(src_path):
80 if not os.path.exists(os.path.dirname(dst_path)):
81 logging.info("creating %s", os.path.dirname(dst_path))
82 os.makedirs(os.path.dirname(dst_path))
83 logging.info("Saving %s to %s", self.root_url + src_path, dst_path)
84 urllib.urlretrieve(self.root_url + src_path, dst_path)
85 return
86 else:
87 for subdir in self.GetSubdirs(src_path):
88 if subdir:
89 self.Traverse(os.path.join(src_path, subdir),
90 os.path.join(dst_path, subdir))
91
92
93 def ParseOptions():
nduca 2013/01/05 01:28:19 I think this can go away
wiltzius 2013/01/08 02:53:34 Done.
94 """Parses command-line options for the bootstrap."""
95 #TODO(wiltzius) have a --revision flag that pulls at a specific rev
96 parser = OptionParser()
97 parser.add_option("-v", "--verbosity", dest="verbosity", default=1,
98 type="int", help="logging verbosity level (0, 1, 2, 3)")
99 parser.add_option("--deps", dest="deps_filename", default=DEPS_FILE,
100 help="look for dependency manifest in this file")
101 return parser.parse_args()
102
103
104 def DownloadDEPS(deps_path):
nduca 2013/01/05 01:28:19 Should we have a TODO here for what revision of te
wiltzius 2013/01/08 02:53:34 Done.
105 """Saves all the dependencies in deps_path."""
106 # dynamically import davclient library
107 bootstrap_davclient()
108 with open(deps_path) as deps_file:
109 deps = imp.new_module('deps')
110 exec deps_file.read() in deps.__dict__
nduca 2013/01/05 01:28:19 unindent the exec stuff so you say with blah as
wiltzius 2013/01/08 02:53:34 Done.
111 #TODO(wiltzius) in the future, make the destination directory configurable
nduca 2013/01/05 01:28:19 formatting
wiltzius 2013/01/08 02:53:34 Done.
112 # as something other than the cwd
nduca 2013/01/05 01:28:19 this function should take in destination dir. E.g.
wiltzius 2013/01/08 02:53:34 Done.
113 destination_dir = os.getcwd()
114 for dst_path, src_path in deps.deps.iteritems():
115 parsed_url = urlparse.urlparse(src_path)
116 root_url = parsed_url.scheme + '://' + parsed_url.netloc
nduca 2013/01/05 01:28:19 where will we handle "foo@181" type stuff?
wiltzius 2013/01/08 02:53:34 That's the "fetch at revision" TODO. This will nee
117 dav_client = DAVClientWrapper(root_url)
118 dav_client.Traverse(parsed_url.path,
119 os.path.join(destination_dir, dst_path))
nduca 2013/01/05 01:28:19 after we clone dst_path, what if dst_path has a DE
120
121
122 def Main():
nduca 2013/01/05 01:28:19 not needed I think.
wiltzius 2013/01/08 02:53:34 Done.
123 """Fetches files specified in dependency manifest from SVN/WebDAV server."""
124 options = ParseOptions()[0]
125 # set logging level per verbosity
126 logging_levels = [logging.ERROR, logging.WARN, logging.INFO, logging.DEBUG]
127 logging.basicConfig(level=logging_levels[options.verbosity])
128 DownloadDEPS(options.deps_filename)
129
130
131 if __name__ == "__main__":
nduca 2013/01/05 01:28:19 Ditch the __name__ bit as well as the #! bit. If s
wiltzius 2013/01/08 02:53:34 Done.
132 Main()
nduca 2013/01/05 01:28:19 Lets add the stuff that you had in __main__ into t
nduca 2013/01/05 01:28:19 Lets move this to tools/telemetry/tools/telemetry_
wiltzius 2013/01/08 02:53:34 I will do this in a follow-up patch after this boo
OLDNEW
« no previous file with comments | « tools/telemetry/DEPS ('k') | tools/telemetry/third_party/davclient/README.chromium » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698