바람직한 소스 코드 관리 전략 #2

Posted at 2008. 3. 5. 08:00 // in S/W개발 // by 김윤수


아래 글을 썼더니 많은 분들이 관심을 나타내 주시더군요.

2008/02/18 - [S/W개발] - 바람직한 소스 코드 관리 전략 #1


그래서 역시 소스 코드 관리하는 건 어느 조직에서나 겪는 문제인가보구나 다시금 느끼게 됐습니다. 댓글을 통해 관심을 나타내 주신 분들께 진심으로 감사드립니다.

지난글에 이어 바람직한 소스 코드 관리 전략에 대한 담론을 이어가도록 하겠습니다.

이번글에서 답변해야 하는 질문이 다섯가지가 될텐데요...

  1. 현재의 개발 싸이클이 완료되어 소프트웨어를 릴리즈하고 나서 다음 개발 싸이클을 시작하기 전에 어떤 조치를 취하시나요 ?
  2. 개발 버전의 소프트웨어와 릴리즈 버전의 소프트웨어를 어떤 식으로 관리하시나요 ?
  3. 이전 프로젝트에서 개발했던 컴포넌트를 현재 개발 중인 프로젝트에서 재활용할 때 어떤 식으로 하시나요 ?
  4. Open Source 를 자사의 요구사항에 맞게 수정해서 개발하고 난 후 어떤 조치를 취하시나요 ?
  5. 사내 조직간에 소프트웨어 컴포넌트를 어떤 식으로 공유하시나요 ?

이 질문들에 대한 답변을 할 때 공통적으로 고려해야할 부분이 있어서 그걸 먼저 얘기해 보도록 하겠습니다.

소스 코드 관리 전략의 핵심

저는 소스 코드 관리 전략의 핵심은 얼마나 관리해야 하는 소스 코드의 양을 줄이느냐에 있다고 봅니다. 왜냐하면 소스 코드 관리 비용의 대부분은 결함 제거 비용이고, 결함의 개수는 관리하는 소스 코드의 양에 비례하기 때문입니다. 소스 코드를 제대로 관리하지 않는 조직일수록 다음 그림과 같은 일들이 벌어질거라 생각합니다.

잘못된 소스 코드 관리

잘못된 소스 코드 관리

A라는 소프트웨어의 1.0 버전이 릴리즈된 후에 어떤 조직에서는 그 소스를 복사해서는 나름대로 수정해서 A+ 라는 소프트웨어를 만들고, 또 다른 조직에서 A+ 소스를 가져다가 나름대로 수정해서 A-라는 소프트웨어를 만들고, 또 다른 조직에서는 A 소프트웨어의 1.1 버전 소스를 수정해서 A++ 라는 소프트웨어를 만듭니다.

이렇게 될 경우 어떤 일이 벌어질지 상상이 되시나요 ? A+, A-, A++, A 에서 모두 같은 결함을 여러번 중복해서 제거하고 있을 가능성이 무척 높습니다. A+, A-, A++ 을 개발하는 조직들은 다음에 릴리즈되는 A 2.0의 향상된 기능을 전혀 사용하지 못할 가능성이 높습니다. 게다가 A 가 컴포넌트가 아니라 일종의 플랫폼이고, A+, A-, A++ 에서 각각 그 플랫폼의 API를 나름대로 수정해 버렸다면 그 위에 올라가는 컴포넌트는 서로 호환되지 않게 됨으로써 컴포넌트의 재사용성도 상당히 떨어지게 될 것입니다.

왜 이런 일이 벌어지게 될까요 ?

