Skip to content

Commit 2956296

Browse files
committedApr 18, 2024·
Auto merge of #13769 - epage:msrv-config, r=weihanglo
fix(msrv): Put MSRV-aware resolver behind a config ### What does this PR try to resolve? This is a part of #13540 which is a party of #9930. The config is `resolver.something-like-precedence` with values: - `something-like-maximum` (default) - `something-like-rust-version` This is punting on the actual config schema so we can implement `package.resolver` and `edition = "2024"` support as we want the MSRV-aware resolver available without `cargo_features`. ### How should we test and review this PR? One of the included test cases shows a bug with `cargo install`. Resolving that will be tracked in #9930 ### Additional information
2 parents 39b8f17 + 18a5940 commit 2956296

File tree

12 files changed

+331
-10
lines changed

12 files changed

+331
-10
lines changed
 

‎src/cargo/core/workspace.rs

+42-6
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ use crate::util::errors::{CargoResult, ManifestError};
2626
use crate::util::interning::InternedString;
2727
use crate::util::lints::check_implicit_features;
2828
use crate::util::toml::{read_manifest, InheritableFields};
29-
use crate::util::{context::ConfigRelativePath, Filesystem, GlobalContext, IntoUrl};
29+
use crate::util::{
30+
context::CargoResolverConfig, context::CargoResolverPrecedence, context::ConfigRelativePath,
31+
Filesystem, GlobalContext, IntoUrl,
32+
};
3033
use cargo_util::paths;
3134
use cargo_util::paths::normalize_path;
3235
use cargo_util_schemas::manifest;
@@ -100,6 +103,7 @@ pub struct Workspace<'gctx> {
100103

101104
/// The resolver behavior specified with the `resolver` field.
102105
resolve_behavior: ResolveBehavior,
106+
resolve_honors_rust_version: bool,
103107
honor_rust_version: Option<bool>,
104108

