[infra] Bring recipe DEPS up to date

Bug: skia:
Change-Id: Iee3a94e56d1c8992f844f2b67d0bb565dd896684
Reviewed-on: https://skia-review.googlesource.com/50262
Reviewed-by: Ravi Mistry <rmistry@google.com>
Commit-Queue: Eric Boren <borenet@google.com>
diff --git a/infra/bots/README.recipes.md b/infra/bots/README.recipes.md
new file mode 100644
index 0000000..baaac70
--- /dev/null
+++ b/infra/bots/README.recipes.md
@@ -0,0 +1,863 @@
+<!--- AUTOGENERATED BY `./recipes.py test train` -->
+# Package documentation for [skia]()
+## Table of Contents
+
+**[Recipe Modules](#Recipe-Modules)**
+  * [builder_name_schema](#recipe_modules-builder_name_schema)
+  * [core](#recipe_modules-core)
+  * [ct](#recipe_modules-ct)
+  * [env](#recipe_modules-env)
+  * [flavor](#recipe_modules-flavor)
+  * [git](#recipe_modules-git)
+  * [infra](#recipe_modules-infra)
+  * [isolate](#recipe_modules-isolate)
+  * [run](#recipe_modules-run)
+  * [skia_swarming](#recipe_modules-skia_swarming)
+  * [swarming](#recipe_modules-swarming)
+  * [swarming_client](#recipe_modules-swarming_client)
+  * [vars](#recipe_modules-vars)
+
+**[Recipes](#Recipes)**
+  * [builder_name_schema:examples/full](#recipes-builder_name_schema_examples_full)
+  * [bundle_recipes](#recipes-bundle_recipes)
+  * [check_generated_files](#recipes-check_generated_files)
+  * [compile](#recipes-compile)
+  * [core:examples/full](#recipes-core_examples_full)
+  * [ct:examples/full](#recipes-ct_examples_full)
+  * [ct_skps](#recipes-ct_skps)
+  * [env:examples/full](#recipes-env_examples_full)
+  * [flavor:examples/full](#recipes-flavor_examples_full)
+  * [git:examples/full](#recipes-git_examples_full)
+  * [housekeeper](#recipes-housekeeper)
+  * [infra](#recipes-infra)
+  * [infra:examples/full](#recipes-infra_examples_full)
+  * [isolate:examples/full](#recipes-isolate_examples_full)
+  * [isolate:tests/clean_isolated_files](#recipes-isolate_tests_clean_isolated_files)
+  * [isolate:tests/isolate_tests](#recipes-isolate_tests_isolate_tests)
+  * [isolate:tests/isolated_tests](#recipes-isolate_tests_isolated_tests)
+  * [isolate:tests/run_isolated](#recipes-isolate_tests_run_isolated)
+  * [perf](#recipes-perf)
+  * [recreate_skps](#recipes-recreate_skps) &mdash; Recipe for the Skia RecreateSKPs Bot.
+  * [run:examples/full](#recipes-run_examples_full)
+  * [skia_swarming:examples/full](#recipes-skia_swarming_examples_full)
+  * [skpbench](#recipes-skpbench)
+  * [swarming:examples/full](#recipes-swarming_examples_full)
+  * [swarming_client:examples/full](#recipes-swarming_client_examples_full)
+  * [test](#recipes-test)
+  * [update_meta_config](#recipes-update_meta_config) &mdash; Recipe for the Bot that updates meta config.
+  * [upload_dm_results](#recipes-upload_dm_results)
+  * [upload_nano_results](#recipes-upload_nano_results)
+  * [vars:examples/full](#recipes-vars_examples_full)
+## Recipe Modules
+
+### *recipe_modules* / [builder\_name\_schema](/infra/bots/recipe_modules/builder_name_schema)
+
+#### **class [BuilderNameSchemaApi](/infra/bots/recipe_modules/builder_name_schema/api.py#14)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
+
+&mdash; **def [DictForBuilderName](/infra/bots/recipe_modules/builder_name_schema/api.py#33)(self, \*args, \*\*kwargs):**
+
+&mdash; **def [MakeBuilderName](/infra/bots/recipe_modules/builder_name_schema/api.py#30)(self, \*args, \*\*kwargs):**
+### *recipe_modules* / [core](/infra/bots/recipe_modules/core)
+
+[DEPS](/infra/bots/recipe_modules/core/__init__.py#5): [depot\_tools/bot\_update][depot_tools/recipe_modules/bot_update], [depot\_tools/gclient][depot_tools/recipe_modules/gclient], [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/python][recipe_engine/recipe_modules/python], [recipe\_engine/step][recipe_engine/recipe_modules/step], [flavor](#recipe_modules-flavor), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
+
+#### **class [SkiaApi](/infra/bots/recipe_modules/core/api.py#18)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
+
+&mdash; **def [checkout\_steps](/infra/bots/recipe_modules/core/api.py#35)(self):**
+
+Run the steps to obtain a checkout of Skia.
+
+&mdash; **def [setup](/infra/bots/recipe_modules/core/api.py#20)(self):**
+
+Prepare the bot to run.
+### *recipe_modules* / [ct](/infra/bots/recipe_modules/ct)
+
+[DEPS](/infra/bots/recipe_modules/ct/__init__.py#5): [depot\_tools/gsutil][depot_tools/recipe_modules/gsutil], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/step][recipe_engine/recipe_modules/step], [run](#recipe_modules-run)
+
+#### **class [CTApi](/infra/bots/recipe_modules/ct/api.py#11)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
+
+Provides steps to run CT tasks.
+
+&mdash; **def [download\_swarming\_skps](/infra/bots/recipe_modules/ct/api.py#16)(self, page_type, slave_num, skps_chromium_build, dest_dir, start_range, num_skps):**
+
+Downloads SKPs corresponding to the specified page type, slave and build.
+
+The SKPs are stored in Google Storage in the following dirs in CT_GS_BUCKET:
+  /swarming/skps/${page_type}/${skps_chromium_build}/{start_range..end_num}/
+The SKPs are downloaded into subdirectories in the dest_dir.
+
+Args:
+  api: RecipeApi instance.
+  page_type: str. The CT page type. Eg: 1k, 10k.
+  slave_num: int. The number of the swarming bot.
+  skps_chromium_build: str. The build the SKPs were captured from.
+  dest_dir: path obj. The directory to download SKPs into.
+  start_range: int. The subdirectory number to start from.
+  num_skps: int. The total number of SKPs to download starting with
+                 start_range.
+### *recipe_modules* / [env](/infra/bots/recipe_modules/env)
+
+[DEPS](/infra/bots/recipe_modules/env/__init__.py#6): [recipe\_engine/context][recipe_engine/recipe_modules/context]
+
+#### **class [EnvApi](/infra/bots/recipe_modules/env/api.py#9)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
+### *recipe_modules* / [flavor](/infra/bots/recipe_modules/flavor)
+
+[DEPS](/infra/bots/recipe_modules/flavor/__init__.py#5): [depot\_tools/bot\_update][depot_tools/recipe_modules/bot_update], [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/python][recipe_engine/recipe_modules/python], [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), [env](#recipe_modules-env), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
+
+#### **class [SkiaFlavorApi](/infra/bots/recipe_modules/flavor/api.py#57)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
+
+&mdash; **def [cleanup\_steps](/infra/bots/recipe_modules/flavor/api.py#137)(self):**
+
+&mdash; **def [compile](/infra/bots/recipe_modules/flavor/api.py#83)(self, target):**
+
+&mdash; **def [copy\_directory\_contents\_to\_device](/infra/bots/recipe_modules/flavor/api.py#96)(self, host_dir, device_dir):**
+
+&mdash; **def [copy\_directory\_contents\_to\_host](/infra/bots/recipe_modules/flavor/api.py#99)(self, device_dir, host_dir):**
+
+&mdash; **def [copy\_extra\_build\_products](/infra/bots/recipe_modules/flavor/api.py#86)(self, swarming_out_dir):**
+
+&mdash; **def [copy\_file\_to\_device](/infra/bots/recipe_modules/flavor/api.py#102)(self, host_path, device_path):**
+
+&mdash; **def [create\_clean\_device\_dir](/infra/bots/recipe_modules/flavor/api.py#108)(self, path):**
+
+&mdash; **def [create\_clean\_host\_dir](/infra/bots/recipe_modules/flavor/api.py#105)(self, path):**
+
+&mdash; **def [device\_path\_join](/infra/bots/recipe_modules/flavor/api.py#93)(self, \*args):**
+
+&mdash; **def [get\_flavor](/infra/bots/recipe_modules/flavor/api.py#58)(self, builder_cfg):**
+
+Return a flavor utils object specific to the given builder.
+
+&mdash; **def [install](/infra/bots/recipe_modules/flavor/api.py#120)(self, skps=False, images=False, svgs=False, resources=False):**
+
+&mdash; **def [install\_everything](/infra/bots/recipe_modules/flavor/api.py#117)(self):**
+
+&emsp; **@property**<br>&mdash; **def [out\_dir](/infra/bots/recipe_modules/flavor/api.py#89)(self):**
+
+&mdash; **def [read\_file\_on\_device](/infra/bots/recipe_modules/flavor/api.py#111)(self, path, \*\*kwargs):**
+
+&mdash; **def [remove\_file\_on\_device](/infra/bots/recipe_modules/flavor/api.py#114)(self, path):**
+
+&mdash; **def [setup](/infra/bots/recipe_modules/flavor/api.py#77)(self):**
+
+&mdash; **def [step](/infra/bots/recipe_modules/flavor/api.py#80)(self, name, cmd, \*\*kwargs):**
+### *recipe_modules* / [git](/infra/bots/recipe_modules/git)
+
+[DEPS](/infra/bots/recipe_modules/git/__init__.py#6): [recipe\_engine/path][recipe_engine/recipe_modules/path], [env](#recipe_modules-env)
+
+#### **class [GitApi](/infra/bots/recipe_modules/git/api.py#9)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
+
+&mdash; **def [env](/infra/bots/recipe_modules/git/api.py#10)(self):**
+
+Add Git to PATH
+
+Requires the infra/git and infra/tools/git CIPD packages to be installed
+in the 'git' relative path.
+### *recipe_modules* / [infra](/infra/bots/recipe_modules/infra)
+
+[DEPS](/infra/bots/recipe_modules/infra/__init__.py#5): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/step][recipe_engine/recipe_modules/step], [run](#recipe_modules-run), [vars](#recipe_modules-vars)
+
+#### **class [InfraApi](/infra/bots/recipe_modules/infra/api.py#13)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
+
+&emsp; **@property**<br>&mdash; **def [go\_bin](/infra/bots/recipe_modules/infra/api.py#18)(self):**
+
+&emsp; **@property**<br>&mdash; **def [go\_env](/infra/bots/recipe_modules/infra/api.py#26)(self):**
+
+&emsp; **@property**<br>&mdash; **def [go\_exe](/infra/bots/recipe_modules/infra/api.py#22)(self):**
+
+&mdash; **def [go\_version](/infra/bots/recipe_modules/infra/api.py#38)(self):**
+
+Print the Go version.
+
+&emsp; **@property**<br>&mdash; **def [gopath](/infra/bots/recipe_modules/infra/api.py#34)(self):**
+
+&emsp; **@property**<br>&mdash; **def [goroot](/infra/bots/recipe_modules/infra/api.py#14)(self):**
+
+&mdash; **def [update\_go\_deps](/infra/bots/recipe_modules/infra/api.py#52)(self):**
+
+Attempt to update go dependencies.
+
+This fails flakily sometimes, so perform multiple attempts.
+### *recipe_modules* / [isolate](/infra/bots/recipe_modules/isolate)
+
+[DEPS](/infra/bots/recipe_modules/isolate/__init__.py#11): [depot\_tools/git][depot_tools/recipe_modules/git], [depot\_tools/gsutil][depot_tools/recipe_modules/gsutil], [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/python][recipe_engine/recipe_modules/python], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/tempfile][recipe_engine/recipe_modules/tempfile], [swarming\_client](#recipe_modules-swarming_client)
+
+#### **class [IsolateApi](/infra/bots/recipe_modules/isolate/api.py#15)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
+
+APIs for interacting with isolates.
+
+&mdash; **def [clean\_isolated\_files](/infra/bots/recipe_modules/isolate/api.py#33)(self, build_dir):**
+
+Cleans out all *.isolated files from the build directory in
+preparation for the compile. Needed in order to ensure isolates
+are rebuilt properly because their dependencies are currently not
+completely described to gyp.
+
+&mdash; **def [find\_isolated\_tests](/infra/bots/recipe_modules/isolate/api.py#47)(self, build_dir, targets=None, \*\*kwargs):**
+
+Returns a step which finds all *.isolated files in a build directory.
+
+Useful only with 'archive' isolation mode.
+In 'prepare' mode use 'isolate_tests' instead.
+
+Assigns the dict {target name -> *.isolated file hash} to the swarm_hashes
+build property. This implies this step can currently only be run once
+per recipe.
+
+If |targets| is None, the step will use all *.isolated files it finds.
+Otherwise, it will verify that all |targets| are found and will use only
+them. If some expected targets are missing, will abort the build.
+
+&emsp; **@isolate_server.setter**<br>&mdash; **def [isolate\_server](/infra/bots/recipe_modules/isolate/api.py#28)(self, value):**
+
+Changes URL of Isolate server to use.
+
+&mdash; **def [isolate\_tests](/infra/bots/recipe_modules/isolate/api.py#93)(self, build_dir, targets=None, verbose=False, set_swarm_hashes=True, always_use_exparchive=False, \*\*kwargs):**
+
+Archives prepared tests in |build_dir| to isolate server.
+
+src/tools/isolate_driver.py is invoked by ninja during compilation
+to produce *.isolated.gen.json files that describe how to archive tests.
+
+This step then uses *.isolated.gen.json files to actually performs the
+archival. By archiving all tests at once it is able to reduce the total
+amount of work. Tests share many common files, and such files are processed
+only once.
+
+Assigns the dict {target name -> *.isolated file hash} to the swarm_hashes
+build property (also accessible as 'isolated_tests' property). This implies
+this step can currently only be run once per recipe.
+
+&emsp; **@property**<br>&mdash; **def [isolated\_tests](/infra/bots/recipe_modules/isolate/api.py#222)(self):**
+
+The dictionary of 'target name -> isolated hash' for this run.
+
+These come either from the incoming swarm_hashes build property,
+or from calling find_isolated_tests, above, at some point during the run.
+
+&mdash; **def [run\_isolated](/infra/bots/recipe_modules/isolate/api.py#244)(self, name, isolate_hash, args=None, \*\*kwargs):**
+
+Runs an isolated test.
+### *recipe_modules* / [run](/infra/bots/recipe_modules/run)
+
+[DEPS](/infra/bots/recipe_modules/run/__init__.py#5): [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/python][recipe_engine/recipe_modules/python], [recipe\_engine/step][recipe_engine/recipe_modules/step], [env](#recipe_modules-env), [vars](#recipe_modules-vars)
+
+#### **class [SkiaStepApi](/infra/bots/recipe_modules/run/api.py#35)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
+
+&mdash; **def [\_\_call\_\_](/infra/bots/recipe_modules/run/api.py#75)(self, steptype, name, abort_on_failure=True, fail_build_on_failure=True, \*\*kwargs):**
+
+Run a step. If it fails, keep going but mark the build status failed.
+
+&mdash; **def [\_\_init\_\_](/infra/bots/recipe_modules/run/api.py#37)(self, \*args, \*\*kwargs):**
+
+Initialize the recipe module.
+
+&mdash; **def [check\_failure](/infra/bots/recipe_modules/run/api.py#46)(self):**
+
+Raise an exception if any step failed.
+
+&mdash; **def [copy\_build\_products](/infra/bots/recipe_modules/run/api.py#87)(self, src, dst):**
+
+Copy whitelisted build products from src to dst.
+
+&emsp; **@property**<br>&mdash; **def [failed\_steps](/infra/bots/recipe_modules/run/api.py#52)(self):**
+
+&mdash; **def [readfile](/infra/bots/recipe_modules/run/api.py#61)(self, filename, \*args, \*\*kwargs):**
+
+Convenience function for reading files.
+
+&mdash; **def [rmtree](/infra/bots/recipe_modules/run/api.py#71)(self, path):**
+
+Wrapper around api.file.rmtree.
+
+&mdash; **def [run\_once](/infra/bots/recipe_modules/run/api.py#56)(self, fn, \*args, \*\*kwargs):**
+
+&mdash; **def [with\_retry](/infra/bots/recipe_modules/run/api.py#119)(self, steptype, name, attempts, between_attempts_fn=None, abort_on_failure=True, fail_build_on_failure=True, \*\*kwargs):**
+
+&mdash; **def [writefile](/infra/bots/recipe_modules/run/api.py#66)(self, filename, contents):**
+
+Convenience function for writing files.
+### *recipe_modules* / [skia\_swarming](/infra/bots/recipe_modules/skia_swarming)
+
+[DEPS](/infra/bots/recipe_modules/skia_swarming/__init__.py#5): [depot\_tools/depot\_tools][depot_tools/recipe_modules/depot_tools], [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/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [isolate](#recipe_modules-isolate), [run](#recipe_modules-run), [swarming](#recipe_modules-swarming), [swarming\_client](#recipe_modules-swarming_client)
+
+#### **class [SkiaSwarmingApi](/infra/bots/recipe_modules/skia_swarming/api.py#17)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
+
+Provides steps to run Skia tasks on swarming bots.
+
+&mdash; **def [batcharchive](/infra/bots/recipe_modules/skia_swarming/api.py#112)(self, targets):**
+
+Calls batcharchive on the skia.isolated.gen.json file.
+
+Args:
+  targets: list of str. The suffixes of the isolated.gen.json files to
+           archive.
+
+Returns:
+  list of tuples containing (task_name, swarming_hash).
+
+&mdash; **def [collect\_swarming\_task](/infra/bots/recipe_modules/skia_swarming/api.py#179)(self, swarming_task):**
+
+Collects the specified swarming task.
+
+Args:
+  swarming_task: An instance of swarming.SwarmingTask.
+
+&mdash; **def [create\_isolated\_gen\_json](/infra/bots/recipe_modules/skia_swarming/api.py#70)(self, isolate_path, base_dir, os_type, task_name, extra_variables, blacklist=None):**
+
+Creates an isolated.gen.json file (used by the isolate recipe module).
+
+Args:
+  isolate_path: path obj. Path to the isolate file.
+  base_dir: path obj. Dir that is the base of all paths in the isolate file.
+  os_type: str. The OS type to use when archiving the isolate file.
+      Eg: linux.
+  task_name: str. The isolated.gen.json file will be suffixed by this str.
+  extra_variables: dict of str to str. The extra vars to pass to isolate.
+      Eg: {'SLAVE_NUM': '1', 'MASTER': 'ChromiumPerfFYI'}
+  blacklist: list of regular expressions indicating which files/directories
+      not to archive.
+
+&mdash; **def [isolated\_file\_path](/infra/bots/recipe_modules/skia_swarming/api.py#30)(self, task_name):**
+
+Get the path to the given task's .isolated file.
+
+&mdash; **def [setup](/infra/bots/recipe_modules/skia_swarming/api.py#34)(self, luci_go_dir, swarming_rev=None):**
+
+Performs setup steps for swarming.
+
+&mdash; **def [setup\_go\_isolate](/infra/bots/recipe_modules/skia_swarming/api.py#42)(self, luci_go_dir):**
+
+Generates and puts in place the isolate Go binary.
+
+&emsp; **@property**<br>&mdash; **def [swarming\_temp\_dir](/infra/bots/recipe_modules/skia_swarming/api.py#20)(self):**
+
+Path where artifacts like isolate file and json output will be stored.
+
+&emsp; **@property**<br>&mdash; **def [tasks\_output\_dir](/infra/bots/recipe_modules/skia_swarming/api.py#25)(self):**
+
+Directory where the outputs of the swarming tasks will be stored.
+
+&mdash; **def [trigger\_swarming\_tasks](/infra/bots/recipe_modules/skia_swarming/api.py#127)(self, swarm_hashes, dimensions, idempotent=False, store_output=True, extra_args=None, expiration=None, hard_timeout=None, io_timeout=None, cipd_packages=None):**
+
+Triggers swarming tasks using swarm hashes.
+
+Args:
+  swarm_hashes: list of str. List of swarm hashes from the isolate server.
+  dimensions: dict of str to str. The dimensions to run the task on.
+              Eg: {'os': 'Ubuntu', 'gpu': '10de', 'pool': 'Skia'}
+  idempotent: bool. Whether or not to de-duplicate tasks.
+  store_output: bool. Whether task output should be stored.
+  extra_args: list of str. Extra arguments to pass to the task.
+  expiration: int. Task will expire if not picked up within this time.
+              DEFAULT_TASK_EXPIRATION is used if this argument is None.
+  hard_timeout: int. Task will timeout if not completed within this time.
+                DEFAULT_TASK_TIMEOUT is used if this argument is None.
+  io_timeout: int. Task will timeout if there is no output within this time.
+              DEFAULT_IO_TIMEOUT is used if this argument is None.
+  cipd_packages: CIPD packages which these tasks depend on.
+
+Returns:
+  List of swarming.SwarmingTask instances.
+### *recipe_modules* / [swarming](/infra/bots/recipe_modules/swarming)
+
+[DEPS](/infra/bots/recipe_modules/swarming/__init__.py#11): [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/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [isolate](#recipe_modules-isolate), [swarming\_client](#recipe_modules-swarming_client)
+
+#### **class [SwarmingApi](/infra/bots/recipe_modules/swarming/api.py#56)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
+
+Recipe module to use swarming.py tool to run tasks on Swarming.
+
+General usage:
+  1. Tweak default task parameters applied to all swarming tasks (such as
+     default_dimensions and default_priority).
+  2. Isolate some test using 'isolate' recipe module. Get isolated hash as
+     a result of that process.
+  3. Create a task configuration using 'task(...)' method, providing
+     isolated hash obtained previously.
+  4. Tweak the task parameters. This step is optional.
+  5. Launch the task on swarming by calling 'trigger_task(...)'.
+  6. Continue doing useful work locally while the task is running concurrently
+     on swarming.
+  7. Wait for task to finish and collect its result (exit code, logs)
+     by calling 'collect_task(...)'.
+
+See also example.py for concrete code.
+
+&mdash; **def [add\_default\_tag](/infra/bots/recipe_modules/swarming/api.py#298)(self, tag):**
+
+Adds a tag to the Swarming tasks triggered.
+
+Tags are used for maintenance, they can be used to calculate the number of
+tasks run for a day to calculate the cost of a type of type (CQ, ASAN, etc).
+
+Tags can be added per individual task.
+
+&mdash; **def [check\_client\_version](/infra/bots/recipe_modules/swarming/api.py#422)(self, step_test_data=None):**
+
+Yields steps to verify compatibility with swarming_client version.
+
+&mdash; **def [collect](/infra/bots/recipe_modules/swarming/api.py#576)(self, tasks, \*\*kwargs):**
+
+Batch version of 'collect_task'.
+
+Deprecated, to be removed soon. Use 'collect_task' in a loop instead,
+properly handling exceptions. This method doesn't handle collect failures
+well (it aborts on a first failure).
+
+&mdash; **def [collect\_task](/infra/bots/recipe_modules/swarming/api.py#539)(self, task, \*\*kwargs):**
+
+Waits for a single triggered task to finish.
+
+If the task is sharded, will wait for all shards to finish. Behaves as
+a regular recipe step: returns StepData with step results on success or
+raises StepFailure if task fails.
+
+Args:
+  task: SwarmingTask instance, previously triggered with 'trigger' method.
+  kwargs: passed to recipe step constructor as-is.
+
+&emsp; **@property**<br>&mdash; **def [default\_dimensions](/infra/bots/recipe_modules/swarming/api.py#243)(self):**
+
+Returns a copy of the default Swarming dimensions to run task on.
+
+The dimensions are what is used to filter which bots are able to run the
+task successfully. This is particularly useful to discern between OS
+versions, type of CPU, GPU card or VM, or preallocated pool.
+
+Example:
+  {'cpu': 'x86-64', 'os': 'Windows-XP-SP3'}
+
+This value can be changed per individual task.
+
+&emsp; **@property**<br>&mdash; **def [default\_env](/infra/bots/recipe_modules/swarming/api.py#266)(self):**
+
+Returns a copy of the default environment variable to run tasks with.
+
+By default the environment variable is not modified. Additional environment
+variables can be specified for each task.
+
+This value can be changed per individual task.
+
+&emsp; **@default_expiration.setter**<br>&mdash; **def [default\_expiration](/infra/bots/recipe_modules/swarming/api.py#166)(self, value):**
+
+&emsp; **@default_hard_timeout.setter**<br>&mdash; **def [default\_hard\_timeout](/infra/bots/recipe_modules/swarming/api.py#183)(self, value):**
+
+&emsp; **@default_idempotent.setter**<br>&mdash; **def [default\_idempotent](/infra/bots/recipe_modules/swarming/api.py#222)(self, value):**
+
+&emsp; **@default_io_timeout.setter**<br>&mdash; **def [default\_io\_timeout](/infra/bots/recipe_modules/swarming/api.py#202)(self, value):**
+
+&emsp; **@default_priority.setter**<br>&mdash; **def [default\_priority](/infra/bots/recipe_modules/swarming/api.py#293)(self, value):**
+
+&emsp; **@default_user.setter**<br>&mdash; **def [default\_user](/infra/bots/recipe_modules/swarming/api.py#238)(self, value):**
+
+&mdash; **def [get\_collect\_cmd\_args](/infra/bots/recipe_modules/swarming/api.py#757)(self, task):**
+
+SwarmingTask -> argument list for 'swarming.py' command.
+
+&mdash; **def [get\_step\_name](/infra/bots/recipe_modules/swarming/api.py#687)(self, prefix, task):**
+
+SwarmingTask -> name of a step of a waterfall.
+
+Will take a task title (+ step name prefix) and append OS dimension to it.
+
+Args:
+  prefix: prefix to append to task title, like 'trigger'.
+  task: SwarmingTask instance.
+
+Returns:
+  '[<prefix>] <task title> on <OS>'
+
+&emsp; **@staticmethod**<br>&mdash; **def [prefered\_os\_dimension](/infra/bots/recipe_modules/swarming/api.py#327)(platform):**
+
+Given a platform name returns the prefered Swarming OS dimension.
+
+Platform name is usually provided by 'platform' recipe module, it's one
+of 'win', 'linux', 'mac'. This function returns more concrete Swarming OS
+dimension that represent this platform on Swarming by default.
+
+Recipes are free to use other OS dimension if there's a need for it. For
+example WinXP try bot recipe may explicitly specify 'Windows-XP-SP3'
+dimension.
+
+&mdash; **def [set\_default\_dimension](/infra/bots/recipe_modules/swarming/api.py#258)(self, key, value):**
+
+&mdash; **def [set\_default\_env](/infra/bots/recipe_modules/swarming/api.py#277)(self, key, value):**
+
+&emsp; **@show_isolated_out_in_collect_step.setter**<br>&mdash; **def [show\_isolated\_out\_in\_collect\_step](/infra/bots/recipe_modules/swarming/api.py#314)(self, value):**
+
+&emsp; **@show_shards_in_collect_step.setter**<br>&mdash; **def [show\_shards\_in\_collect\_step](/infra/bots/recipe_modules/swarming/api.py#323)(self, value):**
+
+&emsp; **@[returns\_placeholder][recipe_engine/wkt/returns_placeholder]**<br>&mdash; **def [summary](/infra/bots/recipe_modules/swarming/api.py#129)(self):**
+
+&emsp; **@swarming_server.setter**<br>&mdash; **def [swarming\_server](/infra/bots/recipe_modules/swarming/api.py#138)(self, value):**
+
+Changes URL of Swarming server to use.
+
+&mdash; **def [task](/infra/bots/recipe_modules/swarming/api.py#345)(self, title, isolated_hash, ignore_task_failure=False, shards=1, task_output_dir=None, extra_args=None, idempotent=None, cipd_packages=None, build_properties=None, merge=None):**
+
+Returns a new SwarmingTask instance to run an isolated executable on
+Swarming.
+
+For google test executables, use gtest_task() instead.
+
+At the time of this writting, this code is used by V8, Skia and iOS.
+
+The return value can be customized if necessary (see SwarmingTask class
+below). Pass it to 'trigger_task' to launch it on swarming. Later pass the
+same instance to 'collect_task' to wait for the task to finish and fetch its
+results.
+
+Args:
+  title: name of the test, used as part of a task ID.
+  isolated_hash: hash of isolated test on isolate server, the test should
+      be already isolated there, see 'isolate' recipe module.
+  ignore_task_failure: whether to ignore the test failure of swarming
+    tasks. By default, this is set to False.
+  shards: if defined, the number of shards to use for the task. By default
+      this value is either 1 or based on the title.
+  task_output_dir: if defined, the directory where task results are placed.
+      The caller is responsible for removing this folder when finished.
+  extra_args: list of command line arguments to pass to isolated tasks.
+  idempotent: whether this task is considered idempotent. Defaults
+      to self.default_idempotent if not specified.
+  cipd_packages: list of 3-tuples corresponding to CIPD packages needed for
+      the task: ('path', 'package_name', 'version'), defined as follows:
+          path: Path relative to the Swarming root dir in which to install
+              the package.
+          package_name: Name of the package to install,
+              eg. "infra/tools/authutil/${platform}"
+          version: Version of the package, either a package instance ID,
+              ref, or tag key/value pair.
+  build_properties: An optional dict containing various build properties.
+      These are typically but not necessarily the properties emitted by
+      bot_update.
+  merge: An optional dict containing:
+      "script": path to a script to call to post process and merge the
+          collected outputs from the tasks. The script should take one
+          named (but required) parameter, '-o' (for output), that represents
+          the path that the merged results should be written to, and accept
+          N additional paths to result files to merge. The merged results
+          should be in the JSON Results File Format
+          (https://www.chromium.org/developers/the-json-test-results-format)
+          and may optionally contain a top level "links" field that
+          may contain a dict mapping link text to URLs, for a set of
+          links that will be included in the buildbot output.
+      "args": an optional list of additional arguments to pass to the
+          above script.
+
+&mdash; **def [trigger](/infra/bots/recipe_modules/swarming/api.py#567)(self, tasks, \*\*kwargs):**
+
+Batch version of 'trigger_task'.
+
+Deprecated, to be removed soon. Use 'trigger_task' in a loop instead,
+properly handling exceptions. This method doesn't handle trigger failures
+well (it aborts on a first failure).
+
+&mdash; **def [trigger\_task](/infra/bots/recipe_modules/swarming/api.py#427)(self, task, \*\*kwargs):**
+
+Triggers one task.
+
+It the task is sharded, will trigger all shards. This steps justs posts
+the task and immediately returns. Use 'collect_task' to wait for a task to
+finish and grab its result.
+
+Behaves as a regular recipe step: returns StepData with step results
+on success or raises StepFailure if step fails.
+
+Args:
+  task: SwarmingTask instance.
+  kwargs: passed to recipe step constructor as-is.
+
+&emsp; **@verbose.setter**<br>&mdash; **def [verbose](/infra/bots/recipe_modules/swarming/api.py#148)(self, value):**
+
+Enables or disables verbose output in swarming scripts.
+### *recipe_modules* / [swarming\_client](/infra/bots/recipe_modules/swarming_client)
+
+[DEPS](/infra/bots/recipe_modules/swarming_client/__init__.py#11): [depot\_tools/git][depot_tools/recipe_modules/git], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step]
+
+#### **class [SwarmingClientApi](/infra/bots/recipe_modules/swarming_client/api.py#14)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
+
+Code that both isolate and swarming recipe modules depend on.
+
+Both swarming and isolate scripts live in a single repository called
+'swarming client'. This module include common functionality like finding
+existing swarming client checkout, fetching a new one, getting version of
+a swarming script, etc.
+
+&mdash; **def [checkout](/infra/bots/recipe_modules/swarming_client/api.py#28)(self, revision=None, curl_trace_file=None, can_fail_build=True):**
+
+Returns a step to checkout swarming client into a separate directory.
+
+Ordinarily swarming client is checked out via Chromium DEPS into
+src/tools/swarming_client. This step configures recipe module to use
+a separate checkout.
+
+If |revision| is None, this requires the build property
+'parent_got_swarming_client_revision' to be present, and raises an exception
+otherwise. Fail-fast behavior is used because if machines silently fell back
+to checking out the entire workspace, that would cause dramatic increases
+in cycle time if a misconfiguration were made and it were no longer possible
+for the bot to check out swarming_client separately.
+
+&mdash; **def [ensure\_script\_version](/infra/bots/recipe_modules/swarming_client/api.py#113)(self, script, min_version, step_test_data=None):**
+
+Yields steps to ensure a script version is not older than |min_version|.
+
+Will abort recipe execution if it is.
+
+&mdash; **def [get\_script\_version](/infra/bots/recipe_modules/swarming_client/api.py#104)(self, script):**
+
+Returns a version of some swarming script as a tuple (Major, Minor, Rev).
+
+It should have been queried by 'query_script_version' step before. Raises
+AssertionError if it wasn't.
+
+&emsp; **@property**<br>&mdash; **def [path](/infra/bots/recipe_modules/swarming_client/api.py#56)(self):**
+
+Returns path to a swarming client checkout.
+
+It's subdirectory of Chromium src/ checkout or a separate directory if
+'checkout_swarming_client' step was used.
+
+&mdash; **def [query\_script\_version](/infra/bots/recipe_modules/swarming_client/api.py#70)(self, script, step_test_data=None):**
+
+Yields a step to query a swarming script for its version.
+
+Version tuple is later accessible via 'get_script_version' method. If
+|step_test_data| is given, it is a tuple with version to use in expectation
+tests by default.
+
+Does nothing if script's version is already known.
+### *recipe_modules* / [vars](/infra/bots/recipe_modules/vars)
+
+[DEPS](/infra/bots/recipe_modules/vars/__init__.py#5): [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/python][recipe_engine/recipe_modules/python], [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)
+
+#### **class [SkiaVarsApi](/infra/bots/recipe_modules/vars/api.py#16)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
+
+&emsp; **@property**<br>&mdash; **def [is\_linux](/infra/bots/recipe_modules/vars/api.py#151)(self):**
+
+&mdash; **def [make\_path](/infra/bots/recipe_modules/vars/api.py#18)(self, \*path):**
+
+Return a Path object for the given path.
+
+&mdash; **def [setup](/infra/bots/recipe_modules/vars/api.py#24)(self):**
+
+Prepare the variables.
+
+&emsp; **@property**<br>&mdash; **def [swarming\_bot\_id](/infra/bots/recipe_modules/vars/api.py#193)(self):**
+
+&emsp; **@property**<br>&mdash; **def [swarming\_task\_id](/infra/bots/recipe_modules/vars/api.py#204)(self):**
+
+&emsp; **@property**<br>&mdash; **def [upload\_dm\_results](/infra/bots/recipe_modules/vars/api.py#155)(self):**
+
+&emsp; **@property**<br>&mdash; **def [upload\_perf\_results](/infra/bots/recipe_modules/vars/api.py#173)(self):**
+## Recipes
+
+### *recipes* / [builder\_name\_schema:examples/full](/infra/bots/recipe_modules/builder_name_schema/examples/full.py)
+
+[DEPS](/infra/bots/recipe_modules/builder_name_schema/examples/full.py#6): [builder\_name\_schema](#recipe_modules-builder_name_schema)
+
+&mdash; **def [RunSteps](/infra/bots/recipe_modules/builder_name_schema/examples/full.py#11)(api):**
+### *recipes* / [bundle\_recipes](/infra/bots/recipes/bundle_recipes.py)
+
+[DEPS](/infra/bots/recipes/bundle_recipes.py#9): [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], [git](#recipe_modules-git)
+
+&mdash; **def [RunSteps](/infra/bots/recipes/bundle_recipes.py#18)(api):**
+### *recipes* / [check\_generated\_files](/infra/bots/recipes/check_generated_files.py)
+
+[DEPS](/infra/bots/recipes/check_generated_files.py#8): [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/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [core](#recipe_modules-core), [flavor](#recipe_modules-flavor), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
+
+&mdash; **def [RunSteps](/infra/bots/recipes/check_generated_files.py#22)(api):**
+### *recipes* / [compile](/infra/bots/recipes/compile.py)
+
+[DEPS](/infra/bots/recipes/compile.py#9): [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/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/step][recipe_engine/recipe_modules/step], [core](#recipe_modules-core), [flavor](#recipe_modules-flavor), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
+
+&mdash; **def [RunSteps](/infra/bots/recipes/compile.py#45)(api):**
+
+&mdash; **def [build\_targets\_from\_builder\_dict](/infra/bots/recipes/compile.py#24)(builder_dict):**
+
+Return a list of targets to build, depending on the builder type.
+
+&mdash; **def [get\_extra\_env\_vars](/infra/bots/recipes/compile.py#31)(builder_dict):**
+### *recipes* / [core:examples/full](/infra/bots/recipe_modules/core/examples/full.py)
+
+[DEPS](/infra/bots/recipe_modules/core/examples/full.py#6): [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [core](#recipe_modules-core)
+
+&mdash; **def [RunSteps](/infra/bots/recipe_modules/core/examples/full.py#13)(api):**
+### *recipes* / [ct:examples/full](/infra/bots/recipe_modules/ct/examples/full.py)
+
+[DEPS](/infra/bots/recipe_modules/ct/examples/full.py#6): [recipe\_engine/path][recipe_engine/recipe_modules/path], [ct](#recipe_modules-ct)
+
+&mdash; **def [RunSteps](/infra/bots/recipe_modules/ct/examples/full.py#12)(api):**
+### *recipes* / [ct\_skps](/infra/bots/recipes/ct_skps.py)
+
+[DEPS](/infra/bots/recipes/ct_skps.py#9): [depot\_tools/gsutil][depot_tools/recipe_modules/gsutil], [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], [core](#recipe_modules-core), [ct](#recipe_modules-ct), [flavor](#recipe_modules-flavor), [run](#recipe_modules-run), [skia\_swarming](#recipe_modules-skia_swarming), [vars](#recipe_modules-vars)
+
+&mdash; **def [RunSteps](/infra/bots/recipes/ct_skps.py#44)(api):**
+### *recipes* / [env:examples/full](/infra/bots/recipe_modules/env/examples/full.py)
+
+[DEPS](/infra/bots/recipe_modules/env/examples/full.py#6): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/step][recipe_engine/recipe_modules/step], [env](#recipe_modules-env)
+
+&mdash; **def [RunSteps](/infra/bots/recipe_modules/env/examples/full.py#13)(api):**
+### *recipes* / [flavor:examples/full](/infra/bots/recipe_modules/flavor/examples/full.py)
+
+[DEPS](/infra/bots/recipe_modules/flavor/examples/full.py#6): [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)
+
+&mdash; **def [RunSteps](/infra/bots/recipe_modules/flavor/examples/full.py#30)(api):**
+
+&mdash; **def [test\_exceptions](/infra/bots/recipe_modules/flavor/examples/full.py#15)(api):**
+### *recipes* / [git:examples/full](/infra/bots/recipe_modules/git/examples/full.py)
+
+[DEPS](/infra/bots/recipe_modules/git/examples/full.py#6): [recipe\_engine/step][recipe_engine/recipe_modules/step], [git](#recipe_modules-git)
+
+&mdash; **def [RunSteps](/infra/bots/recipe_modules/git/examples/full.py#12)(api):**
+### *recipes* / [housekeeper](/infra/bots/recipes/housekeeper.py)
+
+[DEPS](/infra/bots/recipes/housekeeper.py#8): [depot\_tools/bot\_update][depot_tools/recipe_modules/bot_update], [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/python][recipe_engine/recipe_modules/python], [recipe\_engine/step][recipe_engine/recipe_modules/step], [core](#recipe_modules-core), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
+
+&mdash; **def [RunSteps](/infra/bots/recipes/housekeeper.py#21)(api):**
+### *recipes* / [infra](/infra/bots/recipes/infra.py)
+
+[DEPS](/infra/bots/recipes/infra.py#9): [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], [core](#recipe_modules-core), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
+
+&mdash; **def [RunSteps](/infra/bots/recipes/infra.py#21)(api):**
+### *recipes* / [infra:examples/full](/infra/bots/recipe_modules/infra/examples/full.py)
+
+[DEPS](/infra/bots/recipe_modules/infra/examples/full.py#9): [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/step][recipe_engine/recipe_modules/step], [core](#recipe_modules-core), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
+
+&mdash; **def [RunSteps](/infra/bots/recipe_modules/infra/examples/full.py#21)(api):**
+### *recipes* / [isolate:examples/full](/infra/bots/recipe_modules/isolate/examples/full.py)
+
+[DEPS](/infra/bots/recipe_modules/isolate/examples/full.py#13): [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], [isolate](#recipe_modules-isolate), [swarming\_client](#recipe_modules-swarming_client)
+
+&mdash; **def [RunSteps](/infra/bots/recipe_modules/isolate/examples/full.py#28)(api, always_use_exparchive):**
+### *recipes* / [isolate:tests/clean\_isolated\_files](/infra/bots/recipe_modules/isolate/tests/clean_isolated_files.py)
+
+[DEPS](/infra/bots/recipe_modules/isolate/tests/clean_isolated_files.py#5): [recipe\_engine/path][recipe_engine/recipe_modules/path], [isolate](#recipe_modules-isolate)
+
+&mdash; **def [RunSteps](/infra/bots/recipe_modules/isolate/tests/clean_isolated_files.py#11)(api):**
+### *recipes* / [isolate:tests/isolate\_tests](/infra/bots/recipe_modules/isolate/tests/isolate_tests.py)
+
+[DEPS](/infra/bots/recipe_modules/isolate/tests/isolate_tests.py#5): [recipe\_engine/path][recipe_engine/recipe_modules/path], [isolate](#recipe_modules-isolate)
+
+&mdash; **def [RunSteps](/infra/bots/recipe_modules/isolate/tests/isolate_tests.py#11)(api):**
+### *recipes* / [isolate:tests/isolated\_tests](/infra/bots/recipe_modules/isolate/tests/isolated_tests.py)
+
+[DEPS](/infra/bots/recipe_modules/isolate/tests/isolated_tests.py#5): [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [isolate](#recipe_modules-isolate)
+
+&mdash; **def [RunSteps](/infra/bots/recipe_modules/isolate/tests/isolated_tests.py#12)(api):**
+### *recipes* / [isolate:tests/run\_isolated](/infra/bots/recipe_modules/isolate/tests/run_isolated.py)
+
+[DEPS](/infra/bots/recipe_modules/isolate/tests/run_isolated.py#5): [isolate](#recipe_modules-isolate)
+
+&mdash; **def [RunSteps](/infra/bots/recipe_modules/isolate/tests/run_isolated.py#10)(api):**
+### *recipes* / [perf](/infra/bots/recipes/perf.py)
+
+[DEPS](/infra/bots/recipes/perf.py#12): [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], [core](#recipe_modules-core), [env](#recipe_modules-env), [flavor](#recipe_modules-flavor), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
+
+&mdash; **def [RunSteps](/infra/bots/recipes/perf.py#351)(api):**
+
+&mdash; **def [nanobench\_flags](/infra/bots/recipes/perf.py#29)(api, bot):**
+
+&mdash; **def [perf\_steps](/infra/bots/recipes/perf.py#237)(api):**
+
+Run Skia benchmarks.
+### *recipes* / [recreate\_skps](/infra/bots/recipes/recreate_skps.py)
+
+[DEPS](/infra/bots/recipes/recreate_skps.py#9): [depot\_tools/gclient][depot_tools/recipe_modules/gclient], [depot\_tools/gsutil][depot_tools/recipe_modules/gsutil], [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/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [core](#recipe_modules-core), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
+
+Recipe for the Skia RecreateSKPs Bot.
+
+&mdash; **def [RunSteps](/infra/bots/recipes/recreate_skps.py#59)(api):**
+### *recipes* / [run:examples/full](/infra/bots/recipe_modules/run/examples/full.py)
+
+[DEPS](/infra/bots/recipe_modules/run/examples/full.py#6): [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], [run](#recipe_modules-run), [vars](#recipe_modules-vars)
+
+&mdash; **def [RunSteps](/infra/bots/recipe_modules/run/examples/full.py#20)(api):**
+
+&mdash; **def [myfunc](/infra/bots/recipe_modules/run/examples/full.py#16)(api, i):**
+### *recipes* / [skia\_swarming:examples/full](/infra/bots/recipe_modules/skia_swarming/examples/full.py)
+
+[DEPS](/infra/bots/recipe_modules/skia_swarming/examples/full.py#6): [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [skia\_swarming](#recipe_modules-skia_swarming)
+
+&mdash; **def [RunSteps](/infra/bots/recipe_modules/skia_swarming/examples/full.py#14)(api):**
+### *recipes* / [skpbench](/infra/bots/recipes/skpbench.py)
+
+[DEPS](/infra/bots/recipes/skpbench.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/python][recipe_engine/recipe_modules/python], [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], [core](#recipe_modules-core), [flavor](#recipe_modules-flavor), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
+
+&mdash; **def [RunSteps](/infra/bots/recipes/skpbench.py#101)(api):**
+
+&mdash; **def [skpbench\_steps](/infra/bots/recipes/skpbench.py#39)(api):**
+
+benchmark Skia using skpbench.
+### *recipes* / [swarming:examples/full](/infra/bots/recipe_modules/swarming/examples/full.py)
+
+[DEPS](/infra/bots/recipe_modules/swarming/examples/full.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/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [isolate](#recipe_modules-isolate), [swarming](#recipe_modules-swarming), [swarming\_client](#recipe_modules-swarming_client)
+
+&mdash; **def [RunSteps](/infra/bots/recipe_modules/swarming/examples/full.py#37)(api, platforms, show_isolated_out_in_collect_step, show_shards_in_collect_step, gtest_task, merge):**
+### *recipes* / [swarming\_client:examples/full](/infra/bots/recipe_modules/swarming_client/examples/full.py)
+
+[DEPS](/infra/bots/recipe_modules/swarming_client/examples/full.py#11): [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], [swarming\_client](#recipe_modules-swarming_client)
+
+&mdash; **def [RunSteps](/infra/bots/recipe_modules/swarming_client/examples/full.py#19)(api):**
+### *recipes* / [test](/infra/bots/recipes/test.py)
+
+[DEPS](/infra/bots/recipes/test.py#9): [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/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [core](#recipe_modules-core), [env](#recipe_modules-env), [flavor](#recipe_modules-flavor), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
+
+&mdash; **def [RunSteps](/infra/bots/recipes/test.py#861)(api):**
+
+&mdash; **def [dm\_flags](/infra/bots/recipes/test.py#27)(api, bot):**
+
+&mdash; **def [key\_params](/infra/bots/recipes/test.py#687)(api):**
+
+Build a unique key from the builder name (as a list).
+
+E.g.  arch x86 gpu GeForce320M mode MacMini4.1 os Mac10.6
+
+&mdash; **def [test\_steps](/infra/bots/recipes/test.py#704)(api):**
+
+Run the DM test.
+### *recipes* / [update\_meta\_config](/infra/bots/recipes/update_meta_config.py)
+
+[DEPS](/infra/bots/recipes/update_meta_config.py#9): [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/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [core](#recipe_modules-core), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
+
+Recipe for the Bot that updates meta config.
+
+&mdash; **def [RunSteps](/infra/bots/recipes/update_meta_config.py#38)(api):**
+### *recipes* / [upload\_dm\_results](/infra/bots/recipes/upload_dm_results.py)
+
+[DEPS](/infra/bots/recipes/upload_dm_results.py#12): [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]
+
+&mdash; **def [RunSteps](/infra/bots/recipes/upload_dm_results.py#47)(api):**
+
+&mdash; **def [cp](/infra/bots/recipes/upload_dm_results.py#28)(api, name, src, dst, extra_args=None):**
+### *recipes* / [upload\_nano\_results](/infra/bots/recipes/upload_nano_results.py)
+
+[DEPS](/infra/bots/recipes/upload_nano_results.py#9): [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]
+
+&mdash; **def [RunSteps](/infra/bots/recipes/upload_nano_results.py#19)(api):**
+### *recipes* / [vars:examples/full](/infra/bots/recipe_modules/vars/examples/full.py)
+
+[DEPS](/infra/bots/recipe_modules/vars/examples/full.py#6): [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [vars](#recipe_modules-vars)
+
+&mdash; **def [RunSteps](/infra/bots/recipe_modules/vars/examples/full.py#12)(api):**
+
+[depot_tools/recipe_modules/bot_update]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/1bf0340381c2a6942e84fbd896da00df2cba32b1/recipes/README.recipes.md#recipe_modules-bot_update
+[depot_tools/recipe_modules/depot_tools]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/1bf0340381c2a6942e84fbd896da00df2cba32b1/recipes/README.recipes.md#recipe_modules-depot_tools
+[depot_tools/recipe_modules/gclient]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/1bf0340381c2a6942e84fbd896da00df2cba32b1/recipes/README.recipes.md#recipe_modules-gclient
+[depot_tools/recipe_modules/git]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/1bf0340381c2a6942e84fbd896da00df2cba32b1/recipes/README.recipes.md#recipe_modules-git
+[depot_tools/recipe_modules/gsutil]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/1bf0340381c2a6942e84fbd896da00df2cba32b1/recipes/README.recipes.md#recipe_modules-gsutil
+[depot_tools/recipe_modules/tryserver]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/1bf0340381c2a6942e84fbd896da00df2cba32b1/recipes/README.recipes.md#recipe_modules-tryserver
+[recipe_engine/recipe_modules/context]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/54df660706538e94951f101607491e659e5e3ed1/README.recipes.md#recipe_modules-context
+[recipe_engine/recipe_modules/file]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/54df660706538e94951f101607491e659e5e3ed1/README.recipes.md#recipe_modules-file
+[recipe_engine/recipe_modules/json]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/54df660706538e94951f101607491e659e5e3ed1/README.recipes.md#recipe_modules-json
+[recipe_engine/recipe_modules/path]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/54df660706538e94951f101607491e659e5e3ed1/README.recipes.md#recipe_modules-path
+[recipe_engine/recipe_modules/platform]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/54df660706538e94951f101607491e659e5e3ed1/README.recipes.md#recipe_modules-platform
+[recipe_engine/recipe_modules/properties]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/54df660706538e94951f101607491e659e5e3ed1/README.recipes.md#recipe_modules-properties
+[recipe_engine/recipe_modules/python]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/54df660706538e94951f101607491e659e5e3ed1/README.recipes.md#recipe_modules-python
+[recipe_engine/recipe_modules/raw_io]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/54df660706538e94951f101607491e659e5e3ed1/README.recipes.md#recipe_modules-raw_io
+[recipe_engine/recipe_modules/step]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/54df660706538e94951f101607491e659e5e3ed1/README.recipes.md#recipe_modules-step
+[recipe_engine/recipe_modules/tempfile]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/54df660706538e94951f101607491e659e5e3ed1/README.recipes.md#recipe_modules-tempfile
+[recipe_engine/recipe_modules/time]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/54df660706538e94951f101607491e659e5e3ed1/README.recipes.md#recipe_modules-time
+[recipe_engine/wkt/RecipeApi]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/54df660706538e94951f101607491e659e5e3ed1/recipe_engine/recipe_api.py#992
+[recipe_engine/wkt/returns_placeholder]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/54df660706538e94951f101607491e659e5e3ed1/recipe_engine/util.py#119
diff --git a/infra/bots/recipe_modules/core/examples/full.expected/Housekeeper-Weekly-RecreateSKPs.json b/infra/bots/recipe_modules/core/examples/full.expected/Housekeeper-Weekly-RecreateSKPs.json
index ec56896..ab69071 100644
--- a/infra/bots/recipe_modules/core/examples/full.expected/Housekeeper-Weekly-RecreateSKPs.json
+++ b/infra/bots/recipe_modules/core/examples/full.expected/Housekeeper-Weekly-RecreateSKPs.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}, {'deps_file': '.DEPS.git', 'managed': False, 'name': 'src', 'url': 'https://chromium.googlesource.com/chromium/src.git'}]",
       "--patch_root",
       "skia",
@@ -50,10 +50,10 @@
       "src@origin/lkcr"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipe_modules/core/examples/full.expected/cross_repo_trybot.json b/infra/bots/recipe_modules/core/examples/full.expected/cross_repo_trybot.json
index 838d31c..e774442 100644
--- a/infra/bots/recipe_modules/core/examples/full.expected/cross_repo_trybot.json
+++ b/infra/bots/recipe_modules/core/examples/full.expected/cross_repo_trybot.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'parent_repo', 'url': 'https://skia.googlesource.com/parent_repo.git'}]",
       "--patch_root",
       "skia",
@@ -52,10 +52,10 @@
       "parent_repo@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipe_modules/core/examples/full.expected/flutter_trybot.json b/infra/bots/recipe_modules/core/examples/full.expected/flutter_trybot.json
index 3258920..f07fc96 100644
--- a/infra/bots/recipe_modules/core/examples/full.expected/flutter_trybot.json
+++ b/infra/bots/recipe_modules/core/examples/full.expected/flutter_trybot.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': True, 'name': 'src/flutter', 'url': 'https://github.com/flutter/engine.git'}]\ntarget_os = ['android']",
       "--patch_root",
       "src/third_party/skia",
@@ -54,10 +54,10 @@
       "src/third_party/skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]/flutter",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipe_modules/core/examples/full.expected/pdfium_trybot.json b/infra/bots/recipe_modules/core/examples/full.expected/pdfium_trybot.json
index 0192781..a37e089 100644
--- a/infra/bots/recipe_modules/core/examples/full.expected/pdfium_trybot.json
+++ b/infra/bots/recipe_modules/core/examples/full.expected/pdfium_trybot.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': True, 'name': 'pdfium', 'url': 'https://pdfium.googlesource.com/pdfium.git'}]",
       "--patch_root",
       "pdfium/third_party/skia",
@@ -54,10 +54,10 @@
       "pdfium/third_party/skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipe_modules/core/examples/full.expected/test.json b/infra/bots/recipe_modules/core/examples/full.expected/test.json
index 257c13d..7c2cb44 100644
--- a/infra/bots/recipe_modules/core/examples/full.expected/test.json
+++ b/infra/bots/recipe_modules/core/examples/full.expected/test.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_C:\\\\_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -52,10 +52,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_C:\\_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/check_generated_files.expected/Housekeeper-PerCommit-CheckGeneratedFiles.json b/infra/bots/recipes/check_generated_files.expected/Housekeeper-PerCommit-CheckGeneratedFiles.json
index afd9382..2c7b839 100644
--- a/infra/bots/recipes/check_generated_files.expected/Housekeeper-PerCommit-CheckGeneratedFiles.json
+++ b/infra/bots/recipes/check_generated_files.expected/Housekeeper-PerCommit-CheckGeneratedFiles.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Mac-Clang-arm64-Debug-Android.json b/infra/bots/recipes/compile.expected/Build-Mac-Clang-arm64-Debug-Android.json
index c1b62f5..467ea8e 100644
--- a/infra/bots/recipes/compile.expected/Build-Mac-Clang-arm64-Debug-Android.json
+++ b/infra/bots/recipes/compile.expected/Build-Mac-Clang-arm64-Debug-Android.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Mac-Clang-arm64-Debug-iOS.json b/infra/bots/recipes/compile.expected/Build-Mac-Clang-arm64-Debug-iOS.json
index ba654dd..7dfc167 100644
--- a/infra/bots/recipes/compile.expected/Build-Mac-Clang-arm64-Debug-iOS.json
+++ b/infra/bots/recipes/compile.expected/Build-Mac-Clang-arm64-Debug-iOS.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Mac-Clang-x64-Release-iOS.json b/infra/bots/recipes/compile.expected/Build-Mac-Clang-x64-Release-iOS.json
index 0d16aec..de68f05 100644
--- a/infra/bots/recipes/compile.expected/Build-Mac-Clang-x64-Release-iOS.json
+++ b/infra/bots/recipes/compile.expected/Build-Mac-Clang-x64-Release-iOS.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Mac-Clang-x86_64-Debug-CommandBuffer.json b/infra/bots/recipes/compile.expected/Build-Mac-Clang-x86_64-Debug-CommandBuffer.json
index 9ef412b..bde48f8 100644
--- a/infra/bots/recipes/compile.expected/Build-Mac-Clang-x86_64-Debug-CommandBuffer.json
+++ b/infra/bots/recipes/compile.expected/Build-Mac-Clang-x86_64-Debug-CommandBuffer.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}, {'deps_file': '.DEPS.git', 'managed': False, 'name': 'src', 'url': 'https://chromium.googlesource.com/chromium/src.git'}]",
       "--patch_root",
       "skia",
@@ -50,10 +50,10 @@
       "src@origin/lkcr"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Mac-Clang-x86_64-Release.json b/infra/bots/recipes/compile.expected/Build-Mac-Clang-x86_64-Release.json
index d9d8572..d51e07d 100644
--- a/infra/bots/recipes/compile.expected/Build-Mac-Clang-x86_64-Release.json
+++ b/infra/bots/recipes/compile.expected/Build-Mac-Clang-x86_64-Release.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-arm-Release-Chromebook_C100p.json b/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-arm-Release-Chromebook_C100p.json
index 54ee674..103fc31 100644
--- a/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-arm-Release-Chromebook_C100p.json
+++ b/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-arm-Release-Chromebook_C100p.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-arm64-Release-Android.json b/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-arm64-Release-Android.json
index 493981a..82c0077 100644
--- a/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-arm64-Release-Android.json
+++ b/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-arm64-Release-Android.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-arm64-Release-Android_Vulkan.json b/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-arm64-Release-Android_Vulkan.json
index c8c74a3..d0b0124 100644
--- a/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-arm64-Release-Android_Vulkan.json
+++ b/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-arm64-Release-Android_Vulkan.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-mipsel-Debug-Android.json b/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-mipsel-Debug-Android.json
index 4e17051..829038f 100644
--- a/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-mipsel-Debug-Android.json
+++ b/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-mipsel-Debug-Android.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-x86_64-Debug-ASAN.json b/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-x86_64-Debug-ASAN.json
index 9c4f9ae..d00fce5 100644
--- a/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-x86_64-Debug-ASAN.json
+++ b/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-x86_64-Debug-ASAN.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-x86_64-Debug-MSAN.json b/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-x86_64-Debug-MSAN.json
index 7ead220..a78179b 100644
--- a/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-x86_64-Debug-MSAN.json
+++ b/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-x86_64-Debug-MSAN.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-x86_64-Debug.json b/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-x86_64-Debug.json
index 43a1a9f..5cd5971 100644
--- a/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-x86_64-Debug.json
+++ b/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-x86_64-Debug.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-x86_64-Release-Mini.json b/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-x86_64-Release-Mini.json
index d7767bf..5db60b8 100644
--- a/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-x86_64-Release-Mini.json
+++ b/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-x86_64-Release-Mini.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-x86_64-Release-Vulkan.json b/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-x86_64-Release-Vulkan.json
index 98274dd..9d4c5c0 100644
--- a/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-x86_64-Release-Vulkan.json
+++ b/infra/bots/recipes/compile.expected/Build-Ubuntu-Clang-x86_64-Release-Vulkan.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Ubuntu-EMCC-wasm-Release.json b/infra/bots/recipes/compile.expected/Build-Ubuntu-EMCC-wasm-Release.json
index 116a436..ff03e48 100644
--- a/infra/bots/recipes/compile.expected/Build-Ubuntu-EMCC-wasm-Release.json
+++ b/infra/bots/recipes/compile.expected/Build-Ubuntu-EMCC-wasm-Release.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-arm-Release-Chromecast.json b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-arm-Release-Chromecast.json
index 6437684..47e971b 100644
--- a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-arm-Release-Chromecast.json
+++ b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-arm-Release-Chromecast.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86-Debug.json b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86-Debug.json
index 7c5b42f..3e992aa 100644
--- a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86-Debug.json
+++ b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86-Debug.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Debug-GN.json b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Debug-GN.json
index 8897865..addfcbf 100644
--- a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Debug-GN.json
+++ b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Debug-GN.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Debug-MSAN.json b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Debug-MSAN.json
index a749d0a..f35662d 100644
--- a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Debug-MSAN.json
+++ b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Debug-MSAN.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Debug-NoGPU.json b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Debug-NoGPU.json
index 3da5f62..15a847e 100644
--- a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Debug-NoGPU.json
+++ b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Debug-NoGPU.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Debug-SK_USE_DISCARDABLE_SCALEDIMAGECACHE.json b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Debug-SK_USE_DISCARDABLE_SCALEDIMAGECACHE.json
index 1d5ca2b..88c252c 100644
--- a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Debug-SK_USE_DISCARDABLE_SCALEDIMAGECACHE.json
+++ b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Debug-SK_USE_DISCARDABLE_SCALEDIMAGECACHE.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-ANGLE.json b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-ANGLE.json
index 6c3b382..b326ba0 100644
--- a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-ANGLE.json
+++ b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-ANGLE.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-Fast.json b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-Fast.json
index df5d227..15f1763 100644
--- a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-Fast.json
+++ b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-Fast.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-Flutter_Android.json b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-Flutter_Android.json
index 056c8ee..ecf89f0 100644
--- a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-Flutter_Android.json
+++ b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-Flutter_Android.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': True, 'name': 'src/flutter', 'url': 'https://github.com/flutter/engine.git'}]\ntarget_os = ['android']",
       "--patch_root",
       "src/third_party/skia",
@@ -50,10 +50,10 @@
       "src/third_party/skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]/flutter",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-Mesa.json b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-Mesa.json
index 223d367..c85f877 100644
--- a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-Mesa.json
+++ b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-Mesa.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-PDFium.json b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-PDFium.json
index 829dcbd..3f684b4 100644
--- a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-PDFium.json
+++ b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-PDFium.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': True, 'name': 'pdfium', 'url': 'https://pdfium.googlesource.com/pdfium.git'}]",
       "--patch_root",
       "pdfium/third_party/skia",
@@ -50,10 +50,10 @@
       "pdfium/third_party/skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-PDFium_SkiaPaths.json b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-PDFium_SkiaPaths.json
index 78da0b7..c60067d 100644
--- a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-PDFium_SkiaPaths.json
+++ b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-PDFium_SkiaPaths.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': True, 'name': 'pdfium', 'url': 'https://pdfium.googlesource.com/pdfium.git'}]",
       "--patch_root",
       "pdfium/third_party/skia",
@@ -50,10 +50,10 @@
       "pdfium/third_party/skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-Shared.json b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-Shared.json
index ce4d444..d5ed92b 100644
--- a/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-Shared.json
+++ b/infra/bots/recipes/compile.expected/Build-Ubuntu-GCC-x86_64-Release-Shared.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Win-Clang-arm64-Release-Android.json b/infra/bots/recipes/compile.expected/Build-Win-Clang-arm64-Release-Android.json
index cf198a4..df494a5 100644
--- a/infra/bots/recipes/compile.expected/Build-Win-Clang-arm64-Release-Android.json
+++ b/infra/bots/recipes/compile.expected/Build-Win-Clang-arm64-Release-Android.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]\\resources\\bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_C:\\\\_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_C:\\_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>;RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86-Debug-ANGLE.json b/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86-Debug-ANGLE.json
index 5ff63e3..6d4c527 100644
--- a/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86-Debug-ANGLE.json
+++ b/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86-Debug-ANGLE.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]\\resources\\bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_C:\\\\_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_C:\\_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>;RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86-Debug-Exceptions.json b/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86-Debug-Exceptions.json
index 978cc15..1dc4466 100644
--- a/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86-Debug-Exceptions.json
+++ b/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86-Debug-Exceptions.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]\\resources\\bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_C:\\\\_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_C:\\_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>;RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86-Debug.json b/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86-Debug.json
index 52f6b08..f0e7839 100644
--- a/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86-Debug.json
+++ b/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86-Debug.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]\\resources\\bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_C:\\\\_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_C:\\_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>;RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86-Release-GDI.json b/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86-Release-GDI.json
index 118dddb..09b7dc4 100644
--- a/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86-Release-GDI.json
+++ b/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86-Release-GDI.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]\\resources\\bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_C:\\\\_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_C:\\_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>;RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86-Release-GN.json b/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86-Release-GN.json
index a7a9234..5c898aa 100644
--- a/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86-Release-GN.json
+++ b/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86-Release-GN.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]\\resources\\bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_C:\\\\_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_C:\\_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>;RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86_64-Release-Vulkan.json b/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86_64-Release-Vulkan.json
index 770b34a..97b6f9d 100644
--- a/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86_64-Release-Vulkan.json
+++ b/infra/bots/recipes/compile.expected/Build-Win-MSVC-x86_64-Release-Vulkan.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]\\resources\\bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_C:\\\\_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_C:\\_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>;RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/alternate_repo.json b/infra/bots/recipes/compile.expected/alternate_repo.json
index 8ae7213..97e4f2a 100644
--- a/infra/bots/recipes/compile.expected/alternate_repo.json
+++ b/infra/bots/recipes/compile.expected/alternate_repo.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_C:\\\\_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'other_repo', 'url': 'https://skia.googlesource.com/other_repo.git'}]",
       "--patch_root",
       "other_repo",
@@ -48,10 +48,10 @@
       "other_repo@abc123"
     ],
     "cwd": "[CUSTOM_C:\\_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/flutter_trybot.json b/infra/bots/recipes/compile.expected/flutter_trybot.json
index 9c4c4d0..958f934 100644
--- a/infra/bots/recipes/compile.expected/flutter_trybot.json
+++ b/infra/bots/recipes/compile.expected/flutter_trybot.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': True, 'name': 'src/flutter', 'url': 'https://github.com/flutter/engine.git'}]\ntarget_os = ['android']",
       "--patch_root",
       "src/third_party/skia",
@@ -54,10 +54,10 @@
       "src/third_party/skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]/flutter",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/pdfium_trybot.json b/infra/bots/recipes/compile.expected/pdfium_trybot.json
index c9ed8f6..585e934 100644
--- a/infra/bots/recipes/compile.expected/pdfium_trybot.json
+++ b/infra/bots/recipes/compile.expected/pdfium_trybot.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': True, 'name': 'pdfium', 'url': 'https://pdfium.googlesource.com/pdfium.git'}]",
       "--patch_root",
       "pdfium/third_party/skia",
@@ -54,10 +54,10 @@
       "pdfium/third_party/skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/compile.expected/trybot.json b/infra/bots/recipes/compile.expected/trybot.json
index a3f9b2b..651c1d5 100644
--- a/infra/bots/recipes/compile.expected/trybot.json
+++ b/infra/bots/recipes/compile.expected/trybot.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_C:\\\\_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -52,10 +52,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_C:\\_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/ct_skps.expected/CT_CPU_BENCH_10k_SKPs.json b/infra/bots/recipes/ct_skps.expected/CT_CPU_BENCH_10k_SKPs.json
index dd4a283..b0f7c0b 100644
--- a/infra/bots/recipes/ct_skps.expected/CT_CPU_BENCH_10k_SKPs.json
+++ b/infra/bots/recipes/ct_skps.expected/CT_CPU_BENCH_10k_SKPs.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/ct_skps.expected/CT_DM_100k_SKPs.json b/infra/bots/recipes/ct_skps.expected/CT_DM_100k_SKPs.json
index 5613cb6..2bef930 100644
--- a/infra/bots/recipes/ct_skps.expected/CT_DM_100k_SKPs.json
+++ b/infra/bots/recipes/ct_skps.expected/CT_DM_100k_SKPs.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/ct_skps.expected/CT_DM_10k_SKPs.json b/infra/bots/recipes/ct_skps.expected/CT_DM_10k_SKPs.json
index 09b4f63..9726bf4 100644
--- a/infra/bots/recipes/ct_skps.expected/CT_DM_10k_SKPs.json
+++ b/infra/bots/recipes/ct_skps.expected/CT_DM_10k_SKPs.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/ct_skps.expected/CT_DM_10k_SKPs_Trybot.json b/infra/bots/recipes/ct_skps.expected/CT_DM_10k_SKPs_Trybot.json
index 67e6ceb..1b5f1c3 100644
--- a/infra/bots/recipes/ct_skps.expected/CT_DM_10k_SKPs_Trybot.json
+++ b/infra/bots/recipes/ct_skps.expected/CT_DM_10k_SKPs_Trybot.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -52,10 +52,10 @@
       "skia@origin/master"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/ct_skps.expected/CT_DM_1m_SKPs.json b/infra/bots/recipes/ct_skps.expected/CT_DM_1m_SKPs.json
index d1ccac2..d9e6c07 100644
--- a/infra/bots/recipes/ct_skps.expected/CT_DM_1m_SKPs.json
+++ b/infra/bots/recipes/ct_skps.expected/CT_DM_1m_SKPs.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/ct_skps.expected/CT_DM_1m_SKPs_2slaves_failure.json b/infra/bots/recipes/ct_skps.expected/CT_DM_1m_SKPs_2slaves_failure.json
index 79bc364..872a058 100644
--- a/infra/bots/recipes/ct_skps.expected/CT_DM_1m_SKPs_2slaves_failure.json
+++ b/infra/bots/recipes/ct_skps.expected/CT_DM_1m_SKPs_2slaves_failure.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/ct_skps.expected/CT_DM_1m_SKPs_slave3_failure.json b/infra/bots/recipes/ct_skps.expected/CT_DM_1m_SKPs_slave3_failure.json
index ede3229..15b059f 100644
--- a/infra/bots/recipes/ct_skps.expected/CT_DM_1m_SKPs_slave3_failure.json
+++ b/infra/bots/recipes/ct_skps.expected/CT_DM_1m_SKPs_slave3_failure.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/ct_skps.expected/CT_GPU_BENCH_10k_SKPs.json b/infra/bots/recipes/ct_skps.expected/CT_GPU_BENCH_10k_SKPs.json
index 7d239ca..4a637ec 100644
--- a/infra/bots/recipes/ct_skps.expected/CT_GPU_BENCH_10k_SKPs.json
+++ b/infra/bots/recipes/ct_skps.expected/CT_GPU_BENCH_10k_SKPs.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/ct_skps.expected/CT_GPU_BENCH_1k_SKPs.json b/infra/bots/recipes/ct_skps.expected/CT_GPU_BENCH_1k_SKPs.json
index f7f67e4..39b4820 100644
--- a/infra/bots/recipes/ct_skps.expected/CT_GPU_BENCH_1k_SKPs.json
+++ b/infra/bots/recipes/ct_skps.expected/CT_GPU_BENCH_1k_SKPs.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/ct_skps.expected/CT_IMG_DECODE_100k_SKPs.json b/infra/bots/recipes/ct_skps.expected/CT_IMG_DECODE_100k_SKPs.json
index c77d742..ff86054 100644
--- a/infra/bots/recipes/ct_skps.expected/CT_IMG_DECODE_100k_SKPs.json
+++ b/infra/bots/recipes/ct_skps.expected/CT_IMG_DECODE_100k_SKPs.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/ct_skps.expected/CT_IMG_DECODE_10k_SKPs.json b/infra/bots/recipes/ct_skps.expected/CT_IMG_DECODE_10k_SKPs.json
index c945d31..13ad9bd 100644
--- a/infra/bots/recipes/ct_skps.expected/CT_IMG_DECODE_10k_SKPs.json
+++ b/infra/bots/recipes/ct_skps.expected/CT_IMG_DECODE_10k_SKPs.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/ct_skps.expected/CT_IMG_DECODE_10k_SKPs_Trybot.json b/infra/bots/recipes/ct_skps.expected/CT_IMG_DECODE_10k_SKPs_Trybot.json
index c14f2c8..ba63a3e 100644
--- a/infra/bots/recipes/ct_skps.expected/CT_IMG_DECODE_10k_SKPs_Trybot.json
+++ b/infra/bots/recipes/ct_skps.expected/CT_IMG_DECODE_10k_SKPs_Trybot.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -52,10 +52,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/housekeeper.expected/Housekeeper-PerCommit-Trybot.json b/infra/bots/recipes/housekeeper.expected/Housekeeper-PerCommit-Trybot.json
index 9256830..68846f9 100644
--- a/infra/bots/recipes/housekeeper.expected/Housekeeper-PerCommit-Trybot.json
+++ b/infra/bots/recipes/housekeeper.expected/Housekeeper-PerCommit-Trybot.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -52,10 +52,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/housekeeper.expected/Housekeeper-PerCommit.json b/infra/bots/recipes/housekeeper.expected/Housekeeper-PerCommit.json
index 64dae08..c07ad6f 100644
--- a/infra/bots/recipes/housekeeper.expected/Housekeeper-PerCommit.json
+++ b/infra/bots/recipes/housekeeper.expected/Housekeeper-PerCommit.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/infra.expected/failed_all_updates.json b/infra/bots/recipes/infra.expected/failed_all_updates.json
index 7e1dc3e..2f47b34 100644
--- a/infra/bots/recipes/infra.expected/failed_all_updates.json
+++ b/infra/bots/recipes/infra.expected/failed_all_updates.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/infra.expected/failed_one_update.json b/infra/bots/recipes/infra.expected/failed_one_update.json
index b13d2f7..45c0e74 100644
--- a/infra/bots/recipes/infra.expected/failed_one_update.json
+++ b/infra/bots/recipes/infra.expected/failed_one_update.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/infra.expected/infra_tests.json b/infra/bots/recipes/infra.expected/infra_tests.json
index 9221052..79fb6dc 100644
--- a/infra/bots/recipes/infra.expected/infra_tests.json
+++ b/infra/bots/recipes/infra.expected/infra_tests.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/recreate_skps.expected/Housekeeper-Nightly-RecreateSKPs_Canary.json b/infra/bots/recipes/recreate_skps.expected/Housekeeper-Nightly-RecreateSKPs_Canary.json
index 45d0676..c6bc57b 100644
--- a/infra/bots/recipes/recreate_skps.expected/Housekeeper-Nightly-RecreateSKPs_Canary.json
+++ b/infra/bots/recipes/recreate_skps.expected/Housekeeper-Nightly-RecreateSKPs_Canary.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}, {'deps_file': '.DEPS.git', 'managed': False, 'name': 'src', 'url': 'https://chromium.googlesource.com/chromium/src.git'}]",
       "--patch_root",
       "skia",
@@ -50,10 +50,10 @@
       "src@origin/lkcr"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/recreate_skps.expected/Housekeeper-Weekly-RecreateSKPs.json b/infra/bots/recipes/recreate_skps.expected/Housekeeper-Weekly-RecreateSKPs.json
index 6d108fe..9e3fc7a 100644
--- a/infra/bots/recipes/recreate_skps.expected/Housekeeper-Weekly-RecreateSKPs.json
+++ b/infra/bots/recipes/recreate_skps.expected/Housekeeper-Weekly-RecreateSKPs.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}, {'deps_file': '.DEPS.git', 'managed': False, 'name': 'src', 'url': 'https://chromium.googlesource.com/chromium/src.git'}]",
       "--patch_root",
       "skia",
@@ -50,10 +50,10 @@
       "src@origin/lkcr"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/recreate_skps.expected/failed_upload.json b/infra/bots/recipes/recreate_skps.expected/failed_upload.json
index 3404164..7aa7275 100644
--- a/infra/bots/recipes/recreate_skps.expected/failed_upload.json
+++ b/infra/bots/recipes/recreate_skps.expected/failed_upload.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}, {'deps_file': '.DEPS.git', 'managed': False, 'name': 'src', 'url': 'https://chromium.googlesource.com/chromium/src.git'}]",
       "--patch_root",
       "skia",
@@ -50,10 +50,10 @@
       "src@origin/lkcr"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/update_meta_config.expected/Housekeeper-Nightly-UpdateMetaConfig.json b/infra/bots/recipes/update_meta_config.expected/Housekeeper-Nightly-UpdateMetaConfig.json
index a8fe69b..8f3d749 100644
--- a/infra/bots/recipes/update_meta_config.expected/Housekeeper-Nightly-UpdateMetaConfig.json
+++ b/infra/bots/recipes/update_meta_config.expected/Housekeeper-Nightly-UpdateMetaConfig.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/update_meta_config.expected/failed_update.json b/infra/bots/recipes/update_meta_config.expected/failed_update.json
index 0945895..87b1646 100644
--- a/infra/bots/recipes/update_meta_config.expected/failed_update.json
+++ b/infra/bots/recipes/update_meta_config.expected/failed_update.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -48,10 +48,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/bots/recipes/update_meta_config.expected/trybot_test.json b/infra/bots/recipes/update_meta_config.expected/trybot_test.json
index 16bcf06..b64a921 100644
--- a/infra/bots/recipes/update_meta_config.expected/trybot_test.json
+++ b/infra/bots/recipes/update_meta_config.expected/trybot_test.json
@@ -32,7 +32,7 @@
       "python",
       "-u",
       "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec",
+      "--spec-path",
       "cache_dir = '[CUSTOM_/_B_CACHE]'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
       "--patch_root",
       "skia",
@@ -52,10 +52,10 @@
       "skia@abc123"
     ],
     "cwd": "[CUSTOM_/_B_WORK]",
-    "env": {
-      "GIT_HTTP_LOW_SPEED_LIMIT": "1000",
-      "GIT_HTTP_LOW_SPEED_TIME": "300",
-      "PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
+    "env_prefixes": {
+      "PATH": [
+        "RECIPE_PACKAGE_REPO[depot_tools]"
+      ]
     },
     "infra_step": true,
     "name": "bot_update",
diff --git a/infra/config/recipes.cfg b/infra/config/recipes.cfg
index dba836b..95c4abb 100644
--- a/infra/config/recipes.cfg
+++ b/infra/config/recipes.cfg
@@ -14,13 +14,13 @@
   "deps": {
     "depot_tools": {
       "branch": "master",
-      "revision": "897bf0b0836110c11866f745c2dc5f506b864d56",
+      "revision": "1bf0340381c2a6942e84fbd896da00df2cba32b1",
       "url": "https://chromium.googlesource.com/chromium/tools/depot_tools.git"
     },
     "recipe_engine": {
       "branch": "master",
-      "revision": "49d884b8bf92c358eab83cf2da43ef9863a89bbb",
-      "url": "https://chromium.googlesource.com/external/github.com/luci/recipes-py.git"
+      "revision": "54df660706538e94951f101607491e659e5e3ed1",
+      "url": "https://chromium.googlesource.com/infra/luci/recipes-py.git"
     }
   },
   "project_id": "skia",