Allow passing arbitrary fetchurl args per registry (#168)

Co-authored-by: Amos Wenger <amoswenger@gmail.com>
This commit is contained in:
Ivan Petkov 2022-11-20 16:22:13 -08:00 committed by GitHub
parent acbb22591c
commit e80de1e74a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 87 additions and 27 deletions

View File

@ -21,7 +21,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Note that `buildPackage` will continue to use zstd compressed tarballs while - Note that `buildPackage` will continue to use zstd compressed tarballs while
building dependencies (unless either of `cargoArtifacts` or building dependencies (unless either of `cargoArtifacts` or
`installCargoArtifactsMode` is defined, in which case they will be honored) `installCargoArtifactsMode` is defined, in which case they will be honored)
* **Breaking**: the format for defining crate registries has been changed: each
registry URL should map to a set containing a `downloadUrl` attribute. This
set may also define `fetchurlExtraArgs` (another set) which will be forwarded
to the
`fetchurl` invocations for crates for that registry.
* `registryFromGitIndex` now uses shallow checkouts for better performance * `registryFromGitIndex` now uses shallow checkouts for better performance
* `registryFromDownloadUrl` and `registryFromGitIndex` now allow specifying
`fetchurlExtraArgs` which will be forwarded to the `fetchurl` invocations for
crates for that registry
### Fixed ### Fixed
* Unpacking a git repository now ignores duplicate crates to match cargo's * Unpacking a git repository now ignores duplicate crates to match cargo's

View File

@ -44,12 +44,14 @@ newLib = lib.appendCrateRegistries [
(lib.registryFromDownloadUrl { (lib.registryFromDownloadUrl {
indexUrl = "https://github.com/rust-lang/crates.io-index"; indexUrl = "https://github.com/rust-lang/crates.io-index";
dl = "https://crates.io/api/v1/crates"; dl = "https://crates.io/api/v1/crates";
fetchurlExtraArgs = {};
}) })
# Or, alternatively # Or, alternatively
(lib.registryFromGitIndex { (lib.registryFromGitIndex {
indexUrl = "https://github.com/Hirevo/alexandrie-index"; indexUrl = "https://github.com/Hirevo/alexandrie-index";
rev = "90df25daf291d402d1ded8c32c23d5e1498c6725"; rev = "90df25daf291d402d1ded8c32c23d5e1498c6725";
fetchurlExtraArgs = {};
}) })
]; ];
``` ```
@ -648,6 +650,10 @@ raised during evaluation.
Download a packaged cargo crate (e.g. from crates.io) and prepare it for Download a packaged cargo crate (e.g. from crates.io) and prepare it for
vendoring. vendoring.
The registry's `fetchurlExtraArgs` will be passed through to `fetchurl` when
downloading the crate, making it possible to influence interacting with the
registry's API if necessary.
#### Required input attributes #### Required input attributes
* `checksum`: the (sha256) checksum recorded in the Cargo.lock file * `checksum`: the (sha256) checksum recorded in the Cargo.lock file
* `name`: the name of the crate * `name`: the name of the crate
@ -904,16 +910,29 @@ If the registry's download endpoint changes more frequently and you would like
to infer the configuration directly from a git revision, consider using to infer the configuration directly from a git revision, consider using
`registryFromGitIndex` as an alternative. `registryFromGitIndex` as an alternative.
If the registry needs a special way of accessing crate sources the
`fetchurlExtraArgs` set can be used to influence the behavior of fetching the
crate sources (e.g. by setting `curlOptsList`)
#### Required attributes #### Required attributes
* `dl`: the value of the `dl` entry in the registry's `config.json` file * `dl`: the value of the `dl` entry in the registry's `config.json` file
* `indexUrl`: an HTTP URL to the index * `indexUrl`: an HTTP URL to the index
#### Optional attributes
* `fetchurlExtraArgs`: a set of arguments which will be passed on to the
`fetchurl` for each crate being sourced from this registry
```nix ```nix
lib.registryFromDownloadUrl { lib.registryFromDownloadUrl {
dl = "https://crates.io/api/v1/crates"; dl = "https://crates.io/api/v1/crates";
indexUrl = "https://github.com/rust-lang/crates.io-index"; indexUrl = "https://github.com/rust-lang/crates.io-index";
} }
# { "registry+https://github.com/rust-lang/crates.io-index" = "https://crates.io/api/v1/crates/{crate}/{version}/download"; } # {
# "registry+https://github.com/rust-lang/crates.io-index" = {
# downloadUrl = "https://crates.io/api/v1/crates/{crate}/{version}/download";
# fetchurlExtraArgs = {};
# };
# }
``` ```
### `lib.registryFromGitIndex` ### `lib.registryFromGitIndex`
@ -934,24 +953,42 @@ specified revision will be added to the Nix store during evaluation time, and
that IFD will need to be enabled. If this is unsatisfactory, consider using that IFD will need to be enabled. If this is unsatisfactory, consider using
`registryFromDownloadUrl` as a simpler alternative. `registryFromDownloadUrl` as a simpler alternative.
If the registry needs a special way of accessing crate sources the
`fetchurlExtraArgs` set can be used to influence the behavior of fetching the
crate sources (e.g. by setting `curlOptsList`)
#### Required attributes #### Required attributes
* `indexUrl`: an HTTP URL to the index * `indexUrl`: an HTTP URL to the index
* `rev`: any git revision which contains the latest `config.json` definition * `rev`: any git revision which contains the latest `config.json` definition
#### Optional attributes
* `fetchurlExtraArgs`: a set of arguments which will be passed on to the
`fetchurl` for each crate being sourced from this registry
```nix ```nix
lib.registryFromGitIndex { lib.registryFromGitIndex {
url = "https://github.com/Hirevo/alexandrie-index"; url = "https://github.com/Hirevo/alexandrie-index";
rev = "90df25daf291d402d1ded8c32c23d5e1498c6725"; rev = "90df25daf291d402d1ded8c32c23d5e1498c6725";
} }
# { "registry+https://github.com/Hirevo/alexandrie-index" = "https://crates.polomack.eu/api/v1/crates/{crate}/{version}/download"; } # {
# "registry+https://github.com/Hirevo/alexandrie-index" = {
# downloadUrl = "https://crates.polomack.eu/api/v1/crates/{crate}/{version}/download";
# fetchurlExtraArgs = {};
# };
# }
``` ```
### `lib.urlForCargoPackage` ### `lib.urlForCargoPackage`
`urlForCargoPackage :: set -> String` `urlForCargoPackage :: set -> set`
Returns the URL for downloading a particular crate. For now, only crates.io is Returns info pertaining to the URL for downloading a particular crate if the
supported. crate's registry is configured (an error will be thrown if it is not).
The result will contain two attributes:
- `url`: A string representing the URL at which the crate can be fetched
- `fetchurlExtraArgs`: A set of attributes specific to this registry which will
be passed on to the `fetchurl` invocation.
#### Required input attributes #### Required input attributes
* `name`: the name of the crate * `name`: the name of the crate

