Skip to content

Commit d064dea

Browse files
committed
Merge branch 'feature/1256-add-git-bash-shell-plugin'
2 parents a043125 + 11196b0 commit d064dea

File tree

14 files changed

+292
-78
lines changed

14 files changed

+292
-78
lines changed

.github/docker/rez-win-py/Dockerfile

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ SHELL ["powershell.exe", "-NoLogo", "-NoProfile", "-ExecutionPolicy", "ByPass"]
1717
#
1818
ARG PYTHON_VERSION
1919

20+
2021
# ------------------------------------------------------------------------------------------------------------
2122
# Python
2223
#
@@ -32,21 +33,31 @@ RUN ${PYTHON_INSTALL_PATH} = 'C:\Python'; `
3233
${INSTALLARGS} = \"'/quiet InstallAllUsers=1 PrependPath=1 TargetDir=`\"\" + ${PYTHON_INSTALL_PATH} + \"`\"'\"; `
3334
} `
3435
choco install python${PYTHON_MAJOR_VERSION} --yes --version=\"${ENV:PYTHON_VERSION}\" --override --installargs=${INSTALLARGS}; `
35-
if (-not $?) {exit 1};
36+
if (-not $?) {exit 1}
3637

37-
# ------------------------------------------------------------------------------------------------------------
38-
# Verify Python
39-
#
38+
# Verify
4039
RUN $python_relative_ver = (& python --version 2>&1).ToString().Trim().Split(" ")[1]; `
4140
$python_explicit_ver = (& C:\python\python.exe --version 2>&1).ToString().Trim().Split(" ")[1]; `
4241
if (-not $?) {exit 1}; `
4342
$python_relative_ver = (& python --version 2>&1).ToString().Trim().Split(" ")[1]; `
4443
$python_explicit_ver = (& C:\python\python.exe --version 2>&1).ToString().Trim().Split(" ")[1]; `
45-
if (-not ($python_explicit_ver -eq $python_relative_ver -and $python_explicit_ver -eq ${ENV:PYTHON_VERSION})) {exit 1}; `
46-
choco install --yes choco-cleaner; `
44+
if (-not ($python_explicit_ver -eq $python_relative_ver -and $python_explicit_ver -eq ${ENV:PYTHON_VERSION})) {exit 1}
45+
46+
47+
# ------------------------------------------------------------------------------------------------------------
48+
# Git Bash (git for windows)
49+
#
50+
RUN choco install git --yes --params "/GitAndUnixToolsOnPath"
51+
52+
53+
# ------------------------------------------------------------------------------------------------------------
54+
# Cleanup
55+
#
56+
RUN choco install --yes choco-cleaner; `
4757
C:\ProgramData\chocolatey\bin\choco-cleaner.bat; `
4858
choco uninstall --yes choco-cleaner
4959

60+
5061
COPY entrypoint.ps1 /entrypoint.ps1
5162

5263
ENTRYPOINT ["powershell.exe", "-NoLogo", "-ExecutionPolicy", "ByPass", "-File", "/entrypoint.ps1"]

.github/docker/rez-win-py/entrypoint.ps1

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,30 @@ ${ENV:PYTHONIOENCODING} = "UTF-8"
1414
Write-Output "Using docker image ${ENV:_IMAGE_NAME}"
1515

1616
# Verify Python
17-
#
17+
Write-Output "python found at $((Get-Command python).Path)"
1818
python --version
1919
if (-not $?) {exit 1}
2020

2121
# Verify cmake
22-
#
22+
Write-Output "cmake found at $((Get-Command cmake).Path)"
2323
cmake.exe --version
2424
if (-not $?) {exit 1}
2525

26-
#Verify pwsh
26+
# Verify pwsh
27+
Write-Output "pwsh found at $((Get-Command pwsh).Path)"
2728
pwsh --version
2829
if (-not $?) {exit 1}
2930

30-
#Verify git
31+
# Verify git
32+
Write-Output "git found at $((Get-Command git).Path)"
3133
git --version
3234
if (-not $?) {exit 1}
3335

36+
# Verify git-bash
37+
Write-Output "bash (via Git for windows) found at $((Get-Command bash).Path)"
38+
bash --version
39+
if (-not $?) {exit 1}
40+
3441
# Install rez
3542
# Note that the workflow's checkout has been bind mounted to /checkout
3643
mkdir build
@@ -42,7 +49,6 @@ if (-not $?) {exit 1}
4249
.\build\Scripts\rez\rez-python -m pip install parameterized
4350

4451
# Run Rez Tests
45-
#
4652
.\build\Scripts\rez\rez-selftest.exe -v
4753

4854
# Pass on exit code to runner

.github/workflows/mac.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,5 @@ jobs:
5757
- name: Run Rez Tests
5858
run: |
5959
./build/bin/rez/rez-selftest -v
60-
60+
env:
61+
_REZ_ENSURE_TEST_SHELLS: sh,csh,bash,tcsh,zsh,pwsh

.github/workflows/ubuntu.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,5 @@ jobs:
7474
- name: Run Rez Tests
7575
run: |
7676
./build/bin/rez/rez-selftest -v
77-
77+
env:
78+
_REZ_ENSURE_TEST_SHELLS: sh,csh,bash,tcsh,zsh,pwsh

.github/workflows/windows.yaml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,6 @@ jobs:
203203
strategy:
204204
fail-fast: false
205205
matrix:
206-
os-version:
207-
- '2019'
208-
209206
# The windows version has to match the host system.
210207
# 1809 -> 10.0.17763.805 -> windows-2019
211208
# Compare: https://hub.docker.com/_/microsoft-windows-servercore
@@ -378,3 +375,5 @@ jobs:
378375
docker run `
379376
--mount type=bind,src=$pwd,dst=C:\checkout,readonly `
380377
${{ steps.vars.outputs.docker_image }}
378+
env:
379+
_REZ_ENSURE_TEST_SHELLS: cmd,pwsh,gitbash

src/rez/build_system.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ def add_standard_build_actions(cls, executor, context, variant, build_type,
327327
install, build_path, install_path=None):
328328
"""Perform build actions common to every build system.
329329
"""
330+
330331
# set env vars
331332
cls.set_standard_vars(
332333
executor=executor,

src/rez/rex.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,7 @@ def normalize_path(self, path):
594594

595595
def normalize_paths(self, value):
596596
"""Normalize value if it's a path(s).
597+
597598
Note that `value` may be more than one pathsep-delimited paths.
598599
"""
599600
paths = value.split(self.pathsep)
@@ -1352,7 +1353,9 @@ def append_rez_path(self):
13521353

13531354
def normalize_path(self, path):
13541355
"""Normalize a path.
1356+
13551357
Note that in many interpreters this will be unchanged.
1358+
13561359
Returns:
13571360
str: The normalized path.
13581361
"""

src/rez/shells.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,16 @@ def find_executable(cls, name, check_syspaths=False):
176176
Returns:
177177
str: Full filepath of executable.
178178
"""
179+
settings = config.plugins.shell[cls.name()]
180+
181+
if settings.executable_fullpath:
182+
if not os.path.exists(settings.executable_fullpath):
183+
raise RuntimeError(
184+
"Couldn't find executable '%s'." % settings.executable_fullpath
185+
)
186+
else:
187+
return settings.executable_fullpath
188+
179189
exe = which(name)
180190

181191
if not exe and check_syspaths:
@@ -475,6 +485,7 @@ def _create_ex():
475485

476486
if shell_command: # an empty string means 'run no command and exit'
477487
executor.command(shell_command)
488+
478489
executor.command("exit %s" % self.last_command_status)
479490

480491
code = executor.get_output()

src/rez/tests/test_shells.py

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
from __future__ import print_function
99

1010
from rez.system import system
11-
from rez.shells import create_shell
11+
from rez.shells import create_shell, get_shell_types, get_shell_class
1212
from rez.resolved_context import ResolvedContext
1313
from rez.rex import literal, expandable
14+
from rez.plugin_managers import plugin_manager
1415
from rez.utils.execution import ExecutableScriptMode, _get_python_script_files
1516
from rez.tests.util import TestBase, TempdirMixin, per_available_shell, \
1617
install_dependent
@@ -26,6 +27,10 @@
2627

2728
def _stdout(proc):
2829
out_, _ = proc.communicate()
30+
if proc.returncode:
31+
raise RuntimeError(
32+
"The subprocess failed with exitcode %d" % proc.returncode
33+
)
2934
return out_.strip()
3035

3136

@@ -52,6 +57,46 @@ def tearDownClass(cls):
5257
def _create_context(cls, pkgs):
5358
return ResolvedContext(pkgs, caching=False)
5459

60+
def test_aaa_shell_presence(self):
61+
"""Ensure specific shell types are present as loaded plugins.
62+
63+
The env var _REZ_ENSURE_TEST_SHELLS should be set by a CI system (such
64+
as github actions) to make sure the shells we expect to be installed,
65+
are installed, and are getting tested.
66+
67+
Note 'aaa' forces unittest to run this test first.
68+
"""
69+
shells = os.getenv("_REZ_ENSURE_TEST_SHELLS", "").split(',')
70+
shells = set(x for x in shells if x)
71+
72+
if not shells:
73+
self.skipTest("Not ensuring presence of shells from explicit list")
74+
return
75+
76+
# check for missing shells
77+
missing_shells = shells - set(get_shell_types())
78+
if missing_shells:
79+
raise RuntimeError(
80+
"The following shells should be available for testing but are "
81+
"not present: %r" % list(missing_shells)
82+
)
83+
84+
# check for unavailable shells
85+
for shell in shells:
86+
if not get_shell_class(shell).is_available():
87+
raise RuntimeError(
88+
"The shell %r is not available (executable not found)"
89+
% shell
90+
)
91+
92+
# check for shell plugins that failed to load
93+
for (name, reason) in plugin_manager.get_failed_plugins("shell"):
94+
if name in shells:
95+
raise RuntimeError(
96+
"The shell plugin %r failed to load: %s"
97+
% (name, reason)
98+
)
99+
55100
@per_available_shell()
56101
def test_no_output(self, shell):
57102
sh = create_shell(shell)
@@ -208,7 +253,7 @@ def _test(txt):
208253
# how it's been configured
209254
#
210255
if sh_out[1]:
211-
raise Exception("Command %r failed:\n%s" % (txt, sh_out[1]))
256+
raise RuntimeError("Command %r failed:\n%s" % (txt, sh_out[1]))
212257

213258
self.assertEqual(sh_out[0].strip(), txt)
214259

@@ -351,6 +396,7 @@ def _print(value):
351396

352397
# Assertions for other environment variable types
353398
from rez.shells import create_shell
399+
354400
sh = create_shell()
355401
for token in sh.get_all_key_tokens("WHO"):
356402
expected_output += [

src/rezplugins/shell/_utils/windows.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
import os
66
import re
7+
import subprocess
8+
from rez.utils.execution import Popen
79

810

911
_drive_start_regex = re.compile(r"^([A-Za-z]):\\")
@@ -12,6 +14,7 @@
1214

1315
def to_posix_path(path):
1416
"""Convert (eg) "C:\foo" to "/c/foo"
17+
1518
TODO: doesn't take into account escaped bask slashes, which would be
1619
weird to have in a path, but is possible.
1720
"""
@@ -42,3 +45,66 @@ def to_windows_path(path):
4245
weird to have in a path, but is possible.
4346
"""
4447
return path.replace('/', '\\')
48+
49+
50+
def get_syspaths_from_registry():
51+
52+
def gen_expected_regex(parts):
53+
whitespace = r"[\s]+"
54+
return whitespace.join(parts)
55+
56+
entries = (
57+
# local machine
58+
dict(
59+
cmd=[
60+
"REG",
61+
"QUERY",
62+
"HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment",
63+
"/v",
64+
"PATH"
65+
],
66+
expected=gen_expected_regex([
67+
"HKEY_LOCAL_MACHINE\\\\SYSTEM\\\\CurrentControlSet\\\\Control\\\\Session Manager\\\\Environment",
68+
"PATH",
69+
"REG_(EXPAND_)?SZ",
70+
"(.*)"
71+
])
72+
),
73+
# current user
74+
dict(
75+
cmd=[
76+
"REG",
77+
"QUERY",
78+
"HKCU\\Environment",
79+
"/v",
80+
"PATH"
81+
],
82+
expected=gen_expected_regex([
83+
"HKEY_CURRENT_USER\\\\Environment",
84+
"PATH",
85+
"REG_(EXPAND_)?SZ",
86+
"(.*)"
87+
])
88+
)
89+
)
90+
91+
paths = []
92+
93+
for entry in entries:
94+
p = Popen(
95+
entry["cmd"],
96+
stdout=subprocess.PIPE,
97+
stderr=subprocess.PIPE,
98+
shell=True,
99+
text=True
100+
)
101+
102+
out_, _ = p.communicate()
103+
out_ = out_.strip()
104+
105+
if p.returncode == 0:
106+
match = re.match(entry["expected"], out_)
107+
if match:
108+
paths.extend(match.group(2).split(os.pathsep))
109+
110+
return [x for x in paths if x]

0 commit comments

Comments
 (0)