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

Support for examples (and tests?) at the workspace level #7467

Closed
mathstuf opened this issue Oct 2, 2019 · 13 comments
Closed

Support for examples (and tests?) at the workspace level #7467

mathstuf opened this issue Oct 2, 2019 · 13 comments
Labels
C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted`

Comments

@mathstuf
Copy link
Contributor

mathstuf commented Oct 2, 2019

Describe the problem you are trying to solve
In the graphql-client set of crates, there is an examples directory at the workspace level. This keeps them visible and easy to find. However, they are not part of the cargo build --examples build at the top-level because they aren't found in the "right" location. CI ends up building them standalone which ends up causing lots of dependencies to be rebuilt again on top of the main workspace build set.

Describe the solution you'd like
It would be nice if something like this were possible:

[workspace]
examples = true

which would cause cargo to look in the examples/ directory for example (full crates I guess?) and merge them in with the main build set (if --examples or --all is in effect).

@mathstuf mathstuf added the C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` label Oct 2, 2019
@ehuss
Copy link
Contributor

ehuss commented Oct 4, 2019

Is there a reason you can't add the examples as workspace members? That would allow them to share the same artifacts with the other members. Also, if you place the examples' code in an examples directory, then you can do cargo build --examples at the root of the workspace and build all the examples at once. That is, an example could be something like graphql-client/examples/github/examples/query_repo.rs.

@mathstuf
Copy link
Contributor Author

mathstuf commented Oct 4, 2019

I think the main thing is that the examples are full crates which, AFAIK, is not supported in the examples directory today. Plus, one is a WASM test which…not sure how that'd work since it ends up as a cdylib crate type. The others look like they'd add significant crates to the dev-dependencies table if they were just examples.

I think adding them to the workspace is probably fine, but it'd be nice if they could be tagged as examples so they don't always build and are triggered by --examples.

@ehuss
Copy link
Contributor

ehuss commented Oct 4, 2019

Each example can be a full package, with just one example per package, so they can each declare their own dependencies and whatnot. Like:

graphql-client/examples/github/Cargo.toml
graphql-client/examples/github/examples/github.rs
graphql-client/examples/hasura/Cargo.toml
graphql-client/examples/hasura/examples/hasura.rs
graphql-client/examples/web/Cargo.toml
graphql-client/examples/web/examples/web.rs

It is identical to your current layout, instead of placing them in the src directory you place the code in an examples directory. Examples can also specify a crate type, so the web example can still be a cdylib.

@mathstuf
Copy link
Contributor Author

mathstuf commented Oct 4, 2019

Hmm. If I move them, running cargo build --example hasura ends up with "no example target" error. Do they need to still be added to the workspace manually?

@mathstuf
Copy link
Contributor Author

mathstuf commented Oct 4, 2019

Hmm. I'm not seeing any documentation for how to specify an example as a full crate. Looking at cargo-metadata, I don't see a way to say the crate root in the [[example]] array; example.<name>.path seems to want to be a main.rs or lib.rs.

@ehuss
Copy link
Contributor

ehuss commented Oct 4, 2019

They will need to be added to the workspace. One way is to add "examples/*" to the members list (and remove the workspace definition from each sub package).

To create a lib-based example, just explicitly define the example:

[[example]]
name = "myexample"
crate-type = ["cdylib"]

where myexample corresponds to examples/myexample.rs.

@mathstuf
Copy link
Contributor Author

mathstuf commented Oct 4, 2019

Ah, thanks, that clears it up. There is one thing that one example can't specify lto = "thin" since profiles are a workspace-wide thing, but I'll leave that as a comment for now.

@ehuss
Copy link
Contributor

ehuss commented Oct 4, 2019

Yea, that's a bit unfortunate. There is the nightly-only profile overrides which provides a way to set the profile per-package. I'm hoping it will be on the path to stabilization soon.

@mathstuf
Copy link
Contributor Author

mathstuf commented Oct 5, 2019

Thanks for the pointers; this all seems to be working well enough for me now. I've added a comment to the cargo feature in the Cargo.toml for now. Thanks for the help!

@Jake-Shadle
Copy link
Contributor

