개발자를 위해¶
보틀 개발과 릴리스 작업에 관심 있는 개발자와 패키지 제작자를 위한 문서다. 기여하고 싶다면 언제든 환영이다!
참여하기¶
공동체에 참여해서 최신 소식을 받을 수 있는 방법이 여러 가지 있다. 다음이 그 중 일부다.
메일링 리스트: bottlepy+subscribe@googlegroups.com로 이메일 보내서 메일링 리스트에 가입. (구글 계정 필요 없음.)
IRC: irc.freenode.net의 #bottlepy 가입하거나 웹 채팅 인터페이스 이용.
구글 플러스: 가끔씩 Google+ 페이지에 보틀, 릴리스, 기술적 내용에 대한 글이 올라간다.
소스 받기¶
보틀 개발용 저장소와 이슈 트래커 모두 github에 있다. 기여를 할 생각이라면 거기 계정을 만들어서 주 저장소를 포크하는 방식이 좋다. 그러면 변경 내용과 아이디어를 다른 개발자들이 보면서 함께 토론할 수 있게 된다. 계정이 없어도 저장소를 복제하거나 최신 개발 버전을 소스 아카이브로 다운로드하는 건 가능하다.
릴리스와 업데이트¶
보틀은 비정기적으로 릴리스되고 PyPI를 통해 배포된다. 릴리스 후보 버전과 과거 릴리스의 버그 수정 버전은 위에서 언급한 git 저장소에서만 얻을 수 있다. 다만 일부 리눅스 배포판에서 과거 릴리스의 패키지를 제공할 수도 있다.
보틀 버전 번호는 세 부분(major.minor.revision)으로 이뤄져 있다. 이 버전 번호는 새 기능을 알리는 것이 아니라 중요한 버그 수정 및/또는 API 변경을 나타낸다. 중요한 버그는 최근의 최소 두 개 마이너 릴리스에서 수정이 이뤄지며 가능한 모든 채널(메일링 리스트, 트위터, github)로 알린다. 중요하지 않은 버그나 기능은 백포트를 보장하지 않는다. 다만 이는 나중에 바뀔 수 있다.
- 메이저 릴리스 (x.0)
중요한 마일스톤에서, 또는 하위 호환성을 완전히 깨는 업데이트에서 메이저 번호를 올린다. 새 릴리스를 이용하려면 아마 응용 전체에 작업을 해 줘야 할 것이다. 하지만 이런 릴리스는 아주 드물다.
- 마이너 릴리스 (x.y)
API나 동작이 어떤 식으로든 바뀌는 업데이트에서 마이너 번호를 올린다. 폐기 예정 경고를 보게 될 수도 있고 이전 동작 방식을 살리기 위해 설정을 좀 건드려야 할 수도 있지만 대부분의 경우 그런 변화는 적어도 마이너 릴리스 한 개 차이에 대해선 하위 호환성이 있도록 설계된다. 업데이트해서 최신으로 만드는 게 좋지만 필수는 아니다. 0.8은 예외인데, 하위 호환성을 완전히 깼다. (그래서 0.7을 건너뛰었다.) 그렇게 돼서 유감이다.
- 리비전 (x.y.z)
버그 수정, 또는 API나 동작을 바꾸지 않는 기타 패치에서 리비전 번호를 올린다. 응용 코드를 편집할 필요 없이 안전하게 업데이트할 수 있다. 실제로는 되도록 빨리 업데이트하는 게 좋다. 중요한 보안 문제 수정이 이 방식으로 릴리스되기 때문이다.
- 릴리스 전 버전
릴리스 후보는 리비전 번호에
rc
표시가 붙어 있다. API가 거의 안정적이고 테스트 준비가 되었지만 아직 공식적으로 릴리스되지는 않은 버전이다. 운용 환경에 이 버전을 사용해선 안 된다.
저장소 구조¶
소스 저장소는 다음 구조로 돼 있다.
master
브랜치통합, 테스트, 개발이 이뤄지는 브랜치다. 다음 릴리스에 포함될 계획인 모든 변경 사항이 여기 병합되고 테스트가 이뤄진다.
release-x.y
브랜치마스터 브랜치에서 새 릴리스 준비가 (거의) 되면 새 릴리스 브랜치를 딴다. 그 “릴리스 후보”는 피처를 고정하되 버그 수정과 막바지 변경 사항은 받을 수 있으며, 출시 준비가 됐다 싶으면 공식적으로 릴리스한다. 그때부터는 “지원 브랜치”라고 부르게 되며, 계속 버그 수정을 받기는 하되 중요한 것으로 한정한다. 그 브랜치에 푸시를 할 때마다 리비전 번호가 올라가므로 중요한 변경 사항을 계속 따라갈 수 있다.
bugfix_name-x.y
브랜치일시적인 브랜치로 기존 릴리스에 대한 사소하지 않은 버그 수정을 개발하고 공유하는 데 쓴다. 대응하는 릴리스 브랜치로 병합된 후 곧 삭제된다.
- 피처 브랜치
다른 브랜치는 모두 피처 브랜치다. 마스터 브랜치를 기반으로 하며, 활동이 계속 있고
master
로 병합되지 않은 동안만 브랜치가 살아 있다.
개발자는 어떻게 하면 되나?
피처를 추가하고 싶으면 master
에서 새 브랜치를 만들면 된다. 버그를 고치고 싶으면 영향 받는 브랜치 각각에 대해 bugfix_name-x.y
브랜치를 따면 된다. 통합이 되도록 쉽게 이뤄지도록 각 피처 내지 버그마다 브랜치를 따로 만들어 달라. 이게 전부다. 이 페이지 아래에 git 작업 흐름 예시가 있다.
아, 그리고 절대로 릴리스 번호는 바꾸지 말아 달라. 통합 때 우리가 바꾼다. 대기 중인 요청들을 우리가 어떤 순서로 당겨 갈지 알 수 없잖은가. :)
배포판 관리자는 어떻게 하면 되나?
버그 수정과 새 릴리스는 태그를 (그리고 메일링 리스트를) 지켜보면 된다. git 저장소에서 특정 릴리스를 가져오고 싶다면 브랜치 말고 태그를 믿으면 된다. 브랜치에는 아직 릴리스되지 않은 변경 사항이 포함돼 있을 수 있지만 태그는 버전 번호를 바꾼 바로 그 커밋을 나타낸다.
패치 제출하기¶
변경 사항을 주 개발 브랜치로 합치는 최선의 방법은 github에서 주 저장소를 포크하고 새 피처 브랜치를 만들어서 변경 사항을 적용한 다음 pull 요청을 보내는 것이다. 아래에 길잡이가 될 수도 있는 몇 가지 git 작업 흐름 예시들이 있다. git 호환 패치를 메일링 리스트에 제출하는 것도 괜찮다. 어느 경우든 다음 기본 규칙을 따라 달라.
문서화: 패치가 하는 게 뭔지 적자. 코드에 주석을 달자. 새 기능을 추가하는 거면 다른 사람들이 알 수 있도록 문서에 내용을 추가하자.
테스트: 코드가 예상대로 동작하며 어디에도 문제를 일으키지 않는다는 걸 증명하는 테스트를 작성하자. 버그를 수정했으면 그 버그를 유발시키는 테스트 케이스를 적어도 하나는 작성하자. 패치 제출 전에 테스트가 전부 통과하는지 확인하자.
한 번에 패치 하나씩: 버그 수정이든 기능 추가든 한 번에 한 개씩만 하자. 한꺼번에 적용할 수 있도록 패치들을 설계하자. 패치를 깔끔하고 작게, 한 가지에 집중하도록 작성하자.
업스트림과 동기화: 패치 작업 중에
upstream/master
브랜치에 변경이 있었으면 rebase나 pull을 해서 패치가 충돌 없이 적용되게 만들자.
문서 빌드하기¶
문서를 빌드하려면 Sphinx 최신 버전이 필요하다. 배포판 패키지 저장소를 이용해 virtualenv를 설치한 다음 sphinx를 직접 설치해서 최신 버전을 받는 방법을 권장한다.
# 필요한 패키지 설치
which virtualenv || sudo apt-get install python-virtualenv
virtualenv --no-site-dependencies venv
./venv/pip install -U sphinx
# github에서 보틀 복제하거나 내려받기
git clone https://github.com/defnull/bottle.git
# 빌드 환경 활성화
source ./venv/bin/activate
# HTML 문서 빌드
cd bottle/docs
make html
# 선택적: PDF 생성에 필요한 패키지 설치
sudo apt-get install texlive-latex-extra \
texlive-latex-recommended \
texlive-fonts-recommended
# 선택적: PDF로 문서 빌드
make latex
cd ../build/docs/latex
make pdf
GIT 작업 흐름 예시¶
아래 예시에선 (무료인) github 계정이 있다고 가정한다. 필수는 아니지만 일이 훨씬 쉬워진다.
일단은 공식 저장소의 포크(개인용 복제본)를 만들어야 한다. 보틀 프로젝트 페이지에서 “fork” 버튼을 누르기만 하면 된다. 포크가 끝나면 새 저장소에 대한 짧은 소개가 보일 것이다.
방금 만든 포크는 github에 호스팅되어 있으며 모두가 읽을 수 있지만 쓰는 건 여러분만 가능하다. 이제 실제 변경 작업을 하기 위해 그 포크를 로컬로 clone 해야 한다. (읽기 전용인) 공개 URL 말고 (읽기 및 쓰기가 가능한) 비공개 URL을 쓰도록 하자.
git clone git@github.com:your_github_account/bottle.git
clone이 완료되면 “origin”이라는 리모트가 있어서 github의 포크를 가리키게 된다. 이름을 오해하지 말자. 보틀 원본 저장소가 아니라 포크를 가리키는 거다. 공식 저장소를 따라가기 위해 “upstream”이라는 또 다른 리모트를 추가하자.
cd bottle
git remote add upstream git://github.com/defnull/bottle.git
git fetch upstream
보다시피 “upstream”은 읽기 전용인 공개 clone URL이다. 거기로는 변경 사항을 바로 push 할 수 없다. 대신 그 저장소에서 pull을 하게 되는데, 좀 있다 설명한다.
기능 제출
통합을 쉽게 하기 위해 별도의 피처 브랜치에서 새 기능을 개발한다. master
브랜치로 통합될 거니까 upstream/master
를 기반으로 해야 한다. 새 피처 브랜치를 만들려면 다음을 입력하면 된다.
git checkout -b cool_feature upstream/master
이제 피처를 구현하고, 테스트를 작성하고, 문서를 갱신하고, 모든 테스트가 통과하는지 확인한 다음 변경 사항을 커밋하자.
git commit -a -m "Cool Feature"
그사이 upstream/master
브랜치가 바뀌었으면 작성한 변경 내용과 충돌이 날 수 있다. 해결을 위해 최신 upstream/master
브랜치 위로 피처 브랜치를 ‘rebase’ 하자.
git fetch upstream
git rebase upstream
이는 변경 내용을 모두 되돌리고 브랜치를 최신 버전으로 업데이트 한 다음에 패치들을 모두 재적용하는 것과 같다. 브랜치를 이미 내보냈다면 (다음 단계 참고) 이 방법을 택할 수 없다. 변경 이력을 다시 만들기 때문이다. 그 경우엔 일반 pull을 할 수 있다. 충돌이 있으면 해소하고 다시 테스트를 돌린 다음 커밋하면 된다.
이제 pull 요청을 보낼 준비가 거의 다 됐다. 하지만 그 전에 피처 브랜치를 github 포크로 push 해서 공개해 줘야 한다.
git push origin cool_feature
커밋(들)을 push 한 후에는 우리에게 새 피처에 대해 알려 줘야 한다. 일단 github를 이용해 pull 요청을 보내는 방법이 있다. 그리고 메일링 리스트에서 새 스레드를 시작하는 방법도 있는데, 이걸 권장한다. 그러면 다른 개발자들이 패치를 보고 토론할 수 있으니 여러분은 무료 피드백을 얻게 된다. :)
우리가 패치를 받아들이면 공식 개발 브랜치로 통합해서 다음 릴리스에 포함시키게 된다.
버그 수정
버그 수정 작업 흐름은 피처 추가와 아주 비슷하되 몇 가지 차이가 있다.
개발 브랜치가 아니라 영향 받는 릴리스 브랜치들에서 브랜치를 딴다.
버그를 유발하는 테스트 케이스를 적어도 한 개 작성한다.
해당 시
upstream/master
까지 포함해서 영향 받는 각 브랜치에 대해 그렇게 한다. 반복 작업을 줄이는 데git cherry-pick
이 도움이 될 수 있다.혼동을 피하기 위해 기반이 된 릴리스를 따라 브랜치 이름을 짓는다. 예:
my_bugfix-x.y
또는my_bugfix-dev