• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2017 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5# Recipe which:
6# 1) Extracts all fiddles out of markdown files.
7# 2) Forces fiddle.skia.org to compile all those fiddles and get output in JSON.
8# 3) Scans the output and reports any compiletime/runtime errors.
9# 4) Updates markdown in site/user/api/ using the new hashes (if any) from
10#    fiddle.skia.org.
11
12import json
13
14
15DEPS = [
16  'recipe_engine/context',
17  'recipe_engine/file',
18  'recipe_engine/path',
19  'recipe_engine/properties',
20  'recipe_engine/step',
21  'core',
22  'infra',
23  'run',
24  'vars',
25]
26
27UPDATE_DOCS_GITCOOKIES_FILE = 'update_docs.git_cookies'
28UPDATE_DOCS_GITCOOKIES_GS_PATH = (
29    'gs://skia-buildbots/artifacts/server/.gitcookies_update-docs')
30
31
32def go_get_fiddlecli(api):
33  env = api.context.env
34  env.update(api.infra.go_env)
35  with api.context(env=env):
36    api.run.with_retry(
37        api.step,
38        'go get fiddlecli',
39        5,  # Update attempts.
40        cmd=[api.infra.go_exe, 'get', '-u', '-t',
41             'go.skia.org/infra/fiddle/go/fiddlecli'])
42
43
44def RunSteps(api):
45  api.vars.setup()
46  api.core.checkout_steps()
47  api.infra.go_version()
48  go_get_fiddlecli(api)
49
50  with api.context(cwd=api.vars.skia_dir, env=api.infra.go_env):
51    bookmaker_binary = api.path.join(api.vars.skia_out, api.vars.configuration,
52                                     'bookmaker')
53    buildername = api.vars.builder_name
54
55    if 'PerCommit' in buildername:
56      # Check to see if docs matches include/core.
57      cmd = [bookmaker_binary,
58             '-a', 'docs/status.json',  # File containing status of docs.
59             '-x',  # Check bmh against includes.
60             ]
61      try:
62        api.run(api.step, 'Validate docs match include/core/*.h', cmd=cmd)
63      except api.step.StepFailure as e:
64        # Display what needs to be fixed.
65        e.reason += (
66            '\n\nView the output of the "Validate docs match include/core/*.h" '
67            'step to see how to get this bot green.'
68            '\n\nhttps://skia.org/user/api/usingBookmaker details how to build '
69            'and run the bookmaker utility locally if needed.')
70        raise e
71
72    elif 'Nightly' in buildername:
73      fiddlecli_binary = api.path.join(api.infra.gopath, 'bin', 'fiddlecli')
74      fiddlecli_input = api.path.join(api.path['start_dir'], 'fiddle.json')
75      fiddlecli_output = api.path.join(api.path['start_dir'], 'fiddleout.json')
76
77      # Step 1: Extract all fiddles out of markdown files.
78      cmd = [bookmaker_binary,
79             '-a', 'docs/status.json',  # File containing status of docs.
80             '-e', fiddlecli_input,  # Fiddle cli input.
81             ]
82      api.run(api.step, 'Extract all fiddles out of md files', cmd=cmd)
83
84      # Step 2: Forces fiddle.skia.org to compile all fiddles extracted out of
85      #         markdown files and get output in JSON.
86      cmd = [fiddlecli_binary,
87             '--input', fiddlecli_input,
88             '--output', fiddlecli_output,
89             '--logtostderr',
90             '--force',
91          ]
92      api.run(api.step, 'Force fiddle to compile all examples', cmd=cmd)
93
94      # Step 3: Scan the output of fiddlecli for any compiletime/runtime errors.
95      #         Fail the recipe is there are any errors and summarize results at
96      #         the end.
97      if api.path.exists(fiddlecli_output):
98        test_data = api.properties.get('fiddleout_test_data', '{}')
99        content = api.file.read_text('Read fiddleout.json',
100                                     fiddlecli_output, test_data=test_data)
101        out = json.loads(content)
102        # Do a dump of fiddlecli_output. Will be useful for debugging.
103        print 'Dump of %s:' % fiddlecli_output
104        print json.dumps(out, indent=4)
105
106        failing_fiddles = []
107        for fiddle_name in out:
108          props = out[fiddle_name]
109          if props['compile_errors'] or props['runtime_error']:
110            failing_fiddles.append(props['fiddleHash'])
111        if failing_fiddles:
112          # create an eror message and fail the bot!
113          failure_msg = 'The following fiddles failed:\n\n'
114          for fiddle_hash in failing_fiddles:
115            failure_msg += 'https://fiddle.skia.org/c/%s\n' % fiddle_hash
116          raise api.step.StepFailure(failure_msg)
117
118      # Step 4: Update docs in site/user/api/ with the output of fiddlecli.
119      #         If there are any new changes then upload and commit the changes.
120      update_docs_gitcookies = api.path['start_dir'].join(
121          UPDATE_DOCS_GITCOOKIES_FILE)
122      cmd = ['python',
123             api.vars.skia_dir.join('infra', 'bots', 'upload_md.py'),
124            '--bookmaker_binary', bookmaker_binary,
125             '--fiddlecli_output', fiddlecli_output,
126            '--gitcookies', str(update_docs_gitcookies)]
127      with api.infra.DownloadGitCookies(
128         UPDATE_DOCS_GITCOOKIES_GS_PATH, update_docs_gitcookies, api):
129        with api.context(cwd=api.vars.skia_dir, env=api.infra.go_env):
130          api.run(api.step, 'Generate and Upload Markdown files', cmd=cmd)
131
132
133def GenTests(api):
134  fiddleout_no_errors_test_data = """
135{"fiddle1": {"fiddleHash": "abc",
136             "compile_errors": [],
137             "runtime_error": ""}}
138"""
139  fiddleout_with_errors_test_data = """
140{"fiddle1": {"fiddleHash": "abc",
141             "compile_errors": [],
142             "runtime_error": "runtime error"}}
143"""
144  yield (
145      api.test('percommit_bookmaker') +
146      api.properties(buildername='Housekeeper-PerCommit-Bookmaker',
147                     repository='https://skia.googlesource.com/skia.git',
148                     revision='abc123',
149                     path_config='kitchen',
150                     swarm_out_dir='[SWARM_OUT_DIR]')
151  )
152
153  yield (
154      api.test('percommit_failed_validation') +
155      api.properties(buildername='Housekeeper-PerCommit-Bookmaker',
156                     repository='https://skia.googlesource.com/skia.git',
157                     revision='abc123',
158                     path_config='kitchen',
159                     swarm_out_dir='[SWARM_OUT_DIR]') +
160      api.step_data('Validate docs match include/core/*.h', retcode=1)
161  )
162
163  yield (
164      api.test('nightly_bookmaker') +
165      api.properties(buildername='Housekeeper-Nightly-Bookmaker',
166                     repository='https://skia.googlesource.com/skia.git',
167                     revision='abc123',
168                     path_config='kitchen',
169                     fiddleout_test_data=fiddleout_no_errors_test_data,
170                     swarm_out_dir='[SWARM_OUT_DIR]') +
171      api.path.exists(api.path['start_dir'].join('fiddleout.json'),
172                      api.path['start_dir'].join(UPDATE_DOCS_GITCOOKIES_FILE))
173  )
174
175  yield (
176      api.test('nightly_failed_fiddles') +
177      api.properties(buildername='Housekeeper-Nightly-Bookmaker',
178                     repository='https://skia.googlesource.com/skia.git',
179                     revision='abc123',
180                     path_config='kitchen',
181                     fiddleout_test_data=fiddleout_with_errors_test_data,
182                     swarm_out_dir='[SWARM_OUT_DIR]') +
183      api.path.exists(api.path['start_dir'].join('fiddleout.json'))
184  )
185
186  yield (
187      api.test('nightly_failed_extract_fiddles') +
188      api.properties(buildername='Housekeeper-Nightly-Bookmaker',
189                     repository='https://skia.googlesource.com/skia.git',
190                     revision='abc123',
191                     path_config='kitchen',
192                     swarm_out_dir='[SWARM_OUT_DIR]') +
193      api.step_data('Extract all fiddles out of md files', retcode=1)
194  )
195
196  yield (
197      api.test('nightly_failed_fiddlecli') +
198      api.properties(buildername='Housekeeper-Nightly-Bookmaker',
199                     repository='https://skia.googlesource.com/skia.git',
200                     revision='abc123',
201                     path_config='kitchen',
202                     swarm_out_dir='[SWARM_OUT_DIR]') +
203      api.step_data('Force fiddle to compile all examples', retcode=1)
204  )
205
206  yield (
207      api.test('nightly_failed_upload') +
208      api.properties(buildername='Housekeeper-Nightly-Bookmaker',
209                     repository='https://skia.googlesource.com/skia.git',
210                     revision='abc123',
211                     path_config='kitchen',
212                     swarm_out_dir='[SWARM_OUT_DIR]') +
213      api.step_data('Generate and Upload Markdown files', retcode=1)
214  )
215