suyeonme

[의존성 관리] Semantic Versioning이란? 본문

프로그래밍👩🏻‍💻/기타

[의존성 관리] Semantic Versioning이란?

suyeonme 2022. 11. 20. 14:32
구글 엔지니어는 이렇게 일한다 책의 21장 "의존성 관리" 챕터를 읽고 정리한 내용입니다.

Semantic Versioning(SemVer)이란?


Semantic Versioning은 오늘날 의존성 네트워크를 관리하는 가장 대표적인 방법으로, 의존성의 버전을 표기하는 보편적 방식이다.

버전은 숫자 세개로 표현한다. 예를 들어, library  1.5는 1.5나 1.5.1 혹은 1.6이상을 포괄한다는 의미이다.

  • MAJOR: API가 변경되어 의존성을 이용하던 기존 코드를 깨뜨릴 수 있음
  • MINOR: 순수한 기능추가만 있음(기존 코드를 깨뜨리지 않음)
  • PATCH: API에 영향을 주지 않는 내부 구현 개선과 버그 수정

Semantic Versioning(SemVer)의 한계

  • 변경이 얼마나 위험할지를 사람이 추정하는, 간단하지만 정보가 일부 손실되는 표현법이다. 개발자의 판단으로 dot(.)으로 버전을 구분하여 명시해도 하이럼의 법칙(The Law of Implicit Dependencies)으로 빌드가 깨지거나 라이브러리가 의도치 않게 동작할 수 있다. SAT 그래프에서의 노드값은 명백하게 참 혹은 거짓이지만 의존성 그래프의 버전 값은 메인테이너가 기존 버전과 새 버전을 비교한 해 추정한 결과이다.
  • 지나치게 구속할 수 있다. 예를 들어, A모듈과 B모듈은 C라이브러리의 Foo함수를 사용하고 있다. 이후 C라이브러리에서 Bar함수에 파괴적인 변경이 일어났다. SemVer 규칙에 따라서 메이저 버전을 올려야하는데, 현재 C라이브러리 1.x에 의존중인 A모듈과 B모듈에게  의존성 솔버는 2x버전을 허용하지 않을 것이다.(2x버전의 Bar모듈을 사용하지 않아서 버전업을 해도 문제가 없음에도)

Satisfiability Solver(SAT solver)란?

Semantic Versioning과 같이 요구사항 표현법을 정형화하면 의존성 네크워크를 소프트웨어 컴포넌트(Node)와 그 사이의 요구사항(Edge)의 집합으로 표현할 수 있다.

 

의존성이 추가 또는 제거되거나 소스 노드가 변경되어 SemVer 요구사항이 달라지면 엣지의 이름은 변경된다. 시간이 지남에 따라 전체 네트워크가 비동기적으로 변하기 때문에 애플리케이션의 요구사항을 전이 의존성까지 포함하여 모두 만족하는 상호 호환되는 의존성들로 이루어진 집합을 찾는 것은 매우 어려울 수 있다.

 

SAT solver는 SemVer 체계에서 이 집합을 찾아준다. 즉 특정 노드의 제약조건 집합(의존성 에지 버전 요구사항)이 주어지면 이를 모두 충족하는 버전의 집합을 찾는다. 논리 및 알고리즘 연구에서의 SAT solver와 매우 비슷하다. 대부분의 패키지 관리 생태계는 SemVer용 SAT 솔버로 관리되는 그래프를 기초로 구동된다.

최소 버전 선택(Minimum Version Selection, MVS)이란?

2018년에 구글의 러스콕스가 제안한 SemVer 의존성 관리의 변형으로, 의존성 네트워크에서 특정 노드의 버전이 바뀌는 경우 이 노드가 이용하던 다른 의존성들도 업데이트할 때, 최소 버전으로 업데이트하는 방식이다. 

 

예를 들어, liba 1.0이 libbase ≥ 1.7을 요구한다면 1.8이 존재하더라도 1.7부터 시도한다.

 

liba 개발자의 시스템에는 libbase 1.7이 설치되어있을 게 거의 확실하며 메인테이너가 새 버전을 릴리즈하기 전에 기본적인 테스트를 수행했다고 가정하면 최소한 liba 1.0과 libbase 1.7의 상호운용 검증은 이미 이루어졌다고 믿을 수 있다. 즉 개발자가 실제로 테스트한 조합에 가장 가까운 버전을 선택함으로써 실질적인 충실성을 높여준다.

의존성 관련 용어

  • 버전 선택(version selection): 의존성 네트워크 전체를 대상으로 알고리즘을 수행하여 모든 버전 요구사항을 충족하는 의존성 버전을 찾는 행위
  • 의존성 지옥(dependency hell): 만족스러운 버전 조합이 네트워크에 존재하지 않는 경우
  • 의존성 전의(transitive dependency): 여러 모듈이 A모듈에게 의존하는 경우, A 모듈이 변할 때 의존하고 있는 모든 모듈에게 변경이 전파되는 경우
  • 다이아몬드 의존성 충돌(diamond dependency conflict)
Comments