Home Explore Blog Models CI



nixpkgs

8th chunk of `doc/build-helpers/fetchers.chapter.md`
fe3551b1c14a8450be8188065cb5ffbacf100fcb6767b9a80000000100000fb3
:::{.example #ex-fetchers-fetchurl-nixpkgs-version}
# Using `fetchurl` to download a file

The following package downloads a small file from a URL and shows the most common way to use `fetchurl`:

```nix
{ fetchurl }:
fetchurl {
  url = "https://raw.githubusercontent.com/NixOS/nixpkgs/23.11/.version";
  hash = "sha256-BZqI7r0MNP29yGH5+yW2tjU9OOpOCEvwWKrWCv5CQ0I=";
}
```

After building the package, the file will be downloaded and place into the Nix store:

```shell
$ nix-build
(output removed for clarity)
/nix/store/4g9y3x851wqrvim4zcz5x2v3zivmsq8n-version

$ cat /nix/store/4g9y3x851wqrvim4zcz5x2v3zivmsq8n-version
23.11
```
:::

:::{.example #ex-fetchers-fetchurl-nixpkgs-version-multiple-urls}
# Using `fetchurl` to download a file with multiple possible URLs

The following package adapts [](#ex-fetchers-fetchurl-nixpkgs-version) to use multiple URLs.
The first URL was crafted to intentionally return an error to illustrate how `fetchurl` will try multiple URLs until it finds one that works (or all URLs fail).

```nix
{ fetchurl }:
fetchurl {
  urls = [
    "https://raw.githubusercontent.com/NixOS/nixpkgs/23.11/does-not-exist"
    "https://raw.githubusercontent.com/NixOS/nixpkgs/23.11/.version"
  ];
  hash = "sha256-BZqI7r0MNP29yGH5+yW2tjU9OOpOCEvwWKrWCv5CQ0I=";
}
```

After building the package, both URLs will be used to download the file:

```shell
$ nix-build
(some output removed for clarity)
trying https://raw.githubusercontent.com/NixOS/nixpkgs/23.11/does-not-exist
(some output removed for clarity)
curl: (22) The requested URL returned error: 404

trying https://raw.githubusercontent.com/NixOS/nixpkgs/23.11/.version
(some output removed for clarity)
/nix/store/n9asny31z32q7sdw6a8r1gllrsfy53kl-does-not-exist

$ cat /nix/store/n9asny31z32q7sdw6a8r1gllrsfy53kl-does-not-exist
23.11
```

However, note that the name of the file was derived from the first URL (this is further explained in [the `fetchurl` overview](#sec-pkgs-fetchers-fetchurl)).
To ensure the result will have the same name regardless of which URLs are used, we can modify the package:

```nix
{ fetchurl }:
fetchurl {
  name = "nixpkgs-version";
  urls = [
    "https://raw.githubusercontent.com/NixOS/nixpkgs/23.11/does-not-exist"
    "https://raw.githubusercontent.com/NixOS/nixpkgs/23.11/.version"
  ];
  hash = "sha256-BZqI7r0MNP29yGH5+yW2tjU9OOpOCEvwWKrWCv5CQ0I=";
}
```

After building the package, the result will have the name we specified:

```shell
$ nix-build
(output removed for clarity)
/nix/store/zczb6wl3al6jm9sm5h3pr6nqn0i5ji9z-nixpkgs-version
```
:::

:::{.example #ex-fetchers-fetchurl-nixpkgs-version-postfetch}
# Manipulating the content downloaded by `fetchurl`

It might be useful to manipulate the content downloaded by `fetchurl` directly in its derivation.
In this example, we'll adapt [](#ex-fetchers-fetchurl-nixpkgs-version) to append the result of running the `hello` package to the contents we download, purely to illustrate how to manipulate the content.

```nix
{
  fetchurl,
  hello,
  lib,
}:
fetchurl {
  url = "https://raw.githubusercontent.com/NixOS/nixpkgs/23.11/.version";

  nativeBuildInputs = [ hello ];

  downloadToTemp = true;
  postFetch = ''
    ${lib.getExe hello} >> $downloadedFile
    mv $downloadedFile $out
  '';

  hash = "sha256-ceooQQYmDx5+0nfg40uU3NNI2yKrixP7HZ/xLZUNv+w=";
}
```

After building the package, the resulting file will have "Hello, world!" appended to it:

```shell
$ nix-build
(output removed for clarity)
/nix/store/ifi6pp7q0ag5h7c5v9h1c1c7bhd10c7f-version

$ cat /nix/store/ifi6pp7q0ag5h7c5v9h1c1c7bhd10c7f-version
23.11
Hello, world!
```

Note that the `hash` specified in the package is different than the hash specified in [](#ex-fetchers-fetchurl-nixpkgs-version), because the contents of the output have changed (even though the actual file that was downloaded is the same).
See [](#chap-pkgs-fetchers-caveats) for more details on how to work with the `hash` attribute when the output changes.
:::

## `fetchzip` {#sec-pkgs-fetchers-fetchzip}

Title: `fetchurl` Advanced Usage: Multiple URLs and Post-Fetch Manipulation
Summary
This chunk provides examples of `fetchurl` usage in Nix. It first demonstrates the basic method of downloading a single file using `fetchurl` with a URL and hash. Subsequent examples show how to use `fetchurl` with multiple `urls` to provide fallback options, where it will attempt each URL until a successful download occurs. It also illustrates how to explicitly set the output `name` of the downloaded file, which is especially useful when using multiple URLs, as the default name is derived from the first URL. Finally, an example showcases how to manipulate the downloaded content using `postFetch` by temporarily downloading the file to a temporary location (`downloadToTemp = true`), appending output from another package (`hello` in this case), and then moving the modified content to the final output path. This also highlights the necessity of updating the `hash` when the content is modified post-download.