따로 복사되어 관리되기 시작한 코드는 나름의 생명주기를 가지고 계속해서 유지될 가능성이 매우 높기 때문입니다. 그 코드를 개발/관리하는 조직은 소스 코드를 핵심 자산으로 여길 뿐만 아니라 나름대로 가했던 수정 내용들을 원소스에 통합하는 것이 그리 만만치 않아 통합할 엄두를 못낼 것이기 때문입니다. 게다가 조직 문화의 문제, 시간의 문제가 큰 걸림돌이 될 것이기 때문입니다. 처음부터 A 소프트웨어를 사용하는 조직에서 A를 Reference만 하고, 각 조직의 Requirement 에 맞게 달라져야 되는 부분은 A 소프트웨어에 반영하고, 추가되어야할 부분만 따로 각각의 조직에서 개발/관리해야만 이런 일은 발생하지 않을 것입니다. 이런 문제점은 소스 코드 복사의 위험성에서 제가 지적했던 바와 일맥 상통한다고 할 수 있습니다.

특정 소프트웨어를 개발하는 조직이 아무리 여러 조직으로 퍼져있다고 하더라도 모름지기 소스 코드는 어느 한 중앙 서버에서 관리되어야 합니다. 복사본이 퍼지면 퍼질수록 버그가 계속해서 양산되고, 이로 인해 소스 코드 관리 비용도 계속해서 커지게 됩니다.

기존에 이미 개발된 소프트웨어의 경우에도 계속해서 refactoring 또는 rearchitecting 을 통해서 공통 모듈을 찾아냄으로써 전체적인 소스 코드의 크기를 줄여나가는 작업도 병행해야 합니다.

소스 코드 관리의 실제

이런 생각을 배경에 두고 나머지 질문들에 대해서 답해 보도록 하겠습니다.

현재의 개발 싸이클이 완료되어 소프트웨어를 릴리즈하고 나서 다음 개발 싸이클을 시작하기 전에 어떤 조치를 취하시나요 ?

제가 아는 어떤 조직에서는 한 개발 싸이클이 완료되고 나면 항상 이전의 소스 코드 저장소를 그대로 둔 채 새로운 소스 코드 저장소 TOP 디렉토리를 하나 더 만든 후에 그 곳에 이전 소스 코드 Snapshot을 복사한 후에 새로운 개발 싸이클을 시작하곤 했습니다. 혹시 이런식으로 관리하시는 조직 있으신가요 ? Oh! NOOOOOOOOOOOO!

이런 식으로 할 경우, 릴리즈할 때마다 관리하는 소스 코드의 양이 계속해서 증가하게 될 것은 자명한 일입니다.

소프트웨어를 릴리즈하면서 반드시 해야할 일은 릴리즈 버전 Snapshot 에 대해 label (또는 tag)를 달아두는 것입니다. 예를 들어, 1.0 버전을 릴리즈하는 것이라면 1_0_RELEASE라는 label 을 달아두는 것이지요. 그리고 나서 그 릴리즈 버전에 대해 branch 를 만들고, main trunk 상에서 다음 개발 싸이클을 시작해야 합니다. 그림으로 나타낸다면 다음과 같습니다.

소프트웨어 릴리즈후 조치

소프트웨어 릴리즈후 조치

여기에서 Branch 를 만드는 주된 이유는 Main Trunk 상에서 다음 싸이클의 개발을 계속하면서 기능이 추가될 때, 기존에 정상적으로 실행되던 기능들이 비정상 작동할 수 있기 때문입니다. 따라서 릴리즈 버전에 대해서는 따로 Branch 를 통해 관리함으로써 이전 릴리즈 버전에 대한 지원과 다음 개발 싸이클을 병행해서 진행할 수 있습니다. 즉, Branch 에서는 이전 릴리즈 버전에 대해 발견된 문제점들을 해결하고, Main Trunk 에서는 새로운 기능을 추가하는 작업을 계속하는 것이지요.

그리고, 중간 중간이나 또는 이전 릴리즈 버전에 대한 지원을 중단하는 시점에서 Branch 에 반영된 수정사항을 Main Trunk 에도 Merge 를 해주어야 합니다. 이런식으로 모든 코드가 Main Trunk 를 중심으로 유지되도록 해야 합니다.

개발 버전의 소프트웨어와 릴리즈 버전의 소프트웨어를 어떤 식으로 관리하시나요 ?

