Skip to content

Commit ebefa79

Browse files
authored
Fix Get-VirtualEnvs with user containing space in name (#20)
1 parent e31499c commit ebefa79

File tree

2 files changed

+144
-47
lines changed

2 files changed

+144
-47
lines changed

Changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog for VirtualEnvWrapper Powershell
22

3+
## 2020-11.17 (v0.1.2)
4+
* Fix bug on Get-VirtualEnvs for user with space in name
5+
* Fix uncomplete environment
6+
37
## 2019-11-10 (v0.1.1)
48
* Partially merge Swiffer PR
59
* Start tagging

VirtualEnvWrapper.psm1

Lines changed: 140 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22
# Python virtual env manager inspired by VirtualEnvWrapper
33
#
44
# Copyright (c) 2017 Regis FLORET
5-
#
5+
#
66
# Permission is hereby granted, free of charge, to any person obtaining a copy
77
# of this software and associated documentation files (the "Software"), to deal
88
# in the Software without restriction, including without limitation the rights
99
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1010
# copies of the Software, and to permit persons to whom the Software is
1111
# furnished to do so, subject to the following conditions:
12-
#
12+
#
1313
# The above copyright notice and this permission notice shall be included in all
1414
# copies or substantial portions of the Software.
15-
#
15+
#
1616
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1717
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1818
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -43,29 +43,29 @@ function Get-FullPyEnvPath($pypath) {
4343
return ("{0}\{1}" -f $WORKON_HOME, $pypath)
4444
}
4545

46-
#
46+
#
4747
# Display a formated error message
4848
#
4949
function Write-FormatedError($err) {
50-
Write-Host
50+
Write-Host
5151
Write-Host " ERROR: $err" -ForegroundColor Red
52-
Write-Host
52+
Write-Host
5353
}
5454

5555
#
5656
# Display a formated success messge
5757
#
5858
function Write-FormatedSuccess($err) {
59-
Write-Host
59+
Write-Host
6060
Write-Host " SUCCESS: $err" -ForegroundColor Green
61-
Write-Host
61+
Write-Host
6262
}
6363

6464
#
65-
# Retrieve the python version with the path the python exe regarding the version.
65+
# Retrieve the python version with the path the python exe regarding the version.
6666
# Python < 3.3 is for this function a Python 2 because the module venv comes with python 3.3
6767
#
68-
# Return the major version of python
68+
# Return the major version of python
6969
#
7070
function Get-PythonVersion($Python) {
7171
if (!(Test-Path $Python)) {
@@ -76,30 +76,30 @@ function Get-PythonVersion($Python) {
7676
$python_version = Invoke-Expression "& '$Python' --version 2>&1"
7777
if (!$Python -and !$python_version) {
7878
Write-Host "I don't find any Python version into your path" -ForegroundColor Red
79-
return
79+
return
8080
}
8181

8282
$is_version_2 = ($python_version -match "^Python\s2") -or ($python_version -match "^Python\s3.3")
8383
$is_version_3 = $python_version -match "^Python\s3" -and !$is_version_2
84-
84+
8585
if (!$is_version_2 -and !$is_version_3) {
8686
Write-FormatedError "Unknown Python Version expected Python 2 or Python 3 got $python_version"
87-
return
87+
return
8888
}
8989

9090
return $(if ($is_version_2) {"2"} else {"3"})
9191
}
9292

9393
#
94-
# Common command to create the Python Virtual Environement.
94+
# Common command to create the Python Virtual Environement.
9595
# $Command contains either the Py2 or Py3 command
9696
#
9797
function Invoke-CreatePyEnv($Command, $Name) {
9898
$NewEnv = Join-Path $WORKON_HOME $Name
9999
Write-Host "Creating virtual env... "
100-
100+
101101
Invoke-Expression "$Command '$NewEnv'"
102-
102+
103103
$VEnvScritpsPath = Join-Path $NewEnv "Scripts"
104104
$ActivatepPath = Join-Path $VEnvScritpsPath "activate.ps1"
105105
. $ActivatepPath
@@ -112,17 +112,18 @@ function Invoke-CreatePyEnv($Command, $Name) {
112112
#
113113
function New-Python2Env($Python, $Name) {
114114
$Command = (Join-Path (Join-Path (Split-Path $Python -Parent) "Scripts") "virtualenv.exe")
115+
115116
if ((Test-Path $Command) -eq $false) {
116117
Write-FormatedError "You must install virtualenv program to create the Python virtual environment '$Name'"
117-
return
118+
return
118119
}
119120

120121
Invoke-CreatePyEnv $Command $Name
121122
}
122-
123-
#
123+
124+
#
124125
# Create Python Environment using the venv module
125-
#
126+
#
126127
function New-Python3Env($Python, $Name) {
127128
if (!$Python) {
128129
$PythonExe = Find-Python
@@ -142,7 +143,7 @@ function Find-Python ($Python) {
142143
# The path contains the python executable
143144
if ($Python.EndsWith('python.exe'))
144145
{
145-
if (!(Test-Path $Python))
146+
if (!(Test-Path $Python))
146147
{
147148
return $false
148149
}
@@ -159,7 +160,7 @@ function Find-Python ($Python) {
159160
if (!(Test-Path $Python)) {
160161
return $false
161162
}
162-
163+
163164
# The pas is a directory path not a executable path
164165
$PythonExe = Join-Path $Python "python.exe"
165166
if (!(Test-Path $PythonExe)) {
@@ -174,21 +175,21 @@ function Find-Python ($Python) {
174175
#
175176
function New-PythonEnv($Python, $Name, $Packages, $Append) {
176177
$version = Get-PythonVersion $Python
177-
178+
178179
BackupPath
179180
if ($Append) {
180181
$Env:PYTHONPATH = "$Append;$($Env:PYTHONPATH)"
181182
}
182183

183184
if ($Version -eq "2") {
184-
New-Python2Env -Python $Python -Name $Name
185+
New-Python2Env -Python $Python -Name $Name
185186
} elseif ($Version -eq "3") {
186-
New-Python3Env -Python $Python -Name $Name
187+
New-Python3Env -Python $Python -Name $Name
187188
} else {
188189
Write-FormatedError "This is the debug voice. I expected a Python version, got $Version"
189190
RestorePath
190-
191-
}
191+
192+
}
192193
}
193194

194195
function BackupPath {
@@ -200,7 +201,7 @@ function RestorePath {
200201
$Env:Path = $Env:OLD_SYSTEM_PATH
201202
}
202203

203-
#
204+
#
204205
# Test if there's currently a python virtual env
205206
#
206207
function Get-IsInPythonVenv($Name) {
@@ -245,17 +246,18 @@ function Workon {
245246
Write-FormatedError "Enable to find the activation script. You Python environment $Name seems compromized"
246247
return
247248
}
248-
249-
. $activate_path
249+
250+
Load-Module $activate_path
250251

251252
$Env:OLD_PYTHON_PATH = $Env:PYTHON_PATH
252253
$Env:VIRTUAL_ENV = "$new_pyenv"
253254
}
254255

255-
#
256-
# Create a new virtual environment.
257256
#
258-
function New-VirtualEnv {
257+
# Create a new virtual environment.
258+
#
259+
function New-VirtualEnv()
260+
{
259261
Param(
260262
[Parameter(HelpMessage="The virtual env name")]
261263
[string]$Name,
@@ -302,10 +304,10 @@ function New-VirtualEnv {
302304
return
303305
}
304306

305-
New-PythonEnv -Python $PythonRealPath -Name $Name
306-
307+
New-PythonEnv -Python $PythonRealPath -Name $Name
308+
307309
foreach($Package in $Packages) {
308-
Invoke-Expression "$WORKON_HOME\$Name\Scripts\pip.exe install $Package"
310+
Invoke-Expression "$WORKON_HOME\$Name\Scripts\pip.exe install $Package"
309311
}
310312

311313

@@ -317,7 +319,6 @@ function New-VirtualEnv {
317319

318320
Invoke-Expression "$WORKON_HOME\$Name\Scripts\pip.exe install -r $Requirement"
319321
}
320-
321322
}
322323

323324

@@ -348,14 +349,31 @@ function Get-VirtualEnvs {
348349
Write-Host
349350

350351
if ($children.Length) {
352+
$failed = [System.Collections.ArrayList]@()
353+
351354
for($i = 0; $i -lt $children.Length; $i++) {
352355
$child = $children[$i]
353-
$PythonVersion = (((Invoke-Expression ("$WORKON_HOME\{0}\Scripts\Python.exe --version 2>&1" -f $child)) -replace "`r|`n","") -Split " ")[1]
354-
Write-host ("`t{0,-30}{1,-15}" -f $child,$PythonVersion)
356+
try {
357+
$PythonVersion = (((Invoke-Expression ("$WORKON_HOME\{0}\Scripts\Python.exe --version 2>&1" -f "$child")) -replace "`r|`n","") -Split " ")[1]
358+
Write-host ("`t{0,-30}{1,-15}" -f $child,$PythonVersion)
359+
} catch {
360+
$failed += $child
361+
}
355362
}
356363
} else {
357364
Write-Host "`tNo Python Environments"
358365
}
366+
if ($failed.Length -gt 0) {
367+
Write-Host
368+
Write-Host "`tAdditionnaly, one or more environments failed to be listed"
369+
Write-Host "`t=========================================================="
370+
Write-Host
371+
foreach ($item in $failed) {
372+
Write-Host "`t$item"
373+
}
374+
}
375+
376+
359377
Write-Host
360378
}
361379

@@ -366,7 +384,7 @@ function Remove-VirtualEnv {
366384
Param(
367385
[string]$Name
368386
)
369-
387+
370388
if ((Get-IsInPythonVenv $Name) -eq $true) {
371389
Write-FormatedError "You want to destroy the Virtual Env you are in. Please type 'deactivate' before to dispose the environment before"
372390
return
@@ -379,26 +397,101 @@ function Remove-VirtualEnv {
379397

380398
$full_path = Get-FullPyEnvPath $Name
381399
if ((Test-Path $full_path) -eq $true) {
382-
Remove-Item -Path $full_path -Recurse
400+
Remove-Item -Path $full_path -Recurse
383401
Write-FormatedSuccess "$Name was deleted permanently"
384402
} else {
385403
Write-FormatedError "$Name not found"
386404
}
387405
}
388406

389-
#
390-
# Get the current version of VirtualEnvWrapper
391-
#
407+
<#
408+
.Synopsis
409+
Get the current version of VirtualEnvWrapper
410+
#>
392411
function Get-VirtualEnvVersion() {
393412
Write-Host "Version $Version"
394413
}
395414

415+
<#
416+
.Synopsis
417+
Create a temporary environment.
418+
#>
419+
function New-TemporaryVirtualEnv() {
420+
Param(
421+
[Parameter(HelpMessage="Change directory into the newly created virtual environment")]
422+
[alias("c")]
423+
[switch]
424+
$Cd = $False,
425+
426+
[Parameter(HelpMessage="Don't change directory")]
427+
[alias("n")]
428+
[switch]$NoCd = $false,
429+
430+
# Reimplement New-VirtualEnv parameters
431+
[Parameter(HelpMessage="The requirements file")]
432+
[alias("r")]
433+
[string]$Requirement,
434+
435+
[Parameter(HelpMessage="The Python directory where the python.exe lives")]
436+
[string]$Python,
437+
438+
[Parameter(HelpMessage="The package to install. Repeat the parameter for more than one")]
439+
[alias("i")]
440+
[string[]]$Packages,
441+
442+
[Parameter(HelpMessage="Associate an existing project directory to the new environment")]
443+
[alias("a")]
444+
[string]$Associate
445+
)
446+
447+
Begin
448+
{
449+
if ($NoCd -eq $true) {
450+
$Cd = $false;
451+
}
452+
}
453+
454+
Process
455+
{
456+
$uuid = (Invoke-Expression "python -c 'import uuid; print(str(uuid.uuid4()))'")
457+
$dest_dir = "$WORKON_HOME/$uuid"
458+
459+
# Recompose command line
460+
$args = ""
461+
foreach($param in $PSBoundParameters.GetEnumerator())
462+
{
463+
$args += (" -{0} {1}" -f $param.Key,$param.Value)
464+
}
465+
466+
Invoke-Expression "New-VirtualEnv $uuid $args"
467+
468+
$message = "This is a temporary environment. It will be deleted when you run 'deactivate'."
469+
Write-Host $message
470+
$message | Out-File -FilePath "$dest_dir/README.tmpenv"
471+
472+
# Write deactivation file. See Workon rewriting deactivate feature
473+
$post_deactivate_file_content = @"
474+
if ((est-Path -Path `"$dest_dir/README.tmpenv`") {
475+
Write-Host `"Removing temporary environment $uuid`"
476+
# Change the location else MS Windows will refuse to remove the directory
477+
Set-Location `"$WORKON_HOME`"
478+
Remove-VirtualEnv $uuid
479+
}
480+
"@
481+
$post_deactivate_file_content | Out-File -FilePath "$WORKON_HOME/$uuid/postdeactivate.ps1"
482+
483+
if ($Cd -Eq $true) {
484+
Set-Location -Path "$WORKON_HOME/$uuid"
485+
}
486+
}
487+
}
488+
396489
#
397490
# Powershell alias for naming convention
398491
#
399-
Set-Alias lsvirtualenv Get-VirtualEnvs
400-
Set-Alias rmvirtualenv Remove-VirtualEnv
492+
Set-Alias lsvirtualenv Get-VirtualEnvs
493+
Set-Alias rmvirtualenv Remove-VirtualEnv
401494
Set-Alias mkvirtualenv New-VirtualEnv
402-
495+
Set-Alias mktmpenv New-TemporaryVirtualEnv
403496

404497
Write-Host "Virtual Env Wrapper for Powershell activated"

0 commit comments

Comments
 (0)