The envtest recipe now works for Windows
Changes required to get the envtest recipe to work on Windows.
(Mostly a reland of pwrev/6740.)
Simplified way of setting PW_ROOT since then because of pwrev/6783.
Tested with led:
$ led get-builder luci.pigweed.ci:pigweed-windows-envtest \
| led edit-recipe-bundle \
| led launch
...
LUCI UI: https://ci.chromium.org/swarming/task/4a82d9f67accc310?server=chrome-swarming.appspot.com
$ led get-builder luci.pigweed.ci:pigweed-linux-envtest \
| led edit-recipe-bundle \
| led launch
...
LUCI UI: https://ci.chromium.org/swarming/task/4a82da0ab342c810?server=chrome-swarming.appspot.com
Bug: 92
Change-Id: I9a021ce2d7c7040ad37e088ad8ff7d619dc1f573
diff --git a/recipes/envtest.expected/fail.json b/recipes/envtest.expected/fail.json
index 2e4075e..d9c5bae 100644
--- a/recipes/envtest.expected/fail.json
+++ b/recipes/envtest.expected/fail.json
@@ -283,17 +283,13 @@
"RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
"--json-output",
"/path/to/tmp/json",
- "copy",
- ". \"[START_DIR]/checkout/pw_env_setup/bootstrap.sh\"\npw --loglevel debug presubmit --step gn_clang_build --repository $PW_ROOT\n",
- "[START_DIR]/run.sh"
+ "ensure-directory",
+ "--mode",
+ "0777",
+ "[START_DIR]/run"
],
"infra_step": true,
- "name": "write run.sh",
- "~followup_annotations": [
- "@@@STEP_LOG_LINE@run.sh@. \"[START_DIR]/checkout/pw_env_setup/bootstrap.sh\"@@@",
- "@@@STEP_LOG_LINE@run.sh@pw --loglevel debug presubmit --step gn_clang_build --repository $PW_ROOT@@@",
- "@@@STEP_LOG_END@run.sh@@@"
- ]
+ "name": "mkdir run"
},
{
"cmd": [
@@ -302,13 +298,17 @@
"RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
"--json-output",
"/path/to/tmp/json",
- "ensure-directory",
- "--mode",
- "0777",
- "[START_DIR]/run"
+ "copy",
+ ". [START_DIR]/checkout/pw_env_setup/env_setup.sh\npw --loglevel debug presubmit --step gn_clang_build --repository $PW_ROOT\n",
+ "[START_DIR]/run.sh"
],
"infra_step": true,
- "name": "mkdir run"
+ "name": "write run.sh",
+ "~followup_annotations": [
+ "@@@STEP_LOG_LINE@run.sh@. [START_DIR]/checkout/pw_env_setup/env_setup.sh@@@",
+ "@@@STEP_LOG_LINE@run.sh@pw --loglevel debug presubmit --step gn_clang_build --repository $PW_ROOT@@@",
+ "@@@STEP_LOG_END@run.sh@@@"
+ ]
},
{
"cmd": [
@@ -326,9 +326,26 @@
]
},
{
+ "cmd": [
+ "vpython",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "glob",
+ "[START_DIR]/checkout/pw_env_setup",
+ ".env_setup*"
+ ],
+ "infra_step": true,
+ "name": "glob pw_env_setup/.env_setup*",
+ "~followup_annotations": [
+ "@@@STEP_LOG_END@glob@@@"
+ ]
+ },
+ {
"failure": {
"failure": {},
- "humanReason": "Step('run.sh') (retcode: 1)"
+ "humanReason": "1 out of 2 aggregated steps failed: Step('run.sh') (retcode: 1)"
},
"name": "$result"
}
diff --git a/recipes/envtest.expected/pigweed.json b/recipes/envtest.expected/pigweed.json
index 309b775..9635e25 100644
--- a/recipes/envtest.expected/pigweed.json
+++ b/recipes/envtest.expected/pigweed.json
@@ -283,17 +283,13 @@
"RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
"--json-output",
"/path/to/tmp/json",
- "copy",
- ". \"[START_DIR]/checkout/pw_env_setup/bootstrap.sh\"\npw --loglevel debug presubmit --step gn_clang_build --repository $PW_ROOT\n",
- "[START_DIR]/run.sh"
+ "ensure-directory",
+ "--mode",
+ "0777",
+ "[START_DIR]/run"
],
"infra_step": true,
- "name": "write run.sh",
- "~followup_annotations": [
- "@@@STEP_LOG_LINE@run.sh@. \"[START_DIR]/checkout/pw_env_setup/bootstrap.sh\"@@@",
- "@@@STEP_LOG_LINE@run.sh@pw --loglevel debug presubmit --step gn_clang_build --repository $PW_ROOT@@@",
- "@@@STEP_LOG_END@run.sh@@@"
- ]
+ "name": "mkdir run"
},
{
"cmd": [
@@ -302,13 +298,17 @@
"RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
"--json-output",
"/path/to/tmp/json",
- "ensure-directory",
- "--mode",
- "0777",
- "[START_DIR]/run"
+ "copy",
+ ". [START_DIR]/checkout/pw_env_setup/env_setup.sh\npw --loglevel debug presubmit --step gn_clang_build --repository $PW_ROOT\n",
+ "[START_DIR]/run.sh"
],
"infra_step": true,
- "name": "mkdir run"
+ "name": "write run.sh",
+ "~followup_annotations": [
+ "@@@STEP_LOG_LINE@run.sh@. [START_DIR]/checkout/pw_env_setup/env_setup.sh@@@",
+ "@@@STEP_LOG_LINE@run.sh@pw --loglevel debug presubmit --step gn_clang_build --repository $PW_ROOT@@@",
+ "@@@STEP_LOG_END@run.sh@@@"
+ ]
},
{
"cmd": [
@@ -323,6 +323,23 @@
"name": "run.sh"
},
{
+ "cmd": [
+ "vpython",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "glob",
+ "[START_DIR]/checkout/pw_env_setup",
+ ".env_setup*"
+ ],
+ "infra_step": true,
+ "name": "glob pw_env_setup/.env_setup*",
+ "~followup_annotations": [
+ "@@@STEP_LOG_END@glob@@@"
+ ]
+ },
+ {
"name": "$result"
}
]
\ No newline at end of file
diff --git a/recipes/envtest.expected/windows.json b/recipes/envtest.expected/windows.json
index d19a3d2..55e5bcd 100644
--- a/recipes/envtest.expected/windows.json
+++ b/recipes/envtest.expected/windows.json
@@ -283,25 +283,6 @@
"RECIPE_MODULE[recipe_engine::file]\\resources\\fileutil.py",
"--json-output",
"/path/to/tmp/json",
- "copy",
- "\"[START_DIR]\\checkout\\pw_env_setup/bootstrap.bat\"\npw --loglevel debug presubmit --step gn_clang_build --repository $PW_ROOT\n",
- "[START_DIR]\\run.sh"
- ],
- "infra_step": true,
- "name": "write run.sh",
- "~followup_annotations": [
- "@@@STEP_LOG_LINE@run.sh@\"[START_DIR]\\checkout\\pw_env_setup/bootstrap.bat\"@@@",
- "@@@STEP_LOG_LINE@run.sh@pw --loglevel debug presubmit --step gn_clang_build --repository $PW_ROOT@@@",
- "@@@STEP_LOG_END@run.sh@@@"
- ]
- },
- {
- "cmd": [
- "vpython",
- "-u",
- "RECIPE_MODULE[recipe_engine::file]\\resources\\fileutil.py",
- "--json-output",
- "/path/to/tmp/json",
"ensure-directory",
"--mode",
"0777",
@@ -312,15 +293,67 @@
},
{
"cmd": [
- "sh",
- "-x",
- "[START_DIR]\\run.sh"
+ "vpython",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]\\resources\\fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "copy",
+ "call [START_DIR]\\\\checkout\\\\pw_env_setup\\\\env_setup.bat\npw --loglevel debug presubmit --step gn_clang_build --repository %PW_ROOT%\n",
+ "[START_DIR]\\run.bat"
+ ],
+ "infra_step": true,
+ "name": "write run.bat",
+ "~followup_annotations": [
+ "@@@STEP_LOG_LINE@run.bat@call [START_DIR]\\\\checkout\\\\pw_env_setup\\\\env_setup.bat@@@",
+ "@@@STEP_LOG_LINE@run.bat@pw --loglevel debug presubmit --step gn_clang_build --repository %PW_ROOT%@@@",
+ "@@@STEP_LOG_END@run.bat@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "[START_DIR]\\run.bat"
],
"cwd": "[START_DIR]\\run",
"env": {
"PW_CHECKOUT_ROOT": "[START_DIR]\\checkout"
},
- "name": "run.sh"
+ "name": "run.bat"
+ },
+ {
+ "cmd": [
+ "vpython",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]\\resources\\fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "glob",
+ "[START_DIR]\\checkout\\pw_env_setup",
+ ".env_setup*"
+ ],
+ "infra_step": true,
+ "name": "glob pw_env_setup/.env_setup*",
+ "~followup_annotations": [
+ "@@@STEP_LOG_LINE@glob@[START_DIR]\\checkout\\pw_env_setup\\.env_setup.bat@@@",
+ "@@@STEP_LOG_END@glob@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "vpython",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]\\resources\\fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "copy",
+ "[START_DIR]\\checkout\\pw_env_setup\\.env_setup.bat",
+ "/path/to/tmp/"
+ ],
+ "infra_step": true,
+ "name": "read .env_setup.bat",
+ "~followup_annotations": [
+ "@@@STEP_LOG_END@.env_setup.bat@@@"
+ ]
},
{
"name": "$result"
diff --git a/recipes/envtest.py b/recipes/envtest.py
index 067dec8..929c959 100644
--- a/recipes/envtest.py
+++ b/recipes/envtest.py
@@ -13,7 +13,7 @@
# the License.
"""Recipe for testing Pigweed using developer env setup scripts."""
-import os
+import re
from recipe_engine.recipe_api import Property
@@ -38,12 +38,13 @@
kind=str,
help=('Path within repository to env setup script to source '
'(trailing ".sh" will be replaced with ".bat" on Windows)'),
- default='pw_env_setup/bootstrap.sh',
+ default='pw_env_setup/env_setup.sh',
),
'command': Property(
kind=str,
- help='Command with which to test.',
+ help=('Command with which to test. Unix-style variables ($ABC) will be '
+ 'replaced with Windows-style (%ABC%) automatically on Windows.'),
default=('pw --loglevel debug presubmit --step gn_clang_build '
'--repository $PW_ROOT'),
),
@@ -55,22 +56,46 @@
api.checkout(remote)
- if api.platform.is_win and setup_path.endswith('.sh'):
- setup_path = os.path.splitext(setup_path)[0] + '.bat'
-
- sh_source = '{dot}"{env_setup}"\n{command}\n'.format(
- dot='' if api.platform.is_win else '. ',
- env_setup=api.checkout.root.join(setup_path),
- command=command,
- )
-
- sh_path = api.path['start_dir'].join('run.sh')
- api.file.write_text('write run.sh', sh_path, sh_source)
-
run = api.path['start_dir'].join('run')
api.file.ensure_directory('mkdir run', run)
- with api.context(cwd=run, env={'PW_CHECKOUT_ROOT': api.checkout.root}):
- api.step('run.sh', ['sh', '-x', sh_path])
+
+ setup_path = api.checkout.root.join(*re.split(r'[/\\]+', setup_path))
+ env = {}
+
+ if api.platform.is_win and api.path.splitext(setup_path)[1] == '.sh':
+ setup_path = api.path.abs_to_path(
+ api.path.splitext(setup_path)[0] + '.bat')
+
+ env['PW_CHECKOUT_ROOT'] = api.checkout.root
+
+ # Replace '$ABC' with '%ABC%' on Windows.
+ if api.platform.is_win:
+ command = re.sub(r'\$([\w_]+)\b', r'%\1%', command)
+
+ commands = []
+ commands.append('{dot}{env_setup}'.format(
+ dot='call ' if api.platform.is_win else '. ',
+ # Without the replace here we end up with paths that have no
+ # separators. Not sure why, but this fixes it.
+ env_setup=api.path.realpath(setup_path).replace('\\', '\\\\')))
+ commands.append(command)
+
+ sh_source = ''.join(x + '\n' for x in commands)
+ base = 'run.bat' if api.platform.is_win else 'run.sh'
+ sh_path = api.path['start_dir'].join(base)
+ api.file.write_text('write {}'.format(base), sh_path, sh_source)
+
+ with api.step.defer_results():
+ with api.context(cwd=run, env=env):
+ if api.platform.is_win:
+ api.step(base, [sh_path])
+ else:
+ api.step(base, ['sh', '-x', sh_path])
+
+ for path in api.file.glob_paths('glob pw_env_setup/.env_setup*',
+ api.checkout.root.join('pw_env_setup'),
+ '.env_setup*').get_result():
+ api.file.read_text('read {}'.format(api.path.basename(path)), path)
def GenTests(api): # pylint: disable=invalid-name
@@ -83,6 +108,8 @@
api.test('windows')
+ api.platform.name('win')
+ api.checkout.ci_test_data()
+ + api.step_data('glob pw_env_setup/.env_setup*',
+ api.file.glob_paths(['.env_setup.bat']))
)
yield (