Housekeeper-PerCommit-Bookmaker bot to verify that docs match includes

Example failure- https://chromium-swarm.appspot.com/task?id=3a97e6c00ff78010
Example success- https://chromium-swarm.appspot.com/task?id=3a9814b474fcf910

Bug: skia:7432
Change-Id: I2459b7568ac2d12a0ed81b1eec9ddd61cff5b643
Reviewed-on: https://skia-review.googlesource.com/87767
Commit-Queue: Ravi Mistry <rmistry@google.com>
Reviewed-by: Eric Boren <borenet@google.com>
diff --git a/infra/bots/recipes/bookmaker.py b/infra/bots/recipes/bookmaker.py
index bc8b7e7..6b9d564 100644
--- a/infra/bots/recipes/bookmaker.py
+++ b/infra/bots/recipes/bookmaker.py
@@ -50,64 +50,84 @@
   with api.context(cwd=api.vars.skia_dir, env=api.infra.go_env):
     bookmaker_binary = api.path.join(api.vars.skia_out, api.vars.configuration,
                                      'bookmaker')
-    fiddlecli_binary = api.path.join(api.infra.gopath, 'bin', 'fiddlecli')
-    fiddlecli_input = api.path.join(api.path['start_dir'], 'fiddle.json')
-    fiddlecli_output = api.path.join(api.path['start_dir'], 'fiddleout.json')
+    buildername = api.vars.builder_name
 
-    # Step 1: Extract all fiddles out of markdown files.
-    cmd = [bookmaker_binary,
-           '-a', 'docs/status.json',  # File containing status of documentation.
-           '-e', fiddlecli_input,  # Fiddle cli input.
-           ]
-    api.run(api.step, 'Extract all fiddles out of md files', cmd=cmd)
+    if 'PerCommit' in buildername:
+      # Check to see if docs matches include/core.
+      cmd = [bookmaker_binary,
+             '-a', 'docs/status.json',  # File containing status of docs.
+             '-x',  # Check bmh against includes.
+             ]
+      try:
+        api.run(api.step, 'Validate docs match include/core/*.h', cmd=cmd)
+      except api.step.StepFailure as e:
+        # Display what needs to be fixed.
+        e.reason += (
+            '\n\nView the output of the "Validate docs match include/core/*.h" '
+            'step to see how to get this bot green.'
+            '\n\nhttps://skia.org/user/api/usingBookmaker details how to build '
+            'and run the bookmaker utility locally if needed.')
+        raise e
 
-    # Step 2: Forces fiddle.skia.org to compile all fiddles extracted out of
-    #         markdown files and get output in JSON.
-    cmd = [fiddlecli_binary,
-           '--input', fiddlecli_input,
-           '--output', fiddlecli_output,
-           '--logtostderr',
-           '--force',
-        ]
-    api.run(api.step, 'Force fiddle to compile all examples', cmd=cmd)
+    elif 'Nightly' in buildername:
+      fiddlecli_binary = api.path.join(api.infra.gopath, 'bin', 'fiddlecli')
+      fiddlecli_input = api.path.join(api.path['start_dir'], 'fiddle.json')
+      fiddlecli_output = api.path.join(api.path['start_dir'], 'fiddleout.json')
 
-    # Step 3: Scan the output of fiddlecli for any compiletime/runtime errors.
-    #         Fail the recipe is there are any errors and summarize results at
-    #         the end.
-    if api.path.exists(fiddlecli_output):
-      test_data = api.properties.get('fiddleout_test_data', '{}')
-      content = api.file.read_text('Read fiddleout.json',
-                                   fiddlecli_output, test_data=test_data)
-      out = json.loads(content)
-      # Do a dump of fiddlecli_output. Will be useful for debugging.
-      print 'Dump of %s:' % fiddlecli_output
-      print json.dumps(out, indent=4)
+      # Step 1: Extract all fiddles out of markdown files.
+      cmd = [bookmaker_binary,
+             '-a', 'docs/status.json',  # File containing status of docs.
+             '-e', fiddlecli_input,  # Fiddle cli input.
+             ]
+      api.run(api.step, 'Extract all fiddles out of md files', cmd=cmd)
 
-      failing_fiddles = []
-      for fiddle_name in out:
-        props = out[fiddle_name]
-        if props['compile_errors'] or props['runtime_error']:
-          failing_fiddles.append(props['fiddleHash'])
-      if failing_fiddles:
-        # create an eror message and fail the bot!
-        failure_msg = 'The following fiddles failed:\n\n'
-        for fiddle_hash in failing_fiddles:
-          failure_msg += 'https://fiddle.skia.org/c/%s\n' % fiddle_hash
-        raise api.step.StepFailure(failure_msg)
+      # Step 2: Forces fiddle.skia.org to compile all fiddles extracted out of
+      #         markdown files and get output in JSON.
+      cmd = [fiddlecli_binary,
+             '--input', fiddlecli_input,
+             '--output', fiddlecli_output,
+             '--logtostderr',
+             '--force',
+          ]
+      api.run(api.step, 'Force fiddle to compile all examples', cmd=cmd)
 
