CompUnit::Repository::Installation — 모듈 설치를 위한 리포지토리

CompUnit::Repository::Installation — 모듈 설치를 위한 리포지토리 (Filesystem-backed installable repository)

Raku에서 배포판을 설치하고 불러오는 작업은 리포지토리(repository)라는 개념으로 관리돼요. 그중에서도 설치된 모듈을 담당하는 구현이 CompUnit::Repository::Installation이에요. 이 타입이 무엇을 해결해주고, 어떤 메서드를 제공하는지 살펴볼게요.

출처: Raku Documentation — CompUnit::Repository::Installation

본문

CompUnit::Repository::Installation은 파일시스템을 기반으로 하되, 내부 저장 형식을 사용하는 CompUnit::Repository 구현이에요. 그 내부 형식 덕분에 여러 문제를 해결해요.

class CompUnit::Repository::Installation
    does CompUnit::Repository::Locally
    does CompUnit::Repository::Installable
    { }

이 구현이 해결하는 것들:

  • CompUnit::Repository::FileSystem처럼 충돌할 수 있는 파일시스템의 대소문자 구분 문제를 다뤄요.
  • 파일시스템이 지원하지 않는 허용 파일명(예: 유니코드) 문제를 다뤄요.
  • 같은 이름이지만 verauth, api 값이 다른 여러 배포판을 하나의 리포지토리에 따로 설치·접근할 수 있게 해요.
  • 모듈 사전 컴파일(precompilation)을 제공해 모듈 로딩을 더 빠르게 해줘요.

내부 저장 형식 때문에, 배포판을 추가하는 일반적인 방법은 파일을 복사하는 게 아니라 install 메서드를 호출하는 거예요.

메서드

메서드 install

method install(Distribution $distribution, Bool :$force)

모듈을 특별한 위치에 복사해서 이후에 불러올 수 있게 해요.

:$force는 같은 name, auth, api, ver를 가진 기존 배포판 위에 설치하는 것을 허용해요. 그렇지 않으면 이런 상황은 Failure가 돼요.

my $inst-repo = CompUnit::RepositoryRegistry.repository-for-name("site");
my $dist = Distribution::Path.new(...);
$inst-repo.install($dist);

메서드 uninstall

method uninstall(Distribution $distribution)

$distribution을 리포지토리에서 제거해요. $distribution은 제거하는 그 리포지토리에서 얻어야 해요.

my $inst-repo = CompUnit::RepositoryRegistry.repository-for-name("site");
my $dist = $inst-repo.candidates("Acme::Unused").head;
$inst-repo.uninstall($dist);

메서드 candidates

multi method candidates(Str:D $name, :$auth, :$ver, :$api)
multi method candidates(CompUnit::DependencySpecification $spec)

지정한 $name, auth, ver, api에 맞는 모듈을 포함한 모든 배포판을 돌려줘요.

my $inst-repo-path = CompUnit::RepositoryRegistry.repository-for-name("perl").prefix;
my $inst-repo = CompUnit::Repository::Installation.new(prefix => $inst-repo-path);
my $dist = $inst-repo.candidates("Test").head;
say "Test version: " ~ $dist.meta<ver>; # OUTPUT: «6.d␤»

메서드 files

multi method files(Str:D $name, :$auth, :$ver, :$api)
multi method files(CompUnit::DependencySpecification $spec)

지정한 auth, ver, api에 맞고, 지정한 $name과 일치하는 비모듈(non-module) 파일을 포함한 모든 배포판을 돌려줘요.

# assuming Zef is installed to the default location...
my $repo = CompUnit::RepositoryRegistry.repository-for-name("site");

say $repo.files('bin/zef', :ver<419.0+>).head.<name>              // "Nada"; # OUTPUT: «Nada␤»
say $repo.files('resources/config.txt', :ver<419.0+>).head.<name> // "Nada"; # OUTPUT: «Nada␤»

say $repo.files('bin/zef', :ver<0.4.0+>).head.<name>;                        # OUTPUT: «zef␤»
say $repo.files('resources/config.txt', :ver<0.4.0+>).head.<name>;           # OUTPUT: «zef␤»

버전이 419.0 이상인 배포판에 bin/zef 파일이 없어서 "Nada" 폴백이 나오고, 실제 0.4.0대 배포판에서는 zef가 잡히는 모습이에요.

메서드 resolve

method resolve(CompUnit::DependencySpecification $spec --> CompUnit:D)

리포지토리 체인에서 $spec과 일치하는 어떤 버전의 배포판이라도 포함한 첫 리포지토리에서, $spec과 일치하는 가장 높은 버전 배포판에 매핑된 CompUnit을 돌려줘요.

메서드 need

method need(
    CompUnit::DependencySpecification $spec,
    CompUnit::PrecompilationRepository $precomp = self.precomp-repository(),
    CompUnit::PrecompilationStore :@precomp-stores = self!precomp-stores(),
    --> CompUnit:D)

resolve와 같은 규칙으로, 리포지토리 체인에서 $spec과 일치하는 어떤 버전이라도 포함한 첫 리포지토리의 가장 높은 버전 배포판에 매핑된 CompUnit불러온 뒤 돌려줘요.

메서드 load

method load(IO::Path:D $file --> CompUnit:D)

$file을 불러와 그것을 나타내는 CompUnit 객체를 돌려줘요.

메서드 loaded

method loaded(--> Iterable:D)

이 리포지토리가 불러온 모든 CompUnit을 돌려줘요.

메서드 short-id

method short-id()

리포지토리의 짧은 식별자를 돌려줘요. 이 리포지토리에서는 inst예요.

더 알아보기 (Learn more)