(dependency-management-npins)=
# `npins`로 원격 소스 자동 관리하기

Nix 언어는 Nix가 관리하는 파일 사이의 의존성을 기술합니다. Nix 표현식 자체도 원격 소스에 의존할 수 있으며, [](pinning-nixpkgs)에서 볼 수 있듯이 그 출처를 지정하는 방법은 여러 가지입니다.

원격 소스 처리를 더 자동화하려면 프로젝트에 [`npins`](https://github.com/andir/npins/)를 설정하십시오:

```shell-session
$ nix-shell -p npins --run "npins init --bare; npins add github nixos nixpkgs --branch nixos-23.11"
```

이 명령은 Nixpkgs 23.11 릴리스 브랜치의 최신 리비전을 가져옵니다. 현재 디렉터리에 `npins/sources.json`을 생성하며, 이 파일에는 가져온 리비전에 대한 고정 참조가 들어 있습니다. 또한 해당 의존성을 속성 집합으로 노출하는 `npins/default.nix`도 생성합니다.

생성된 `npins/default.nix`를 `default.nix`에 있는 함수 인자의 기본값으로 가져오고, 이를 사용해 Nixpkgs 소스 디렉터리를 참조하십시오:

```nix
{
  sources ? import ./npins,
  system ? builtins.currentSystem,
  pkgs ? import sources.nixpkgs { inherit system; config = {}; overlays = []; },
}:
{
  package = pkgs.hello;
}
```

`nix-build`는 최상위 함수를 빈 속성 집합 `{}`로 호출하거나, [`--arg`](https://nix.dev/manual/nix/stable/command-ref/nix-build#opt-arg) 또는 [`--argstr`](https://nix.dev/manual/nix/stable/command-ref/nix-build#opt-argstr)로 전달된 속성으로 호출합니다. 이 패턴을 사용하면 프로그래밍 방식으로 [원격 소스를 오버라이드](overriding-sources-npins)할 수 있습니다.

`npins`를 바로 사용할 수 있도록 프로젝트의 개발 환경에 추가하십시오:

```diff
 {
   sources ? import ./npins,
   system ? builtins.currentSystem,
   pkgs ? import sources.nixpkgs { inherit system; config = {}; overlays = []; },
 }:
-{
+rec {
   package = pkgs.hello;
+  shell = pkgs.mkShellNoCC {
+    inputsFrom = [ package ];
+    packages = with pkgs; [
+      npins
+    ];
+  };
 }
```

해당 환경에 더 편리하게 진입할 수 있도록 `shell.nix`도 추가하십시오:

```nix
(import ./. {}).shell
```

자세한 내용은 [](./sharing-dependencies)를 참고하십시오. 이제 `default.nix`에 함수가 들어 있으므로, 여기서는 가져온 표현식에 빈 속성 집합을 전달해야 한다는 점에 유의하십시오.

(overriding-sources-npins)=
## 소스 오버라이드하기

예시로, 앞에서 만든 표현식을 더 오래된 버전의 Nixpkgs와 함께 사용하겠습니다.

개발 환경에 진입하여 새 디렉터리를 만들고, 다른 버전의 Nixpkgs로 npins를 설정하십시오:

```shell-session
$ nix-shell
[nix-shell]$ mkdir old
[nix-shell]$ cd old
[nix-shell]$ npins init --bare
[nix-shell]$ npins add github nixos nixpkgs --branch nixos-21.11
```

새 디렉터리에 `default.nix` 파일을 만들어, 방금 생성한 `sources`로 원래 파일을 가져오십시오.

```nix
import ../default.nix { sources = import ./npins; }
```

그러면 다른 버전이 빌드됩니다:

```shell-session
$ nix-build -A build
$ ./result/bin/hello --version | head -1
hello (GNU Hello) 2.10
```

소스는 명령줄에서도 오버라이드할 수 있습니다:

```shell-session
nix-build .. -A build --arg sources 'import ./npins'
```

## `niv`에서 마이그레이션하기

이 가이드의 이전 버전에서는 Haskell로 작성된 유사한 고정 관리 도구인 [`niv`](https://github.com/nmattia/niv/)를 사용하도록 권장했습니다.

`niv`를 사용하는 프로젝트가 있다면 원격 소스 정의를 `npins`로 가져올 수 있습니다:

```shell-session
npins import-niv
```

:::{warning}
가져온 항목은 모두 업데이트되므로, 반드시 이전과 같은 커밋을 가리키지는 않습니다.
:::

## NixOS 설정 관리하기

NixOS는 기본적으로 채널을 사용하여 `nixpkgs`의 위치를 찾습니다. 대신 `system.nix` 진입점(26.05부터 사용 가능)에서 `npins`를 사용하여 버전을 고정할 수 있습니다:

```nix
let
  sources = import ./npins;
in
import "${sources.nixpkgs}/nixos" {
  configuration = ./configuration.nix;
}
```

NixOS 26.05의 `system.nix` 이전에는 다음을 사용하십시오:

```bash
sudo NIX_PATH="nixos-config=configuration.nix:nixpkgs=$(nix-instantiate --raw --eval npins -A nixpkgs.outPath)" nixos-rebuild switch
```

`system.nix`와 함께 npins를 사용한다면 설정에서 채널을 비활성화하십시오:

```nix
# configuration.nix
{
  # ...
  nix.channel.enable = false;
}
```

NixOS 설정을 사용하는 동안 이렇게 고정된 의존성을 (`<nixpkgs>`와 같은) [조회 경로](https://nix.dev/tutorials/nix-language.html#lookup-paths)로 사용할 수 있게 하려면 다음을 사용할 수 있습니다:

```nix
# configuration.nix
{ lib, ... }:
let
  sources = import ./npins;
in
{
  # ...
  nix.nixPath = lib.mapAttrsToList (k: v: "${k}=${v}") sources;
}
```

[v3 명령줄][v3 command line]을 사용하여 `nix run nixpkgs#hello`처럼 [플레이크][flake]를 통해 패키지를 노출하는 의존성의 프로그램을 실행하려면, 다음과 같이 플레이크를 활성화하고 고정 항목을 플레이크 레지스트리에 추가할 수 있습니다:

```nix
# configuration.nix
{ lib, ... }:
let
  sources = import ./npins;
in
{
  # ...
  experimental-features = "nix-command flakes";
  nix.registry = lib.mapAttrs (_: path: {
    to = {
      type = "path";
      inherit path;
    };
  }) sources;
```

[v3 command line]: https://nix.dev/manual/nix/stable/command-ref/new-cli/nix.html
[flake]: https://nix.dev/concepts/flakes

## 다음 단계

- 자세한 내용은 내장 도움말을 확인하십시오:

  ```shell-session
  npins --help
  ```

- 원격 소스를 지정하는 여러 가지 방법에 대한 자세한 내용과 예시는 [](pinning-nixpkgs)를 참고하십시오.
