-
Notifications
You must be signed in to change notification settings - Fork 992
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
Add Fish support for environments #15503
Changes from 5 commits
5f19714
bf5d21e
b249c6d
e16bf22
d42b388
269b4c8
e703b07
88a48b4
c60eb5a
1ab3a8d
70c34ae
37eab05
e32b420
8cdfd29
966c631
dd517c6
325fe06
2d202ed
66ca6a2
f57f32f
4535b74
32125de
cd94ce3
35d682e
d55eff5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,7 @@ | |
from collections import OrderedDict | ||
from contextlib import contextmanager | ||
|
||
from conans.client.generators import relativize_paths | ||
from conans.client.generators import relativize_paths, relativize_generated_file | ||
from conans.client.subsystems import deduce_subsystem, WINDOWS, subsystem_path | ||
from conan.errors import ConanException | ||
from conans.model.recipe_ref import ref_matches | ||
|
@@ -520,12 +520,52 @@ def save_sh(self, file_location, generate_deactivate=True): | |
content = f'script_folder="{os.path.abspath(filepath)}"\n' + content | ||
save(file_location, content) | ||
|
||
def save_fish(self, file_location, generate_deactivate=True): | ||
filepath, filename = os.path.split(file_location) | ||
deactivate_file = os.path.join(filepath, "deactivate_{}".format(filename)) | ||
values = self._values.keys() | ||
if len(values) == 0: | ||
# Empty environment, nothing to restore (Easier to handle in Fish) | ||
deactivate = ("""echo "echo Nothing to restore" > {deactivate_file}""" | ||
.format(deactivate_file=deactivate_file)) | ||
else: | ||
deactivate = textwrap.dedent("""\ | ||
echo "echo Restoring environment" > "{deactivate_file}" | ||
for v in {vars} | ||
set is_defined "true" | ||
set value (printenv $v); or set is_defined "" | ||
if test -n "$value" -o -n "$is_defined" | ||
echo set -gx "$v" "$value" >> "{deactivate_file}" | ||
else | ||
echo set -ge "$v" >> "{deactivate_file}" | ||
end | ||
end | ||
""".format(deactivate_file=deactivate_file, vars=" ".join(self._values.keys()))) | ||
capture = textwrap.dedent("""\ | ||
{deactivate} | ||
""").format(deactivate=deactivate if generate_deactivate else "") | ||
result = [capture] | ||
for varname, varvalues in self._values.items(): | ||
value = varvalues.get_str("${name}", self._subsystem, pathsep=self._pathsep) | ||
value = value.replace('"', '\\"') | ||
if value: | ||
result.append('set -gx {} "{}"'.format(varname, value)) | ||
else: | ||
result.append('set -ge {}'.format(varname)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess it could be simplified by using |
||
|
||
content = "\n".join(result) | ||
content = relativize_generated_file(content, self._conanfile, "$script_folder") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't it possible to not use this and relativize paths as the other environment do? |
||
content = f'set script_folder "{os.path.abspath(filepath)}"\n' + content | ||
save(file_location, content) | ||
|
||
def save_script(self, filename): | ||
""" | ||
Saves a script file (bat, sh, ps1) with a launcher to set the environment. | ||
If the conf "tools.env.virtualenv:powershell" is set to True it will generate powershell | ||
launchers if Windows. | ||
|
||
If the conf "tools.env.virtualenv:fish" is set to True it will generate fish launchers. | ||
|
||
:param filename: Name of the file to generate. If the extension is provided, it will generate | ||
the launcher script for that extension, otherwise the format will be deduced | ||
checking if we are running inside Windows (checking also the subsystem) or not. | ||
|
@@ -534,18 +574,27 @@ def save_script(self, filename): | |
if ext: | ||
is_bat = ext == ".bat" | ||
is_ps1 = ext == ".ps1" | ||
is_fish = ext == ".fish" | ||
else: # Need to deduce it automatically | ||
is_bat = self._subsystem == WINDOWS | ||
is_ps1 = self._conanfile.conf.get("tools.env.virtualenv:powershell", check_type=bool) | ||
if is_ps1: | ||
is_fish = self._conanfile.conf.get("tools.env.virtualenv:fish", check_type=bool) | ||
memsharded marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if is_fish: | ||
filename = filename + ".fish" | ||
is_bat = False | ||
is_ps1 = False | ||
elif is_ps1: | ||
filename = filename + ".ps1" | ||
is_bat = False | ||
is_fish = False | ||
else: | ||
filename = filename + (".bat" if is_bat else ".sh") | ||
|
||
path = os.path.join(self._conanfile.generators_folder, filename) | ||
if is_bat: | ||
self.save_bat(path) | ||
elif is_fish: | ||
self.save_fish(path) | ||
elif is_ps1: | ||
self.save_ps1(path) | ||
else: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import os | ||
|
||
import pytest | ||
|
||
from conans.test.assets.genconanfile import GenConanfile | ||
from conans.test.utils.test_files import temp_folder | ||
from conans.test.utils.tools import TestClient | ||
from conans.util.files import save | ||
|
||
|
||
@pytest.mark.tool("fish") | ||
def test_virtualenv_fish(): | ||
cache_folder = os.path.join(temp_folder(), "[sub] folder") | ||
client = TestClient(cache_folder) | ||
conanfile = str(GenConanfile("pkg", "0.1")) | ||
conanfile += """ | ||
|
||
def package_info(self): | ||
self.buildenv_info.define_path("MYPATH1", "/path/to/ar") | ||
""" | ||
client.save({"conanfile.py": conanfile}) | ||
client.run("create .") | ||
save(client.cache.new_config_path, "tools.env.virtualenv:fish=True\n") | ||
client.save({"conanfile.py": GenConanfile("app", "0.1").with_requires("pkg/0.1")}) | ||
client.run("install . -s:a os=Linux") | ||
|
||
assert not os.path.exists(os.path.join(client.current_folder, "conanbuildenv.sh")) | ||
assert not os.path.exists(os.path.join(client.current_folder, "conanbuildenv.bat")) | ||
assert not os.path.exists(os.path.join(client.current_folder, "conanrunenv.sh")) | ||
assert not os.path.exists(os.path.join(client.current_folder, "conanrunenv.bat")) | ||
|
||
assert os.path.exists(os.path.join(client.current_folder, "conanbuildenv.fish")) | ||
assert os.path.exists(os.path.join(client.current_folder, "conanrunenv.fish")) | ||
|
||
with open(os.path.join(client.current_folder, "conanbuildenv.fish"), "r") as f: | ||
buildenv = f.read() | ||
assert 'set -gx MYPATH1 "/path/to/ar"' in buildenv | ||
|
||
client.run_command("fish -c 'source conanbuildenv.fish && set'") | ||
assert 'MYPATH1 /path/to/ar' in client.out | ||
|
||
client.run_command("fish -c 'source conanbuildenv.fish && set && source deactivate_conanbuildenv.fish && set'") | ||
assert str(client.out).count('MYPATH1 /path/to/ar') == 1 | ||
uilianries marked this conversation as resolved.
Show resolved
Hide resolved
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For new one, I'd try to do directly an in-memory or in-tmp-folder deactivate script rather than a local generated one.