cargo/tests/testsuite/alt_registry.rs
Ed Page fd8a91d185 fix(test): Un-redact Packaged files
This is a partial revert of ##14121
(e11d1722bb6e1e58c91adb1964993c74b45f4293)

Our focus for redacting (auto or with globs) includes
- run-specific information (timing, hashes, platform-specific wording)
- rustc-specific information

(We tend to use globs for rustc-specific information because there might
be some very specific times we need to care about some of the details)

However, "Packaged files" does not fit into any of that and, for now, we
are erring on the side of redacting less, rather than more, with the
move to snapbox.
As we see how it works out and what the underlying requirements are, we
can revisit this.
2024-06-21 11:05:41 -04:00

1982 lines
51 KiB
Rust

//! Tests for alternative registries.
use cargo_test_support::compare::assert_e2e;
use cargo_test_support::prelude::*;
use cargo_test_support::publish::validate_alt_upload;
use cargo_test_support::registry::{self, Package, RegistryBuilder};
use cargo_test_support::str;
use cargo_test_support::{basic_manifest, paths, project};
use std::fs;
#[cargo_test]
fn depend_on_alt_registry() {
registry::alt_init();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
edition = "2015"
[dependencies.bar]
version = "0.0.1"
registry = "alternative"
"#,
)
.file("src/main.rs", "fn main() {}")
.build();
Package::new("bar", "0.0.1").alternative(true).publish();
p.cargo("check")
.with_stderr_data(str![[r#"
[UPDATING] `alternative` index
[LOCKING] 2 packages to latest compatible versions
[DOWNLOADING] crates ...
[DOWNLOADED] bar v0.0.1 (registry `alternative`)
[CHECKING] bar v0.0.1 (registry `alternative`)
[CHECKING] foo v0.0.1 ([ROOT]/foo)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
"#]])
.run();
p.cargo("clean").run();
// Don't download a second time
p.cargo("check")
.with_stderr_data(str![[r#"
[CHECKING] bar v0.0.1 (registry `alternative`)
[CHECKING] foo v0.0.1 ([ROOT]/foo)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
"#]])
.run();
}
#[cargo_test]
fn depend_on_alt_registry_depends_on_same_registry_no_index() {
registry::alt_init();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
edition = "2015"
[dependencies.bar]
version = "0.0.1"
registry = "alternative"
"#,
)
.file("src/main.rs", "fn main() {}")
.build();
Package::new("baz", "0.0.1").alternative(true).publish();
Package::new("bar", "0.0.1")
.registry_dep("baz", "0.0.1")
.alternative(true)
.publish();
p.cargo("check")
.with_stderr_data(str![[r#"
[UPDATING] `alternative` index
[LOCKING] 3 packages to latest compatible versions
[DOWNLOADING] crates ...
[DOWNLOADED] baz v0.0.1 (registry `alternative`)
[DOWNLOADED] bar v0.0.1 (registry `alternative`)
[CHECKING] baz v0.0.1 (registry `alternative`)
[CHECKING] bar v0.0.1 (registry `alternative`)
[CHECKING] foo v0.0.1 ([ROOT]/foo)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
"#]])
.run();
}
#[cargo_test]
fn depend_on_alt_registry_depends_on_same_registry() {
registry::alt_init();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
edition = "2015"
[dependencies.bar]
version = "0.0.1"
registry = "alternative"
"#,
)
.file("src/main.rs", "fn main() {}")
.build();
Package::new("baz", "0.0.1").alternative(true).publish();
Package::new("bar", "0.0.1")
.registry_dep("baz", "0.0.1")
.alternative(true)
.publish();
p.cargo("check")
.with_stderr_data(str![[r#"
[UPDATING] `alternative` index
[LOCKING] 3 packages to latest compatible versions
[DOWNLOADING] crates ...
[DOWNLOADED] baz v0.0.1 (registry `alternative`)
[DOWNLOADED] bar v0.0.1 (registry `alternative`)
[CHECKING] baz v0.0.1 (registry `alternative`)
[CHECKING] bar v0.0.1 (registry `alternative`)
[CHECKING] foo v0.0.1 ([ROOT]/foo)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
"#]])
.run();
}
#[cargo_test]
fn depend_on_alt_registry_depends_on_crates_io() {
registry::alt_init();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
edition = "2015"
[dependencies.bar]
version = "0.0.1"
registry = "alternative"
"#,
)
.file("src/main.rs", "fn main() {}")
.build();
Package::new("baz", "0.0.1").publish();
Package::new("bar", "0.0.1")
.dep("baz", "0.0.1")
.alternative(true)
.publish();
p.cargo("check")
.with_stderr_data(
str![[r#"
[UPDATING] `alternative` index
[UPDATING] `dummy-registry` index
[LOCKING] 3 packages to latest compatible versions
[DOWNLOADING] crates ...
[DOWNLOADED] baz v0.0.1 (registry `dummy-registry`)
[DOWNLOADED] bar v0.0.1 (registry `alternative`)
[CHECKING] baz v0.0.1
[CHECKING] bar v0.0.1 (registry `alternative`)
[CHECKING] foo v0.0.1 ([ROOT]/foo)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
"#]]
.unordered(),
)
.run();
}
#[cargo_test]
fn registry_and_path_dep_works() {
registry::alt_init();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
edition = "2015"
[dependencies.bar]
path = "bar"
registry = "alternative"
"#,
)
.file("src/main.rs", "fn main() {}")
.file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
.file("bar/src/lib.rs", "")
.build();
p.cargo("check")
.with_stderr_data(str![[r#"
[LOCKING] 2 packages to latest compatible versions
[CHECKING] bar v0.0.1 ([ROOT]/foo/bar)
[CHECKING] foo v0.0.1 ([ROOT]/foo)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
"#]])
.run();
}
#[cargo_test]
fn registry_incompatible_with_git() {
registry::alt_init();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
edition = "2015"
[dependencies.bar]
git = ""
registry = "alternative"
"#,
)
.file("src/main.rs", "fn main() {}")
.build();
p.cargo("check")
.with_status(101)
.with_stderr_data(str![[r#"
[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml`
Caused by:
dependency (bar) specification is ambiguous. Only one of `git` or `registry` is allowed.
"#]])
.run();
}
#[cargo_test]
fn cannot_publish_to_crates_io_with_registry_dependency() {
let crates_io = registry::init();
let _alternative = RegistryBuilder::new().alternative().build();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
edition = "2015"
[dependencies.bar]
version = "0.0.1"
registry = "alternative"
"#,
)
.file("src/main.rs", "fn main() {}")
.build();
Package::new("bar", "0.0.1").alternative(true).publish();
p.cargo("publish")
.replace_crates_io(crates_io.index_url())
.with_status(101)
.with_stderr_data(str![[r#"
[UPDATING] crates.io index
[ERROR] crates cannot be published to crates.io with dependencies sourced from other
registries. `bar` needs to be published to crates.io before publishing this crate.
(crate `bar` is pulled from registry `alternative`)
"#]])
.run();
p.cargo("publish")
.replace_crates_io(crates_io.index_url())
.arg("--token")
.arg(crates_io.token())
.arg("--index")
.arg(crates_io.index_url().as_str())
.with_status(101)
.with_stderr_data(str![[r#"
[UPDATING] crates.io index
[ERROR] crates cannot be published to crates.io with dependencies sourced from other
registries. `bar` needs to be published to crates.io before publishing this crate.
(crate `bar` is pulled from registry `alternative`)
"#]])
.run();
}
#[cargo_test]
fn publish_with_registry_dependency() {
let _reg = RegistryBuilder::new()
.http_api()
.http_index()
.alternative()
.build();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
edition = "2015"
[dependencies.bar]
version = "0.0.1"
registry = "alternative"
"#,
)
.file("src/main.rs", "fn main() {}")
.build();
Package::new("bar", "0.0.1").alternative(true).publish();
p.cargo("publish --registry alternative")
.with_stderr_data(str![[r#"
[UPDATING] `alternative` index
[WARNING] manifest has no description, license, license-file, documentation, homepage or repository.
See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
[PACKAGING] foo v0.0.1 ([ROOT]/foo)
[UPDATING] `alternative` index
[PACKAGED] 4 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
[VERIFYING] foo v0.0.1 ([ROOT]/foo)
[DOWNLOADING] crates ...
[DOWNLOADED] bar v0.0.1 (registry `alternative`)
[COMPILING] bar v0.0.1 (registry `alternative`)
[COMPILING] foo v0.0.1 ([ROOT]/foo/target/package/foo-0.0.1)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
[UPLOADING] foo v0.0.1 ([ROOT]/foo)
[UPLOADED] foo v0.0.1 to registry `alternative`
[NOTE] waiting for `foo v0.0.1` to be available at registry `alternative`.
You may press ctrl-c to skip waiting; the crate should be available shortly.
[PUBLISHED] foo v0.0.1 at registry `alternative`
"#]])
.run();
validate_alt_upload(
r#"{
"authors": [],
"badges": {},
"categories": [],
"deps": [
{
"default_features": true,
"features": [],
"kind": "normal",
"name": "bar",
"optional": false,
"target": null,
"version_req": "^0.0.1"
}
],
"description": null,
"documentation": null,
"features": {},
"homepage": null,
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"name": "foo",
"readme": null,
"readme_file": null,
"repository": null,
"homepage": null,
"documentation": null,
"rust_version": null,
"vers": "0.0.1"
}"#,
"foo-0.0.1.crate",
&["Cargo.lock", "Cargo.toml", "Cargo.toml.orig", "src/main.rs"],
);
}
#[cargo_test]
fn alt_registry_and_crates_io_deps() {
registry::alt_init();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
edition = "2015"
[dependencies]
crates_io_dep = "0.0.1"
[dependencies.alt_reg_dep]
version = "0.1.0"
registry = "alternative"
"#,
)
.file("src/main.rs", "fn main() {}")
.build();
Package::new("crates_io_dep", "0.0.1").publish();
Package::new("alt_reg_dep", "0.1.0")
.alternative(true)
.publish();
p.cargo("check")
.with_stderr_data(
str![[r#"
[UPDATING] `alternative` index
[UPDATING] `dummy-registry` index
[LOCKING] 3 packages to latest compatible versions
[DOWNLOADING] crates ...
[DOWNLOADED] crates_io_dep v0.0.1 (registry `dummy-registry`)
[DOWNLOADED] alt_reg_dep v0.1.0 (registry `alternative`)
[CHECKING] crates_io_dep v0.0.1
[CHECKING] alt_reg_dep v0.1.0 (registry `alternative`)
[CHECKING] foo v0.0.1 ([ROOT]/foo)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
"#]]
.unordered(),
)
.run();
}
#[cargo_test]
fn block_publish_due_to_no_token() {
registry::alt_init();
let p = project().file("src/lib.rs", "").build();
fs::remove_file(paths::home().join(".cargo/credentials.toml")).unwrap();
// Now perform the actual publish
p.cargo("publish --registry alternative")
.with_status(101)
.with_stderr_data(str![[r#"
[UPDATING] `alternative` index
[ERROR] no token found for `alternative`, please run `cargo login --registry alternative`
or use environment variable CARGO_REGISTRIES_ALTERNATIVE_TOKEN
"#]])
.run();
}
#[cargo_test]
fn cargo_registries_crates_io_protocol() {
let _ = RegistryBuilder::new()
.no_configure_token()
.alternative()
.build();
// Should not produce a warning due to the registries.crates-io.protocol = 'sparse' configuration
let p = project()
.file("src/lib.rs", "")
.file(
".cargo/config.toml",
"[registries.crates-io]
protocol = 'sparse'",
)
.build();
p.cargo("publish --registry alternative")
.with_status(101)
.with_stderr_data(str![[r#"
[UPDATING] `alternative` index
[ERROR] no token found for `alternative`, please run `cargo login --registry alternative`
or use environment variable CARGO_REGISTRIES_ALTERNATIVE_TOKEN
"#]])
.run();
}
#[cargo_test]
fn publish_to_alt_registry() {
let _reg = RegistryBuilder::new()
.http_api()
.http_index()
.alternative()
.build();
let p = project().file("src/main.rs", "fn main() {}").build();
// Now perform the actual publish
p.cargo("publish --registry alternative")
.with_stderr_data(str![[r#"
[UPDATING] `alternative` index
[WARNING] manifest has no description, license, license-file, documentation, homepage or repository.
See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
[PACKAGING] foo v0.0.1 ([ROOT]/foo)
[PACKAGED] 4 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
[VERIFYING] foo v0.0.1 ([ROOT]/foo)
[COMPILING] foo v0.0.1 ([ROOT]/foo/target/package/foo-0.0.1)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
[UPLOADING] foo v0.0.1 ([ROOT]/foo)
[UPLOADED] foo v0.0.1 to registry `alternative`
[NOTE] waiting for `foo v0.0.1` to be available at registry `alternative`.
You may press ctrl-c to skip waiting; the crate should be available shortly.
[PUBLISHED] foo v0.0.1 at registry `alternative`
"#]])
.run();
validate_alt_upload(
r#"{
"authors": [],
"badges": {},
"categories": [],
"deps": [],
"description": null,
"documentation": null,
"features": {},
"homepage": null,
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"name": "foo",
"readme": null,
"readme_file": null,
"repository": null,
"homepage": null,
"documentation": null,
"rust_version": null,
"vers": "0.0.1"
}"#,
"foo-0.0.1.crate",
&["Cargo.lock", "Cargo.toml", "Cargo.toml.orig", "src/main.rs"],
);
}
#[cargo_test]
fn publish_with_crates_io_dep() {
// crates.io registry.
let _dummy_reg = registry::init();
// Alternative registry.
let _alt_reg = RegistryBuilder::new()
.http_api()
.http_index()
.alternative()
.build();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
authors = ["me"]
edition = "2015"
license = "MIT"
description = "foo"
[dependencies.bar]
version = "0.0.1"
"#,
)
.file("src/main.rs", "fn main() {}")
.build();
Package::new("bar", "0.0.1").publish();
p.cargo("publish --registry alternative")
.with_stderr_data(str![[r#"
[UPDATING] `alternative` index
[WARNING] manifest has no documentation, homepage or repository.
See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
[PACKAGING] foo v0.0.1 ([ROOT]/foo)
[UPDATING] `dummy-registry` index
[PACKAGED] 4 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
[VERIFYING] foo v0.0.1 ([ROOT]/foo)
[DOWNLOADING] crates ...
[DOWNLOADED] bar v0.0.1 (registry `dummy-registry`)
[COMPILING] bar v0.0.1
[COMPILING] foo v0.0.1 ([ROOT]/foo/target/package/foo-0.0.1)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
[UPLOADING] foo v0.0.1 ([ROOT]/foo)
[UPLOADED] foo v0.0.1 to registry `alternative`
[NOTE] waiting for `foo v0.0.1` to be available at registry `alternative`.
You may press ctrl-c to skip waiting; the crate should be available shortly.
[PUBLISHED] foo v0.0.1 at registry `alternative`
"#]])
.run();
validate_alt_upload(
r#"{
"authors": ["me"],
"badges": {},
"categories": [],
"deps": [
{
"default_features": true,
"features": [],
"kind": "normal",
"name": "bar",
"optional": false,
"registry": "https://github.com/rust-lang/crates.io-index",
"target": null,
"version_req": "^0.0.1"
}
],
"description": "foo",
"documentation": null,
"features": {},
"homepage": null,
"keywords": [],
"license": "MIT",
"license_file": null,
"links": null,
"name": "foo",
"readme": null,
"readme_file": null,
"repository": null,
"homepage": null,
"documentation": null,
"rust_version": null,
"vers": "0.0.1"
}"#,
"foo-0.0.1.crate",
&["Cargo.lock", "Cargo.toml", "Cargo.toml.orig", "src/main.rs"],
);
}
#[cargo_test]
fn passwords_in_registries_index_url_forbidden() {
registry::alt_init();
let config = paths::home().join(".cargo/config.toml");
fs::write(
config,
r#"
[registries.alternative]
index = "ssh://git:secret@foobar.com"
"#,
)
.unwrap();
let p = project().file("src/main.rs", "fn main() {}").build();
p.cargo("publish --registry alternative")
.with_status(101)
.with_stderr_data(str![[r#"
[ERROR] invalid index URL for registry `alternative` defined in [ROOT]/home/.cargo/config.toml
Caused by:
registry URLs may not contain passwords
"#]])
.run();
}
#[cargo_test]
fn patch_alt_reg() {
registry::alt_init();
Package::new("bar", "0.1.0").publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
edition = "2015"
[dependencies]
bar = { version = "0.1.0", registry = "alternative" }
[patch.alternative]
bar = { path = "bar" }
"#,
)
.file(
"src/lib.rs",
"
extern crate bar;
pub fn f() { bar::bar(); }
",
)
.file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("bar/src/lib.rs", "pub fn bar() {}")
.build();
p.cargo("check")
.with_stderr_data(str![[r#"
[UPDATING] `alternative` index
[LOCKING] 2 packages to latest compatible versions
[CHECKING] bar v0.1.0 ([ROOT]/foo/bar)
[CHECKING] foo v0.0.1 ([ROOT]/foo)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
"#]])
.run();
}
#[cargo_test]
fn bad_registry_name() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
edition = "2015"
[dependencies.bar]
version = "0.0.1"
registry = "bad name"
"#,
)
.file("src/main.rs", "fn main() {}")
.build();
p.cargo("build")
.with_status(101)
.with_stderr_data(str![[r#"
[ERROR] invalid character ` ` in registry name: `bad name`, characters must be Unicode XID characters (numbers, `-`, `_`, or most letters)
--> Cargo.toml:8:17
|
8 | [dependencies.bar]
| _________________^
9 | | version = "0.0.1"
10 | | registry = "bad name"
| |_____________________________________^
|
"#]])
.run();
for cmd in &[
"init",
"install foo",
"login",
"owner",
"publish",
"search",
"yank --version 0.0.1",
] {
p.cargo(cmd)
.arg("--registry")
.arg("bad name")
.with_status(101)
.with_stderr_data(str![[r#"
[ERROR] invalid character ` ` in registry name: `bad name`, characters must be Unicode XID characters (numbers, `-`, `_`, or most letters)
"#]])
.run();
}
}
#[cargo_test]
fn no_api() {
let _registry = RegistryBuilder::new().alternative().no_api().build();
Package::new("bar", "0.0.1").alternative(true).publish();
// First check that a dependency works.
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
edition = "2015"
[dependencies.bar]
version = "0.0.1"
registry = "alternative"
"#,
)
.file("src/lib.rs", "")
.build();
p.cargo("check")
.with_stderr_data(str![[r#"
[UPDATING] `alternative` index
[LOCKING] 2 packages to latest compatible versions
[DOWNLOADING] crates ...
[DOWNLOADED] bar v0.0.1 (registry `alternative`)
[CHECKING] bar v0.0.1 (registry `alternative`)
[CHECKING] foo v0.0.1 ([ROOT]/foo)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
"#]])
.run();
p.cargo("login --registry alternative TOKEN")
.with_status(101)
.with_stderr_data(str![[r#"
[ERROR] registry `alternative` does not support API commands
"#]])
.run();
p.cargo("publish --registry alternative")
.with_status(101)
.with_stderr_data(str![[r#"
[UPDATING] `alternative` index
[ERROR] registry `alternative` does not support API commands
"#]])
.run();
p.cargo("search --registry alternative")
.with_status(101)
.with_stderr_data(str![[r#"
[ERROR] registry `alternative` does not support API commands
"#]])
.run();
p.cargo("owner --registry alternative --list")
.with_status(101)
.with_stderr_data(str![[r#"
[UPDATING] `alternative` index
[ERROR] registry `alternative` does not support API commands
"#]])
.run();
p.cargo("yank --registry alternative --version=0.0.1 bar")
.with_status(101)
.with_stderr_data(str![[r#"
[UPDATING] `alternative` index
[ERROR] registry `alternative` does not support API commands
"#]])
.run();
p.cargo("yank --registry alternative --version=0.0.1 bar")
.with_status(101)
.with_stderr_data(str![[r#"
[UPDATING] `alternative` index
[ERROR] registry `alternative` does not support API commands
"#]])
.run();
}
#[cargo_test]
fn alt_reg_metadata() {
// Check for "registry" entries in `cargo metadata` with alternative registries.
registry::alt_init();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
edition = "2015"
[dependencies]
altdep = { version = "0.0.1", registry = "alternative" }
iodep = { version = "0.0.1" }
"#,
)
.file("src/lib.rs", "")
.build();
Package::new("bar", "0.0.1").publish();
Package::new("altdep", "0.0.1")
.dep("bar", "0.0.1")
.alternative(true)
.publish();
Package::new("altdep2", "0.0.1").alternative(true).publish();
Package::new("iodep", "0.0.1")
.registry_dep("altdep2", "0.0.1")
.publish();
// The important thing to check here is the "registry" value in `deps`.
// They should be:
// foo -> altdep: alternative-registry
// foo -> iodep: null (because it is in crates.io)
// altdep -> bar: null (because it is in crates.io)
// iodep -> altdep2: alternative-registry
p.cargo("metadata --format-version=1 --no-deps")
.with_stdout_data(
str![[r#"
{
"metadata": null,
"packages": [
{
"authors": [],
"categories": [],
"default_run": null,
"dependencies": [
{
"features": [],
"kind": null,
"name": "altdep",
"optional": false,
"registry": "[ROOTURL]/alternative-registry",
"rename": null,
"req": "^0.0.1",
"source": "registry+[ROOTURL]/alternative-registry",
"target": null,
"uses_default_features": true
},
{
"features": [],
"kind": null,
"name": "iodep",
"optional": false,
"registry": null,
"rename": null,
"req": "^0.0.1",
"source": "registry+https://github.com/rust-lang/crates.io-index",
"target": null,
"uses_default_features": true
}
],
"description": null,
"documentation": null,
"edition": "2015",
"features": {},
"homepage": null,
"id": "path+[ROOTURL]/foo#0.0.1",
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"manifest_path": "[ROOT]/foo/Cargo.toml",
"metadata": null,
"name": "foo",
"publish": null,
"readme": null,
"repository": null,
"rust_version": null,
"source": null,
"targets": [
{
"crate_types": [
"lib"
],
"doc": true,
"doctest": true,
"edition": "2015",
"kind": [
"lib"
],
"name": "foo",
"src_path": "[ROOT]/foo/src/lib.rs",
"test": true
}
],
"version": "0.0.1"
}
],
"resolve": null,
"target_directory": "[ROOT]/foo/target",
"version": 1,
"workspace_default_members": [
"path+[ROOTURL]/foo#0.0.1"
],
"workspace_members": [
"path+[ROOTURL]/foo#0.0.1"
],
"workspace_root": "[ROOT]/foo"
}
"#]]
.json(),
)
.run();
// --no-deps uses a different code path, make sure both work.
p.cargo("metadata --format-version=1")
.with_stdout_data(
str![[r#"
{
"metadata": null,
"packages": [
{
"authors": [],
"categories": [],
"default_run": null,
"dependencies": [
{
"features": [],
"kind": null,
"name": "bar",
"optional": false,
"registry": null,
"rename": null,
"req": "^0.0.1",
"source": "registry+https://github.com/rust-lang/crates.io-index",
"target": null,
"uses_default_features": true
}
],
"description": null,
"documentation": null,
"edition": "2015",
"features": {},
"homepage": null,
"id": "registry+[ROOTURL]/alternative-registry#altdep@0.0.1",
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"manifest_path": "[ROOT]/home/.cargo/registry/src/-[HASH]/altdep-0.0.1/Cargo.toml",
"metadata": null,
"name": "altdep",
"publish": null,
"readme": null,
"repository": null,
"rust_version": null,
"source": "registry+[ROOTURL]/alternative-registry",
"targets": [
{
"crate_types": [
"lib"
],
"doc": true,
"doctest": true,
"edition": "2015",
"kind": [
"lib"
],
"name": "altdep",
"src_path": "[ROOT]/home/.cargo/registry/src/-[HASH]/altdep-0.0.1/src/lib.rs",
"test": true
}
],
"version": "0.0.1"
},
{
"authors": [],
"categories": [],
"default_run": null,
"dependencies": [],
"description": null,
"documentation": null,
"edition": "2015",
"features": {},
"homepage": null,
"id": "registry+[ROOTURL]/alternative-registry#altdep2@0.0.1",
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"manifest_path": "[ROOT]/home/.cargo/registry/src/-[HASH]/altdep2-0.0.1/Cargo.toml",
"metadata": null,
"name": "altdep2",
"publish": null,
"readme": null,
"repository": null,
"rust_version": null,
"source": "registry+[ROOTURL]/alternative-registry",
"targets": [
{
"crate_types": [
"lib"
],
"doc": true,
"doctest": true,
"edition": "2015",
"kind": [
"lib"
],
"name": "altdep2",
"src_path": "[ROOT]/home/.cargo/registry/src/-[HASH]/altdep2-0.0.1/src/lib.rs",
"test": true
}
],
"version": "0.0.1"
},
{
"authors": [],
"categories": [],
"default_run": null,
"dependencies": [],
"description": null,
"documentation": null,
"edition": "2015",
"features": {},
"homepage": null,
"id": "registry+https://github.com/rust-lang/crates.io-index#bar@0.0.1",
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"manifest_path": "[ROOT]/home/.cargo/registry/src/-[HASH]/bar-0.0.1/Cargo.toml",
"metadata": null,
"name": "bar",
"publish": null,
"readme": null,
"repository": null,
"rust_version": null,
"source": "registry+https://github.com/rust-lang/crates.io-index",
"targets": [
{
"crate_types": [
"lib"
],
"doc": true,
"doctest": true,
"edition": "2015",
"kind": [
"lib"
],
"name": "bar",
"src_path": "[ROOT]/home/.cargo/registry/src/-[HASH]/bar-0.0.1/src/lib.rs",
"test": true
}
],
"version": "0.0.1"
},
{
"authors": [],
"categories": [],
"default_run": null,
"dependencies": [
{
"features": [],
"kind": null,
"name": "altdep",
"optional": false,
"registry": "[ROOTURL]/alternative-registry",
"rename": null,
"req": "^0.0.1",
"source": "registry+[ROOTURL]/alternative-registry",
"target": null,
"uses_default_features": true
},
{
"features": [],
"kind": null,
"name": "iodep",
"optional": false,
"registry": null,
"rename": null,
"req": "^0.0.1",
"source": "registry+https://github.com/rust-lang/crates.io-index",
"target": null,
"uses_default_features": true
}
],
"description": null,
"documentation": null,
"edition": "2015",
"features": {},
"homepage": null,
"id": "path+[ROOTURL]/foo#0.0.1",
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"manifest_path": "[ROOT]/foo/Cargo.toml",
"metadata": null,
"name": "foo",
"publish": null,
"readme": null,
"repository": null,
"rust_version": null,
"source": null,
"targets": [
{
"crate_types": [
"lib"
],
"doc": true,
"doctest": true,
"edition": "2015",
"kind": [
"lib"
],
"name": "foo",
"src_path": "[ROOT]/foo/src/lib.rs",
"test": true
}
],
"version": "0.0.1"
},
{
"authors": [],
"categories": [],
"default_run": null,
"dependencies": [
{
"features": [],
"kind": null,
"name": "altdep2",
"optional": false,
"registry": "[ROOTURL]/alternative-registry",
"rename": null,
"req": "^0.0.1",
"source": "registry+[ROOTURL]/alternative-registry",
"target": null,
"uses_default_features": true
}
],
"description": null,
"documentation": null,
"edition": "2015",
"features": {},
"homepage": null,
"id": "registry+https://github.com/rust-lang/crates.io-index#iodep@0.0.1",
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"manifest_path": "[ROOT]/home/.cargo/registry/src/-[HASH]/iodep-0.0.1/Cargo.toml",
"metadata": null,
"name": "iodep",
"publish": null,
"readme": null,
"repository": null,
"rust_version": null,
"source": "registry+https://github.com/rust-lang/crates.io-index",
"targets": [
{
"crate_types": [
"lib"
],
"doc": true,
"doctest": true,
"edition": "2015",
"kind": [
"lib"
],
"name": "iodep",
"src_path": "[ROOT]/home/.cargo/registry/src/-[HASH]/iodep-0.0.1/src/lib.rs",
"test": true
}
],
"version": "0.0.1"
}
],
"resolve": {
"nodes": [
{
"dependencies": [
"registry+https://github.com/rust-lang/crates.io-index#bar@0.0.1"
],
"deps": [
{
"dep_kinds": [
{
"kind": null,
"target": null
}
],
"name": "bar",
"pkg": "registry+https://github.com/rust-lang/crates.io-index#bar@0.0.1"
}
],
"features": [],
"id": "registry+[ROOTURL]/alternative-registry#altdep@0.0.1"
},
{
"dependencies": [],
"deps": [],
"features": [],
"id": "registry+[ROOTURL]/alternative-registry#altdep2@0.0.1"
},
{
"dependencies": [],
"deps": [],
"features": [],
"id": "registry+https://github.com/rust-lang/crates.io-index#bar@0.0.1"
},
{
"dependencies": [
"registry+[ROOTURL]/alternative-registry#altdep@0.0.1",
"registry+https://github.com/rust-lang/crates.io-index#iodep@0.0.1"
],
"deps": [
{
"dep_kinds": [
{
"kind": null,
"target": null
}
],
"name": "altdep",
"pkg": "registry+[ROOTURL]/alternative-registry#altdep@0.0.1"
},
{
"dep_kinds": [
{
"kind": null,
"target": null
}
],
"name": "iodep",
"pkg": "registry+https://github.com/rust-lang/crates.io-index#iodep@0.0.1"
}
],
"features": [],
"id": "path+[ROOTURL]/foo#0.0.1"
},
{
"dependencies": [
"registry+[ROOTURL]/alternative-registry#altdep2@0.0.1"
],
"deps": [
{
"dep_kinds": [
{
"kind": null,
"target": null
}
],
"name": "altdep2",
"pkg": "registry+[ROOTURL]/alternative-registry#altdep2@0.0.1"
}
],
"features": [],
"id": "registry+https://github.com/rust-lang/crates.io-index#iodep@0.0.1"
}
],
"root": "path+[ROOTURL]/foo#0.0.1"
},
"target_directory": "[ROOT]/foo/target",
"version": 1,
"workspace_default_members": [
"path+[ROOTURL]/foo#0.0.1"
],
"workspace_members": [
"path+[ROOTURL]/foo#0.0.1"
],
"workspace_root": "[ROOT]/foo"
}
"#]]
.json(),
)
.run();
}
#[cargo_test]
fn unknown_registry() {
// A known registry refers to an unknown registry.
// foo -> bar(crates.io) -> baz(alt)
registry::alt_init();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
edition = "2015"
[dependencies.bar]
version = "0.0.1"
"#,
)
.file("src/main.rs", "fn main() {}")
.build();
Package::new("baz", "0.0.1").alternative(true).publish();
Package::new("bar", "0.0.1")
.registry_dep("baz", "0.0.1")
.publish();
// Remove "alternative" from config.
let cfg_path = paths::home().join(".cargo/config.toml");
let mut config = fs::read_to_string(&cfg_path).unwrap();
let start = config.find("[registries.alternative]").unwrap();
config.insert(start, '#');
let start_index = &config[start..].find("index =").unwrap();
config.insert(start + start_index, '#');
fs::write(&cfg_path, config).unwrap();
p.cargo("check").run();
// Important parts:
// foo -> bar registry = null
// bar -> baz registry = alternate
p.cargo("metadata --format-version=1")
.with_stdout_data(
str![[r#"
{
"metadata": null,
"packages": [
{
"authors": [],
"categories": [],
"default_run": null,
"dependencies": [
{
"features": [],
"kind": null,
"name": "baz",
"optional": false,
"registry": "[ROOTURL]/alternative-registry",
"rename": null,
"req": "^0.0.1",
"source": "registry+[ROOTURL]/alternative-registry",
"target": null,
"uses_default_features": true
}
],
"description": null,
"documentation": null,
"edition": "2015",
"features": {},
"homepage": null,
"id": "registry+https://github.com/rust-lang/crates.io-index#bar@0.0.1",
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"manifest_path": "[ROOT]/home/.cargo/registry/src/-[HASH]/bar-0.0.1/Cargo.toml",
"metadata": null,
"name": "bar",
"publish": null,
"readme": null,
"repository": null,
"rust_version": null,
"source": "registry+https://github.com/rust-lang/crates.io-index",
"targets": [
{
"crate_types": [
"lib"
],
"doc": true,
"doctest": true,
"edition": "2015",
"kind": [
"lib"
],
"name": "bar",
"src_path": "[ROOT]/home/.cargo/registry/src/-[HASH]/bar-0.0.1/src/lib.rs",
"test": true
}
],
"version": "0.0.1"
},
{
"authors": [],
"categories": [],
"default_run": null,
"dependencies": [],
"description": null,
"documentation": null,
"edition": "2015",
"features": {},
"homepage": null,
"id": "registry+[ROOTURL]/alternative-registry#baz@0.0.1",
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"manifest_path": "[ROOT]/home/.cargo/registry/src/-[HASH]/baz-0.0.1/Cargo.toml",
"metadata": null,
"name": "baz",
"publish": null,
"readme": null,
"repository": null,
"rust_version": null,
"source": "registry+[ROOTURL]/alternative-registry",
"targets": [
{
"crate_types": [
"lib"
],
"doc": true,
"doctest": true,
"edition": "2015",
"kind": [
"lib"
],
"name": "baz",
"src_path": "[ROOT]/home/.cargo/registry/src/-[HASH]/baz-0.0.1/src/lib.rs",
"test": true
}
],
"version": "0.0.1"
},
{
"authors": [],
"categories": [],
"default_run": null,
"dependencies": [
{
"features": [],
"kind": null,
"name": "bar",
"optional": false,
"registry": null,
"rename": null,
"req": "^0.0.1",
"source": "registry+https://github.com/rust-lang/crates.io-index",
"target": null,
"uses_default_features": true
}
],
"description": null,
"documentation": null,
"edition": "2015",
"features": {},
"homepage": null,
"id": "path+[ROOTURL]/foo#0.0.1",
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"manifest_path": "[ROOT]/foo/Cargo.toml",
"metadata": null,
"name": "foo",
"publish": null,
"readme": null,
"repository": null,
"rust_version": null,
"source": null,
"targets": [
{
"crate_types": [
"bin"
],
"doc": true,
"doctest": false,
"edition": "2015",
"kind": [
"bin"
],
"name": "foo",
"src_path": "[ROOT]/foo/src/main.rs",
"test": true
}
],
"version": "0.0.1"
}
],
"resolve": {
"nodes": [
{
"dependencies": [
"registry+[ROOTURL]/alternative-registry#baz@0.0.1"
],
"deps": [
{
"dep_kinds": [
{
"kind": null,
"target": null
}
],
"name": "baz",
"pkg": "registry+[ROOTURL]/alternative-registry#baz@0.0.1"
}
],
"features": [],
"id": "registry+https://github.com/rust-lang/crates.io-index#bar@0.0.1"
},
{
"dependencies": [],
"deps": [],
"features": [],
"id": "registry+[ROOTURL]/alternative-registry#baz@0.0.1"
},
{
"dependencies": [
"registry+https://github.com/rust-lang/crates.io-index#bar@0.0.1"
],
"deps": [
{
"dep_kinds": [
{
"kind": null,
"target": null
}
],
"name": "bar",
"pkg": "registry+https://github.com/rust-lang/crates.io-index#bar@0.0.1"
}
],
"features": [],
"id": "path+[ROOTURL]/foo#0.0.1"
}
],
"root": "path+[ROOTURL]/foo#0.0.1"
},
"target_directory": "[ROOT]/foo/target",
"version": 1,
"workspace_default_members": [
"path+[ROOTURL]/foo#0.0.1"
],
"workspace_members": [
"path+[ROOTURL]/foo#0.0.1"
],
"workspace_root": "[ROOT]/foo"
}
"#]]
.json(),
)
.run();
}
#[cargo_test]
fn registries_index_relative_url() {
registry::alt_init();
let config = paths::root().join(".cargo/config.toml");
fs::create_dir_all(config.parent().unwrap()).unwrap();
fs::write(
&config,
r#"
[registries.relative]
index = "file:alternative-registry"
"#,
)
.unwrap();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
edition = "2015"
[dependencies.bar]
version = "0.0.1"
registry = "relative"
"#,
)
.file("src/main.rs", "fn main() {}")
.build();
Package::new("bar", "0.0.1").alternative(true).publish();
p.cargo("check")
.with_stderr_data(str![[r#"
[UPDATING] `relative` index
[LOCKING] 2 packages to latest compatible versions
[DOWNLOADING] crates ...
[DOWNLOADED] bar v0.0.1 (registry `relative`)
[CHECKING] bar v0.0.1 (registry `relative`)
[CHECKING] foo v0.0.1 ([ROOT]/foo)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
"#]])
.run();
}
#[cargo_test]
fn registries_index_relative_path_not_allowed() {
registry::alt_init();
let config = paths::root().join(".cargo/config.toml");
fs::create_dir_all(config.parent().unwrap()).unwrap();
fs::write(
&config,
r#"
[registries.relative]
index = "alternative-registry"
"#,
)
.unwrap();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
edition = "2015"
[dependencies.bar]
version = "0.0.1"
registry = "relative"
"#,
)
.file("src/main.rs", "fn main() {}")
.build();
Package::new("bar", "0.0.1").alternative(true).publish();
p.cargo("check")
.with_stderr_data(str![[r#"
[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml`
Caused by:
invalid index URL for registry `relative` defined in [ROOT]/.cargo/config.toml
Caused by:
invalid url `alternative-registry`: relative URL without a base
"#]])
.with_status(101)
.run();
}
#[cargo_test]
fn both_index_and_registry() {
let p = project().file("src/lib.rs", "").build();
for cmd in &["publish", "owner", "search", "yank --version 1.0.0"] {
p.cargo(cmd)
.arg("--registry=foo")
.arg("--index=foo")
.with_status(1)
.with_stderr_data(str![[r#"
[ERROR] the argument '--registry <REGISTRY>' cannot be used with '--index <INDEX>'
Usage: [..]
For more information, try '--help'.
"#]])
.run();
}
}
#[cargo_test]
fn both_index_and_default() {
let p = project().file("src/lib.rs", "").build();
for cmd in &[
"publish",
"owner",
"search",
"yank --version 1.0.0",
"install foo",
] {
p.cargo(cmd)
.env("CARGO_REGISTRY_DEFAULT", "undefined")
.arg(format!("--index=index_url"))
.with_status(101)
.with_stderr_data(str![[r#"
[ERROR] invalid url `index_url`: relative URL without a base
"#]])
.run();
}
}
#[cargo_test]
fn sparse_lockfile() {
let _registry = registry::RegistryBuilder::new()
.http_index()
.alternative()
.build();
Package::new("foo", "0.1.0").alternative(true).publish();
let p = project()
.file(
"Cargo.toml",
r#"
[project]
name = "a"
version = "0.5.0"
authors = []
edition = "2015"
[dependencies]
foo = { registry = 'alternative', version = '0.1.0'}
"#,
)
.file("src/lib.rs", "")
.build();
p.cargo("generate-lockfile").run();
assert_e2e().eq(
&p.read_lockfile(),
str![[r##"
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "a"
version = "0.5.0"
dependencies = [
"foo",
]
[[package]]
name = "foo"
version = "0.1.0"
source = "sparse+http://127.0.0.1:[..]/index/"
checksum = "458c1addb23fde7dfbca0410afdbcc0086f96197281ec304d9e0e10def3cb899"
"##]],
);
}
#[cargo_test]
fn publish_with_transitive_dep() {
let _alt1 = RegistryBuilder::new()
.http_api()
.http_index()
.alternative_named("Alt-1")
.build();
let _alt2 = RegistryBuilder::new()
.http_api()
.http_index()
.alternative_named("Alt-2")
.build();
let p1 = project()
.file(
"Cargo.toml",
r#"
[package]
name = "a"
version = "0.5.0"
edition = "2015"
"#,
)
.file("src/lib.rs", "")
.build();
p1.cargo("publish --registry Alt-1").run();
let p2 = project()
.file(
"Cargo.toml",
r#"
[package]
name = "b"
version = "0.6.0"
publish = ["Alt-2"]
edition = "2015"
[dependencies]
a = { version = "0.5.0", registry = "Alt-1" }
"#,
)
.file("src/lib.rs", "")
.build();
p2.cargo("publish").run();
}
#[cargo_test]
fn warn_for_unused_fields() {
let _ = RegistryBuilder::new()
.no_configure_token()
.alternative()
.build();
let p = project()
.file("src/lib.rs", "")
.file(
".cargo/config.toml",
"[registry]
unexpected-field = 'foo'
[registries.alternative]
unexpected-field = 'foo'
",
)
.build();
p.cargo("publish --registry alternative")
.with_status(101)
.with_stderr_data(str![[r#"
[UPDATING] `alternative` index
[WARNING] unused config key `registries.alternative.unexpected-field` in `[ROOT]/foo/.cargo/config.toml`
[ERROR] no token found for `alternative`, please run `cargo login --registry alternative`
or use environment variable CARGO_REGISTRIES_ALTERNATIVE_TOKEN
"#]])
.run();
let crates_io = registry::RegistryBuilder::new()
.no_configure_token()
.build();
p.cargo("publish --registry crates-io")
.replace_crates_io(crates_io.index_url())
.with_status(101)
.with_stderr_data(str![[r#"
[UPDATING] crates.io index
[WARNING] unused config key `registry.unexpected-field` in `[ROOT]/foo/.cargo/config.toml`
[ERROR] no token found, please run `cargo login`
or use environment variable CARGO_REGISTRY_TOKEN
"#]])
.run();
}
#[cargo_test]
fn config_empty_registry_name() {
let _ = RegistryBuilder::new()
.no_configure_token()
.alternative()
.build();
let p = project()
.file("src/lib.rs", "")
.file(
".cargo/config.toml",
"[registry.'']
",
)
.build();
p.cargo("publish")
.arg("--registry")
.arg("")
.with_status(101)
.with_stderr_data(str![[r#"
[ERROR] registry name cannot be empty
"#]])
.run();
}
#[cargo_test]
fn empty_registry_flag() {
let p = project().file("src/lib.rs", "").build();
p.cargo("publish")
.arg("--registry")
.arg("")
.with_status(101)
.with_stderr_data(str![[r#"
[ERROR] registry name cannot be empty
"#]])
.run();
}
#[cargo_test]
fn empty_dependency_registry() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
edition = "2015"
[dependencies]
bar = { version = "0.1.0", registry = "" }
"#,
)
.file(
"src/lib.rs",
"
extern crate bar;
pub fn f() { bar::bar(); }
",
)
.build();
p.cargo("check")
.with_status(101)
.with_stderr_data(str![[r#"
[ERROR] registry name cannot be empty
--> Cargo.toml:8:23
|
8 | bar = { version = "0.1.0", registry = "" }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
"#]])
.run();
}