Skip to content

Commit

Permalink
Merge pull request #82 from davidmarble/mkvirtualenvopts
Browse files Browse the repository at this point in the history
Implement -a, -i, and -r options to mkvirtualenv.
This solves #60, part of #67 (mkvirtualenv without parameters is now the same as mkvirtualenv -h), and
#68.
  • Loading branch information
thebjorn authored Aug 11, 2017
2 parents 791344c + 55eff9d commit 5c812b7
Show file tree
Hide file tree
Showing 15 changed files with 502 additions and 60 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ dist
Include
Lib
virtualenvwrapper_win.egg-info
tests/logfile.txt
7 changes: 7 additions & 0 deletions devenv.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@echo off
::
:: Add scripts and tests directory to front of path.
::
set "VIRTUALENV_WRAPPER_SOURCE=%~dp0%"

path %VIRTUALENV_WRAPPER_SOURCE%scripts;%VIRTUALENV_WRAPPER_SOURCE%tests;%PATH%
277 changes: 225 additions & 52 deletions scripts/mkvirtualenv.bat
Original file line number Diff line number Diff line change
@@ -1,62 +1,173 @@
@echo off
:: Create a new environment, in the WORKON_HOME.
::
:: Syntax:
::
:: mkvirtualenv [-a project_path] [-i package] [-r requirements_file] [virtualenv options] %venvwrapper.envname%
::
:: All command line options except -a, -i, -r, and -h are passed directly
:: to virtualenv. The new environment is automatically activated after being
:: initialized.
::
:: The -a option can be used to associate an existing project directory
:: with the new environment.
::
:: The -i option can be used to install one or more packages (by repeating
:: the option) after the environment is created.
::
:: The -r option can be used to specify a text file listing packages to be
:: installed. The argument value is passed to pip -r to be installed.
::

if [%1]==[] goto USAGE
goto MKVIRTUALENV
:defaults
set "venvwrapper.original_args=%*"
set "venvwrapper.default_workon_home=%USERPROFILE%\Envs"
set "venvwrapper.scriptsdir=Scripts"

:USAGE
echo.
echo. Pass a name to create a new virtualenv
goto END
:: make sure WORKON_HOME has a useful value
if not defined WORKON_HOME set "WORKON_HOME=%venvwrapper.default_workon_home%"
set "venvwrapper.workon_home=%WORKON_HOME%"

