소프트웨어 버전이란 컴퓨터 소프트웨어의 특정 시점의 상태에 대해 식별 가능한 유일한 이름을 지정하는 것을 의미합니다. 윈도 7(버전 6.1), 리눅스 커널  버전 3.10.0-123, PHP 버전 5.6.8 등 발표되는 소프트웨어는 저마다의 버전을 갖고 있습니다.

 

윈도나 리눅스 PHP 등 개별 소프트웨어는 나름대로 버전 이름을 지정하는 규칙이 있지만 이는 해당 소프트웨어에만 해당되며 다른 소프트웨어들은 또 저마다의 버전 규칙이 있기 마련이었습니다.

개발하는 소프트웨어의 규모가 커지고 외부 라이브러리를 많이 사용할 수록 의존성 지옥에 빠지기 쉬운 이유중 하나는 라이브러리의 버전을 변경할 때 어떤 규칙에 의해서 버전이 매겨지는지 통용되는 명확한 규칙이 없기 때문입니다.

 

유의적 버전(Semantic versioning)은 이런 의존성 문제를 해결하고자 나온 라이브러리의 버전 명시 규칙과 요구 사항으로 요약하면 다음과 같습니다.

 

먼저 외부에서 사용할 수 있는 공개 API 를 선언하고 라이브러리의 버전은 MAJOR.MINOR.PATCH 와 같은 형식으로 한다.

  • 기존 버전과 호환되지 않게 API가 변경되면 "MAJOR 버전"을 올린다.
  • 기존 버전과 호환되면서 새로운 기능이 추가 되었을 때는 "MINOR 버전"을 올린다.
  • 기존 버전과 호환되면서 버그를 수정했을 경우 "PATCH 버전" 을 올린다.
  • 버전 형식 뒤에 "정식 출시전" 이나 빌드 메타데이타를 위한 레이블을 추가할 수 있다.

 

예로 버전이 lib-bar의 버전이 2.1.1 일 경우 API 가 호환되지 않는 새 버전은 3.y.z 가 됩니다. (y.z 는 숫자)

lib-bar 를 사용하는 lib-foo 3.y.z 는 2.y.z 버전대의 라이브러리를 사용하면 호환성을 확보하면서 가장 안정적인 버전의 lib-bar 를 사용할 수 있습니다.

 

크게 기능을 개선한 lib-foo 는 기존 API 를 대폭 수정하면서 4.y.z 버전을 출시해도 이를 사용하는 app-A 는 3.y.z 대의 lib-foo 를 사용하면 안정적으로 동작할 수 있습니다.

또 의존성 있는 라이브러리를 시스템 전역적으로 설치하지 않고 애플리케이션 마다 분리하여 사용하면 특정 라이브러리가 업데이트 되어도 다른 애플리케이션 영향을 주지 않고 안정적으로 업그레이드할 수 있는 장점이 있습니다.

 

컴포저(Composer)는 ruby 의 bundler, Node.js 의 NPM, python 의 pip 와 비슷한 역할을 수행하는 의존성 관리자로 PHP 를 사용할 때 발생하는 라이브러리 간의 의존성 문제를 간단한 의존성 선언만으로 해결해 줍니다.

PHP 의 패키지 관리자인 컴포져는 이를 기반으로 의존성 관리를 하므로 유의적 버전을 따르는 PHP 라이브러리들을 사용한다면 의존성 지옥에 빠지지 않고 PHP로 개발과 유지보수를 진행할 수 있습니다.