mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +00:00
More work on porting errors
This commit is contained in:
parent
48dc081419
commit
b3c2350325
@ -6,7 +6,7 @@ extern crate serialize;
|
||||
extern crate hammer;
|
||||
|
||||
use hammer::FlagConfig;
|
||||
use cargo::{execute_main_without_stdin,CLIResult};
|
||||
use cargo::{execute_main_without_stdin,CLIResult,CLIError};
|
||||
use cargo::core::Package;
|
||||
use cargo::ops::cargo_read_manifest::read_manifest;
|
||||
|
||||
@ -23,4 +23,9 @@ fn main() {
|
||||
|
||||
fn execute(options: Options) -> CLIResult<Option<Package>> {
|
||||
read_manifest(options.manifest_path.as_slice()).map(|m| Some(m))
|
||||
.map_err(|err| CLIError {
|
||||
msg: err.get_desc().to_owned(),
|
||||
detail: err.get_detail().map(|s| s.to_owned()),
|
||||
exit_code: 1
|
||||
})
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ use core::{
|
||||
Summary,
|
||||
Registry
|
||||
};
|
||||
use core::errors::CargoResult;
|
||||
use util::result::CargoResult;
|
||||
|
||||
/* TODO:
|
||||
* - The correct input here is not a registry. Resolves should be performable
|
||||
|
@ -1,5 +1,5 @@
|
||||
use core::{Summary,NameVer,Package};
|
||||
use core::errors::CargoResult;
|
||||
use util::CargoResult;
|
||||
|
||||
/**
|
||||
* A Source finds and downloads remote packages based on names and
|
||||
|
@ -36,10 +36,12 @@ pub trait SummaryVec {
|
||||
}
|
||||
|
||||
impl SummaryVec for Vec<Summary> {
|
||||
// TODO: Move to Registery
|
||||
fn names(&self) -> Vec<~str> {
|
||||
self.iter().map(|summary| summary.name_ver.get_name().to_owned()).collect()
|
||||
}
|
||||
|
||||
// TODO: Delete
|
||||
fn deps(&self) -> Vec<Dependency> {
|
||||
self.iter().map(|summary| Dependency::with_namever(summary.get_name_ver())).collect()
|
||||
}
|
||||
|
@ -16,42 +16,37 @@
|
||||
|
||||
use std::os;
|
||||
use util::config;
|
||||
use util::config::{all_configs,ConfigValue};
|
||||
use util::config::{ConfigValue};
|
||||
use core::{PackageSet,Source};
|
||||
use core::resolver::resolve;
|
||||
use sources::path::PathSource;
|
||||
use ops::cargo_rustc;
|
||||
use ops::cargo_read_manifest::read_manifest;
|
||||
use core::errors::{CargoError,CLIError,CLIResult,ToResult};
|
||||
// use core::errors::{CargoError,CLIError,CLIResult,ToResult};
|
||||
use core::summary::SummaryVec;
|
||||
use util::{other_error, CargoError, CargoResult, Wrap};
|
||||
|
||||
pub fn compile(manifest_path: &str) -> CLIResult<()> {
|
||||
pub fn compile(manifest_path: &str) -> CargoResult<()> {
|
||||
let root_dep = try!(read_manifest(manifest_path)).to_dependency();
|
||||
|
||||
let configs = try!(all_configs(os::getcwd()).to_result(|err: CargoError|
|
||||
CLIError::new("Could not load configurations", Some(err.to_str()), 1)));
|
||||
let configs = try!(config::all_configs(os::getcwd()));
|
||||
|
||||
let config_paths = configs.find(&("paths".to_owned())).map(|v| v.clone()).unwrap_or_else(|| ConfigValue::new());
|
||||
|
||||
let mut paths: Vec<Path> = match config_paths.get_value() {
|
||||
&config::String(_) => return Err(CLIError::new("The path was configured as a String instead of a List", None, 1)),
|
||||
&config::String(_) => return Err(other_error("The path was configured as a String instead of a List")),
|
||||
&config::List(ref list) => list.iter().map(|path| Path::new(path.as_slice())).collect()
|
||||
};
|
||||
|
||||
paths.push(Path::new(manifest_path).dir_path());
|
||||
|
||||
let source = PathSource::new(paths);
|
||||
let summaries = try!(source.list().to_result(|err|
|
||||
CLIError::new(format!("Unable to list packages from {}", source), Some(err.to_str()), 1)));
|
||||
let summaries = try!(source.list().wrap("unable to list packages from source"));
|
||||
let resolved = try!(resolve([root_dep], &summaries).wrap("unable to resolve dependencies"));
|
||||
|
||||
let resolved = try!(resolve([root_dep], &summaries).to_result(|err: CargoError|
|
||||
CLIError::new("Unable to resolve dependencies", Some(err.to_str()), 1)));
|
||||
try!(source.download(resolved.as_slice()).wrap("unable to download packages"));
|
||||
|
||||
try!(source.download(resolved.as_slice()).to_result(|err|
|
||||
CLIError::new(format!("Unable to download packages from {}", source), Some(err.to_str()), 1)));
|
||||
|
||||
let packages = try!(source.get(resolved.as_slice()).to_result(|err|
|
||||
CLIError::new(format!("Unable to get packages from {} for {}", source, summaries.names()), Some(err.to_str()), 1)));
|
||||
let packages = try!(source.get(resolved.as_slice()).wrap("unable ot get packages from source"));
|
||||
|
||||
let package_set = PackageSet::new(packages.as_slice());
|
||||
|
||||
|
@ -1,16 +1,24 @@
|
||||
use toml;
|
||||
use toml::from_toml;
|
||||
use core;
|
||||
use core::Package;
|
||||
use core::manifest::{TomlManifest};
|
||||
use core::errors::{CLIError,CLIResult,ToResult};
|
||||
use util::{other_error,CargoResult,CargoError};
|
||||
|
||||
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::<TomlManifest>(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)));
|
||||
|
||||
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))
|
||||
pub fn read_manifest(path: &str) -> CargoResult<Package> {
|
||||
let root = try!(parse_from_file(path));
|
||||
let toml = try!(load_toml(path, root));
|
||||
toml.to_package(path)
|
||||
}
|
||||
|
||||
fn parse_from_file(path: &str) -> CargoResult<toml::Value> {
|
||||
toml::parse_from_file(path.clone()).map_err(|err| to_cargo_err(path, err))
|
||||
}
|
||||
|
||||
fn load_toml(path: &str, root: toml::Value) -> CargoResult<TomlManifest> {
|
||||
from_toml::<TomlManifest>(root).map_err(|err| to_cargo_err(path, err))
|
||||
}
|
||||
|
||||
fn to_cargo_err(path: &str, err: toml::Error) -> CargoError {
|
||||
other_error("Cargo.toml is not valid Toml")
|
||||
.with_detail(format!("path={}; err={}", path, err.to_str()))
|
||||
}
|
||||
|
@ -4,13 +4,14 @@ use std::path::Path;
|
||||
use core::errors::{CLIError,CLIResult,ToResult};
|
||||
use core;
|
||||
use util;
|
||||
use util::{other_error,CargoResult,CargoError};
|
||||
|
||||
type Args = Vec<~str>;
|
||||
|
||||
pub fn compile(pkgs: &core::PackageSet) -> CLIResult<()> {
|
||||
pub fn compile(pkgs: &core::PackageSet) -> CargoResult<()> {
|
||||
let sorted = match pkgs.sort() {
|
||||
Some(pkgs) => pkgs,
|
||||
None => return Err(CLIError::new("Circular dependency detected", None, 1))
|
||||
None => return Err(other_error("circular dependency detected"))
|
||||
};
|
||||
|
||||
for pkg in sorted.iter() {
|
||||
@ -21,14 +22,13 @@ pub fn compile(pkgs: &core::PackageSet) -> CLIResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn compile_pkg(pkg: &core::Package, pkgs: &core::PackageSet) -> CLIResult<()> {
|
||||
fn compile_pkg(pkg: &core::Package, pkgs: &core::PackageSet) -> CargoResult<()> {
|
||||
// Build up the destination
|
||||
// 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_dir).to_result(|err|
|
||||
CLIError::new(format!("Could not create the target directory {}", target_dir.display()), Some(err.to_str()), 1)));
|
||||
try!(mk_target(&target_dir).map_err(|err| other_error("could not create target directory")));
|
||||
|
||||
// compile
|
||||
for target in pkg.get_targets().iter() {
|
||||
@ -42,7 +42,7 @@ fn mk_target(target: &Path) -> io::IoResult<()> {
|
||||
io::fs::mkdir_recursive(target, io::UserRWX)
|
||||
}
|
||||
|
||||
fn rustc(root: &Path, target: &core::Target, dest: &Path, deps: &[core::Package]) -> CLIResult<()> {
|
||||
fn rustc(root: &Path, target: &core::Target, dest: &Path, deps: &[core::Package]) -> CargoResult<()> {
|
||||
let mut args = Vec::new();
|
||||
|
||||
build_base_args(&mut args, target, dest);
|
||||
@ -52,8 +52,7 @@ fn rustc(root: &Path, target: &core::Target, dest: &Path, deps: &[core::Package]
|
||||
.cwd(root.clone())
|
||||
.args(args.as_slice())
|
||||
.exec()
|
||||
.to_result(|err|
|
||||
CLIError::new(format!("Couldn't execute `rustc {}` in `{}`", args.connect(" "), root.display()), Some(err.to_str()), 1)));
|
||||
.map_err(|err| rustc_to_cargo_err(&args, root, err)));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -74,3 +73,8 @@ fn build_deps_args(dst: &mut Args, deps: &[core::Package]) {
|
||||
dst.push(dir.as_str().unwrap().to_owned());
|
||||
}
|
||||
}
|
||||
|
||||
fn rustc_to_cargo_err(args: &Vec<~str>, cwd: &Path, err: io::IoError) -> CargoError {
|
||||
other_error("failed to exec rustc")
|
||||
.with_detail(format!("args={}; root={}; cause={}", args.connect(" "), cwd.display(), err.to_str()))
|
||||
}
|
||||
|
@ -2,8 +2,8 @@ use std::fmt;
|
||||
use std::fmt::{Show,Formatter};
|
||||
use core::{NameVer,Package,Summary};
|
||||
use core::source::Source;
|
||||
use core::errors::{CargoResult,CargoCLIError,ToResult};
|
||||
use cargo_read_manifest = ops::cargo_read_manifest::read_manifest;
|
||||
use util::{CargoResult};
|
||||
|
||||
pub struct PathSource {
|
||||
paths: Vec<Path>
|
||||
@ -49,5 +49,5 @@ impl Source for PathSource {
|
||||
|
||||
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))
|
||||
cargo_read_manifest(joined.as_str().unwrap())
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
extern crate collections;
|
||||
extern crate serialize;
|
||||
extern crate toml;
|
||||
|
||||
use core::errors::{CargoResult,CargoError,ToResult};
|
||||
use serialize::{Encodable,Encoder};
|
||||
use std::{io,fmt};
|
||||
use collections::HashMap;
|
||||
use serialize::{Encodable,Encoder};
|
||||
use toml;
|
||||
use util::{other_error,CargoResult,Require};
|
||||
|
||||
#[deriving(Eq,TotalEq,Clone,Encodable,Decodable)]
|
||||
pub enum Location {
|
||||
@ -76,12 +74,12 @@ impl fmt::Show for ConfigValue {
|
||||
}
|
||||
|
||||
pub fn get_config(pwd: Path, key: &str) -> CargoResult<ConfigValue> {
|
||||
find_in_tree(&pwd, |file| extract_config(file, key)).to_result(|_|
|
||||
CargoError::described(format!("Config key not found: {}", key)))
|
||||
find_in_tree(&pwd, |file| extract_config(file, key))
|
||||
.map_err(|_| other_error("config key not found").with_detail(format!("key={}", key)))
|
||||
}
|
||||
|
||||
pub fn all_configs(pwd: Path) -> CargoResult<collections::HashMap<~str, ConfigValue>> {
|
||||
let mut map = collections::HashMap::new();
|
||||
pub fn all_configs(pwd: Path) -> CargoResult<HashMap<~str, ConfigValue>> {
|
||||
let mut map = HashMap::new();
|
||||
|
||||
try!(walk_tree(&pwd, |file| {
|
||||
extract_all_configs(file, &mut map)
|
||||
@ -101,7 +99,7 @@ fn find_in_tree<T>(pwd: &Path, walk: |io::fs::File| -> CargoResult<T>) -> CargoR
|
||||
loop {
|
||||
let possible = current.join(".cargo").join("config");
|
||||
if possible.exists() {
|
||||
let file = try!(io::fs::File::open(&possible).to_result(|_| CargoError::other()));
|
||||
let file = try!(io::fs::File::open(&possible).map_err(|_| other_error("could not open file")));
|
||||
match walk(file) {
|
||||
Ok(res) => return Ok(res),
|
||||
_ => ()
|
||||
@ -111,7 +109,7 @@ fn find_in_tree<T>(pwd: &Path, walk: |io::fs::File| -> CargoResult<T>) -> CargoR
|
||||
if !current.pop() { break; }
|
||||
}
|
||||
|
||||
Err(CargoError::other())
|
||||
Err(other_error(""))
|
||||
}
|
||||
|
||||
fn walk_tree(pwd: &Path, walk: |io::fs::File| -> CargoResult<()>) -> CargoResult<()> {
|
||||
@ -121,14 +119,14 @@ fn walk_tree(pwd: &Path, walk: |io::fs::File| -> CargoResult<()>) -> CargoResult
|
||||
loop {
|
||||
let possible = current.join(".cargo").join("config");
|
||||
if possible.exists() {
|
||||
let file = try!(io::fs::File::open(&possible).to_result(|_| CargoError::other()));
|
||||
let file = try!(io::fs::File::open(&possible).map_err(|_| other_error("could not open file")));
|
||||
match walk(file) {
|
||||
Err(_) => err = false,
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
||||
if err { return Err(CargoError::other()); }
|
||||
if err { return Err(other_error("")); }
|
||||
if !current.pop() { break; }
|
||||
}
|
||||
|
||||
@ -138,26 +136,26 @@ fn walk_tree(pwd: &Path, walk: |io::fs::File| -> CargoResult<()>) -> CargoResult
|
||||
fn extract_config(file: io::fs::File, key: &str) -> CargoResult<ConfigValue> {
|
||||
let path = file.path().clone();
|
||||
let mut buf = io::BufferedReader::new(file);
|
||||
let root = try!(toml::parse_from_buffer(&mut buf).to_result(|_| CargoError::other()));
|
||||
let val = try!(root.lookup(key).to_result(|_| CargoError::other()));
|
||||
let root = try!(toml::parse_from_buffer(&mut buf).map_err(|_| other_error("")));
|
||||
let val = try!(root.lookup(key).require(other_error("")));
|
||||
|
||||
let v = match val {
|
||||
&toml::String(ref val) => String(val.to_owned()),
|
||||
&toml::Array(ref val) => List(val.iter().map(|s: &toml::Value| s.to_str()).collect()),
|
||||
_ => return Err(CargoError::other())
|
||||
_ => return Err(other_error(""))
|
||||
};
|
||||
|
||||
Ok(ConfigValue{ value: v, path: vec!(path) })
|
||||
}
|
||||
|
||||
fn extract_all_configs(file: io::fs::File, map: &mut collections::HashMap<~str, ConfigValue>) -> CargoResult<()> {
|
||||
fn extract_all_configs(file: io::fs::File, map: &mut HashMap<~str, ConfigValue>) -> CargoResult<()> {
|
||||
let path = file.path().clone();
|
||||
let mut buf = io::BufferedReader::new(file);
|
||||
let root = try!(toml::parse_from_buffer(&mut buf).to_result(|err|
|
||||
CargoError::described(format!("Couldn't parse Toml manifest `{}`: {}", path.display(), err))));
|
||||
let root = try!(toml::parse_from_buffer(&mut buf).map_err(|err|
|
||||
other_error("could not parse Toml manifest").with_detail(format!("path={}; err={}", path.display(), err.to_str()))));
|
||||
|
||||
let table = try!(root.get_table().to_result(|err|
|
||||
CargoError::described(format!("Couldn't parse Toml manifest `{}`: {}", path.display(), err))));
|
||||
let table = try!(root.get_table()
|
||||
.require(other_error("could not parse Toml manifest").with_detail(format!("path={}", path.display()))));
|
||||
|
||||
for (key, value) in table.iter() {
|
||||
match value {
|
||||
@ -167,8 +165,8 @@ fn extract_all_configs(file: io::fs::File, map: &mut collections::HashMap<~str,
|
||||
ConfigValue { path: vec!(), value: List(vec!()) }
|
||||
});
|
||||
|
||||
try!(merge_array(config, val.as_slice(), &path).to_result(|err|
|
||||
CargoError::described(format!("The `{}` key in your config {}", key, err))));
|
||||
try!(merge_array(config, val.as_slice(), &path).map_err(|err|
|
||||
other_error("missing").with_detail(format!("The `{}` key in your config {}", key, err))));
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
@ -179,11 +177,11 @@ fn extract_all_configs(file: io::fs::File, map: &mut collections::HashMap<~str,
|
||||
|
||||
fn merge_array(existing: &mut ConfigValue, val: &[toml::Value], path: &Path) -> CargoResult<()> {
|
||||
match existing.value {
|
||||
String(_) => return Err(CargoError::described("should be an Array, but it was a String")),
|
||||
String(_) => return Err(other_error("should be an Array, but it was a String")),
|
||||
List(ref mut list) => {
|
||||
let new_list: Vec<CargoResult<~str>> = val.iter().map(|s: &toml::Value| toml_string(s)).collect();
|
||||
if new_list.iter().any(|v| v.is_err()) {
|
||||
return Err(CargoError::described("should be an Array of Strings, but was an Array of other values"));
|
||||
return Err(other_error("should be an Array of Strings, but was an Array of other values"));
|
||||
} else {
|
||||
let new_list: Vec<~str> = new_list.move_iter().map(|v| v.unwrap()).collect();
|
||||
list.push_all(new_list.as_slice());
|
||||
@ -197,6 +195,6 @@ fn merge_array(existing: &mut ConfigValue, val: &[toml::Value], path: &Path) ->
|
||||
fn toml_string(val: &toml::Value) -> CargoResult<~str> {
|
||||
match val {
|
||||
&toml::String(ref str) => Ok(str.to_owned()),
|
||||
_ => Err(CargoError::other())
|
||||
_ => Err(other_error(""))
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
pub use self::process_builder::{process,ProcessBuilder};
|
||||
pub use self::result::{CargoError,CargoResult,Wrap,Require,other_error};
|
||||
|
||||
pub mod graph;
|
||||
pub mod process_builder;
|
||||
pub mod config;
|
||||
|
@ -2,14 +2,39 @@ use std::io;
|
||||
|
||||
pub type CargoResult<T> = Result<T, CargoError>;
|
||||
|
||||
#[deriving(Show)]
|
||||
pub fn other_error(desc: &'static str) -> CargoError {
|
||||
CargoError {
|
||||
kind: OtherCargoError,
|
||||
desc: desc,
|
||||
detail: None,
|
||||
cause: None
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Show,Clone)]
|
||||
pub struct CargoError {
|
||||
kind: CargoErrorKind,
|
||||
desc: &'static str,
|
||||
detail: Option<~str>
|
||||
detail: Option<~str>,
|
||||
cause: Option<Box<CargoError>>
|
||||
}
|
||||
|
||||
#[deriving(Show)]
|
||||
impl CargoError {
|
||||
pub fn get_desc(&self) -> &'static str {
|
||||
self.desc
|
||||
}
|
||||
|
||||
pub fn get_detail<'a>(&'a self) -> Option<&'a str> {
|
||||
self.detail.as_ref().map(|s| s.as_slice())
|
||||
}
|
||||
|
||||
pub fn with_detail(mut self, detail: ~str) -> CargoError {
|
||||
self.detail = Some(detail);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Show,Clone)]
|
||||
pub enum CargoErrorKind {
|
||||
InternalError,
|
||||
IoError(io::IoError),
|
||||
@ -18,7 +43,7 @@ pub enum CargoErrorKind {
|
||||
|
||||
type CargoCliResult<T> = Result<T, CargoCliError>;
|
||||
|
||||
#[deriving(Show)]
|
||||
#[deriving(Show,Clone)]
|
||||
pub struct CargoCliError {
|
||||
kind: CargoCliErrorKind,
|
||||
exit_status: uint,
|
||||
@ -27,7 +52,30 @@ pub struct CargoCliError {
|
||||
cause: Option<CargoError>
|
||||
}
|
||||
|
||||
#[deriving(Show)]
|
||||
#[deriving(Show,Clone)]
|
||||
pub enum CargoCliErrorKind {
|
||||
OtherCargoCliError
|
||||
}
|
||||
|
||||
pub trait Wrap {
|
||||
fn wrap(self, desc: &'static str) -> Self;
|
||||
}
|
||||
|
||||
impl<T> Wrap for Result<T, CargoError> {
|
||||
fn wrap(self, desc: &'static str) -> Result<T, CargoError> {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Require<T> {
|
||||
fn require(self, err: CargoError) -> CargoResult<T>;
|
||||
}
|
||||
|
||||
impl<T> Require<T> for Option<T> {
|
||||
fn require(self, err: CargoError) -> CargoResult<T> {
|
||||
match self {
|
||||
Some(x) => Ok(x),
|
||||
None => Err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user