Skip to content

fix references to git depencies in workspaces with inherited configuration #393

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

Open
wants to merge 47 commits into
base: master
Choose a base branch
from

Conversation

hallettj
Copy link

@hallettj hallettj commented Mar 8, 2025

This is a follow-up to the great groundwork already established by @tilpner in #298. I've merged the branch from that PR with the latest crate2nix code, and made some more fixes.

This PR depends on #382 - the number of changes here should go down after that PR is merged.

The problem comes up with dependency crates that are in workspace repos, and that have manifests that "inherit" configuration from the workspace manifest. For example a crate manifest might look something like this,

[package]
name = "main"
version.workspace = true  # inherit version number from workspace

[dependencies]
serde = { workspace = true }  # inherit dependency configuration from workspace

This is all fine for dependencies in registries (such as crates.io) because part of the process of publishing a crate to a registry is to rewrite the crate's Cargo.toml to inline all inherited configuration. But when crate2nix references git dependencies it doesn't apply that process. Instead it copies the crate subdirectory as-is into its own derivation. When that derivation builds, and a manifest parser attempts to look up workspace values it fails because the workspace manifest is not present in the derivation source. So the dependency fails to build.

This PR reproduces some of the crate publication processing. Most of the new logic is in normalize_manifest.rs. During the process of creating each dependency derivation the Cargo.toml file is parsed, workspace configuration is inlined, and a new Cargo.toml file is written. (The original file is preserved in the derivation source - it is renamed to Cargo.toml.orig.)

I chose to use a library called cargo_toml to do this processing because it is narrowly focused on this type of task, and as a result it is a small dependency. But cargo_toml is not perfect, and it doesn't inline every possible inherited configuration. In particular I found that it lets inherited lint settings go through unchanged. To prevent build failures in such situations there is a fixup step after normalization that deletes any workspace references that weren't inlined. This assumes that there isn't much reason to reference lint configuration in dependency derivations, and I think there is not.

An alternative would be to use cargo (the library) for normalization. It's the library that the cargo program uses so its behavior will exactly match what is generally expected. cargo could also replace other functionality that crate2nix requires - in particular it could replace use of cargo_metadata. I'll note that cargo2nix uses cargo. I didn't use cargo in this PR because it's a very big dependency, and incorporating it would be a larger change.

If you have been waiting for this fix, and you don't want to wait on this PR to be merged, I have included this fix and a number of other fixes in the main branch of my fork, https://github.com/hallettj/crate2nix

marius851000 and others added 30 commits September 19, 2023 12:22
It has a fairly narrow range of libgit2 versions it will accept from the
system environment, so instead of manually providing a recent-enough
version from nixpkgs-unstable, or downgrading the rust crate until the
available version matches, we allow it to build its preferred version.
When copying out workspace member crates from a larger workspace,
cargo will not be able to process the separated manifest if it still
refers to e.g. the workspace license or workspace dependencies, because
it can't find the workspace manifest.

We can't help it find the workspace manifest, because crates in a cargo
vendor directory aren't discovered recursively, and cargo doesn't resolve
symlinks before checking the ancestors to find the workspace manifest.
This requires bumping the nodejs version used to build docs because
nodejs_21 does not exist in the latest nixpkgs.
@hallettj hallettj mentioned this pull request Mar 8, 2025
@Pacman99
Copy link

Pacman99 commented Mar 19, 2025

I'm trying out the main branch of your fork and I'm getting the error below, any chance you know why thats happening?
I also merged in my wildcards/subcrates fix in my local clone which I'm referencing, but I don't think that should affect much. I also made a small change to use cargo/config.toml instead of cargo/config, because I was getting an error about cargo/config being deprecated. This is the exact branch I'm using: https://github.com/timewave-computer/crate2nix

Full log
Running phase: unpackPhase
@nix { "action": "setPhase", "phase": "unpackPhase" }
unpacking source archive /nix/store/wlfpcb74c5jzkqxhlqsyjfn1w4l913ml-kpj77z2w93wjkp40fc1pvz79a22a2bvs-source
source root is kpj77z2w93wjkp40fc1pvz79a22a2bvs-source
Running phase: buildPhase
@nix { "action": "setPhase", "phase": "buildPhase" }
+++ crate2nix generate -f ./Cargo.toml -o Cargo-generated.nix -h /nix/store/3hz2aplxnmn2g9jgz9ry9xjv7qfmcmr4-valence-protocol-crate2nix/crate-hashes.json
Error: while retrieving metadata about ./Cargo.toml: `cargo metadata` exited with an error: error: source `https://github.com/DA0-DA0/dao-contracts?branch=cw-std-2#48ce9249ebd28c9092de0bf2368c78458726c9e9` defines source https://github.com/DA0-DA0/dao-contracts?branch=cw-std-2, but that source is already defined by `git+https://github.com/DA0-DA0/dao-contracts?branch=cw-std-2`
note: Sources are not allowed to be defined multiple times.

crate2nix failed.
== cargo/config.toml (BEGIN)
    [source.crates-io]
    replace-with = "vendored-sources"
    
    [source."https://github.com/DA0-DA0/dao-contracts?branch=cw-std-2#48ce9249ebd28c9092de0bf2368c78458726c9e9"]
    git = "https://github.com/DA0-DA0/dao-contracts"
    rev = "48ce9249ebd28c9092de0bf2368c78458726c9e9"
    
    branch = "cw-std-2"
    replace-with = "vendored-sources"
    
    [source."https://github.com/many-things/cw-hyperlane?rev=d07e55e#d07e55e17c791a5f6557f114e3fb6cb433d9b800"]
    git = "https://github.com/many-things/cw-hyperlane"
    rev = "d07e55e17c791a5f6557f114e3fb6cb433d9b800"
    
    
    replace-with = "vendored-sources"
    
    [source."https://github.com/strangelove-ventures/interchaintest?branch=main#4bd4690ac4b89a8d73f5e3ea78158ea0ecaf653a"]
    git = "https://github.com/strangelove-ventures/interchaintest"
    rev = "4bd4690ac4b89a8d73f5e3ea78158ea0ecaf653a"
    
    branch = "main"
    replace-with = "vendored-sources"
    
    [source."https://github.com/timewave-computer/localic-utils?branch=main#e1750be3dc19192ed92e901ce5f862c17ae5032c"]
    git = "https://github.com/timewave-computer/localic-utils"
    rev = "e1750be3dc19192ed92e901ce5f862c17ae5032c"
    
    branch = "main"
    replace-with = "vendored-sources"
    
    [source."https://github.com/DA0-DA0/polytone?rev=f70440a#f70440a35f12f97a9018849ca7e6d241a53582ce"]
    git = "https://github.com/DA0-DA0/polytone"
    rev = "f70440a35f12f97a9018849ca7e6d241a53582ce"
    
    
    replace-with = "vendored-sources"
    
    
    [source.vendored-sources]
    directory = "/nix/store/pn0gqzf7dqhig1w6li73kd6rh4gcsblj-deps"

== cargo/config.toml (END)

