Add ability to rebaseline skimage to rebaseline.py

Skip pattern matching for skimage, since the skimage results do not
match the pattern.

Automatically fill in expectations_root and actuals_base_url when
--skimage is specified.

Requires a change to move the expectations files to the right place.
Depends on https://codereview.chromium.org/26734006

(SkipBuildBotRuns)

BUG=skia:1466
R=epoger@google.com

Review URL: https://codereview.chromium.org/26666004

git-svn-id: http://skia.googlecode.com/svn/trunk@11717 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gm/gm_json.py b/gm/gm_json.py
index 0620bca..1d8da9f 100644
--- a/gm/gm_json.py
+++ b/gm/gm_json.py
@@ -13,6 +13,7 @@
 
 # system-level imports
 import json
+import os
 
 
 # Key strings used in GM results JSON files (both expected-results.json and
@@ -82,6 +83,12 @@
 #  as a GS URL that allows credential-protected write access:
 GM_ACTUALS_ROOT_GS_URL = 'gs://chromium-skia-gm/gm'
 
+# Root directory where buildbots store skimage actual results json files.
+SKIMAGE_ACTUALS_BASE_URL = (
+    'http://chromium-skia-gm.commondatastorage.googleapis.com/skimage/actuals')
+# Root directory inside trunk where skimage expectations are stored.
+SKIMAGE_EXPECTATIONS_ROOT = os.path.join('expectations', 'skimage')
+
 # Pattern used to assemble each image's filename
 IMAGE_FILENAME_PATTERN = '(\S+)_(\S+)\.png'  # matches (testname, config)
 
diff --git a/tools/rebaseline.py b/tools/rebaseline.py
index 275d84e..76bbfe8 100755
--- a/tools/rebaseline.py
+++ b/tools/rebaseline.py
@@ -172,6 +172,8 @@
   #                   TODO(epoger): Add that capability to a review tool.
   #  mark_ignore_failure: if True, mark failures of a given test as being
   #                       ignored.
+  #  from_trybot: if True, read actual-result JSON files generated from a
+  #               trybot run rather than a waterfall run.
   def __init__(self, expectations_root, expectations_input_filename,
                expectations_output_filename, actuals_base_url,
                actuals_filename, exception_handler,
@@ -191,7 +193,10 @@
     self._notes = notes
     self._mark_unreviewed = mark_unreviewed
     self._mark_ignore_failure = mark_ignore_failure;
-    self._image_filename_re = re.compile(gm_json.IMAGE_FILENAME_PATTERN)
+    if self._tests or self._configs:
+      self._image_filename_re = re.compile(gm_json.IMAGE_FILENAME_PATTERN)
+    else:
+      self._image_filename_re = None
     self._using_svn = os.path.isdir(os.path.join(expectations_root, '.svn'))
     self._from_trybot = from_trybot
 
@@ -293,15 +298,16 @@
     skipped_images = []
     if results_to_update:
       for (image_name, image_results) in results_to_update.iteritems():
-        (test, config) = self._image_filename_re.match(image_name).groups()
-        if self._tests:
-          if test not in self._tests:
-            skipped_images.append(image_name)
-            continue
-        if self._configs:
-          if config not in self._configs:
-            skipped_images.append(image_name)
-            continue
+        if self._image_filename_re:
+          (test, config) = self._image_filename_re.match(image_name).groups()
+          if self._tests:
+            if test not in self._tests:
+              skipped_images.append(image_name)
+              continue
+          if self._configs:
+            if config not in self._configs:
+              skipped_images.append(image_name)
+              continue
         if not expected_results.get(image_name):
           expected_results[image_name] = {}
         expected_results[image_name]\
@@ -344,8 +350,10 @@
 parser.add_argument('--actuals-base-url',
                     help=('base URL from which to read files containing JSON '
                           'summaries of actual GM results; defaults to '
-                          '%(default)s. To get a specific revision (useful for'
-                          'trybots) replace "svn" with "svn-history/r123".'),
+                          '%(default)s. To get a specific revision (useful for '
+                          'trybots) replace "svn" with "svn-history/r123". '
+                          'If SKIMAGE is True, defaults to ' +
+                          gm_json.SKIMAGE_ACTUALS_BASE_URL),
                     default='http://skia-autogen.googlecode.com/svn/gm-actual')
 parser.add_argument('--actuals-filename',
                     help=('filename (within builder-specific subdirectories '
@@ -370,7 +378,8 @@
                     help=('which configurations to rebaseline, e.g. '
                           '"--configs 565 8888", as a filter over the full set '
                           'of results in ACTUALS_FILENAME; if unspecified, '
-                          'rebaseline *all* configs that are available.'))
+                          'rebaseline *all* configs that are available. '
+                          'Ignored if SKIMAGE is True.'))
 parser.add_argument('--expectations-filename',
                     help=('filename (under EXPECTATIONS_ROOT) to read '
                           'current expectations from, and to write new '
@@ -386,7 +395,8 @@
 parser.add_argument('--expectations-root',
                     help=('root of expectations directory to update-- should '
                           'contain one or more builder subdirectories. '
-                          'Defaults to %(default)s'),
+                          'Defaults to %(default)s. If SKIMAGE is set, '
+                          ' defaults to ' + gm_json.SKIMAGE_EXPECTATIONS_ROOT),
                     default=os.path.join('expectations', 'gm'))
 parser.add_argument('--keep-going-on-failure', action='store_true',
                     help=('instead of halting at the first error encountered, '
@@ -402,7 +412,7 @@
                           '"--tests aaclip bigmatrix", as a filter over the '
                           'full set of results in ACTUALS_FILENAME; if '
                           'unspecified, rebaseline *all* tests that are '
-                          'available.'))
+                          'available. Ignored if SKIMAGE is True.'))
 parser.add_argument('--unreviewed', action='store_true',
                     help=('mark all expectations modified by this run as '
                           '"%s": False' %
@@ -414,6 +424,11 @@
 parser.add_argument('--from-trybot', action='store_true',
                     help=('pull the actual-results.json file from the '
                           'corresponding trybot, rather than the main builder'))
+parser.add_argument('--skimage', action='store_true',
+                    help=('Rebaseline skimage results instead of gm. Defaults '
+                          'to False. If True, TESTS and CONFIGS are ignored, '
+                          'and ACTUALS_BASE_URL and EXPECTATIONS_ROOT are set '
+                          'to alternate defaults, specific to skimage.'))
 args = parser.parse_args()
 exception_handler = ExceptionHandler(
     keep_going_on_failure=args.keep_going_on_failure)
@@ -423,6 +438,15 @@
 else:
   builders = sorted(TEST_BUILDERS)
   missing_json_is_fatal = False
+if args.skimage:
+  # Use a different default if --skimage is specified.
+  if args.actuals_base_url == parser.get_default('actuals_base_url'):
+    args.actuals_base_url = gm_json.SKIMAGE_ACTUALS_BASE_URL
+  if args.expectations_root == parser.get_default('expectations_root'):
+    args.expectations_root = gm_json.SKIMAGE_EXPECTATIONS_ROOT
+  # Also ignore TESTS and CONFIGS
+  args.tests = None
+  args.configs = None
 for builder in builders:
   if not builder in TEST_BUILDERS:
     raise Exception(('unrecognized builder "%s"; ' +