Add test for publish with [patch] + cleanup.

This commit is contained in:
Eric Huss 2019-01-11 15:56:46 -08:00
parent ea47200b47
commit b5144c7f83
10 changed files with 179 additions and 163 deletions

View file

@ -467,6 +467,8 @@ fn block_publish_due_to_no_token() {
// Setup the registry by publishing a package
Package::new("bar", "0.0.1").alternative(true).publish();
fs::remove_file(paths::home().join(".cargo/credentials")).unwrap();
// Now perform the actual publish
p.cargo("publish --registry alternative -Zunstable-options")
.masquerade_as_nightly_cargo()

View file

@ -1,4 +1,4 @@
use crate::support::{project, publish};
use crate::support::{project, registry};
#[test]
fn feature_required() {
@ -295,7 +295,7 @@ fn z_flags_rejected() {
#[test]
fn publish_allowed() {
publish::setup();
registry::init();
let p = project()
.file(
@ -312,7 +312,7 @@ fn publish_allowed() {
.file("src/lib.rs", "")
.build();
p.cargo("publish --index")
.arg(publish::registry().to_string())
.arg(registry::registry_url().to_string())
.masquerade_as_nightly_cargo()
.run();
}

View file

@ -1,6 +1,6 @@
use std::fs::File;
use crate::support::{cross_compile, project, publish};
use crate::support::{cross_compile, project, publish, registry};
#[test]
fn simple_cross_package() {
@ -64,7 +64,7 @@ fn publish_with_target() {
return;
}
publish::setup();
registry::init();
let p = project()
.file(
@ -96,7 +96,7 @@ fn publish_with_target() {
let target = cross_compile::alternate();
p.cargo("publish --index")
.arg(publish::registry().to_string())
.arg(registry::registry_url().to_string())
.arg("--target")
.arg(&target)
.with_stderr(&format!(
@ -107,7 +107,7 @@ fn publish_with_target() {
Finished dev [unoptimized + debuginfo] target(s) in [..]
Uploading foo v0.0.0 ([CWD])
",
registry = publish::registry_path().to_str().unwrap()
registry = registry::registry_path().to_str().unwrap()
))
.run();
}

View file

@ -3,7 +3,7 @@ use std::io::prelude::*;
use crate::support::cargo_process;
use crate::support::install::cargo_home;
use crate::support::registry::{self, registry};
use crate::support::registry::{self, registry_url};
use cargo::core::Shell;
use cargo::util::config::Config;
use toml;
@ -62,7 +62,7 @@ fn login_with_old_credentials() {
registry::init();
cargo_process("login --host")
.arg(registry().to_string())
.arg(registry_url().to_string())
.arg(TOKEN)
.run();
@ -76,7 +76,7 @@ fn login_with_new_credentials() {
setup_new_credentials();
cargo_process("login --host")
.arg(registry().to_string())
.arg(registry_url().to_string())
.arg(TOKEN)
.run();
@ -94,7 +94,7 @@ fn login_with_old_and_new_credentials() {
fn login_without_credentials() {
registry::init();
cargo_process("login --host")
.arg(registry().to_string())
.arg(registry_url().to_string())
.arg(TOKEN)
.run();
@ -108,7 +108,7 @@ fn new_credentials_is_used_instead_old() {
setup_new_credentials();
cargo_process("login --host")
.arg(registry().to_string())
.arg(registry_url().to_string())
.arg(TOKEN)
.run();

View file

@ -839,7 +839,7 @@ registry-index = "{}"
[dependencies.ghi]
version = "1.0"
"#,
registry::alt_registry()
registry::alt_registry_url()
);
validate_crate_contents(

View file

@ -3,6 +3,7 @@ use std::io::prelude::*;
use crate::support::git::repo;
use crate::support::paths;
use crate::support::registry::{self, registry_path, registry_url, Package};
use crate::support::{basic_manifest, project, publish};
const CLEAN_FOO_JSON: &str = r#"
@ -70,7 +71,7 @@ fn validate_upload_foo_clean() {
#[test]
fn simple() {
publish::setup();
registry::init();
let p = project()
.file(
@ -88,7 +89,7 @@ fn simple() {
.build();
p.cargo("publish --no-verify --index")
.arg(publish::registry().to_string())
.arg(registry_url().to_string())
.with_stderr(&format!(
"\
[UPDATING] `{reg}` index
@ -97,7 +98,7 @@ See [..]
[PACKAGING] foo v0.0.1 ([CWD])
[UPLOADING] foo v0.0.1 ([CWD])
",
reg = publish::registry_path().to_str().unwrap()
reg = registry::registry_path().to_str().unwrap()
))
.run();
@ -106,16 +107,9 @@ See [..]
#[test]
fn old_token_location() {
publish::setup();
// publish::setup puts a token in this file.
fs::remove_file(paths::root().join(".cargo/config")).unwrap();
let credentials = paths::root().join("home/.cargo/credentials");
File::create(credentials)
.unwrap()
.write_all(br#"token = "api-token""#)
.unwrap();
// Check that the `token` key works at the root instead of under a
// `[registry]` table.
registry::init();
let p = project()
.file(
@ -132,8 +126,23 @@ fn old_token_location() {
.file("src/main.rs", "fn main() {}")
.build();
let credentials = paths::home().join(".cargo/credentials");
fs::remove_file(&credentials).unwrap();
// Verify can't publish without a token.
p.cargo("publish --no-verify --index")
.arg(publish::registry().to_string())
.arg(registry_url().to_string())
.with_status(101)
.with_stderr_contains("[ERROR] no upload token found, please run `cargo login`")
.run();
File::create(&credentials)
.unwrap()
.write_all(br#"token = "api-token""#)
.unwrap();
p.cargo("publish --no-verify --index")
.arg(registry_url().to_string())
.with_stderr(&format!(
"\
[UPDATING] `{reg}` index
@ -142,7 +151,7 @@ See [..]
[PACKAGING] foo v0.0.1 ([CWD])
[UPLOADING] foo v0.0.1 ([CWD])
",
reg = publish::registry_path().to_str().unwrap()
reg = registry_path().to_str().unwrap()
))
.run();
@ -153,7 +162,7 @@ See [..]
// remove once it has been decided --host can be removed
#[test]
fn simple_with_host() {
publish::setup();
registry::init();
let p = project()
.file(
@ -171,7 +180,7 @@ fn simple_with_host() {
.build();
p.cargo("publish --no-verify --host")
.arg(publish::registry().to_string())
.arg(registry_url().to_string())
.with_stderr(&format!(
"\
[WARNING] The flag '--host' is no longer valid.
@ -189,7 +198,7 @@ See [..]
[PACKAGING] foo v0.0.1 ([CWD])
[UPLOADING] foo v0.0.1 ([CWD])
",
reg = publish::registry_path().to_str().unwrap()
reg = registry_path().to_str().unwrap()
))
.run();
@ -200,7 +209,7 @@ See [..]
// remove once it has been decided --host can be removed
#[test]
fn simple_with_index_and_host() {
publish::setup();
registry::init();
let p = project()
.file(
@ -218,9 +227,9 @@ fn simple_with_index_and_host() {
.build();
p.cargo("publish --no-verify --index")
.arg(publish::registry().to_string())
.arg(registry_url().to_string())
.arg("--host")
.arg(publish::registry().to_string())
.arg(registry_url().to_string())
.with_stderr(&format!(
"\
[WARNING] The flag '--host' is no longer valid.
@ -238,7 +247,7 @@ See [..]
[PACKAGING] foo v0.0.1 ([CWD])
[UPLOADING] foo v0.0.1 ([CWD])
",
reg = publish::registry_path().to_str().unwrap()
reg = registry_path().to_str().unwrap()
))
.run();
@ -247,7 +256,7 @@ See [..]
#[test]
fn git_deps() {
publish::setup();
registry::init();
let p = project()
.file(
@ -268,7 +277,7 @@ fn git_deps() {
.build();
p.cargo("publish -v --no-verify --index")
.arg(publish::registry().to_string())
.arg(registry_url().to_string())
.with_status(101)
.with_stderr(
"\
@ -285,7 +294,7 @@ repository and specify it with a path and version\n\
#[test]
fn path_dependency_no_version() {
publish::setup();
registry::init();
let p = project()
.file(
@ -308,7 +317,7 @@ fn path_dependency_no_version() {
.build();
p.cargo("publish --index")
.arg(publish::registry().to_string())
.arg(registry_url().to_string())
.with_status(101)
.with_stderr(
"\
@ -322,7 +331,7 @@ dependency `bar` does not specify a version
#[test]
fn unpublishable_crate() {
publish::setup();
registry::init();
let p = project()
.file(
@ -341,7 +350,7 @@ fn unpublishable_crate() {
.build();
p.cargo("publish --index")
.arg(publish::registry().to_string())
.arg(registry_url().to_string())
.with_status(101)
.with_stderr(
"\
@ -354,7 +363,7 @@ fn unpublishable_crate() {
#[test]
fn dont_publish_dirty() {
publish::setup();
registry::init();
let p = project().file("bar", "").build();
let _ = repo(&paths::root().join("foo"))
@ -376,7 +385,7 @@ fn dont_publish_dirty() {
.build();
p.cargo("publish --index")
.arg(publish::registry().to_string())
.arg(registry_url().to_string())
.with_status(101)
.with_stderr(
"\
@ -394,7 +403,7 @@ to proceed despite this, pass the `--allow-dirty` flag
#[test]
fn publish_clean() {
publish::setup();
registry::init();
let p = project().build();
@ -417,7 +426,7 @@ fn publish_clean() {
.build();
p.cargo("publish --index")
.arg(publish::registry().to_string())
.arg(registry_url().to_string())
.run();
validate_upload_foo_clean();
@ -425,7 +434,7 @@ fn publish_clean() {
#[test]
fn publish_in_sub_repo() {
publish::setup();
registry::init();
let p = project().no_manifest().file("baz", "").build();
@ -450,7 +459,7 @@ fn publish_in_sub_repo() {
p.cargo("publish")
.cwd(p.root().join("bar"))
.arg("--index")
.arg(publish::registry().to_string())
.arg(registry_url().to_string())
.run();
validate_upload_foo_clean();
@ -458,7 +467,7 @@ fn publish_in_sub_repo() {
#[test]
fn publish_when_ignored() {
publish::setup();
registry::init();
let p = project().file("baz", "").build();
@ -482,7 +491,7 @@ fn publish_when_ignored() {
.build();
p.cargo("publish --index")
.arg(publish::registry().to_string())
.arg(registry_url().to_string())
.run();
publish::validate_upload(
@ -500,7 +509,7 @@ fn publish_when_ignored() {
#[test]
fn ignore_when_crate_ignored() {
publish::setup();
registry::init();
let p = project().no_manifest().file("bar/baz", "").build();
@ -524,7 +533,7 @@ fn ignore_when_crate_ignored() {
p.cargo("publish")
.cwd(p.root().join("bar"))
.arg("--index")
.arg(publish::registry().to_string())
.arg(registry_url().to_string())
.run();
publish::validate_upload(
@ -536,7 +545,7 @@ fn ignore_when_crate_ignored() {
#[test]
fn new_crate_rejected() {
publish::setup();
registry::init();
let p = project().file("baz", "").build();
@ -557,7 +566,7 @@ fn new_crate_rejected() {
)
.nocommit_file("src/main.rs", "fn main() {}");
p.cargo("publish --index")
.arg(publish::registry().to_string())
.arg(registry_url().to_string())
.with_status(101)
.with_stderr_contains(
"[ERROR] 3 files in the working directory contain \
@ -568,7 +577,7 @@ fn new_crate_rejected() {
#[test]
fn dry_run() {
publish::setup();
registry::init();
let p = project()
.file(
@ -586,7 +595,7 @@ fn dry_run() {
.build();
p.cargo("publish --dry-run --index")
.arg(publish::registry().to_string())
.arg(registry_url().to_string())
.with_stderr(
"\
[UPDATING] `[..]` index
@ -603,12 +612,13 @@ See [..]
.run();
// Ensure the API request wasn't actually made
assert!(!publish::upload_path().join("api/v1/crates/new").exists());
assert!(registry::api_path().join("api/v1/crates").exists());
assert!(!registry::api_path().join("api/v1/crates/new").exists());
}
#[test]
fn block_publish_feature_not_enabled() {
publish::setup();
registry::init();
let p = project()
.file(
@ -649,7 +659,7 @@ consider adding `cargo-features = [\"alternative-registries\"]` to the manifest
#[test]
fn registry_not_in_publish_list() {
publish::setup();
registry::init();
let p = project()
.file(
@ -688,7 +698,7 @@ fn registry_not_in_publish_list() {
#[test]
fn publish_empty_list() {
publish::setup();
registry::init();
let p = project()
.file(
@ -722,7 +732,7 @@ fn publish_empty_list() {
#[test]
fn publish_allowed_registry() {
publish::setup();
registry::init();
let p = project().build();
@ -751,12 +761,21 @@ fn publish_allowed_registry() {
.masquerade_as_nightly_cargo()
.run();
validate_upload_foo_clean();
publish::validate_alt_upload(
CLEAN_FOO_JSON,
"foo-0.0.1.crate",
&[
"Cargo.toml",
"Cargo.toml.orig",
"src/main.rs",
".cargo_vcs_info.json",
],
);
}
#[test]
fn block_publish_no_registry() {
publish::setup();
registry::init();
let p = project()
.file(
@ -790,7 +809,7 @@ fn block_publish_no_registry() {
#[test]
fn publish_with_select_features() {
publish::setup();
registry::init();
let p = project()
.file(
@ -817,14 +836,14 @@ fn publish_with_select_features() {
.build();
p.cargo("publish --features required --index")
.arg(publish::registry().to_string())
.arg(registry_url().to_string())
.with_stderr_contains("[UPLOADING] foo v0.0.1 ([CWD])")
.run();
}
#[test]
fn publish_with_all_features() {
publish::setup();
registry::init();
let p = project()
.file(
@ -851,14 +870,14 @@ fn publish_with_all_features() {
.build();
p.cargo("publish --all-features --index")
.arg(publish::registry().to_string())
.arg(registry_url().to_string())
.with_stderr_contains("[UPLOADING] foo v0.0.1 ([CWD])")
.run();
}
#[test]
fn publish_with_no_default_features() {
publish::setup();
registry::init();
let p = project()
.file(
@ -885,8 +904,43 @@ fn publish_with_no_default_features() {
.build();
p.cargo("publish --no-default-features --index")
.arg(publish::registry().to_string())
.arg(registry_url().to_string())
.with_stderr_contains("error: This crate requires `required` feature!")
.with_status(101)
.run();
}
#[test]
fn publish_with_patch() {
Package::new("bar", "1.0.0").publish();
let p = project()
.file(
"Cargo.toml",
r#"
[project]
name = "foo"
version = "0.0.1"
authors = []
license = "MIT"
description = "foo"
[dependencies]
bar = "1.0"
[patch.crates-io]
bar = { path = "bar" }
"#,
)
.file("src/main.rs", "extern crate bar; fn main() {}")
.file("bar/Cargo.toml", &basic_manifest("bar", "1.0.0"))
.file("bar/src/lib.rs", "")
.build();
// Check that it works with the patched crate.
p.cargo("build").run();
p.cargo("publish --index")
.arg(registry_url().to_string())
.with_status(101)
.with_stderr_contains("[ERROR] published crates cannot contain [patch] sections")
.run();
}

View file

@ -1,21 +1,12 @@
use std::fs::{self, File};
use std::io::prelude::*;
use std::path::PathBuf;
use crate::support::cargo_process;
use crate::support::git;
use crate::support::paths::{self, CargoPathExt};
use crate::support::registry::{self, Dependency, Package};
use crate::support::registry::{self, registry_path, registry_url, Dependency, Package};
use crate::support::{basic_manifest, project};
use cargo::util::paths::remove_dir_all;
use url::Url;
fn registry_path() -> PathBuf {
paths::root().join("registry")
}
fn registry() -> Url {
Url::from_file_path(&*registry_path()).ok().unwrap()
}
#[test]
fn simple() {
@ -47,7 +38,7 @@ fn simple() {
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
",
reg = registry::registry_path().to_str().unwrap()
reg = registry_path().to_str().unwrap()
))
.run();
@ -98,7 +89,7 @@ fn deps() {
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
",
reg = registry::registry_path().to_str().unwrap()
reg = registry_path().to_str().unwrap()
))
.run();
}
@ -336,7 +327,7 @@ required by package `foo v0.0.1 ([..])`
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
",
reg = registry::registry_path().to_str().unwrap()
reg = registry_path().to_str().unwrap()
))
.run();
}
@ -581,7 +572,7 @@ fn yanks_in_lockfiles_are_ok() {
p.cargo("build").run();
registry::registry_path().join("3").rm_rf();
registry_path().join("3").rm_rf();
Package::new("bar", "0.0.1").yanked(true).publish();
@ -806,10 +797,12 @@ fn login_with_no_cargo_dir() {
fn login_with_differently_sized_token() {
// Verify that the configuration file gets properly truncated.
registry::init();
let credentials = paths::home().join(".cargo/credentials");
fs::remove_file(&credentials).unwrap();
cargo_process("login lmaolmaolmao -v").run();
cargo_process("login lmao -v").run();
cargo_process("login lmaolmaolmao -v").run();
let credentials = fs::read_to_string(paths::home().join(".cargo/credentials")).unwrap();
let credentials = fs::read_to_string(&credentials).unwrap();
assert_eq!(credentials, "[registry]\ntoken = \"lmaolmaolmao\"\n");
}
@ -832,7 +825,7 @@ fn bad_license_file() {
.file("src/main.rs", "fn main() {}")
.build();
p.cargo("publish -v --index")
.arg(registry().to_string())
.arg(registry_url().to_string())
.with_status(101)
.with_stderr_contains("[ERROR] the license file `foo` does not exist")
.run();

View file

@ -5,7 +5,7 @@ use std::path::Path;
use crate::support::cargo_process;
use crate::support::git::repo;
use crate::support::paths;
use crate::support::registry::{api_path, registry as registry_url, registry_path};
use crate::support::registry::{api_path, registry_path, registry_url};
use url::Url;
fn api() -> Url {

View file

@ -1,75 +1,18 @@
use std::collections::{HashMap, HashSet};
use std::fs::{self, File};
use std::fs::File;
use std::io::{prelude::*, SeekFrom};
use std::path::{Path, PathBuf};
use crate::support::git::{repo, Repository};
use crate::support::registry::alt_api_path;
use crate::support::{find_json_mismatch, paths};
use crate::support::registry::{self, alt_api_path};
use crate::support::find_json_mismatch;
use byteorder::{LittleEndian, ReadBytesExt};
use flate2::read::GzDecoder;
use tar::Archive;
use url::Url;
pub fn setup() -> Repository {
let config = paths::root().join(".cargo/config");
t!(fs::create_dir_all(config.parent().unwrap()));
t!(t!(File::create(&config)).write_all(
format!(
r#"
[registry]
token = "api-token"
[registries.alternative]
index = "{registry}"
"#,
registry = registry().to_string()
)
.as_bytes()
));
let credentials = paths::root().join("home/.cargo/credentials");
t!(fs::create_dir_all(credentials.parent().unwrap()));
t!(t!(File::create(&credentials)).write_all(
br#"
[registries.alternative]
token = "api-token"
"#
));
t!(fs::create_dir_all(&upload_path().join("api/v1/crates")));
repo(&registry_path())
.file(
"config.json",
&format!(
r#"{{
"dl": "{0}",
"api": "{0}"
}}"#,
upload()
),
)
.build()
}
pub fn registry_path() -> PathBuf {
paths::root().join("registry")
}
pub fn registry() -> Url {
Url::from_file_path(&*registry_path()).ok().unwrap()
}
pub fn upload_path() -> PathBuf {
paths::root().join("upload")
}
fn upload() -> Url {
Url::from_file_path(&*upload_path()).ok().unwrap()
}
/// Check the result of a crate publish.
pub fn validate_upload(expected_json: &str, expected_crate_name: &str, expected_files: &[&str]) {
let new_path = upload_path().join("api/v1/crates/new");
let new_path = registry::api_path().join("api/v1/crates/new");
_validate_upload(
&new_path,
expected_json,

View file

@ -15,39 +15,54 @@ use url::Url;
use crate::support::git::repo;
use crate::support::paths;
/// Path to the local index pretending to be crates.io. This is a git repo
/// initialized with a `config.json` file pointing to `dl_path` for downloads
/// and `api_path` for uploads.
pub fn registry_path() -> PathBuf {
paths::root().join("registry")
}
pub fn registry() -> Url {
Url::from_file_path(&*registry_path()).ok().unwrap()
pub fn registry_url() -> Url {
Url::from_file_path(registry_path()).ok().unwrap()
}
/// Path for local web API uploads. Cargo will place the contents of a web API
/// request here, for example `api/v1/crates/new` is the result of publishing
/// a crate.
pub fn api_path() -> PathBuf {
paths::root().join("api")
}
pub fn api_url() -> Url {
Url::from_file_path(api_path()).ok().unwrap()
}
/// Path where crates can be downloaded using the web API endpoint. Crates
/// should be organized as `{name}/{version}/download` to match the web API
/// endpoint. This is rarely used and must be manually set up.
pub fn dl_path() -> PathBuf {
paths::root().join("dl")
}
pub fn dl_url() -> Url {
Url::from_file_path(&*dl_path()).ok().unwrap()
Url::from_file_path(dl_path()).ok().unwrap()
}
/// Alternative-registry version of `registry_path`.
pub fn alt_registry_path() -> PathBuf {
paths::root().join("alternative-registry")
}
pub fn alt_registry() -> Url {
Url::from_file_path(&*alt_registry_path()).ok().unwrap()
pub fn alt_registry_url() -> Url {
Url::from_file_path(alt_registry_path()).ok().unwrap()
}
/// Alternative-registry version of `dl_path`.
pub fn alt_dl_path() -> PathBuf {
paths::root().join("alt_dl")
}
pub fn alt_dl_url() -> String {
let base = Url::from_file_path(&*alt_dl_path()).ok().unwrap();
let base = Url::from_file_path(alt_dl_path()).ok().unwrap();
format!("{}/{{crate}}/{{version}}/{{crate}}-{{version}}.crate", base)
}
/// Alternative-registry version of `api_path`.
pub fn alt_api_path() -> PathBuf {
paths::root().join("alt_api")
}
pub fn alt_api_url() -> Url {
Url::from_file_path(&*alt_api_path()).ok().unwrap()
Url::from_file_path(alt_api_path()).ok().unwrap()
}
/// A builder for creating a new package in a registry.
@ -145,9 +160,6 @@ pub fn init() {
t!(t!(File::create(&config)).write_all(
format!(
r#"
[registry]
token = "api-token"
[source.crates-io]
registry = 'https://wut'
replace-with = 'dummy-registry'
@ -158,11 +170,22 @@ pub fn init() {
[registries.alternative]
index = '{alt}'
"#,
reg = registry(),
alt = alt_registry()
reg = registry_url(),
alt = alt_registry_url()
)
.as_bytes()
));
let credentials = paths::home().join(".cargo/credentials");
t!(t!(File::create(&credentials)).write_all(
br#"
[registry]
token = "api-token"
[registries.alternative]
token = "api-token"
"#
));
// Init a new registry
let _ = repo(&registry_path())
@ -170,13 +193,14 @@ pub fn init() {
"config.json",
&format!(
r#"
{{"dl":"{0}","api":"{0}"}}
{{"dl":"{}","api":"{}"}}
"#,
dl_url()
dl_url(),
api_url()
),
)
.build();
fs::create_dir_all(dl_path().join("api/v1/crates")).unwrap();
fs::create_dir_all(api_path().join("api/v1/crates")).unwrap();
// Init an alt registry
repo(&alt_registry_path())
@ -338,7 +362,7 @@ impl Package {
let registry_url =
match (self.alternative, dep.registry.as_ref().map(|s| s.as_ref())) {
(false, None) => None,
(false, Some("alternative")) => Some(alt_registry().to_string()),
(false, Some("alternative")) => Some(alt_registry_url().to_string()),
(true, None) => Some(CRATES_IO_INDEX.to_string()),
(true, Some("alternative")) => None,
_ => panic!("registry_dep currently only supports `alternative`"),
@ -455,7 +479,7 @@ impl Package {
));
if let Some(registry) = &dep.registry {
assert_eq!(registry, "alternative");
manifest.push_str(&format!("registry-index = \"{}\"", alt_registry()));
manifest.push_str(&format!("registry-index = \"{}\"", alt_registry_url()));
}
}