== crate-hashes.json (BEGIN)
    {
      "cw-denom 2.4.2 (git+https://github.com/DA0-DA0/dao-contracts?branch=cw-std-2#48ce9249ebd28c9092de0bf2368c78458726c9e9)": "090jhdwmigk2726sffmcqcvnwh8m1gyapx96rmbjz3b5dvqp9cca",
      "hpl-interface 0.0.7 (git+https://github.com/many-things/cw-hyperlane?rev=d07e55e#d07e55e17c791a5f6557f114e3fb6cb433d9b800)": "1ijy218xqnf74gizrlm11533pfkz6iaf87y3hkyzs0h74ils5b8b",
      "localic-std 0.0.1 (git+https://github.com/strangelove-ventures/interchaintest?branch=main#4bd4690ac4b89a8d73f5e3ea78158ea0ecaf653a)": "10wqig9sfadwgynyy5pph5nvfghy9jqd7f0j49z82l8nb2vm300y",
      "localic-utils 0.1.0 (git+https://github.com/timewave-computer/localic-utils?branch=main#e1750be3dc19192ed92e901ce5f862c17ae5032c)": "0m4ch74p0vhwnm6yfq09ykff2zn2k16i894pfkbqqjvcbwq67b9v",
      "polytone 1.1.0 (git+https://github.com/DA0-DA0/polytone?rev=f70440a#f70440a35f12f97a9018849ca7e6d241a53582ce)": "1c77n4v45j2avdqqj41zas4w31dp23bdfjzw5nhb9y21gnrdrgj5",
      "polytone-note 1.1.0 (git+https://github.com/DA0-DA0/polytone?rev=f70440a#f70440a35f12f97a9018849ca7e6d241a53582ce)": "1c77n4v45j2avdqqj41zas4w31dp23bdfjzw5nhb9y21gnrdrgj5",
      "polytone-proxy 1.1.0 (git+https://github.com/DA0-DA0/polytone?rev=f70440a#f70440a35f12f97a9018849ca7e6d241a53582ce)": "1c77n4v45j2avdqqj41zas4w31dp23bdfjzw5nhb9y21gnrdrgj5",
      "polytone-voice 1.1.0 (git+https://github.com/DA0-DA0/polytone?rev=f70440a#f70440a35f12f97a9018849ca7e6d241a53582ce)": "1c77n4v45j2avdqqj41zas4w31dp23bdfjzw5nhb9y21gnrdrgj5"
    }
== crate-hashes.json (END)

== ls -la (BEGIN)
total 336
drwxr-xr-x 17 nixbld nixbld   4096 Jan  1  1970 .
drwx------  3 nixbld nixbld   4096 Mar 19 03:01 ..
drwxr-xr-x  2 nixbld nixbld   4096 Jan  1  1970 .cargo
-rw-r--r--  1 nixbld nixbld     10 Jan  1  1970 .envrc
drwxr-xr-x  4 nixbld nixbld   4096 Jan  1  1970 .github
-rw-r--r--  1 nixbld nixbld    461 Jan  1  1970 .gitignore
-rw-r--r--  1 nixbld nixbld 200841 Jan  1  1970 Cargo.lock
-rw-r--r--  1 nixbld nixbld   6607 Jan  1  1970 Cargo.toml
-rw-r--r--  1 nixbld nixbld  11358 Jan  1  1970 LICENSE
-rw-r--r--  1 nixbld nixbld    874 Jan  1  1970 README.md
drwxr-xr-x  2 nixbld nixbld   4096 Jan  1  1970 audits
drwxr-xr-x 10 nixbld nixbld   4096 Jan  1  1970 contracts
drwxr-xr-x  4 nixbld nixbld   4096 Jan  1  1970 deployment
drwxr-xr-x  2 nixbld nixbld   4096 Jan  1  1970 devtools
drwxr-xr-x  3 nixbld nixbld   4096 Jan  1  1970 docs
drwxr-xr-x  7 nixbld nixbld   4096 Jan  1  1970 e2e
drwxr-xr-x  3 nixbld nixbld   4096 Jan  1  1970 examples
-rw-r--r--  1 nixbld nixbld  27665 Jan  1  1970 flake.lock
-rw-r--r--  1 nixbld nixbld   3922 Jan  1  1970 flake.nix
-rw-r--r--  1 nixbld nixbld    765 Jan  1  1970 justfile
drwxr-xr-x  2 nixbld nixbld   4096 Jan  1  1970 nix
drwxr-xr-x 15 nixbld nixbld   4096 Jan  1  1970 packages
drwxr-xr-x  5 nixbld nixbld   4096 Jan  1  1970 program-manager
drwxr-xr-x  3 nixbld nixbld   4096 Jan  1  1970 schema
drwxr-xr-x  2 nixbld nixbld   4096 Jan  1  1970 scripts
drwxr-xr-x  4 nixbld nixbld   4096 Jan  1  1970 solidity
== ls -la (END)

@hallettj
Copy link
Author

hallettj commented Mar 19, 2025

Yeah, let's see if we can get that figured out. I don't see immediately what the problem is. But I do see that the error is coming from the cargo metadata command, which is outside of crate2nix. You can likely reproduce the error by running cargo metadata yourself. If you try that, and don't get an error that might indicate that we need to update the version of cargo that crate2nix uses. If that's the problem I think you can get crate2nix to use a newer version of cargo by overriding its nixpkgs input:

inputs = {
  nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
  crate2nix = {
    url = "github:hallettj/crate2nix";
    inputs.nixpkgs.follows = "nixpkgs";
  };
};

Crate2nix relies on cargo metadata to provide processed dependency information. Anything that cargo metadata can't process won't work in crate2nix without some re-architecting. But there is another builder, cargo2nix, that uses the cargo rust library instead which is the same library that cargo uses internally. If your project works when building with cargo, and updating the cargo version for crate2nix doesn't fix the problem when building with crate2nix, then you might get better results using cargo2nix. The downside for the moment is that cargo2nix requires code generation because it doesn't implement "import from derivation" (IFD) mode yet - but that's something I'm working on adding.

@Pacman99
Copy link

Pacman99 commented Mar 19, 2025

I tried overriding cargo with a newer version by adding the commit from this PR to my branch: #390. I then get the error below. I think cargo isn't accepting the vendored source and tries to download it again. I get the same error when I override the flake input as you suggested.

Log
Running phase: unpackPhase
@nix { "action": "setPhase", "phase": "unpackPhase" }
unpacking source archive /nix/store/yfzybnvl814whpkysy8x4wfqihgxnyiz-lzznc8m6r01d52xdgris73hn7qwmh0z1-source
source root is lzznc8m6r01d52xdgris73hn7qwmh0z1-source
Running phase: buildPhase
@nix { "action": "setPhase", "phase": "buildPhase" }
+++ crate2nix generate -f ./Cargo.toml -o Cargo-generated.nix -h /nix/store/msabvg0dk23gdz4vxaavsabzmmbfh9bf-valence-protocol-crate2nix/crate-hashes.json
Error: while retrieving metadata about ./Cargo.toml: `cargo metadata` exited with an error:     Updating git repository `https://github.com/many-things/cw-hyperlane`
warning: spurious network error (3 tries remaining): failed to resolve address for github.com: Temporary failure in name resolution; class=Net (12)
warning: spurious network error (2 tries remaining): failed to resolve address for github.com: Temporary failure in name resolution; class=Net (12)
warning: spurious network error (1 tries remaining): failed to resolve address for github.com: Temporary failure in name resolution; class=Net (12)
error: failed to get `hpl-interface` as a dependency of package `valence-e2e v0.2.0 (/build/lzznc8m6r01d52xdgris73hn7qwmh0z1-source/e2e)`

Caused by:
  failed to load source for dependency `hpl-interface`

Caused by:
  Unable to update https://github.com/many-things/cw-hyperlane?rev=d07e55e#d07e55e1

Caused by:
  failed to clone into: /nix/store/msabvg0dk23gdz4vxaavsabzmmbfh9bf-valence-protocol-crate2nix/cargo/git/db/cw-hyperlane-86e5b06a6a092ebb

Caused by:
  revision d07e55e17c791a5f6557f114e3fb6cb433d9b800 not found

