의존성 충돌 해결하기 free

2019-07-16

컴포저로 패키지를 설치하려고 하는데 빨간색 경고문만 나오고 설치가 되지 않는 경우를 겪어봤을지 모르겠다. 대부분은 의존성이 꼬여서 발생하는 문제이다. 이를 해결하는 방법은 알면 쉽지만 모르면 한 없이 어렵게 느껴질 수 있다. 구체적인 사례를 통해 의존성을 해결하는 방법을 알아보자.


설치가 안된다!


현재 약간은 방치되어 있는 내 출판사의 웹사이트인 https://uptodatebookspub.com 를 실사례로 다뤄보면 좋을 것 같다. 오랜만에 코드를 열어서 확인해보니 벨 5.5로 만들어져있다. 하 오래됐구나……


벨을 최신 버전으로 업데이트 해보자! composer.json을 열어 “laravel/framework” 항목을 찾아 “5.8.*”로 변경했다.


// before
"laravel/framework": "5.5.*",

// after
"laravel/framework": "5.8.*",

가랏! 업데이트!!


composer update

실제로 메이저 버전을 업데이트할 때는 laravel/framework 패키지를 업데이트하는 것 뿐만 아니 코드도 이곳 저곳 수정해야한다. 여기서는 편의상 패키지를 업데이트하는 것만 다루겠다.



스크린샷 2019-07-17 오전 12.01.25.png

긴 메시지와 함께 업데이트에 실패했다. 메시지가 기니까 괜히 무섭고 어려워보인다. 하지만 쫄지말자. 사실 에러 메시지는 우리의 친구다.


잘 살펴보면 문제가 Problem 1 하나만 있는 아주 간단한 상황이다.


Problem 1
- laravelnews/laravel-twbs4 1.3.2 requires laravel/framework ~5.5.0 -> satisfiable by laravel/framework[5.5.x-dev, v5.5.0, v5.5.1, v5.5.10, v5.5.11, v5.5.12, v5.5.13, v5.5.14, v5.5.15, v5.5.16, v5.5.17, v5.5.18, v5.5.19, v5.5.2, v5.5.20, v5.5.21, v5.5.22, v5.5.23, v5.5.24, v5.5.25, v5.5.26, v5.5.27, v5.5.28, v5.5.29, v5.5.3, v5.5.30, v5.5.31, v5.5.32, v5.5.33, v5.5.34, v5.5.35, v5.5.36, v5.5.37, v5.5.38, v5.5.39, v5.5.4, v5.5.40, v5.5.41, v5.5.42, v5.5.43, v5.5.44, v5.5.45, v5.5.46, v5.5.5, v5.5.6, v5.5.7, v5.5.8, v5.5.9] but these conflict with your requirements or minimum-stability.

차분히 읽어보면 laravelnews/laravel-twbs4 1.3.2 requires laravel/framework ~5.5.0가 핵심이다. laravelnews/laravel-twbs4 1.3.2 패키지를 설치하려면 laravel/framework ~5.5.0이 필요하다. satisfiable by laravel/framework 뒤에 나오는 버전 넘버들은 ~5.5.0에 해당하는 버전의 목록을 의미한다.(큰 의미는 없다.)


나야 걔야?


PHP의 대표적인 의존성 관리도구는 컴포저이다. 컴포저는 한 프로젝트에는 하나의 패키지 버전만 허용한다. 즉 한 프로젝트 안에 somepackage 1.0.1과 somepackage 1.2.5를 동시에 설치할 수 없다. 그래서 여러 버전의 패키지가 필요한 상황이 되면 업데이트를 진행하지 않고 사용자가 선택할 수 있게 한다.


위의 상황은 laravelnews/laravel-twbs4 1.3.2laravel/framework 5.8.* 둘 중 하나를 포기해야한다.


벨 최신 버전을 설치하는 것이 목적이었으므로 laravelnews/laravel-twbs4 1.3.2를 포기하자. laravel/framework 5.8.*를 지원하는 laravelnews/laravel-twbs4를 찾아 업데이트하던가, 아예 다른 패키지로 교체해야 한다.


composer.json을 살펴보니 laravelnews/laravel-twbs4^1.2 조건으로 업데이트되도록 설정되어 있었다.


"laravelnews/laravel-twbs4": "^1.2"

컴포저에 설치 조건을 지정하는 방법은 컴포저 매뉴얼을 참고하자.



얼마면 돼?


하위호환성이 깨졌더도 같은 패키지를 유지하는게 다른 패키지로 교체하는 것 보다는 수고가 적다. laravelnews/laravel-twbs4가 더이상 개발이 안되고 있는 것인지 2점대 이상으로 버전이 올간건지 확인해보자.


깃헙 저장소릴리즈 페이지에 가보니 1.3.2가 최신 버전이다. 다른 패키지를 찾아야하는 건가 흑……