-    # Step 4: Update docs in site/user/api/ with the output of fiddlecli.
-    #         If there are any new changes then upload and commit the changes.
-    update_docs_gitcookies = api.path['start_dir'].join(
-        UPDATE_DOCS_GITCOOKIES_FILE)
-    cmd = ['python',
-           api.vars.skia_dir.join('infra', 'bots', 'upload_md.py'),
-           '--bookmaker_binary', bookmaker_binary,
-           '--fiddlecli_output', fiddlecli_output,
-           '--gitcookies', str(update_docs_gitcookies)]
-    with api.infra.DownloadGitCookies(
-        UPDATE_DOCS_GITCOOKIES_GS_PATH, update_docs_gitcookies, api):
-      with api.context(cwd=api.vars.skia_dir, env=api.infra.go_env):
-        api.run(api.step, 'Generate and Upload Markdown files', cmd=cmd)
+      # Step 3: Scan the output of fiddlecli for any compiletime/runtime errors.
+      #         Fail the recipe is there are any errors and summarize results at
+      #         the end.
+      if api.path.exists(fiddlecli_output):
+        test_data = api.properties.get('fiddleout_test_data', '{}')
+        content = api.file.read_text('Read fiddleout.json',
+                                     fiddlecli_output, test_data=test_data)
+        out = json.loads(content)
+        # Do a dump of fiddlecli_output. Will be useful for debugging.
+        print 'Dump of %s:' % fiddlecli_output
+        print json.dumps(out, indent=4)
+
+        failing_fiddles = []
+        for fiddle_name in out:
+          props = out[fiddle_name]
+          if props['compile_errors'] or props['runtime_error']:
+            failing_fiddles.append(props['fiddleHash'])
+        if failing_fiddles:
+          # create an eror message and fail the bot!
+          failure_msg = 'The following fiddles failed:\n\n'
+          for fiddle_hash in failing_fiddles:
+            failure_msg += 'https://fiddle.skia.org/c/%s\n' % fiddle_hash
+          raise api.step.StepFailure(failure_msg)
+
+      # Step 4: Update docs in site/user/api/ with the output of fiddlecli.
+      #         If there are any new changes then upload and commit the changes.
+      update_docs_gitcookies = api.path['start_dir'].join(
+          UPDATE_DOCS_GITCOOKIES_FILE)
+      cmd = ['python',
+             api.vars.skia_dir.join('infra', 'bots', 'upload_md.py'),
+            '--bookmaker_binary', bookmaker_binary,
+             '--fiddlecli_output', fiddlecli_output,
+            '--gitcookies', str(update_docs_gitcookies)]
+      with api.infra.DownloadGitCookies(
+         UPDATE_DOCS_GITCOOKIES_GS_PATH, update_docs_gitcookies, api):
+        with api.context(cwd=api.vars.skia_dir, env=api.infra.go_env):
+          api.run(api.step, 'Generate and Upload Markdown files', cmd=cmd)
 
 
 def GenTests(api):
@@ -122,7 +142,26 @@
              "runtime_error": "runtime error"}}
 """
   yield (
-      api.test('bookmaker') +
+      api.test('percommit_bookmaker') +
+      api.properties(buildername='Housekeeper-PerCommit-Bookmaker',
+                     repository='https://skia.googlesource.com/skia.git',
+                     revision='abc123',
+                     path_config='kitchen',
+                     swarm_out_dir='[SWARM_OUT_DIR]')
+  )
+
+  yield (
+      api.test('percommit_failed_validation') +
+      api.properties(buildername='Housekeeper-PerCommit-Bookmaker',
+                     repository='https://skia.googlesource.com/skia.git',
+                     revision='abc123',
+                     path_config='kitchen',
+                     swarm_out_dir='[SWARM_OUT_DIR]') +
+      api.step_data('Validate docs match include/core/*.h', retcode=1)
+  )
+
+  yield (
+      api.test('nightly_bookmaker') +
       api.properties(buildername='Housekeeper-Nightly-Bookmaker',
                      repository='https://skia.googlesource.com/skia.git',
                      revision='abc123',
@@ -134,7 +173,7 @@
   )
 
   yield (
-      api.test('failed_fiddles') +
+      api.test('nightly_failed_fiddles') +
       api.properties(buildername='Housekeeper-Nightly-Bookmaker',
                      repository='https://skia.googlesource.com/skia.git',
                      revision='abc123',
@@ -145,7 +184,7 @@
   )
 
   yield (
-      api.test('failed_extract_fiddles') +
+      api.test('nightly_failed_extract_fiddles') +
       api.properties(buildername='Housekeeper-Nightly-Bookmaker',
                      repository='https://skia.googlesource.com/skia.git',
                      revision='abc123',
@@ -155,7 +194,7 @@
   )
 
   yield (
-      api.test('failed_fiddlecli') +
+      api.test('nightly_failed_fiddlecli') +
       api.properties(buildername='Housekeeper-Nightly-Bookmaker',
                      repository='https://skia.googlesource.com/skia.git',
                      revision='abc123',
@@ -165,7 +204,7 @@
   )
 
   yield (
-      api.test('failed_upload') +
+      api.test('nightly_failed_upload') +
       api.properties(buildername='Housekeeper-Nightly-Bookmaker',
                      repository='https://skia.googlesource.com/skia.git',
                      revision='abc123',