105109
/// Workspace-level custom metadata
@@ -207,7 +211,7 @@ impl<'gctx> Workspace<'gctx> {
207211
.load_workspace_config()?
208212
.and_then(|cfg| cfg.custom_metadata);
209213
ws.find_members()?;
210-
ws.set_resolve_behavior();
214+
ws.set_resolve_behavior()?;
211215
ws.validate()?;
212216
Ok(ws)
213217
}
@@ -230,6 +234,7 @@ impl<'gctx> Workspace<'gctx> {
230234
loaded_packages: RefCell::new(HashMap::new()),
231235
ignore_lock: false,
232236
resolve_behavior: ResolveBehavior::V1,
237+
resolve_honors_rust_version: false,
233238
honor_rust_version: None,
234239
custom_metadata: None,
235240
}
@@ -248,7 +253,7 @@ impl<'gctx> Workspace<'gctx> {
248253
.packages
249254
.insert(root_path, MaybePackage::Virtual(manifest));
250255
ws.find_members()?;
251-
ws.set_resolve_behavior();
256+
ws.set_resolve_behavior()?;
252257
// TODO: validation does not work because it walks up the directory
253258
// tree looking for the root which is a fake file that doesn't exist.
254259
Ok(ws)
@@ -284,11 +289,11 @@ impl<'gctx> Workspace<'gctx> {
284289
ws.members.push(ws.current_manifest.clone());
285290
ws.member_ids.insert(id);
286291
ws.default_members.push(ws.current_manifest.clone());
287-
ws.set_resolve_behavior();
292+
ws.set_resolve_behavior()?;
288293
Ok(ws)
289294
}
290295

291-
fn set_resolve_behavior(&mut self) {
296+
fn set_resolve_behavior(&mut self) -> CargoResult<()> {
292297
// - If resolver is specified in the workspace definition, use that.
293298
// - If the root package specifies the resolver, use that.
294299
// - If the root package specifies edition 2021, use v2.
@@ -299,7 +304,36 @@ impl<'gctx> Workspace<'gctx> {
299304
.resolve_behavior()
300305
.unwrap_or_else(|| p.manifest().edition().default_resolve_behavior()),
301306
MaybePackage::Virtual(vm) => vm.resolve_behavior().unwrap_or(ResolveBehavior::V1),
307+
};
308+
309+
match self.gctx().get::<CargoResolverConfig>("resolver") {
310+
Ok(CargoResolverConfig {
311+
something_like_precedence: Some(precedence),
312+
}) => {
313+
if self.gctx().cli_unstable().msrv_policy {
314+
self.resolve_honors_rust_version =
315+
precedence == CargoResolverPrecedence::SomethingLikeRustVersion;
316+
} else {
317+
self.gctx()
318+
.shell()
319+
.warn("ignoring `resolver` config table without `-Zmsrv-policy`")?;
320+
}
321+
}
322+
Ok(CargoResolverConfig {
323+
something_like_precedence: None,
324+
}) => {}
325+
Err(err) => {
326+
if self.gctx().cli_unstable().msrv_policy {
327+
return Err(err);
328+
} else {
329+
self.gctx()
330+
.shell()
331+
.warn("ignoring `resolver` config table without `-Zmsrv-policy`")?;
332+
}
333+
}
302334
}
335+
336+
Ok(())
303337
}
304338

305339
/// Returns the current package of this workspace.
@@ -616,7 +650,9 @@ impl<'gctx> Workspace<'gctx> {
616650
}
617651

618652
pub fn resolve_honors_rust_version(&self) -> bool {
619-
self.gctx().cli_unstable().msrv_policy && self.honor_rust_version.unwrap_or(true)
653+
// Give CLI precedence
654+
self.honor_rust_version
655+
.unwrap_or(self.resolve_honors_rust_version)
620656
}
621657

622658
pub fn custom_metadata(&self) -> Option<&toml::Value> {

‎src/cargo/util/context/mod.rs

+13
Original file line numberDiff line numberDiff line change
@@ -2644,6 +2644,19 @@ impl BuildTargetConfig {
26442644
}
26452645
}
26462646

2647+
#[derive(Debug, Deserialize)]
2648+
#[serde(rename_all = "kebab-case")]
2649+
pub struct CargoResolverConfig {
2650+
pub something_like_precedence: Option<CargoResolverPrecedence>,
2651+
}
2652+
2653+
#[derive(Debug, Deserialize, PartialEq, Eq)]
2654+
#[serde(rename_all = "kebab-case")]
2655+
pub enum CargoResolverPrecedence {
2656+
SomethingLikeMaximum,
2657+
SomethingLikeRustVersion,
2658+
}
2659+
26472660
#[derive(Deserialize, Default)]
26482661
#[serde(rename_all = "kebab-case")]
26492662
pub struct TermConfig {

‎src/doc/src/reference/unstable.md

+14-3
Original file line numberDiff line numberDiff line change
@@ -336,15 +336,26 @@ This was stabilized in 1.79 in [#13608](https://github.com/rust-lang/cargo/pull/
336336

337337
### MSRV-aware resolver
338338

339-
By default, `-Zmsrv-policy` enables an MSRV-aware resolver.
339+
`-Zmsrv-policy` allows access to an MSRV-aware resolver which can be enabled with:
340+
- `resolver.something-like-precedence` config field
341+
340342
The resolver will prefer dependencies with a `package.rust-version` that is the same or older than your project's MSRV.
341343
Your project's MSRV is determined by taking the lowest `package.rust-version` set among your workspace members.
342344
If there is none set, your toolchain version will be used with the intent to pick up the version from rustup's `rust-toolchain.toml`, if present.
343345

344-
MSRV-incompatible dependencies can still be selected by:
346+
#### `resolver.something-like-precedence`
347+
* Type: string
348+
* Default: "something-like-maximum"
349+
* Environment: `CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE`
350+
351+
Select which policy should be used when resolving dependencies. Values include
352+
- `something-like-maximum`: prefer highest compatible versions of a package
353+
- `something-like-rust-version`: prefer versions of packages compatible with your project's Rust version
354+
355+
Can be overridden with
356+
- `--ignore-rust-version` CLI option
345357
- Setting the dependency's version requirement too high
346358
- Specifying the version to `cargo update` with `--precise`
347-
- Passing `--ignore-rust-version`
348359

349360
## precise-pre-release
350361

‎tests/testsuite/cargo_add/rust_version_ignore/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ fn case() {
2525
.arg("--ignore-rust-version")
2626
.arg_line("rust-version-user")
2727
.current_dir(cwd)
28+
.env(
29+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
30+
"something-like-rust-version",
31+
)
2832
.masquerade_as_nightly_cargo(&["msrv-policy"])
2933
.assert()
3034
.code(0)

‎tests/testsuite/cargo_add/rust_version_incompatible/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ fn case() {
2727
.arg("add")
2828
.arg_line("rust-version-user")
2929
.current_dir(cwd)
30+
.env(
31+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
32+
"something-like-rust-version",
33+
)
3034
.masquerade_as_nightly_cargo(&["msrv-policy"])
3135
.assert()
3236
.failure()

‎tests/testsuite/cargo_add/rust_version_latest/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ fn case() {
2424
.arg("add")
2525
.arg_line("rust-version-user")
2626
.current_dir(cwd)
27+
.env(
28+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
29+
"something-like-rust-version",
30+
)
2731
.masquerade_as_nightly_cargo(&["msrv-policy"])
2832
.assert()
2933
.success()

‎tests/testsuite/cargo_add/rust_version_older/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ fn case() {
2424
.arg("add")
2525
.arg_line("rust-version-user")
2626
.current_dir(cwd)
27+
.env(
28+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
29+
"something-like-rust-version",
30+
)
2731
.masquerade_as_nightly_cargo(&["msrv-policy"])
2832
.assert()
2933
.success()

‎tests/testsuite/cargo_add/rustc_ignore/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ fn case() {
2828
.arg("--ignore-rust-version")
2929
.arg_line("rust-version-user")
3030
.current_dir(cwd)
31+
.env(
32+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
33+
"something-like-rust-version",
34+
)
3135
.masquerade_as_nightly_cargo(&["msrv-policy"])
3236
.assert()
3337
.code(0)

‎tests/testsuite/cargo_add/rustc_incompatible/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ fn case() {
2121
.arg("add")
2222
.arg_line("rust-version-user")
2323
.current_dir(cwd)
24+
.env(
25+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
26+
"something-like-rust-version",
27+
)
2428
.masquerade_as_nightly_cargo(&["msrv-policy"])
2529
.assert()
2630
.failure()

‎tests/testsuite/cargo_add/rustc_latest/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ fn case() {
2727
.arg("add")
2828
.arg_line("rust-version-user")
2929
.current_dir(cwd)
30+
.env(
31+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
32+
"something-like-rust-version",
33+
)
3034
.masquerade_as_nightly_cargo(&["msrv-policy"])
3135
.assert()
3236
.success()

‎tests/testsuite/cargo_add/rustc_older/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ fn case() {
2727
.arg("add")
2828
.arg_line("rust-version-user")
2929
.current_dir(cwd)
30+
.env(
31+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
32+
"something-like-rust-version",
33+
)
3034
.masquerade_as_nightly_cargo(&["msrv-policy"])
3135
.assert()
3236
.success()

‎tests/testsuite/rust_version.rs

+230-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Tests for targets with `rust-version`.
22
3-
use cargo_test_support::{project, registry::Package};
3+
use cargo_test_support::{cargo_process, project, registry::Package};
44

55
#[cargo_test]
66
fn rust_version_satisfied() {
@@ -213,6 +213,10 @@ fn resolve_with_rust_version() {
213213
.build();
214214

215215
p.cargo("generate-lockfile --ignore-rust-version")
216+
.env(
217+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
218+
"something-like-rust-version",
219+
)
216220
.arg("-Zmsrv-policy")
217221
.masquerade_as_nightly_cargo(&["msrv-policy"])
218222
.with_stderr(
@@ -233,6 +237,10 @@ foo v0.0.1 ([CWD])
233237
.run();
234238

235239
p.cargo("generate-lockfile")
240+
.env(
241+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
242+
"something-like-rust-version",
243+
)
236244
.arg("-Zmsrv-policy")
237245
.masquerade_as_nightly_cargo(&["msrv-policy"])
238246
.with_stderr(
@@ -289,6 +297,10 @@ fn resolve_with_rustc() {
289297
.build();
290298

291299
p.cargo("generate-lockfile --ignore-rust-version")
300+
.env(
301+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
302+
"something-like-rust-version",
303+
)
292304
.arg("-Zmsrv-policy")
293305
.masquerade_as_nightly_cargo(&["msrv-policy"])
294306
.with_stderr(
@@ -309,6 +321,10 @@ foo v0.0.1 ([CWD])
309321
.run();
310322

311323
p.cargo("generate-lockfile")
324+
.env(
325+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
326+
"something-like-rust-version",
327+
)
312328
.arg("-Zmsrv-policy")
313329
.masquerade_as_nightly_cargo(&["msrv-policy"])
314330
.with_stderr(
@@ -363,6 +379,10 @@ fn resolve_with_backtracking() {
363379
.build();
364380

365381
p.cargo("generate-lockfile --ignore-rust-version")
382+
.env(
383+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
384+
"something-like-rust-version",
385+
)
366386
.arg("-Zmsrv-policy")
367387
.masquerade_as_nightly_cargo(&["msrv-policy"])
368388
.with_stderr(
@@ -384,6 +404,10 @@ foo v0.0.1 ([CWD])
384404

385405
// Ideally we'd pick `has-rust-version` 1.6.0 which requires backtracking
386406
p.cargo("generate-lockfile")
407+
.env(
408+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
409+
"something-like-rust-version",
410+
)
387411
.arg("-Zmsrv-policy")
388412
.masquerade_as_nightly_cargo(&["msrv-policy"])
389413
.with_stderr(
@@ -462,6 +486,10 @@ fn resolve_with_multiple_rust_versions() {
462486
.build();
463487

464488
p.cargo("generate-lockfile --ignore-rust-version")
489+
.env(
490+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
491+
"something-like-rust-version",
492+
)
465493
.arg("-Zmsrv-policy")
466494
.masquerade_as_nightly_cargo(&["msrv-policy"])
467495
.with_stderr(
@@ -482,6 +510,10 @@ higher v0.0.1 ([CWD])
482510
.run();
483511

484512
p.cargo("generate-lockfile")
513+
.env(
514+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
515+
"something-like-rust-version",
516+
)
485517
.arg("-Zmsrv-policy")
486518
.masquerade_as_nightly_cargo(&["msrv-policy"])
487519
.with_stderr(
@@ -503,6 +535,84 @@ higher v0.0.1 ([CWD])
503535
.run();
504536
}
505537

538+
#[cargo_test]
539+
fn resolve_unstable_config_on_stable() {
540+
Package::new("only-newer", "1.6.0")
541+
.rust_version("1.65.0")
542+
.file("src/lib.rs", "fn other_stuff() {}")
543+
.publish();
544+
Package::new("newer-and-older", "1.5.0")
545+
.rust_version("1.55.0")
546+
.file("src/lib.rs", "fn other_stuff() {}")
547+
.publish();
548+
Package::new("newer-and-older", "1.6.0")
549+
.rust_version("1.65.0")
550+
.file("src/lib.rs", "fn other_stuff() {}")
551+
.publish();
552+
553+
let p = project()
554+
.file(
555+
"Cargo.toml",
556+
r#"
557+
[package]
558+
name = "foo"
559+
version = "0.0.1"
560+
edition = "2015"
561+
authors = []
562+
rust-version = "1.60.0"
563+
564+
[dependencies]
565+
only-newer = "1.0.0"
566+
newer-and-older = "1.0.0"
567+
"#,
568+
)
569+
.file("src/main.rs", "fn main(){}")
570+
.build();
571+
572+
p.cargo("generate-lockfile")
573+
.env(
574+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
575+
"something-like-rust-version",
576+
)
577+
.with_stderr(
578+
"\
579+
[WARNING] ignoring `resolver` config table without `-Zmsrv-policy`
580+
[UPDATING] `dummy-registry` index
581+
[LOCKING] 3 packages to latest compatible versions
582+
",
583+
)
584+
.run();
585+
p.cargo("tree")
586+
.with_stdout(
587+
"\
588+
foo v0.0.1 ([CWD])
589+
├── newer-and-older v1.6.0
590+
└── only-newer v1.6.0
591+
",
592+
)
593+
.run();
594+
595+
p.cargo("generate-lockfile")
596+
.env("CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE", "non-existent")
597+
.with_stderr(
598+
"\
599+
[WARNING] ignoring `resolver` config table without `-Zmsrv-policy`
600+
[UPDATING] `dummy-registry` index
601+
[LOCKING] 3 packages to latest compatible versions
602+
",
603+
)
604+
.run();
605+
p.cargo("tree")
606+
.with_stdout(
607+
"\
608+
foo v0.0.1 ([CWD])
609+
├── newer-and-older v1.6.0
610+
└── only-newer v1.6.0
611+
",
612+
)
613+
.run();
614+
}
615+
506616
#[cargo_test]
507617
fn generate_lockfile_ignore_rust_version_is_unstable() {
508618
Package::new("bar", "1.5.0")
@@ -572,6 +682,10 @@ fn update_msrv_resolve() {
572682
.build();
573683

574684
p.cargo("update")
685+
.env(
686+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
687+
"something-like-rust-version",
688+
)
575689
.arg("-Zmsrv-policy")
576690
.masquerade_as_nightly_cargo(&["msrv-policy"])
577691
.with_stderr(
@@ -593,6 +707,10 @@ See https://github.com/rust-lang/cargo/issues/9930 for more information about th
593707
)
594708
.run();
595709
p.cargo("update --ignore-rust-version")
710+
.env(
711+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
712+
"something-like-rust-version",
713+
)
596714
.arg("-Zmsrv-policy")
597715
.masquerade_as_nightly_cargo(&["msrv-policy"])
598716
.with_stderr(
@@ -605,6 +723,65 @@ See https://github.com/rust-lang/cargo/issues/9930 for more information about th
605723
.run();
606724
}
607725

726+
#[cargo_test]
727+
fn update_precise_overrides_msrv_resolver() {
728+
Package::new("bar", "1.5.0")
729+
.rust_version("1.55.0")
730+
.file("src/lib.rs", "fn other_stuff() {}")
731+
.publish();
732+
Package::new("bar", "1.6.0")
733+
.rust_version("1.65.0")
734+
.file("src/lib.rs", "fn other_stuff() {}")
735+
.publish();
736+
737+
let p = project()
738+
.file(
739+
"Cargo.toml",
740+
r#"
741+
[package]
742+
name = "foo"
743+
version = "0.0.1"
744+
edition = "2015"
745+
authors = []
746+
rust-version = "1.60.0"
747+
[dependencies]
748+
bar = "1.0.0"
749+
"#,
750+
)
751+
.file("src/main.rs", "fn main(){}")
752+
.build();
753+
754+
p.cargo("update")
755+
.env(
756+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
757+
"something-like-rust-version",
758+
)
759+
.arg("-Zmsrv-policy")
760+
.masquerade_as_nightly_cargo(&["msrv-policy"])
761+
.with_stderr(
762+
"\
763+
[UPDATING] `dummy-registry` index
764+
[LOCKING] 2 packages to latest Rust 1.60.0 compatible versions
765+
[ADDING] bar v1.5.0 (latest: v1.6.0)
766+
",
767+
)
768+
.run();
769+
p.cargo("update --precise 1.6.0 bar")
770+
.env(
771+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
772+
"something-like-rust-version",
773+
)
774+
.arg("-Zmsrv-policy")
775+
.masquerade_as_nightly_cargo(&["msrv-policy"])
776+
.with_stderr(
777+
"\
778+
[UPDATING] `dummy-registry` index
779+
[UPDATING] bar v1.5.0 -> v1.6.0
780+
",
781+
)
782+
.run();
783+
}
784+
608785
#[cargo_test]
609786
fn check_msrv_resolve() {
610787
Package::new("only-newer", "1.6.0")
@@ -640,6 +817,10 @@ fn check_msrv_resolve() {
640817
.build();
641818

642819
p.cargo("check --ignore-rust-version")
820+
.env(
821+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
822+
"something-like-rust-version",
823+
)
643824
.arg("-Zmsrv-policy")
644825
.masquerade_as_nightly_cargo(&["msrv-policy"])
645826
.with_stderr(
@@ -668,6 +849,10 @@ foo v0.0.1 ([CWD])
668849

669850
std::fs::remove_file(p.root().join("Cargo.lock")).unwrap();
670851
p.cargo("check")
852+
.env(
853+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
854+
"something-like-rust-version",
855+
)
671856
.arg("-Zmsrv-policy")
672857
.masquerade_as_nightly_cargo(&["msrv-policy"])
673858
.with_stderr(
@@ -693,3 +878,47 @@ foo v0.0.1 ([CWD])
693878
)
694879
.run();
695880
}
881+
882+
#[cargo_test]
883+
fn cargo_install_ignores_msrv_config() {
884+
Package::new("dep", "1.0.0")
885+
.rust_version("1.50")
886+
.file("src/lib.rs", "fn hello() {}")
887+
.publish();
888+
Package::new("dep", "1.1.0")
889+
.rust_version("1.70")
890+
.file("src/lib.rs", "fn hello() {}")
891+
.publish();
892+
Package::new("foo", "0.0.1")
893+
.rust_version("1.60")
894+
.file("src/main.rs", "fn main() {}")
895+
.dep("dep", "1")
896+
.publish();
897+
898+
cargo_process("install foo")
899+
.env(
900+
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
901+
"something-like-rust-version",
902+
)
903+
.arg("-Zmsrv-policy")
904+
.masquerade_as_nightly_cargo(&["msrv-policy"])
905+
.with_stderr(
906+
"\
907+
[UPDATING] `[..]` index
908+
[DOWNLOADING] crates ...
909+
[DOWNLOADED] foo v0.0.1 (registry [..])
910+
[INSTALLING] foo v0.0.1
911+
[LOCKING] 2 packages to latest Rust 1.60 compatible versions
912+
[ADDING] dep v1.0.0 (latest: v1.1.0)
913+
[DOWNLOADING] crates ...
914+
[DOWNLOADED] dep v1.0.0 (registry [..])
915+
[COMPILING] dep v1.0.0
916+
[COMPILING] foo v0.0.1
917+
[FINISHED] `release` profile [optimized] target(s) in [..]
918+
[INSTALLING] [CWD]/home/.cargo/bin/foo[EXE]
919+
[INSTALLED] package `foo v0.0.1` (executable `foo[EXE]`)
920+
[WARNING] be sure to add `[..]` to your PATH to be able to run the installed binaries
921+
",
922+
)
923+
.run();
924+
}

0 commit comments

Comments
 (0)
Please sign in to comment.