Caused by:
  network failure seems to have happened
  if a proxy or similar is necessary `net.git-fetch-with-cli` may help here
  https://doc.rust-lang.org/cargo/reference/config.html#netgit-fetch-with-cli

Caused by:
  failed to resolve address for github.com: Temporary failure in name resolution; class=Net (12)

crate2nix failed.
== cargo/config.toml (BEGIN)
    [source.crates-io]
    replace-with = "vendored-sources"
    
    [source."https://github.com/DA0-DA0/dao-contracts?branch=cw-std-2#48ce9249ebd28c9092de0bf2368c78458726c9e9"]
    git = "https://github.com/DA0-DA0/dao-contracts"
    rev = "48ce9249ebd28c9092de0bf2368c78458726c9e9"
    
    branch = "cw-std-2"
    replace-with = "vendored-sources"
    
    [source."https://github.com/many-things/cw-hyperlane?rev=d07e55e#d07e55e17c791a5f6557f114e3fb6cb433d9b800"]
    git = "https://github.com/many-things/cw-hyperlane"
    rev = "d07e55e17c791a5f6557f114e3fb6cb433d9b800"
    
    
    replace-with = "vendored-sources"
    
    [source."https://github.com/strangelove-ventures/interchaintest?branch=main#4bd4690ac4b89a8d73f5e3ea78158ea0ecaf653a"]
    git = "https://github.com/strangelove-ventures/interchaintest"
    rev = "4bd4690ac4b89a8d73f5e3ea78158ea0ecaf653a"
    
    branch = "main"
    replace-with = "vendored-sources"
    
    [source."https://github.com/timewave-computer/localic-utils?branch=main#e1750be3dc19192ed92e901ce5f862c17ae5032c"]
    git = "https://github.com/timewave-computer/localic-utils"
    rev = "e1750be3dc19192ed92e901ce5f862c17ae5032c"
    
    branch = "main"
    replace-with = "vendored-sources"
    
    [source."https://github.com/DA0-DA0/polytone?rev=f70440a#f70440a35f12f97a9018849ca7e6d241a53582ce"]
    git = "https://github.com/DA0-DA0/polytone"
    rev = "f70440a35f12f97a9018849ca7e6d241a53582ce"
    
    
    replace-with = "vendored-sources"
    
    
    [source.vendored-sources]
    directory = "/nix/store/s3rwl1i0zd9lisfy5aqrlr9m85071wm9-deps"

== cargo/config.toml (END)

== crate-hashes.json (BEGIN)
    {
      "cw-denom 2.4.2 (git+https://github.com/DA0-DA0/dao-contracts?branch=cw-std-2#48ce9249ebd28c9092de0bf2368c78458726c9e9)": "090jhdwmigk2726sffmcqcvnwh8m1gyapx96rmbjz3b5dvqp9cca",
      "hpl-interface 0.0.7 (git+https://github.com/many-things/cw-hyperlane?rev=d07e55e#d07e55e17c791a5f6557f114e3fb6cb433d9b800)": "1ijy218xqnf74gizrlm11533pfkz6iaf87y3hkyzs0h74ils5b8b",
      "localic-std 0.0.1 (git+https://github.com/strangelove-ventures/interchaintest?branch=main#4bd4690ac4b89a8d73f5e3ea78158ea0ecaf653a)": "10wqig9sfadwgynyy5pph5nvfghy9jqd7f0j49z82l8nb2vm300y",
      "localic-utils 0.1.0 (git+https://github.com/timewave-computer/localic-utils?branch=main#e1750be3dc19192ed92e901ce5f862c17ae5032c)": "0m4ch74p0vhwnm6yfq09ykff2zn2k16i894pfkbqqjvcbwq67b9v",
      "polytone 1.1.0 (git+https://github.com/DA0-DA0/polytone?rev=f70440a#f70440a35f12f97a9018849ca7e6d241a53582ce)": "1c77n4v45j2avdqqj41zas4w31dp23bdfjzw5nhb9y21gnrdrgj5",
      "polytone-note 1.1.0 (git+https://github.com/DA0-DA0/polytone?rev=f70440a#f70440a35f12f97a9018849ca7e6d241a53582ce)": "1c77n4v45j2avdqqj41zas4w31dp23bdfjzw5nhb9y21gnrdrgj5",
      "polytone-proxy 1.1.0 (git+https://github.com/DA0-DA0/polytone?rev=f70440a#f70440a35f12f97a9018849ca7e6d241a53582ce)": "1c77n4v45j2avdqqj41zas4w31dp23bdfjzw5nhb9y21gnrdrgj5",
      "polytone-voice 1.1.0 (git+https://github.com/DA0-DA0/polytone?rev=f70440a#f70440a35f12f97a9018849ca7e6d241a53582ce)": "1c77n4v45j2avdqqj41zas4w31dp23bdfjzw5nhb9y21gnrdrgj5"
    }
