Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the EnvVar.save_ps1() method #10049

Merged
merged 4 commits into from Nov 22, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
39 changes: 33 additions & 6 deletions conan/tools/env/environment.py
Expand Up @@ -291,19 +291,46 @@ def save_bat(self, filename, generate_deactivate=True):
for varname, varvalues in self._values.items():
value = varvalues.get_str("%{name}%", subsystem=self._subsystem, pathsep=self._pathsep)
result.append('set {}={}'.format(varname, value))

content = "\n".join(result)
save(filename, content)

def save_ps1(self, filename, generate_deactivate=True,):
# FIXME: This is broken and doesnt work
deactivate = ""
deactivate = textwrap.dedent("""\
echo "Capturing current environment in deactivate_{filename}"

"echo `"Restoring environment`"" | Out-File -FilePath "deactivate_{filename}"
$vars = (Get-ChildItem env:*).name
$updated_vars = @({vars})

foreach ($var in $updated_vars)
{{
if ($var -in $vars)
{{
$var_value = (Get-ChildItem env:$var).value
Add-Content "deactivate_{filename}" "`n`$env:$var = `"$var_value`""
}}
else
{{
Add-Content "deactivate_{filename}" "`nif (Test-Path env:$var) {{ Remove-Item env:$var }}"
}}
}}
""").format(
filename=os.path.basename(filename),
vars=",".join(['"{}"'.format(var) for var in self._values.keys()])
)

capture = textwrap.dedent("""\
{deactivate}
""").format(deactivate=deactivate if generate_deactivate else "")
{deactivate}
echo "Configuring environment variables"
""").format(deactivate=deactivate if generate_deactivate else "")
result = [capture]
for varname, varvalues in self._values.items():
value = varvalues.get_str("$env:{name}", self._pathsep)
result.append('$env:{}={}'.format(varname, value))
value = varvalues.get_str("$env:{name}", subsystem=self._subsystem, pathsep=self._pathsep)
if value:
result.append('$env:{}="{}"'.format(varname, value))
else:
result.append('if (Test-Path env:{0}) {{ Remove-Item env:{0} }}'.format(varname))

content = "\n".join(result)
save(filename, content)
Expand Down
36 changes: 36 additions & 0 deletions conans/test/integration/environment/test_env.py
Expand Up @@ -491,3 +491,39 @@ def generate(self):
assert 2 == str(out).count("Restoring environment")
assert "VAR1=!!" in out
assert "VAR2=!!" in out


@pytest.mark.skipif(platform.system() != "Windows", reason="Path problem in Windows only")
@pytest.mark.parametrize("num_deps", [3, 60])
tapia marked this conversation as resolved.
Show resolved Hide resolved
def test_massive_paths(num_deps):
client = TestClient()
compiler_bat = "@echo off\necho MYTOOL {}!!\n"
conanfile = textwrap.dedent("""\
from conans import ConanFile
class Pkg(ConanFile):
exports = "*"
def package(self):
self.copy("*", dst="bin")
""")

for i in range(num_deps):
client.save({"conanfile.py": conanfile,
"mycompiler{}.bat".format(i): compiler_bat.format(i)})
client.run("create . pkg{}/0.1@".format(i))

conanfile = textwrap.dedent("""\
from conans import ConanFile
class Pkg(ConanFile):
settings = "os"
requires = {}
generators = "VirtualRunEnv"
""")
requires = ", ".join('"pkg{}/0.1"'.format(i) for i in range(num_deps))
client.save({"conanfile.py": conanfile.format(requires)}, clean_first=True)
client.run("install .")

for i in range(num_deps):
cmd = environment_wrap_command("conanrunenv", "mycompiler{}.bat".format(i),
cwd=client.current_folder)
client.run_command(cmd)
assert "MYTOOL {}!!".format(i) in client.out
82 changes: 58 additions & 24 deletions conans/test/unittests/tools/env/test_env.py
Expand Up @@ -201,6 +201,7 @@ def test_env_files():
"MyPath3": "OldPath3",
"MyPath4": "OldPath4",
}
prevenv.update(dict(os.environ.copy()))
tapia marked this conversation as resolved.
Show resolved Hide resolved

display_bat = textwrap.dedent("""\
@echo off
Expand All @@ -217,6 +218,20 @@ def test_env_files():
echo MyPath4=%MyPath4%!!
""")

display_ps1 = textwrap.dedent("""\
echo "MyVar=$env:MyVar!!"
echo "MyVar1=$env:MyVar1!!"
echo "MyVar2=$env:MyVar2!!"
echo "MyVar3=$env:MyVar3!!"
echo "MyVar4=$env:MyVar4!!"
echo "MyVar5=$env:MyVar5!!"
echo "MyVar6=$env:MyVar6!!"
echo "MyPath1=$env:MyPath1!!"
echo "MyPath2=$env:MyPath2!!"
echo "MyPath3=$env:MyPath3!!"
echo "MyPath4=$env:MyPath4!!"
""")

display_sh = textwrap.dedent("""\
echo MyVar=$MyVar!!
echo MyVar1=$MyVar1!!
Expand All @@ -232,9 +247,10 @@ def test_env_files():
""")

def check(cmd_):
out, _ = subprocess.Popen(cmd_, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
env=prevenv, shell=True).communicate()
out = out.decode()
result = subprocess.run(cmd_, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
env=prevenv, shell=True)
out = result.stdout.decode()

assert "MyVar=MyValue!!" in out
assert "MyVar1=MyValue1!!" in out
assert "MyVar2=OldVar2 MyValue2!!" in out
Expand Down Expand Up @@ -268,13 +284,11 @@ def check(cmd_):
save("display.bat", display_bat)
cmd = "test.bat && display.bat && deactivate_test.bat && display.bat"
check(cmd)
# FIXME: Powershell still not working
# env.save_ps1("test.ps1", pathsep=":")
# cmd = 'powershell.exe -ExecutionPolicy ./test.ps1; gci env:'
# shell = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# (stdout, stderr) = shell.communicate()
# stdout, stderr = decode_text(stdout), decode_text(stderr)
# check(cmd)

env.save_ps1("test.ps1")
save("display.ps1", display_ps1)
cmd = "powershell.exe .\\test.ps1 ; .\\display.ps1 ; .\\deactivate_test.ps1 ; .\\display.ps1"
check(cmd)
else:
env = env.vars(ConanFileMock())
env.save_sh("test.sh")
Expand Down Expand Up @@ -302,23 +316,43 @@ def test_windows_case_insensitive():
echo MyVar2=%MyVar2%!!
""")

