$(TOML): $(wildcard libs/rust-toml/src/toml/*.rs)
cd libs/rust-toml && make
-$(HAMCREST): $(wildcard libs/hamcrest-rust/src/hamcrest/*.rs)
+$(HAMCREST): $(shell find libs/hamcrest-rust/src/hamcrest -name '*.rs')
cd libs/hamcrest-rust && make
# === Cargo
TEST_SRC = $(wildcard tests/*.rs)
TEST_DEPS = $(DEPS) -L libs/hamcrest-rust/target
-target/tests: $(BIN_TARGETS) $(HAMCREST) $(TEST_SRC)
- $(RUSTC) --test --crate-type=lib $(TEST_DEPS) -Ltarget --out-dir target tests/tests.rs
+target/tests/test-integration: $(BIN_TARGETS) $(HAMCREST) $(TEST_SRC)
+ $(RUSTC) --test --crate-type=lib $(TEST_DEPS) -Ltarget -o $@ tests/tests.rs
-test-integration: target/tests
+target/tests/test-unit: $(HAMCREST) $(SRC) $(HAMMER)
+ mkdir -p target/tests
+ $(RUSTC) --test $(RUSTC_FLAGS) $(TEST_DEPS) -o $@ src/cargo/mod.rs
+
+test-unit: target/tests/test-unit
+ target/tests/test-unit
+
+test-integration: target/tests/test-integration
CARGO_BIN_PATH=$(PWD)/target/ $<
-test: test-integration
+test: test-unit test-integration
clean:
rm -rf target
cd libs/rust-toml && make clean
# Setup phony tasks
-.PHONY: all clean distclean test test-integration libcargo
+.PHONY: all clean distclean test test-unit test-integration libcargo
# Disable unnecessary built-in rules
.SUFFIXES:
-Subproject commit 634495ea08f3c3b019dc4e6d464ada83b00f926f
+Subproject commit 54ef9a3064d85c9756a9c183087a9e4e28056651
--- /dev/null
+
+// TODO: add version restrictions
+#[deriving(Clone,Eq,Show)]
+pub struct Dependency {
+ name: ~str,
+}
+
+impl Dependency {
+ pub fn new(name: &str) -> Dependency {
+ Dependency { name: name.to_owned() }
+ }
+
+ pub fn get_name<'a>(&'a self) -> &'a str {
+ self.name.as_slice()
+ }
+}
+pub use self::dependency::Dependency;
+pub use self::registry::{
+ Registry,
+ MemRegistry};
+
pub use self::manifest::{
Manifest,
Project,
LibTarget,
ExecTarget};
+pub use self::package::Package;
+
+mod dependency;
mod manifest;
+mod package;
+mod registry;
+mod resolver;
--- /dev/null
+use std::vec::Vec;
+use core;
+
+/**
+ * Represents a rust library internally to cargo. This will things like where
+ * on the local system the code is located, it's remote location, dependencies,
+ * etc..
+ *
+ * This differs from core::Project
+ */
+#[deriving(Clone,Eq,Show)]
+pub struct Package {
+ name: ~str,
+ deps: Vec<core::Dependency>
+}
+
+impl Package {
+ pub fn new(name: &str, deps: &Vec<core::Dependency>) -> Package {
+ Package { name: name.to_owned(), deps: deps.clone() }
+ }
+
+ pub fn get_name<'a>(&'a self) -> &'a str {
+ self.name.as_slice()
+ }
+}
--- /dev/null
+use std::vec::Vec;
+
+use core::{
+ // Dependency,
+ Package};
+
+pub trait Registry {
+ fn query<'a>(&'a self, name: &str) -> Vec<&'a Package>;
+}
+
+/*
+ *
+ * ===== Temporary for convenience =====
+ *
+ */
+
+pub struct MemRegistry {
+ packages: Vec<Package>
+}
+
+impl MemRegistry {
+ pub fn new(packages: &Vec<Package>) -> MemRegistry {
+ MemRegistry { packages: packages.clone() }
+ }
+
+ pub fn empty() -> MemRegistry {
+ MemRegistry { packages: Vec::new() }
+ }
+}
+
+impl Registry for MemRegistry {
+ fn query<'a>(&'a self, name: &str) -> Vec<&'a Package> {
+ self.packages.iter()
+ .filter(|pkg| name == pkg.get_name())
+ .collect()
+ }
+}
--- /dev/null
+use collections::HashMap;
+use core;
+use {CargoResult};
+
+#[allow(dead_code)]
+pub fn resolve(deps: &Vec<core::Dependency>, registry: &core::Registry) -> CargoResult<Vec<core::Package>> {
+ let mut remaining = deps.clone();
+ let mut resolve = HashMap::<&str, &core::Package>::new();
+
+ loop {
+ let curr = match remaining.pop() {
+ Some(curr) => curr,
+ None => return Ok(resolve.values().map(|v| (*v).clone()).collect())
+ };
+
+ let opts = registry.query(curr.get_name());
+
+ assert!(!resolve.contains_key_equiv(&curr.get_name()), "already traversed {}", curr.get_name());
+ // Temporary, but we must have exactly one option to satisfy the dep
+ assert!(opts.len() == 1, "invalid num of results {}", opts.len());
+
+ let pkg = opts.get(0);
+ resolve.insert(pkg.get_name(), *pkg);
+ }
+}
+
+#[cfg(test)]
+mod test {
+
+ use hamcrest::{
+ assert_that,
+ equal_to,
+ of_len,
+ contains
+ };
+
+ use core::{
+ MemRegistry,
+ Dependency,
+ Package
+ };
+
+ use super::{
+ resolve
+ };
+
+ fn pkg(name: &str) -> Package {
+ Package::new(name, &Vec::<Dependency>::new())
+ }
+
+ fn dep(name: &str) -> Dependency {
+ Dependency::new(name)
+ }
+
+ fn registry(pkgs: Vec<Package>) -> MemRegistry {
+ MemRegistry::new(&pkgs)
+ }
+
+ #[test]
+ pub fn test_resolving_empty_dependency_list() {
+ let res = resolve(&vec!(), ®istry(vec!())).unwrap();
+
+ assert_that(&res, equal_to(&Vec::<Package>::new()));
+ }
+
+ #[test]
+ pub fn test_resolving_only_package() {
+ let reg = registry(vec!(pkg("foo")));
+ let res = resolve(&vec!(dep("foo")), ®);
+
+ assert_that(&res.unwrap(), equal_to(&vec!(pkg("foo"))));
+ }
+
+ #[test]
+ pub fn test_resolving_one_dep() {
+ let reg = registry(vec!(pkg("foo"), pkg("bar")));
+ let res = resolve(&vec!(dep("foo")), ®);
+
+ assert_that(&res.unwrap(), equal_to(&vec!(pkg("foo"))));
+ }
+
+ #[test]
+ pub fn test_resolving_multiple_deps() {
+ let reg = registry(vec!(pkg("foo"), pkg("bar"), pkg("baz")));
+ let res = resolve(&vec!(dep("foo"), dep("baz")), ®).unwrap();
+
+ assert_that(&res, of_len(2));
+ assert_that(&res, contains(vec!(pkg("foo"), pkg("baz"))).exactly());
+ }
+}
#![allow(deprecated_owned_vector)]
-extern crate serialize;
+extern crate collections;
extern crate hammer;
+extern crate serialize;
+
+#[cfg(test)]
+extern crate hamcrest;
use serialize::{Decoder,Encoder,Decodable,Encodable,json};
use std::io;
use std::fmt::{Show,Formatter};
use hammer::{FlagDecoder,FlagConfig,HammerError};
+
pub mod core;
pub mod util;
impl Execs {
- pub fn with_stdout(mut self, expected: &str) -> Execs {
+ pub fn with_stdout(mut ~self, expected: &str) -> ~Execs {
self.expect_stdout = Some(expected.to_owned());
self
}
}
impl ham::Matcher<ProcessBuilder> for Execs {
- fn matches(&self, process: &ProcessBuilder) -> ham::MatchResult {
+ fn matches(&self, process: ProcessBuilder) -> ham::MatchResult {
let res = process.exec_with_output();
match res {
}
}
-pub fn execs() -> Execs {
- Execs {
+pub fn execs() -> ~Execs {
+ ~Execs {
expect_stdout: None,
expect_stdin: None,
expect_exit_code: None
assert_that(&p.root().join("target/foo"), existing_file());
assert_that(
- &cargo::util::process("foo").extra_path(p.root().join("target")),
+ cargo::util::process("foo").extra_path(p.root().join("target")),
execs().with_stdout("i am foo\n"));
})