For anyone who finds this issue in the future, it should be noted that the layout described in #7467 (comment) will only work if you are using a virtual manifest, if you try the method in a workspace defined in a non-virtual manifest it will give the error: no example target named <name> error.

Jake-Shadle added a commit to EmbarkStudios/discord-sdk that referenced this issue Jun 24, 2021
See rust-lang/cargo#7467, egui, structopt, etc
are quite heavy, so making each example an isolated crate means people can just
build the one example they want, and the sdk itself is also not
"polluted" with every dev-dependency.
Jake-Shadle added a commit to EmbarkStudios/discord-sdk that referenced this issue Jun 25, 2021
* Add built in handlers

* Move event types into submodules

* Add error for when a lobby secret is incorrect

* Make disconnect an error rather than string

* Move lobby search functionality to submodule

* Add synthesized events

It's useful to also emit events for some commands when they affect eg lobby
state

* Add LobbyStates

This is just a helper that can be used to keep the state of 1 or more
lobbies updated as events pertaining to them are streamed from Discord

* Fixup examples and tests with changed API

* Add a simple repl example

* Begin adding overlay example

* Windows fixes

* Reorganize the repo to get isolated examples

See rust-lang/cargo#7467, egui, structopt, etc
are quite heavy, so making each example an isolated crate means people can just
build the one example they want, and the sdk itself is also not
"polluted" with every dev-dependency.

* Cleanup

* Fixup so that the sdk is packageable

cargo won't allow using files (eg README) from above the crate root, so
we just copy the files into the repo root before making the commit a
release is published from

* Fix deny config

* Fix clippy lints

* Correct publish crate

* Rustfmt

* Don't build examples during testing

* Only run tests for the sdk itself
@jeffmo
Copy link

jeffmo commented Jun 21, 2022

Wanted to add a note here since I banged my head on this for a minute while trying to add examples to my workspace:

In order to do this, AFAICT, you (1) must create a full crate for each of your workspace examples (i.e. you cannot create single-file examples for a workspace) and you (2) must place your example code into the /examples subdirectory of those example-crates (i.e. not in the src/ directory of those example-crates).

(point 2 is specified in @ehuss 's comment above above, I just skimmed too quickly and overlooked it thinking each example-crate specifies a src/main.rs).

So for clarity, my workspace dir:

$ ls
Cargo.lock
Cargo.toml
examples/
target/
terse_client/
terse_common/
terse_server/

My Cargo.toml:

[workspace]
members = [
  "terse_common",
  "terse_client",
  "terse_server",
  "examples/*",
]

And then my recursive examples/ dir:

$ ls examples/*/**
examples/client/Cargo.toml
examples/server/Cargo.toml

examples/client/examples:
client.rs

examples/server/examples:
server.rs

The 2 file structures I tried first which did not work as I'd initially assumed:
(i.e. cargo run --example client would not find the example)

  1. myworkspace/examples/{client.rs,server.rs}
  2. myworkspace/examples/client/{Cargo.toml,src/main.rs}

A general piece of feedback: It'd be nice if single-file examples worked for workspaces as they do for crates (e.g. myworkspace/examples/{client.rs,server.rs})

@aurexav
Copy link

aurexav commented Oct 23, 2022

For anyone who finds this issue in the future, it should be noted that the layout described in #7467 (comment) will only work if you are using a virtual manifest, if you try the method in a workspace defined in a non-virtual manifest it will give the error: no example target named <name> error.

I found this works without the requirement of the virtual manifest.

[[example]]
name = "xxx"
path = "examples/xxx/src/main.rs"

gibbz00 added a commit to gibbz00/tower-lsp that referenced this issue Sep 10, 2023
Not entirely possible to support the cargo examples at the workspace
level right now.

(rust-lang/cargo#7467)
@nielsle
Copy link
Contributor

nielsle commented Jan 18, 2024

For the sake of Google. Here is a nice example of a crate with grouped examples:

https://github.com/tracel-ai/burn/blob/main/Cargo.toml
https://github.com/tracel-ai/burn/tree/main/examples

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted`
Projects
None yet
Development

No branches or pull requests

6 participants