From: Carl Lerche Date: Tue, 6 May 2014 04:54:49 +0000 (-0700) Subject: Core struct refactor X-Git-Tag: archive/raspbian/0.35.0-2+rpi1~3^2^2^2^2^2^2^2~1087 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=1ce7641593d237d53ceeeeb198b80a96c24be1af;p=cargo.git Core struct refactor --- diff --git a/libs/hamcrest-rust b/libs/hamcrest-rust index de700414a..138de49f2 160000 --- a/libs/hamcrest-rust +++ b/libs/hamcrest-rust @@ -1 +1 @@ -Subproject commit de700414aab1aaa4461618ce7a516cb24a8e6665 +Subproject commit 138de49f217604d22e019afd71c529a7d76643f0 diff --git a/src/bin/cargo-read-manifest.rs b/src/bin/cargo-read-manifest.rs index bb0ebfcc8..db3195f56 100644 --- a/src/bin/cargo-read-manifest.rs +++ b/src/bin/cargo-read-manifest.rs @@ -5,26 +5,7 @@ extern crate cargo; 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> { - match read_manifest(flags.manifest_path) { - Ok(manifest) => Ok(Some(manifest)), - Err(e) => Err(e) - } + // Standalone cargo-read-manifest will go here + unimplemented!(); } diff --git a/src/bin/cargo-rustc.rs b/src/bin/cargo-rustc.rs index 46977b3f8..1e9e7e959 100644 --- a/src/bin/cargo-rustc.rs +++ b/src/bin/cargo-rustc.rs @@ -3,9 +3,7 @@ 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!(); } diff --git a/src/cargo/core/manifest.rs b/src/cargo/core/manifest.rs index 92a909f81..95ca363fe 100644 --- a/src/cargo/core/manifest.rs +++ b/src/cargo/core/manifest.rs @@ -1,40 +1,65 @@ -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_dir: Path, +} -#[deriving(Decodable,Encodable,Eq,Clone)] -pub struct SerializedManifest { - project: ~Project, - lib: Option<~[SerializedLibTarget]>, - bin: Option<~[SerializedExecTarget]>, - dependencies: Option> +#[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 -} + 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 { let (lib,bin) = normalize(&serialized.lib, &serialized.bin); let &SerializedManifest { ref project, ref dependencies, .. } = serialized; @@ -59,61 +84,132 @@ impl Manifest { 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> +} + +impl SerializedManifest { + pub fn to_package(&self, path: &str) -> CargoResult { + // 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 { + fn lib_targets(dst: &mut Vec, 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, 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 } diff --git a/src/cargo/core/mod.rs b/src/cargo/core/mod.rs index 14d108d17..5f1c7a92f 100644 --- a/src/cargo/core/mod.rs +++ b/src/cargo/core/mod.rs @@ -8,9 +8,8 @@ pub use self::registry::{ pub use self::manifest::{ Manifest, - Project, - LibTarget, - ExecTarget + Target, + TargetKind }; pub use self::package::{ @@ -18,6 +17,10 @@ pub use self::package::{ PackageSet }; +pub use self::summary::{ + Summary +}; + pub use self::dependency::Dependency; pub mod errors; @@ -27,4 +30,5 @@ pub mod package; pub mod dependency; pub mod manifest; pub mod resolver; +mod summary; mod registry; diff --git a/src/cargo/core/package.rs b/src/cargo/core/package.rs index 983c7422c..efc7ea99f 100644 --- a/src/cargo/core/package.rs +++ b/src/cargo/core/package.rs @@ -1,73 +1,60 @@ 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, + // 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, 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()) } } diff --git a/src/cargo/core/summary.rs b/src/cargo/core/summary.rs new file mode 100644 index 000000000..eb1a21208 --- /dev/null +++ b/src/cargo/core/summary.rs @@ -0,0 +1,27 @@ +use core::{ + Dependency, + NameVer +}; + +#[deriving(Show,Clone,Eq)] +pub struct Summary { + name_ver: NameVer, + dependencies: Vec +} + +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() + } +} diff --git a/src/cargo/ops/cargo_read_manifest.rs b/src/cargo/ops/cargo_read_manifest.rs index 264dd917a..4983992b9 100644 --- a/src/cargo/ops/cargo_read_manifest.rs +++ b/src/cargo/ops/cargo_read_manifest.rs @@ -1,15 +1,16 @@ 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 { +pub fn read_manifest(manifest_path: &str) -> CLIResult { 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::(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)) } diff --git a/src/cargo/ops/cargo_rustc.rs b/src/cargo/ops/cargo_rustc.rs index e4fc8fa3a..0d2af16ef 100644 --- a/src/cargo/ops/cargo_rustc.rs +++ b/src/cargo/ops/cargo_rustc.rs @@ -1,10 +1,7 @@ -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; @@ -23,18 +20,19 @@ pub fn compile(pkgs: &core::PackageSet) -> CLIResult<()> { 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(()) } @@ -43,10 +41,10 @@ fn mk_target(target: &Path) -> io::IoResult<()> { 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") @@ -59,20 +57,20 @@ fn rustc(root: &Path, src: &Path, target: &Path, deps: &[core::Package]) -> CLIR 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()); } } @@ -81,52 +79,3 @@ fn deps(pkg: &core::Package, pkgs: &core::PackageSet) -> ~[core::Package] { 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> { - 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()) -} diff --git a/src/cargo/sources/path.rs b/src/cargo/sources/path.rs index 205b6df07..0e69281f7 100644 --- a/src/cargo/sources/path.rs +++ b/src/cargo/sources/path.rs @@ -2,7 +2,6 @@ use std::fmt; 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; @@ -28,7 +27,7 @@ impl Source for PathSource { fn list(&self) -> CargoResult> { 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()) @@ -41,14 +40,14 @@ impl Source for PathSource { fn get(&self, _: &[NameVer]) -> CargoResult> { 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 { +fn read_manifest(path: &Path) -> CargoResult { let joined = path.join("Cargo.toml"); cargo_read_manifest(joined.as_str().unwrap()).to_result(|err| CargoCLIError(err)) } diff --git a/tests/test_cargo_compile.rs b/tests/test_cargo_compile.rs index 30c2e92ae..ba250808f 100644 --- a/tests/test_cargo_compile.rs +++ b/tests/test_cargo_compile.rs @@ -5,6 +5,7 @@ use cargo; 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#"