Replace api.path['foo'] with api.path.foo
Also minor other changes to keep coverage.
Bug: 329113288
Change-Id: I5c1828ce6fb8d5c08bd41c4727071b0c91fa7fcf
Reviewed-on: https://chromium-review.googlesource.com/c/infra/luci/recipes-py/+/5444879
Commit-Queue: Robbie Iannucci <iannucci@chromium.org>
Reviewed-by: Robbie Iannucci <iannucci@chromium.org>
Auto-Submit: Rob Mohr <mohrr@google.com>
diff --git a/README.recipes.md b/README.recipes.md
index b8beb07..9ef5a48 100644
--- a/README.recipes.md
+++ b/README.recipes.md
@@ -173,6 +173,7 @@
* [nodejs:examples/full](#recipes-nodejs_examples_full)
* [path:examples/full](#recipes-path_examples_full)
* [path:tests/cast_to_path](#recipes-path_tests_cast_to_path)
+ * [path:tests/deprecated](#recipes-path_tests_deprecated)
* [path:tests/dynamic_paths](#recipes-path_tests_dynamic_paths)
* [path:tests/exists](#recipes-path_tests_exists)
* [path:tests/test_api_legacy](#recipes-path_tests_test_api_legacy) — Test to cover legacy aspects of PathTestApi.
@@ -291,7 +292,7 @@
# Archive root/**
zip_path = (
api.archive.package(root).
- archive('archive step', api.path['start_dir'].join('output.zip'))
+ archive('archive step', api.path.start_dir.join('output.zip'))
)
Args:
@@ -991,7 +992,7 @@
Args:
output_dir: The output directory to download the caches to. If you're
- unsure of what directory to use, self.m.path['start_dir'] is a directory
+ unsure of what directory to use, self.m.path.start_dir is a directory
the recipe engine sets up for you that you can use.
caches: A CasCache proto message containing the caches which should be
downloaded. See properties.proto for the message definition.
@@ -1381,7 +1382,7 @@
Example:
```python
-with api.context(cwd=api.path['start_dir'].join('subdir')):
+with api.context(cwd=api.path.start_dir.join('subdir')):
# this step is run inside of the subdir directory.
api.step("cat subdir/foo", ['cat', './foo'])
```
@@ -1395,7 +1396,7 @@
Args:
* cwd (Path) - the current working directory to use for all steps.
To 'reset' to the original cwd at the time recipes started, pass
- `api.path['start_dir']`.
+ `api.path.start_dir`.
* env_prefixes (dict) - Environmental variable prefix augmentations. See
below for more info.
* env_suffixes (dict) - Environmental variable suffix augmentations. See
@@ -1444,7 +1445,7 @@
Returns the current working directory that steps will run in.
**Returns (Path|None)** - The current working directory. A value of None is
-equivalent to api.path['start_dir'], though only occurs if no cwd has been
+equivalent to api.path.start_dir, though only occurs if no cwd has been
set (e.g. in the outermost context of RunSteps).
  **@property**<br>— **def [deadline](/recipe_modules/context/api.py#345)(self):**
@@ -2381,7 +2382,7 @@
#### **class [GeneratorScriptApi](/recipe_modules/generator_script/api.py#12)([RecipeApi](/recipe_engine/recipe_api.py#471)):**
-— **def [\_\_call\_\_](/recipe_modules/generator_script/api.py#71)(self, path_to_script, \*args, \*\*_):**
+— **def [\_\_call\_\_](/recipe_modules/generator_script/api.py#71)(self, path_to_script, \*args, checkout_dir=None, \*\*_):**
Run a script and generate the steps emitted by that script.
@@ -2835,19 +2836,19 @@
In this way, all paths in Recipes are absolute, and are constructed from a small
collection of anchor points. The built-in anchor points are:
- * `api.path['start_dir']` - This is the directory that the recipe started in.
+ * `api.path.start_dir` - This is the directory that the recipe started in.
it's similar to `cwd`, except that it's constant.
- * `api.path['cache']` - This directory is provided by whatever's running the
+ * `api.path.cache_dir` - This directory is provided by whatever's running the
recipe. Files and directories created under here /may/ be evicted in between
runs of the recipe (i.e. to relieve disk pressure).
- * `api.path['cleanup']` - This directory is provided by whatever's running the
+ * `api.path.cleanup_dir` - This directory is provided by whatever's running the
recipe. Files and directories created under here /are guaranteed/ to be
evicted in between runs of the recipe. Additionally, this directory is
guaranteed to be empty when the recipe starts.
- * `api.path['tmp_base']` - This directory is the system-configured temp dir.
+ * `api.path.tmp_base_dir` - This directory is the system-configured temp dir.
This is a weaker form of 'cleanup', and its use should be avoided. This may
be removed in the future (or converted to an alias of 'cleanup').
- * `api.path['checkout']` - This directory is set by various checkout modules
+ * `api.path.checkout_dir` - This directory is set by various checkout modules
in recipes. It was originally intended to make recipes easier to read and
make code somewhat generic or homogeneous, but this was a mistake. New code
should avoid 'checkout', and instead just explicitly pass paths around. This
@@ -2855,7 +2856,7 @@
#### **class [PathApi](/recipe_modules/path/api.py#328)([RecipeApi](/recipe_engine/recipe_api.py#471)):**
-— **def [\_\_contains\_\_](/recipe_modules/path/api.py#588)(self, pathname: NamedBasePathsType):**
+— **def [\_\_contains\_\_](/recipe_modules/path/api.py#589)(self, pathname: NamedBasePathsType):**
This method is DEPRECATED.
@@ -2870,7 +2871,7 @@
a very complicated 'config' system. All of that has been removed, but this
method remains for now.
-— **def [\_\_getitem\_\_](/recipe_modules/path/api.py#687)(self, name: NamedBasePathsType):**
+— **def [\_\_getitem\_\_](/recipe_modules/path/api.py#688)(self, name: NamedBasePathsType):**
Gets the base path named `name`. See module docstring for more info.
@@ -2885,7 +2886,7 @@
pass the Paths around instead of using this global variable).
***
-— **def [\_\_setitem\_\_](/recipe_modules/path/api.py#606)(self, pathname: CheckoutPathNameType, path: config_types.Path):**
+— **def [\_\_setitem\_\_](/recipe_modules/path/api.py#607)(self, pathname: CheckoutPathNameType, path: config_types.Path):**
Sets the checkout path.
@@ -2895,7 +2896,7 @@
The only valid value of `pathname` is the literal string CheckoutPathName.
-— **def [abs\_to\_path](/recipe_modules/path/api.py#525)(self, abs_string_path: str):**
+— **def [abs\_to\_path](/recipe_modules/path/api.py#526)(self, abs_string_path: str):**
Converts an absolute path string `abs_string_path` to a real Path
object, using the most appropriate known base path.
@@ -2924,7 +2925,7 @@
Raises an ValueError if the preconditions are not met, otherwise returns the
Path object.
-— **def [abspath](/recipe_modules/path/api.py#796)(self, path: (config_types.Path | str)):**
+— **def [abspath](/recipe_modules/path/api.py#797)(self, path: (config_types.Path | str)):**
Equivalent to os.abspath.
@@ -2935,11 +2936,11 @@
Args:
* path - The path to check.
-— **def [basename](/recipe_modules/path/api.py#800)(self, path: (config_types.Path | str)):**
+— **def [basename](/recipe_modules/path/api.py#801)(self, path: (config_types.Path | str)):**
Equivalent to os.path.basename.
-  **@property**<br>— **def [cache\_dir](/recipe_modules/path/api.py#730)(self):**
+  **@property**<br>— **def [cache\_dir](/recipe_modules/path/api.py#731)(self):**
This directory is provided by whatever's running the recipe.
@@ -2962,7 +2963,7 @@
Note that directories created under here /may/ be evicted in between runs of
the recipe (i.e. to relieve disk pressure).
-— **def [cast\_to\_path](/recipe_modules/path/api.py#764)(self, strpath: str):**
+— **def [cast\_to\_path](/recipe_modules/path/api.py#765)(self, strpath: str):**
This returns a Path for strpath which can be used anywhere a Path is
required.
@@ -2975,20 +2976,20 @@
cache_dir), the returned Path will be based on that known path. This is
important for test compatibility.
-  **@checkout_dir.setter**<br>— **def [checkout\_dir](/recipe_modules/path/api.py#626)(self, path: config_types.Path):**
+  **@checkout_dir.setter**<br>— **def [checkout\_dir](/recipe_modules/path/api.py#627)(self, path: config_types.Path):**
Sets the global variable `api.path.checkout_dir` to the given path.
-  **@property**<br>— **def [cleanup\_dir](/recipe_modules/path/api.py#755)(self):**
+  **@property**<br>— **def [cleanup\_dir](/recipe_modules/path/api.py#756)(self):**
This directory is guaranteed to be cleaned up (eventually) after the
execution of this recipe.
This directory is guaranteed to be empty when the recipe starts.
-— **def [dirname](/recipe_modules/path/api.py#804)(self, path: (config_types.Path | str)):**
+— **def [dirname](/recipe_modules/path/api.py#805)(self, path: (config_types.Path | str)):**
For "foo/bar/baz", return "foo/bar".
@@ -3001,7 +3002,7 @@
Returns dirname of path
-— **def [eq](/recipe_modules/path/api.py#968)(self, path1: config_types.Path, path2: config_types.Path):**
+— **def [eq](/recipe_modules/path/api.py#969)(self, path1: config_types.Path, path2: config_types.Path):**
Check whether path1 points to the same path as path2.
@@ -3009,20 +3010,20 @@
**DEPRECATED**: Just directly compare path1 and path2 with `==`.
***
-— **def [exists](/recipe_modules/path/api.py#908)(self, path):**
+— **def [exists](/recipe_modules/path/api.py#909)(self, path):**
Equivalent to os.path.exists.
The presence or absence of paths can be mocked during the execution of the
recipe by using the mock_* methods.
-— **def [expanduser](/recipe_modules/path/api.py#899)(self, path):**
+— **def [expanduser](/recipe_modules/path/api.py#900)(self, path):**
-Do not use this, use `api.path['home']` instead.
+Do not use this, use `api.path.home_dir` instead.
-This ONLY handles `path` == "~", and returns `str(api.path['home'])`.
+This ONLY handles `path` == "~", and returns `str(api.path.home_dir)`.
-— **def [get](/recipe_modules/path/api.py#655)(self, name: NamedBasePathsType):**
+— **def [get](/recipe_modules/path/api.py#656)(self, name: NamedBasePathsType):**
Gets the base path named `name`. See module docstring for more info.
@@ -3037,7 +3038,7 @@
pass the Paths around instead of using this global variable).
***
-  **@property**<br>— **def [home\_dir](/recipe_modules/path/api.py#712)(self):**
+  **@property**<br>— **def [home\_dir](/recipe_modules/path/api.py#713)(self):**
This is the path to the current $HOME directory.
@@ -3049,7 +3050,7 @@
This is called by the recipe engine immediately after __init__(), but
with `self._paths_client` initialized.
-— **def [is\_parent\_of](/recipe_modules/path/api.py#975)(self, parent: config_types.Path, child: config_types.Path):**
+— **def [is\_parent\_of](/recipe_modules/path/api.py#976)(self, parent: config_types.Path, child: config_types.Path):**
Check whether child is contained within parent.
@@ -3057,32 +3058,32 @@
**DEPRECATED**: Just use `parent.is_parent_of(child)`.
***
-— **def [isdir](/recipe_modules/path/api.py#916)(self, path):**
+— **def [isdir](/recipe_modules/path/api.py#917)(self, path):**
Equivalent to os.path.isdir.
The presence or absence of paths can be mocked during the execution of the
recipe by using the mock_* methods.
-— **def [isfile](/recipe_modules/path/api.py#924)(self, path):**
+— **def [isfile](/recipe_modules/path/api.py#925)(self, path):**
Equivalent to os.path.isfile.
The presence or absence of paths can be mocked during the execution of the
recipe by using the mock_* methods.
-— **def [join](/recipe_modules/path/api.py#823)(self, path, \*paths):**
+— **def [join](/recipe_modules/path/api.py#824)(self, path, \*paths):**
Equivalent to os.path.join.
Note that Path objects returned from this module (e.g.
-api.path['start_dir']) have a built-in join method (e.g.
+api.path.start_dir) have a built-in join method (e.g.
new_path = p.join('some', 'name')). Many recipe modules expect Path objects
rather than strings. Using this `join` method gives you raw path joining
functionality and returns a string.
If your path is rooted in one of the path module's root paths (i.e. those
-retrieved with api.path[something]), then you can convert from a string path
+retrieved with api.path.something), then you can convert from a string path
back to a Path with the `abs_to_path` method.
— **def [mkdtemp](/recipe_modules/path/api.py#474)(self, prefix: str=tempfile.template):**
@@ -3094,7 +3095,7 @@
Returns a Path to the new directory.
-— **def [mkstemp](/recipe_modules/path/api.py#497)(self, prefix: str=tempfile.template):**
+— **def [mkstemp](/recipe_modules/path/api.py#498)(self, prefix: str=tempfile.template):**
Makes a new temporary file, returns Path to it.
@@ -3109,23 +3110,23 @@
either a resource script of your recipe module or recipe.
***
-— **def [mock\_add\_directory](/recipe_modules/path/api.py#943)(self, path: config_types.Path):**
+— **def [mock\_add\_directory](/recipe_modules/path/api.py#944)(self, path: config_types.Path):**
For testing purposes, mark that file |path| exists.
-— **def [mock\_add\_file](/recipe_modules/path/api.py#939)(self, path: config_types.Path):**
+— **def [mock\_add\_file](/recipe_modules/path/api.py#940)(self, path: config_types.Path):**
For testing purposes, mark that file |path| exists.
-— **def [mock\_add\_paths](/recipe_modules/path/api.py#932)(self, path: config_types.Path, kind: FileType=FileType.FILE):**
+— **def [mock\_add\_paths](/recipe_modules/path/api.py#933)(self, path: config_types.Path, kind: FileType=FileType.FILE):**
For testing purposes, mark that |path| exists.
-— **def [mock\_copy\_paths](/recipe_modules/path/api.py#947)(self, source: config_types.Path, dest: config_types.Path):**
+— **def [mock\_copy\_paths](/recipe_modules/path/api.py#948)(self, source: config_types.Path, dest: config_types.Path):**
For testing purposes, copy |source| to |dest|.
-— **def [mock\_remove\_paths](/recipe_modules/path/api.py#954)(self, path: config_types.Path, should_remove: Callable[([str], bool)]=(lambda p: True)):**
+— **def [mock\_remove\_paths](/recipe_modules/path/api.py#955)(self, path: config_types.Path, should_remove: Callable[([str], bool)]=(lambda p: True)):**
For testing purposes, mark that |path| doesn't exist.
@@ -3134,34 +3135,34 @@
should_remove: Called for every candidate path. Return True to remove this
path.
-— **def [normpath](/recipe_modules/path/api.py#895)(self, path):**
+— **def [normpath](/recipe_modules/path/api.py#896)(self, path):**
Equivalent to os.path.normpath.
-  **@property**<br>— **def [pardir](/recipe_modules/path/api.py#781)(self):**
+  **@property**<br>— **def [pardir](/recipe_modules/path/api.py#782)(self):**
Equivalent to os.pardir.
-  **@property**<br>— **def [pathsep](/recipe_modules/path/api.py#791)(self):**
+  **@property**<br>— **def [pathsep](/recipe_modules/path/api.py#792)(self):**
Equivalent to os.pathsep.
-— **def [realpath](/recipe_modules/path/api.py#883)(self, path: (config_types.Path | str)):**
+— **def [realpath](/recipe_modules/path/api.py#884)(self, path: (config_types.Path | str)):**
Equivalent to os.path.realpath.
-— **def [relpath](/recipe_modules/path/api.py#887)(self, path, start):**
+— **def [relpath](/recipe_modules/path/api.py#888)(self, path, start):**
Roughly equivalent to os.path.relpath.
Unlike os.path.relpath, `start` is _required_. If you want the 'current
directory', use the `recipe_engine/context` module's `cwd` property.
-  **@property**<br>— **def [sep](/recipe_modules/path/api.py#786)(self):**
+  **@property**<br>— **def [sep](/recipe_modules/path/api.py#787)(self):**
Equivalent to os.sep.
-— **def [split](/recipe_modules/path/api.py#838)(self, path):**
+— **def [split](/recipe_modules/path/api.py#839)(self, path):**
For "foo/bar/baz", return ("foo/bar", "baz").
@@ -3175,7 +3176,7 @@
Returns (dirname(path), basename(path)).
-— **def [splitext](/recipe_modules/path/api.py#859)(self, path: (config_types.Path | str)):**
+— **def [splitext](/recipe_modules/path/api.py#860)(self, path: (config_types.Path | str)):**
For "foo/bar.baz", return ("foo/bar", ".baz").
@@ -3190,7 +3191,7 @@
Returns:
(name, extension_including_dot).
-  **@property**<br>— **def [start\_dir](/recipe_modules/path/api.py#701)(self):**
+  **@property**<br>— **def [start\_dir](/recipe_modules/path/api.py#702)(self):**
This is the directory that the recipe started in. it's similar to `cwd`,
except that it's constant for the duration of the entire program.
@@ -3199,7 +3200,7 @@
See the 'recipe_engine/context' module which allows modifying the cwd safely
via a context manager.
-  **@property**<br>— **def [tmp\_base\_dir](/recipe_modules/path/api.py#721)(self):**
+  **@property**<br>— **def [tmp\_base\_dir](/recipe_modules/path/api.py#722)(self):**
This directory is the system-configured temp dir.
@@ -4322,17 +4323,17 @@
# output path, cwd and cache directory.
with api.context(
# Change the cwd of the launched LUCI executable
- cwd=api.path['start_dir'].join('subdir'),
+ cwd=api.path.start_dir.join('subdir'),
# Change the cache_dir of the launched LUCI executable. Defaults to
- # api.path['cache'] if unchanged.
- luciexe=sections_pb2.LUCIExe(cache_dir=api.path['cache'].join('sub')),
+ # api.path.cache_dir if unchanged.
+ luciexe=sections_pb2.LUCIExe(cache_dir=api.path.cache_dir.join('sub')),
):
# Command executed:
# `/path/to/run_exe --output [CLEANUP]/build.json --foo bar baz`
ret = api.sub_build("launch sub build",
[run_exe, '--foo', 'bar', 'baz'],
api.buildbucket.build,
- output_path=api.path['cleanup'].join('build.json'))
+ output_path=api.path.cleanup_dir.join('build.json'))
sub_build = ret.step.sub_build # access final build proto result
```
@@ -5720,16 +5721,22 @@
— **def [RunSteps](/recipe_modules/nodejs/examples/full.py#12)(api):**
### *recipes* / [path:examples/full](/recipe_modules/path/examples/full.py)
-[DEPS](/recipe_modules/path/examples/full.py#5): [json](#recipe_modules-json), [path](#recipe_modules-path), [platform](#recipe_modules-platform), [properties](#recipe_modules-properties), [step](#recipe_modules-step)
+[DEPS](/recipe_modules/path/examples/full.py#7): [json](#recipe_modules-json), [path](#recipe_modules-path), [platform](#recipe_modules-platform), [properties](#recipe_modules-properties), [step](#recipe_modules-step)
-— **def [RunSteps](/recipe_modules/path/examples/full.py#16)(api):**
+  **@recipe_api.ignore_warnings('recipe_engine/CHECKOUT_DIR_DEPRECATED')**<br>— **def [RunSteps](/recipe_modules/path/examples/full.py#18)(api):**
### *recipes* / [path:tests/cast\_to\_path](/recipe_modules/path/tests/cast_to_path.py)
[DEPS](/recipe_modules/path/tests/cast_to_path.py#8): [path](#recipe_modules-path), [platform](#recipe_modules-platform)
— **def [RunSteps](/recipe_modules/path/tests/cast_to_path.py#14)(api):**
+### *recipes* / [path:tests/deprecated](/recipe_modules/path/tests/deprecated.py)
+
+[DEPS](/recipe_modules/path/tests/deprecated.py#7): [path](#recipe_modules-path), [step](#recipe_modules-step)
+
+
+  **@recipe_api.ignore_warnings('recipe_engine/CHECKOUT_DIR_DEPRECATED', 'recipe_engine/PATH_GETITEM_DEPRECATED')**<br>— **def [RunSteps](/recipe_modules/path/tests/deprecated.py#13)(api):**
### *recipes* / [path:tests/dynamic\_paths](/recipe_modules/path/tests/dynamic_paths.py)
[DEPS](/recipe_modules/path/tests/dynamic_paths.py#7): [path](#recipe_modules-path)
diff --git a/doc/walkthrough.md b/doc/walkthrough.md
index 5826872..1ebbacd 100644
--- a/doc/walkthrough.md
+++ b/doc/walkthrough.md
@@ -692,7 +692,7 @@
def greet(self, default_verb=None):
self.m.step('Greet Admired Individual', [
- self.m.path['start_dir'].join(self.c.tool),
+ self.m.path.start_dir.join(self.c.tool),
self.c.verb % self.c.TARGET])
```
@@ -836,15 +836,15 @@
def RunSteps(api):
step_result = api.step(
'Determine blue moon',
- [api.path['start_dir'].join('is_blue_moon.sh')],
+ [api.path.start_dir.join('is_blue_moon.sh')],
ok_ret='any')
if step_result.retcode == 0:
api.step('HARLEM SHAKE!',
- [api.path['start_dir'].join('do_the_harlem_shake.sh')])
+ [api.path.start_dir.join('do_the_harlem_shake.sh')])
else:
api.step('Boring',
- [api.path['start_dir'].join('its_a_small_world.sh')])
+ [api.path.start_dir.join('its_a_small_world.sh')])
def GenTests(api):
yield api.test(
@@ -897,14 +897,14 @@
def RunSteps(api):
step_result = api.step(
'run tests',
- [api.path['start_dir'].join('do_test_things.sh'), api.json.output()])
+ [api.path.start_dir.join('do_test_things.sh'), api.json.output()])
num_passed = step_result.json.output['num_passed']
if num_passed > 500:
- api.step('victory', [api.path['start_dir'].join('do_a_dance.sh')])
+ api.step('victory', [api.path.start_dir.join('do_a_dance.sh')])
elif num_passed > 200:
- api.step('not defeated', [api.path['start_dir'].join('woohoo.sh')])
+ api.step('not defeated', [api.path.start_dir.join('woohoo.sh')])
else:
- api.step('deads!', [api.path['start_dir'].join('you_r_deads.sh')])
+ api.step('deads!', [api.path.start_dir.join('you_r_deads.sh')])
def GenTests(api):
yield api.test(
diff --git a/misc/fake_bbagent.sh b/misc/fake_bbagent.sh
index 9ac56b7..e1c5c3d 100755
--- a/misc/fake_bbagent.sh
+++ b/misc/fake_bbagent.sh
@@ -14,9 +14,9 @@
#
# This puts all the outputs from the executed recipe in the current git repo's
# //workdir directory:
-# * //workdir/tmp - api.path['tmp_base']
-# * //workdir/cache - api.path['cache']
-# * //workdir/wd - api.path['start_dir']
+# * //workdir/tmp - api.path.tmp_base_dir
+# * //workdir/cache - api.path.cache_dir
+# * //workdir/wd - api.path.start_dir
# * //workdir/logs - Dumps of all the logdog streams emitted by the recipe
# engine (and any child processes).
#
diff --git a/recipe_modules/archive/api.py b/recipe_modules/archive/api.py
index cff331a..0a801d6 100644
--- a/recipe_modules/archive/api.py
+++ b/recipe_modules/archive/api.py
@@ -27,7 +27,7 @@
# Archive root/**
zip_path = (
api.archive.package(root).
- archive('archive step', api.path['start_dir'].join('output.zip'))
+ archive('archive step', api.path.start_dir.join('output.zip'))
)
Args:
diff --git a/recipe_modules/archive/examples/full.py b/recipe_modules/archive/examples/full.py
index 22454d0..c9d4e51 100644
--- a/recipe_modules/archive/examples/full.py
+++ b/recipe_modules/archive/examples/full.py
@@ -18,7 +18,7 @@
def RunSteps(api):
# Prepare directories.
- out = api.path['start_dir'].join('output')
+ out = api.path.start_dir.join('output')
api.file.rmtree('cleanup', out)
api.file.ensure_directory('mkdirs out', out)
diff --git a/recipe_modules/bcid_reporter/api.py b/recipe_modules/bcid_reporter/api.py
index 46d9f90..1a51c71 100644
--- a/recipe_modules/bcid_reporter/api.py
+++ b/recipe_modules/bcid_reporter/api.py
@@ -31,7 +31,7 @@
broker will be installed using cipd.
"""
if self._broker_bin is None:
- reporter_dir = self.m.path['start_dir'].join('reporter')
+ reporter_dir = self.m.path.start_dir.join('reporter')
ensure_file = self.m.cipd.EnsureFile().add_package(
'infra/tools/security/provenance_broker/${platform}',
_LATEST_STABLE_VERSION)
diff --git a/recipe_modules/buildbucket/api.py b/recipe_modules/buildbucket/api.py
index e9f4af8..2214cc4 100644
--- a/recipe_modules/buildbucket/api.py
+++ b/recipe_modules/buildbucket/api.py
@@ -283,7 +283,7 @@
See "Builder cache" in
https://chromium.googlesource.com/infra/luci/luci-go/+/main/buildbucket/proto/project_config.proto
"""
- return self.m.path['cache'].join('builder')
+ return self.m.path.cache_dir.join('builder')
# RPCs.
diff --git a/recipe_modules/cas_input/api.py b/recipe_modules/cas_input/api.py
index 0efd691..d42356a 100644
--- a/recipe_modules/cas_input/api.py
+++ b/recipe_modules/cas_input/api.py
@@ -34,7 +34,7 @@
Args:
output_dir: The output directory to download the caches to. If you're
- unsure of what directory to use, self.m.path['start_dir'] is a directory
+ unsure of what directory to use, self.m.path.start_dir is a directory
the recipe engine sets up for you that you can use.
caches: A CasCache proto message containing the caches which should be
downloaded. See properties.proto for the message definition.
diff --git a/recipe_modules/cas_input/examples/full.py b/recipe_modules/cas_input/examples/full.py
index 657e0ee..a1ce3d3 100644
--- a/recipe_modules/cas_input/examples/full.py
+++ b/recipe_modules/cas_input/examples/full.py
@@ -14,7 +14,10 @@
def RunSteps(api):
- download_dir = api.path[api.properties.get('download_dir', 'start_dir')]
+ if dd := api.properties.get('download_dir'):
+ download_dir = api.path.abs_to_path(dd)
+ else:
+ download_dir = api.path.start_dir
api.cas_input.download_caches(download_dir)
@@ -35,7 +38,7 @@
'download_to_directory',
cas_props(
InputProperties(caches=[CasCache(digest='deadbeef')]),
- download_dir='tmp_base'),
+ download_dir='[TMP_BASE]'),
api.post_process(StepSuccess, 'download cache'),
api.post_process(StepCommandContains, 'download cache', '[TMP_BASE]'),
api.post_process(DropExpectation))
diff --git a/recipe_modules/cipd/api.py b/recipe_modules/cipd/api.py
index d594c07..2371b00 100644
--- a/recipe_modules/cipd/api.py
+++ b/recipe_modules/cipd/api.py
@@ -1017,7 +1017,7 @@
cache_key = (package, version)
package_parts = [p for p in package.split('/') if '${' not in p]
- package_dir = self.m.path['start_dir'].join('cipd_tool', *package_parts)
+ package_dir = self.m.path.start_dir.join('cipd_tool', *package_parts)
# Hashing the version is the easiest way to produce a string with no special
# characters e.g. removing colons which don't work on Windows.
package_dir = package_dir.join(
diff --git a/recipe_modules/cipd/examples/full.py b/recipe_modules/cipd/examples/full.py
index 1942fae..7c24c8a 100644
--- a/recipe_modules/cipd/examples/full.py
+++ b/recipe_modules/cipd/examples/full.py
@@ -46,7 +46,7 @@
for i, v in enumerate(metadata)
]
- cipd_root = api.path['start_dir'].join('packages')
+ cipd_root = api.path.start_dir.join('packages')
# Some packages don't require credentials to be installed or queried.
api.cipd.ensure(cipd_root, ensure_file)
api.cipd.ensure_file_resolve(ensure_file)
@@ -95,7 +95,7 @@
# Create (build & register).
if use_pkg:
- root = api.path['start_dir'].join('some_subdir')
+ root = api.path.start_dir.join('some_subdir')
pkg = api.cipd.PackageDefinition(
'infra/fake-package',
root,
@@ -118,13 +118,13 @@
api.cipd.create_from_pkg(pkg, refs=refs, tags=tags, metadata=md)
else:
- api.cipd.build_from_yaml(api.path['start_dir'].join('fake-package.yaml'),
+ api.cipd.build_from_yaml(api.path.start_dir.join('fake-package.yaml'),
'fake-package-path', pkg_vars=pkg_vars,
compression_level=9)
api.cipd.register('infra/fake-package', 'fake-package-path',
refs=refs, tags=tags, metadata=md)
- api.cipd.create_from_yaml(api.path['start_dir'].join('fake-package.yaml'),
+ api.cipd.create_from_yaml(api.path.start_dir.join('fake-package.yaml'),
refs=refs, tags=tags, metadata=md,
pkg_vars=pkg_vars, compression_level=9,
verification_timeout='20m')
@@ -145,30 +145,30 @@
api.cipd.Metadata(key='key1', value='val2', content_type='text/plain'),
api.cipd.Metadata(
key='key2',
- value_from_file=api.path['start_dir'].join('val1.json'),
+ value_from_file=api.path.start_dir.join('val1.json'),
),
api.cipd.Metadata(
key='key2',
- value_from_file=api.path['start_dir'].join('val2.json'),
+ value_from_file=api.path.start_dir.join('val2.json'),
content_type='application/json',
),
])
# Fetch a raw package
- api.cipd.pkg_fetch(api.path['start_dir'].join('fetched_pkg'),
+ api.cipd.pkg_fetch(api.path.start_dir.join('fetched_pkg'),
'fake-package/${platform}', 'some:tag')
# Deploy a raw package
api.cipd.pkg_deploy(
- api.path['start_dir'].join('raw_root'),
- api.path['start_dir'].join('fetched_pkg'))
+ api.path.start_dir.join('raw_root'),
+ api.path.start_dir.join('fetched_pkg'))
api.cipd.ensure(
cipd_root,
- api.path['start_dir'].join('cipd.ensure'),
+ api.path.start_dir.join('cipd.ensure'),
name='ensure with existing file')
api.cipd.ensure_file_resolve(
- api.path['start_dir'].join('cipd.ensure'),
+ api.path.start_dir.join('cipd.ensure'),
name='ensure-file-resolve with existing file')
# Install a tool using the high-level helper function. This operation should
diff --git a/recipe_modules/context/api.py b/recipe_modules/context/api.py
index 694c3ac..d0a1007 100644
--- a/recipe_modules/context/api.py
+++ b/recipe_modules/context/api.py
@@ -20,7 +20,7 @@
Example:
```python
-with api.context(cwd=api.path['start_dir'].join('subdir')):
+with api.context(cwd=api.path.start_dir.join('subdir')):
# this step is run inside of the subdir directory.
api.step("cat subdir/foo", ['cat', './foo'])
```
@@ -114,7 +114,7 @@
Args:
* cwd (Path) - the current working directory to use for all steps.
To 'reset' to the original cwd at the time recipes started, pass
- `api.path['start_dir']`.
+ `api.path.start_dir`.
* env_prefixes (dict) - Environmental variable prefix augmentations. See
below for more info.
* env_suffixes (dict) - Environmental variable suffix augmentations. See
@@ -254,7 +254,7 @@
"""Returns the current working directory that steps will run in.
**Returns (Path|None)** - The current working directory. A value of None is
- equivalent to api.path['start_dir'], though only occurs if no cwd has been
+ equivalent to api.path.start_dir, though only occurs if no cwd has been
set (e.g. in the outermost context of RunSteps).
"""
return self._state.cwd
diff --git a/recipe_modules/context/examples/full.py b/recipe_modules/context/examples/full.py
index 9f16869..315a6be 100644
--- a/recipe_modules/context/examples/full.py
+++ b/recipe_modules/context/examples/full.py
@@ -26,13 +26,13 @@
# can change cwd
api.step('mk subdir', ['mkdir', '-p', 'subdir'])
- with api.context(cwd=api.path['start_dir'].join('subdir')):
+ with api.context(cwd=api.path.start_dir.join('subdir')):
api.step('subdir step', ['bash', '-c', 'pwd'])
api.step('other subdir step', ['bash', '-c', 'echo hi again!'])
# can set envvars, and path prefix.
- pants = api.path['start_dir'].join('pants')
- shirt = api.path['start_dir'].join('shirt')
+ pants = api.path.start_dir.join('pants')
+ shirt = api.path.start_dir.join('shirt')
with api.context(env={'FOO': 'bar'}):
api.step('env step', ['bash', '-c', 'echo $FOO'])
diff --git a/recipe_modules/context/tests/cwd.py b/recipe_modules/context/tests/cwd.py
index 2e408d9..91f2a4a 100644
--- a/recipe_modules/context/tests/cwd.py
+++ b/recipe_modules/context/tests/cwd.py
@@ -11,7 +11,7 @@
def RunSteps(api):
api.step('no cwd', ['echo', 'hello'])
- with api.context(cwd=api.path['start_dir'].join('subdir')):
+ with api.context(cwd=api.path.start_dir.join('subdir')):
api.step('with cwd', ['echo', 'hello', 'subdir'])
with api.context(cwd=None):
diff --git a/recipe_modules/context/tests/env.py b/recipe_modules/context/tests/env.py
index 136a83b..dcca227 100644
--- a/recipe_modules/context/tests/env.py
+++ b/recipe_modules/context/tests/env.py
@@ -45,10 +45,10 @@
with api.context(env={_KEY: None}):
expect_step('drop', '')
- pants = api.path['start_dir'].join('pants')
- shirt = api.path['start_dir'].join('shirt')
- good_hat = api.path['start_dir'].join('good_hat')
- bad_hat = api.path['start_dir'].join('bad_hat')
+ pants = api.path.start_dir.join('pants')
+ shirt = api.path.start_dir.join('shirt')
+ good_hat = api.path.start_dir.join('good_hat')
+ bad_hat = api.path.start_dir.join('bad_hat')
with api.context(env={_KEY: 'bar'}):
expect_step('env step', 'bar')
diff --git a/recipe_modules/file/examples/compute_hash.py b/recipe_modules/file/examples/compute_hash.py
index e0e1fc5..9a7faa7 100644
--- a/recipe_modules/file/examples/compute_hash.py
+++ b/recipe_modules/file/examples/compute_hash.py
@@ -9,8 +9,8 @@
]
def RunSteps(api):
- base_path = api.path['start_dir']
- some_dir = api.path['start_dir'].join('some_dir')
+ base_path = api.path.start_dir
+ some_dir = api.path.start_dir.join('some_dir')
api.file.ensure_directory('ensure some_dir', some_dir)
some_file = some_dir.join('some file')
@@ -26,7 +26,7 @@
expected = 'deadbeef'
api.assertions.assertEqual(result, expected)
- some_other_dir = api.path['start_dir'].join('some_other_dir')
+ some_other_dir = api.path.start_dir.join('some_other_dir')
api.file.ensure_directory('ensure some_other_dir', some_other_dir)
some_other_file = some_other_dir.join('new_f')
@@ -39,7 +39,7 @@
expected = 'abcdefab'
api.assertions.assertEqual(result, expected)
- another_file = api.path['start_dir'].join('another_file')
+ another_file = api.path.start_dir.join('another_file')
api.file.write_text('write another file', another_file, 'some data')
result = api.file.compute_hash('compute_hash of list of dirs and file',
diff --git a/recipe_modules/file/examples/copy.py b/recipe_modules/file/examples/copy.py
index df0ee62..f76fcbc 100644
--- a/recipe_modules/file/examples/copy.py
+++ b/recipe_modules/file/examples/copy.py
@@ -10,21 +10,21 @@
def RunSteps(api):
- dest = api.path['start_dir'].join('some file')
+ dest = api.path.start_dir.join('some file')
data = 'Here is some text data'
api.file.write_text('write a file', dest, data)
- api.file.copy('copy it', dest, api.path['start_dir'].join('new path'))
+ api.file.copy('copy it', dest, api.path.start_dir.join('new path'))
read_data = api.file.read_text(
- 'read it', api.path['start_dir'].join('new path'), test_data=data)
+ 'read it', api.path.start_dir.join('new path'), test_data=data)
assert read_data == data, (read_data, data)
- api.file.move('move it', api.path['start_dir'].join('new path'),
- api.path['start_dir'].join('new new path'))
+ api.file.move('move it', api.path.start_dir.join('new path'),
+ api.path.start_dir.join('new new path'))
read_data = api.file.read_text(
- 'read it', api.path['start_dir'].join('new new path'), test_data=data)
+ 'read it', api.path.start_dir.join('new new path'), test_data=data)
assert read_data == data, (read_data, data)
diff --git a/recipe_modules/file/examples/copytree.py b/recipe_modules/file/examples/copytree.py
index 8834444..d80b945 100644
--- a/recipe_modules/file/examples/copytree.py
+++ b/recipe_modules/file/examples/copytree.py
@@ -11,13 +11,13 @@
def RunSteps(api):
file_names = ['a', 'aa', 'b', 'bb', 'c', 'cc']
- dest = api.path['start_dir'].join('some dir')
+ dest = api.path.start_dir.join('some dir')
api.file.ensure_directory('ensure "some dir"', dest)
for fname in file_names:
api.file.write_text('write %s' % fname, dest.join(fname), fname)
api.file.filesizes('check filesizes', [dest.join(f) for f in file_names])
- dest2 = api.path['start_dir'].join('some other dir')
+ dest2 = api.path.start_dir.join('some other dir')
api.file.rmtree('make sure dest is gone', dest2)
api.file.copytree('copy it', dest, dest2)
diff --git a/recipe_modules/file/examples/error.py b/recipe_modules/file/examples/error.py
index e625fe7..2a41c90 100644
--- a/recipe_modules/file/examples/error.py
+++ b/recipe_modules/file/examples/error.py
@@ -11,7 +11,7 @@
def RunSteps(api):
try:
api.file.read_text(
- 'does not exist', api.path['start_dir'].join('not_there'))
+ 'does not exist', api.path.start_dir.join('not_there'))
assert False, "never reached" # pragma: no cover
except api.file.Error as e:
assert e.errno_name == 'ENOENT'
diff --git a/recipe_modules/file/examples/file_hash.py b/recipe_modules/file/examples/file_hash.py
index d06aa11..5a19d01 100644
--- a/recipe_modules/file/examples/file_hash.py
+++ b/recipe_modules/file/examples/file_hash.py
@@ -9,7 +9,7 @@
]
def RunSteps(api):
- some_dir = api.path['start_dir'].join('some_dir')
+ some_dir = api.path.start_dir.join('some_dir')
api.file.ensure_directory('ensure some_dir', some_dir)
some_file = some_dir.join('some file')
@@ -21,7 +21,7 @@
expected = 'deadbeef'
api.assertions.assertEqual(result, expected)
- another_file = api.path['start_dir'].join('another_file')
+ another_file = api.path.start_dir.join('another_file')
api.file.write_text('write another file', another_file, 'some data')
result = api.file.file_hash(another_file,
diff --git a/recipe_modules/file/examples/flatten_single_directories.py b/recipe_modules/file/examples/flatten_single_directories.py
index 733562a..46a1d24 100644
--- a/recipe_modules/file/examples/flatten_single_directories.py
+++ b/recipe_modules/file/examples/flatten_single_directories.py
@@ -9,7 +9,7 @@
def RunSteps(api):
- base = api.path['start_dir'].join('dir')
+ base = api.path.start_dir.join('dir')
long_dir = base.join('which_has', 'some', 'singular', 'subdirs')
api.file.ensure_directory('make chain of single dirs', long_dir)
diff --git a/recipe_modules/file/examples/glob.py b/recipe_modules/file/examples/glob.py
index 8bc5c2b..9a7f94c 100644
--- a/recipe_modules/file/examples/glob.py
+++ b/recipe_modules/file/examples/glob.py
@@ -9,7 +9,7 @@
]
def RunSteps(api):
- sd = api.path['start_dir']
+ sd = api.path.start_dir
api.file.ensure_directory('mkdir a', sd.join('a'))
api.file.ensure_directory('mkdir b', sd.join('b'))
diff --git a/recipe_modules/file/examples/handle_json_file.py b/recipe_modules/file/examples/handle_json_file.py
index b1d0c56..fa5c44c 100644
--- a/recipe_modules/file/examples/handle_json_file.py
+++ b/recipe_modules/file/examples/handle_json_file.py
@@ -9,7 +9,7 @@
def RunSteps(api):
- dest = api.path['start_dir'].join('some_file.json')
+ dest = api.path.start_dir.join('some_file.json')
# Test a non-trivial number of keys in a dict. This tests that the keys
# are sorted in the output.
data = {str('key%d' % i): True for i in range(10)}
diff --git a/recipe_modules/file/examples/listdir.py b/recipe_modules/file/examples/listdir.py
index dfc66b8..4610ad2 100644
--- a/recipe_modules/file/examples/listdir.py
+++ b/recipe_modules/file/examples/listdir.py
@@ -9,7 +9,7 @@
def RunSteps(api):
- root_dir = api.path['start_dir'].join('root_dir')
+ root_dir = api.path.start_dir.join('root_dir')
api.file.ensure_directory('ensure root_dir', root_dir)
listdir_result = api.file.listdir('listdir root_dir', root_dir, test_data=[])
diff --git a/recipe_modules/file/examples/raw_copy.py b/recipe_modules/file/examples/raw_copy.py
index f9eb69d..2596c5e 100644
--- a/recipe_modules/file/examples/raw_copy.py
+++ b/recipe_modules/file/examples/raw_copy.py
@@ -10,21 +10,21 @@
def RunSteps(api):
- dest = api.path['start_dir'].join('some file')
+ dest = api.path.start_dir.join('some file')
data = b'\xef\xbb\xbft'
api.file.write_raw('write a file', dest, data)
- api.file.copy('copy it', dest, api.path['start_dir'].join('new path'))
+ api.file.copy('copy it', dest, api.path.start_dir.join('new path'))
read_data = api.file.read_raw(
- 'read it', api.path['start_dir'].join('new path'), test_data=data)
+ 'read it', api.path.start_dir.join('new path'), test_data=data)
assert read_data == data, (read_data, data)
- api.file.move('move it', api.path['start_dir'].join('new path'),
- api.path['start_dir'].join('new new path'))
+ api.file.move('move it', api.path.start_dir.join('new path'),
+ api.path.start_dir.join('new new path'))
read_data = api.file.read_raw(
- 'read it', api.path['start_dir'].join('new new path'), test_data=data)
+ 'read it', api.path.start_dir.join('new new path'), test_data=data)
assert read_data == data, (read_data, data)
diff --git a/recipe_modules/file/examples/read_write_proto.py b/recipe_modules/file/examples/read_write_proto.py
index 44c89da..c8b707b 100644
--- a/recipe_modules/file/examples/read_write_proto.py
+++ b/recipe_modules/file/examples/read_write_proto.py
@@ -14,7 +14,7 @@
def RunSteps(api):
msg = SomeMessage(fields=['abc', 'def'])
- dest = api.path['start_dir'].join('message.textproto')
+ dest = api.path.start_dir.join('message.textproto')
api.file.write_proto('write_proto', dest, msg, 'TEXTPB')
read_msg = api.file.read_proto(
diff --git a/recipe_modules/file/examples/symlink.py b/recipe_modules/file/examples/symlink.py
index 13dda8b..e87b239 100644
--- a/recipe_modules/file/examples/symlink.py
+++ b/recipe_modules/file/examples/symlink.py
@@ -10,25 +10,25 @@
def RunSteps(api):
- src = api.path['start_dir'].join('some file')
+ src = api.path.start_dir.join('some file')
data = 'Here is some text data'
api.file.write_text('write a file', src, data)
- api.file.symlink('symlink it', src, api.path['start_dir'].join('new path'))
+ api.file.symlink('symlink it', src, api.path.start_dir.join('new path'))
read_data = api.file.read_text(
- 'read it', api.path['start_dir'].join('new path'), test_data=data)
+ 'read it', api.path.start_dir.join('new path'), test_data=data)
assert read_data == data, (read_data, data)
# Also create a tree of symlinks.
- root = api.path['cleanup'].join('root')
+ root = api.path.cleanup_dir.join('root')
tree = api.file.symlink_tree(root)
assert root == tree.root
# It is okay to register the same pair multiple times.
tree.register_link(src, root.join('another', 'symlink'))
tree.register_link(src, root.join('another', 'symlink'))
- src2 = api.path['start_dir'].join('a-second-file')
+ src2 = api.path.start_dir.join('a-second-file')
tree.register_link(src2, root.join('yet', 'another', 'symlink'))
tree.create_links('create a tree of symlinks')
diff --git a/recipe_modules/file/examples/truncate.py b/recipe_modules/file/examples/truncate.py
index 4193995..14c573d 100644
--- a/recipe_modules/file/examples/truncate.py
+++ b/recipe_modules/file/examples/truncate.py
@@ -9,7 +9,7 @@
def RunSteps(api):
- filepath = api.path['start_dir'].join('some_file')
+ filepath = api.path.start_dir.join('some_file')
size_mb = 300
MBtoB = lambda x: x * 1024 * 1024
diff --git a/recipe_modules/futures/examples/background_helper.py b/recipe_modules/futures/examples/background_helper.py
index 713269c..5446970 100644
--- a/recipe_modules/futures/examples/background_helper.py
+++ b/recipe_modules/futures/examples/background_helper.py
@@ -18,7 +18,7 @@
def manage_helper(api, chn):
with api.step.nest('helper'):
- pid_file = api.path['cleanup'].join('pid_file')
+ pid_file = api.path.cleanup_dir.join('pid_file')
helper_future = api.futures.spawn_immediate(
api.step, 'helper loop',
['python3', api.resource('helper.py'), pid_file],
diff --git a/recipe_modules/futures/examples/extreme_namespaces.py b/recipe_modules/futures/examples/extreme_namespaces.py
index 2e86dc9..d91f724 100644
--- a/recipe_modules/futures/examples/extreme_namespaces.py
+++ b/recipe_modules/futures/examples/extreme_namespaces.py
@@ -13,7 +13,7 @@
def Level2(api, i):
work = []
with api.step.nest('Level2 [%d]' % i):
- with api.context(cwd=api.path['start_dir'].join('deep')):
+ with api.context(cwd=api.path.start_dir.join('deep')):
work.append(api.futures.spawn(
api.step, 'cool step', cmd=['echo', 'cool']))
diff --git a/recipe_modules/generator_script/api.py b/recipe_modules/generator_script/api.py
index 6ba67c7..ca68ccd 100644
--- a/recipe_modules/generator_script/api.py
+++ b/recipe_modules/generator_script/api.py
@@ -68,7 +68,7 @@
raise cls.MalformedCmd(generator_step_result.name)
- def __call__(self, path_to_script, *args, **_):
+ def __call__(self, path_to_script, *args, checkout_dir=None, **_):
"""Run a script and generate the steps emitted by that script.
The script will be invoked with --output-json /path/to/file.json. The script
@@ -109,7 +109,7 @@
f = '--output-json'
step_name = 'gen step(%s)' % self.m.path.basename(path_to_script)
- with self.m.context(cwd=self.m.path['checkout']):
+ with self.m.context(cwd=checkout_dir or self.m.path.checkout_dir):
if str(path_to_script).endswith('.py'):
step_result = self.m.step(
step_name,
diff --git a/recipe_modules/generator_script/examples/full.py b/recipe_modules/generator_script/examples/full.py
index be5f19a..c9f6a92 100644
--- a/recipe_modules/generator_script/examples/full.py
+++ b/recipe_modules/generator_script/examples/full.py
@@ -18,9 +18,9 @@
}
def RunSteps(api, script_name):
- api.path['checkout'] = api.path['tmp_base']
- script_name = api.properties['script_name']
- api.generator_script(script_name)
+ api.generator_script(
+ path_to_script=api.properties['script_name'],
+ checkout_dir=api.path.tmp_base_dir)
def GenTests(api):
yield api.test(
diff --git a/recipe_modules/golang/api.py b/recipe_modules/golang/api.py
index 3ea7ec4..31e3bb4 100644
--- a/recipe_modules/golang/api.py
+++ b/recipe_modules/golang/api.py
@@ -42,8 +42,8 @@
* path (Path) - a path to install Go into.
* cache (Path) - a path to put Go caches under.
"""
- path = path or self.m.path['cache'].join('golang')
- cache = cache or self.m.path['cache'].join('gocache')
+ path = path or self.m.path.cache_dir.join('golang')
+ cache = cache or self.m.path.cache_dir.join('gocache')
with self.m.context(infra_steps=True):
env, env_pfx, env_sfx = self._ensure_installed(version, path, cache)
with self.m.context(env=env, env_prefixes=env_pfx, env_suffixes=env_sfx):
diff --git a/recipe_modules/json/examples/full.py b/recipe_modules/json/examples/full.py
index 5d0bf8e..a18fc97 100644
--- a/recipe_modules/json/examples/full.py
+++ b/recipe_modules/json/examples/full.py
@@ -69,7 +69,7 @@
assert step_result.stdout == example_dict
# json.read reads a file containing JSON data.
- leak_path = api.path['tmp_base'].join('temp.json')
+ leak_path = api.path.tmp_base_dir.join('temp.json')
api.step('write json to file',
['cat', api.json.input(example_dict)],
stdout=api.raw_io.output(leak_to=leak_path))
@@ -83,7 +83,7 @@
'python3',
api.resource('cool_script.py'),
'{"x":1,"y":2}',
- api.json.output(leak_to=api.path['tmp_base'].join('leak.json')),
+ api.json.output(leak_to=api.path.tmp_base_dir.join('leak.json')),
])
assert step_result.json.output == example_dict
@@ -116,7 +116,7 @@
assert step_result.json.output is None
# Check that certain non-stdlib types are JSON serializable.
- assert api.json.dumps(api.path['start_dir']) == '"%s"' % api.path['start_dir']
+ assert api.json.dumps(api.path.start_dir) == '"%s"' % api.path.start_dir
assert api.json.dumps(engine_types.FrozenDict(foo='bar')) == '{"foo": "bar"}'
foobar_struct = struct_pb2.Struct(
fields={'foo': struct_pb2.Value(string_value='bar')})
diff --git a/recipe_modules/led/api.py b/recipe_modules/led/api.py
index 3bc73b8..ea66a43 100644
--- a/recipe_modules/led/api.py
+++ b/recipe_modules/led/api.py
@@ -439,7 +439,7 @@
# trace a bit more obvious.
build = self.test_api._transform_build(
previous, cmd, self._mock_edits,
- str(self.m.context.cwd or self.m.path['start_dir']))
+ str(self.m.context.cwd or self.m.path.start_dir))
kwargs['step_test_data'] = (
lambda: self.test_api.m.proto.output_stream(build))
diff --git a/recipe_modules/nodejs/api.py b/recipe_modules/nodejs/api.py
index c8e02d2..9888c6a 100644
--- a/recipe_modules/nodejs/api.py
+++ b/recipe_modules/nodejs/api.py
@@ -40,8 +40,8 @@
* path (Path) - a path to install Node.js into.
* cache (Path) - a path to put Node.js caches under.
"""
- path = path or self.m.path['cache'].join('nodejs')
- cache = cache or self.m.path['cache'].join('npmcache')
+ path = path or self.m.path.cache_dir.join('nodejs')
+ cache = cache or self.m.path.cache_dir.join('npmcache')
with self.m.context(infra_steps=True):
env, env_pfx = self._ensure_installed(version, path, cache)
with self.m.context(env=env, env_prefixes=env_pfx):
diff --git a/recipe_modules/path/api.py b/recipe_modules/path/api.py
index e8a20b1..a1943fc 100644
--- a/recipe_modules/path/api.py
+++ b/recipe_modules/path/api.py
@@ -11,19 +11,19 @@
In this way, all paths in Recipes are absolute, and are constructed from a small
collection of anchor points. The built-in anchor points are:
- * `api.path['start_dir']` - This is the directory that the recipe started in.
+ * `api.path.start_dir` - This is the directory that the recipe started in.
it's similar to `cwd`, except that it's constant.
- * `api.path['cache']` - This directory is provided by whatever's running the
+ * `api.path.cache_dir` - This directory is provided by whatever's running the
recipe. Files and directories created under here /may/ be evicted in between
runs of the recipe (i.e. to relieve disk pressure).
- * `api.path['cleanup']` - This directory is provided by whatever's running the
+ * `api.path.cleanup_dir` - This directory is provided by whatever's running the
recipe. Files and directories created under here /are guaranteed/ to be
evicted in between runs of the recipe. Additionally, this directory is
guaranteed to be empty when the recipe starts.
- * `api.path['tmp_base']` - This directory is the system-configured temp dir.
+ * `api.path.tmp_base_dir` - This directory is the system-configured temp dir.
This is a weaker form of 'cleanup', and its use should be avoided. This may
be removed in the future (or converted to an alias of 'cleanup').
- * `api.path['checkout']` - This directory is set by various checkout modules
+ * `api.path.checkout_dir` - This directory is set by various checkout modules
in recipes. It was originally intended to make recipes easier to read and
make code somewhat generic or homogeneous, but this was a mistake. New code
should avoid 'checkout', and instead just explicitly pass paths around. This
@@ -486,11 +486,12 @@
new_path = tempfile.mkdtemp(prefix=prefix, dir=cleanup_dir)
assert new_path.startswith(cleanup_dir), (
f'{new_path=!r} -- {cleanup_dir=!r}')
- temp_dir = self['cleanup'].join(new_path[len(cleanup_dir):])
+ temp_dir = self.cleanup_dir.join(new_path[len(cleanup_dir):])
else:
self._test_counter[prefix] += 1
- temp_dir = self['cleanup'].join(
+ temp_dir = self.cleanup_dir.join(
f'{prefix}_tmp_{self._test_counter[prefix]}')
+
self.mock_add_paths(temp_dir, FileType.DIRECTORY)
return temp_dir
@@ -513,11 +514,11 @@
fd, new_path = tempfile.mkstemp(prefix=prefix, dir=cleanup_dir)
assert new_path.startswith(cleanup_dir), (
f'{new_path=!r} -- {cleanup_dir=!r}')
- temp_file = self['cleanup'].join(new_path[len(cleanup_dir):])
+ temp_file = self.cleanup_dir.join(new_path[len(cleanup_dir):])
os.close(fd)
else:
self._test_counter[prefix] += 1
- temp_file = self['cleanup'].join(
+ temp_file = self.cleanup_dir.join(
f'{prefix}_tmp_{self._test_counter[prefix]}')
self.mock_add_paths(temp_file, FileType.FILE)
return temp_file
@@ -824,13 +825,13 @@
"""Equivalent to os.path.join.
Note that Path objects returned from this module (e.g.
- api.path['start_dir']) have a built-in join method (e.g.
+ api.path.start_dir) have a built-in join method (e.g.
new_path = p.join('some', 'name')). Many recipe modules expect Path objects
rather than strings. Using this `join` method gives you raw path joining
functionality and returns a string.
If your path is rooted in one of the path module's root paths (i.e. those
- retrieved with api.path[something]), then you can convert from a string path
+ retrieved with api.path.something), then you can convert from a string path
back to a Path with the `abs_to_path` method.
"""
return self._path_mod.join(str(path), *[str(p) for p in paths])
@@ -897,12 +898,12 @@
return self._path_mod.normpath(str(path))
def expanduser(self, path): # pragma: no cover
- """Do not use this, use `api.path['home']` instead.
+ """Do not use this, use `api.path.home_dir` instead.
- This ONLY handles `path` == "~", and returns `str(api.path['home'])`.
+ This ONLY handles `path` == "~", and returns `str(api.path.home_dir)`.
"""
if path == "~":
- return str(self['home'])
+ return str(self.home_dir)
raise ValueError("expanduser only supports `~`.")
def exists(self, path):
diff --git a/recipe_modules/path/examples/full.py b/recipe_modules/path/examples/full.py
index 9851278..c3d5179 100644
--- a/recipe_modules/path/examples/full.py
+++ b/recipe_modules/path/examples/full.py
@@ -2,6 +2,8 @@
# Use of this source code is governed under the Apache License, Version 2.0
# that can be found in the LICENSE file.
+from recipe_engine import recipe_api
+
DEPS = [
'json',
'path',
@@ -13,8 +15,9 @@
from builtins import range, zip
+@recipe_api.ignore_warnings('recipe_engine/CHECKOUT_DIR_DEPRECATED')
def RunSteps(api):
- api.step('step1', ['/bin/echo', str(api.path['tmp_base'].join('foo'))])
+ api.step('step1', ['/bin/echo', str(api.path.tmp_base_dir.join('foo'))])
# module.resource(...) demo.
api.step('print resource',
@@ -25,10 +28,10 @@
['echo', api.path.repo_resource('dir', 'file.py')])
assert 'start_dir' in api.path
- assert api.path['start_dir'].join('.') == api.path['start_dir']
+ assert api.path.start_dir.join('.') == api.path.start_dir
assert 'checkout' not in api.path
- api.path['checkout'] = api.path['tmp_base'].join('checkout')
+ api.path.checkout_dir = api.path.tmp_base_dir.join('checkout')
assert 'checkout' in api.path
# Test missing/default value.
@@ -39,18 +42,13 @@
except ValueError as ex:
assert 'unknown base path' in str(ex), str(ex)
- try:
- raise Exception('Should never raise: %s' % (api.path['nonexistent'],))
- except ValueError:
- pass
-
# Global dynamic paths (see config.py example for declaration):
- dynamic_path = api.path['checkout'].join('jerky')
+ dynamic_path = api.path.checkout_dir.join('jerky')
api.step('checkout path', ['/bin/echo', dynamic_path])
# Methods from python os.path are available via api.path. For testing, we
# asserted that this file existed in the test description below.
- assert api.path.exists(api.path['tmp_base'])
+ assert api.path.exists(api.path.tmp_base_dir)
temp_dir = api.path.mkdtemp('kawaab')
assert api.path.exists(temp_dir)
@@ -58,7 +56,7 @@
temp_file = api.path.mkstemp('kawaac')
assert api.path.exists(temp_file)
- file_path = api.path['tmp_base'].join('new_file')
+ file_path = api.path.tmp_base_dir.join('new_file')
abspath = api.path.abspath(file_path)
api.path.assert_absolute(abspath)
try:
@@ -76,16 +74,16 @@
assert api.path.pathsep == ':'
assert api.path.basename(file_path) == 'new_file'
- assert api.path.dirname(file_path) == api.path['tmp_base']
- assert api.path.split(file_path) == (api.path['tmp_base'], 'new_file')
+ assert api.path.dirname(file_path) == api.path.tmp_base_dir
+ assert api.path.split(file_path) == (api.path.tmp_base_dir, 'new_file')
- thing_bat = api.path['tmp_base'].join('thing.bat')
- thing_bat_mkv = api.path['tmp_base'].join('thing.bat.mkv')
+ thing_bat = api.path.tmp_base_dir.join('thing.bat')
+ thing_bat_mkv = api.path.tmp_base_dir.join('thing.bat.mkv')
assert api.path.splitext(thing_bat_mkv) == (thing_bat, '.mkv')
- assert api.path.abs_to_path(api.path['tmp_base']) == api.path['tmp_base']
+ assert api.path.abs_to_path(api.path.tmp_base_dir) == api.path.tmp_base_dir
- assert api.path.relpath(file_path, api.path['tmp_base']) == 'new_file'
+ assert api.path.relpath(file_path, api.path.tmp_base_dir) == 'new_file'
assert api.path.splitext('abc.xyz') == ('abc', '.xyz')
assert api.path.split('abc/xyz') == ('abc', 'xyz')
@@ -107,7 +105,7 @@
normpath = api.path.normpath(file_path)
assert api.path.exists(normpath)
- directory = api.path['start_dir'].join('directory')
+ directory = api.path.start_dir.join('directory')
filepath = directory.join('filepath')
api.step('rm directory (initial)', ['rm', '-rf', directory])
assert not api.path.exists(directory)
@@ -139,10 +137,10 @@
assert not api.path.isfile(directory)
# We can mock copy paths. See the file module to do this for real.
- copy1 = api.path['start_dir'].join('copy1')
- copy10 = api.path['start_dir'].join('copy10')
- copy2 = api.path['start_dir'].join('copy2')
- copy20 = api.path['start_dir'].join('copy20')
+ copy1 = api.path.start_dir.join('copy1')
+ copy10 = api.path.start_dir.join('copy10')
+ copy2 = api.path.start_dir.join('copy2')
+ copy20 = api.path.start_dir.join('copy20')
api.step('rm copy2 (initial)', ['rm', '-rf', copy2])
api.step('rm copy20 (initial)', ['rm', '-rf', copy20])
@@ -172,10 +170,10 @@
# Convert strings to Paths.
def _mk_paths():
return [
- api.path['start_dir'].join('some', 'thing'),
- api.path['start_dir'],
- api.path['cache'] / 'a file',
- api.path['home'] / 'another file',
+ api.path.start_dir.join('some', 'thing'),
+ api.path.start_dir,
+ api.path.cache_dir / 'a file',
+ api.path.home_dir / 'another file',
api.path.resource("module_resource.py"),
api.path.resource(),
api.resource("recipe_resource.py"),
@@ -214,7 +212,7 @@
except ValueError as ex:
assert "could not figure out" in str(ex), ex
- start_dir = api.path['start_dir']
+ start_dir = api.path.start_dir
a = start_dir / 'a'
b = start_dir / 'b'
assert a < b
@@ -224,13 +222,13 @@
# there is also a join method on the path module
assert start_dir.join('a') == api.path.join(start_dir, 'a')
- slashy_path = api.path['start_dir'].join(f'foo{api.path.sep}bar')
- separated_path = api.path['start_dir'].join('foo', 'bar')
+ slashy_path = api.path.start_dir.join(f'foo{api.path.sep}bar')
+ separated_path = api.path.start_dir.join('foo', 'bar')
assert str(slashy_path) == str(separated_path)
assert slashy_path == separated_path
assert api.path.eq(slashy_path, separated_path)
- slashy_file = api.path['start_dir'].join(
+ slashy_file = api.path.start_dir.join(
f'foo{api.path.sep}bar{api.path.sep}baz.txt')
assert separated_path.is_parent_of(slashy_file)
assert api.path.is_parent_of(separated_path, slashy_file)
diff --git a/recipe_modules/path/test_api.py b/recipe_modules/path/test_api.py
index 877495b..aac30ae 100644
--- a/recipe_modules/path/test_api.py
+++ b/recipe_modules/path/test_api.py
@@ -88,8 +88,8 @@
return self.checkout_dir
# Avoid circular import.
- from .api import PathApi
- if name not in PathApi.NamedBasePaths:
+ from .api import PathApi # pragma: no cover
+ if name not in PathApi.NamedBasePaths: # pragma: no cover
raise ValueError(
f'Unknown base path {name!r} - allowed names are {PathApi.NamedBasePaths!r}'
)
diff --git a/recipe_modules/path/tests/deprecated.py b/recipe_modules/path/tests/deprecated.py
new file mode 100644
index 0000000..44828ff
--- /dev/null
+++ b/recipe_modules/path/tests/deprecated.py
@@ -0,0 +1,49 @@
+# Copyright 2024 The LUCI Authors. All rights reserved.
+# Use of this source code is governed under the Apache License, Version 2.0
+# that can be found in the LICENSE file.
+
+from recipe_engine import post_process, recipe_api
+
+DEPS = [
+ 'path',
+ 'step',
+]
+
+
+@recipe_api.ignore_warnings(
+ 'recipe_engine/CHECKOUT_DIR_DEPRECATED',
+ 'recipe_engine/PATH_GETITEM_DEPRECATED',
+)
+def RunSteps(api):
+ assert api.path['cache'] == api.path.cache_dir
+ assert api.path['cleanup'] == api.path.cleanup_dir
+ assert api.path['home'] == api.path.home_dir
+ assert api.path['start_dir'] == api.path.start_dir
+ assert api.path['tmp_base'] == api.path.tmp_base_dir
+
+ api.path['checkout'] = api.path.start_dir
+ assert api.path['checkout'] == api.path.checkout_dir
+
+ api.step.empty('cache', step_text=str(api.path.cache_dir))
+ api.step.empty('cleanup', step_text=str(api.path.cleanup_dir))
+ api.step.empty('home', step_text=str(api.path.home_dir))
+ api.step.empty('start_dir', step_text=str(api.path.start_dir))
+ api.step.empty('tmp_base', step_text=str(api.path.tmp_base_dir))
+
+ api.step.empty('checkout', step_text=str(api.path.checkout_dir))
+
+
+def GenTests(api):
+ def equals(name):
+ return api.post_process(post_process.StepTextEquals, name, api.path[name])
+
+ yield api.test(
+ 'equal',
+ equals('cache'),
+ equals('cleanup'),
+ equals('home'),
+ equals('start_dir'),
+ equals('tmp_base'),
+ equals('checkout'),
+ api.post_process(post_process.DropExpectation),
+ )
diff --git a/recipe_modules/path/tests/dynamic_paths.py b/recipe_modules/path/tests/dynamic_paths.py
index 1ee69cc..701c097 100644
--- a/recipe_modules/path/tests/dynamic_paths.py
+++ b/recipe_modules/path/tests/dynamic_paths.py
@@ -23,20 +23,20 @@
assert 'cannot be rooted in checkout_dir' in str(ex), str(ex)
try:
- api.path['something'] = api.path['start_dir'].join('coolstuff')
+ api.path['something'] = api.path.start_dir.join('coolstuff')
assert False, 'able to assign path to non-dynamic path?' # pragma: no cover
except ValueError as ex:
assert 'The only valid dynamic path value is `checkout`' in str(ex), str(ex)
# OK!
- api.path['checkout'] = api.path['start_dir'].join('coolstuff')
+ api.path.checkout_dir = api.path.start_dir.join('coolstuff')
# Can re-set to the same thing
- api.path['checkout'] = api.path['start_dir'].join('coolstuff')
+ api.path.checkout_dir = api.path.start_dir.join('coolstuff')
try:
# Setting a new value is not allowed
- api.path['checkout'] = api.path['start_dir'].join('neatstuff')
+ api.path.checkout_dir = api.path.start_dir.join('neatstuff')
assert False, 'able to set a dynamic path twice?' # pragma: no cover
except ValueError as ex:
assert 'can only be set once' in str(ex), str(ex)
diff --git a/recipe_modules/path/tests/exists.py b/recipe_modules/path/tests/exists.py
index 76feb02..04d329e 100644
--- a/recipe_modules/path/tests/exists.py
+++ b/recipe_modules/path/tests/exists.py
@@ -24,7 +24,7 @@
# directory. However, the checkout directory still must be set before this
# check is done.
api.path.checkout_dir = api.path.cache_dir / 'builder' / 'src'
- assert api.path.exists(api.path['checkout'] / 'somefile')
+ assert api.path.exists(api.path.checkout_dir / 'somefile')
def GenTests(api):
diff --git a/recipe_modules/path/tests/test_api_legacy.py b/recipe_modules/path/tests/test_api_legacy.py
index 6b076cb..b72fe4f 100644
--- a/recipe_modules/path/tests/test_api_legacy.py
+++ b/recipe_modules/path/tests/test_api_legacy.py
@@ -26,16 +26,13 @@
def GenTests(api):
- paths = [api.path[name].join('file') for name in GETITEM_NAMES]
- paths.append(api.path['checkout'].join('file'))
+ def base_path(name):
+ if not name.endswith('_dir'):
+ name += '_dir'
+ return getattr(api.path, name)
- # This is for coverage - we need to make sure that api.path[typo] raises an
- # exception.
- try:
- api.path['chekout'] # note the typo
- assert False, 'PathTestApi did not catch typo' # pragma: no cover
- except ValueError:
- pass
+ paths = [base_path(name).join('file') for name in GETITEM_NAMES]
+ paths.append(api.path.checkout_dir.join('file'))
yield api.test(
'basic',
diff --git a/recipe_modules/proto/tests/placeholders.py b/recipe_modules/proto/tests/placeholders.py
index 263f9a2..dce3bae 100644
--- a/recipe_modules/proto/tests/placeholders.py
+++ b/recipe_modules/proto/tests/placeholders.py
@@ -30,13 +30,13 @@
step = api.step('read missing output', [
'python3', api.resource('dump.py'),
api.proto.output(SomeMessage, 'JSONPB',
- leak_to=api.path['start_dir'].join('gone')),
+ leak_to=api.path.start_dir.join('gone')),
])
step = api.step('read invalid output', [
'python3', api.resource('dump.py'),
api.proto.output(SomeMessage, 'JSONPB',
- leak_to=api.path['start_dir'].join('gone')),
+ leak_to=api.path.start_dir.join('gone')),
])
api.step('write to script (jsonpb)', [
diff --git a/recipe_modules/raw_io/examples/full.py b/recipe_modules/raw_io/examples/full.py
index ea54eb1..2ac863d 100644
--- a/recipe_modules/raw_io/examples/full.py
+++ b/recipe_modules/raw_io/examples/full.py
@@ -67,14 +67,14 @@
step_result = api.step(
'leak stdout', ['echo', 'leaking'],
stdout=api.raw_io.output_text(
- leak_to=api.path['tmp_base'].join('out.txt')),
+ leak_to=api.path.tmp_base_dir.join('out.txt')),
step_test_data=(
lambda: api.raw_io.test_api.stream_output_text('leaking\n')))
assert step_result.stdout == 'leaking\n'
api.step('list temp dir', ['ls', api.raw_io.output_dir()])
api.step('leak dir', ['ls', api.raw_io.output_dir(
- leak_to=api.path['tmp_base'].join('out'))])
+ leak_to=api.path.tmp_base_dir.join('out'))])
step_result = api.step(
'dump output_dir',
@@ -95,7 +95,7 @@
step_result = api.step(
'nothing leaked to leak_to',
['echo',
- api.raw_io.output(leak_to=api.path['tmp_base'].join('missing.txt'))])
+ api.raw_io.output(leak_to=api.path.tmp_base_dir.join('missing.txt'))])
# Example of overriding default mocked output for a single named output.
step_result = api.step(
diff --git a/recipe_modules/service_account/examples/full.py b/recipe_modules/service_account/examples/full.py
index fbba4c8..a2c691f 100644
--- a/recipe_modules/service_account/examples/full.py
+++ b/recipe_modules/service_account/examples/full.py
@@ -49,7 +49,7 @@
yield api.test(
'json_key',
api.platform('linux', 64),
- props(key_path=api.path['start_dir'].join('key_name.json')),
+ props(key_path=api.path.start_dir.join('key_name.json')),
)
yield api.test(
diff --git a/recipe_modules/step/api.py b/recipe_modules/step/api.py
index d5fed19..0941c7c 100644
--- a/recipe_modules/step/api.py
+++ b/recipe_modules/step/api.py
@@ -377,7 +377,7 @@
return cost or _ResourceCost.zero()
def _normalize_cwd(self, cwd):
- if cwd and cwd == self.m.path['start_dir']:
+ if cwd and cwd == self.m.path.start_dir:
cwd = None
elif cwd is not None:
cwd = str(cwd)
@@ -523,17 +523,17 @@
# output path, cwd and cache directory.
with api.context(
# Change the cwd of the launched LUCI executable
- cwd=api.path['start_dir'].join('subdir'),
+ cwd=api.path.start_dir.join('subdir'),
# Change the cache_dir of the launched LUCI executable. Defaults to
- # api.path['cache'] if unchanged.
- luciexe=sections_pb2.LUCIExe(cache_dir=api.path['cache'].join('sub')),
+ # api.path.cache_dir if unchanged.
+ luciexe=sections_pb2.LUCIExe(cache_dir=api.path.cache_dir.join('sub')),
):
# Command executed:
# `/path/to/run_exe --output [CLEANUP]/build.json --foo bar baz`
ret = api.sub_build("launch sub build",
[run_exe, '--foo', 'bar', 'baz'],
api.buildbucket.build,
- output_path=api.path['cleanup'].join('build.json'))
+ output_path=api.path.cleanup_dir.join('build.json'))
sub_build = ret.step.sub_build # access final build proto result
```
diff --git a/recipe_modules/step/examples/full.py b/recipe_modules/step/examples/full.py
index 2f9f706..c71fb5c 100644
--- a/recipe_modules/step/examples/full.py
+++ b/recipe_modules/step/examples/full.py
@@ -42,13 +42,13 @@
# You can change the current working directory as well.
api.step('mk subdir', ['mkdir', '-p', 'something'])
- with api.context(cwd=api.path['start_dir'].join('something')):
+ with api.context(cwd=api.path.start_dir.join('something')):
api.step('something', ['bash', '-c', 'echo Why hello, there, in a subdir.'])
# By default, all steps run in 'start_dir', or the cwd of the recipe engine
# when the recipe begins. Because of this, setting cwd to start_dir doesn't
# show anything in particular in the expectations.
- with api.context(cwd=api.path['start_dir']):
+ with api.context(cwd=api.path.start_dir):
api.step('start_dir ignored', ['bash', '-c', 'echo what happen'])
# You can also manipulate various aspects of the step, such as env.
diff --git a/recipe_modules/step/tests/sub_build.py b/recipe_modules/step/tests/sub_build.py
index 65c32b3..8e273a3 100644
--- a/recipe_modules/step/tests/sub_build.py
+++ b/recipe_modules/step/tests/sub_build.py
@@ -30,7 +30,7 @@
output_path = None
if props.HasField('output_path'):
output_path = (
- api.path[props.output_path.base].join(props.output_path.file))
+ getattr(api.path, props.output_path.base).join(props.output_path.file))
with api.context(infra_steps=props.infra_step):
input_build = props.input_build if props.HasField('input_build') else (
build_pb2.Build(id=11111, status=common_pb2.SCHEDULED))
@@ -93,7 +93,7 @@
base='start_dir',
file='sub_build.json'),
),
- api.path.exists(api.path['start_dir'].join('sub_build.json')),
+ api.path.exists(api.path.start_dir.join('sub_build.json')),
api.expect_exception('ValueError'),
api.post_process(post_process.StatusException),
api.post_process(
diff --git a/recipe_modules/tricium/api.py b/recipe_modules/tricium/api.py
index e1d272c..57122fa 100644
--- a/recipe_modules/tricium/api.py
+++ b/recipe_modules/tricium/api.py
@@ -171,7 +171,7 @@
if not _matches_path_filters(affected_files, analyzer.path_filters):
presentation.step_text = 'skipped due to path filters'
try:
- analyzer_dir = self.m.path['cleanup'].join(analyzer.name)
+ analyzer_dir = self.m.path.cleanup_dir.join(analyzer.name)
output_base = analyzer_dir.join('out')
package_dir = analyzer_dir.join('package')
self._fetch_legacy_analyzer(package_dir, analyzer)
diff --git a/recipe_modules/tricium/examples/wrapper.py b/recipe_modules/tricium/examples/wrapper.py
index 90ca014..224d1a0 100644
--- a/recipe_modules/tricium/examples/wrapper.py
+++ b/recipe_modules/tricium/examples/wrapper.py
@@ -17,7 +17,7 @@
def RunSteps(api):
- checkout_base = api.path['cleanup'].join('checkout')
+ checkout_base = api.path.cleanup_dir.join('checkout')
api.file.write_text('one', checkout_base.join('one.txt'), 'one')
api.file.write_text('two', checkout_base.join('foo', 'two.txt'), 'two')
diff --git a/recipe_modules/url/examples/full.py b/recipe_modules/url/examples/full.py
index 4fe9ab5..b7499cf 100644
--- a/recipe_modules/url/examples/full.py
+++ b/recipe_modules/url/examples/full.py
@@ -30,7 +30,7 @@
assert api.url.urlencode({'foo': 'bar'}) == 'foo=bar'
with api.step.nest('get_file'):
- dest = api.path['start_dir'].join('download.bin')
+ dest = api.path.start_dir.join('download.bin')
v = api.url.get_file(TEST_HTTPS_URL, dest,
headers={'Authorization': 'thing'})
assert str(v.output) == str(dest)
diff --git a/recipe_proto/go.chromium.org/luci/buildbucket/proto/build.proto b/recipe_proto/go.chromium.org/luci/buildbucket/proto/build.proto
index 1c7b3fa..68bd53e 100644
--- a/recipe_proto/go.chromium.org/luci/buildbucket/proto/build.proto
+++ b/recipe_proto/go.chromium.org/luci/buildbucket/proto/build.proto
@@ -703,7 +703,7 @@
// Must use POSIX format (forward slashes).
// In most cases, it does not need slashes at all.
//
- // In recipes, use api.path['cache'].join(path) to get absolute path.
+ // In recipes, use api.path.cache_dir.join(path) to get absolute path.
//
// Must be unique in the build.
string path = 2;
diff --git a/recipe_proto/go.chromium.org/luci/buildbucket/proto/common.proto b/recipe_proto/go.chromium.org/luci/buildbucket/proto/common.proto
index 5f1a582..79a5e85 100644
--- a/recipe_proto/go.chromium.org/luci/buildbucket/proto/common.proto
+++ b/recipe_proto/go.chromium.org/luci/buildbucket/proto/common.proto
@@ -308,7 +308,7 @@
// Must use POSIX format (forward slashes).
// In most cases, it does not need slashes at all.
//
- // In recipes, use api.path['cache'].join(path) to get absolute path.
+ // In recipes, use api.path.cache_dir.join(path) to get absolute path.
//
// Must be unique in the build.
string path = 2;
diff --git a/recipes/engine_tests/early_termination.py b/recipes/engine_tests/early_termination.py
index 502bc6c..7764e68 100644
--- a/recipes/engine_tests/early_termination.py
+++ b/recipes/engine_tests/early_termination.py
@@ -23,10 +23,10 @@
output_touchfile = props.output_touchfile
if not output_touchfile:
- output_touchfile = api.path['cleanup'].join('output_touchfile')
+ output_touchfile = api.path.cleanup_dir.join('output_touchfile')
running_touchfile = props.running_touchfile
if not running_touchfile:
- running_touchfile = api.path['cleanup'].join('running_touchfile')
+ running_touchfile = api.path.cleanup_dir.join('running_touchfile')
# make sure touchfile is there
api.file.write_text("ensure output_touchfile", output_touchfile,
"meep".encode('utf-8'))
diff --git a/recipes/engine_tests/missing_start_dir.py b/recipes/engine_tests/missing_start_dir.py
index 328c318..718aa74 100644
--- a/recipes/engine_tests/missing_start_dir.py
+++ b/recipes/engine_tests/missing_start_dir.py
@@ -12,7 +12,7 @@
def RunSteps(api):
api.step('innocent step', ['bash', '-c', "echo some step"])
- api.step('nuke it', ['rm', '-rf', api.path['start_dir']])
+ api.step('nuke it', ['rm', '-rf', api.path.start_dir])
try:
api.step('bash needs cwd', ['bash', '-c', "echo fail"])