-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Make commands in dev-dependencies available to run #2267
Comments
This sounds like it may be more of a use case for |
The issues that I can see with cargo install for this use case are:
My current motivation for raising this issue is that I'm developing bindings for a C-library using github.com/crabtw/rust-bindgen. rust-bindgen has a library crate which provides a rust api, as well as a binary crate which provides a command line API. I need to use the binary crate because the library API won't work for my use case. So, rust-bindgen needs to be installed and available as a runnable binary for doing routine development, and it would be nice to formally record that somewhere, and have a simple 'cargo update' or 'cargo install' that would fetch crates with the commands that I need. |
For that use case, wouldn't a build script suffice? In theory rust-bindgen would also have a library API and then your build script would take care of what while building. |
Rust-bindgen does indeed have a library API, but it is not exactly the same as the CLI. Not to get into too much detail, but the library API is a macro that generates bindings at compile time, and the CLI writes the bindings to a .rs file. I'm wrapping a library with safe rust bindings, so writing the bindings explictly to a .rs file where I'll see in git if they've changed and can review the changes before committing them is preferable. I suspect that many crates are like this. The library api and the CLI are slightly different use cases, and so will be designed slightly differently and be good for different things. Or, the library will be a command-line oriented tool with no library API, but still used in the development of a particular rust project. |
There was a failure mode of the handling of the rerun-if-changed directive where it would rerun the build script twice before hitting a steady state of actually processing the directives. The order of events that led to this were: 1. A project was built from a clean directory. Cargo recorded a fingerprint indicating this (for the build script), but the fingerprint indicated that the build script was a normal build script (no manually specified inputs) because Cargo had no prior knowledge. 2. A project was then rebuilt from the same directory. Cargo's new fingerprint for the build script now indicates that there is a custom list of dependencies, but the previous fingerprint indicates there wasn't, so the mismatch causes another rebuild. 3. All future rebuilds will agree that there are custom lists both before and after, so the directives are processed as one would expect. This commit does a bit of refactoring in the fingerprint module to fix this situation. The recorded fingerprint in step (1) is now recorded as a "custom dependencies are specified" fingerprint if, after the build script is run, custom dependencies were specified. Closes rust-lang#2267
There was a failure mode of the handling of the rerun-if-changed directive where it would rerun the build script twice before hitting a steady state of actually processing the directives. The order of events that led to this were: 1. A project was built from a clean directory. Cargo recorded a fingerprint indicating this (for the build script), but the fingerprint indicated that the build script was a normal build script (no manually specified inputs) because Cargo had no prior knowledge. 2. A project was then rebuilt from the same directory. Cargo's new fingerprint for the build script now indicates that there is a custom list of dependencies, but the previous fingerprint indicates there wasn't, so the mismatch causes another rebuild. 3. All future rebuilds will agree that there are custom lists both before and after, so the directives are processed as one would expect. This commit does a bit of refactoring in the fingerprint module to fix this situation. The recorded fingerprint in step (1) is now recorded as a "custom dependencies are specified" fingerprint if, after the build script is run, custom dependencies were specified. Closes #2267
Unless I'm mistaken, this was accidentally closed. |
Oh dear I did indeed fat finger that, sorry! |
I have a use case that also requires commands available from dev-dependencies. My project has to run arbitrary user script/commands (sort of like codingame), those scripts are run as a child process by the library, which pipes and interact with stdin, stdout and stderr of the child. I want to test that, and the most sensible way I thought would be having in-project dev-dependencies with executables to act as user scripts. But then I found out that cargo does not compile dev-depenencies commands. Although somewhat different than the original issue this also involves having binaries from dev-dependencies compiled. I'm open to alternatives, my strongest motivation for having this done in cargo is the continuous integration testing of the child process piping functionality on multiple platforms. Is there a strong reasoning to oppose binaries in dependencies in general and in dev-dependencies in particular? Edit: fiddle a bit and found #1581, which could also be used to compile my test user scripts. |
There's not really any particularly strong reason to not do this, it basically just needs a principled design. For example we can't really "just compile" all dev-dependency binaries and put them somewhere. Some concerns I have with that are:
In general build scripts tend to solve most of these problems naturally, so I personally like to push on those as hard as possible, but I can definitely see that for CLI tools this may fall down from time to time (but |
In my case I miss the ability to compile binaries for use inside tests, not running commands from dev-dependencies outside tests. The more I think about it dev-build scripts seem more reasonable as in the general case it could be used to generate anything for tests and benches. For now I'll resort to a Makefile + PS script (windows) for compiling a binary and making it available to tests via some environment variable. But I'm willing to write my first RFC for #1581. |
Out of curiosity, isn't it easier to link to a library and call a function than it is to execute a binary? Shouldn't the dev-dependencies ship libraries that you can call in tests? I do have a feeling though, yeah, that dev build scripts will likely be a thing at some point. |
Well, the point is to specifically test integration on running a child On Fri, Feb 26, 2016, 03:25 Alex Crichton notifications@github.com wrote:
|
Are there any workarounds for this right now? I was getting flaky builds due to the problem of having to use
And then somehow be able to call that specific binary. |
Perhaps instead of having separate main dependencies and devDependencies, cargo should make it possible to specify a list of environments for each dependency? Same as features: by default the crate would only be available at runtime, but specifying "dev"/"bin"/"ci" would mean that the dependency should be installed only during development/should be installed with binaries/should be installed in ci pipelines |
Just want to chime in that this is also a problem for Deno. We have a rust http server that we test Deno programs against. It needs to be a standalone binary so we can use it outside of “cargo test” for debugging and whatnot. But the binary is a dependency of the tests as well. There is no way to express this dependency in cargo currently (as far as I can tell). |
I am trying to write a database system in Rust and would love to have this feature too. It's a distributed system where I need to run a couple of processes for integration testing. Currently I have build script that re-runs cargo install whenever one of the binary projects ( use std::process::Command;
fn visit_dirs(dir: std::path::PathBuf) {
println!("cargo:rerun-if-changed={}", dir.as_os_str().to_str().unwrap());
for entry in std::fs::read_dir(dir).unwrap() {
let entry = entry.unwrap();
let path = entry.path();
if path.is_dir() {
visit_dirs(path);
} else {
println!("cargo:rerun-if-changed={}", path.as_os_str().to_str().unwrap());
}
}
}
fn main() {
let mdir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
let path = std::path::Path::new(&mdir).join("..");
Command::new("cargo").args(&["install", "--path=coordinator"])
.current_dir(path.clone())
.spawn().unwrap().wait().unwrap();
Command::new("cargo").args(&["install", "--path=node"])
.current_dir(path.clone())
.spawn().unwrap().wait().unwrap();
visit_dirs(path.join("coordinator"));
visit_dirs(path.join("node"));
println!("cargo:rerun-if-changed=build.rs");
} |
Given the description, and that we want:
Wouldn't it be enough to teach
|
Yeah, I really would have expected the cargo dev dependencies section to support CLI tools, similar to how NPM dev dependencies work. Oddly, there isn't even necessarily a way to tell the One workaround mentioned previously involves a third party cargo-run-bin plugin. This may work for some uses. But it messes up the flow of my custom build tool, tinyrick. I don't want to require the user to laboriously type out I don't want to have to resort to shell aliases or shell functions that would expand WSL is nice to have, but I do not like to depend on it unless absolutely necessary. While the user may manually run I am taking notes towards an accio equivalent in Rust. Pity that both Rust and Go lack robust support for pinning dev tools. |
I would like this feature very much. Naturally, these external tools have to run executable, but there is no way to use these tools on a per-project, fixed version basis. |
See also #5120 for more use cases. |
I also believe this feature is greatly needed. I was shocked coming from an npm and python world. Currently, my local dev instructions require my users to In the meantime, I'll try the |
Workaround: a different approach would be to use Nix. |
Here is a related proposal that could be adapted for this purpose #13359. |
I have a rust project which uses a few shell scripts that need commands from other crates. I added them as dev-dependencies, but I couldn't find the binaries anywhere. It would be nice if the binaries were available to run from the command line.
As an example, npm makes binaries available in
node_modules/.bin
, so you can put them in devDependencies and use them in scripts.The text was updated successfully, but these errors were encountered: