Adding tests for --target with cargo publish and cargo package
authorNisarg Thakkar <nisthakkar@paypal.com>
Sun, 27 Aug 2017 06:49:17 +0000 (12:19 +0530)
committerNisarg Thakkar <nisthakkar@paypal.com>
Tue, 29 Aug 2017 14:47:55 +0000 (20:17 +0530)
src/bin/publish.rs
tests/cargotest/support/cross_compile.rs [new file with mode: 0644]
tests/cargotest/support/mod.rs
tests/cargotest/support/publish.rs [new file with mode: 0644]
tests/cross-compile.rs
tests/cross-publish.rs [new file with mode: 0644]
tests/publish.rs

index 3299aacf1c6483ae251f2bf323386b1908439918..0ce5d897fdb4d0251b148786b535f62f09fa681f 100644 (file)
@@ -66,6 +66,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult {
         flag_allow_dirty: allow_dirty,
         flag_jobs: jobs,
         flag_dry_run: dry_run,
+        flag_target: target,
         ..
     } = options;
 
@@ -96,7 +97,7 @@ about this warning.";
             else { config.shell().warn(&msg)?; host },  // TODO: Deprecated, remove
         verify: !no_verify,
         allow_dirty: allow_dirty,
-        target: options.flag_target.as_ref().map(|t| &t[..]),
+        target: target.as_ref().map(|t| &t[..]),
         jobs: jobs,
         dry_run: dry_run,
     })?;