다행히 README를 보니 벨 5.6부터는 부트스트랩을 내장되기 때문에 이 패키지가 더이상 필요 없다고 한다.(설명을 빼먹었었는데 laravelnews/laravel-twbs4벨에서 부트스트랩4를 쉽게 쓸 수 있게 해주는 패키지였다.) laravelnews/laravel-twbs4를 제거하는 것으로 쉽게 문제가 해결됐다. 아래처럼 composer.json에서 제거한 후


// before
"laravel/tinker": "~1.0",
"laravelnews/laravel-twbs4": "^1.2",
"prettus/l5-repository": "^2.6",

// after
"laravel/tinker": "~1.0",
"prettus/l5-repository": "^2.6",

다시 컴포저 업데이트!


composer update
스크린샷 2019-07-17 오전 12.37.33.png

아…… 또 안되네. 아까 문제가 하나며. 문제를 한 번에 다 알려주는게 아니고 순차적으로 알려주는지는 나도 이번에 알게됐다.


아무튼 방법은 아까와 같다. 긴 메시지에 쫄지 않고 차분히 읽어보면 누구와 누가 충돌이 났는지 파악할 수 있다. 이번엔 graham-campbell/markdown이 문제다.


graham-campbell/markdown v9.0.0 requires illuminate/view 5.1.*|5.2.*|5.3.*|5.4.*|5.5.* -> satisfiable by laravel/framework[v5.5.32]

위의 메시지로 판단하자면 graham-campbell/markdown v9.0.0illuminate/view 5.5 이하 버전에 의존하고 있다. illuminate 패키지는 벨과 메이저 버전이 같으므로 벨 5.8은 illuminate/view 5.8.*에 의존할 것이다. 벨 최신 버전의 composer.json을 열어보면 알 수 있지만 그렇게하긴 번거로우므로 packagist에서 확인해보자. 

스크린샷 2019-07-17 오전 1.15.42.png

예상했던대로 버전 넘버가 같다. 어쨋든 벨 최신 버전이냐 graham-campbell/markdown v9.0.0를 두고 선택하는 것이기 때문에 이번에도 graham-campbell/markdown v9.0.0의 버전을 올리면 해결될지 다른 패키지로 바꿔야 할지 확인해보자.


이번에는 깃헙이 아닌 packagist에서 확인했다. packagist가 깃헙에 비해 버전별 의존성을 확인하기 쉽다. 의존성을 해결해야할 때는 packagist를 활용하자.

스크린샷 2019-07-17 오전 12.54.34.png


graham-campbell/markdown 최신 버전인 11.0.0은 illuminate/view 5.8에 의존한다. graham-campbell/markdown를 11버전으로 올리자. composer.json을 다음과 같이 변경한 후 업데이트했다.


// before
"graham-campbell/markdown": "^9.0",

// after
"graham-campbell/markdown": "^11.0",
스크린샷 2019-07-17 오전 12.59.08.png

설치에 성공했다.


마치며


다른 프로그래밍 환경에서도 의존성 관리 도구를 사용한 경험이 있다면 컴포저를 이해하고 사용하는데 큰 무리가 없을거 생각한다. 아직 프로그래밍 경험이 적거나, 전통적인 PHP 개발만 해오던 사람이면 의존성 개념도 생소하고, 의존성이 충돌하는 상황을 어떻게 해결해야 할지 익숙치 않을 것이다. 이번 글에서는 의존성이 충돌하는 상황을 어떻게 해결하는지 실제 사례를 들어 설명했다. 의존성을 해결하는 절차를 간단히 요약하면 다음과 같다.



  1. 에러 메시지에서 누구와 누구의 싸움인지 확인한다.

  2. 누구를 버리고 누구를 택할지 선택한다.

  3. 버릴 패키지를 업데이트해서 해결할 수 있는 상황인지, 업데이트로 해결이 가능하다면 어떤 버전을 쓰면 되는지 확인한다.

  4. 업데이트로 해결 가능하면 업데이트 하고, 그렇지 않으면 대안을 마련한다.

  5. 필요시 패키지를 사용하는 애플리케이션 코드를 수정한다. (이번 글에선 5번 내용은 다루지 않았다.)


===

2019년 7월 16
1 1




유료 구독자 전용 레터입니다.

한 달 1만원으로 매일 라라벨 관련 메일 받아보시고 과거 메일도 열람하세요. 일반 구독으로 공개글만 받아보실 수도 있습니다.

구독하기 버튼을 눌러주시면 구독과 동시에 xly에도 가입됩니다.

이현석

바쁜 팀장님 대신 알려주는 신입 PHP 개발자 안내서를 쓰고, 클린 아키텍처 인 PHP를 번역했습니다. 2020년에 출간될 Laravel Up & Running 2nd Edition을 번역하고 있습니다.