5/14/2018

Pyenv-virtualenv + virtualenvwrapper + autodir

Pyenv-virtualenv + virtualenvwrapper + autodir

배경

  • 오랜만에 Django project를 하나 만들어 볼까하는데 환경설정이 항상 문제다.
  • 그저 프로젝트 폴더에 virtualenv 만들어서 개발할 때마다 activate를 할수 있을 것이다.
  • 그런데 이게 괜히 불편해서 폴더 들어가면 자동으로 virtualenv를 activate 시켜주고 싶어졌다.
  • 사실 vagrant나 docker로 띄우면 개발환경이 아예 격리되기에 위같은 고민을 한번에 해결할수 있었을 것이지만…
아무튼 하기로 한거니 해보려고 했다.

문제와 목표

문제 1. virtualenv 폴더를 매번 찾기 귀찮다.

  • virtualenvwrapper를 이용하여, 한곳에 가상환경을 몰아넣고 alias로 가상환경을 불러온다.

문제 2. 해당 alias를 project name과 같게 해야하거나 기억해야한다.

문제 3. 개발할 때마다, CLI로 매번 가상환경을 불러와야함

  • 프로젝트 폴더 들어갈 때, 자동으로 virtualenv를 activate
  • (중요) 나갈때는 deactivate
반복되고 실수할 수 있는 것을 줄이자

결과

Zsh-autoenv를 사용하여 해결함
# When enter project folder
pyenv activate [your-pyenv-virtualenv]
echo $(pyenv versions)
pip freeze > requirements.txt
ll requirements.txt
view raw .autoenv.zsh hosted with ❤ by GitHub
# When leave project folder
# /Users/.../projects/project $ cd ..
pyenv deactivate
echo $(pyenv versions)

  • env file이 변경되면 처음에만 실행할 건지 묻게 됨
  • pyenv versions가 한줄에 표시되어 가독성이 좋지 않은 건 일단 넘어갔음
~/projects $ cd starbucks-between-us
Attempting to load unauthorized env file!
-rw-r--r--  1 erwre  staff  48  5 14 19:06 /Users/erwre/projects/starbucks-between-us/.autoenv.zsh

**********************************************

pyenv activate starbucks
echo $(pyenv versions)

**********************************************

Would you like to authorize it? (type 'yes') yes
system 3.6.4 3.6.4/envs/starbucks * starbucks (set by PYENV_VERSION environment variable)
~/projects/starbucks-between-us $
~/projects/starbucks-between-us $ cd ..
Attempting to load unauthorized env file!
-rw-r--r--  1 erwre  staff  40  5 14 19:07 /Users/erwre/projects/starbucks-between-us/.autoenv_leave.zsh

**********************************************

pyenv deactivate
echo $(pyenv versions)

**********************************************

Would you like to authorize it? (type 'yes') yes
system * 3.6.4 (set by /usr/local/var/pyenv/version) 3.6.4/envs/starbucks starbucks
~/projects $

과정

기존 개발 환경은 pyenv로 python 3.6.4를 global default로 사용 중이었다. 터미널은 iTerm+Zsh 조합을 쓰고 있다.
  1. smartcd : 설치가 번거로움
  2. direnv : directory를 벗어날 때, 적을 수 있는 스크립트 옵션이 없어보임( 예시에서는 폴더 들어갈 때, 스크립트에서 환경변수를 export 함. 폴더를 빠져나오니 사라지는 정도의 환경변수 정리만 지원하는 것으로 보임)
    • brew install로 설치 시, repo master와 버전이 다름
      • env.leave 기능(폴더 빠져나올 때 실행할 스크립트)을 지원하지 않음
    • pip로 설치하기에는 pyenv에 있는 특정 버전에만 설치되어 꼬일까봐 brew로 최대한 설치하려 했음
      • 합리적인 의심이 맞는건가?
      • 어차피 가상환경들어가서도 deactivate는 될텐데?
      • 그건 virtualenv로 생성된 환경이라 가능한거 아닌가라고 생각되었고 pip로 일단 시도는 안해봄
    • 성공!
    • zsh를 위해 autoenv를 wrapping 함
    • env.leave 기능이 반영되어 있어서 사용함
      • 정확히는 .autoenv.zsh.autoenv_leave.zsh로 파일 이름이 다름
    • 다만 설치는 brew나 pip를 사용할 수 없어 repo clone 해야함
      • 업데이트 시점을 알수 없어 버전 관리에 취약할 수 있음
      • git pull로 할수도 있지만, brew update나 pip update에 비하면 개별적인 패키지 관리는 번거롭다.

