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

Add CLI arg to make virtualenvs not autogenerate if needed #16935

Merged
merged 11 commits into from
Sep 24, 2024
4 changes: 2 additions & 2 deletions conan/api/subapi/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def install_sources(self, graph, remotes):

# TODO: Look for a better name
def install_consumer(self, deps_graph, generators=None, source_folder=None, output_folder=None,
deploy=False, deploy_package=None, deploy_folder=None):
deploy=False, deploy_package=None, deploy_folder=None, generate_virtualenvs=None):
""" Once a dependency graph has been installed, there are things to be done, like invoking
generators for the root consumer.
This is necessary for example for conanfile.txt/py, or for "conan install <ref> -g
Expand Down Expand Up @@ -88,4 +88,4 @@ def install_consumer(self, deps_graph, generators=None, source_folder=None, outp
final_generators.append(gen)
conanfile.generators = final_generators
app = ConanApp(self.conan_api)
write_generators(conanfile, app)
write_generators(conanfile, app, generate_virtualenvs=generate_virtualenvs)
5 changes: 4 additions & 1 deletion conan/cli/commands/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ def install(conan_api, parser, *args):
"the provided patterns")
parser.add_argument("--build-require", action='store_true', default=False,
help='Whether the provided path is a build-require')
parser.add_argument("--generate-virtualenvs", default="auto", choices=["auto", "never", "NotEmpty"],
AbrilRBS marked this conversation as resolved.
Show resolved Hide resolved
AbrilRBS marked this conversation as resolved.
Show resolved Hide resolved
help="Generate virtual environment files for the root")
args = parser.parse_args(*args)
validate_common_graph_args(args)
# basic paths
Expand Down Expand Up @@ -74,7 +76,8 @@ def install(conan_api, parser, *args):
ConanOutput().title("Finalizing install (deploy, generators)")
conan_api.install.install_consumer(deps_graph, args.generator, source_folder, output_folder,
deploy=args.deployer, deploy_package=args.deployer_package,
deploy_folder=args.deployer_folder)
deploy_folder=args.deployer_folder,
generate_virtualenvs=args.generate_virtualenvs)
ConanOutput().success("Install finished successfully")

# Update lockfile if necessary
Expand Down
28 changes: 15 additions & 13 deletions conan/internal/api/install/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def load_cache_generators(path):
return result


def write_generators(conanfile, app):
def write_generators(conanfile, app, generate_virtualenvs="auto"):
new_gen_folder = conanfile.generators_folder
_receive_conf(conanfile)

Expand Down Expand Up @@ -118,18 +118,20 @@ def write_generators(conanfile, app):
with conanfile_exception_formatter(conanfile, "generate"):
conanfile.generate()

if conanfile.virtualbuildenv:
mkdir(new_gen_folder)
with chdir(new_gen_folder):
from conan.tools.env.virtualbuildenv import VirtualBuildEnv
env = VirtualBuildEnv(conanfile)
env.generate()
if conanfile.virtualrunenv:
mkdir(new_gen_folder)
with chdir(new_gen_folder):
from conan.tools.env import VirtualRunEnv
env = VirtualRunEnv(conanfile)
env.generate()
if generate_virtualenvs == "auto":
if conanfile.virtualbuildenv:
mkdir(new_gen_folder)
with chdir(new_gen_folder):
from conan.tools.env.virtualbuildenv import VirtualBuildEnv
env = VirtualBuildEnv(conanfile)
# TODO: Check length of env.vars().keys() when adding NotEmpty
env.generate()
if conanfile.virtualrunenv:
mkdir(new_gen_folder)
with chdir(new_gen_folder):
from conan.tools.env import VirtualRunEnv
env = VirtualRunEnv(conanfile)
env.generate()

_generate_aggregated_env(conanfile)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is one scenario that this will still produce env-files: if the build system is for example msvc+ninja, the conanvcvars to activate the Visual prompt will be there, and conanbuild.bat will be generated. is this expected? It is true that in certain conditions like using VSCode, the IDE can also manage vcvars, so this might be included in the if envs_generation is None?


Expand Down
22 changes: 13 additions & 9 deletions test/integration/toolchains/env/test_virtualenv_default_apply.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,32 @@ def package_info(self):
return client


@pytest.mark.parametrize("scope", ["build", "run"])
@pytest.mark.parametrize("default_virtualenv", [True, False, None])
def test_virtualenv_deactivated(client, default_virtualenv):
format_str = {True: "virtualbuildenv = True",
False: "virtualbuildenv = False",
@pytest.mark.parametrize("cli_value", ["auto", "never"])
def test_virtualenv_deactivated(client, scope, default_virtualenv, cli_value):
format_str = {True: f"virtual{scope}env = True",
False: f"virtual{scope}env = False",
None: ""}[default_virtualenv]
conanfile = textwrap.dedent("""
from conan import ConanFile
import platform

class ConanFileToolsTest(ConanFile):
{}
requires = "foo/1.0"
""").format(format_str)

client.save({"conanfile.py": conanfile})
client.run("install . ")
cli_extra = f"--generate-virtualenvs={cli_value}" if cli_value is not None else ""
client.run(f"install . {cli_extra}")
extension = "bat" if platform.system() == "Windows" else "sh"
exists_file = os.path.exists(os.path.join(client.current_folder,
"conanbuildenv.{}".format(extension)))
if default_virtualenv is True or default_virtualenv is None:
exists_file = os.path.exists(os.path.join(client.current_folder, f"conan{scope}env.{extension}"))

should_exist = cli_value != "never" and (default_virtualenv is None or default_virtualenv)

if should_exist:
assert exists_file
elif default_virtualenv is False:
else:
assert not exists_file


Expand Down