feat(tvix/cli): bundle corepkgs/fetchurl.nix with tvix-cli

This file which ships with C++ Nix is required for evaluating nixpkgs.
Like C++ Nix, we now inject a pseudo path in EvalIO from which this
will resolve as <nix/fetchurl.nix>

Change-Id: Ic948c476a2cfc6381d5655d308bc2d5fa25b7123
Reviewed-on: https://cl.tvl.fyi/c/depot/+/8213
Reviewed-by: raitobezarius <tvl@lahfa.xyz>
Tested-by: BuildkiteCI
This commit is contained in:
Vincent Ambo 2023-03-04 03:43:59 +03:00 committed by tazjin
parent c700776733
commit a59e264457
3 changed files with 76 additions and 1 deletions

53
tvix/cli/src/fetchurl.nix Normal file
View file

@ -0,0 +1,53 @@
# SPDX-License-Identifier: LGPL-2.1
#
# This file is vendored from C++ Nix, as it needs to be bundled with
# an evaluator to be able to evaluate nixpkgs.
#
# Source: https://github.com/NixOS/nix/blob/2.3.16/corepkgs/fetchurl.nix
{ system ? "" # obsolete
, url
, hash ? "" # an SRI hash
# Legacy hash specification
, md5 ? ""
, sha1 ? ""
, sha256 ? ""
, sha512 ? ""
, outputHash ? if hash != "" then hash else if sha512 != "" then sha512 else if sha1 != "" then sha1 else if md5 != "" then md5 else sha256
, outputHashAlgo ? if hash != "" then "" else if sha512 != "" then "sha512" else if sha1 != "" then "sha1" else if md5 != "" then "md5" else "sha256"
, executable ? false
, unpack ? false
, name ? baseNameOf (toString url)
}:
derivation {
builder = "builtin:fetchurl";
# New-style output content requirements.
inherit outputHashAlgo outputHash;
outputHashMode = if unpack || executable then "recursive" else "flat";
inherit name url executable unpack;
system = "builtin";
# No need to double the amount of network traffic
preferLocalBuild = true;
impureEnvVars = [
# We borrow these environment variables from the caller to allow
# easy proxy configuration. This is impure, but a fixed-output
# derivation like fetchurl is allowed to do so since its result is
# by definition pure.
"http_proxy"
"https_proxy"
"ftp_proxy"
"all_proxy"
"no_proxy"
];
# To make "nix-prefetch-url" work.
urls = [ url ];
}

View file

@ -56,7 +56,15 @@ fn interpret(code: &str, path: Option<PathBuf>, args: &Args, explain: bool) -> b
let known_paths: Rc<RefCell<KnownPaths>> = Default::default();
eval.io_handle = Box::new(nix_compat::NixCompatIO::new(known_paths.clone()));
eval.nix_path = args.nix_search_path.clone();
// bundle fetchurl.nix (used in nixpkgs) by resolving <nix> to
// `/__corepkgs__`, which has special handling in [`nix_compat`].
eval.nix_path = args
.nix_search_path
.as_ref()
.map(|p| format!("nix=/__corepkgs__:{}", p))
.or_else(|| Some("nix=/__corepkgs__".to_string()));
eval.builtins
.extend(derivation::derivation_builtins(known_paths));

View file

@ -59,10 +59,24 @@ impl EvalIO for NixCompatIO {
// Pass the rest of the functions through to `Self::underlying`
fn path_exists(&self, path: PathBuf) -> Result<bool, ErrorKind> {
if path.starts_with("/__corepkgs__") {
return Ok(true);
}
self.underlying.path_exists(path)
}
fn read_to_string(&self, path: PathBuf) -> Result<String, ErrorKind> {
// Bundled version of corepkgs/fetchurl.nix. This workaround
// is similar to what cppnix does for passing the path
// through.
//
// TODO: this comparison is bad and allocates, we should use
// the sane path library.
if path.starts_with("/__corepkgs__/fetchurl.nix") {
return Ok(include_str!("fetchurl.nix").to_string());
}
self.underlying.read_to_string(path)
}