From e3bc066bd8f2bcf8433616b7610ef59ba04b679e Mon Sep 17 00:00:00 2001 From: Roman Melnikov Date: Tue, 18 Apr 2023 15:28:39 +0800 Subject: [#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. --- Cargo.lock | 28 ++++++++++------------------ src/push.rs | 27 ++++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 28b124e..ff195da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,10 +1,12 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "aho-corasick" -version = "0.7.15" +version = "0.7.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" dependencies = [ "memchr", ] @@ -390,9 +392,9 @@ checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" [[package]] name = "memchr" -version = "2.3.4" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "merge" @@ -657,21 +659,20 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "regex" -version = "1.4.2" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c" +checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" dependencies = [ "aho-corasick", "memchr", "regex-syntax", - "thread_local", ] [[package]] name = "regex-syntax" -version = "0.6.21" +version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "rnix" @@ -868,15 +869,6 @@ dependencies = [ "syn", ] -[[package]] -name = "thread_local" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" -dependencies = [ - "lazy_static", -] - [[package]] name = "time" version = "0.1.44" 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 .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(()) -- cgit v1.2.3 From c17d71fadf9a124ad6dd6af91944dbc2f0a60496 Mon Sep 17 00:00:00 2001 From: Roman Melnikov Date: Fri, 5 May 2023 15:04:26 +0800 Subject: fixup! [#202] Provide '^out' suffix for deriver on newer nix --- src/push.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/push.rs b/src/push.rs index 80fc537..ab4085c 100644 --- a/src/push.rs +++ b/src/push.rs @@ -43,6 +43,9 @@ pub enum PushProfileError { CopyExit(Option), #[error("The remote building option is not supported when using legacy nix")] RemoteBuildWithLegacyNix, + + #[error("Failed to run Nix path-info command: {0}")] + PathInfo(std::io::Error), } pub struct PushProfileData<'a> { @@ -251,18 +254,23 @@ pub async fn build_profile(data: PushProfileData<'_>) -> Result<(), PushProfileE .arg("--experimental-features").arg("nix-command") .arg("path-info") .arg(&deriver) - .output().await; + .output().await + .map_err(PushProfileError::PathInfo)?; - let deriver = match path_info_output { + let deriver = if std::str::from_utf8(&path_info_output.stdout).map(|s| s.trim()) == Ok(deriver) { // 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, + new_deriver + } else { + // 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. + // + // Alternatively, the result of the derivation build may not be 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 { -- cgit v1.2.3