Custom package repositories

Custom package repositories (사용자 정의 패키지 저장소)

dart pub 도구는 제3자 패키지 저장소를 지원해요. 패키지 저장소는 dart pub 도구가 사용할 Dart 패키지를 호스팅하는 서버예요. 기본적으로 사용되는 저장소인 pub.dev는 Dart 팀이 운영하며, 공개용으로 Dart 패키지를 게시하기 쉽게 해 주는 곳이에요. 패키지 저장소는 hosted-url로 식별되는데, 예를 들면 https://dart-packages.example.com/ 같은 형식이에요.

사용자 정의 패키지 저장소가 유용한 경우도 있어요. 특히 개인(private) 패키지를 호스팅할 때 그런데, 대표적인 시나리오는 이렇습니다.

  • 조직 내에서 내부 독점 패키지를 공유하는 경우
  • 엔터프라이즈 환경에서 의존성을 엄격하게 통제하는 경우
  • 공개 인터넷에 접속할 수 없는 보안 환경

개인 패키지를 호스팅할 때 git-dependencies를 쓰는 것도 흔하지만, dart pub 도구는 git 저장소에 대해 버전 해석을 지원하지 않아요. 단지 git 저장소의 특정 리비전을 가져올 뿐이죠. 그래서 여러 사람이 협업할 때는 보통 개인 패키지 저장소를 사용하는 편이 좋아요.

출처: Custom package repositories

본문

사용자 정의 패키지 저장소와 인증

대부분의 사용자 정의 패키지 저장소는 인증이 필요한 개인 패키지 저장소예요. 사용자 정의 패키지 저장소에 인증하기 위해 dart pub 도구는 요청에 secret token(비밀 토큰)을 붙여요.

secret token은 사용자 정의 패키지 저장소에서 얻을 수 있고, 직접 지정하거나 환경 변수를 통해 지정할 수 있어요. secret token을 직접 지정하려면 토큰을 입력하라는 프롬프트가 뜨는 dart pub token add 명령어를 사용해요.

$ dart pub token add https://dart-packages.example.com
Enter secret token: [enter secret token]
Requests to "https://dart-packages.example.com" will now be authenticated using the secret token.

CI 환경을 포함해 토큰을 환경 변수에서 읽도록 dart pub에 알려줄 수도 있는데, --env-var 플래그를 사용해요.

$ dart pub token add https://dart-packages.example.com --env-var MY_SECRET_TOKEN
Requests to "https://dart-packages.example.com" will now be authenticated using the secret token stored in the environment variable "MY_SECRET_TOKEN".

이렇게 하면 dart pub이 secret token을 실제로 설정(configuration)에 저장하지 않아요. 대신 $MY_SECRET_TOKEN 환경 변수에서 secret을 읽어야 한다는 사실만 저장해요. 이는 CI 작업 간에 실행 환경을 공유할 때 secret이 실수로 유출될 위험을 줄여줘요.

사용자 정의 패키지 저장소에서 의존성 가져오기

사용자 정의 패키지 저장소에서 패키지를 가져오려면 pubspec.yaml에서 호스트된 패키지(hyphenated hosted package) 문법을 사용해 그 패키지의 hosted-url을 지정해야 해요. 예를 들어:

dependencies:
  example_package:
    hosted: https://dart-packages.example.com
    version: ^1.4.0

앞의 예제에서 package:example_packagehttps://dart-packages.example.com에서 가져와요. 이 패키지 저장소가 인증을 요구한다면, 요청을 인증하는 방법은 사용자 정의 패키지 저장소와 인증을 참고하세요.

dart pub add 명령어에 --hosted 플래그를 사용해서 사용자 정의 패키지 저장소의 의존성을 추가할 수도 있어요.

$ dart pub add example_package --hosted https://dart-packages.example.com

여러 패키지 저장소 사용하기

각 의존성에 hosted-url을 지정할 수 있으므로, 서로 다른 패키지 저장소에서 서로 다른 의존성을 가져올 수도 있어요.

dependencies:
  # package retry는 pub.dev(기본 패키지 저장소)에서 가져옵니다
  retry: ^3.0.0
  # package example_package는 https://dart-packages.example.com에서 가져옵니다
  example_package:
    hosted: https://dart-packages.example.com
    version: ^1.4.0

이렇게 하면 가장 최신의 공개 패키지를 의존성으로 사용하면서 개인 패키지는 개인 패키지 저장소에 유지할 수 있어요.

다만 의존성들이 서로 다른 저장소에서 같은 이름의 패키지를 요구하면 충돌이 쉽게 생길 수 있어요. 예를 들어 retry 패키지가 pub.dev에서 meta를 요구하고, example_packagehttps://dart-packages.example.com에서 meta를 요구하는 경우죠. 그래서 어떤 패키지를 개인 패키지 저장소로 미러링(mirroring)한다면 모든 의존성을 미러링하고, 각 패키지의 dependencies 섹션을 업데이트하거나 기본 패키지 저장소를 override하는 것이 필요한 경우가 많아요.

사용자 정의 패키지 저장소에 게시하기

pub.dev 대신 사용자 정의 패키지 저장소에 패키지를 게시하려면 pubspec.yamlpublish_to 속성을 지정해요. 인증이 활성화되어 있으면, 패키지를 가져올 때와 같은 토큰 인증을 사용해 게시해요.

https://dart-packages.example.com에 게시할 패키지를 준비하려면 pubspec.yaml은 최소한 다음과 같이 생겨야 해요.

name: example_package
version: 1.0.0
# 패키지가 https://dart-packages.example.com에 게시되도록 보장합니다
publish_to: https://dart-packages.example.com

그런 다음 패키지의 새 버전을 게시하려면 dart pub publish를 사용해요.

$ dart pub publish
Publishing example_package 1.0.0 to https://dart-packages.example.com
|-- CHANGELOG.md
|-- LICENSE
|-- README.md
|-- lib
|   '-- example_package.dart
'-- pubspec.yaml
...

기본 패키지 저장소 override

기본적으로 dart pub은 호스트된 의존성 문법으로 사용자 정의 패키지 저장소를 지정하지 않는 한, pub.dev 사이트에서 의존성을 가져오고 pub.dev에 패키지를 게시해요. 다만 PUB_HOSTED_URL 환경 변수를 사용해 기본 패키지 저장소를 override할 수 있어요.

이 방법은 제한된 네트워크 환경에서 작업할 때 개인 패키지 저장소나 pub.dev의 일부를 모든 패키지로 미러링하는 경우 특히 유용해요.

사용자 정의 패키지 저장소 설정하기

Hosted Pub Repository Specification Version 2에 정의된 REST API를 구현해서 사용자 정의 패키지 저장소를 직접 작성할 수 있어요.

서비스로서의 Dart 패키지 저장소

사용자 정의 패키지 저장소는 여러 벤더가 토큰 인증을 지원하며 서비스로도 제공돼요. 직접 저장소를 호스팅하고 유지 관리하는 부담을 덜 수 있어요.

  • Cloudsmith
  • Inedo ProGet
  • JFrog Artifactory
  • OnePub Dart Repository
  • Publy
  • GLPub.dev

더 알아보기