:MKVIRTUALENV
if not defined WORKON_HOME (
set "WORKON_HOME=%USERPROFILE%\Envs"
if defined VIRTUALENV_EXECUTABLE (
set "venvwrapper.virtualenv_executable=%VIRTUALENV_EXECUTABLE%"
) else (
set "venvwrapper.virtualenv_executable=virtualenv"
)

:: print usage if no arguments given
if [%1]==[] goto:usage


setlocal
:: virtualenv options that take a paramter
set "virualenv_param_options=-p --python --extra-search-dir --prompt"

set /a debug=0
:getopts
set /a ouropt=0
:: --debug and ---stop xxx should be first on the command line to get most effect
if [%1]==[---stop] set "stop=%2" & shift & shift
if [%1]==[--debug] (
echo time: %TIME%
set /a ouropt=1
set /a debug=1
:: add verbose mode to virtualenv when in debug mode
set "venvargs=%venvargs% -v"
)
if [%1]==[-h] goto:usage
if [%1]==[--help] goto:usage

if [%1]==[-a] (
set /a ouropt=1
set "project_path=%2"
shift
)

if [%1]==[-r] (
set /a ouropt=1
set "requirements_file=%2"
shift
)

if [%1]==[-i] (
set /a ouropt=1
set "install_packages=%install_packages% %2"
shift
)

set "cur=%1"
:: is cur in virualenv_param_options?
call set filteredvar=%%virualenv_param_options:*%cur%=%%

if %ouropt% equ 0 (
if "%cur:~0,1%"=="-" (
:: starts with a dash (we found an option)
if not "%filteredvar%"=="%virualenv_param_options%" (
:: this is one of virtualenv's options that take a parameter
set "venvargs=%venvargs% %1=%2"
shift
) else (
set "venvargs=%venvargs% %1"
)
) else (
set "envname=%1"
)
)

shift
if not [%1]==[] goto:getopts
(endlocal & rem export from setlocal block
set "venvwrapper.project_path=%project_path%"
set "venvwrapper.requirements_file=%requirements_file%"
set "venvwrapper.install_packages=%install_packages%"
set "venvwrapper.virtualenv_args=%venvargs%"
set "venvwrapper.envname=%envname%"
set "venvwrapper.stop=%stop%"
set /a venvwrapper.debug=%debug%
)

if defined VIRTUAL_ENV (
call "%VIRTUAL_ENV%\Scripts\deactivate.bat"
if %venvwrapper.debug% equ 1 (
echo ^<DEBUG options="%venvwrapper.original_args%"^>
set venvwrapper.
echo ^</DEBUG^>
if "%venvwrapper.stop%"=="after-argparse" goto:cleanup
)

if defined PYTHONHOME (
set "PYHOME=%PYTHONHOME%"
goto MAIN
if "%venvwrapper.envname%"=="" (
call :error_message You must specify a name for the virtualenv
call :cleanup
exit /b 1
)
for /f "usebackq tokens=*" %%a in (`python.exe -c "import sys;print(sys.exec_prefix)"`) do (
set "PYHOME=%%a"

:: exit any current virtualenv..
if defined VIRTUAL_ENV (
call "%VIRTUAL_ENV%\%venvwrapper.scriptsdir%\deactivate.bat"
)

:MAIN
REM Copy all arguments, then set ENVNAME to the last argument
set "ARGS=%*"
call :GET_ENVNAME %*

pushd "%WORKON_HOME%" 2>NUL && popd
if errorlevel 1 (
if not exist "%WORKON_HOME%\*" (
echo. %WORKON_HOME% is not a directory, creating
:: try making it.. (let the user see any error messages)
mkdir "%WORKON_HOME%"
if errorlevel 1 (
call :error_message couldn't create directory.
call :cleanup
exit /b 2
)
)

pushd "%WORKON_HOME%\%ENVNAME%" 2>NUL && popd
if not errorlevel 1 (
echo.
echo. virtualenv "%ENVNAME%" already exists
goto END
:: make sure we know where the Scripts directory is located
if defined PYTHONHOME (
set "venvwrapper.pyhome=%PYTHONHOME%"
) else (
for /f "usebackq tokens=*" %%a in (`python.exe -c "import sys;print(sys.exec_prefix)"`) do (
set "venvwrapper.pyhome=%%a"
)
)

:: Check if venv exists (could be a file name, but don't care - still can't use it)
if exist %WORKON_HOME%\%venvwrapper.envname% (
call :error_message virtualenv "%venvwrapper.envname%" already exists
call :cleanup
exit /b 3
)

pushd "%WORKON_HOME%"
REM As of Python 2.7, calling virtualenv.exe causes a new window to open,
REM so call the script directly
REM recent versions of virtualenv does not contain virtualenv-script.py..
if exist "%PYHOME%\Scripts\virtualenv-script.py" (
python.exe "%PYHOME%\Scripts\virtualenv-script.py" %ARGS%
) else (
virtualenv.exe %ARGS%
if %venvwrapper.debug% equ 1 (
echo ^<DEBUG calling-virtualenv^>
set venvwrapper.
echo %venvwrapper.virtualenv_executable% %venvwrapper.virtualenv_args% %venvwrapper.envname%
echo ^</DEBUG^>
if "%venvwrapper.stop%"=="before-virtualenv" goto:cleanup
)
:: call virtualenv
pushd "%WORKON_HOME%"
%venvwrapper.virtualenv_executable% %venvwrapper.virtualenv_args% %venvwrapper.envname%
popd
if errorlevel 2 goto END
if errorlevel 2 goto:cleanup

REM In activate.bat, keep track of PYTHONPATH.
REM This should be a change adopted by virtualenv.
>>"%WORKON_HOME%\%ENVNAME%\Scripts\activate.bat" (
:: In activate.bat, keep track of PYTHONPATH.
:: This should be a change adopted by virtualenv.
>>"%WORKON_HOME%\%venvwrapper.envname%\Scripts\activate.bat" (
echo.:: In case user makes changes to PYTHONPATH
echo.if defined _OLD_VIRTUAL_PYTHONPATH (
echo. set "PYTHONPATH=%%_OLD_VIRTUAL_PYTHONPATH%%"
Expand All @@ -65,33 +176,95 @@ REM This should be a change adopted by virtualenv.
echo.^)
)

REM In deactivate.bat, reset PYTHONPATH to its former value
>>"%WORKON_HOME%\%ENVNAME%\Scripts\deactivate.bat" (
:: In deactivate.bat, reset PYTHONPATH to its former value
>>"%WORKON_HOME%\%venvwrapper.envname%\Scripts\deactivate.bat" (
echo.
echo.if defined _OLD_VIRTUAL_PYTHONPATH (
echo. set "PYTHONPATH=%%_OLD_VIRTUAL_PYTHONPATH%%"
echo.^)
)

call "%WORKON_HOME%\%ENVNAME%\Scripts\activate.bat"
call "%WORKON_HOME%\%venvwrapper.envname%\Scripts\activate.bat"

:: handle -a
if not "%venvwrapper.project_path%"=="" call setprojectdir.bat "%venvwrapper.project_path%"

REM Run postmkvirtualenv.bat
:: handle -i (can be multiple)
if not "%venvwrapper.install_packages%"=="" call :pipinstall "%venvwrapper.install_packages%"

:: handle -r
if not "%venvwrapper.requirements_file%"=="" (
call %VIRTUAL_ENV%\Scripts\pip install -r "%venvwrapper.requirements_file%"
)

:: Run postmkvirtualenv.bat
if defined VIRTUALENVWRAPPER_HOOK_DIR (
if exist "%VIRTUALENVWRAPPER_HOOK_DIR%\postmkvirtualenv.bat" (
call "%VIRTUALENVWRAPPER_HOOK_DIR%\postmkvirtualenv.bat"
)
)


goto END
goto:cleanup

:pipinstall
setlocal
set packages=%~1
for /F "tokens=1*" %%g in ("%packages%") do (
:: XXX should use --disable-pip-version-check (but only if pip version >= 6)
if not "%%g"=="" call %VIRTUAL_ENV%\Scripts\pip install %%g
if not "%%h"=="" call :pipinstall "%%h"
)
endlocal
goto:eof

:GET_ENVNAME
set "ENVNAME=%~1"
shift
if not "%~1"=="" goto GET_ENVNAME
goto :eof
:error_message
echo.
echo. ERROR: %*
echo.
if %venvwrapper.debug% equ 1 (
echo ^<DEBUG error-message^>
echo %*
echo ^</DEBUG^>
)
goto:eof

:debug_message
if %venvwrapper.debug% equ 1 (
echo ^<DEBUG message^>
echo %*
echo ^</DEBUG^>
)
goto:eof


:usage
echo.
echo.Usage: mkvirtualenv [mkvirtualenv-options] [virtualenv-options] DEST_DIR
echo.
echo. DEST_DIR The name of the envirnment to create (must be last).
echo.
echo.The new environment is automatically activated after being
echo.initialized.
echo.
echo.mkvirtualenv options:
echo. -a project_path Associate existing path as project directory
echo. -i package Install package in new environment. This option
echo. can be repeated to install more than one package.
echo -r requirements_file requirements_file is passed to
echo. pip install -r requirements_file
echo.
echo. NOTE: all mkvirtualenv-options must come before virtualenv-options!
echo.
echo.Options not specified above are passed to virtualenv:
echo.
echo %venvwrapper.virtualenv_executable% -h
call %venvwrapper.virtualenv_executable% -h
echo.
:: fall through

:END
set PYHOME=
set ENVNAME=
:cleanup
if %venvwrapper.debug% equ 1 echo time: %TIME%
:: clear any variables that shouldn't escape
for /f "usebackq delims==" %%v in (`set venvwrapper.`) do @set "%%v="
goto:eof
6 changes: 4 additions & 2 deletions scripts/setprojectdir.bat
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
@echo off
set "__callingpath=%CALLINGPATH%"
set "__projdir=%PROJDIR%"

if [%1]==[] goto USAGE
goto SETPROJECTDIR
Expand Down Expand Up @@ -44,5 +46,5 @@ set /p ="%PROJDIR%">"%VIRTUAL_ENV%\%VIRTUALENVWRAPPER_PROJECT_FILENAME%" <NUL
call add2virtualenv.bat "%PROJDIR%"

:END
set CALLINGPATH=
set PROJDIR=
set "CALLINGPATH=%__callingpath%"
set "PROJDIR=%__projdir%"
6 changes: 6 additions & 0 deletions tests/_log.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@echo off
set config.log.output=%TMP%\config.log.output%RANDOM%.bat
python -u _log.py %* > %config.log.output%
call %config.log.output%
del %config.log.output%
set config.log.output=
Loading

0 comments on commit 5c812b7

Please sign in to comment.