display_ps1 = textwrap.dedent("""\
echo "MyVar=$env:MyVar!!"
echo "MyVar1=$env:MyVar1!!"
echo "MyVar2=$env:MyVar2!!"
""")

def check(cmd_):
prevenv = {
"MYVAR2": "OldValue2",
}
prevenv.update(dict(os.environ.copy()))

result = subprocess.run(cmd_, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
env=prevenv, shell=True)
out = result.stdout.decode()

assert "MyVar=MyValueB!!" in out
assert "MyVar=!!" in out
assert "MyVar1=MyValue1A MyValue1B!!" in out
assert "MyVar1=!!" in out
assert "MyVar2=MyNewValue2!!" in out
assert "MyVar2=OldValue2!!" in out

with chdir(folder):
env = env.vars(ConanFileMock())
env._subsystem = WINDOWS
env.save_bat("test.bat")
env1 = env.vars(ConanFileMock())
env1._subsystem = WINDOWS
env1.save_bat("test.bat")
save("display.bat", display_bat)
cmd = "test.bat && display.bat && deactivate_test.bat && display.bat"
out, _ = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
shell=True, env={"MYVAR2": "OldValue2"}).communicate()

out = out.decode()
assert "MyVar=MyValueB!!" in out
assert "MyVar=!!" in out
assert "MyVar1=MyValue1A MyValue1B!!" in out
assert "MyVar1=!!" in out
assert "MyVar2=MyNewValue2!!" in out
assert "MyVar2=OldValue2!!" in out

check(cmd)

env2 = env.vars(ConanFileMock())
env2._subsystem = WINDOWS
env2.save_ps1("test.ps1")
save("display.ps1", display_ps1)
cmd = "powershell.exe .\\test.ps1 ; .\\display.ps1 ; .\\deactivate_test.ps1 ; .\\display.ps1"
check(cmd)

def test_dict_access():
env = Environment()
Expand Down