-use std::vec::Vec;
+use std::slice;
use semver;
use core;
use core::{NameVer,Dependency};
use core::manifest::{Manifest,LibTarget};
+use core::Registry;
+use util::graph;
/**
* Represents a rust library internally to cargo. This will things like where
self.deps.as_slice()
}
}
+
+pub struct PackageSet {
+ packages: ~[Package]
+}
+
+impl PackageSet {
+ pub fn new(packages: &[Package]) -> PackageSet {
+ PackageSet { packages: packages.to_owned() }
+ }
+
+ /**
+ * Get a package by name out of the set
+ */
+ pub fn get<'a>(&'a self, name: &str) -> &'a Package {
+ let opts = self.query(name);
+ assert!(opts.len() == 1, "expected exactly one package named `{}`", name);
+ *opts.get(0)
+ }
+
+ // For now, assume that the package set contains only one package with a
+ // given name
+ pub fn sort(&self) -> Option<PackageSet> {
+ let mut graph = graph::Graph::new();
+
+ for pkg in self.packages.iter() {
+ let deps: ~[&str] = pkg.get_dependencies().iter()
+ .map(|dep| dep.get_name())
+ .collect();
+
+ graph.add(pkg.get_name(), deps.as_slice());
+ }
+
+ let pkgs = some!(graph.sort()).iter().map(|name| self.get(*name).clone()).collect();
+
+ Some(PackageSet {
+ packages: pkgs
+ })
+ }
+
+ pub fn iter<'a>(&'a self) -> slice::Items<'a, Package> {
+ self.packages.iter()
+ }
+}
+
+impl Registry for PackageSet {
+ fn query<'a>(&'a self, name: &str) -> Vec<&'a Package> {
+ self.packages.iter()
+ .filter(|pkg| name == pkg.get_name())
+ .collect()
+ }
+}
use std::io::process::{Process,ProcessConfig,InheritFd};
use std::path::Path;
use {CargoResult,CargoError,ToCargoError,NoFlags,core};
+use core;
+pub fn compile(pkgs: &core::PackageSet) {
+ let sorted = match pkgs.sort() {
+ Some(pkgs) => pkgs,
+ None => return
+ };
+
+ for pkg in sorted.iter() {
+ compile_pkg(pkg, pkgs);
+ }
+}
-pub fn compile() {
+fn compile_pkg(pkg: &core::Package, pkgs: &core::PackageSet) {
+
+}
+
+fn rustc() {
}
pub fn execute(_: NoFlags, manifest: core::Manifest) -> CargoResult<Option<core::Manifest>> {
+use std::hash::Hash;
use collections::HashMap;
-trait Node<'a, I: Iterator<&'a Self>> {
- fn children(&'a self) -> I;
+pub struct Graph<N> {
+ nodes: HashMap<N, ~[N]>
}
-trait Graph<'a, N: Node<'a, I>, I: Iterator<&'a N>> {
- fn nodes(&'a self) -> I;
-}
-
-#[deriving(Clone)]
enum Mark {
InProgress,
Done
}
-/**
- * Returns None in the event of a cycle
- */
-pub fn topsort<'a, N: Node<'a, I>, G: Graph<'a, N, I>, I: Iterator<&'a N>>(graph: &'a G) -> Option<Vec<&'a N>> {
- let mut ret = Vec::new();
- let mut iter: I = graph.nodes();
- let mut stack = Vec::<&'a N>::new();
- let mut marks: HashMap<*N, Mark> = HashMap::new();
-
- // Prime the stack
- for node in iter {
- visit(node, &mut ret, &mut marks);
+impl<N: TotalEq + Hash + Clone> Graph<N> {
+ pub fn new() -> Graph<N> {
+ Graph { nodes: HashMap::new() }
}
- Some(ret)
-}
-
-fn visit<'a, N: Node<'a, I>, I: Iterator<&'a N>>(curr: &'a N, dst: &mut Vec<&'a N>, marks: &mut HashMap<*N, Mark>) {
- let ident = curr as *N;
-
- if marks.contains_key(&ident) {
- return;
+ pub fn add(&mut self, node: N, children: &[N]) {
+ self.nodes.insert(node, children.to_owned());
}
- marks.insert(ident, InProgress);
+ pub fn sort(&self) -> Option<Vec<N>> {
+ let mut ret = Vec::new();
+ let mut marks = HashMap::new();
- let mut iter: I = curr.children();
+ for node in self.nodes.keys() {
+ self.visit(node, &mut ret, &mut marks);
+ }
- for child in iter {
- visit::<'a, N, I>(child, dst, marks);
+ Some(ret)
}
- dst.push(curr);
- marks.insert(ident, Done);
-}
+ fn visit(&self, node: &N, dst: &mut Vec<N>, marks: &mut HashMap<N, Mark>) {
+ if marks.contains_key(node) {
+ return;
+ }
+
+ marks.insert(node.clone(), InProgress);
-#[cfg(test)]
-mod test {
- // TODO: tests
+ for child in self.nodes.get(node).iter() {
+ self.visit(child, dst, marks);
+ }
+
+ dst.push(node.clone());
+ marks.insert(node.clone(), Done);
+ }
}