aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRoman Melnikov2023-04-18 15:28:39 +0800
committerRoman Melnikov2023-05-05 14:57:31 +0800
commite3bc066bd8f2bcf8433616b7610ef59ba04b679e (patch)
treeccc150b4d16ebcc173a651c1e1cbc2039fcb029b /src
parent8c9ea9605eed20528bf60fae35a2b613b901fd77 (diff)
[#202] Provide '^out' suffix for deriver on newer nix
Problem: Since 2.15 nix no longer reference '.drv' as derivation outputs. At the same time, nix before '2.13' doesn't support '.drv' special suffix handling. Solution: Provide '^out' suffix for the profile deriver in case 'nix path-info <...>.drv' returns the same '<...>.drv' path. In other cases either an error about the build result not being present in the /nix/store is returned or an actual build result path is returned.
Diffstat (limited to 'src')
-rw-r--r--src/push.rs27
1 files changed, 24 insertions, 3 deletions
diff --git a/src/push.rs b/src/push.rs
index 6d9f10d..80fc537 100644
--- a/src/push.rs
+++ b/src/push.rs
@@ -238,19 +238,40 @@ pub async fn build_profile(data: PushProfileData<'_>) -> Result<(), PushProfileE
)
.map_err(PushProfileError::ShowDerivationParse)?;
- let derivation_name = derivation_info
+ let &deriver = derivation_info
.keys()
.next()
.ok_or(PushProfileError::ShowDerivationEmpty)?;
+ // Since nix 2.15.0 'nix build <path>.drv' will build only the .drv file itself, not the
+ // derivation outputs, '^out' is used to refer to outputs explicitly
+ let new_deriver = &(deriver.to_owned().to_string() + "^out");
+
+ let path_info_output = Command::new("nix")
+ .arg("--experimental-features").arg("nix-command")
+ .arg("path-info")
+ .arg(&deriver)
+ .output().await;
+
+ let deriver = match path_info_output {
+ // In this case we're on 2.15.0 or newer, because 'nix path-infonix path-info <...>.drv'
+ // returns the same '<...>.drv' path.
+ // If 'nix path-info <...>.drv' returns a different path, then we're on pre 2.15.0 nix and
+ // derivation build result is already present in the /nix/store.
+ Ok(path) if std::str::from_utf8(&path.stdout).map(|s| s.trim()) == Ok(deriver) => new_deriver,
+ // At this point, we're sure that derivation path is valid, but
+ // the result of the derivation build is not yet present in the /nix/store.
+ // In this case, 'nix path-info' returns 'error: path '...' is not valid'.
+ _ => deriver,
+ };
if data.deploy_data.merged_settings.remote_build.unwrap_or(false) {
if !data.supports_flakes {
return Err(PushProfileError::RemoteBuildWithLegacyNix)
}
- build_profile_remotely(&data, derivation_name).await?;
+ build_profile_remotely(&data, &deriver).await?;
} else {
- build_profile_locally(&data, derivation_name).await?;
+ build_profile_locally(&data, &deriver).await?;
}
Ok(())