Skip to content
isdnetworks
Go back

포크가 답이 아닐 때

(수정됨)

외부 오픈소스를 우리 환경에 맞게 고쳐 쓰면서 이미지 빌드 중에 patches/*.patch 를 git apply 로 얹는 방식을 쓰고 있었다. 지저분해 보여서 포크를 떠서 소스를 직접 관리하는 편이 낫지 않을지 검토했다.

Table of contents

Open Table of contents

조사 — upstream 구조 확인

전환하려면 upstream 구조를 알아야 해서 저장소를 직접 읽었다. 먼저 Dockerfile 이 둘이었는데 Dockerfile.bundled 는 데이터베이스를 이미지 안에 넣는 형태이고 Dockerfile.external-db 는 외부 데이터베이스에 연결하는 형태였다.

우리는 외부 데이터베이스를 쓰므로 뒤의 것이 기반이 돼야 하고 지금도 맞게 쓰고 있었다. 이 확인이 전환 계획의 첫 줄이 됐다.

잘라 내는 의존 오버라이드

pyproject.toml 에는 버전이 고정돼 있는데 그 아래 path = "./src" 로컬 경로 오버라이드 섹션이 있었다. 그 섹션이 이기면 배포된 패키지 대신 로컬 소스를 쓴다.

그런데 Dockerfile.external-db 가 빌드 시점에 sed -i 로 그 섹션을 잘라 내고 있었다. 즉 로컬 소스를 직접 쓰려면 그 잘라 내기를 없애면 되고 포크해서 소스를 직접 관리한다는 계획의 구체적 방법이 그 한 줄에 있었다.

원인 — 갈라진 구조

여기서 계획이 뒤집혔다. upstream 의 main.py 는 900여 줄이고 config/ 와 models/ 와 services/ 와 utils/ 가 서브모듈로 분리돼 ProviderFactory 로 여러 제공자를 지원하고 있었다.

우리 판은 1,400여 줄의 단일 main.py 모놀리식이었다. 우리 판이 옛 버전에서 갈라져 나와 계속 붙여 온 사이에 upstream은 구조를 갈아엎은 것이다.

결론 — 깨진 전제

포크 방식의 전제는 upstream 변경을 git merge upstream/main 으로 우리 포크에 병합하고 충돌만 해결하는 것이다. 구조가 다르면 이것이 성립하지 않는다.

파일이 쪼개졌으므로 우리 쪽 변경이 어느 파일로 가야 하는지를 매번 사람이 판단해야 한다. 자동 병합은 전부 충돌이 된다. 두 가지 방법이 있었는데 포크를 떠서 병합으로 따라가는 것과 patches/ 를 빌드 때 얹는 현재 방식을 유지하는 것이다. 뒤쪽을 골랐다. 이유는 구조가 갈라져 병합이 전부 충돌이라서다. 대신 upstream 판이 오를 때마다 git apply --check 로 패치가 깨지는지 손으로 확인해야 하는 것을 감수했다. 포크하면 관리가 쉬워진다는 전제가 깨졌으므로 전환을 접었다. 지저분하지만 패치 파일이 곧 우리 변경 목록이라 어디를 고치는지가 명시돼 있다.

접은 결정의 기록

전환을 접었다고 조사가 헛된 것은 아니어서 결과를 DECISIONS.md 에 남겼다. 향후 포크로 전환하면 Dockerfile.external-db 를 기반으로 하고 sed -i 잘라 내기를 제거해야 한다고 적었다. 구조가 정렬되기 전에는 관리가 불가능하다는 것도 적었다.

언제 다시 검토할지의 조건도 함께 적었다. 접은 이유를 안 남기면 몇 달 뒤에 누가 같은 검토를 반복한다. 지저분한 것을 보면 누구나 같은 생각을 하기 때문이다. 구조가 갈라져서 관리가 안 된다는 한 줄이면 다음 사람이 바로 안다.

정리


Share this post on:

Previous Post
밖으로 나가는 컬럼
Next Post
스케줄러가 둘일 때의 필터