# === Tests
-TEST_SRC = $(wildcard tests/*.rs)
+TEST_SRC = $(shell find tests -name '*.rs')
TEST_DEPS = $(DEPS) -L libs/hamcrest-rust/target
target/tests/test-integration: $(HAMCREST) $(TEST_SRC) $(BIN_TARGETS)
use cargo::{execute_main_without_stdin,CLIResult,CLIError,ToResult};
use cargo::ops;
use cargo::util::important_paths::find_project;
-use cargo::util::ToCLI;
+use cargo::util::{ToCLI,simple_human};
#[deriving(PartialEq,Clone,Decodable,Encodable)]
pub struct Options {
let sources = try!(sources_for(&package));
+ try!(sources.update().wrap("unable to update sources"));
let summaries = try!(sources.list().wrap("unable to list packages from source"));
let resolved = try!(resolve(package.get_dependencies(), &summaries).wrap("unable to resolve dependencies"));
impl Source for GitSource {
fn update(&self) -> CargoResult<()> {
+ log!(5, "updating git source `{}`", self.remote);
let repo = try!(self.remote.checkout(&self.db_path));
try!(repo.copy_to(self.reference.as_slice(), &self.checkout_path));
}
fn list(&self) -> CargoResult<Vec<Summary>> {
+ log!(5, "listing summaries in git source `{}`", self.remote);
let pkg = try!(read_manifest(&self.checkout_path, self.get_namespace()));
Ok(vec!(pkg.get_summary().clone()))
}
}
fn get(&self, package_ids: &[PackageId]) -> CargoResult<Vec<Package>> {
+ log!(5, "getting packages for package ids `{}` from `{}`", package_ids, self.remote);
// TODO: Support multiple manifests per repo
let pkg = try!(read_manifest(&self.checkout_path, self.remote.get_url()));
* GitRemote represents a remote repository. It gets cloned into a local GitDatabase.
*/
-#[deriving(PartialEq,Clone)]
+#[deriving(PartialEq,Clone,Show)]
pub struct GitRemote {
url: Url,
verbose: bool
}
fn fetch_into(&self, path: &Path) -> CargoResult<()> {
- Ok(git!(*path, self.verbose, "fetch --force --quiet --tags {} refs/heads/*:refs/heads/*", self.url))
+ Ok(git!(*path, self.verbose, "fetch --force --quiet --tags {} refs/heads/*:refs/heads/*", self.fetch_location()))
}
fn clone_into(&self, path: &Path) -> CargoResult<()> {
try!(mkdir_recursive(path, UserDir).map_err(|err|
human_error(format!("Couldn't recursively create `{}`", dirname.display()), format!("path={}", dirname.display()), io_error(err))));
- Ok(git!(dirname, self.verbose, "clone {} {} --bare --no-hardlinks --quiet", self.url, path.display()))
+ Ok(git!(dirname, self.verbose, "clone {} {} --bare --no-hardlinks --quiet", self.fetch_location(), path.display()))
+ }
+
+ fn fetch_location(&self) -> String {
+ match self.url.scheme.as_slice() {
+ "file" => self.url.path.clone(),
+ _ => self.url.to_str()
+ }
}
}
}
fn git(path: &Path, verbose: bool, str: &str) -> ProcessBuilder {
- if verbose {
- errln!("Executing git {} @ {}", str, path.display());
- }
+ debug!("Executing git {} @ {}", str, path.display());
process("git").args(str.split(' ').collect::<Vec<&str>>().as_slice()).cwd(path.clone())
}
CargoError { kind: HumanReadableError, desc: BoxedDescription(desc), detail: detail, .. } => {
CLIError::new(desc, detail, exit_code)
},
- CargoError { kind: InternalError, desc: StaticDescription(desc), detail: None, .. } => {
- CLIError::new("An unexpected error occurred", Some(desc), exit_code)
+ ref err @ CargoError { kind: InternalError, desc: StaticDescription(desc), detail: None, .. } => {
+ CLIError::new(format!("An unexpected error occurred: {}", err), Some(desc), exit_code)
},
- CargoError { kind: InternalError, desc: StaticDescription(desc), detail: Some(detail), .. } => {
- CLIError::new("An unexpected error occurred", Some(format!("{}\n{}", desc, detail)), exit_code)
+ ref err @ CargoError { kind: InternalError, desc: StaticDescription(desc), detail: Some(ref detail), .. } => {
+ CLIError::new(format!("An unexpected error occurred: {}", err), Some(format!("{}\n{}", desc, detail)), exit_code)
},
- _ => {
- CLIError::new("An unexpected error occurred", None::<&str>, exit_code)
+ ref err @ _ => {
+ CLIError::new(format!("An unexpected error occurred: {}", err), None::<&str>, exit_code)
}
}
}
+++ /dev/null
-// use std::io::fs::{mkdir_recursive,rmdir_recursive};
-use std;
-use std::io;
-use std::io::fs;
-use std::io::process::{ProcessOutput,ProcessExit};
-use std::os;
-use std::path::{Path,BytesContainer};
-use std::str;
-use std::vec::Vec;
-use std::fmt::Show;
-use ham = hamcrest;
-use cargo::core::shell;
-use cargo::util::{process,ProcessBuilder,CargoError};
-use cargo::util::result::ProcessError;
-
-static CARGO_INTEGRATION_TEST_DIR : &'static str = "cargo-integration-tests";
-
-/*
- *
- * ===== Builders =====
- *
- */
-
-#[deriving(PartialEq,Clone)]
-struct FileBuilder {
- path: Path,
- body: String
-}
-
-impl FileBuilder {
- pub fn new(path: Path, body: &str) -> FileBuilder {
- FileBuilder { path: path, body: body.to_str() }
- }
-
- fn mk(&self) -> Result<(), String> {
- try!(mkdir_recursive(&self.dirname()));
-
- let mut file = try!(
- fs::File::create(&self.path)
- .with_err_msg(format!("Could not create file; path={}", self.path.display())));
-
- file.write_str(self.body.as_slice())
- .with_err_msg(format!("Could not write to file; path={}", self.path.display()))
- }
-
- fn dirname(&self) -> Path {
- Path::new(self.path.dirname())
- }
-}
-
-#[deriving(PartialEq,Clone)]
-struct ProjectBuilder {
- name: String,
- root: Path,
- files: Vec<FileBuilder>
-}
-
-impl ProjectBuilder {
- pub fn new(name: &str, root: Path) -> ProjectBuilder {
- ProjectBuilder {
- name: name.to_str(),
- root: root,
- files: vec!()
- }
- }
-
- pub fn root(&self) -> Path {
- self.root.clone()
- }
-
- pub fn cargo_process(&self, program: &str) -> ProcessBuilder {
- self.build();
-
- process(program)
- .cwd(self.root())
- .extra_path(cargo_dir())
- }
-
- pub fn file<B: BytesContainer>(mut self, path: B, body: &str) -> ProjectBuilder {
- self.files.push(FileBuilder::new(self.root.join(path), body));
- self
- }
-
- // TODO: return something different than a ProjectBuilder
- pub fn build<'a>(&'a self) -> &'a ProjectBuilder {
- match self.build_with_result() {
- Err(e) => fail!(e),
- _ => return self
- }
- }
-
- pub fn build_with_result(&self) -> Result<(), String> {
- // First, clean the directory if it already exists
- try!(self.rm_root());
-
- // Create the empty directory
- try!(mkdir_recursive(&self.root));
-
- for file in self.files.iter() {
- try!(file.mk());
- }
-
- Ok(())
- }
-
- fn rm_root(&self) -> Result<(), String> {
- if self.root.exists() {
- rmdir_recursive(&self.root)
- }
- else {
- Ok(())
- }
- }
-}
-
-// Generates a project layout
-pub fn project(name: &str) -> ProjectBuilder {
- ProjectBuilder::new(name, os::tmpdir().join(CARGO_INTEGRATION_TEST_DIR))
-}
-
-// === Helpers ===
-
-pub fn mkdir_recursive(path: &Path) -> Result<(), String> {
- fs::mkdir_recursive(path, io::UserDir)
- .with_err_msg(format!("could not create directory; path={}", path.display()))
-}
-
-pub fn rmdir_recursive(path: &Path) -> Result<(), String> {
- fs::rmdir_recursive(path)
- .with_err_msg(format!("could not rm directory; path={}", path.display()))
-}
-
-trait ErrMsg<T> {
- fn with_err_msg(self, val: String) -> Result<T, String>;
-}
-
-impl<T, E: Show> ErrMsg<T> for Result<T, E> {
- fn with_err_msg(self, val: String) -> Result<T, String> {
- match self {
- Ok(val) => Ok(val),
- Err(err) => Err(format!("{}; original={}", val, err))
- }
- }
-}
-
-// Path to cargo executables
-pub fn cargo_dir() -> Path {
- os::getenv("CARGO_BIN_PATH")
- .map(|s| Path::new(s))
- .unwrap_or_else(|| fail!("CARGO_BIN_PATH wasn't set. Cannot continue running test"))
-}
-
-/// Returns an absolute path in the filesystem that `path` points to. The
-/// returned path does not contain any symlinks in its hierarchy.
-/*
- *
- * ===== Matchers =====
- *
- */
-
-#[deriving(Clone)]
-struct Execs {
- expect_stdout: Option<String>,
- expect_stdin: Option<String>,
- expect_stderr: Option<String>,
- expect_exit_code: Option<int>
-}
-
-impl Execs {
-
- pub fn with_stdout<S: ToStr>(mut ~self, expected: S) -> Box<Execs> {
- self.expect_stdout = Some(expected.to_str());
- self
- }
-
- pub fn with_stderr<S: ToStr>(mut ~self, expected: S) -> Box<Execs> {
- self.expect_stderr = Some(expected.to_str());
- self
- }
-
- pub fn with_status(mut ~self, expected: int) -> Box<Execs> {
- self.expect_exit_code = Some(expected);
- self
- }
-
- fn match_output(&self, actual: &ProcessOutput) -> ham::MatchResult {
- self.match_status(actual.status)
- .and(self.match_stdout(actual))
- .and(self.match_stderr(actual))
- }
-
- fn match_status(&self, actual: ProcessExit) -> ham::MatchResult {
- match self.expect_exit_code {
- None => ham::success(),
- Some(code) => {
- ham::expect(
- actual.matches_exit_status(code),
- format!("exited with {}", actual))
- }
- }
- }
-
- fn match_stdout(&self, actual: &ProcessOutput) -> ham::MatchResult {
- self.match_std(self.expect_stdout.as_ref(), actual.output.as_slice(), "stdout", actual.error.as_slice())
- }
-
- fn match_stderr(&self, actual: &ProcessOutput) -> ham::MatchResult {
- self.match_std(self.expect_stderr.as_ref(), actual.error.as_slice(), "stderr", actual.output.as_slice())
- }
-
- fn match_std(&self, expected: Option<&String>, actual: &[u8], description: &str, extra: &[u8]) -> ham::MatchResult {
- match expected.as_ref().map(|s| s.as_slice()) {
- None => ham::success(),
- Some(out) => {
- match str::from_utf8(actual) {
- None => Err(format!("{} was not utf8 encoded", description)),
- Some(actual) => {
- ham::expect(actual == out, format!("{} was:\n`{}`\n\nexpected:\n`{}`\n\nother output:\n`{}`", description, actual, out, str::from_utf8_lossy(extra)))
- }
- }
- }
- }
- }
-}
-
-impl ham::SelfDescribing for Execs {
- fn describe(&self) -> String {
- "execs".to_str()
- }
-}
-
-impl ham::Matcher<ProcessBuilder> for Execs {
- fn matches(&self, process: ProcessBuilder) -> ham::MatchResult {
- let res = process.exec_with_output();
-
- match res {
- Ok(out) => self.match_output(&out),
- Err(CargoError { kind: ProcessError(_, ref out), .. }) => self.match_output(out.get_ref()),
- Err(e) => Err(format!("could not exec process {}: {}", process, e))
- }
- }
-}
-
-pub fn execs() -> Box<Execs> {
- box Execs {
- expect_stdout: None,
- expect_stderr: None,
- expect_stdin: None,
- expect_exit_code: None
- }
-}
-
-#[deriving(Clone)]
-struct ShellWrites {
- expected: String
-}
-
-impl ham::SelfDescribing for ShellWrites {
- fn describe(&self) -> String {
- format!("`{}` written to the shell", self.expected)
- }
-}
-
-impl<'a> ham::Matcher<&'a mut shell::Shell<std::io::MemWriter>> for ShellWrites {
- fn matches(&self, actual: &mut shell::Shell<std::io::MemWriter>) -> ham::MatchResult {
- use term::Terminal;
-
- let actual = std::str::from_utf8_lossy(actual.get_ref().get_ref()).to_str();
- ham::expect(actual == self.expected, actual)
- }
-}
-
-pub fn shell_writes<T: Show>(string: T) -> Box<ShellWrites> {
- box ShellWrites { expected: string.to_str() }
-}
-
-pub trait ResultTest<T,E> {
- fn assert(self) -> T;
-}
-
-impl<T,E: Show> ResultTest<T,E> for Result<T,E> {
- fn assert(self) -> T {
- match self {
- Ok(val) => val,
- Err(err) => fail!("Result was error: {}", err)
- }
- }
-}
-
-impl<T> ResultTest<T,()> for Option<T> {
- fn assert(self) -> T {
- match self {
- Some(val) => val,
- None => fail!("Option was None")
- }
- }
-}
-
-pub trait Tap {
- fn tap(mut self, callback: |&mut Self|) -> Self;
-}
-
-impl<T> Tap for T {
- fn tap(mut self, callback: |&mut T|) -> T {
- callback(&mut self);
- self
- }
-}
--- /dev/null
+// use std::io::fs::{mkdir_recursive,rmdir_recursive};
+use std;
+use std::io;
+use std::io::fs;
+use std::io::process::{ProcessOutput,ProcessExit};
+use std::os;
+use std::path::{Path,BytesContainer};
+use std::str;
+use std::vec::Vec;
+use std::fmt::Show;
+use ham = hamcrest;
+use cargo::core::shell;
+use cargo::util::{process,ProcessBuilder,CargoError};
+use cargo::util::result::ProcessError;
+
+pub mod paths;
+
+/*
+ *
+ * ===== Builders =====
+ *
+ */
+
+#[deriving(PartialEq,Clone)]
+struct FileBuilder {
+ path: Path,
+ body: String
+}
+
+impl FileBuilder {
+ pub fn new(path: Path, body: &str) -> FileBuilder {
+ FileBuilder { path: path, body: body.to_str() }
+ }
+
+ fn mk(&self) -> Result<(), String> {
+ try!(mkdir_recursive(&self.dirname()));
+
+ let mut file = try!(
+ fs::File::create(&self.path)
+ .with_err_msg(format!("Could not create file; path={}", self.path.display())));
+
+ file.write_str(self.body.as_slice())
+ .with_err_msg(format!("Could not write to file; path={}", self.path.display()))
+ }
+
+ fn dirname(&self) -> Path {
+ Path::new(self.path.dirname())
+ }
+}
+
+#[deriving(PartialEq,Clone)]
+pub struct ProjectBuilder {
+ name: String,
+ root: Path,
+ files: Vec<FileBuilder>
+}
+
+impl ProjectBuilder {
+ pub fn new(name: &str, root: Path) -> ProjectBuilder {
+ ProjectBuilder {
+ name: name.to_str(),
+ root: root,
+ files: vec!()
+ }
+ }
+
+ pub fn join<T: Str>(&self, name: &str, path: T) -> ProjectBuilder {
+ ProjectBuilder {
+ name: name.as_slice().to_str(),
+ root: self.root.join(path.as_slice()).clone(),
+ files: vec!()
+ }
+ }
+
+ pub fn root(&self) -> Path {
+ self.root.clone()
+ }
+
+ pub fn process(&self, program: &str) -> ProcessBuilder {
+ process(program)
+ .cwd(self.root())
+ .env("HOME", Some(paths::home().display().to_str().as_slice()))
+ }
+
+ pub fn cargo_process(&self, program: &str) -> ProcessBuilder {
+ self.build();
+ self.process(program)
+ .extra_path(cargo_dir())
+ }
+
+ pub fn file<B: BytesContainer, S: Str>(mut self, path: B, body: S) -> ProjectBuilder {
+ self.files.push(FileBuilder::new(self.root.join(path), body.as_slice()));
+ self
+ }
+
+ // TODO: return something different than a ProjectBuilder
+ pub fn build<'a>(&'a self) -> &'a ProjectBuilder {
+ match self.build_with_result() {
+ Err(e) => fail!(e),
+ _ => return self
+ }
+ }
+
+ pub fn build_with_result(&self) -> Result<(), String> {
+ // First, clean the directory if it already exists
+ try!(self.rm_root());
+
+ // Create the empty directory
+ try!(mkdir_recursive(&self.root));
+
+ for file in self.files.iter() {
+ try!(file.mk());
+ }
+
+ Ok(())
+ }
+
+ fn rm_root(&self) -> Result<(), String> {
+ if self.root.exists() {
+ rmdir_recursive(&self.root)
+ }
+ else {
+ Ok(())
+ }
+ }
+}
+
+// Generates a project layout
+pub fn project(name: &str) -> ProjectBuilder {
+ ProjectBuilder::new(name, paths::root().join(name))
+}
+
+// === Helpers ===
+
+pub fn mkdir_recursive(path: &Path) -> Result<(), String> {
+ fs::mkdir_recursive(path, io::UserDir)
+ .with_err_msg(format!("could not create directory; path={}", path.display()))
+}
+
+pub fn rmdir_recursive(path: &Path) -> Result<(), String> {
+ fs::rmdir_recursive(path)
+ .with_err_msg(format!("could not rm directory; path={}", path.display()))
+}
+
+pub fn main_file<T: Str>(println: T, deps: &[&str]) -> String {
+ let mut buf = String::new();
+
+ for dep in deps.iter() {
+ buf.push_str(format!("extern crate {};\n", dep).as_slice());
+ }
+
+ buf.push_str("fn main() { println!(");
+ buf.push_str(println.as_slice());
+ buf.push_str("); }\n");
+
+ buf.to_str()
+}
+
+trait ErrMsg<T> {
+ fn with_err_msg(self, val: String) -> Result<T, String>;
+}
+
+impl<T, E: Show> ErrMsg<T> for Result<T, E> {
+ fn with_err_msg(self, val: String) -> Result<T, String> {
+ match self {
+ Ok(val) => Ok(val),
+ Err(err) => Err(format!("{}; original={}", val, err))
+ }
+ }
+}
+
+// Path to cargo executables
+pub fn cargo_dir() -> Path {
+ os::getenv("CARGO_BIN_PATH")
+ .map(|s| Path::new(s))
+ .unwrap_or_else(|| fail!("CARGO_BIN_PATH wasn't set. Cannot continue running test"))
+}
+
+/// Returns an absolute path in the filesystem that `path` points to. The
+/// returned path does not contain any symlinks in its hierarchy.
+/*
+ *
+ * ===== Matchers =====
+ *
+ */
+
+#[deriving(Clone)]
+struct Execs {
+ expect_stdout: Option<String>,
+ expect_stdin: Option<String>,
+ expect_stderr: Option<String>,
+ expect_exit_code: Option<int>
+}
+
+impl Execs {
+
+ pub fn with_stdout<S: ToStr>(mut ~self, expected: S) -> Box<Execs> {
+ self.expect_stdout = Some(expected.to_str());
+ self
+ }
+
+ pub fn with_stderr<S: ToStr>(mut ~self, expected: S) -> Box<Execs> {
+ self.expect_stderr = Some(expected.to_str());
+ self
+ }
+
+ pub fn with_status(mut ~self, expected: int) -> Box<Execs> {
+ self.expect_exit_code = Some(expected);
+ self
+ }
+
+ fn match_output(&self, actual: &ProcessOutput) -> ham::MatchResult {
+ self.match_status(actual.status)
+ .and(self.match_stdout(actual))
+ .and(self.match_stderr(actual))
+ }
+
+ fn match_status(&self, actual: ProcessExit) -> ham::MatchResult {
+ match self.expect_exit_code {
+ None => ham::success(),
+ Some(code) => {
+ ham::expect(
+ actual.matches_exit_status(code),
+ format!("exited with {}", actual))
+ }
+ }
+ }
+
+ fn match_stdout(&self, actual: &ProcessOutput) -> ham::MatchResult {
+ self.match_std(self.expect_stdout.as_ref(), actual.output.as_slice(), "stdout", actual.error.as_slice())
+ }
+
+ fn match_stderr(&self, actual: &ProcessOutput) -> ham::MatchResult {
+ self.match_std(self.expect_stderr.as_ref(), actual.error.as_slice(), "stderr", actual.output.as_slice())
+ }
+
+ fn match_std(&self, expected: Option<&String>, actual: &[u8], description: &str, extra: &[u8]) -> ham::MatchResult {
+ match expected.as_ref().map(|s| s.as_slice()) {
+ None => ham::success(),
+ Some(out) => {
+ match str::from_utf8(actual) {
+ None => Err(format!("{} was not utf8 encoded", description)),
+ Some(actual) => {
+ ham::expect(actual == out, format!("{} was:\n`{}`\n\nexpected:\n`{}`\n\nother output:\n`{}`", description, actual, out, str::from_utf8_lossy(extra)))
+ }
+ }
+ }
+ }
+ }
+}
+
+impl ham::SelfDescribing for Execs {
+ fn describe(&self) -> String {
+ "execs".to_str()
+ }
+}
+
+impl ham::Matcher<ProcessBuilder> for Execs {
+ fn matches(&self, process: ProcessBuilder) -> ham::MatchResult {
+ let res = process.exec_with_output();
+
+ match res {
+ Ok(out) => self.match_output(&out),
+ Err(CargoError { kind: ProcessError(_, ref out), .. }) => self.match_output(out.get_ref()),
+ Err(e) => Err(format!("could not exec process {}: {}", process, e))
+ }
+ }
+}
+
+pub fn execs() -> Box<Execs> {
+ box Execs {
+ expect_stdout: None,
+ expect_stderr: None,
+ expect_stdin: None,
+ expect_exit_code: None
+ }
+}
+
+#[deriving(Clone)]
+struct ShellWrites {
+ expected: String
+}
+
+impl ham::SelfDescribing for ShellWrites {
+ fn describe(&self) -> String {
+ format!("`{}` written to the shell", self.expected)
+ }
+}
+
+impl<'a> ham::Matcher<&'a mut shell::Shell<std::io::MemWriter>> for ShellWrites {
+ fn matches(&self, actual: &mut shell::Shell<std::io::MemWriter>) -> ham::MatchResult {
+ use term::Terminal;
+
+ let actual = std::str::from_utf8_lossy(actual.get_ref().get_ref()).to_str();
+ ham::expect(actual == self.expected, actual)
+ }
+}
+
+pub fn shell_writes<T: Show>(string: T) -> Box<ShellWrites> {
+ box ShellWrites { expected: string.to_str() }
+}
+
+pub trait ResultTest<T,E> {
+ fn assert(self) -> T;
+}
+
+impl<T,E: Show> ResultTest<T,E> for Result<T,E> {
+ fn assert(self) -> T {
+ match self {
+ Ok(val) => val,
+ Err(err) => fail!("Result was error: {}", err)
+ }
+ }
+}
+
+impl<T> ResultTest<T,()> for Option<T> {
+ fn assert(self) -> T {
+ match self {
+ Some(val) => val,
+ None => fail!("Option was None")
+ }
+ }
+}
+
+pub trait Tap {
+ fn tap(mut self, callback: |&mut Self|) -> Self;
+}
+
+impl<T> Tap for T {
+ fn tap(mut self, callback: |&mut T|) -> T {
+ callback(&mut self);
+ self
+ }
+}
--- /dev/null
+use std::{io,os};
+use std::io::IoResult;
+use std::io::fs;
+use cargo::util::realpath;
+
+static CARGO_INTEGRATION_TEST_DIR : &'static str = "cargo-integration-tests";
+
+pub fn root() -> Path {
+ realpath(&os::tmpdir().join(CARGO_INTEGRATION_TEST_DIR)).unwrap()
+}
+
+pub fn home() -> Path {
+ root().join("home")
+}
+
+pub trait PathExt {
+ fn rm_rf(&self) -> IoResult<()>;
+ fn mkdir_p(&self) -> IoResult<()>;
+}
+
+impl PathExt for Path {
+ /* Technically there is a potential race condition, but we don't
+ * care all that much for our tests
+ */
+ fn rm_rf(&self) -> IoResult<()> {
+ if self.exists() {
+ fs::rmdir_recursive(self)
+ }
+ else {
+ Ok(())
+ }
+ }
+
+ fn mkdir_p(&self) -> IoResult<()> {
+ fs::mkdir_recursive(self, io::UserDir)
+ }
+}
+
+/**
+ * Ensure required test directories exist and are empty
+ */
+pub fn setup() {
+ debug!("path setup; root={}; home={}", root().display(), home().display());
+ root().rm_rf().unwrap();
+ home().mkdir_p().unwrap();
+}
-use support::{ResultTest,project,execs};
+use support::{ResultTest,project,execs,main_file};
use hamcrest::{assert_that,existing_file};
use cargo;
use cargo::util::{process,realpath};
execs().with_stdout("test passed\n"));
})
-fn main_file(println: &str, deps: &[&str]) -> String {
- let mut buf = String::new();
-
- for dep in deps.iter() {
- buf.push_str(format!("extern crate {};\n", dep).as_slice());
- }
-
- buf.push_str("fn main() { println!(");
- buf.push_str(println);
- buf.push_str("); }\n");
-
- buf.to_str()
-}
-
// test!(compiling_project_with_invalid_manifest)
--- /dev/null
+use support::{ProjectBuilder,ResultTest,project,execs,main_file};
+use hamcrest::{assert_that,existing_file};
+use cargo;
+use cargo::util::{CargoResult,process};
+
+fn setup() {
+}
+
+fn git_repo(name: &str, callback: |ProjectBuilder| -> ProjectBuilder) -> CargoResult<ProjectBuilder> {
+ let mut git_project = project(name);
+ git_project = callback(git_project);
+ git_project.build();
+
+ log!(5, "git init");
+ try!(git_project.process("git").args(["init"]).exec_with_output());
+ log!(5, "building git project");
+ log!(5, "git add .");
+ try!(git_project.process("git").args(["add", "."]).exec_with_output());
+ log!(5, "git commit");
+ try!(git_project.process("git").args(["commit", "-m", "Initial commit"]).exec_with_output());
+ Ok(git_project)
+}
+
+test!(cargo_compile_simple_git_dep {
+ let project = project("foo");
+ let git_project = git_repo("dep1", |project| {
+ project
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "dep1"
+ version = "0.5.0"
+ authors = ["carlhuda@example.com"]
+
+ [[lib]]
+
+ name = "dep1"
+ "#)
+ .file("src/dep1.rs", r#"
+ pub fn hello() -> &'static str {
+ "hello world"
+ }
+ "#)
+ }).assert();
+
+ let project = project
+ .file("Cargo.toml", format!(r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.dep1]
+
+ version = "0.5.0"
+ git = "file://{}"
+
+ [[bin]]
+
+ name = "foo"
+ "#, git_project.root().display()))
+ .file("src/foo.rs", main_file(r#""{}", dep1::hello()"#, ["dep1"]));
+
+ let root = project.root();
+ let git_root = git_project.root();
+
+ assert_that(project.cargo_process("cargo-compile"),
+ execs()
+ .with_stdout(format!("Compiling dep1 v0.5.0 (file:{})\nCompiling foo v0.5.0 (file:{})\n",
+ git_root.display(), root.display()))
+ .with_stderr(""));
+
+ assert_that(&project.root().join("target/foo"), existing_file());
+
+ assert_that(
+ cargo::util::process("foo").extra_path(project.root().join("target")),
+ execs().with_stdout("hello world\n"));
+})
#[phase(plugin, link)]
extern crate log;
+mod support;
macro_rules! test(
($name:ident $expr:expr) => (
#[test]
fn $name() {
+ ::support::paths::setup();
setup();
$expr;
}
)
)
-mod support;
mod test_cargo_compile;
+mod test_cargo_compile_git_deps;
mod test_shell;