blob: da67743a4c8290f5ef0c370dcaddc2c433f18e32 [file] [log] [blame]
epoger@google.com27442af2011-12-29 21:13:08 +00001'''
2Downloads the actual gm results most recently generated by the Skia buildbots,
3and adds any new ones to SVN control.
4
5This tool makes it much easier to check in new baselines, via the following
6steps:
7
8cd .../trunk
9svn update
10# make sure there are no files awaiting svn commit
epoger@google.comd6256552012-01-10 14:10:34 +000011python tools/download-baselines.py gm/base-macmini-lion-fixed # or other gm/ subdir
epoger@google.comfc241ee2012-02-02 16:49:49 +000012# validate that the new images look right (maybe using compare-baselines.py)
epoger@google.com27442af2011-12-29 21:13:08 +000013# upload CL for review
epoger@google.comfc241ee2012-02-02 16:49:49 +000014# validate that the new images look right in the review tool
epoger@google.com27442af2011-12-29 21:13:08 +000015# commit CL
16
epoger@google.comd6256552012-01-10 14:10:34 +000017Launch with --help to see more options.
18
epoger@google.com27442af2011-12-29 21:13:08 +000019
20Copyright 2011 Google Inc.
21
22Use of this source code is governed by a BSD-style license that can be
23found in the LICENSE file.
24'''
25
26# common Python modules
epoger@google.com20ad5ac2012-01-17 21:26:05 +000027import fnmatch
epoger@google.comd6256552012-01-10 14:10:34 +000028import optparse
29import os
epoger@google.com27442af2011-12-29 21:13:08 +000030import re
epoger@google.com20ad5ac2012-01-17 21:26:05 +000031import shutil
epoger@google.com27442af2011-12-29 21:13:08 +000032import sys
epoger@google.com20ad5ac2012-01-17 21:26:05 +000033import tempfile
epoger@google.com27442af2011-12-29 21:13:08 +000034
35# modules declared within this same directory
36import svn
37
epoger@google.com20ad5ac2012-01-17 21:26:05 +000038# Base URL of SVN repository where buildbots store actual gm image results.
39SVN_BASE_URL = 'http://skia-autogen.googlecode.com/svn/gm-actual'
epoger@google.com27442af2011-12-29 21:13:08 +000040
epoger@google.comd6256552012-01-10 14:10:34 +000041USAGE_STRING = 'usage: %s [options] <baseline_subdir>'
42OPTION_IGNORE_LOCAL_MODS = '--ignore-local-mods'
43OPTION_ADD_NEW_FILES = '--add-new-files'
44
epoger@google.com20ad5ac2012-01-17 21:26:05 +000045def GetLatestResultsSvnUrl(baseline_subdir):
46 """Return SVN URL from which we can check out the MOST RECENTLY generated
epoger@google.com27442af2011-12-29 21:13:08 +000047 images for this baseline type.
48
49 @param baseline_subdir indicates which platform we want images for
50 """
epoger@google.com20ad5ac2012-01-17 21:26:05 +000051 # trim off 'gm/' prefix
52 gm_prefix = 'gm%s' % os.sep
53 if not baseline_subdir.startswith(gm_prefix):
54 raise Exception('baseline_subdir "%s" should start with "%s"' % (
55 baseline_subdir, gm_prefix))
56 return '%s/%s' % (SVN_BASE_URL, baseline_subdir[len(gm_prefix):])
epoger@google.com27442af2011-12-29 21:13:08 +000057
epoger@google.com20ad5ac2012-01-17 21:26:05 +000058def CopyMatchingFiles(source_dir, dest_dir, filename_pattern,
59 only_copy_updates=False):
60 """Copy all files from source_dir that match filename_pattern, and
61 save them (with their original filenames) in dest_dir.
epoger@google.com27442af2011-12-29 21:13:08 +000062
epoger@google.com20ad5ac2012-01-17 21:26:05 +000063 @param source_dir
64 @param dest_dir where to save the copied files
65 @param filename_pattern only copy files that match this Unix-style filename
66 pattern (e.g., '*.jpg')
67 @param only_copy_updates if True, only copy files that are already
68 present in dest_dir
epoger@google.com27442af2011-12-29 21:13:08 +000069 """
epoger@google.com20ad5ac2012-01-17 21:26:05 +000070 all_filenames = os.listdir(source_dir)
71 matching_filenames = fnmatch.filter(all_filenames, filename_pattern)
72 for filename in matching_filenames:
73 source_path = os.path.join(source_dir, filename)
74 dest_path = os.path.join(dest_dir, filename)
75 if only_copy_updates and not os.path.isfile(dest_path):
epoger@google.comd6256552012-01-10 14:10:34 +000076 continue
epoger@google.com20ad5ac2012-01-17 21:26:05 +000077 shutil.copyfile(source_path, dest_path)
epoger@google.com27442af2011-12-29 21:13:08 +000078
epoger@google.comd6256552012-01-10 14:10:34 +000079def Main(options, args):
epoger@google.com27442af2011-12-29 21:13:08 +000080 """Download most recently generated baseline images for a given platform,
81 and add any new ones to SVN control.
82
epoger@google.comd6256552012-01-10 14:10:34 +000083 @param options
84 @param args
epoger@google.com27442af2011-12-29 21:13:08 +000085 """
epoger@google.comd6256552012-01-10 14:10:34 +000086 num_args = len(args)
87 if num_args != 1:
88 RaiseUsageException()
epoger@google.com27442af2011-12-29 21:13:08 +000089
epoger@google.com20ad5ac2012-01-17 21:26:05 +000090 # Create repo_to_modify to handle the SVN repository we will add files to.
91 baseline_subdir = args[0].rstrip(os.sep);
92 if not os.path.isdir(baseline_subdir):
93 raise Exception('could not find baseline_subdir "%s"' % baseline_subdir)
94 repo_to_modify = svn.Svn(baseline_subdir)
epoger@google.comd6256552012-01-10 14:10:34 +000095
96 # If there are any locally modified files in that directory, exit
97 # (so that we don't risk overwriting the user's previous work).
epoger@google.com20ad5ac2012-01-17 21:26:05 +000098 new_and_modified_files = repo_to_modify.GetNewAndModifiedFiles()
epoger@google.comd6256552012-01-10 14:10:34 +000099 if not options.ignore_local_mods:
100 if new_and_modified_files:
101 raise Exception('Exiting because there are already new and/or '
102 'modified files in %s. To continue in spite of '
103 'that, run with %s option.' % (
104 baseline_subdir, OPTION_IGNORE_LOCAL_MODS))
105
epoger@google.com20ad5ac2012-01-17 21:26:05 +0000106 # Download actual gm images into a separate repo in a temporary directory.
107 tempdir = tempfile.mkdtemp()
108 download_repo = svn.Svn(tempdir)
109 download_repo.Checkout(GetLatestResultsSvnUrl(baseline_subdir), '.')
110
111 # Copy any of those files we are interested in into repo_to_modify,
112 # and then delete the temporary directory.
113 CopyMatchingFiles(source_dir=tempdir, dest_dir=baseline_subdir,
114 filename_pattern='*.png',
115 only_copy_updates=(not options.add_new_files))
116 shutil.rmtree(tempdir)
117 download_repo = None
epoger@google.comd6256552012-01-10 14:10:34 +0000118
119 # Add any new files to SVN control (if we are running with add_new_files).
epoger@google.com20ad5ac2012-01-17 21:26:05 +0000120 new_files = repo_to_modify.GetNewFiles()
epoger@google.comd6256552012-01-10 14:10:34 +0000121 if new_files and options.add_new_files:
epoger@google.com20ad5ac2012-01-17 21:26:05 +0000122 repo_to_modify.AddFiles(new_files)
123
124 # Set the mimetype property on *all* image files in baseline_subdir, even
125 # the ones that were already there (in case that property wasn't properly
126 # set already).
127 repo_to_modify.SetPropertyByFilenamePattern(
128 '*.png', svn.PROPERTY_MIMETYPE, 'image/png')
129 repo_to_modify.SetPropertyByFilenamePattern(
130 '*.pdf', svn.PROPERTY_MIMETYPE, 'application/pdf')
epoger@google.com27442af2011-12-29 21:13:08 +0000131
epoger@google.comd6256552012-01-10 14:10:34 +0000132def RaiseUsageException():
133 raise Exception(USAGE_STRING % __file__)
134
epoger@google.com27442af2011-12-29 21:13:08 +0000135if __name__ == '__main__':
epoger@google.comd6256552012-01-10 14:10:34 +0000136 parser = optparse.OptionParser(USAGE_STRING % '%prog')
137 parser.add_option(OPTION_IGNORE_LOCAL_MODS,
138 action='store_true', default=False,
139 help='allow tool to run even if there are already '
140 'local modifications in the baseline_subdir')
141 parser.add_option(OPTION_ADD_NEW_FILES,
142 action='store_true', default=False,
143 help='in addition to downloading new versions of '
144 'existing baselines, also download baselines that are '
145 'not under SVN control yet')
146 (options, args) = parser.parse_args()
147 Main(options, args)