diff --git a/crates/mdman/doc/out/mdman.1 b/crates/mdman/doc/out/mdman.1
index b114715aef20..e05df2bcc382 100644
--- a/crates/mdman/doc/out/mdman.1
+++ b/crates/mdman/doc/out/mdman.1
@@ -101,7 +101,7 @@ relative URL will be joined with this URL.
.sp
\fB\-\-man\fR \fIname\fR\fB:\fR\fIsection\fR\fB=\fR\fIurl\fR
.RS 4
-Specifies a URL to use for the given man page. When the \fB{{man name section}}\fR expression is used, the given URL will be inserted as a link. This
+Specifies a URL to use for the given man page. When the \fB{{man name section}}\fR expression is used, the given URL will be inserted as a link. This
may be specified multiple times. If a man page reference does not have a
matching \fB\-\-man\fR entry, then a relative link to a file named \fIname\fR\fB\&.md\fR will
be used.
diff --git a/crates/mdman/doc/out/mdman.md b/crates/mdman/doc/out/mdman.md
index 8f6f1018c725..d5d816cbd4cd 100644
--- a/crates/mdman/doc/out/mdman.md
+++ b/crates/mdman/doc/out/mdman.md
@@ -75,7 +75,7 @@ relative URL will be joined with this URL.
--manname:section=url
-
Specifies a URL to use for the given man page. When the {{man name section}} expression is used, the given URL will be inserted as a link. This
+
Specifies a URL to use for the given man page. When the {{man name section}} expression is used, the given URL will be inserted as a link. This
may be specified multiple times. If a man page reference does not have a
matching --man entry, then a relative link to a file named name.md will
be used.
diff --git a/src/bin/cargo/commands/add.rs b/src/bin/cargo/commands/add.rs
index da821f328bd2..f6a9a5338020 100644
--- a/src/bin/cargo/commands/add.rs
+++ b/src/bin/cargo/commands/add.rs
@@ -101,6 +101,12 @@ Example uses:
.help("Filesystem path to local crate to add")
.group("selected")
.conflicts_with("git"),
+ clap::Arg::new("base")
+ .long("base")
+ .action(ArgAction::Set)
+ .value_name("BASE")
+ .help("The path base to use when adding from a local crate.")
+ .requires("path"),
clap::Arg::new("git")
.long("git")
.action(ArgAction::Set)
@@ -224,6 +230,7 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult {
fn parse_dependencies(gctx: &GlobalContext, matches: &ArgMatches) -> CargoResult> {
let path = matches.get_one::("path");
+ let base = matches.get_one::("base");
let git = matches.get_one::("git");
let branch = matches.get_one::("branch");
let rev = matches.get_one::("rev");
@@ -329,6 +336,7 @@ fn parse_dependencies(gctx: &GlobalContext, matches: &ArgMatches) -> CargoResult
public,
registry: registry.clone(),
path: path.map(String::from),
+ base: base.map(String::from),
git: git.map(String::from),
branch: branch.map(String::from),
rev: rev.map(String::from),
diff --git a/src/cargo/ops/cargo_add/mod.rs b/src/cargo/ops/cargo_add/mod.rs
index c6f71847df38..be9265cd347b 100644
--- a/src/cargo/ops/cargo_add/mod.rs
+++ b/src/cargo/ops/cargo_add/mod.rs
@@ -12,6 +12,7 @@ use std::str::FromStr;
use anyhow::Context as _;
use cargo_util::paths;
use cargo_util_schemas::core::PartialVersion;
+use cargo_util_schemas::manifest::PathBaseName;
use cargo_util_schemas::manifest::RustVersion;
use indexmap::IndexSet;
use itertools::Itertools;
@@ -28,6 +29,7 @@ use crate::core::Workspace;
use crate::sources::source::QueryKind;
use crate::util::cache_lock::CacheLockMode;
use crate::util::style;
+use crate::util::toml::lookup_path_base;
use crate::util::toml_mut::dependency::Dependency;
use crate::util::toml_mut::dependency::GitSource;
use crate::util::toml_mut::dependency::MaybeWorkspace;
@@ -270,8 +272,11 @@ pub struct DepOp {
/// Registry for looking up dependency version
pub registry: Option,
- /// Git repo for dependency
+ /// File system path for dependency
pub path: Option,
+ /// Specify a named base for a path dependency
+ pub base: Option,
+
/// Git repo for dependency
pub git: Option,
/// Specify an alternative git branch
@@ -331,10 +336,25 @@ fn resolve_dependency(
};
selected
} else if let Some(raw_path) = &arg.path {
- let path = paths::normalize_path(&std::env::current_dir()?.join(raw_path));
- let src = PathSource::new(&path);
+ let (path, base_name_and_value) = if let Some(base_name) = &arg.base {
+ let workspace_root = || Ok(ws.root_manifest().parent().unwrap());
+ let base_value = lookup_path_base(
+ &PathBaseName::new(base_name.clone())?,
+ gctx,
+ &workspace_root,
+ None,
+ )?;
+ (
+ base_value.join(raw_path),
+ Some((base_name.clone(), base_value)),
+ )
+ } else {
+ (std::env::current_dir()?.join(raw_path), None)
+ };
+ let path = paths::normalize_path(&path);
+ let src = PathSource::new(path);
- let selected = if let Some(crate_spec) = &crate_spec {
+ let mut selected = if let Some(crate_spec) = &crate_spec {
if let Some(v) = crate_spec.version_req() {
// crate specifier includes a version (e.g. `docopt@0.8`)
anyhow::bail!("cannot specify a path (`{raw_path}`) with a version (`{v}`).");
@@ -349,10 +369,15 @@ fn resolve_dependency(
}
selected
} else {
- let mut source = crate::sources::PathSource::new(&path, src.source_id()?, gctx);
+ let mut source = crate::sources::PathSource::new(&src.path, src.source_id()?, gctx);
let package = source.root_package()?;
Dependency::from(package.summary())
};
+ if let Some(selected_source) = selected.source.as_mut() {
+ if let Source::Path(selected_source) = selected_source {
+ selected_source.base_name_and_value = base_name_and_value;
+ }
+ }
selected
} else if let Some(crate_spec) = &crate_spec {
crate_spec.to_dependency()?
diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs
index 44b3b6812c80..0bd4cd241841 100644
--- a/src/cargo/util/toml/mod.rs
+++ b/src/cargo/util/toml/mod.rs
@@ -312,7 +312,7 @@ fn normalize_toml(
inherit_cell
.try_borrow_with(|| load_inheritable_fields(gctx, manifest_file, &workspace_config))
};
- let workspace_root = || inherit().map(|fields| fields.ws_root());
+ let workspace_root = || inherit().map(|fields| fields.ws_root().as_path());
if let Some(original_package) = original_toml.package() {
let package_name = &original_package.name;
@@ -538,7 +538,7 @@ fn normalize_toml(
fn normalize_patch<'a>(
gctx: &GlobalContext,
original_patch: Option<&BTreeMap>>,
- workspace_root: &dyn Fn() -> CargoResult<&'a PathBuf>,
+ workspace_root: &dyn Fn() -> CargoResult<&'a Path>,
features: &Features,
) -> CargoResult
--all-targets
-
Build all targets. This is equivalent to specifying --lib --bins --tests --benches --examples.
+
Build all targets. This is equivalent to specifying --lib --bins --tests --benches --examples.
diff --git a/src/doc/src/commands/cargo-check.md b/src/doc/src/commands/cargo-check.md
index 664fa19f13d4..8022e16981f2 100644
--- a/src/doc/src/commands/cargo-check.md
+++ b/src/doc/src/commands/cargo-check.md
@@ -129,7 +129,7 @@ manifest settings for the target.
--all-targets
-
Check all targets. This is equivalent to specifying --lib --bins --tests --benches --examples.
+
Check all targets. This is equivalent to specifying --lib --bins --tests --benches --examples.
diff --git a/src/doc/src/commands/cargo-fix.md b/src/doc/src/commands/cargo-fix.md
index c84d33abd13a..a69478f553e9 100644
--- a/src/doc/src/commands/cargo-fix.md
+++ b/src/doc/src/commands/cargo-fix.md
@@ -209,7 +209,7 @@ manifest settings for the target.
--all-targets
-
Fix all targets. This is equivalent to specifying --lib --bins --tests --benches --examples.
+
Fix all targets. This is equivalent to specifying --lib --bins --tests --benches --examples.
diff --git a/src/doc/src/commands/cargo-rustc.md b/src/doc/src/commands/cargo-rustc.md
index 7d4943e85ed7..324aa9e56eb0 100644
--- a/src/doc/src/commands/cargo-rustc.md
+++ b/src/doc/src/commands/cargo-rustc.md
@@ -122,7 +122,7 @@ manifest settings for the target.
--all-targets
-
Build all targets. This is equivalent to specifying --lib --bins --tests --benches --examples.
+
Build all targets. This is equivalent to specifying --lib --bins --tests --benches --examples.
diff --git a/src/doc/src/commands/cargo-rustdoc.md b/src/doc/src/commands/cargo-rustdoc.md
index 5ff822877a08..33ea29826e71 100644
--- a/src/doc/src/commands/cargo-rustdoc.md
+++ b/src/doc/src/commands/cargo-rustdoc.md
@@ -128,7 +128,7 @@ manifest settings for the target.
--all-targets
-
Document all targets. This is equivalent to specifying --lib --bins --tests --benches --examples.
+
Document all targets. This is equivalent to specifying --lib --bins --tests --benches --examples.
diff --git a/src/doc/src/commands/cargo-test.md b/src/doc/src/commands/cargo-test.md
index 205985f4d088..50916fc6bead 100644
--- a/src/doc/src/commands/cargo-test.md
+++ b/src/doc/src/commands/cargo-test.md
@@ -231,7 +231,7 @@ manifest settings for the target.
--all-targets
-
Test all targets. This is equivalent to specifying --lib --bins --tests --benches --examples.
+
Test all targets. This is equivalent to specifying --lib --bins --tests --benches --examples.
diff --git a/src/etc/man/cargo-add.1 b/src/etc/man/cargo-add.1
index b89508b3f091..0fc43b9f2eed 100644
--- a/src/etc/man/cargo-add.1
+++ b/src/etc/man/cargo-add.1
@@ -8,7 +8,7 @@ cargo\-add \[em] Add dependencies to a Cargo.toml manifest file
.SH "SYNOPSIS"
\fBcargo add\fR [\fIoptions\fR] \fIcrate\fR\[u2026]
.br
-\fBcargo add\fR [\fIoptions\fR] \fB\-\-path\fR \fIpath\fR
+\fBcargo add\fR [\fIoptions\fR] \fB\-\-path\fR \fIpath\fR [\fB\-\-base\fR \fIbase\fR]
.br
\fBcargo add\fR [\fIoptions\fR] \fB\-\-git\fR \fIurl\fR [\fIcrate\fR\[u2026]]
.SH "DESCRIPTION"
@@ -74,6 +74,11 @@ Specific commit to use when adding from git.
\fIFilesystem path\fR to local crate to add.
.RE
.sp
+\fB\-\-base\fR \fIbase\fR
+.RS 4
+The \fIpath base\fR to use when adding a local crate.
+.RE
+.sp
\fB\-\-registry\fR \fIregistry\fR
.RS 4
Name of the registry to use. Registry names are defined in \fICargo config
diff --git a/src/etc/man/cargo-bench.1 b/src/etc/man/cargo-bench.1
index c74751013d37..ff32fc7e9705 100644
--- a/src/etc/man/cargo-bench.1
+++ b/src/etc/man/cargo-bench.1
@@ -236,7 +236,7 @@ manifest settings for the target.
.sp
\fB\-\-all\-targets\fR
.RS 4
-Benchmark all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&.
+Benchmark all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&.
.RE
.SS "Feature Selection"
The feature flags allow you to control which features are enabled. When no
diff --git a/src/etc/man/cargo-build.1 b/src/etc/man/cargo-build.1
index d210f44698a8..a61cb7013c15 100644
--- a/src/etc/man/cargo-build.1
+++ b/src/etc/man/cargo-build.1
@@ -135,7 +135,7 @@ manifest settings for the target.
.sp
\fB\-\-all\-targets\fR
.RS 4
-Build all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&.
+Build all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&.
.RE
.SS "Feature Selection"
The feature flags allow you to control which features are enabled. When no
diff --git a/src/etc/man/cargo-check.1 b/src/etc/man/cargo-check.1
index 30bc39098704..4f19d748bb36 100644
--- a/src/etc/man/cargo-check.1
+++ b/src/etc/man/cargo-check.1
@@ -131,7 +131,7 @@ manifest settings for the target.
.sp
\fB\-\-all\-targets\fR
.RS 4
-Check all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&.
+Check all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&.
.RE
.SS "Feature Selection"
The feature flags allow you to control which features are enabled. When no
diff --git a/src/etc/man/cargo-fix.1 b/src/etc/man/cargo-fix.1
index 4bb1ef4e1034..fa8f42cf7ade 100644
--- a/src/etc/man/cargo-fix.1
+++ b/src/etc/man/cargo-fix.1
@@ -226,7 +226,7 @@ manifest settings for the target.
.sp
\fB\-\-all\-targets\fR
.RS 4
-Fix all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&.
+Fix all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&.
.RE
.SS "Feature Selection"
The feature flags allow you to control which features are enabled. When no
diff --git a/src/etc/man/cargo-rustc.1 b/src/etc/man/cargo-rustc.1
index e301d13e4e61..1975db3ec7e5 100644
--- a/src/etc/man/cargo-rustc.1
+++ b/src/etc/man/cargo-rustc.1
@@ -121,7 +121,7 @@ manifest settings for the target.
.sp
\fB\-\-all\-targets\fR
.RS 4
-Build all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&.
+Build all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&.
.RE
.SS "Feature Selection"
The feature flags allow you to control which features are enabled. When no
diff --git a/src/etc/man/cargo-rustdoc.1 b/src/etc/man/cargo-rustdoc.1
index 0908e8ecbeb6..78f77d6a00f7 100644
--- a/src/etc/man/cargo-rustdoc.1
+++ b/src/etc/man/cargo-rustdoc.1
@@ -123,7 +123,7 @@ manifest settings for the target.
.sp
\fB\-\-all\-targets\fR
.RS 4
-Document all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&.
+Document all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&.
.RE
.SS "Feature Selection"
The feature flags allow you to control which features are enabled. When no
diff --git a/src/etc/man/cargo-test.1 b/src/etc/man/cargo-test.1
index 61fd967c956e..bd6b4a07be3c 100644
--- a/src/etc/man/cargo-test.1
+++ b/src/etc/man/cargo-test.1
@@ -250,7 +250,7 @@ manifest settings for the target.
.sp
\fB\-\-all\-targets\fR
.RS 4
-Test all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&.
+Test all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&.
.RE
.sp
\fB\-\-doc\fR
diff --git a/tests/testsuite/cargo_add/help/stdout.term.svg b/tests/testsuite/cargo_add/help/stdout.term.svg
index 9335d6061138..5aebaf2b3c38 100644
--- a/tests/testsuite/cargo_add/help/stdout.term.svg
+++ b/tests/testsuite/cargo_add/help/stdout.term.svg
@@ -219,83 +219,89 @@
- --git<URI>
+ --base<BASE>
- Git repository location
+ The path base to use when adding from a local crate.
-
+
- Without any other information, cargo will use latest commit on the main branch.
+ --git<URI>
-
+ Git repository location
- --branch<BRANCH>
+
- Git branch to download the crate from
+ Without any other information, cargo will use latest commit on the main branch.
- --tag<TAG>
+ --branch<BRANCH>
- Git tag to download the crate from
+ Git branch to download the crate from
- --rev<REV>
+ --tag<TAG>
- Git reference to download the crate from
+ Git tag to download the crate from
-
+
- This is the catch all, handling hashes to named references in remote repositories.
+ --rev<REV>
-
+ Git reference to download the crate from
- --registry<NAME>
+
- Package registry for this dependency
+ This is the catch all, handling hashes to named references in remote repositories.
- Section:
+ --registry<NAME>
- --dev
+ Package registry for this dependency
- Add as development dependency
+
-
+ Section:
- Dev-dependencies are not used when compiling a package for building, but are used for
+ --dev
- compiling tests, examples, and benchmarks.
+ Add as development dependency
- These dependencies are not propagated to other packages which depend on this package.
+ Dev-dependencies are not used when compiling a package for building, but are used for
-
+ compiling tests, examples, and benchmarks.
- --build
+
- Add as build dependency
+ These dependencies are not propagated to other packages which depend on this package.
-
+
- Build-dependencies are the only dependencies available for use by build scripts
+ --build
- (`build.rs` files).
+ Add as build dependency
-
+
- --target<TARGET>
+ Build-dependencies are the only dependencies available for use by build scripts
- Add as dependency to the given target platform
+ (`build.rs` files).
- Run `cargo help add` for more detailed information.
+ --target<TARGET>
-
+ Add as dependency to the given target platform
+
+
+
+ Run `cargo help add` for more detailed information.
+
+
diff --git a/tests/testsuite/cargo_add/mod.rs b/tests/testsuite/cargo_add/mod.rs
index 62feb8422c85..74156bb9c3ac 100644
--- a/tests/testsuite/cargo_add/mod.rs
+++ b/tests/testsuite/cargo_add/mod.rs
@@ -76,6 +76,7 @@ mod overwrite_default_features;
mod overwrite_default_features_with_no_default_features;
mod overwrite_features;
mod overwrite_git_with_path;
+mod overwrite_git_with_path_base;
mod overwrite_inherit_features_noop;
mod overwrite_inherit_noop;
mod overwrite_inherit_optional_noop;
@@ -91,6 +92,7 @@ mod overwrite_no_public_with_public;
mod overwrite_optional;
mod overwrite_optional_with_no_optional;
mod overwrite_optional_with_optional;
+mod overwrite_path_base_with_version;
mod overwrite_path_noop;
mod overwrite_path_with_version;
mod overwrite_preserves_inline_table;
@@ -105,6 +107,9 @@ mod overwrite_with_rename;
mod overwrite_workspace_dep;
mod overwrite_workspace_dep_features;
mod path;
+mod path_base;
+mod path_base_inferred_name;
+mod path_base_missing_base_path;
mod path_dev;
mod path_inferred_name;
mod path_inferred_name_conflicts_full_feature;
diff --git a/tests/testsuite/cargo_add/overwrite_git_with_path_base/in/.cargo/config.toml b/tests/testsuite/cargo_add/overwrite_git_with_path_base/in/.cargo/config.toml
new file mode 100644
index 000000000000..4539a4384236
--- /dev/null
+++ b/tests/testsuite/cargo_add/overwrite_git_with_path_base/in/.cargo/config.toml
@@ -0,0 +1,2 @@
+[path-bases]
+my_base = "."
diff --git a/tests/testsuite/cargo_add/overwrite_git_with_path_base/in/dependency/Cargo.toml b/tests/testsuite/cargo_add/overwrite_git_with_path_base/in/dependency/Cargo.toml
new file mode 100644
index 000000000000..c645a3371c0b
--- /dev/null
+++ b/tests/testsuite/cargo_add/overwrite_git_with_path_base/in/dependency/Cargo.toml
@@ -0,0 +1,6 @@
+[workspace]
+
+[package]
+name = "cargo-list-test-fixture-dependency"
+version = "0.0.0"
+edition = "2015"
diff --git a/tests/testsuite/cargo_add/overwrite_git_with_path_base/in/dependency/src/lib.rs b/tests/testsuite/cargo_add/overwrite_git_with_path_base/in/dependency/src/lib.rs
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/tests/testsuite/cargo_add/overwrite_git_with_path_base/in/primary/Cargo.toml b/tests/testsuite/cargo_add/overwrite_git_with_path_base/in/primary/Cargo.toml
new file mode 100644
index 000000000000..8650d6300199
--- /dev/null
+++ b/tests/testsuite/cargo_add/overwrite_git_with_path_base/in/primary/Cargo.toml
@@ -0,0 +1,11 @@
+cargo-features = ["path-bases"]
+
+[workspace]
+
+[package]
+name = "cargo-list-test-fixture"
+version = "0.0.0"
+edition = "2015"
+
+[dependencies]
+cargo-list-test-fixture-dependency = { git = "git://git.git", branch = "main", optional = true }
diff --git a/tests/testsuite/cargo_add/overwrite_git_with_path_base/in/primary/src/lib.rs b/tests/testsuite/cargo_add/overwrite_git_with_path_base/in/primary/src/lib.rs
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/tests/testsuite/cargo_add/overwrite_git_with_path_base/mod.rs b/tests/testsuite/cargo_add/overwrite_git_with_path_base/mod.rs
new file mode 100644
index 000000000000..b049b3f811e2
--- /dev/null
+++ b/tests/testsuite/cargo_add/overwrite_git_with_path_base/mod.rs
@@ -0,0 +1,39 @@
+use cargo_test_support::compare::assert_ui;
+use cargo_test_support::current_dir;
+use cargo_test_support::file;
+use cargo_test_support::prelude::*;
+use cargo_test_support::str;
+use cargo_test_support::Project;
+
+#[cargo_test]
+fn case() {
+ cargo_test_support::registry::init();
+ for ver in [
+ "0.1.1+my-package",
+ "0.2.0+my-package",
+ "0.2.3+my-package",
+ "0.4.1+my-package",
+ "20.0.0+my-package",
+ "99999.0.0+my-package",
+ "99999.0.0-alpha.1+my-package",
+ ] {
+ cargo_test_support::registry::Package::new("cargo-list-test-fixture-dependency", ver)
+ .publish();
+ }
+
+ let project = Project::from_template(current_dir!().join("in"));
+ let project_root = project.root();
+ let cwd = project_root.join("primary");
+
+ snapbox::cmd::Command::cargo_ui()
+ .arg("add")
+ .arg_line("cargo-list-test-fixture-dependency --path dependency --base my_base")
+ .current_dir(&cwd)
+ .masquerade_as_nightly_cargo(&["path-base"])
+ .assert()
+ .success()
+ .stdout_eq(str![""])
+ .stderr_eq(file!["stderr.term.svg"]);
+
+ assert_ui().subset_matches(current_dir!().join("out"), &project_root);
+}
diff --git a/tests/testsuite/cargo_add/overwrite_git_with_path_base/out/dependency/Cargo.toml b/tests/testsuite/cargo_add/overwrite_git_with_path_base/out/dependency/Cargo.toml
new file mode 100644
index 000000000000..c645a3371c0b
--- /dev/null
+++ b/tests/testsuite/cargo_add/overwrite_git_with_path_base/out/dependency/Cargo.toml
@@ -0,0 +1,6 @@
+[workspace]
+
+[package]
+name = "cargo-list-test-fixture-dependency"
+version = "0.0.0"
+edition = "2015"
diff --git a/tests/testsuite/cargo_add/overwrite_git_with_path_base/out/primary/Cargo.toml b/tests/testsuite/cargo_add/overwrite_git_with_path_base/out/primary/Cargo.toml
new file mode 100644
index 000000000000..5366a76cb402
--- /dev/null
+++ b/tests/testsuite/cargo_add/overwrite_git_with_path_base/out/primary/Cargo.toml
@@ -0,0 +1,14 @@
+cargo-features = ["path-bases"]
+
+[workspace]
+
+[package]
+name = "cargo-list-test-fixture"
+version = "0.0.0"
+edition = "2015"
+
+[dependencies]
+cargo-list-test-fixture-dependency = { optional = true, base = "my_base", path = "dependency", version = "0.0.0" }
+
+[features]
+cargo-list-test-fixture-dependency = ["dep:cargo-list-test-fixture-dependency"]
diff --git a/tests/testsuite/cargo_add/overwrite_git_with_path_base/stderr.term.svg b/tests/testsuite/cargo_add/overwrite_git_with_path_base/stderr.term.svg
new file mode 100644
index 000000000000..597efa5a7e25
--- /dev/null
+++ b/tests/testsuite/cargo_add/overwrite_git_with_path_base/stderr.term.svg
@@ -0,0 +1,31 @@
+
diff --git a/tests/testsuite/cargo_add/overwrite_path_base_with_version/in/.cargo/config.toml b/tests/testsuite/cargo_add/overwrite_path_base_with_version/in/.cargo/config.toml
new file mode 100644
index 000000000000..4539a4384236
--- /dev/null
+++ b/tests/testsuite/cargo_add/overwrite_path_base_with_version/in/.cargo/config.toml
@@ -0,0 +1,2 @@
+[path-bases]
+my_base = "."
diff --git a/tests/testsuite/cargo_add/overwrite_path_base_with_version/in/dependency/Cargo.toml b/tests/testsuite/cargo_add/overwrite_path_base_with_version/in/dependency/Cargo.toml
new file mode 100644
index 000000000000..c645a3371c0b
--- /dev/null
+++ b/tests/testsuite/cargo_add/overwrite_path_base_with_version/in/dependency/Cargo.toml
@@ -0,0 +1,6 @@
+[workspace]
+
+[package]
+name = "cargo-list-test-fixture-dependency"
+version = "0.0.0"
+edition = "2015"
diff --git a/tests/testsuite/cargo_add/overwrite_path_base_with_version/in/dependency/src/lib.rs b/tests/testsuite/cargo_add/overwrite_path_base_with_version/in/dependency/src/lib.rs
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/tests/testsuite/cargo_add/overwrite_path_base_with_version/in/primary/Cargo.toml b/tests/testsuite/cargo_add/overwrite_path_base_with_version/in/primary/Cargo.toml
new file mode 100644
index 000000000000..9d01c0943691
--- /dev/null
+++ b/tests/testsuite/cargo_add/overwrite_path_base_with_version/in/primary/Cargo.toml
@@ -0,0 +1,11 @@
+cargo-features = ["path-bases"]
+
+[workspace]
+
+[package]
+name = "cargo-list-test-fixture"
+version = "0.0.0"
+edition = "2015"
+
+[dependencies]
+cargo-list-test-fixture-dependency = { optional = true, path = "dependency", base = "my_base" }
diff --git a/tests/testsuite/cargo_add/overwrite_path_base_with_version/in/primary/src/lib.rs b/tests/testsuite/cargo_add/overwrite_path_base_with_version/in/primary/src/lib.rs
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/tests/testsuite/cargo_add/overwrite_path_base_with_version/mod.rs b/tests/testsuite/cargo_add/overwrite_path_base_with_version/mod.rs
new file mode 100644
index 000000000000..33a2fb8268ac
--- /dev/null
+++ b/tests/testsuite/cargo_add/overwrite_path_base_with_version/mod.rs
@@ -0,0 +1,39 @@
+use cargo_test_support::compare::assert_ui;
+use cargo_test_support::current_dir;
+use cargo_test_support::file;
+use cargo_test_support::prelude::*;
+use cargo_test_support::str;
+use cargo_test_support::Project;
+
+#[cargo_test]
+fn case() {
+ cargo_test_support::registry::init();
+ for ver in [
+ "0.1.1+my-package",
+ "0.2.0+my-package",
+ "0.2.3+my-package",
+ "0.4.1+my-package",
+ "20.0.0+my-package",
+ "99999.0.0+my-package",
+ "99999.0.0-alpha.1+my-package",
+ ] {
+ cargo_test_support::registry::Package::new("cargo-list-test-fixture-dependency", ver)
+ .publish();
+ }
+
+ let project = Project::from_template(current_dir!().join("in"));
+ let project_root = project.root();
+ let cwd = project_root.join("primary");
+
+ snapbox::cmd::Command::cargo_ui()
+ .arg("add")
+ .arg_line("cargo-list-test-fixture-dependency@20.0")
+ .current_dir(&cwd)
+ .masquerade_as_nightly_cargo(&["path-base"])
+ .assert()
+ .success()
+ .stdout_eq(str![""])
+ .stderr_eq(file!["stderr.term.svg"]);
+
+ assert_ui().subset_matches(current_dir!().join("out"), &project_root);
+}
diff --git a/tests/testsuite/cargo_add/overwrite_path_base_with_version/out/dependency/Cargo.toml b/tests/testsuite/cargo_add/overwrite_path_base_with_version/out/dependency/Cargo.toml
new file mode 100644
index 000000000000..c645a3371c0b
--- /dev/null
+++ b/tests/testsuite/cargo_add/overwrite_path_base_with_version/out/dependency/Cargo.toml
@@ -0,0 +1,6 @@
+[workspace]
+
+[package]
+name = "cargo-list-test-fixture-dependency"
+version = "0.0.0"
+edition = "2015"
diff --git a/tests/testsuite/cargo_add/overwrite_path_base_with_version/out/primary/Cargo.toml b/tests/testsuite/cargo_add/overwrite_path_base_with_version/out/primary/Cargo.toml
new file mode 100644
index 000000000000..ead3ec392329
--- /dev/null
+++ b/tests/testsuite/cargo_add/overwrite_path_base_with_version/out/primary/Cargo.toml
@@ -0,0 +1,14 @@
+cargo-features = ["path-bases"]
+
+[workspace]
+
+[package]
+name = "cargo-list-test-fixture"
+version = "0.0.0"
+edition = "2015"
+
+[dependencies]
+cargo-list-test-fixture-dependency = { optional = true, version = "20.0" }
+
+[features]
+cargo-list-test-fixture-dependency = ["dep:cargo-list-test-fixture-dependency"]
diff --git a/tests/testsuite/cargo_add/overwrite_path_base_with_version/stderr.term.svg b/tests/testsuite/cargo_add/overwrite_path_base_with_version/stderr.term.svg
new file mode 100644
index 000000000000..d2bab110c2e0
--- /dev/null
+++ b/tests/testsuite/cargo_add/overwrite_path_base_with_version/stderr.term.svg
@@ -0,0 +1,37 @@
+
diff --git a/tests/testsuite/cargo_add/path_base/in/.cargo/config.toml b/tests/testsuite/cargo_add/path_base/in/.cargo/config.toml
new file mode 100644
index 000000000000..4539a4384236
--- /dev/null
+++ b/tests/testsuite/cargo_add/path_base/in/.cargo/config.toml
@@ -0,0 +1,2 @@
+[path-bases]
+my_base = "."
diff --git a/tests/testsuite/cargo_add/path_base/in/dependency/Cargo.toml b/tests/testsuite/cargo_add/path_base/in/dependency/Cargo.toml
new file mode 100644
index 000000000000..c645a3371c0b
--- /dev/null
+++ b/tests/testsuite/cargo_add/path_base/in/dependency/Cargo.toml
@@ -0,0 +1,6 @@
+[workspace]
+
+[package]
+name = "cargo-list-test-fixture-dependency"
+version = "0.0.0"
+edition = "2015"
diff --git a/tests/testsuite/cargo_add/path_base/in/dependency/src/lib.rs b/tests/testsuite/cargo_add/path_base/in/dependency/src/lib.rs
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/tests/testsuite/cargo_add/path_base/in/primary/Cargo.toml b/tests/testsuite/cargo_add/path_base/in/primary/Cargo.toml
new file mode 100644
index 000000000000..420ef1eb8f7f
--- /dev/null
+++ b/tests/testsuite/cargo_add/path_base/in/primary/Cargo.toml
@@ -0,0 +1,8 @@
+cargo-features = ["path-bases"]
+
+[workspace]
+
+[package]
+name = "cargo-list-test-fixture"
+version = "0.0.0"
+edition = "2015"
diff --git a/tests/testsuite/cargo_add/path_base/in/primary/src/lib.rs b/tests/testsuite/cargo_add/path_base/in/primary/src/lib.rs
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/tests/testsuite/cargo_add/path_base/mod.rs b/tests/testsuite/cargo_add/path_base/mod.rs
new file mode 100644
index 000000000000..b049b3f811e2
--- /dev/null
+++ b/tests/testsuite/cargo_add/path_base/mod.rs
@@ -0,0 +1,39 @@
+use cargo_test_support::compare::assert_ui;
+use cargo_test_support::current_dir;
+use cargo_test_support::file;
+use cargo_test_support::prelude::*;
+use cargo_test_support::str;
+use cargo_test_support::Project;
+
+#[cargo_test]
+fn case() {
+ cargo_test_support::registry::init();
+ for ver in [
+ "0.1.1+my-package",
+ "0.2.0+my-package",
+ "0.2.3+my-package",
+ "0.4.1+my-package",
+ "20.0.0+my-package",
+ "99999.0.0+my-package",
+ "99999.0.0-alpha.1+my-package",
+ ] {
+ cargo_test_support::registry::Package::new("cargo-list-test-fixture-dependency", ver)
+ .publish();
+ }
+
+ let project = Project::from_template(current_dir!().join("in"));
+ let project_root = project.root();
+ let cwd = project_root.join("primary");
+
+ snapbox::cmd::Command::cargo_ui()
+ .arg("add")
+ .arg_line("cargo-list-test-fixture-dependency --path dependency --base my_base")
+ .current_dir(&cwd)
+ .masquerade_as_nightly_cargo(&["path-base"])
+ .assert()
+ .success()
+ .stdout_eq(str![""])
+ .stderr_eq(file!["stderr.term.svg"]);
+
+ assert_ui().subset_matches(current_dir!().join("out"), &project_root);
+}
diff --git a/tests/testsuite/cargo_add/path_base/out/dependency/Cargo.toml b/tests/testsuite/cargo_add/path_base/out/dependency/Cargo.toml
new file mode 100644
index 000000000000..c645a3371c0b
--- /dev/null
+++ b/tests/testsuite/cargo_add/path_base/out/dependency/Cargo.toml
@@ -0,0 +1,6 @@
+[workspace]
+
+[package]
+name = "cargo-list-test-fixture-dependency"
+version = "0.0.0"
+edition = "2015"
diff --git a/tests/testsuite/cargo_add/path_base/out/primary/Cargo.toml b/tests/testsuite/cargo_add/path_base/out/primary/Cargo.toml
new file mode 100644
index 000000000000..ecba72b5df69
--- /dev/null
+++ b/tests/testsuite/cargo_add/path_base/out/primary/Cargo.toml
@@ -0,0 +1,11 @@
+cargo-features = ["path-bases"]
+
+[workspace]
+
+[package]
+name = "cargo-list-test-fixture"
+version = "0.0.0"
+edition = "2015"
+
+[dependencies]
+cargo-list-test-fixture-dependency = { version = "0.0.0", base = "my_base", path = "dependency" }
diff --git a/tests/testsuite/cargo_add/path_base/stderr.term.svg b/tests/testsuite/cargo_add/path_base/stderr.term.svg
new file mode 100644
index 000000000000..602e208606ed
--- /dev/null
+++ b/tests/testsuite/cargo_add/path_base/stderr.term.svg
@@ -0,0 +1,29 @@
+
diff --git a/tests/testsuite/cargo_add/path_base_inferred_name/in/.cargo/config.toml b/tests/testsuite/cargo_add/path_base_inferred_name/in/.cargo/config.toml
new file mode 100644
index 000000000000..4539a4384236
--- /dev/null
+++ b/tests/testsuite/cargo_add/path_base_inferred_name/in/.cargo/config.toml
@@ -0,0 +1,2 @@
+[path-bases]
+my_base = "."
diff --git a/tests/testsuite/cargo_add/path_base_inferred_name/in/dependency/Cargo.toml b/tests/testsuite/cargo_add/path_base_inferred_name/in/dependency/Cargo.toml
new file mode 100644
index 000000000000..c645a3371c0b
--- /dev/null
+++ b/tests/testsuite/cargo_add/path_base_inferred_name/in/dependency/Cargo.toml
@@ -0,0 +1,6 @@
+[workspace]
+
+[package]
+name = "cargo-list-test-fixture-dependency"
+version = "0.0.0"
+edition = "2015"
diff --git a/tests/testsuite/cargo_add/path_base_inferred_name/in/dependency/src/lib.rs b/tests/testsuite/cargo_add/path_base_inferred_name/in/dependency/src/lib.rs
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/tests/testsuite/cargo_add/path_base_inferred_name/in/primary/Cargo.toml b/tests/testsuite/cargo_add/path_base_inferred_name/in/primary/Cargo.toml
new file mode 100644
index 000000000000..420ef1eb8f7f
--- /dev/null
+++ b/tests/testsuite/cargo_add/path_base_inferred_name/in/primary/Cargo.toml
@@ -0,0 +1,8 @@
+cargo-features = ["path-bases"]
+
+[workspace]
+
+[package]
+name = "cargo-list-test-fixture"
+version = "0.0.0"
+edition = "2015"
diff --git a/tests/testsuite/cargo_add/path_base_inferred_name/in/primary/src/lib.rs b/tests/testsuite/cargo_add/path_base_inferred_name/in/primary/src/lib.rs
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/tests/testsuite/cargo_add/path_base_inferred_name/mod.rs b/tests/testsuite/cargo_add/path_base_inferred_name/mod.rs
new file mode 100644
index 000000000000..38ceae1d21ba
--- /dev/null
+++ b/tests/testsuite/cargo_add/path_base_inferred_name/mod.rs
@@ -0,0 +1,39 @@
+use cargo_test_support::compare::assert_ui;
+use cargo_test_support::current_dir;
+use cargo_test_support::file;
+use cargo_test_support::prelude::*;
+use cargo_test_support::str;
+use cargo_test_support::Project;
+
+#[cargo_test]
+fn case() {
+ cargo_test_support::registry::init();
+ for ver in [
+ "0.1.1+my-package",
+ "0.2.0+my-package",
+ "0.2.3+my-package",
+ "0.4.1+my-package",
+ "20.0.0+my-package",
+ "99999.0.0+my-package",
+ "99999.0.0-alpha.1+my-package",
+ ] {
+ cargo_test_support::registry::Package::new("cargo-list-test-fixture-dependency", ver)
+ .publish();
+ }
+
+ let project = Project::from_template(current_dir!().join("in"));
+ let project_root = project.root();
+ let cwd = project_root.join("primary");
+
+ snapbox::cmd::Command::cargo_ui()
+ .arg("add")
+ .arg_line("--path dependency --base my_base")
+ .current_dir(&cwd)
+ .masquerade_as_nightly_cargo(&["path-base"])
+ .assert()
+ .success()
+ .stdout_eq(str![""])
+ .stderr_eq(file!["stderr.term.svg"]);
+
+ assert_ui().subset_matches(current_dir!().join("out"), &project_root);
+}
diff --git a/tests/testsuite/cargo_add/path_base_inferred_name/out/dependency/Cargo.toml b/tests/testsuite/cargo_add/path_base_inferred_name/out/dependency/Cargo.toml
new file mode 100644
index 000000000000..c645a3371c0b
--- /dev/null
+++ b/tests/testsuite/cargo_add/path_base_inferred_name/out/dependency/Cargo.toml
@@ -0,0 +1,6 @@
+[workspace]
+
+[package]
+name = "cargo-list-test-fixture-dependency"
+version = "0.0.0"
+edition = "2015"
diff --git a/tests/testsuite/cargo_add/path_base_inferred_name/out/primary/Cargo.toml b/tests/testsuite/cargo_add/path_base_inferred_name/out/primary/Cargo.toml
new file mode 100644
index 000000000000..ecba72b5df69
--- /dev/null
+++ b/tests/testsuite/cargo_add/path_base_inferred_name/out/primary/Cargo.toml
@@ -0,0 +1,11 @@
+cargo-features = ["path-bases"]
+
+[workspace]
+
+[package]
+name = "cargo-list-test-fixture"
+version = "0.0.0"
+edition = "2015"
+
+[dependencies]
+cargo-list-test-fixture-dependency = { version = "0.0.0", base = "my_base", path = "dependency" }
diff --git a/tests/testsuite/cargo_add/path_base_inferred_name/stderr.term.svg b/tests/testsuite/cargo_add/path_base_inferred_name/stderr.term.svg
new file mode 100644
index 000000000000..602e208606ed
--- /dev/null
+++ b/tests/testsuite/cargo_add/path_base_inferred_name/stderr.term.svg
@@ -0,0 +1,29 @@
+
diff --git a/tests/testsuite/cargo_add/path_base_missing_base_path/in/primary/Cargo.toml b/tests/testsuite/cargo_add/path_base_missing_base_path/in/primary/Cargo.toml
new file mode 100644
index 000000000000..8194d1deb0e0
--- /dev/null
+++ b/tests/testsuite/cargo_add/path_base_missing_base_path/in/primary/Cargo.toml
@@ -0,0 +1,4 @@
+[package]
+name = "cargo-list-test-fixture"
+version = "0.0.0"
+edition = "2015"
diff --git a/tests/testsuite/cargo_add/path_base_missing_base_path/in/primary/src/lib.rs b/tests/testsuite/cargo_add/path_base_missing_base_path/in/primary/src/lib.rs
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/tests/testsuite/cargo_add/path_base_missing_base_path/mod.rs b/tests/testsuite/cargo_add/path_base_missing_base_path/mod.rs
new file mode 100644
index 000000000000..9ff666d6a00b
--- /dev/null
+++ b/tests/testsuite/cargo_add/path_base_missing_base_path/mod.rs
@@ -0,0 +1,27 @@
+use cargo_test_support::compare::assert_ui;
+use cargo_test_support::current_dir;
+use cargo_test_support::file;
+use cargo_test_support::prelude::*;
+use cargo_test_support::str;
+use cargo_test_support::Project;
+
+#[cargo_test]
+fn case() {
+ cargo_test_support::registry::init();
+
+ let project = Project::from_template(current_dir!().join("in"));
+ let project_root = project.root();
+ let cwd = project_root.join("primary");
+
+ snapbox::cmd::Command::cargo_ui()
+ .arg("add")
+ .arg_line("--path dependency --base bad_base")
+ .current_dir(&cwd)
+ .masquerade_as_nightly_cargo(&["path-base"])
+ .assert()
+ .code(101)
+ .stdout_eq(str![""])
+ .stderr_eq(file!["stderr.term.svg"]);
+
+ assert_ui().subset_matches(current_dir!().join("out"), &project_root);
+}
diff --git a/tests/testsuite/cargo_add/path_base_missing_base_path/out/primary/Cargo.toml b/tests/testsuite/cargo_add/path_base_missing_base_path/out/primary/Cargo.toml
new file mode 100644
index 000000000000..8194d1deb0e0
--- /dev/null
+++ b/tests/testsuite/cargo_add/path_base_missing_base_path/out/primary/Cargo.toml
@@ -0,0 +1,4 @@
+[package]
+name = "cargo-list-test-fixture"
+version = "0.0.0"
+edition = "2015"
diff --git a/tests/testsuite/cargo_add/path_base_missing_base_path/stderr.term.svg b/tests/testsuite/cargo_add/path_base_missing_base_path/stderr.term.svg
new file mode 100644
index 000000000000..ebe52195f6c0
--- /dev/null
+++ b/tests/testsuite/cargo_add/path_base_missing_base_path/stderr.term.svg
@@ -0,0 +1,27 @@
+