이 질문에 대한 답변은 위에서 이미 해결되었다고 생각합니다. 즉, 개발 버전을 Main Trunk 에서 유지하고, 릴리즈 버전을 Branch 에서 유지하는 것이지요. 개발 버전과 릴리즈 버전을 서로 독립된 저장소에서 관리해서는 안된다는 것입니다.

이전 프로젝트에서 개발했던 컴포넌트를 현재 개발 중인 프로젝트에서 재활용할 때 어떤 식으로 하시나요 ?

이 질문에 대한 답변의 핵심은 자신이 속한 조직에서 개발했던 컴포넌트를 외부 컴포넌트로 보느냐 아니면 지금 개발 중인 더 큰 규모의 소프트웨어의 일부로 보느냐에 있습니다. 외부 컴포넌트로 볼 경우에는 단순 Reference 만 해야 하고, 현재 개발 중인 소프트웨어의 일부로 볼 경우에는 그 컴포넌트를 현재 소프트웨어로 import 해야겠지요. 이것은 다시 그 컴포넌트가 독립적으로 재활용될 여지가 있는 컴포넌트인지 아닌지에 대한 판단이 전제가 되어야 합니다.

즉, 독립적으로 재활용될 여지가 있는 것이라면 별도의 저장소를 갖고 유지되는 것이 바람직할 것이고, 그럴 여지가 없는 것이라면 import 되어도 무방하겠지요. 결국 내부적인 개발 편의성 보다는 컴포넌트 자체의 재활용성 여부가 더 중요한 판단 기준이 되어야 합니다.

Open Source 를 자사의 요구사항에 맞게 수정해서 개발하고 난 후 어떤 조치를 취하시나요 ?

보통은 소스 코드를 자사의 핵심 지적 자산으로 보기 때문에 Open Source를 수정한 후에도 공개를 꺼리거나 적어도 상당한 시일이 지난 후에 공개하는 경우가 많이 있습니다. 또는 처음부터 Open Source 중 license 가 수정 내용을 공개하지 않아도 되는 것을 가져다가 수정한 후 공개하지 않는 정책을 취하기도 합니다.

그렇지만 Open Source의 license와는 관계없이 그 복사본을 자사의 소스 코드 저장소에서 따로 관리한다는 것이 무엇을 의미하는지 곰곰히 생각해 볼 필요가 있습니다. 소스 코드의 양 측면에서 보면 관리해야할 소스 코드의 양이 늘어나는 것을 뜻합니다. 그 중에 자사의 핵심 지적 자산으로 보호하고 싶은 부분은 아주 일부분일 뿐일 것입니다. 그 조그만 부분을 보호하기 위해 그에 비해 수십배 때로는 수천배에 이르는 Open Source 코드를 관리하는 비용을 지불하는 것이 과연 바람직한 전략인지 고민해 봐야할 것입니다.

Open Source 의 복사본을 자사의 소스 코드 저장소에 따로 관리해 보신 분은 Open Source 를 사내에서 관리하기 위해서는 어떤 일들을 해야하는지 잘 이해하시리라 생각합니다. Open Source 가 계속해서 발전되는 것들을 지켜보며 수정 내용을 적용할지 적용하지 않을지를 매번 결정해야 합니다. 관련 mailing list 에도 가입해서 논의 내용에 대해서도 follow-up 해야 하구요. 그러다가 Major Release 가 되면서 대대적인 소스 개편이라도 있게되면 새로운 소스 코드를 다운 받아서 자사 요구사항에 맞게 수정한 부분을 다시 찾아서 수정해야 합니다. 그렇게 되면 이전에 수정을 하기 위해 Open Source 를 분석했던 노력을 반복해야 하는 것이지요. 요약하자면 사내에서 직접 개발한 소스 못지 않은 관리 노력이 들어가야 합니다.

