paketo-community / cargo

A Cloud Native Buildpack for Cargo (Rust)
Apache License 2.0
4 stars 3 forks source link

Buildpack attempts to build lib members in a workspace #177

Open edude03 opened 2 years ago

edude03 commented 2 years ago

To reproduce:

$ cargo new --lib testing
$ cargo new other 
$ cat <<EOF >> Cargo.toml
[workspace]
members = [
  "other"
]
EOF

$ echo "testing = { path = "../testing"}" >> other/Cargo.toml

$ pack build testing

The result is

[builder]     cargo install --locked --color=never --root=/layers/paketo-community_cargo/Cargo --path=/workspace/other
[builder]         Installing other v0.1.0 (/workspace/other)
[builder]          Compiling testing v0.1.0 (/workspace/testing)
[builder]          Compiling other v0.1.0 (/workspace/other)
[builder]           Finished release [optimized] target(s) in 0.51s
[builder]         Installing /layers/paketo-community_cargo/Cargo/bin/other
[builder]          Installed package `other v0.1.0 (/workspace/other)` (executable `other`)
[builder]     cargo install --locked --color=never --root=/layers/paketo-community_cargo/Cargo --path=/workspace/testing
[builder]       error: no packages found with binaries or examples
[builder] unable to invoke layer creator
[builder] unable to contribute application layer
[builder] unable to install member
[builder] unable to build
[builder] exit status 101
[builder] ERROR: failed to build: exit status 1

It seems for some reason the logic detects that the lib crate is in the same directory and makes it part of the workspace?

edude03 commented 2 years ago

The issue seems to be here https://sourcegraph.com/github.com/paketo-community/cargo@9a30f3c5983f7e3b03bde63f1cae4b5d88c376cc/-/blob/runner/runners.go?L422-442

It's actually cargo that says it's a workspace member, if you run ❯ cargo metadata --format-version=1 --no-deps | jq on this example you'll see

 "workspace_members": [
    "other 0.1.0 (path+file:///Users/edude03/code/pack-repo/other)",
    "testing 0.1.0 (path+file:///Users/edude03/code/pack-repo/testing)"
  ],

I wonder if this logic should actually look at packages to see if the member contains a bin crate type?

dmikusa commented 1 year ago

Right now, if you have one member (i.e. not a workspace), it'll cargo install that. If you have multiple members, it'll cargo install all of them. I agree that's not ideal and there's a manual workaround, which is to set BP_CARGO_WORKSPACE_MEMBERS to the list that it should build.

A comma delimited list of the workspace package names (this is the package name in the member's Cargo.toml, not what is in the workspace's Cargo.toml's member list) to install. If the project is not using workspaces, this is not used. By default, for projects with a workspace, the buildpack will build all members in a workspace. See more details below.

pack build testing -b paketo-community/rust -e BP_CARGO_WORKSPACE_MEMBERS='other'

We could fix this, like you said by looking at the targets, but I don't think using cargo install is the right way to be building user applications. I think cargo build is a better methodology, it's what you see a lot more often, especially when doing Dockerfiles. I think that will also avoid some issues like this because then it's up to Cargo to decide what to build. Really, the only draw back is that using cargo build makes it harder to pick out and install the files, but I think I know how to make that work.

At any rate, we have #162 to do that so I'd rather focus efforts there and for now just recommend using the manual workaround of setting your workspace members through the env variables.