1년 넘게 setV는 제 bash_scripts 프로젝트 안에 숨겨져 있었는데, 이제 공개할 때가 되었다고 생각합니다. setV는 virtualenvwrapper의 대안으로 사용하는 Bash 함수로, 다음과 같은 기본 기능들을 제공합니다.
- 기본적으로 Python 3 사용
- 새로운 가상 환경 생성
- -p(또는 --python) 옵션으로 사용자 지정 Python 경로를 이용한 가상 환경 생성
- 기존 가상 환경 삭제
- 모든 가상 환경 목록 조회
- 탭(Tab) 자동 완성 지원 — 가상 환경 이름이 기억나지 않을 때 유용
설치 방법
setV를 설치하려면 먼저 설치 스크립트를 다운로드합니다.
curl https://gitlab.com/psachin/setV/raw/master/install.sh
스크립트 내용을 확인한 뒤 실행합니다.
sh ./install.sh
setV 설치 시, 설치 스크립트가 ~/.bashrc 또는 ~/.bash_profile 파일을 소싱(source)하도록 안내합니다. 반드시 이 과정을 수행해야 합니다.
사용 방법
기본 명령어는 setv입니다.
새 가상 환경 만들기
setv --new rango # setv -n rango
# 또는 사용자 지정 Python 바이너리 경로를 사용하는 경우
setv --new --python /opt/python/python3 rango # setv -n -p /opt/python/python3 rango
기존 환경 활성화하기
setv VIRTUAL_ENVIRONMENT_NAME
# 예시
setv rango
모든 가상 환경 목록 보기
setv --list
# 또는
setv [TAB] [TAB]
가상 환경 삭제하기
setv --delete rango
다른 가상 환경으로 전환하기
# 현재 'rango' 환경에 있다면, 아래 명령으로 'tango'로 전환할 수 있습니다.
setv tango
탭 자동 완성
가상 환경 이름이 정확히 기억나지 않아도 괜찮습니다. Bash의 탭 자동 완성처럼 가상 환경 이름에 대한 자동 완성이 작동합니다.
참여하기
setV는 GNU GPLv3 라이선스로 배포되는 오픈소스 프로젝트이며, 언제든 기여를 환영합니다. 자세한 내용은 GitLab 저장소에 있는 setV README의 Contribute 섹션을 참고하세요.
setV 스크립트 전체 코드
#!/usr/bin/env bash
# setV - A Lightweight Python virtual environment manager.
# Author: Sachin (psachin) <iclcoolster@gmail.com>
# Author's URL: https://psachin.gitlab.io/about
#
# License: GNU GPL v3, See LICENSE file
#
# Configure(Optional):
# Set `SETV_VIRTUAL_DIR_PATH` value to your virtual environments
# directory-path. By default it is set to '~/virtualenvs/'
#
# Usage:
# Manual install: Added below line to your .bashrc or any local rc script():
# ---
# source /path/to/virtual.sh
# ---
#
# Now you can 'activate' the virtual environment by typing
# $ setv <YOUR VIRTUAL ENVIRONMENT NAME>
#
# For example:
# $ setv rango
#
# or type:
# setv [TAB] [TAB] (to list all virtual envs)
#
# To list all your virtual environments:
# $ setv --list
#
# To create new virtual environment:
# $ setv --new new_virtualenv_name
#
# To delete existing virtual environment:
# $ setv --delete existing_virtualenv_name
#
# To deactivate, type:
# $ deactivate
# Path to virtual environment directory
SETV_VIRTUAL_DIR_PATH="$HOME/virtualenvs/"
# Default python version to use. This decides whether to use `virtualenv` or `python3 -m venv`
SETV_PYTHON_VERSION=3 # Defaults to Python3
SETV_PY_PATH=$(which python${SETV_PYTHON_VERSION})
function _setvcomplete_()
{
# Bash-autocompletion.
# This ensures Tab-auto-completions work for virtual environment names.
local cmd="${1##*/}" # to handle command(s).
# Not necessary as such. 'setv' is the only command
local word=${COMP_WORDS[COMP_CWORD]} # Words thats being completed
local xpat='${word}' # Filter pattern. Include
# only words in variable '$names'
local names=$(ls -l "${SETV_VIRTUAL_DIR_PATH}" | egrep '^d' | awk -F " " '{print $NF}') # Virtual environment names
COMPREPLY=($(compgen -W "$names" -X "$xpat" -- "$word")) # compgen generates the results
}
function _setv_help_() {
# Echo help/usage message
echo "Usage: setv [OPTIONS] [NAME]"
echo Positional argument:
echo -e "NAME Activate virtual env."
echo Optional arguments:
echo -e "-l, --list List all Virtual Envs."
echo -e "-n, --new NAME Create a new Python Virtual Env."
echo -e "-d, --delete NAME Delete existing Python Virtual Env."
echo -e "-p, --python PATH Python binary path."
}
function _setv_custom_python_path()
{
if [ -f "${1}" ];
then
if [ "`expr $1 : '.*python\([2,3]\)'`" = "3" ];
then
SETV_PYTHON_VERSION=3
else
SETV_PYTHON_VERSION=2
fi
SETV_PY_PATH=${1}
_setv_create $2
else
echo "Error: Path ${1} does not exist!"
fi
}
function _setv_create()
{
# Creates new virtual environment if ran with -n|--new flag
if [ -z ${1} ];
then
echo "You need to pass virtual environment name"
_setv_help_
else
echo "Creating new virtual environment with the name: $1"
if [ ${SETV_PYTHON_VERSION} -eq 3 ];
then
${SETV_PY_PATH} -m venv ${SETV_VIRTUAL_DIR_PATH}${1}
else
virtualenv -p ${SETV_PY_PATH} ${SETV_VIRTUAL_DIR_PATH}${1}
fi
echo "You can now activate the Python virtual environment by typing: setv ${1}"
fi
}
function _setv_delete()
{
# Deletes virtual environment if ran with -d|--delete flag
# TODO: Refactor
if [ -z ${1} ];
then
echo "You need to pass virtual environment name"
_setv_help_
else
if [ -d ${SETV_VIRTUAL_DIR_PATH}${1} ];
then
read -p "Really delete this virtual environment(Y/N)? " yes_no
case $yes_no in
Y|y) rm -rvf ${SETV_VIRTUAL_DIR_PATH}${1};;
N|n) echo "Leaving the virtual environment as it is.";;
*) echo "You need to enter either Y/y or N/n"
esac
else
echo "Error: No virtual environment found by the name: ${1}"
fi
fi
}
function _setv_list()
{
# Lists all virtual environments if ran with -l|--list flag
echo -e "List of virtual environments you have under ${SETV_VIRTUAL_DIR_PATH}:\n"
for virt in $(ls -l "${SETV_VIRTUAL_DIR_PATH}" | egrep '^d' | awk -F " " '{print $NF}')
do
echo ${virt}
done
}
function setv() {
# Main function
if [ $# -eq 0 ];
then
_setv_help_
elif [ $# -le 3 ];
then
case "${1}" in
-n|--new) _setv_create ${2};;
-d|--delete) _setv_delete ${2};;
-l|--list) _setv_list;;
*) if [ -d ${SETV_VIRTUAL_DIR_PATH}${1} ];
then
# Activate the virtual environment
source ${SETV_VIRTUAL_DIR_PATH}${1}/bin/activate
else
# Else throw an error message
echo "Sorry, you don't have any virtual environment with the name: ${1}"
_setv_help_
fi
;;
esac
elif [ $# -le 5 ];
then
case "${2}" in
-p|--python) _setv_custom_python_path ${3} ${4};;
*) _setv_help_;;
esac
fi
}
# Calls bash-complete. The compgen command accepts most of the same
# options that complete does but it generates results rather than just
# storing the rules for future use.
complete -F _setvcomplete_ setv