diff --git a/.gitattributes b/.gitattributes
index 2fd4db1a4b..1af7357a60 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -29,10 +29,8 @@
/roll-dep* recipes
/yapf* recipes
-# Additional files for cipd_bin_setup.{sh, bat},
-# including cipd/cipd.bat, cipd_client_version* and cipd_manifest*.
-/cipd* recipes
-/.cipd_impl.ps1 recipes
+# Ensure depot_tools/.cipd_bin in a recipe step.
+/cipd_manifest* recipes
# Symlinks
/cbuildbot recipes
diff --git a/recipes/README.recipes.md b/recipes/README.recipes.md
index 431a6817e9..db6e8f8a51 100644
--- a/recipes/README.recipes.md
+++ b/recipes/README.recipes.md
@@ -119,7 +119,7 @@ Sets a fixed revision for a single dependency using project revision
properties.
### *recipe_modules* / [depot\_tools](/recipes/recipe_modules/depot_tools)
-[DEPS](/recipes/recipe_modules/depot_tools/__init__.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/runtime][recipe_engine/recipe_modules/runtime]
+[DEPS](/recipes/recipe_modules/depot_tools/__init__.py#7): [recipe\_engine/cipd][recipe_engine/recipe_modules/cipd], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/runtime][recipe_engine/recipe_modules/runtime]
PYTHON_VERSION_COMPATIBILITY: PY2+3
@@ -128,19 +128,19 @@ the depot_tools repo.
#### **class [DepotToolsApi](/recipes/recipe_modules/depot_tools/api.py#12)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
- **@property**
— **def [autoninja\_path](/recipes/recipe_modules/depot_tools/api.py#45)(self):**
+ **@property**
— **def [autoninja\_path](/recipes/recipe_modules/depot_tools/api.py#50)(self):**
- **@property**
— **def [cros\_path](/recipes/recipe_modules/depot_tools/api.py#26)(self):**
+ **@property**
— **def [cros\_path](/recipes/recipe_modules/depot_tools/api.py#30)(self):**
- **@property**
— **def [download\_from\_google\_storage\_path](/recipes/recipe_modules/depot_tools/api.py#13)(self):**
+ **@property**
— **def [download\_from\_google\_storage\_path](/recipes/recipe_modules/depot_tools/api.py#17)(self):**
- **@property**
— **def [gn\_py\_path](/recipes/recipe_modules/depot_tools/api.py#30)(self):**
+ **@property**
— **def [gn\_py\_path](/recipes/recipe_modules/depot_tools/api.py#34)(self):**
- **@property**
— **def [gsutil\_py\_path](/recipes/recipe_modules/depot_tools/api.py#36)(self):**
+ **@property**
— **def [gsutil\_py\_path](/recipes/recipe_modules/depot_tools/api.py#40)(self):**
- **@property**
— **def [ninja\_path](/recipes/recipe_modules/depot_tools/api.py#40)(self):**
+ **@property**
— **def [ninja\_path](/recipes/recipe_modules/depot_tools/api.py#44)(self):**
- **@contextlib.contextmanager**
— **def [on\_path](/recipes/recipe_modules/depot_tools/api.py#54)(self):**
+ **@contextlib.contextmanager**
— **def [on\_path](/recipes/recipe_modules/depot_tools/api.py#60)(self):**
Use this context manager to put depot_tools on $PATH.
@@ -151,13 +151,13 @@ with api.depot_tools.on_path():
# run some steps
```
- **@property**
— **def [presubmit\_support\_py\_path](/recipes/recipe_modules/depot_tools/api.py#50)(self):**
+ **@property**
— **def [presubmit\_support\_py\_path](/recipes/recipe_modules/depot_tools/api.py#56)(self):**
- **@property**
— **def [root](/recipes/recipe_modules/depot_tools/api.py#21)(self):**
+ **@property**
— **def [root](/recipes/recipe_modules/depot_tools/api.py#25)(self):**
Returns (Path): The "depot_tools" root directory.
- **@property**
— **def [upload\_to\_google\_storage\_path](/recipes/recipe_modules/depot_tools/api.py#17)(self):**
+ **@property**
— **def [upload\_to\_google\_storage\_path](/recipes/recipe_modules/depot_tools/api.py#21)(self):**
### *recipe_modules* / [gclient](/recipes/recipe_modules/gclient)
[DEPS](/recipes/recipe_modules/gclient/__init__.py#3): [git](#recipe_modules-git), [gitiles](#recipe_modules-gitiles), [tryserver](#recipe_modules-tryserver), [recipe\_engine/buildbucket][recipe_engine/recipe_modules/buildbucket], [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]
diff --git a/recipes/recipe_modules/depot_tools/__init__.py b/recipes/recipe_modules/depot_tools/__init__.py
index af3717db31..c9f0de463f 100644
--- a/recipes/recipe_modules/depot_tools/__init__.py
+++ b/recipes/recipe_modules/depot_tools/__init__.py
@@ -5,6 +5,7 @@
PYTHON_VERSION_COMPATIBILITY = 'PY2+3'
DEPS = [
+ 'recipe_engine/cipd',
'recipe_engine/context',
'recipe_engine/platform',
'recipe_engine/runtime',
diff --git a/recipes/recipe_modules/depot_tools/api.py b/recipes/recipe_modules/depot_tools/api.py
index 0175269345..6c52b3905b 100644
--- a/recipes/recipe_modules/depot_tools/api.py
+++ b/recipes/recipe_modules/depot_tools/api.py
@@ -10,6 +10,10 @@ import contextlib
from recipe_engine import recipe_api
class DepotToolsApi(recipe_api.RecipeApi):
+ def __init__(self, **kwargs):
+ super(DepotToolsApi, self).__init__(**kwargs);
+ self._cipd_bin_setup_called = False
+
@property
def download_from_google_storage_path(self):
return self.repo_resource('download_from_google_storage.py')
@@ -39,11 +43,13 @@ class DepotToolsApi(recipe_api.RecipeApi):
@property
def ninja_path(self):
+ self._cipd_bin_setup()
ninja_exe = 'ninja.exe' if self.m.platform.is_win else 'ninja'
return self.repo_resource(ninja_exe)
@property
def autoninja_path(self):
+ self._cipd_bin_setup()
autoninja = 'autoninja.bat' if self.m.platform.is_win else 'autoninja'
return self.repo_resource(autoninja)
@@ -70,3 +76,13 @@ class DepotToolsApi(recipe_api.RecipeApi):
'DEPOT_TOOLS_UPDATE': '0'
}}):
yield
+
+ def _cipd_bin_setup(self):
+ """Installs CIPD packages under .cipd_bin."""
+ if self._cipd_bin_setup_called:
+ return
+ self.m.cipd.ensure(
+ self.repo_resource('.cipd_bin'),
+ self.repo_resource('cipd_manifest.txt'),
+ 'ensure depot_tools/.cipd_bin')
+ self._cipd_bin_setup_called = True
diff --git a/recipes/recipe_modules/depot_tools/examples/full.expected/basic.json b/recipes/recipe_modules/depot_tools/examples/full.expected/basic.json
index 0826600bfe..1e98803783 100644
--- a/recipes/recipe_modules/depot_tools/examples/full.expected/basic.json
+++ b/recipes/recipe_modules/depot_tools/examples/full.expected/basic.json
@@ -41,6 +41,27 @@
],
"name": "gsutil_py_path"
},
+ {
+ "cmd": [
+ "cipd",
+ "ensure",
+ "-root",
+ "RECIPE_REPO[depot_tools]/.cipd_bin",
+ "-ensure-file",
+ "RECIPE_REPO[depot_tools]/cipd_manifest.txt",
+ "-max-threads",
+ "0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "name": "ensure depot_tools/.cipd_bin",
+ "~followup_annotations": [
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {}@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
{
"cmd": [
"ls",
diff --git a/recipes/recipe_modules/depot_tools/examples/full.expected/win.json b/recipes/recipe_modules/depot_tools/examples/full.expected/win.json
index bce098696b..8ae032a4e6 100644
--- a/recipes/recipe_modules/depot_tools/examples/full.expected/win.json
+++ b/recipes/recipe_modules/depot_tools/examples/full.expected/win.json
@@ -41,6 +41,27 @@
],
"name": "gsutil_py_path"
},
+ {
+ "cmd": [
+ "cipd.bat",
+ "ensure",
+ "-root",
+ "RECIPE_REPO[depot_tools]\\.cipd_bin",
+ "-ensure-file",
+ "RECIPE_REPO[depot_tools]\\cipd_manifest.txt",
+ "-max-threads",
+ "0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "name": "ensure depot_tools/.cipd_bin",
+ "~followup_annotations": [
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {}@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
{
"cmd": [
"ls",