diff --git a/tests/cargotest/support/cross_compile.rs b/tests/cargotest/support/cross_compile.rs
new file mode 100644 (file)
index 0000000..95d6ea3
--- /dev/null
@@ -0,0 +1,130 @@
+use std::env;
+use std::process::Command;
+use std::sync::{Once, ONCE_INIT};
+use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
+
+use support::{project, main_file, basic_bin_manifest};
+
+pub fn disabled() -> bool {
+    // First, disable if ./configure requested so
+    match env::var("CFG_DISABLE_CROSS_TESTS") {
+        Ok(ref s) if *s == "1" => return true,
+        _ => {}
+    }
+
+    // Right now the windows bots cannot cross compile due to the mingw setup,
+    // so we disable ourselves on all but macos/linux setups where the rustc
+    // install script ensures we have both architectures
+    if !(cfg!(target_os = "macos") ||
+         cfg!(target_os = "linux") ||
+         cfg!(target_env = "msvc")) {
+        return true;
+    }
+
+    // It's not particularly common to have a cross-compilation setup, so
+    // try to detect that before we fail a bunch of tests through no fault
+    // of the user.
+    static CAN_RUN_CROSS_TESTS: AtomicBool = ATOMIC_BOOL_INIT;
+    static CHECK: Once = ONCE_INIT;
+
+    let cross_target = alternate();
+
+    CHECK.call_once(|| {
+        let p = project("cross_test")
+            .file("Cargo.toml", &basic_bin_manifest("cross_test"))
+            .file("src/cross_test.rs", &main_file(r#""testing!""#, &[]));
+
+        let result = p.cargo_process("build")
+            .arg("--target").arg(&cross_target)
+            .exec_with_output();
+
+        if result.is_ok() {
+            CAN_RUN_CROSS_TESTS.store(true, Ordering::SeqCst);
+        }
+    });
+
+    if CAN_RUN_CROSS_TESTS.load(Ordering::SeqCst) {
+        // We were able to compile a simple project, so the user has the
+        // necessary std:: bits installed.  Therefore, tests should not
+        // be disabled.
+        return false;
+    }
+
+    // We can't compile a simple cross project.  We want to warn the user
+    // by failing a single test and having the remainder of the cross tests
+    // pass.  We don't use std::sync::Once here because panicing inside its
+    // call_once method would poison the Once instance, which is not what
+    // we want.
+    static HAVE_WARNED: AtomicBool = ATOMIC_BOOL_INIT;
+
+    if HAVE_WARNED.swap(true, Ordering::SeqCst) {
+        // We are some other test and somebody else is handling the warning.
+        // Just disable the current test.
+        return true;
+    }
+
+    // We are responsible for warning the user, which we do by panicing.
+    let rustup_available = Command::new("rustup").output().is_ok();
+
+    let linux_help = if cfg!(target_os = "linux") {
+        "
+
+You may need to install runtime libraries for your Linux distribution as well.".to_string()
+    } else {
+        "".to_string()
+    };
+
+    let rustup_help = if rustup_available {
+        format!("
+
+Alternatively, you can install the necessary libraries for cross-compilation with
+
+    rustup target add {}{}", cross_target, linux_help)
+    } else {
+        "".to_string()
+    };
+
+    panic!("Cannot cross compile to {}.
+
+This failure can be safely ignored. If you would prefer to not see this
+failure, you can set the environment variable CFG_DISABLE_CROSS_TESTS to \"1\".{}
+", cross_target, rustup_help);
+}
+
+pub fn alternate() -> String {
+    let platform = match env::consts::OS {
+        "linux" => "unknown-linux-gnu",
+        "macos" => "apple-darwin",
+        "windows" => "pc-windows-msvc",
+        _ => unreachable!(),
+    };
+    let arch = match env::consts::ARCH {
+        "x86" => "x86_64",
+        "x86_64" => "i686",
+        _ => unreachable!(),
+    };
+    format!("{}-{}", arch, platform)
+}
+
+pub fn alternate_arch() -> &'static str {
+    match env::consts::ARCH {
+        "x86" => "x86_64",
+        "x86_64" => "x86",
+        _ => unreachable!(),
+    }
+}
+
+pub fn host() -> String {
+    let platform = match env::consts::OS {
+        "linux" => "unknown-linux-gnu",
+        "macos" => "apple-darwin",
+        "windows" => "pc-windows-msvc",
+        _ => unreachable!(),
+    };
+    let arch = match env::consts::ARCH {
+        "x86" => "i686",
+        "x86_64" => "x86_64",
+        _ => unreachable!(),
+    };
+    format!("{}-{}", arch, platform)
+}
\ No newline at end of file
index e7376b1160453512d66b9c63fed3c2d45ae005dc..b3b16b1f85245544f898835a28b762613ede942f 100644 (file)
@@ -30,6 +30,8 @@ macro_rules! t {
 pub mod paths;
 pub mod git;
 pub mod registry;
+pub mod cross_compile;
+pub mod publish;
 
 /*
  *
diff --git a/tests/cargotest/support/publish.rs b/tests/cargotest/support/publish.rs
new file mode 100644 (file)
index 0000000..2d6ca66
--- /dev/null
@@ -0,0 +1,32 @@
+extern crate url;
+
+use std::path::PathBuf;
+use std::io::prelude::*;
+use std::fs::{self, File};
+
+use support::paths;
+use support::git::repo;
+
+use url::Url;
+
+pub fn setup() {
+    let config = paths::root().join(".cargo/config");
+    t!(fs::create_dir_all(config.parent().unwrap()));
+    t!(t!(File::create(&config)).write_all(br#"
+        [registry]
+            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();
+}
+
+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() }
\ No newline at end of file
index 3225c6cabbef39404f47cdc26ba47287b52617b2..84d528492cb0a4fc0d157bc2b1c82e905b4c9f18 100644 (file)
@@ -2,143 +2,14 @@ extern crate cargo;
 extern crate cargotest;
 extern crate hamcrest;
 
-use std::env;
-use std::process::Command;
-use std::sync::{Once, ONCE_INIT};
-use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
-
 use cargo::util::process;
 use cargotest::{is_nightly, rustc_host};
-use cargotest::support::{project, execs, main_file, basic_bin_manifest};
+use cargotest::support::{project, execs, basic_bin_manifest, cross_compile};
 use hamcrest::{assert_that, existing_file};
 
-fn disabled() -> bool {
-    // First, disable if ./configure requested so
-    match env::var("CFG_DISABLE_CROSS_TESTS") {
-        Ok(ref s) if *s == "1" => return true,
-        _ => {}
-    }
-
-    // Right now the windows bots cannot cross compile due to the mingw setup,
-    // so we disable ourselves on all but macos/linux setups where the rustc
-    // install script ensures we have both architectures
-    if !(cfg!(target_os = "macos") ||
-         cfg!(target_os = "linux") ||
-         cfg!(target_env = "msvc")) {
-        return true;
-    }
-
-    // It's not particularly common to have a cross-compilation setup, so
-    // try to detect that before we fail a bunch of tests through no fault
-    // of the user.
-    static CAN_RUN_CROSS_TESTS: AtomicBool = ATOMIC_BOOL_INIT;
-    static CHECK: Once = ONCE_INIT;
-
-    let cross_target = alternate();
-
-    CHECK.call_once(|| {
-        let p = project("cross_test")
-            .file("Cargo.toml", &basic_bin_manifest("cross_test"))
-            .file("src/cross_test.rs", &main_file(r#""testing!""#, &[]));
-
-        let result = p.cargo_process("build")
-            .arg("--target").arg(&cross_target)
-            .exec_with_output();
-
-        if result.is_ok() {
-            CAN_RUN_CROSS_TESTS.store(true, Ordering::SeqCst);
-        }
-    });
-
-    if CAN_RUN_CROSS_TESTS.load(Ordering::SeqCst) {
-        // We were able to compile a simple project, so the user has the
-        // necessary std:: bits installed.  Therefore, tests should not
-        // be disabled.
-        return false;
-    }
-
-    // We can't compile a simple cross project.  We want to warn the user
-    // by failing a single test and having the remainder of the cross tests
-    // pass.  We don't use std::sync::Once here because panicing inside its
-    // call_once method would poison the Once instance, which is not what
-    // we want.
-    static HAVE_WARNED: AtomicBool = ATOMIC_BOOL_INIT;
-
-    if HAVE_WARNED.swap(true, Ordering::SeqCst) {
-        // We are some other test and somebody else is handling the warning.
-        // Just disable the current test.
-        return true;
-    }
-
-    // We are responsible for warning the user, which we do by panicing.
-    let rustup_available = Command::new("rustup").output().is_ok();
-
-    let linux_help = if cfg!(target_os = "linux") {
-        "
-
-You may need to install runtime libraries for your Linux distribution as well.".to_string()
-    } else {
-        "".to_string()
-    };
-
-    let rustup_help = if rustup_available {
-        format!("
-
-Alternatively, you can install the necessary libraries for cross-compilation with
-
-    rustup target add {}{}", cross_target, linux_help)
-    } else {
-        "".to_string()
-    };
-
-    panic!("Cannot cross compile to {}.
-
-This failure can be safely ignored. If you would prefer to not see this
-failure, you can set the environment variable CFG_DISABLE_CROSS_TESTS to \"1\".{}
-", cross_target, rustup_help);
-}
-
-fn alternate() -> String {
-    let platform = match env::consts::OS {
-        "linux" => "unknown-linux-gnu",
-        "macos" => "apple-darwin",
-        "windows" => "pc-windows-msvc",
-        _ => unreachable!(),
-    };
-    let arch = match env::consts::ARCH {
-        "x86" => "x86_64",
-        "x86_64" => "i686",
-        _ => unreachable!(),
-    };
-    format!("{}-{}", arch, platform)
-}
-
-fn alternate_arch() -> &'static str {
-    match env::consts::ARCH {
-        "x86" => "x86_64",
-        "x86_64" => "x86",
-        _ => unreachable!(),
-    }
-}
-
-fn host() -> String {
-    let platform = match env::consts::OS {
-        "linux" => "unknown-linux-gnu",
-        "macos" => "apple-darwin",
-        "windows" => "pc-windows-msvc",
-        _ => unreachable!(),
-    };
-    let arch = match env::consts::ARCH {
-        "x86" => "i686",
-        "x86_64" => "x86_64",
-        _ => unreachable!(),
-    };
-    format!("{}-{}", arch, platform)
-}
-
 #[test]
 fn simple_cross() {
-    if disabled() { return }
+    if cross_compile::disabled() { return }
 
     let p = project("foo")
         .file("Cargo.toml", r#"
@@ -152,15 +23,15 @@ fn simple_cross() {
             fn main() {{
                 assert_eq!(std::env::var("TARGET").unwrap(), "{}");
             }}
-        "#, alternate()))
+        "#, cross_compile::alternate()))
         .file("src/main.rs", &format!(r#"
             use std::env;
             fn main() {{
                 assert_eq!(env::consts::ARCH, "{}");
             }}
-        "#, alternate_arch()));
+        "#, cross_compile::alternate_arch()));
 
-    let target = alternate();
+    let target = cross_compile::alternate();
     assert_that(p.cargo_process("build").arg("--target").arg(&target).arg("-v"),
                 execs().with_status(0));
     assert_that(&p.target_bin(&target, "foo"), existing_file());
@@ -171,13 +42,13 @@ fn simple_cross() {
 
 #[test]
 fn simple_cross_config() {
-    if disabled() { return }
+    if cross_compile::disabled() { return }
 
     let p = project("foo")
         .file(".cargo/config", &format!(r#"
             [build]
             target = "{}"
-        "#, alternate()))
+        "#, cross_compile::alternate()))
         .file("Cargo.toml", r#"
             [package]
             name = "foo"
@@ -189,15 +60,15 @@ fn simple_cross_config() {
             fn main() {{
                 assert_eq!(std::env::var("TARGET").unwrap(), "{}");
             }}
-        "#, alternate()))
+        "#, cross_compile::alternate()))
         .file("src/main.rs", &format!(r#"
             use std::env;
             fn main() {{
                 assert_eq!(env::consts::ARCH, "{}");
             }}
-        "#, alternate_arch()));
+        "#, cross_compile::alternate_arch()));
 
-    let target = alternate();
+    let target = cross_compile::alternate();
     assert_that(p.cargo_process("build").arg("-v"),
                 execs().with_status(0));
     assert_that(&p.target_bin(&target, "foo"), existing_file());
@@ -208,7 +79,7 @@ fn simple_cross_config() {
 
 #[test]
 fn simple_deps() {
-    if disabled() { return }
+    if cross_compile::disabled() { return }
 
     let p = project("foo")
         .file("Cargo.toml", r#"
@@ -234,7 +105,7 @@ fn simple_deps() {
         .file("src/lib.rs", "pub fn bar() {}");
     p2.build();
 
-    let target = alternate();
+    let target = cross_compile::alternate();
     assert_that(p.cargo_process("build").arg("--target").arg(&target),
                 execs().with_status(0));
     assert_that(&p.target_bin(&target, "foo"), existing_file());
@@ -245,7 +116,7 @@ fn simple_deps() {
 
 #[test]
 fn plugin_deps() {
-    if disabled() { return }
+    if cross_compile::disabled() { return }
     if !is_nightly() { return }
 
     let foo = project("foo")
@@ -312,7 +183,7 @@ fn plugin_deps() {
     bar.build();
     baz.build();
 
-    let target = alternate();
+    let target = cross_compile::alternate();
     assert_that(foo.cargo_process("build").arg("--target").arg(&target),
                 execs().with_status(0));
     assert_that(&foo.target_bin(&target, "foo"), existing_file());
@@ -323,7 +194,7 @@ fn plugin_deps() {
 
 #[test]
 fn plugin_to_the_max() {
-    if disabled() { return }
+    if cross_compile::disabled() { return }
     if !is_nightly() { return }
 
     let foo = project("foo")
@@ -394,7 +265,7 @@ fn plugin_to_the_max() {
     bar.build();
     baz.build();
 
-    let target = alternate();
+    let target = cross_compile::alternate();
     assert_that(foo.cargo_process("build").arg("--target").arg(&target).arg("-v"),
                 execs().with_status(0));
     println!("second");
@@ -409,9 +280,9 @@ fn plugin_to_the_max() {
 
 #[test]
 fn linker_and_ar() {
-    if disabled() { return }
+    if cross_compile::disabled() { return }
 
-    let target = alternate();
+    let target = cross_compile::alternate();
     let p = project("foo")
         .file(".cargo/config", &format!(r#"
             [target.{}]
@@ -424,7 +295,7 @@ fn linker_and_ar() {
             fn main() {{
                 assert_eq!(env::consts::ARCH, "{}");
             }}
-        "#, alternate_arch()));
+        "#, cross_compile::alternate_arch()));
 
     assert_that(p.cargo_process("build").arg("--target").arg(&target)
                                               .arg("-v"),
@@ -448,7 +319,7 @@ fn linker_and_ar() {
 
 #[test]
 fn plugin_with_extra_dylib_dep() {
-    if disabled() { return }
+    if cross_compile::disabled() { return }
     if !is_nightly() { return }
 
     let foo = project("foo")
@@ -509,14 +380,14 @@ fn plugin_with_extra_dylib_dep() {
     bar.build();
     baz.build();
 
-    let target = alternate();
+    let target = cross_compile::alternate();
     assert_that(foo.cargo_process("build").arg("--target").arg(&target),
                 execs().with_status(0));
 }
 
 #[test]
 fn cross_tests() {
-    if disabled() { return }
+    if cross_compile::disabled() { return }
 
     let p = project("foo")
         .file("Cargo.toml", r#"
@@ -536,14 +407,14 @@ fn cross_tests() {
                 assert_eq!(env::consts::ARCH, "{}");
             }}
             #[test] fn test() {{ main() }}
-        "#, alternate_arch()))
+        "#, cross_compile::alternate_arch()))
         .file("src/lib.rs", &format!(r#"
             use std::env;
             pub fn foo() {{ assert_eq!(env::consts::ARCH, "{}"); }}
             #[test] fn test_foo() {{ foo() }}
-        "#, alternate_arch()));
+        "#, cross_compile::alternate_arch()));
 
-    let target = alternate();
+    let target = cross_compile::alternate();
     assert_that(p.cargo_process("test").arg("--target").arg(&target),
                 execs().with_status(0)
                        .with_stderr(&format!("\
@@ -557,7 +428,7 @@ fn cross_tests() {
 
 #[test]
 fn no_cross_doctests() {
-    if disabled() { return }
+    if cross_compile::disabled() { return }
 
     let p = project("foo")
         .file("Cargo.toml", r#"
@@ -587,7 +458,7 @@ fn no_cross_doctests() {
                        .with_stderr(&host_output));
 
     println!("b");
-    let target = host();
+    let target = cross_compile::host();
     assert_that(p.cargo("test").arg("--target").arg(&target),
                 execs().with_status(0)
                        .with_stderr(&format!("\
@@ -598,7 +469,7 @@ fn no_cross_doctests() {
 ", foo = p.url(), triple = target)));
 
     println!("c");
-    let target = alternate();
+    let target = cross_compile::alternate();
     assert_that(p.cargo("test").arg("--target").arg(&target),
                 execs().with_status(0)
                        .with_stderr(&format!("\
@@ -610,7 +481,7 @@ fn no_cross_doctests() {
 
 #[test]
 fn simple_cargo_run() {
-    if disabled() { return }
+    if cross_compile::disabled() { return }
 
     let p = project("foo")
         .file("Cargo.toml", r#"
@@ -624,18 +495,18 @@ fn simple_cargo_run() {
             fn main() {{
                 assert_eq!(env::consts::ARCH, "{}");
             }}
-        "#, alternate_arch()));
+        "#, cross_compile::alternate_arch()));
 
-    let target = alternate();
+    let target = cross_compile::alternate();
     assert_that(p.cargo_process("run").arg("--target").arg(&target),
                 execs().with_status(0));
 }
 
 #[test]
 fn cross_with_a_build_script() {
-    if disabled() { return }
+    if cross_compile::disabled() { return }
 
-    let target = alternate();
+    let target = cross_compile::alternate();
     let p = project("foo")
         .file("Cargo.toml", r#"
             [package]
@@ -680,9 +551,9 @@ fn cross_with_a_build_script() {
 
 #[test]
 fn build_script_needed_for_host_and_target() {
-    if disabled() { return }
+    if cross_compile::disabled() { return }
 
-    let target = alternate();
+    let target = cross_compile::alternate();
     let host = rustc_host();
     let p = project("foo")
         .file("Cargo.toml", r#"
@@ -769,7 +640,7 @@ fn build_script_needed_for_host_and_target() {
 
 #[test]
 fn build_deps_for_the_right_arch() {
-    if disabled() { return }
+    if cross_compile::disabled() { return }
 
     let p = project("foo")
         .file("Cargo.toml", r#"
@@ -804,14 +675,14 @@ fn build_deps_for_the_right_arch() {
         .file("d2/build.rs", "extern crate d1; fn main() {}")
         .file("d2/src/lib.rs", "");
 
-    let target = alternate();
+    let target = cross_compile::alternate();
     assert_that(p.cargo_process("build").arg("--target").arg(&target).arg("-v"),
                 execs().with_status(0));
 }
 
 #[test]
 fn build_script_only_host() {
-    if disabled() { return }
+    if cross_compile::disabled() { return }
 
     let p = project("foo")
         .file("Cargo.toml", r#"
@@ -846,14 +717,14 @@ fn build_script_only_host() {
             }
         "#);
 
-    let target = alternate();
+    let target = cross_compile::alternate();
     assert_that(p.cargo_process("build").arg("--target").arg(&target).arg("-v"),
                 execs().with_status(0));
 }
 
 #[test]
 fn plugin_build_script_right_arch() {
-    if disabled() { return }
+    if cross_compile::disabled() { return }
     let p = project("foo")
         .file("Cargo.toml", r#"
             [package]
@@ -869,7 +740,7 @@ fn plugin_build_script_right_arch() {
         .file("build.rs", "fn main() {}")
         .file("src/lib.rs", "");
 
-    assert_that(p.cargo_process("build").arg("-v").arg("--target").arg(alternate()),
+    assert_that(p.cargo_process("build").arg("-v").arg("--target").arg(cross_compile::alternate()),
                 execs().with_status(0)
                        .with_stderr("\
 [COMPILING] foo v0.0.1 ([..])
@@ -882,9 +753,9 @@ fn plugin_build_script_right_arch() {
 
 #[test]
 fn build_script_with_platform_specific_dependencies() {
-    if disabled() { return }
+    if cross_compile::disabled() { return }
 
-    let target = alternate();
+    let target = cross_compile::alternate();
     let host = rustc_host();
     let p = project("foo")
         .file("Cargo.toml", r#"
@@ -941,9 +812,9 @@ fn build_script_with_platform_specific_dependencies() {
 
 #[test]
 fn platform_specific_dependencies_do_not_leak() {
-    if disabled() { return }
+    if cross_compile::disabled() { return }
 
-    let target = alternate();
+    let target = cross_compile::alternate();
     let host = rustc_host();
     let p = project("foo")
         .file("Cargo.toml", r#"
@@ -987,9 +858,9 @@ fn platform_specific_dependencies_do_not_leak() {
 
 #[test]
 fn platform_specific_variables_reflected_in_build_scripts() {
-    if disabled() { return }
+    if cross_compile::disabled() { return }
 
-    let target = alternate();
+    let target = cross_compile::alternate();
     let host = rustc_host();
     let p = project("foo")
         .file("Cargo.toml", &format!(r#"
@@ -1056,9 +927,9 @@ fn platform_specific_variables_reflected_in_build_scripts() {
 
 #[test]
 fn cross_test_dylib() {
-    if disabled() { return }
+    if cross_compile::disabled() { return }
 
-    let target = alternate();
+    let target = cross_compile::alternate();
 
     let p = project("foo")
         .file("Cargo.toml", r#"
@@ -1103,7 +974,7 @@ fn cross_test_dylib() {
              pub fn baz() {{
                 assert_eq!(env::consts::ARCH, "{}");
             }}
-        "#, alternate_arch()));
+        "#, cross_compile::alternate_arch()));
 
     assert_that(p.cargo_process("test").arg("--target").arg(&target),
                 execs().with_status(0)
@@ -1113,7 +984,7 @@ fn cross_test_dylib() {
 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
 [RUNNING] target[/]{arch}[/]debug[/]deps[/]foo-[..][EXE]
 [RUNNING] target[/]{arch}[/]debug[/]deps[/]test-[..][EXE]",
-                        dir = p.url(), arch = alternate()))
+                        dir = p.url(), arch = cross_compile::alternate()))
                        .with_stdout_contains_n("test foo ... ok", 2));
 
 }
diff --git a/tests/cross-publish.rs b/tests/cross-publish.rs
new file mode 100644 (file)
index 0000000..0070cb9
--- /dev/null
@@ -0,0 +1,100 @@
+extern crate cargo;
+extern crate cargotest;
+extern crate hamcrest;
+extern crate flate2;
+extern crate tar;
+
+use std::fs::File;
+use std::path::PathBuf;
+use std::io::prelude::*;
+
+use cargotest::support::{project, execs, cross_compile, publish};
+use hamcrest::{assert_that, contains};
+use flate2::read::GzDecoder;
+use tar::Archive;
+
+#[test]
+fn simple_cross_package() {
+    if cross_compile::disabled() { return }
+
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.0"
+            authors = []
+            license = "MIT"
+            description = "foo"
+            repository = "bar"
+        "#)
+        .file("src/main.rs", &format!(r#"
+            use std::env;
+            fn main() {{
+                assert_eq!(env::consts::ARCH, "{}");
+            }}
+        "#, cross_compile::alternate_arch()));
+
+    let target = cross_compile::alternate();
+
+    assert_that(p.cargo_process("package").arg("--target").arg(&target),
+                execs().with_status(0).with_status(0).with_stderr(&format!(
+"   Packaging foo v0.0.0 ({dir})
+   Verifying foo v0.0.0 ({dir})
+   Compiling foo v0.0.0 ({dir}/target/package/foo-0.0.0)
+    Finished dev [unoptimized + debuginfo] target(s) in [..]
+", dir = p.url())));
+
+    // Check that the tarball contains the files
+    let f = File::open(&p.root().join("target/package/foo-0.0.0.crate")).unwrap();
+    let mut rdr = GzDecoder::new(f).unwrap();
+    let mut contents = Vec::new();
+    rdr.read_to_end(&mut contents).unwrap();
+    let mut ar = Archive::new(&contents[..]);
+    let entries = ar.entries().unwrap();
+    let entry_paths = entries.map(|entry| {
+        entry.unwrap().path().unwrap().into_owned()
+    }).collect::<Vec<PathBuf>>();
+    assert_that(&entry_paths, contains(vec![PathBuf::from("foo-0.0.0/Cargo.toml")]));
+    assert_that(&entry_paths, contains(vec![PathBuf::from("foo-0.0.0/Cargo.toml.orig")]));
+    assert_that(&entry_paths, contains(vec![PathBuf::from("foo-0.0.0/src/main.rs")]));
+}
+
+#[test]
+fn publish_with_target() {
+    if cross_compile::disabled() { return }
+
+    publish::setup();
+
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.0"
+            authors = []
+            license = "MIT"
+            description = "foo"
+            repository = "bar"
+        "#)
+        .file("src/main.rs", &format!(r#"
+            use std::env;
+            fn main() {{
+                assert_eq!(env::consts::ARCH, "{}");
+            }}
+        "#, cross_compile::alternate_arch()));
+
+    p.build();
+
+    let target = cross_compile::alternate();
+
+    assert_that(p.cargo("publish")
+                 .arg("--index").arg(publish::registry().to_string())
+                 .arg("--target").arg(&target),
+                execs().with_status(0).with_stderr(&format!(
+"    Updating registry `{registry}`
+   Packaging foo v0.0.0 ({dir})
+   Verifying foo v0.0.0 ({dir})
+   Compiling foo v0.0.0 ({dir}/target/package/foo-0.0.0)
+    Finished dev [unoptimized + debuginfo] target(s) in [..]
+   Uploading foo v0.0.0 ({dir})
+", dir = p.url(), registry = publish::registry())));
+}
\ No newline at end of file
index 166b021c7bec3401e039859ad515965f708d0f38..41856dbd664b64a074a672ef55f301c090b8331a 100644 (file)
@@ -1,48 +1,22 @@
-#[macro_use]
 extern crate cargotest;
 extern crate flate2;
 extern crate hamcrest;
 extern crate tar;
-extern crate url;
 
 use std::io::prelude::*;
-use std::fs::{self, File};
+use std::fs::File;
 use std::io::SeekFrom;
-use std::path::PathBuf;
 
 use cargotest::support::git::repo;
 use cargotest::support::paths;
-use cargotest::support::{project, execs};
+use cargotest::support::{project, execs, publish};
 use flate2::read::GzDecoder;
 use hamcrest::assert_that;
 use tar::Archive;
-use url::Url;
-
-fn registry_path() -> PathBuf { paths::root().join("registry") }
-fn registry() -> Url { Url::from_file_path(&*registry_path()).ok().unwrap() }
-fn upload_path() -> PathBuf { paths::root().join("upload") }
-fn upload() -> Url { Url::from_file_path(&*upload_path()).ok().unwrap() }
-
-fn setup() {
-    let config = paths::root().join(".cargo/config");
-    t!(fs::create_dir_all(config.parent().unwrap()));
-    t!(t!(File::create(&config)).write_all(br#"
-        [registry]
-            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();
-}
 
 #[test]
 fn simple() {
-    setup();
+    publish::setup();
 
     let p = project("foo")
         .file("Cargo.toml", r#"
@@ -56,7 +30,7 @@ fn simple() {
         .file("src/main.rs", "fn main() {}");
 
     assert_that(p.cargo_process("publish").arg("--no-verify")
-                 .arg("--index").arg(registry().to_string()),
+                 .arg("--index").arg(publish::registry().to_string()),
                 execs().with_status(0).with_stderr(&format!("\
 [UPDATING] registry `{reg}`
 [WARNING] manifest has no documentation, [..]
@@ -65,9 +39,9 @@ See [..]
 [UPLOADING] foo v0.0.1 ({dir})
 ",
         dir = p.url(),
-        reg = registry())));
+        reg = publish::registry())));
 
-    let mut f = File::open(&upload_path().join("api/v1/crates/new")).unwrap();
+    let mut f = File::open(&publish::upload_path().join("api/v1/crates/new")).unwrap();
     // Skip the metadata payload and the size of the tarball
     let mut sz = [0; 4];
     assert_eq!(f.read(&mut sz).unwrap(), 4);
@@ -98,7 +72,7 @@ See [..]
 // remove once it has been decided --host can be removed
 #[test]
 fn simple_with_host() {
-    setup();
+    publish::setup();
 
     let p = project("foo")
         .file("Cargo.toml", r#"
@@ -112,7 +86,7 @@ fn simple_with_host() {
         .file("src/main.rs", "fn main() {}");
 
     assert_that(p.cargo_process("publish").arg("--no-verify")
-                 .arg("--host").arg(registry().to_string()),
+                 .arg("--host").arg(publish::registry().to_string()),
                 execs().with_status(0).with_stderr(&format!("\
 [WARNING] The flag '--host' is no longer valid.
 
@@ -131,9 +105,9 @@ See [..]
 [UPLOADING] foo v0.0.1 ({dir})
 ",
         dir = p.url(),
-        reg = registry())));
+        reg = publish::registry())));
 
-    let mut f = File::open(&upload_path().join("api/v1/crates/new")).unwrap();
+    let mut f = File::open(&publish::upload_path().join("api/v1/crates/new")).unwrap();
     // Skip the metadata payload and the size of the tarball
     let mut sz = [0; 4];
     assert_eq!(f.read(&mut sz).unwrap(), 4);
@@ -164,7 +138,7 @@ See [..]
 // remove once it has been decided --host can be removed
 #[test]
 fn simple_with_index_and_host() {
-    setup();
+    publish::setup();
 
     let p = project("foo")
         .file("Cargo.toml", r#"
@@ -178,8 +152,8 @@ fn simple_with_index_and_host() {
         .file("src/main.rs", "fn main() {}");
 
     assert_that(p.cargo_process("publish").arg("--no-verify")
-                 .arg("--index").arg(registry().to_string())
-                 .arg("--host").arg(registry().to_string()),
+                 .arg("--index").arg(publish::registry().to_string())
+                 .arg("--host").arg(publish::registry().to_string()),
                 execs().with_status(0).with_stderr(&format!("\
 [WARNING] The flag '--host' is no longer valid.
 
@@ -198,9 +172,9 @@ See [..]
 [UPLOADING] foo v0.0.1 ({dir})
 ",
         dir = p.url(),
-        reg = registry())));
+        reg = publish::registry())));
 
-    let mut f = File::open(&upload_path().join("api/v1/crates/new")).unwrap();
+    let mut f = File::open(&publish::upload_path().join("api/v1/crates/new")).unwrap();
     // Skip the metadata payload and the size of the tarball
     let mut sz = [0; 4];
     assert_eq!(f.read(&mut sz).unwrap(), 4);
@@ -229,7 +203,7 @@ See [..]
 
 #[test]
 fn git_deps() {
-    setup();
+    publish::setup();
 
     let p = project("foo")
         .file("Cargo.toml", r#"
@@ -246,7 +220,7 @@ fn git_deps() {
         .file("src/main.rs", "fn main() {}");
 
     assert_that(p.cargo_process("publish").arg("-v").arg("--no-verify")
-                 .arg("--index").arg(registry().to_string()),
+                 .arg("--index").arg(publish::registry().to_string()),
                 execs().with_status(101).with_stderr("\
 [UPDATING] registry [..]
 [ERROR] crates cannot be published to crates.io with dependencies sourced from \
@@ -259,7 +233,7 @@ repository and specify it with a path and version\n\
 
 #[test]
 fn path_dependency_no_version() {
-    setup();
+    publish::setup();
 
     let p = project("foo")
         .file("Cargo.toml", r#"
@@ -283,7 +257,7 @@ fn path_dependency_no_version() {
         .file("bar/src/lib.rs", "");
 
     assert_that(p.cargo_process("publish")
-                 .arg("--index").arg(registry().to_string()),
+                 .arg("--index").arg(publish::registry().to_string()),
                 execs().with_status(101).with_stderr("\
 [UPDATING] registry [..]
 [ERROR] all path dependencies must have a version specified when publishing.
@@ -293,7 +267,7 @@ dependency `bar` does not specify a version
 
 #[test]
 fn unpublishable_crate() {
-    setup();
+    publish::setup();
 
     let p = project("foo")
         .file("Cargo.toml", r#"
@@ -308,7 +282,7 @@ fn unpublishable_crate() {
         .file("src/main.rs", "fn main() {}");
 
     assert_that(p.cargo_process("publish")
-                 .arg("--index").arg(registry().to_string()),
+                 .arg("--index").arg(publish::registry().to_string()),
                 execs().with_status(101).with_stderr("\
 [ERROR] some crates cannot be published.
 `foo` is marked as unpublishable
@@ -317,7 +291,7 @@ fn unpublishable_crate() {
 
 #[test]
 fn dont_publish_dirty() {
-    setup();
+    publish::setup();
     let p = project("foo")
         .file("bar", "");
     p.build();
@@ -338,7 +312,7 @@ fn dont_publish_dirty() {
         .build();
 
     assert_that(p.cargo("publish")
-                 .arg("--index").arg(registry().to_string()),
+                 .arg("--index").arg(publish::registry().to_string()),
                 execs().with_status(101).with_stderr("\
 [UPDATING] registry `[..]`
 error: 1 files in the working directory contain changes that were not yet \
@@ -352,7 +326,7 @@ to proceed despite this, pass the `--allow-dirty` flag
 
 #[test]
 fn publish_clean() {
-    setup();
+    publish::setup();
 
     let p = project("foo");
     p.build();
@@ -373,13 +347,13 @@ fn publish_clean() {
         .build();
 
     assert_that(p.cargo("publish")
-                 .arg("--index").arg(registry().to_string()),
+                 .arg("--index").arg(publish::registry().to_string()),
                 execs().with_status(0));
 }
 
 #[test]
 fn publish_in_sub_repo() {
-    setup();
+    publish::setup();
 
     let p = project("foo")
         .file("baz", "");
@@ -401,13 +375,13 @@ fn publish_in_sub_repo() {
         .build();
 
     assert_that(p.cargo("publish").cwd(p.root().join("bar"))
-                 .arg("--index").arg(registry().to_string()),
+                 .arg("--index").arg(publish::registry().to_string()),
                 execs().with_status(0));
 }
 
 #[test]
 fn publish_when_ignored() {
-    setup();
+    publish::setup();
 
     let p = project("foo")
         .file("baz", "");
@@ -430,13 +404,13 @@ fn publish_when_ignored() {
         .build();
 
     assert_that(p.cargo("publish")
-                 .arg("--index").arg(registry().to_string()),
+                 .arg("--index").arg(publish::registry().to_string()),
                 execs().with_status(0));
 }
 
 #[test]
 fn ignore_when_crate_ignored() {
-    setup();
+    publish::setup();
 
     let p = project("foo")
         .file("bar/baz", "");
@@ -457,13 +431,13 @@ fn ignore_when_crate_ignored() {
         "#)
         .nocommit_file("bar/src/main.rs", "fn main() {}");
     assert_that(p.cargo("publish").cwd(p.root().join("bar"))
-                 .arg("--index").arg(registry().to_string()),
+                 .arg("--index").arg(publish::registry().to_string()),
                 execs().with_status(0));
 }
 
 #[test]
 fn new_crate_rejected() {
-    setup();
+    publish::setup();
 
     let p = project("foo")
         .file("baz", "");
@@ -483,13 +457,13 @@ fn new_crate_rejected() {
         "#)
         .nocommit_file("src/main.rs", "fn main() {}");
     assert_that(p.cargo("publish")
-                 .arg("--index").arg(registry().to_string()),
+                 .arg("--index").arg(publish::registry().to_string()),
                 execs().with_status(101));
 }
 
 #[test]
 fn dry_run() {
-    setup();
+    publish::setup();
 
     let p = project("foo")
         .file("Cargo.toml", r#"
@@ -503,7 +477,7 @@ fn dry_run() {
         .file("src/main.rs", "fn main() {}");
 
     assert_that(p.cargo_process("publish").arg("--dry-run")
-                 .arg("--index").arg(registry().to_string()),
+                 .arg("--index").arg(publish::registry().to_string()),
                 execs().with_status(0).with_stderr(&format!("\
 [UPDATING] registry `[..]`
 [WARNING] manifest has no documentation, [..]
@@ -518,5 +492,5 @@ See [..]
         dir = p.url())));
 
     // Ensure the API request wasn't actually made
-    assert!(!upload_path().join("api/v1/crates/new").exists());
+    assert!(!publish::upload_path().join("api/v1/crates/new").exists());
 }