Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

krates 0.18.0 fails to parse cargo metadata of project that uses unstable artifacts dependency declarations #100

Closed
ginglis13 opened this issue Feb 26, 2025 · 1 comment · Fixed by #101
Labels
bug Something isn't working

Comments

@ginglis13
Copy link

ginglis13 commented Feb 26, 2025

Describe the bug

twoliter is a build tool used by the Bottlerocket project. The tool uses artifact dependency declarations, which is an unstable feature provided in nightly rust toolchains. In bottlerocket-os/twoliter#467, our CI has updated cargo-deny to the latest release, which pulls in krates 0.18.0.

Running cargo deny in our project now fails with the following:

╰─➤  cargo deny -L trace --no-default-features check licenses bans sources
2025-02-26 18:58:57 [INFO] using config from /home/fedora/twoliter/deny.toml
2025-02-26 18:58:57 [DEBUG] loading license store...
2025-02-26 18:58:57 [INFO] fetching crates for /home/fedora/twoliter/Cargo.toml
2025-02-26 18:58:57 [INFO] fetched crates in 198.073188ms
2025-02-26 18:58:57 [INFO] gathering crates for /home/fedora/twoliter/Cargo.toml
2025-02-26 18:58:57 [DEBUG] gathering crate metadata
2025-02-26 18:58:57 [ERROR] failed to interpret `cargo metadata`'s json: expected `,` or `}` at line 1 column 251645: expected `,` or `}` at line 1 column 251645

I've narrowed this down to some issue in krates 0.18.0, see below reproduction and expected behavior.

To Reproduce

Create a new crate and use example from https://github.com/EmbarkStudios/krates?tab=readme-ov-file#usage. Point the manifest path to twoliter's Cargo.toml

use krates::{Builder, Cmd, Krates, cm, petgraph};
fn main() -> Result<(), krates::Error> {
    let mut cmd = Cmd::new();
    cmd.manifest_path("/home/fedora/twoliter/Cargo.toml");
    // Enable all features, works for either an entire workspace or a single crate
    cmd.all_features();

    let mut builder = Builder::new();
    // Let's filter out any crates that aren't used by x86_64 windows

    let krates: Krates = builder.build(cmd, |pkg: cm::Package| {
        println!("Crate {} was filtered out", pkg.id);
    })?;

    // Print a dot graph of the entire crate graph
    println!("{:?}", petgraph::dot::Dot::new(krates.graph()));

    Ok(())
}

Cargo.toml:

[package]
name = "cargo-metadata"
version = "0.1.0"
edition = "2021"

[dependencies]
krates = "0.18"

rust-toolchain.toml:

[toolchain]
# latest 1.85.0 nightly
channel = "nightly-2025-01-02"
profile = "default"
$ cargo run
Error: Metadata(Json(Error("expected `,` or `}`", line: 1, column: 251645)))

Same error as what cargo deny is reporting.

Checking what's at this specific byte:

$ cargo metadata | cut -b 251000-251645                                                                                                                                                                                                                                
ses_default_features":true,"features":[],"target":null,"registry":null},{"name":"lazy_static","source":"registry+https://github.com/rust-lang/crates.io-index","req":"^1","kind":null,"rename":null,"optional":false,"uses_default_features":true,"features":[],"target":null,"registry":null},{"name":"nonzero_ext","source":"registry+https://github.com/rust-lang/crates.io-index","req":"^0.3","kind":null,"rename":null,"optional":false,"uses_default_features":true,"features":[],"target":null,"registry":null},{"name":"pipesys","source":null,"req":"^0.1","kind":null,"rename":null,"optional":false,"uses_default_features":true,"features":[],"artifact":

Can see that this error in parsing the cargo metadata JSON is coming from the artifact object - I verified this is the first occurrence of artifact in the JSON.

Expected behavior

Expected behavior is that cargo metadata JSON can be parsed.

Downgrade krates, still point this example at twoliter's manifest:

[package]
name = "cargo-metadata"
version = "0.1.0"
edition = "2021"

[dependencies]
krates = "0.17"
$ cargo run
<expected output>

Test krates 0.18.0 on a project that does not declare binary artifacts:

  1. Point manifest path to such a project (like tough): cmd.manifest_path("/home/fedora/tough/Cargo.toml");
  2. Set krates = "0.18.0" in Cargo.toml of this example crate
  3. cargo run results in expected output

Screenshots
n/a

Device:

  • OS:
$ uname -a
Linux btlrkt 6.11.10-200.fc40.x86_64 #1 SMP PREEMPT_DYNAMIC Sat Nov 23 00:53:13 UTC 2024 x86_64 GNU/Linux
@ginglis13 ginglis13 added the bug Something isn't working label Feb 26, 2025
@ginglis13
Copy link
Author

It looks like #99 doesn't include artifacts in the field for a Package in

map!(Package, map, {
or

krates/src/cm.rs

Lines 235 to 239 in d62d75e

/// One or more crates described by a single `Cargo.toml`
///
/// Each [`target`][Package::targets] of a `Package` will be built as a crate.
/// For more information, see <https://doc.rust-lang.org/book/ch07-01-packages-and-crates.html>.
pub struct Package {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant