diff --git a/generators/VirtualPythonEnv.py b/generators/VirtualPythonEnv.py index 3709803..329c494 100644 --- a/generators/VirtualPythonEnv.py +++ b/generators/VirtualPythonEnv.py @@ -23,13 +23,7 @@ class VirtualPythonEnv(Generator): @property def filename(self): - filepath = str(Path(self.conanfile.generators_folder).joinpath("activate")) - if self.conanfile.settings.get_safe("os") == "Windows": - if self.conanfile.conf.get("tools.env.virtualenv:powershell", check_type = bool): - filepath += ".ps1" - else: - filepath += ".bat" - return filepath + pass @property def content(self): @@ -79,7 +73,6 @@ class VirtualPythonEnv(Generator): env.prepend_path("PATH", os.path.join(self.conanfile.build_folder, self._venv_path)) env.prepend_path("PYTHONPATH", pythonpath) env.unset("PYTHONHOME") - env.define("PS1", f"({self.conanfile.name}) ${{PS1:-}}") envvars = env.vars(self.conanfile, scope = "run") @@ -116,14 +109,21 @@ class VirtualPythonEnv(Generator): self.conanfile.output.warn(f"Failed to find pip requirement file: {requirements_txt_path}") # Generate the Python Virtual Environment Script - template = Template("""\ -deactivate() -{ -{% for k, v in envvars.items() %}export {{ k }}=$OLD_{{ k }} -unset OLD_{{ k }} -{% endfor %}} - -{% for k, v in envvars.items() %}export OLD_{{ k }}=${{ k }} -export {{ k }}={{ v }} -{% endfor %}""") - return template.render(envvars = envvars) + with open(Path(__file__).parent.joinpath("VirtualPythonEnvResources", "activate.bat.jinja"), "r") as f: + activate_bat = Template(f.read()).render(envvars = envvars, prompt = self.conanfile.name) + + with open(Path(__file__).parent.joinpath("VirtualPythonEnvResources", "deactivate.bat.jinja"), "r") as f: + deactivate_bat = Template(f.read()).render(envvars = envvars) + + with open(Path(__file__).parent.joinpath("VirtualPythonEnvResources", "Activate.ps1.jinja"), "r") as f: + activate_ps1 = Template(f.read()).render(envvars = envvars, prompt = self.conanfile.name) + + with open(Path(__file__).parent.joinpath("VirtualPythonEnvResources", "activate.jinja"), "r") as f: + activate_sh = Template(f.read()).render(envvars = envvars, prompt = self.conanfile.name) + + return { + str(Path(self.conanfile.build_folder, self._venv_path, "activate.bat")): activate_bat, + str(Path(self.conanfile.build_folder, self._venv_path, "deactivate.bat.jinja")): deactivate_bat, + str(Path(self.conanfile.build_folder, self._venv_path, "Activate.ps1")): activate_ps1, + str(Path(self.conanfile.build_folder, self._venv_path, "activate")): activate_sh + } diff --git a/generators/VirtualPythonEnvResources/Activate.ps1.jinja b/generators/VirtualPythonEnvResources/Activate.ps1.jinja new file mode 100644 index 0000000..1c5c294 --- /dev/null +++ b/generators/VirtualPythonEnvResources/Activate.ps1.jinja @@ -0,0 +1,77 @@ +<# +.Synopsis +Activate a Python virtual environment for the current PowerShell session. + +.Notes +On Windows, it may be required to enable this Activate.ps1 script by setting the +execution policy for the user. You can do this by issuing the following PowerShell +command: + +PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +For more information on Execution Policies: +https://go.microsoft.com/fwlink/?LinkID=135170 + +#> + +<# +.Synopsis +Remove all shell session elements added by the Activate script, including the +addition of the virtual environment's Python executable from the beginning of +the PATH variable. + +.Parameter NonDestructive +If present, do not remove this function from the global namespace for the +session. + +#> +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + + # The prior prompt: + if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { + Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt + Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT + } + + if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { + Remove-Item -Path env:VIRTUAL_ENV_PROMPT + } + + # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: + if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { + Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force + } + + {% for var, value in envvars.items() %}if (Test-Path -Path Env:_OLD_{{ var }}) { + Copy-Item -Path Env:_OLD_{{ var }} -Destination Env:{{ var }} + Remove-Item -Path Env:_OLD_{{ var }} + } else { + if (Test-Path -Path Env:{{ var }}) { + Remove-Item -Path Env:{{ var }} + } + } + {% endfor %} + # Leave deactivate function in the global namespace if requested: + if (-not $NonDestructive) { + Remove-Item -Path function:deactivate + } +} + +Copy-Item -Path Env:PATH -Destination Env:_OLD_PATH + +{% for var, value in envvars.items() %}if (Test-Path -Path Env:{{ var }}) { + Copy-Item -Path Env:{{ var }} -Destination Env:_OLD_{{ var }} +} +$Env:{{ var }} = "{{ value }}" +{% endfor %} + +function global:_OLD_VIRTUAL_PROMPT { "" } +Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT +New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value {{ prompt }} + +function global:prompt { + Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " + _OLD_VIRTUAL_PROMPT +} +$env:VIRTUAL_ENV_PROMPT = "{{ prompt }}" diff --git a/generators/VirtualPythonEnvResources/activate.bat.jinja b/generators/VirtualPythonEnvResources/activate.bat.jinja new file mode 100644 index 0000000..4b1374e --- /dev/null +++ b/generators/VirtualPythonEnvResources/activate.bat.jinja @@ -0,0 +1,19 @@ +@echo off + +rem This file is UTF-8 encoded, so we need to update the current code page while executing it +for /f "tokens=2 delims=:." %%a in ('"%SystemRoot%\System32\chcp.com"') do ( + set _OLD_CODEPAGE=%%a +) +if defined _OLD_CODEPAGE ( + "%SystemRoot%\System32\chcp.com" 65001 > nul +) + +{% for var, value in envvars.items() %}set _OLD_{{ var }}=%PATH% +set {{ var }}={{ value }} +{% endfor %} +set PATH=%VIRTUAL_ENV%\Scripts;%PATH% +:END +if defined _OLD_CODEPAGE ( + "%SystemRoot%\System32\chcp.com" %_OLD_CODEPAGE% > nul + set _OLD_CODEPAGE= +) diff --git a/generators/VirtualPythonEnvResources/activate.jinja b/generators/VirtualPythonEnvResources/activate.jinja new file mode 100644 index 0000000..011a1d7 --- /dev/null +++ b/generators/VirtualPythonEnvResources/activate.jinja @@ -0,0 +1,32 @@ +# This file must be used with "source bin/activate" *from bash* +# you cannot run it directly + +deactivate () { + # reset old environment variables + {% for var in envvars.keys() %}if [ -n "$_OLD_{{ var }}" ] ; then + {{ var }}="$_OLD_{{ var }}" + export {{ var }} + unset _OLD_{{ var }} + then + unset {{ var }} + fi + {% endfor %} + + if [ -n "${_OLD_VIRTUAL_PS1}" ] ; then + PS1="${_OLD_VIRTUAL_PS1}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi +} + +{% for var, value in envvars.items() %}if [ -n "${{ var }}" ] ; then + _OLD_{{ var }}="${{ var }}" + export _OLD_{{ var }} +fi +{{ var }}="{{ value }}" +export {{ var }} +{% endfor %} + +_OLD_VIRTUAL_PS1="${PS1:-}" +PS1="({{ prompt }}) ${PS1:-}" +export PS1 diff --git a/generators/VirtualPythonEnvResources/deactivate.bat.jinja b/generators/VirtualPythonEnvResources/deactivate.bat.jinja new file mode 100644 index 0000000..3c6a22e --- /dev/null +++ b/generators/VirtualPythonEnvResources/deactivate.bat.jinja @@ -0,0 +1,9 @@ +@echo off + +{% for var in envvars.keys() %}if defined _OLD_{{ var }} ( + set "{{ var }}=%_OLD_{{ var }}%" +) +set _OLD_{{ var }}= +{% endfor %} + +:END