Furthermore

  • pyenv-virtualenv와 virtualenv 어느 것을 쓰는 게 적합할까?
    • pyenv에서 제공하는 virtualenv는 해당 pyenv를 들어가지 않고도 한눈에 확인이 가능하다.
    • 그래서 pyenv-virtualenv를 사용함
  • pyenv-virtualenv: prompt changing will be removed from future release. configureexport PYENVVIRTUALENVDISABLE_PROMPT=1' to simulate the behavior.`
    • pyenv-virtualenv에서는 prompt에서 가상환경을 변경하는 것을 제거할 예정이라고 함…
    • 왜일까는 덜 살펴보았는데, 쉘 환경마다 prompt 앞에 붙던 가상환경의 alias가 문제가 된 것으로 보인다. (대충 살펴봐서 정확하지 않습니다. 너무 발산하는 거 같아서 풀고자 하는 것에 집중했음)
    • 일단은 prompt 옵션을 ~/.zshrc에서 바꾸도록 했음
    • 아쉬운 건, activate 되었는지 prompt 상에서 확인하기가 어렵다는 것인데, autudir에서 pyenv version을 echo로 출력하면 쉽게 해결됨
  • pyenv-virtualenv로 가상환경을 만들면 pyenv versions에 두개가 추가된다. 사용중인 pyenv의 환경을 기반으로 virtualenv를 만들고 alias를 두는 형태로 보인다. 모르고 비활성화된 한쪽을 지웠다가 오류가 났음
$ pyenv versions
  system
  3.6.4
  3.6.4/envs/starbucks
* starbucks (set by PYENV_VERSION environment variable)

$ which python
/usr/local/var/pyenv/shims/python

$ pyenv which python
/usr/local/var/pyenv/versions/starbucks/bin/python

$ ll /usr/local/var/pyenv/versions
total 0
drwxr-xr-x  7 erwre  admin   224B  5 11 17:08 3.6.4
lrwxr-xr-x  1 erwre  admin    50B  5 11 18:00 starbucks -> /usr/local/var/pyenv/versions/3.6.4/envs/starbucks
  • 다른 사람과 협업하기에 개발 환경이 내 환경에 너무 의존적이지 않은가?
    • requirements.txt로 의존성 관리를 하여, pip install -r requirements.txt는 명시적으로 실행될 거기 때문에 문제가 되지 않음
    • dockerfile을 이용하여, 이 과정을 줄일 수도 있음
  • (추가 아이디어) pip freeze > requirements.txt를 프로젝트 폴더 빠져나갈 때마다 실행하면 어떨까?
    • 테스트 중이고 의도되지 않은 패키지들이 반영 될수도 있지만, 그건 commit을 안하면 될 문제고, 패키지 변경을 알려주는 측면에서는 더 좋지않을까?!
    • cd .. 를 이미 한 시점에서 pwd는 project 상위 폴더를 가리키고 있음
    • 그리고 보통 cd ..로 종료 안하고 터미널 자체를 끄거나 새로운 터미널 세션을 사용하는 경우가 많아 의도대로 프로젝트 종료 시점과는 일치하지 않을 수 있음
    • 프로젝트 진입 시점(는 매번 호출)으로 바꿔도 큰 문제가 없을거 같음

댓글 없음:

댓글 쓰기