== crate-hashes.json (END)

== ls -la (BEGIN)
total 336
drwxr-xr-x 17 nixbld nixbld   4096 Jan  1  1970 .
drwx------  3 nixbld nixbld   4096 Mar 19 20:36 ..
drwxr-xr-x  2 nixbld nixbld   4096 Jan  1  1970 .cargo
-rw-r--r--  1 nixbld nixbld     10 Jan  1  1970 .envrc
drwxr-xr-x  4 nixbld nixbld   4096 Jan  1  1970 .github
-rw-r--r--  1 nixbld nixbld    461 Jan  1  1970 .gitignore
-rw-r--r--  1 nixbld nixbld 200841 Jan  1  1970 Cargo.lock
-rw-r--r--  1 nixbld nixbld   6607 Jan  1  1970 Cargo.toml
-rw-r--r--  1 nixbld nixbld  11358 Jan  1  1970 LICENSE
-rw-r--r--  1 nixbld nixbld    874 Jan  1  1970 README.md
drwxr-xr-x  2 nixbld nixbld   4096 Jan  1  1970 audits
drwxr-xr-x 10 nixbld nixbld   4096 Jan  1  1970 contracts
drwxr-xr-x  4 nixbld nixbld   4096 Jan  1  1970 deployment
drwxr-xr-x  2 nixbld nixbld   4096 Jan  1  1970 devtools
drwxr-xr-x  3 nixbld nixbld   4096 Jan  1  1970 docs
drwxr-xr-x  7 nixbld nixbld   4096 Jan  1  1970 e2e
drwxr-xr-x  3 nixbld nixbld   4096 Jan  1  1970 examples
-rw-r--r--  1 nixbld nixbld  27665 Jan  1  1970 flake.lock
-rw-r--r--  1 nixbld nixbld   3920 Jan  1  1970 flake.nix
-rw-r--r--  1 nixbld nixbld    765 Jan  1  1970 justfile
drwxr-xr-x  2 nixbld nixbld   4096 Jan  1  1970 nix
drwxr-xr-x 15 nixbld nixbld   4096 Jan  1  1970 packages
drwxr-xr-x  5 nixbld nixbld   4096 Jan  1  1970 program-manager
drwxr-xr-x  3 nixbld nixbld   4096 Jan  1  1970 schema
drwxr-xr-x  2 nixbld nixbld   4096 Jan  1  1970 scripts
drwxr-xr-x  4 nixbld nixbld   4096 Jan  1  1970 solidity
== ls -la (END)

</details>

@hallettj
Copy link
Author

@Pacman99 Oh damn - that might be due to Cargo changing its internal package ID format as I discussed in #381. Crate2nix uses package IDs, but currently assumes the old format. I suppose the fix is to update crate2nix to a recent version of cargo, and change any crate2nix code that generates package IDs to use the new format.

In the meantime if you're using IFD, maybe you can get things working by switching to code generation mode? By that I mean generating a Cargo.nix file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants