-Subproject commit de700414aab1aaa4461618ce7a516cb24a8e6665
+Subproject commit 138de49f217604d22e019afd71c529a7d76643f0
extern crate serialize;
extern crate hammer;
-use cargo::execute_main_without_stdin;
-use cargo::ops::cargo_read_manifest::read_manifest;
-use cargo::core::Manifest;
-use cargo::core::errors::CLIResult;
-use hammer::FlagConfig;
-
-#[deriving(Decodable,Eq,Clone,Ord)]
-pub struct ReadManifestFlags {
- manifest_path: ~str
-}
-
-impl FlagConfig for ReadManifestFlags {}
-
fn main() {
- execute_main_without_stdin(execute);
-}
-
-fn execute(flags: ReadManifestFlags) -> CLIResult<Option<Manifest>> {
- match read_manifest(flags.manifest_path) {
- Ok(manifest) => Ok(Some(manifest)),
- Err(e) => Err(e)
- }
+ // Standalone cargo-read-manifest will go here
+ unimplemented!();
}
extern crate cargo;
-use cargo::execute_main;
-use cargo::ops::cargo_rustc::execute;
-
fn main() {
- execute_main(execute);
+ // Standalone cargo-rustc will go here
+ unimplemented!();
}
-use core::NameVer;
-use core::dependency::Dependency;
use collections::HashMap;
+use core::{
+ Dependency,
+ NameVer,
+ Package,
+ Summary
+};
use core::errors::{CargoResult,CargoError,ToResult,PathError};
-/*
- * TODO: Make all struct fields private
- */
+// #[deriving(Decodable,Encodable,Eq,Clone)]
+#[deriving(Eq,Clone)]
+pub struct Manifest {
+ summary: Summary,
+ authors: Vec<~str>,
+ targets: Vec<Target>,
+ target_dir: Path,
+}
-#[deriving(Decodable,Encodable,Eq,Clone)]
-pub struct SerializedManifest {
- project: ~Project,
- lib: Option<~[SerializedLibTarget]>,
- bin: Option<~[SerializedExecTarget]>,
- dependencies: Option<HashMap<~str, ~str>>
+#[deriving(Clone,Eq)]
+pub enum TargetKind {
+ LibTarget,
+ BinTarget
}
-#[deriving(Decodable,Encodable,Eq,Clone)]
-struct SerializedTarget {
+#[deriving(Clone,Eq)]
+pub struct Target {
+ kind: TargetKind,
name: ~str,
- path: Option<~str>
+ path: Path
}
-type SerializedLibTarget = SerializedTarget;
-type SerializedExecTarget = SerializedTarget;
+impl Manifest {
+ pub fn new(summary: &Summary, targets: &[Target], target_dir: &Path) -> Manifest {
+ Manifest {
+ summary: summary.clone(),
+ authors: Vec::new(),
+ targets: Vec::from_slice(targets),
+ target_dir: target_dir.clone()
+ }
+ }
-#[deriving(Decodable,Encodable,Eq,Clone,Show)]
-pub struct Manifest {
- pub project: ~Project,
- pub root: ~str,
- pub lib: ~[LibTarget],
- pub bin: ~[ExecTarget],
- pub target: ~str,
- pub dependencies: Vec<Dependency>
-}
+ pub fn get_summary<'a>(&'a self) -> &'a Summary {
+ &self.summary
+ }
-impl Manifest {
+ pub fn get_name<'a>(&'a self) -> &'a str {
+ self.get_summary().get_name_ver().get_name()
+ }
+
+ pub fn get_dependencies<'a>(&'a self) -> &'a [Dependency] {
+ self.get_summary().get_dependencies()
+ }
+
+ pub fn get_targets<'a>(&'a self) -> &'a [Target] {
+ self.targets.as_slice()
+ }
+
+ pub fn get_target_dir<'a>(&'a self) -> &'a Path {
+ &self.target_dir
+ }
+
+ /*
pub fn from_serialized(path: &str, serialized: &SerializedManifest) -> CargoResult<Manifest> {
let (lib,bin) = normalize(&serialized.lib, &serialized.bin);
let &SerializedManifest { ref project, ref dependencies, .. } = serialized;
dependencies: deps
})
}
+ */
+}
+
+impl Target {
+ pub fn lib_target(name: &str, path: &Path) -> Target {
+ Target {
+ kind: LibTarget,
+ name: name.to_owned(),
+ path: path.clone()
+ }
+ }
+
+ pub fn bin_target(name: &str, path: &Path) -> Target {
+ Target {
+ kind: BinTarget,
+ name: name.to_owned(),
+ path: path.clone()
+ }
+ }
+
+ pub fn get_path<'a>(&'a self) -> &'a Path {
+ &self.path
+ }
+
+ pub fn rustc_crate_type(&self) -> &'static str {
+ match self.kind {
+ LibTarget => "lib",
+ BinTarget => "bin"
+ }
+ }
+}
+
+/*
+ *
+ * ===== Serialized =====
+ *
+ */
+
+type SerializedLibTarget = SerializedTarget;
+type SerializedExecTarget = SerializedTarget;
+
+#[deriving(Decodable,Encodable,Eq,Clone,Show)]
+pub struct Project {
+ pub name: ~str,
+ pub version: ~str,
+ pub authors: ~[~str]
+}
+
+/*
+ * TODO: Make all struct fields private
+ */
+
+#[deriving(Decodable,Encodable,Eq,Clone)]
+pub struct SerializedManifest {
+ project: ~Project,
+ lib: Option<~[SerializedLibTarget]>,
+ bin: Option<~[SerializedExecTarget]>,
+ dependencies: Option<HashMap<~str, ~str>>
+}
+
+impl SerializedManifest {
+ pub fn to_package(&self, path: &str) -> CargoResult<Package> {
+ // Get targets
+ let targets = normalize(&self.lib, &self.bin);
+ // Get deps
+ let deps = self.dependencies.clone().map(|deps| {
+ deps.iter().map(|(k,v)| {
+ // This can produce an invalid version, but it's temporary because this needs
+ // to be replaced with Dependency, not NameVer
+ Dependency::with_namever(&NameVer::new(k.clone(), v.clone()))
+ }).collect()
+ }).unwrap_or_else(|| vec!());
+
+ let root = try!(Path::new(path.to_owned()).dirname_str().map(|s| s.to_owned()).to_result(|_|
+ CargoError::internal(PathError(format!("Couldn't convert {} to a directory name", path)))));
- pub fn get_name_ver(&self) -> NameVer {
- NameVer::new(self.project.name.as_slice(), self.project.version.as_slice())
+ Ok(Package::new(
+ &Manifest::new(
+ &Summary::new(&self.project.to_name_ver(), deps.as_slice()),
+ targets.as_slice(),
+ &Path::new("target")),
+ &Path::new(root)))
}
+}
- pub fn get_path<'a>(&'a self) -> Path {
- Path::new(self.root.as_slice())
+impl Project {
+ fn to_name_ver(&self) -> NameVer {
+ NameVer::new(self.name, self.version)
}
}
-fn normalize(lib: &Option<~[SerializedLibTarget]>, bin: &Option<~[SerializedExecTarget]>) -> (~[LibTarget], ~[ExecTarget]) {
- fn lib_targets(libs: &[SerializedLibTarget]) -> ~[LibTarget] {
+#[deriving(Decodable,Encodable,Eq,Clone)]
+struct SerializedTarget {
+ name: ~str,
+ path: Option<~str>
+}
+
+fn normalize(lib: &Option<~[SerializedLibTarget]>, bin: &Option<~[SerializedExecTarget]>) -> Vec<Target> {
+ fn lib_targets(dst: &mut Vec<Target>, libs: &[SerializedLibTarget]) {
let l = &libs[0];
let path = l.path.clone().unwrap_or_else(|| format!("src/{}.rs", l.name));
- ~[LibTarget { path: path, name: l.name.clone() }]
+ dst.push(Target::lib_target(l.name, &Path::new(path)));
}
- fn bin_targets(bins: &[SerializedExecTarget], default: |&SerializedExecTarget| -> ~str) -> ~[ExecTarget] {
- bins.iter().map(|bin| {
+ fn bin_targets(dst: &mut Vec<Target>, bins: &[SerializedExecTarget], default: |&SerializedExecTarget| -> ~str) {
+ for bin in bins.iter() {
let path = bin.path.clone().unwrap_or_else(|| default(bin));
- ExecTarget { path: path, name: bin.name.clone() }
- }).collect()
+ dst.push(Target::bin_target(bin.name.clone(), &Path::new(path)));
+ }
}
+ let mut ret = Vec::new();
+
match (lib, bin) {
(&Some(ref libs), &Some(ref bins)) => {
- (lib_targets(libs.as_slice()), bin_targets(bins.as_slice(), |bin| format!("src/bin/{}.rs", bin.name)))
+ lib_targets(&mut ret, libs.as_slice());
+ bin_targets(&mut ret, bins.as_slice(), |bin| format!("src/bin/{}.rs", bin.name));
},
(&Some(ref libs), &None) => {
- (lib_targets(libs.as_slice()), ~[])
+ lib_targets(&mut ret, libs.as_slice());
},
(&None, &Some(ref bins)) => {
- (~[], bin_targets(bins.as_slice(), |bin| format!("src/{}.rs", bin.name)))
+ bin_targets(&mut ret, bins.as_slice(), |bin| format!("src/{}.rs", bin.name));
},
- (&None, &None) => {
- (~[], ~[])
- }
+ (&None, &None) => ()
}
-}
-#[deriving(Decodable,Encodable,Eq,Clone,Show)]
-pub struct ExecTarget {
- pub name: ~str,
- pub path: ~str
-}
-
-#[deriving(Decodable,Encodable,Eq,Clone,Show)]
-pub struct LibTarget {
- pub name: ~str,
- pub path: ~str
-}
-
-#[deriving(Decodable,Encodable,Eq,Clone,Show)]
-pub struct Project {
- pub name: ~str,
- pub version: ~str,
- pub authors: ~[~str]
+ ret
}
pub use self::manifest::{
Manifest,
- Project,
- LibTarget,
- ExecTarget
+ Target,
+ TargetKind
};
pub use self::package::{
PackageSet
};
+pub use self::summary::{
+ Summary
+};
+
pub use self::dependency::Dependency;
pub mod errors;
pub mod dependency;
pub mod manifest;
pub mod resolver;
+mod summary;
mod registry;
use std::slice;
use std::path::Path;
-use semver;
-use core;
-use core::{NameVer,Dependency};
-use core::manifest::{Manifest,LibTarget};
-use core::Registry;
+use core::{
+ Dependency,
+ Manifest,
+ Registry,
+ Target,
+ Summary
+};
use util::graph;
-/**
- * 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)]
+#[deriving(Clone)]
pub struct Package {
- name_ver: core::NameVer,
- deps: Vec<core::Dependency>,
+ // The package's manifest
+ manifest: Manifest,
+ // The root of the package
root: Path,
- source: LibTarget,
- target: ~str
}
impl Package {
- pub fn new(name: &core::NameVer, deps: &Vec<core::Dependency>, root: &str, source: &LibTarget, target: &str) -> Package {
+ pub fn new(manifest: &Manifest, root: &Path) -> Package {
Package {
- name_ver: name.clone(),
- deps: deps.clone(),
- root: Path::new(root),
- source: source.clone(),
- target: target.to_owned()
+ manifest: manifest.clone(),
+ root: root.clone()
}
}
- pub fn from_manifest(manifest: &Manifest) -> Package {
- let project = &manifest.project;
+ pub fn get_manifest<'a>(&'a self) -> &'a Manifest {
+ &self.manifest
+ }
- Package {
- name_ver: core::NameVer::new(project.name.as_slice(), project.version.as_slice()),
- deps: manifest.dependencies.clone(),
- root: Path::new(manifest.root.as_slice()),
- source: manifest.lib.as_slice().get(0).unwrap().clone(),
- target: manifest.target.clone()
- }
+ pub fn get_summary<'a>(&'a self) -> &'a Summary {
+ self.manifest.get_summary()
}
pub fn get_name<'a>(&'a self) -> &'a str {
- self.name_ver.get_name()
+ self.get_manifest().get_name()
}
- pub fn get_version<'a>(&'a self) -> &'a semver::Version {
- self.name_ver.get_version()
+ pub fn get_dependencies<'a>(&'a self) -> &'a [Dependency] {
+ self.get_manifest().get_dependencies()
}
- pub fn get_root<'a>(&'a self) -> &'a Path {
- &self.root
+ pub fn get_targets<'a>(&'a self) -> &'a [Target] {
+ self.get_manifest().get_targets()
}
- pub fn get_source<'a>(&'a self) -> &'a LibTarget {
- &self.source
+ pub fn get_root<'a>(&'a self) -> &'a Path {
+ &self.root
}
- pub fn get_target<'a>(&'a self) -> &'a str {
- self.target.as_slice()
+ pub fn get_target_dir<'a>(&'a self) -> &'a Path {
+ self.manifest.get_target_dir()
}
- pub fn get_dependencies<'a>(&'a self) -> &'a [core::Dependency] {
- self.deps.as_slice()
+ pub fn get_absolute_target_dir(&self) -> Path {
+ self.get_root().join(self.get_target_dir())
}
}
--- /dev/null
+use core::{
+ Dependency,
+ NameVer
+};
+
+#[deriving(Show,Clone,Eq)]
+pub struct Summary {
+ name_ver: NameVer,
+ dependencies: Vec<Dependency>
+}
+
+impl Summary {
+ pub fn new(name_ver: &NameVer, dependencies: &[Dependency]) -> Summary {
+ Summary {
+ name_ver: name_ver.clone(),
+ dependencies: Vec::from_slice(dependencies)
+ }
+ }
+
+ pub fn get_name_ver<'a>(&'a self) -> &'a NameVer {
+ &self.name_ver
+ }
+
+ pub fn get_dependencies<'a>(&'a self) -> &'a [Dependency] {
+ self.dependencies.as_slice()
+ }
+}
use toml;
use toml::from_toml;
-use core::manifest::{SerializedManifest,Manifest};
+use core;
+use core::manifest::{SerializedManifest};
use core::errors::{CLIError,CLIResult,ToResult};
-pub fn read_manifest(manifest_path: &str) -> CLIResult<Manifest> {
+pub fn read_manifest(manifest_path: &str) -> CLIResult<core::Package> {
let root = try!(toml::parse_from_file(manifest_path.clone()).to_result(|err|
CLIError::new(format!("Cargo.toml was not valid Toml: {}", manifest_path), Some(err.to_str()), 1)));
let toml_manifest = try!(from_toml::<SerializedManifest>(root.clone()).to_result(|err: toml::Error|
CLIError::new(format!("Cargo.toml was not in the right format: {}", manifest_path), Some(err.to_str()), 1)));
- Manifest::from_serialized(manifest_path.as_slice(), &toml_manifest).to_result(|err|
+ toml_manifest.to_package(manifest_path.as_slice()).to_result(|err|
CLIError::new(format!("Cargo.toml was not in the right format: {}", manifest_path), Some(err.to_str()), 1))
}
-use std;
use std::os::args;
use std::io;
-use std::io::process::{Process,ProcessConfig,InheritFd};
use std::path::Path;
use core::errors::{CLIError,CLIResult,ToResult};
-use NoFlags;
use core;
use util;
Ok(())
}
-
fn compile_pkg(pkg: &core::Package, pkgs: &core::PackageSet) -> CLIResult<()> {
// Build up the destination
- let src = pkg.get_root().join(Path::new(pkg.get_source().path.as_slice()));
- let target = pkg.get_root().join(Path::new(pkg.get_target()));
+ // let src = pkg.get_root().join(Path::new(pkg.get_source().path.as_slice()));
+ let target_dir = pkg.get_absolute_target_dir();
// First ensure that the directory exists
- try!(mk_target(&target).to_result(|err|
- CLIError::new(format!("Could not create the target directory {}", target.display()), Some(err.to_str()), 1)));
+ try!(mk_target(&target_dir).to_result(|err|
+ CLIError::new(format!("Could not create the target directory {}", target_dir.display()), Some(err.to_str()), 1)));
// compile
- try!(rustc(pkg.get_root(), &src, &target, deps(pkg, pkgs)));
+ for target in pkg.get_targets().iter() {
+ try!(rustc(pkg.get_root(), target, &target_dir, deps(pkg, pkgs)));
+ }
Ok(())
}
io::fs::mkdir_recursive(target, io::UserRWX)
}
-fn rustc(root: &Path, src: &Path, target: &Path, deps: &[core::Package]) -> CLIResult<()> {
+fn rustc(root: &Path, target: &core::Target, dest: &Path, deps: &[core::Package]) -> CLIResult<()> {
let mut args = Vec::new();
- build_base_args(&mut args, src, target);
+ build_base_args(&mut args, target, dest);
build_deps_args(&mut args, deps);
try!(util::process("rustc")
Ok(())
}
-fn build_base_args(dst: &mut Args, src: &Path, target: &Path) {
- dst.push(src.as_str().unwrap().to_owned());
- dst.push("--crate-type".to_owned());
- dst.push("lib".to_owned());
- dst.push("--out-dir".to_owned());
- dst.push(target.as_str().unwrap().to_owned());
+fn build_base_args(into: &mut Args, target: &core::Target, dest: &Path) {
+ into.push(target.get_path().as_str().unwrap().to_owned());
+ into.push("--crate-type".to_owned());
+ into.push(target.rustc_crate_type().to_owned());
+ into.push("--out-dir".to_owned());
+ into.push(dest.as_str().unwrap().to_owned());
}
fn build_deps_args(dst: &mut Args, deps: &[core::Package]) {
for dep in deps.iter() {
- let target = dep.get_root().join(Path::new(dep.get_target()));
+ let dir = dep.get_absolute_target_dir();
dst.push("-L".to_owned());
- dst.push(target.as_str().unwrap().to_owned());
+ dst.push(dir.as_str().unwrap().to_owned());
}
}
let names: ~[&str] = pkg.get_dependencies().iter().map(|d| d.get_name()).collect();
pkgs.get_all(names).iter().map(|p| (*p).clone()).collect()
}
-
-pub fn execute(_: NoFlags, manifest: core::Manifest) -> CLIResult<Option<core::Manifest>> {
- let core::Manifest { root, lib, bin, .. } = manifest;
-
- let (crate_type, out_dir) = if lib.len() > 0 {
- ( "lib".to_owned(), lib[0].path )
- } else if bin.len() > 0 {
- ( "bin".to_owned(), bin[0].path )
- } else {
- return Err(CLIError::new("bad manifest, no lib or bin specified", None, 1));
- };
-
- let root = Path::new(root);
- let target = join(&root, "target".to_owned());
-
- let args = [
- join(&root, out_dir),
- "--out-dir".to_owned(), target,
- "--crate-type".to_owned(), crate_type
- ];
-
- match io::fs::mkdir_recursive(&root.join("target"), io::UserRWX) {
- Err(_) => fail!("Couldn't mkdir -p"),
- Ok(val) => val
- }
-
- println!("Executing rustc {}", args.as_slice());
-
- let mut config = ProcessConfig::new();
- config.stdout = InheritFd(1);
- config.stderr = InheritFd(2);
- config.program = "rustc";
- config.args = args.as_slice();
-
- let mut p = try!(Process::configure(config).to_result(|err|
- CLIError::new(format!("Could not start process: rustc {}", args.connect(" ")), Some(err.to_str()), 1)));
-
- let status = p.wait();
-
- if status != std::io::process::ExitStatus(0) {
- return Err(CLIError::new(format!("Non-zero status code from rustc {}", args.connect(" ")), None, 1));
- }
-
- Ok(None)
-}
-
-fn join(path: &Path, part: ~str) -> ~str {
- format!("{}", path.join(part).display())
-}
use std::fmt::{Show,Formatter};
use core::{NameVer,Package};
use core::source::Source;
-use core::manifest::Manifest;
use core::errors::{CargoResult,CargoCLIError,ToResult};
use cargo_read_manifest = ops::cargo_read_manifest::read_manifest;
fn list(&self) -> CargoResult<Vec<NameVer>> {
Ok(self.paths.iter().filter_map(|path| {
match read_manifest(path) {
- Ok(ref manifest) => Some(manifest.get_name_ver()),
+ Ok(ref pkg) => Some(pkg.get_summary().get_name_ver().clone()),
Err(_) => None
}
}).collect())
fn get(&self, _: &[NameVer]) -> CargoResult<Vec<Package>> {
Ok(self.paths.iter().filter_map(|path| {
match read_manifest(path) {
- Ok(ref manifest) => Some(Package::from_manifest(manifest)),
+ Ok(pkg) => Some(pkg),
Err(_) => None
}
}).collect())
}
}
-fn read_manifest(path: &Path) -> CargoResult<Manifest> {
+fn read_manifest(path: &Path) -> CargoResult<Package> {
let joined = path.join("Cargo.toml");
cargo_read_manifest(joined.as_str().unwrap()).to_result(|err| CargoCLIError(err))
}
fn setup() {
}
+// Currently doesn't pass due to the code being broken
test!(cargo_compile_with_explicit_manifest_path {
let p = project("foo")
.file("Cargo.toml", r#"