• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!--- AUTOGENERATED BY `./recipes.py test train` -->
2# Repo documentation for [skia]()
3## Table of Contents
4
5**[Recipe Modules](#Recipe-Modules)**
6  * [build](#recipe_modules-build) &mdash; Build Skia for various platforms.
7  * [builder_name_schema](#recipe_modules-builder_name_schema)
8  * [checkout](#recipe_modules-checkout)
9  * [docker](#recipe_modules-docker)
10  * [doxygen](#recipe_modules-doxygen)
11  * [env](#recipe_modules-env)
12  * [flavor](#recipe_modules-flavor)
13  * [git](#recipe_modules-git)
14  * [gold_upload](#recipe_modules-gold_upload)
15  * [gsutil](#recipe_modules-gsutil)
16  * [infra](#recipe_modules-infra)
17  * [run](#recipe_modules-run)
18  * [vars](#recipe_modules-vars)
19  * [xcode](#recipe_modules-xcode)
20
21**[Recipes](#Recipes)**
22  * [build:examples/full](#recipes-build_examples_full)
23  * [builder_name_schema:examples/full](#recipes-builder_name_schema_examples_full)
24  * [checkout:examples/full](#recipes-checkout_examples_full)
25  * [compile](#recipes-compile)
26  * [compute_buildstats](#recipes-compute_buildstats)
27  * [docker:examples/full](#recipes-docker_examples_full)
28  * [doxygen:examples/full](#recipes-doxygen_examples_full)
29  * [env:examples/full](#recipes-env_examples_full)
30  * [flavor:examples/full](#recipes-flavor_examples_full)
31  * [git:examples/full](#recipes-git_examples_full)
32  * [gold_upload:examples/full](#recipes-gold_upload_examples_full)
33  * [gsutil:examples/full](#recipes-gsutil_examples_full)
34  * [housekeeper](#recipes-housekeeper)
35  * [infra](#recipes-infra)
36  * [infra:examples/full](#recipes-infra_examples_full)
37  * [perf](#recipes-perf)
38  * [perf_pathkit](#recipes-perf_pathkit)
39  * [perf_skottietrace](#recipes-perf_skottietrace)
40  * [perf_skottiewasm_lottieweb](#recipes-perf_skottiewasm_lottieweb)
41  * [run:examples/full](#recipes-run_examples_full)
42  * [sync_and_compile](#recipes-sync_and_compile)
43  * [test](#recipes-test)
44  * [test_canvaskit](#recipes-test_canvaskit)
45  * [test_lottie_web](#recipes-test_lottie_web)
46  * [test_pathkit](#recipes-test_pathkit)
47  * [upload_buildstats_results](#recipes-upload_buildstats_results)
48  * [upload_dm_results](#recipes-upload_dm_results)
49  * [upload_nano_results](#recipes-upload_nano_results)
50  * [vars:examples/full](#recipes-vars_examples_full)
51  * [xcode:examples/full](#recipes-xcode_examples_full)
52## Recipe Modules
53
54### *recipe_modules* / [build](/infra/bots/recipe_modules/build)
55
56[DEPS](/infra/bots/recipe_modules/build/__init__.py#7): [depot\_tools/gclient][depot_tools/recipe_modules/gclient], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/step][recipe_engine/recipe_modules/step], [docker](#recipe_modules-docker), [env](#recipe_modules-env), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars), [xcode](#recipe_modules-xcode)
57
58
59Build Skia for various platforms.
60
61#### **class [BuildApi](/infra/bots/recipe_modules/build/api.py#20)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
62
63&mdash; **def [\_\_call\_\_](/infra/bots/recipe_modules/build/api.py#47)(self, checkout_root, out_dir):**
64
65Compile the code.
66
67&mdash; **def [copy\_build\_products](/infra/bots/recipe_modules/build/api.py#51)(self, out_dir, dst):**
68
69Copy selected build products to dst.
70### *recipe_modules* / [builder\_name\_schema](/infra/bots/recipe_modules/builder_name_schema)
71
72
73#### **class [BuilderNameSchemaApi](/infra/bots/recipe_modules/builder_name_schema/api.py#14)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
74
75&mdash; **def [DictForBuilderName](/infra/bots/recipe_modules/builder_name_schema/api.py#32)(self, \*args, \*\*kwargs):**
76
77&mdash; **def [MakeBuilderName](/infra/bots/recipe_modules/builder_name_schema/api.py#29)(self, \*\*kwargs):**
78### *recipe_modules* / [checkout](/infra/bots/recipe_modules/checkout)
79
80[DEPS](/infra/bots/recipe_modules/checkout/__init__.py#7): [depot\_tools/bot\_update][depot_tools/recipe_modules/bot_update], [depot\_tools/gclient][depot_tools/recipe_modules/gclient], [depot\_tools/git][depot_tools/recipe_modules/git], [depot\_tools/tryserver][depot_tools/recipe_modules/tryserver], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [run](#recipe_modules-run), [vars](#recipe_modules-vars)
81
82
83#### **class [CheckoutApi](/infra/bots/recipe_modules/checkout/api.py#13)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
84
85&mdash; **def [assert\_git\_is\_from\_cipd](/infra/bots/recipe_modules/checkout/api.py#20)(self):**
86
87Fail if git is not obtained from CIPD.
88
89&mdash; **def [bot\_update](/infra/bots/recipe_modules/checkout/api.py#39)(self, checkout_root, gclient_cache=None, skip_patch=False, override_revision=None):**
90
91Run the steps to obtain a checkout using bot_update.
92
93Args:
94  checkout_root: Root directory where the code will be synced.
95  gclient_cache: Optional, directory of the gclient cache.
96  skip_patch: Ignore changelist/patchset when syncing the Skia repo.
97
98&emsp; **@property**<br>&mdash; **def [default\_checkout\_root](/infra/bots/recipe_modules/checkout/api.py#15)(self):**
99
100The default location for cached persistent checkouts.
101
102&mdash; **def [git](/infra/bots/recipe_modules/checkout/api.py#26)(self, checkout_root):**
103
104Run the steps to perform a pure-git checkout without DEPS.
105### *recipe_modules* / [docker](/infra/bots/recipe_modules/docker)
106
107[DEPS](/infra/bots/recipe_modules/docker/__init__.py#8): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [env](#recipe_modules-env), [run](#recipe_modules-run)
108
109
110#### **class [DockerApi](/infra/bots/recipe_modules/docker/api.py#15)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
111
112&mdash; **def [mount\_out](/infra/bots/recipe_modules/docker/api.py#27)(self):**
113
114&mdash; **def [mount\_src](/infra/bots/recipe_modules/docker/api.py#24)(self):**
115
116&mdash; **def [run](/infra/bots/recipe_modules/docker/api.py#32)(self, name, docker_image, src_dir, out_dir, script, args=None, docker_args=None, copies=None, recursive_read=None, attempts=1, match_directory_structure=False):**
117### *recipe_modules* / [doxygen](/infra/bots/recipe_modules/doxygen)
118
119[DEPS](/infra/bots/recipe_modules/doxygen/__init__.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/step][recipe_engine/recipe_modules/step], [run](#recipe_modules-run)
120
121
122#### **class [DoxygenApi](/infra/bots/recipe_modules/doxygen/api.py#9)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
123
124&mdash; **def [generate\_and\_upload](/infra/bots/recipe_modules/doxygen/api.py#10)(self, skia_dir):**
125### *recipe_modules* / [env](/infra/bots/recipe_modules/env)
126
127[DEPS](/infra/bots/recipe_modules/env/__init__.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context]
128
129
130#### **class [EnvApi](/infra/bots/recipe_modules/env/api.py#9)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
131### *recipe_modules* / [flavor](/infra/bots/recipe_modules/flavor)
132
133[DEPS](/infra/bots/recipe_modules/flavor/__init__.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [env](#recipe_modules-env), [run](#recipe_modules-run), [vars](#recipe_modules-vars), [xcode](#recipe_modules-xcode)
134
135
136#### **class [SkiaFlavorApi](/infra/bots/recipe_modules/flavor/api.py#54)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
137
138&mdash; **def [cleanup\_steps](/infra/bots/recipe_modules/flavor/api.py#122)(self):**
139
140&mdash; **def [copy\_directory\_contents\_to\_device](/infra/bots/recipe_modules/flavor/api.py#80)(self, host_dir, device_dir):**
141
142&mdash; **def [copy\_directory\_contents\_to\_host](/infra/bots/recipe_modules/flavor/api.py#83)(self, device_dir, host_dir):**
143
144&mdash; **def [copy\_file\_to\_device](/infra/bots/recipe_modules/flavor/api.py#86)(self, host_path, device_path):**
145
146&mdash; **def [create\_clean\_device\_dir](/infra/bots/recipe_modules/flavor/api.py#92)(self, path):**
147
148&mdash; **def [create\_clean\_host\_dir](/infra/bots/recipe_modules/flavor/api.py#89)(self, path):**
149
150&mdash; **def [device\_path\_join](/infra/bots/recipe_modules/flavor/api.py#77)(self, \*args):**
151
152&mdash; **def [get\_flavor](/infra/bots/recipe_modules/flavor/api.py#55)(self, vars_api, app_name):**
153
154Return a flavor utils object specific to the given builder.
155
156&mdash; **def [install](/infra/bots/recipe_modules/flavor/api.py#101)(self, skps=False, images=False, lotties=False, svgs=False, resources=False, texttraces=False):**
157
158&mdash; **def [read\_file\_on\_device](/infra/bots/recipe_modules/flavor/api.py#95)(self, path, \*\*kwargs):**
159
160&mdash; **def [remove\_file\_on\_device](/infra/bots/recipe_modules/flavor/api.py#98)(self, path):**
161
162&mdash; **def [setup](/infra/bots/recipe_modules/flavor/api.py#68)(self, app_name):**
163
164&mdash; **def [step](/infra/bots/recipe_modules/flavor/api.py#74)(self, name, cmd, \*\*kwargs):**
165### *recipe_modules* / [git](/infra/bots/recipe_modules/git)
166
167[DEPS](/infra/bots/recipe_modules/git/__init__.py#7): [recipe\_engine/path][recipe_engine/recipe_modules/path], [env](#recipe_modules-env)
168
169
170#### **class [GitApi](/infra/bots/recipe_modules/git/api.py#9)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
171
172&mdash; **def [env](/infra/bots/recipe_modules/git/api.py#10)(self):**
173
174Add Git to PATH
175
176Requires the infra/git and infra/tools/git CIPD packages to be installed
177in the 'git' relative path.
178### *recipe_modules* / [gold\_upload](/infra/bots/recipe_modules/gold_upload)
179
180[DEPS](/infra/bots/recipe_modules/gold_upload/__init__.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/time][recipe_engine/recipe_modules/time], [flavor](#recipe_modules-flavor), [gsutil](#recipe_modules-gsutil), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
181
182
183#### **class [GoldUploadApi](/infra/bots/recipe_modules/gold_upload/api.py#11)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
184
185&mdash; **def [upload](/infra/bots/recipe_modules/gold_upload/api.py#12)(self):**
186
187Attempt to upload files to Gold.
188This module assumes setup has occurred for the vars and flavor modules.
189### *recipe_modules* / [gsutil](/infra/bots/recipe_modules/gsutil)
190
191[DEPS](/infra/bots/recipe_modules/gsutil/__init__.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/step][recipe_engine/recipe_modules/step], [run](#recipe_modules-run), [vars](#recipe_modules-vars)
192
193
194#### **class [GSUtilApi](/infra/bots/recipe_modules/gsutil/api.py#10)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
195
196&mdash; **def [\_\_call\_\_](/infra/bots/recipe_modules/gsutil/api.py#11)(self, step_name, \*args):**
197
198Run gsutil with the given args.
199
200This assumes there exists an executable called gsutil on the PATH.
201This probably only works for Linux/Mac, but those are the only
202hosts that we try to upload to GCS from anyway.
203
204&mdash; **def [cp](/infra/bots/recipe_modules/gsutil/api.py#20)(self, name, src, dst, extra_gsutil_args=None, extra_args=None, multithread=False):**
205
206Attempt to upload or download files to/from Google Cloud Storage (GCS).
207
208Args:
209  name: string. Will be used to fill out the step name.
210  src: string. Absolute path for a local file or gcs file (e.g. gs://...)
211  dst: string. Same as src.
212  extra_gsutil_args: optional list of args to be passed to gsutil before the
213    cp command.
214  extra_args: optional list of args to be passed to gsutil cp. e.g. [-Z]
215    asks all files be compressed with gzip after upload and before download.
216  multi_thread: if the -m argument should be used to copy multiple items
217    at once (e.g. gsutil -m cp foo* gs://bar/dir)
218
219If the operation fails, it will be retried multiple times.
220### *recipe_modules* / [infra](/infra/bots/recipe_modules/infra)
221
222[DEPS](/infra/bots/recipe_modules/infra/__init__.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [run](#recipe_modules-run), [vars](#recipe_modules-vars)
223
224
225#### **class [InfraApi](/infra/bots/recipe_modules/infra/api.py#14)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
226
227&emsp; **@property**<br>&mdash; **def [go\_bin](/infra/bots/recipe_modules/infra/api.py#46)(self):**
228
229&emsp; **@property**<br>&mdash; **def [go\_env](/infra/bots/recipe_modules/infra/api.py#50)(self):**
230
231&emsp; **@property**<br>&mdash; **def [gopath](/infra/bots/recipe_modules/infra/api.py#60)(self):**
232
233&emsp; **@property**<br>&mdash; **def [goroot](/infra/bots/recipe_modules/infra/api.py#15)(self):**
234### *recipe_modules* / [run](/infra/bots/recipe_modules/run)
235
236[DEPS](/infra/bots/recipe_modules/run/__init__.py#7): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [env](#recipe_modules-env), [vars](#recipe_modules-vars)
237
238
239#### **class [SkiaStepApi](/infra/bots/recipe_modules/run/api.py#14)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
240
241&mdash; **def [\_\_call\_\_](/infra/bots/recipe_modules/run/api.py#69)(self, steptype, name, abort_on_failure=True, fail_build_on_failure=True, \*\*kwargs):**
242
243Run a step. If it fails, keep going but mark the build status failed.
244
245&mdash; **def [\_\_init\_\_](/infra/bots/recipe_modules/run/api.py#16)(self, \*args, \*\*kwargs):**
246
247Initialize the recipe module.
248
249&mdash; **def [asset\_version](/infra/bots/recipe_modules/run/api.py#54)(self, asset_name, skia_dir, test_data=None):**
250
251Return the contents of VERSION for the given asset as a string.
252
253If test_data is not specified, reads the property
254'test_<asset_name>_version' or if not present, uses
255TEST_DEFAULT_ASSET_VERSION.
256
257&mdash; **def [check\_failure](/infra/bots/recipe_modules/run/api.py#25)(self):**
258
259Raise an exception if any step failed.
260
261&emsp; **@property**<br>&mdash; **def [failed\_steps](/infra/bots/recipe_modules/run/api.py#31)(self):**
262
263&mdash; **def [readfile](/infra/bots/recipe_modules/run/api.py#40)(self, filename, \*args, \*\*kwargs):**
264
265Convenience function for reading files.
266
267&mdash; **def [rmtree](/infra/bots/recipe_modules/run/api.py#50)(self, path):**
268
269Wrapper around api.file.rmtree.
270
271&mdash; **def [run\_once](/infra/bots/recipe_modules/run/api.py#35)(self, fn, \*args, \*\*kwargs):**
272
273&mdash; **def [with\_retry](/infra/bots/recipe_modules/run/api.py#81)(self, steptype, name, attempts, between_attempts_fn=None, abort_on_failure=True, fail_build_on_failure=True, \*\*kwargs):**
274
275&mdash; **def [writefile](/infra/bots/recipe_modules/run/api.py#45)(self, filename, contents):**
276
277Convenience function for writing files.
278### *recipe_modules* / [vars](/infra/bots/recipe_modules/vars)
279
280[DEPS](/infra/bots/recipe_modules/vars/__init__.py#7): [depot\_tools/bot\_update][depot_tools/recipe_modules/bot_update], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [builder\_name\_schema](#recipe_modules-builder_name_schema)
281
282
283#### **class [SkiaVarsApi](/infra/bots/recipe_modules/vars/api.py#16)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
284
285&mdash; **def [getenv](/infra/bots/recipe_modules/vars/api.py#107)(self, name, var):**
286
287&emsp; **@property**<br>&mdash; **def [is\_linux](/infra/bots/recipe_modules/vars/api.py#87)(self):**
288
289&mdash; **def [setup](/infra/bots/recipe_modules/vars/api.py#18)(self):**
290
291Prepare the variables.
292
293&emsp; **@property**<br>&mdash; **def [swarming\_bot\_id](/infra/bots/recipe_modules/vars/api.py#95)(self):**
294
295&emsp; **@property**<br>&mdash; **def [swarming\_task\_id](/infra/bots/recipe_modules/vars/api.py#101)(self):**
296### *recipe_modules* / [xcode](/infra/bots/recipe_modules/xcode)
297
298[DEPS](/infra/bots/recipe_modules/xcode/__init__.py#8): [recipe\_engine/cipd][recipe_engine/recipe_modules/cipd], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/step][recipe_engine/recipe_modules/step], [vars](#recipe_modules-vars)
299
300
301#### **class [SkiaXCodeApi](/infra/bots/recipe_modules/xcode/api.py#10)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
302
303&mdash; **def [install](/infra/bots/recipe_modules/xcode/api.py#21)(self):**
304
305&emsp; **@property**<br>&mdash; **def [path](/infra/bots/recipe_modules/xcode/api.py#17)(self):**
306
307&emsp; **@property**<br>&mdash; **def [version](/infra/bots/recipe_modules/xcode/api.py#13)(self):**
308## Recipes
309
310### *recipes* / [build:examples/full](/infra/bots/recipe_modules/build/examples/full.py)
311
312[DEPS](/infra/bots/recipe_modules/build/examples/full.py#7): [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [build](#recipe_modules-build), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
313
314
315&mdash; **def [RunSteps](/infra/bots/recipe_modules/build/examples/full.py#18)(api):**
316### *recipes* / [builder\_name\_schema:examples/full](/infra/bots/recipe_modules/builder_name_schema/examples/full.py)
317
318[DEPS](/infra/bots/recipe_modules/builder_name_schema/examples/full.py#7): [builder\_name\_schema](#recipe_modules-builder_name_schema)
319
320
321&mdash; **def [RunSteps](/infra/bots/recipe_modules/builder_name_schema/examples/full.py#12)(api):**
322### *recipes* / [checkout:examples/full](/infra/bots/recipe_modules/checkout/examples/full.py)
323
324[DEPS](/infra/bots/recipe_modules/checkout/examples/full.py#7): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [checkout](#recipe_modules-checkout), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
325
326
327&mdash; **def [RunSteps](/infra/bots/recipe_modules/checkout/examples/full.py#18)(api):**
328### *recipes* / [compile](/infra/bots/recipes/compile.py)
329
330[DEPS](/infra/bots/recipes/compile.py#11): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [build](#recipe_modules-build), [checkout](#recipe_modules-checkout), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
331
332
333&mdash; **def [RunSteps](/infra/bots/recipes/compile.py#26)(api):**
334### *recipes* / [compute\_buildstats](/infra/bots/recipes/compute_buildstats.py)
335
336[DEPS](/infra/bots/recipes/compute_buildstats.py#12): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [checkout](#recipe_modules-checkout), [env](#recipe_modules-env), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
337
338
339&mdash; **def [RunSteps](/infra/bots/recipes/compute_buildstats.py#34)(api):**
340
341&mdash; **def [add\_binary\_size\_output\_property](/infra/bots/recipes/compute_buildstats.py#30)(result, source, binary_size):**
342
343&mdash; **def [analyze\_cpp\_lib](/infra/bots/recipes/compute_buildstats.py#166)(api, checkout_root, out_dir, files):**
344
345&mdash; **def [analyze\_flutter\_lib](/infra/bots/recipes/compute_buildstats.py#194)(api, checkout_root, out_dir, files):**
346
347&mdash; **def [analyze\_wasm\_file](/infra/bots/recipes/compute_buildstats.py#233)(api, checkout_root, out_dir, files):**
348
349&mdash; **def [analyze\_web\_file](/infra/bots/recipes/compute_buildstats.py#139)(api, checkout_root, out_dir, files):**
350
351&mdash; **def [keys\_and\_props](/infra/bots/recipes/compute_buildstats.py#115)(api):**
352
353&mdash; **def [make\_treemap](/infra/bots/recipes/compute_buildstats.py#265)(api, checkout_root, out_dir, files):**
354### *recipes* / [docker:examples/full](/infra/bots/recipe_modules/docker/examples/full.py)
355
356[DEPS](/infra/bots/recipe_modules/docker/examples/full.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [docker](#recipe_modules-docker), [vars](#recipe_modules-vars)
357
358
359&mdash; **def [RunSteps](/infra/bots/recipe_modules/docker/examples/full.py#16)(api):**
360### *recipes* / [doxygen:examples/full](/infra/bots/recipe_modules/doxygen/examples/full.py)
361
362[DEPS](/infra/bots/recipe_modules/doxygen/examples/full.py#7): [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [doxygen](#recipe_modules-doxygen), [vars](#recipe_modules-vars)
363
364
365&mdash; **def [RunSteps](/infra/bots/recipe_modules/doxygen/examples/full.py#15)(api):**
366### *recipes* / [env:examples/full](/infra/bots/recipe_modules/env/examples/full.py)
367
368[DEPS](/infra/bots/recipe_modules/env/examples/full.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/step][recipe_engine/recipe_modules/step], [env](#recipe_modules-env)
369
370
371&mdash; **def [RunSteps](/infra/bots/recipe_modules/env/examples/full.py#14)(api):**
372### *recipes* / [flavor:examples/full](/infra/bots/recipe_modules/flavor/examples/full.py)
373
374[DEPS](/infra/bots/recipe_modules/flavor/examples/full.py#7): [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [flavor](#recipe_modules-flavor), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
375
376
377&mdash; **def [RunSteps](/infra/bots/recipe_modules/flavor/examples/full.py#32)(api):**
378
379&mdash; **def [test\_exceptions](/infra/bots/recipe_modules/flavor/examples/full.py#17)(api):**
380### *recipes* / [git:examples/full](/infra/bots/recipe_modules/git/examples/full.py)
381
382[DEPS](/infra/bots/recipe_modules/git/examples/full.py#7): [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/step][recipe_engine/recipe_modules/step], [git](#recipe_modules-git)
383
384
385&mdash; **def [RunSteps](/infra/bots/recipe_modules/git/examples/full.py#14)(api):**
386### *recipes* / [gold\_upload:examples/full](/infra/bots/recipe_modules/gold_upload/examples/full.py)
387
388[DEPS](/infra/bots/recipe_modules/gold_upload/examples/full.py#10): [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [flavor](#recipe_modules-flavor), [gold\_upload](#recipe_modules-gold_upload), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
389
390
391&mdash; **def [RunSteps](/infra/bots/recipe_modules/gold_upload/examples/full.py#22)(api):**
392### *recipes* / [gsutil:examples/full](/infra/bots/recipe_modules/gsutil/examples/full.py)
393
394[DEPS](/infra/bots/recipe_modules/gsutil/examples/full.py#10): [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [gsutil](#recipe_modules-gsutil), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
395
396
397&mdash; **def [RunSteps](/infra/bots/recipe_modules/gsutil/examples/full.py#20)(api):**
398### *recipes* / [housekeeper](/infra/bots/recipes/housekeeper.py)
399
400[DEPS](/infra/bots/recipes/housekeeper.py#13): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [checkout](#recipe_modules-checkout), [doxygen](#recipe_modules-doxygen), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
401
402
403&mdash; **def [RunSteps](/infra/bots/recipes/housekeeper.py#24)(api):**
404### *recipes* / [infra](/infra/bots/recipes/infra.py)
405
406[DEPS](/infra/bots/recipes/infra.py#10): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [infra](#recipe_modules-infra), [vars](#recipe_modules-vars)
407
408
409&mdash; **def [RunSteps](/infra/bots/recipes/infra.py#28)(api):**
410
411&mdash; **def [git\_init](/infra/bots/recipes/infra.py#20)(api, repo_root, env):**
412### *recipes* / [infra:examples/full](/infra/bots/recipe_modules/infra/examples/full.py)
413
414[DEPS](/infra/bots/recipe_modules/infra/examples/full.py#10): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
415
416
417&mdash; **def [RunSteps](/infra/bots/recipe_modules/infra/examples/full.py#22)(api):**
418### *recipes* / [perf](/infra/bots/recipes/perf.py)
419
420[DEPS](/infra/bots/recipes/perf.py#15): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/time][recipe_engine/recipe_modules/time], [env](#recipe_modules-env), [flavor](#recipe_modules-flavor), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
421
422
423&mdash; **def [RunSteps](/infra/bots/recipes/perf.py#104)(api):**
424
425&mdash; **def [perf\_steps](/infra/bots/recipes/perf.py#31)(api):**
426
427Run Skia benchmarks.
428### *recipes* / [perf\_pathkit](/infra/bots/recipes/perf_pathkit.py)
429
430[DEPS](/infra/bots/recipes/perf_pathkit.py#9): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [checkout](#recipe_modules-checkout), [docker](#recipe_modules-docker), [env](#recipe_modules-env), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
431
432
433&mdash; **def [RunSteps](/infra/bots/recipes/perf_pathkit.py#27)(api):**
434### *recipes* / [perf\_skottietrace](/infra/bots/recipes/perf_skottietrace.py)
435
436[DEPS](/infra/bots/recipes/perf_skottietrace.py#17): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/time][recipe_engine/recipe_modules/time], [flavor](#recipe_modules-flavor), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
437
438
439&mdash; **def [RunSteps](/infra/bots/recipes/perf_skottietrace.py#191)(api):**
440
441&mdash; **def [get\_trace\_match](/infra/bots/recipes/perf_skottietrace.py#147)(lottie_filename, is_android):**
442
443Returns the DM regex to match the specified lottie file name.
444
445&mdash; **def [parse\_trace](/infra/bots/recipes/perf_skottietrace.py#162)(trace_json, lottie_filename, api):**
446
447parse_trace parses the specified trace JSON.
448
449Parses the trace JSON and calculates the time of a single frame. Frame time is
450considered the same as seek time + render time.
451Note: The first seek is ignored because it is a constructor call.
452
453A dictionary is returned that has the following structure:
454{
455  'frame_max_us': 100,
456  'frame_min_us': 90,
457  'frame_avg_us': 95,
458}
459
460&mdash; **def [perf\_steps](/infra/bots/recipes/perf_skottietrace.py#37)(api):**
461
462Run DM on lottie files with tracing turned on and then parse the output.
463### *recipes* / [perf\_skottiewasm\_lottieweb](/infra/bots/recipes/perf_skottiewasm_lottieweb.py)
464
465[DEPS](/infra/bots/recipes/perf_skottiewasm_lottieweb.py#14): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/time][recipe_engine/recipe_modules/time], [checkout](#recipe_modules-checkout), [env](#recipe_modules-env), [flavor](#recipe_modules-flavor), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
466
467
468&mdash; **def [RunSteps](/infra/bots/recipes/perf_skottiewasm_lottieweb.py#87)(api):**
469
470&mdash; **def [parse\_trace](/infra/bots/recipes/perf_skottiewasm_lottieweb.py#208)(trace_json, lottie_filename, api, renderer):**
471
472parse_trace parses the specified trace JSON.
473
474Parses the trace JSON and calculates the time of a single frame.
475A dictionary is returned that has the following structure:
476{
477  'frame_max_us': 100,
478  'frame_min_us': 90,
479  'frame_avg_us': 95,
480}
481### *recipes* / [run:examples/full](/infra/bots/recipe_modules/run/examples/full.py)
482
483[DEPS](/infra/bots/recipe_modules/run/examples/full.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [run](#recipe_modules-run), [vars](#recipe_modules-vars)
484
485
486&mdash; **def [RunSteps](/infra/bots/recipe_modules/run/examples/full.py#22)(api):**
487
488&mdash; **def [myfunc](/infra/bots/recipe_modules/run/examples/full.py#18)(api, i):**
489### *recipes* / [sync\_and\_compile](/infra/bots/recipes/sync_and_compile.py)
490
491[DEPS](/infra/bots/recipes/sync_and_compile.py#10): [depot\_tools/gitiles][depot_tools/recipe_modules/gitiles], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [build](#recipe_modules-build), [checkout](#recipe_modules-checkout), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
492
493
494&mdash; **def [RunSteps](/infra/bots/recipes/sync_and_compile.py#27)(api):**
495### *recipes* / [test](/infra/bots/recipes/test.py)
496
497[DEPS](/infra/bots/recipes/test.py#13): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [env](#recipe_modules-env), [flavor](#recipe_modules-flavor), [gold\_upload](#recipe_modules-gold_upload), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
498
499
500&mdash; **def [RunSteps](/infra/bots/recipes/test.py#136)(api):**
501
502&mdash; **def [test\_steps](/infra/bots/recipes/test.py#30)(api):**
503
504Run the DM test.
505### *recipes* / [test\_canvaskit](/infra/bots/recipes/test_canvaskit.py)
506
507[DEPS](/infra/bots/recipes/test_canvaskit.py#9): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [checkout](#recipe_modules-checkout), [docker](#recipe_modules-docker), [env](#recipe_modules-env), [flavor](#recipe_modules-flavor), [gold\_upload](#recipe_modules-gold_upload), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
508
509
510&mdash; **def [RunSteps](/infra/bots/recipes/test_canvaskit.py#28)(api):**
511### *recipes* / [test\_lottie\_web](/infra/bots/recipes/test_lottie_web.py)
512
513[DEPS](/infra/bots/recipes/test_lottie_web.py#9): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [checkout](#recipe_modules-checkout), [docker](#recipe_modules-docker), [env](#recipe_modules-env), [flavor](#recipe_modules-flavor), [gold\_upload](#recipe_modules-gold_upload), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
514
515
516&mdash; **def [RunSteps](/infra/bots/recipes/test_lottie_web.py#29)(api):**
517### *recipes* / [test\_pathkit](/infra/bots/recipes/test_pathkit.py)
518
519[DEPS](/infra/bots/recipes/test_pathkit.py#9): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [checkout](#recipe_modules-checkout), [docker](#recipe_modules-docker), [env](#recipe_modules-env), [flavor](#recipe_modules-flavor), [gold\_upload](#recipe_modules-gold_upload), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
520
521
522&mdash; **def [RunSteps](/infra/bots/recipes/test_pathkit.py#29)(api):**
523### *recipes* / [upload\_buildstats\_results](/infra/bots/recipes/upload_buildstats_results.py)
524
525[DEPS](/infra/bots/recipes/upload_buildstats_results.py#10): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/time][recipe_engine/recipe_modules/time], [vars](#recipe_modules-vars)
526
527
528&mdash; **def [RunSteps](/infra/bots/recipes/upload_buildstats_results.py#21)(api):**
529### *recipes* / [upload\_dm\_results](/infra/bots/recipes/upload_dm_results.py)
530
531[DEPS](/infra/bots/recipes/upload_dm_results.py#13): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/time][recipe_engine/recipe_modules/time], [gsutil](#recipe_modules-gsutil), [vars](#recipe_modules-vars)
532
533
534&mdash; **def [RunSteps](/infra/bots/recipes/upload_dm_results.py#29)(api):**
535### *recipes* / [upload\_nano\_results](/infra/bots/recipes/upload_nano_results.py)
536
537[DEPS](/infra/bots/recipes/upload_nano_results.py#10): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/time][recipe_engine/recipe_modules/time], [vars](#recipe_modules-vars)
538
539
540&mdash; **def [RunSteps](/infra/bots/recipes/upload_nano_results.py#21)(api):**
541### *recipes* / [vars:examples/full](/infra/bots/recipe_modules/vars/examples/full.py)
542
543[DEPS](/infra/bots/recipe_modules/vars/examples/full.py#7): [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [vars](#recipe_modules-vars)
544
545
546&mdash; **def [RunSteps](/infra/bots/recipe_modules/vars/examples/full.py#16)(api):**
547### *recipes* / [xcode:examples/full](/infra/bots/recipe_modules/xcode/examples/full.py)
548
549[DEPS](/infra/bots/recipe_modules/xcode/examples/full.py#8): [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [vars](#recipe_modules-vars), [xcode](#recipe_modules-xcode)
550
551
552&mdash; **def [RunSteps](/infra/bots/recipe_modules/xcode/examples/full.py#15)(api):**
553
554[depot_tools/recipe_modules/bot_update]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/d3299d99867bf6d8a510afeaa7597fd9d6db44e2/recipes/README.recipes.md#recipe_modules-bot_update
555[depot_tools/recipe_modules/gclient]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/d3299d99867bf6d8a510afeaa7597fd9d6db44e2/recipes/README.recipes.md#recipe_modules-gclient
556[depot_tools/recipe_modules/git]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/d3299d99867bf6d8a510afeaa7597fd9d6db44e2/recipes/README.recipes.md#recipe_modules-git
557[depot_tools/recipe_modules/gitiles]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/d3299d99867bf6d8a510afeaa7597fd9d6db44e2/recipes/README.recipes.md#recipe_modules-gitiles
558[depot_tools/recipe_modules/tryserver]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/d3299d99867bf6d8a510afeaa7597fd9d6db44e2/recipes/README.recipes.md#recipe_modules-tryserver
559[recipe_engine/recipe_modules/cipd]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/42e0c97c4954dfedc6ab26b64646cfd742ac340f/README.recipes.md#recipe_modules-cipd
560[recipe_engine/recipe_modules/context]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/42e0c97c4954dfedc6ab26b64646cfd742ac340f/README.recipes.md#recipe_modules-context
561[recipe_engine/recipe_modules/file]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/42e0c97c4954dfedc6ab26b64646cfd742ac340f/README.recipes.md#recipe_modules-file
562[recipe_engine/recipe_modules/json]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/42e0c97c4954dfedc6ab26b64646cfd742ac340f/README.recipes.md#recipe_modules-json
563[recipe_engine/recipe_modules/path]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/42e0c97c4954dfedc6ab26b64646cfd742ac340f/README.recipes.md#recipe_modules-path
564[recipe_engine/recipe_modules/platform]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/42e0c97c4954dfedc6ab26b64646cfd742ac340f/README.recipes.md#recipe_modules-platform
565[recipe_engine/recipe_modules/properties]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/42e0c97c4954dfedc6ab26b64646cfd742ac340f/README.recipes.md#recipe_modules-properties
566[recipe_engine/recipe_modules/raw_io]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/42e0c97c4954dfedc6ab26b64646cfd742ac340f/README.recipes.md#recipe_modules-raw_io
567[recipe_engine/recipe_modules/step]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/42e0c97c4954dfedc6ab26b64646cfd742ac340f/README.recipes.md#recipe_modules-step
568[recipe_engine/recipe_modules/time]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/42e0c97c4954dfedc6ab26b64646cfd742ac340f/README.recipes.md#recipe_modules-time
569[recipe_engine/wkt/RecipeApi]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/42e0c97c4954dfedc6ab26b64646cfd742ac340f/recipe_engine/recipe_api.py#433
570