.arg(
opt("version", "The version to yank or un-yank")
.alias("vers")
- .value_name("VERSION")
- .required(true),
+ .value_name("VERSION"),
)
.arg(opt(
"undo",
let registry = args.registry(config)?;
+ let (krate, version) = resolve_crate(args.value_of("crate"), args.value_of("version"))?;
+ if version.is_none() {
+ return Err(anyhow::format_err!("`--version` is required").into());
+ }
+
ops::yank(
config,
- args.value_of("crate").map(|s| s.to_string()),
- args.value_of("version").map(|s| s.to_string()),
+ krate.map(|s| s.to_string()),
+ version.map(|s| s.to_string()),
args.value_of("token").map(|s| s.to_string()),
args.value_of("index").map(|s| s.to_string()),
args.is_present("undo"),
)?;
Ok(())
}
+
+fn resolve_crate<'k>(
+ mut krate: Option<&'k str>,
+ mut version: Option<&'k str>,
+) -> crate::CargoResult<(Option<&'k str>, Option<&'k str>)> {
+ if let Some((k, v)) = krate.and_then(|k| k.split_once('@')) {
+ if version.is_some() {
+ anyhow::bail!("cannot specify both `@{v}` and `--version`");
+ }
+ if k.is_empty() {
+ // by convention, arguments starting with `@` are response files
+ anyhow::bail!("missing crate name for `@{v}`");
+ }
+ krate = Some(k);
+ version = Some(v);
+ }
+ Ok((krate, version))
+}
}
#[cargo_test]
-fn simple() {
+fn explicit_version() {
registry::init();
setup("foo", "0.0.1");
)
.run();
}
+
+#[cargo_test]
+fn inline_version() {
+ registry::init();
+ setup("foo", "0.0.1");
+
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ license = "MIT"
+ description = "foo"
+ "#,
+ )
+ .file("src/main.rs", "fn main() {}")
+ .build();
+
+ p.cargo("yank foo@0.0.1 --token sekrit").run();
+
+ p.cargo("yank --undo foo@0.0.1 --token sekrit")
+ .with_status(101)
+ .with_stderr(
+ " Updating `[..]` index
+ Unyank foo@0.0.1
+error: failed to undo a yank from the registry at file:///[..]
+
+Caused by:
+ EOF while parsing a value at line 1 column 0",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn version_required() {
+ registry::init();
+ setup("foo", "0.0.1");
+
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ license = "MIT"
+ description = "foo"
+ "#,
+ )
+ .file("src/main.rs", "fn main() {}")
+ .build();
+
+ p.cargo("yank foo --token sekrit")
+ .with_status(101)
+ .with_stderr("error: `--version` is required")
+ .run();
+}
+
+#[cargo_test]
+fn inline_version_without_name() {
+ registry::init();
+ setup("foo", "0.0.1");
+
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ license = "MIT"
+ description = "foo"
+ "#,
+ )
+ .file("src/main.rs", "fn main() {}")
+ .build();
+
+ p.cargo("yank @0.0.1 --token sekrit")
+ .with_status(101)
+ .with_stderr("error: missing crate name for `@0.0.1`")
+ .run();
+}
+
+#[cargo_test]
+fn inline_and_explicit_version() {
+ registry::init();
+ setup("foo", "0.0.1");
+
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ license = "MIT"
+ description = "foo"
+ "#,
+ )
+ .file("src/main.rs", "fn main() {}")
+ .build();
+
+ p.cargo("yank foo@0.0.1 --version 0.0.1 --token sekrit")
+ .with_status(101)
+ .with_stderr("error: cannot specify both `@0.0.1` and `--version`")
+ .run();
+}