Skip to content

Commit 6416027

Browse files
authored
Merge pull request #203 from serokell/rvem/#202-add-workaround-for-derivations-store-paths-interpolation
[#202] Provide '^out' suffix for deriver on newer nix
2 parents 6b0b6a1 + c17d71f commit 6416027

File tree

2 files changed

+40
-21
lines changed

2 files changed

+40
-21
lines changed

Cargo.lock

Lines changed: 8 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/push.rs

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ pub enum PushProfileError {
4343
CopyExit(Option<i32>),
4444
#[error("The remote building option is not supported when using legacy nix")]
4545
RemoteBuildWithLegacyNix,
46+
47+
#[error("Failed to run Nix path-info command: {0}")]
48+
PathInfo(std::io::Error),
4649
}
4750

4851
pub struct PushProfileData<'a> {
@@ -236,19 +239,45 @@ pub async fn build_profile(data: PushProfileData<'_>) -> Result<(), PushProfileE
236239
)
237240
.map_err(PushProfileError::ShowDerivationParse)?;
238241

239-
let derivation_name = derivation_info
242+
let &deriver = derivation_info
240243
.keys()
241244
.next()
242245
.ok_or(PushProfileError::ShowDerivationEmpty)?;
243246

247+
// Since nix 2.15.0 'nix build <path>.drv' will build only the .drv file itself, not the
248+
// derivation outputs, '^out' is used to refer to outputs explicitly
249+
let new_deriver = &(deriver.to_owned().to_string() + "^out");
250+
251+
let path_info_output = Command::new("nix")
252+
.arg("--experimental-features").arg("nix-command")
253+
.arg("path-info")
254+
.arg(&deriver)
255+
.output().await
256+
.map_err(PushProfileError::PathInfo)?;
257+
258+
let deriver = if std::str::from_utf8(&path_info_output.stdout).map(|s| s.trim()) == Ok(deriver) {
259+
// In this case we're on 2.15.0 or newer, because 'nix path-infonix path-info <...>.drv'
260+
// returns the same '<...>.drv' path.
261+
// If 'nix path-info <...>.drv' returns a different path, then we're on pre 2.15.0 nix and
262+
// derivation build result is already present in the /nix/store.
263+
new_deriver
264+
} else {
265+
// If 'nix path-info <...>.drv' returns a different path, then we're on pre 2.15.0 nix and
266+
// derivation build result is already present in the /nix/store.
267+
//
268+
// Alternatively, the result of the derivation build may not be yet present
269+
// in the /nix/store. In this case, 'nix path-info' returns
270+
// 'error: path '...' is not valid'.
271+
deriver
272+
};
244273
if data.deploy_data.merged_settings.remote_build.unwrap_or(false) {
245274
if !data.supports_flakes {
246275
return Err(PushProfileError::RemoteBuildWithLegacyNix)
247276
}
248277

249-
build_profile_remotely(&data, derivation_name).await?;
278+
build_profile_remotely(&data, &deriver).await?;
250279
} else {
251-
build_profile_locally(&data, derivation_name).await?;
280+
build_profile_locally(&data, &deriver).await?;
252281
}
253282

254283
Ok(())

0 commit comments

Comments
 (0)