CompUnit::Repository::Installation — 모듈 설치를 위한 리포지토리
CompUnit::Repository::Installation — 모듈 설치를 위한 리포지토리 (Filesystem-backed installable repository)
Raku에서 배포판을 설치하고 불러오는 작업은 리포지토리(repository)라는 개념으로 관리돼요. 그중에서도 설치된 모듈을 담당하는 구현이 CompUnit::Repository::Installation이에요. 이 타입이 무엇을 해결해주고, 어떤 메서드를 제공하는지 살펴볼게요.
본문
CompUnit::Repository::Installation은 파일시스템을 기반으로 하되, 내부 저장 형식을 사용하는 CompUnit::Repository 구현이에요. 그 내부 형식 덕분에 여러 문제를 해결해요.
class CompUnit::Repository::Installation
does CompUnit::Repository::Locally
does CompUnit::Repository::Installable
{ }
이 구현이 해결하는 것들:
- CompUnit::Repository::FileSystem처럼 충돌할 수 있는 파일시스템의 대소문자 구분 문제를 다뤄요.
- 파일시스템이 지원하지 않는 허용 파일명(예: 유니코드) 문제를 다뤄요.
- 같은 이름이지만
ver와auth,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예요.