이런 측면을 고려하여 Open Source 를 자사의 요구사항에 맞게 수정한 내용을 차라리 공개해 버린다면 자사가 Contribution 한 내용이 계속해서 해당 Open Source 코드에 유지되면서 차후 버전에서도 추가적인 노력없이 계속 활용함과 동시에 Open Source Community 에서 해당 소프트웨어에 추가한 발전된 기능들을 고스란히 활용할 수 있게 될 것입니다. 오히려 소스 코드 관리 비용의 일부를 외부 조직에 전가한 효과를 가져올 수 있는 것이지요.

따라서 Open Source 를 수정한 내용에 대한 공개 여부를 결정할 때, 단순 자사의 지적 자산을 보호한다는 측면뿐 아니라 소스 코드 관리 비용을 고려하여 결정해야 할 것입니다.

사내 조직간에 소프트웨어 컴포넌트를 어떤 식으로 공유하시나요 ?

사내 조직간에 소프트웨어 컴포넌트를 어떤 식으로 공유하는지에 대한 사내 규정의 존재 여부와는 관계 없이 여러분이라면 어떻게 공유를 하고 싶으신가요 ? 아예 공유를 하지 않으시나요 ? 아니면 공유를 하되 소스 코드 복사본과 관련 문서를 전달만 하고 끝내시나요 ? 그것도 아니라면 소스는 절대 공유하지 않고 실제 지원을 하면서 최종 결과물만 전달하고 오시나요 ?

만약 소스 코드를 공유하는 경우라면 복사본을 공유하기 보다는 소스 코드 저장소에 대한 접근 권한을 공유하는 것이 바람직할 것입니다. 해당 조직에 소스 코드를 릴리즈하면서 릴리즈 당시의 Snapshot에 Label을 붙이고, branch를 만들어 소스 코드를 활용하는 조직도 branch 상에서 발견하는 문제들을 수정할 수 있도록 해 줄 필요가 있습니다. 더불어 해당 조직과 주기적 또는 비정기적인 소스 관리 미팅을 통해 그 조직에서 수정한 내용을 Main Trunk 쪽으로 sync back 해줄 필요가 있습니다.

마찬가지로 사내에 조직간 컴포넌트 재사용을 권장하는 정책이 있다면 소스 코드 복사본이 이 조직 저 조직으로 유통되게 하기 보다는 소스 코드 저장소 자체를 공유하는 방향으로 전개되어야 할 것입니다. 이렇게 함으로써 재사용되는 컴포넌트의 품질도 계속해서 개선해 갈 수 있을 것이며, 사내의 다양한 개발자들의 개발 노력이 서로 상승 작용을 일으킬 수 있을 것이고, 관리하는 소스 코드 양을 회사 전체적으로 볼 때 적당한 수준에서 유지할 수 있을 것입니다.

이상으로 바람직한 소스 코드 관리 전략에 대한 담론을 마치도록 하겠습니다. 참 오랜 동안 고민해 오면서 가슴 속에 담아 두었던 말을 장문으로 풀어 내고 나니 시원 섭섭합니다. 글을 주로단정적인 말투로 작성한 것은 제가 그만큼 100% 확신하고 있어서라기 보다는 제 성격이 주장하는 바를 명확히 나타내지 못하는 것을 잘 참지 못하는 성격이라서 그렇답니다. 이점 양해해 주시고, 제가 제시한 전략에 대해 반대 의견 있으시면 얼마든지 환영이니 댓글이나 트랙백 달아주시면 감사하겠습니다. 그렇다고 꼭 반대 의견만 댓글로 다셔야 되는 건 아니고요. 요즘 워낙 댓글에 목말라 있어서요. ^^

제 글이 유익하셨다면 오른쪽 버튼을 눌러 제 블로그를 구독하세요. ->
블로그를 구독하는 방법을 잘 모르시는 분은 2. RSS 활용을 클릭하세요.
RSS에 대해 잘 모르시는 분은 1. RSS란 무엇인가를 클릭하세요.

다음글 예고편: C++ 이야기 열여덟번째: 임시 객체가 충분히 임시스럽기 위하여
다음글도 기대해 주세요~~~ :)