View File

@ -35,6 +35,9 @@
(craneLibOrig.registryFromGitIndex { (craneLibOrig.registryFromGitIndex {
indexUrl = "https://github.com/Hirevo/alexandrie-index"; indexUrl = "https://github.com/Hirevo/alexandrie-index";
rev = "90df25daf291d402d1ded8c32c23d5e1498c6725"; rev = "90df25daf291d402d1ded8c32c23d5e1498c6725";
fetchurlExtraArgs = {
# Extra parameters which will be passed to the fetchurl invocation for each crate
};
}) })
# As a more lightweight alternative, the `dl` endpoint of the registry's `config.json` # As a more lightweight alternative, the `dl` endpoint of the registry's `config.json`
@ -42,6 +45,9 @@
# (craneLibOrig.registryFromDownloadUrl { # (craneLibOrig.registryFromDownloadUrl {
# indexUrl = "https://github.com/Hirevo/alexandrie-index"; # indexUrl = "https://github.com/Hirevo/alexandrie-index";
# dl = "https://crates.polomack.eu/api/v1/crates/{crate}/{version}/download"; # dl = "https://crates.polomack.eu/api/v1/crates/{crate}/{version}/download";
# fetchurlExtraArgs = {
# # Extra parameters which will be passed to the fetchurl invocation for each crate
# };
# }) # })
]; ];

View File

@ -9,11 +9,12 @@
, ... , ...
}@args: }@args:
let let
tarball = fetchurl { pkgInfo = urlForCargoPackage args;
tarball = fetchurl (pkgInfo.fetchurlExtraArgs // {
inherit (pkgInfo) url;
name = "${name}-${version}"; name = "${name}-${version}";
sha256 = checksum; sha256 = checksum;
url = urlForCargoPackage args; });
};
in in
runCommandLocal "cargo-package-${name}-${version}" { } '' runCommandLocal "cargo-package-${name}-${version}" { } ''
mkdir -p $out mkdir -p $out

View File

@ -4,6 +4,7 @@
# https://doc.rust-lang.org/cargo/reference/registries.html # https://doc.rust-lang.org/cargo/reference/registries.html
{ dl { dl
, indexUrl , indexUrl
, fetchurlExtraArgs ? {}
}: }:
let let
matches = m: builtins.match ".*${lib.escapeRegex m}.*" dl; matches = m: builtins.match ".*${lib.escapeRegex m}.*" dl;
@ -24,5 +25,8 @@ let
else "${registryPrefix}${indexUrl}"; else "${registryPrefix}${indexUrl}";
in in
{ {
"${registryIndexUrl}" = fullDownloadUrl; "${registryIndexUrl}" = {
inherit fetchurlExtraArgs;
downloadUrl = fullDownloadUrl;
};
} }

View File

@ -3,6 +3,7 @@
{ indexUrl { indexUrl
, rev , rev
, fetchurlExtraArgs ? {}
}: }:
let let
@ -26,5 +27,5 @@ let
''); '');
in in
registryFromDownloadUrl { registryFromDownloadUrl {
inherit dl indexUrl; inherit dl indexUrl fetchurlExtraArgs;
} }

View File

@ -19,7 +19,7 @@ let
else if nameLen == 3 then "3/${substr 0 1 name}" else if nameLen == 3 then "3/${substr 0 1 name}"
else "${substr 0 2 name}/${substr 2 4 name}"; else "${substr 0 2 name}/${substr 2 4 name}";
dl = crateRegistries.${source} or (throw '' registry = crateRegistries.${source} or (throw ''
not sure how to download crates from ${source}. not sure how to download crates from ${source}.
for example, this can be resolved with: for example, this can be resolved with:
@ -42,7 +42,9 @@ let
} }
''); '');
in in
builtins.replaceStrings {
fetchurlExtraArgs = registry.fetchurlExtraArgs or {};
url = builtins.replaceStrings
[ [
"{crate}" "{crate}"
"{version}" "{version}"
@ -57,4 +59,5 @@ builtins.replaceStrings
(lib.toLower prefix) (lib.toLower prefix)
checksum checksum
] ]
dl registry.downloadUrl;
}