cargo-outdated icon indicating copy to clipboard operation
cargo-outdated copied to clipboard

Error running in project with custom target file

Open phijor opened this issue 3 years ago • 0 comments

Problem

cargo outdated fails to run when a project specifies a custom target file:

error: target path "/tmp/cargo-outdated2acTI1/x86_64-custom.json" is not a valid file

Caused by:
  No such file or directory (os error 2)

I assume that the custom target file is not copied over to the temporary copy of the project, so cargo cannot find it and fails to run.

Reproduction

Here's a script to reproduce a MWE:

#!/bin/env bash
# repro.sh

set -e

PROJECT=$1

echo ":: Creating new project $PROJECT"
cargo new $PROJECT

cd $PROJECT
mkdir .cargo

TARGET="x86_64-custom.json"

echo ":: Creating custom target .json"
rustc +nightly -Z unstable-options \
    --print target-spec-json \
    --target x86_64-unknown-linux-gnu \
    | jq 'del(.["is-builtin"])' \
    | tee $TARGET \
    | jq

echo ":: Creating Cargo config file:"
tee .cargo/config.toml <<EOF
[build]
target = "$TARGET"
EOF

echo ":: Trying to run cargo outdated:"
cargo outdated

The first argument is the name of the project directory:

$ bash repro.sh $(mktemp -u mwe-XXXX)

Fix

There might be two ways to solve this problem:

  1. also copy over the custom target .json
  2. delete build.target from .cargo/config{,.toml}

I tried my hands at a (crude) implementation of 2., that seems to work:

diff --git a/src/cargo_ops/temp_project.rs b/src/cargo_ops/temp_project.rs
index 695d56b..1dc16f0 100644
--- a/src/cargo_ops/temp_project.rs
+++ b/src/cargo_ops/temp_project.rs
@@ -129,26 +129,46 @@ impl<'tmp> TempProject<'tmp> {
             }
         }
 
+        let copy_cargo_config = |name: &str| -> CargoResult<()> {
+            let config_path = workspace_root.join(".cargo").join(name);
+            if config_path.is_file() {
+                let mut config: ::toml::Value = {
+                    let mut buf = String::new();
+                    let mut file = File::open(&config_path)?;
+                    file.read_to_string(&mut buf)?;
+                    ::toml::from_str(&buf)?
+                };
+
+                if let Some(::toml::Value::Table(build)) = config.get_mut("build") {
+                    let _ = build.remove("target");
+                }
+
+                fs::create_dir_all(temp_dir.path().join(".cargo"))?;
+
+                let dest = temp_dir.path().join(".cargo").join(name);
+
+                let config_serialized = ::toml::to_string(&config)
+                    .expect("Cannot format cargo config file as toml file");
+                let mut config_toml = OpenOptions::new()
+                    .read(true)
+                    .write(true)
+                    .create(true)
+                    .truncate(true)
+                    .open(&dest)?;
+                write!(config_toml, "{}", config_serialized)?;
+            }
+
+            Ok(())
+        };
+
         //.cargo/config.toml
         // this is the preferred way
         // https://doc.rust-lang.org/cargo/reference/config.html
-        if workspace_root.join(".cargo/config.toml").is_file() {
-            fs::create_dir_all(temp_dir.path().join(".cargo"))?;
-            fs::copy(
-                &workspace_root.join(".cargo/config.toml"),
-                temp_dir.path().join(".cargo/config.toml"),
-            )?;
-        }
+        copy_cargo_config("config.toml")?;
 
         //.cargo/config
         // this is legacy support for config files without the `.toml` extension
-        if workspace_root.join(".cargo/config").is_file() {
-            fs::create_dir_all(temp_dir.path().join(".cargo"))?;
-            fs::copy(
-                &workspace_root.join(".cargo/config"),
-                temp_dir.path().join(".cargo/config"),
-            )?;
-        }
+        copy_cargo_config("config")?;
 
         let relative_manifest = String::from(&orig_manifest[workspace_root_str.len() + 1..]);
         let config = Self::generate_config(temp_dir.path(), &relative_manifest, options)?;

phijor avatar May 10 '22 17:05 phijor