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

Unified 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, 12 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
« no previous file with comments | « tools/telemetry/DEPS ('k') | tools/telemetry/third_party/davclient/README.chromium » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/telemetry/telemetry_bootstrap.py
===================================================================
--- tools/telemetry/telemetry_bootstrap.py (revision 0)
+++ tools/telemetry/telemetry_bootstrap.py (revision 0)
@@ -0,0 +1,132 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 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.
+
+"""Bootstrap Chrome Telemetry by downloading all its files from SVN servers.
+
+Requires a DEPS file to specify which directories on which SVN servers
+are required to run Telemetry. Format of that DEPS file is a subset of the
+normal DEPS file format[1]; currently only only the "deps" dictionary is
+supported and nothing else.
+
+DEPS can be specified with --deps or defaults to ./DEPS
+
+Fetches all files in the specified directories using WebDAV (SVN is WebDAV under
+the hood).
+
+[1] http://dev.chromium.org/developers/how-tos/depottools#TOC-DEPS-file
+"""
+
+import imp
+import logging
+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.
+import os
+import urllib
+import urlparse
+
+# default DEPS filename
+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.
+# 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.
+#TODO(wiltzius) change this to point at Chromium SVN server after checkin
nduca 2013/01/05 01:28:19 # TODO(wiltzius):
+DAVCLIENT_URL = 'http://svn.osafoundation.org/tools/davclient/trunk/src/davclient/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.
+
+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.
+ """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.
+ global davclient
+ 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.
+ davclient = imp.new_module('davclient')
+ exec davclient_txt in davclient.__dict__
+
+
+class DAVClientWrapper():
+ """Knows how to retrieve subdirectories and files from WebDAV/SVN servers."""
+
+ def __init__(self, root_url):
+ """Initialize SVN server root_url, save files to local dest_dir.
+
+ Args:
+ root_url: string url of SVN/WebDAV server
+ """
+ self.root_url = root_url
+ self.client = davclient.DAVClient(root_url)
+
+ def GetSubdirs(self, path):
+ """Returns string names of all subdirs of this path on the SVN server."""
+ props = self.client.propfind(path, depth=1)
+ return map(os.path.basename, props.keys())
+
+ def IsFile(self, path):
+ """Returns True if the path is a file on the server, False if directory."""
+ props = self.client.propfind(path, depth=1)
+ # build up normalized path list since paths to directories may or may not
+ # have trailing slashes
+ norm_keys = {}
+ for entry in props.keys():
+ norm_keys[os.path.normpath(entry)] = entry
+ return props[norm_keys[os.path.normpath(path)]]['resourcetype'] is None
+
+ def Traverse(self, src_path, dst_path):
+ """Walks the directory hierarchy pointed to by src_path download all files.
+
+ Recursively walks src_path and saves all files and subfolders into
+ dst_path.
+
+ Args:
+ src_path: string path on SVN server to save (absolute path on server).
+ dest_path: string local path (relative or absolute) to save to.
+ """
+ if self.IsFile(src_path):
+ if not os.path.exists(os.path.dirname(dst_path)):
+ logging.info("creating %s", os.path.dirname(dst_path))
+ os.makedirs(os.path.dirname(dst_path))
+ logging.info("Saving %s to %s", self.root_url + src_path, dst_path)
+ urllib.urlretrieve(self.root_url + src_path, dst_path)
+ return
+ else:
+ for subdir in self.GetSubdirs(src_path):
+ if subdir:
+ self.Traverse(os.path.join(src_path, subdir),
+ os.path.join(dst_path, subdir))
+
+
+def ParseOptions():
nduca 2013/01/05 01:28:19 I think this can go away
wiltzius 2013/01/08 02:53:34 Done.
+ """Parses command-line options for the bootstrap."""
+ #TODO(wiltzius) have a --revision flag that pulls at a specific rev
+ parser = OptionParser()
+ parser.add_option("-v", "--verbosity", dest="verbosity", default=1,
+ type="int", help="logging verbosity level (0, 1, 2, 3)")
+ parser.add_option("--deps", dest="deps_filename", default=DEPS_FILE,
+ help="look for dependency manifest in this file")
+ return parser.parse_args()
+
+
+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.
+ """Saves all the dependencies in deps_path."""
+ # dynamically import davclient library
+ bootstrap_davclient()
+ with open(deps_path) as deps_file:
+ deps = imp.new_module('deps')
+ 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.
+ #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.
+ # 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.
+ destination_dir = os.getcwd()
+ for dst_path, src_path in deps.deps.iteritems():
+ parsed_url = urlparse.urlparse(src_path)
+ 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
+ dav_client = DAVClientWrapper(root_url)
+ dav_client.Traverse(parsed_url.path,
+ 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
+
+
+def Main():
nduca 2013/01/05 01:28:19 not needed I think.
wiltzius 2013/01/08 02:53:34 Done.
+ """Fetches files specified in dependency manifest from SVN/WebDAV server."""
+ options = ParseOptions()[0]
+ # set logging level per verbosity
+ logging_levels = [logging.ERROR, logging.WARN, logging.INFO, logging.DEBUG]
+ logging.basicConfig(level=logging_levels[options.verbosity])
+ DownloadDEPS(options.deps_filename)
+
+
+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.
+ 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
Property changes on: tools/telemetry/telemetry_bootstrap.py
___________________________________________________________________
Added: svn:executable
+ *
« 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