extern crate serialize;
use cargo::ops::cargo_compile::compile;
-use cargo::{CargoResult,ToCargoError};
+use cargo::core::errors::{CLIResult,CLIError,ToResult};
use hammer::{FlagDecoder,FlagConfig,HammerError};
use serialize::Decodable;
impl FlagConfig for Options {}
-fn flags<T: FlagConfig + Decodable<FlagDecoder, HammerError>>() -> CargoResult<T> {
+fn flags<T: FlagConfig + Decodable<FlagDecoder, HammerError>>() -> CLIResult<T> {
let mut decoder = FlagDecoder::new::<T>(std::os::args().tail());
- Decodable::decode(&mut decoder).to_cargo_error(|e: HammerError| e.message, 1)
+ Decodable::decode(&mut decoder).to_result(|e: HammerError| CLIError::new(e.message, None, 1))
}
-fn execute() -> CargoResult<()> {
- compile(try!(flags::<Options>()).manifest_path.as_slice())
+fn execute() -> CLIResult<()> {
+ compile(try!(flags::<Options>()).manifest_path.as_slice()).to_result(|_|
+ CLIError::new("Compilation failed", None, 1))
}
fn main() {
match execute() {
- Err(io_error) => fail!("{}", io_error),
+ Err(err) => fail!("{}", err),
Ok(_) => return
}
}
extern crate serialize;
extern crate hammer;
-use cargo::{CargoResult,execute_main_without_stdin};
+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)]
execute_main_without_stdin(execute);
}
-fn execute(flags: ReadManifestFlags) -> CargoResult<Option<Manifest>> {
+fn execute(flags: ReadManifestFlags) -> CLIResult<Option<Manifest>> {
match read_manifest(flags.manifest_path) {
Ok(manifest) => Ok(Some(manifest)),
Err(e) => Err(e)
use hammer::{FlagConfig,FlagConfiguration};
use std::os;
use serialize::Encodable;
-use cargo::{CargoResult,ToCargoError,NoFlags,execute_main_without_stdin,handle_error};
+use cargo::{NoFlags,execute_main_without_stdin,handle_error};
+use cargo::core::errors::{CLIError,CLIResult,ToResult};
use cargo::util::important_paths::find_project;
use cargo::util::config;
else if cmd == "locate-project".to_owned() { execute_main_without_stdin(locate_project) }
}
-fn process(mut args: ~[~str]) -> CargoResult<(~str, ~[~str])> {
+fn process(mut args: ~[~str]) -> CLIResult<(~str, ~[~str])> {
args = args.tail().to_owned();
- let head = try!(args.head().to_cargo_error("No subcommand found".to_owned(), 1)).to_owned();
+ let head = try!(args.head().to_result(|_| CLIError::new("No subcommand found", None, 1))).to_owned();
let tail = args.tail().to_owned();
Ok((head, tail))
}
}
-fn config_for_key(args: ConfigForKeyFlags) -> CargoResult<Option<ConfigOut>> {
- let value = try!(config::get_config(os::getcwd(), args.key.as_slice()));
+fn config_for_key(args: ConfigForKeyFlags) -> CLIResult<Option<ConfigOut>> {
+ let value = try!(config::get_config(os::getcwd(), args.key.as_slice()).to_result(|err|
+ CLIError::new("Couldn't load configuration", Some(err.to_str()), 1)));
if args.human {
println!("{}", value);
}
}
-fn config_list(args: ConfigListFlags) -> CargoResult<Option<ConfigOut>> {
- let configs = try!(config::all_configs(os::getcwd()));
+fn config_list(args: ConfigListFlags) -> CLIResult<Option<ConfigOut>> {
+ let configs = try!(config::all_configs(os::getcwd()).to_result(|err|
+ CLIError::new("Couldn't load conifguration", Some(err.to_str()), 1)));
if args.human {
for (key, value) in configs.iter() {
}
}
-fn locate_project(_: NoFlags) -> CargoResult<Option<ProjectLocation>> {
- let root = try!(find_project(os::getcwd(), "Cargo.toml".to_owned()));
- let string = try!(root.as_str().to_cargo_error(format!("Your project path contains characters not representable in Unicode: {}", os::getcwd().display()), 1));
+fn locate_project(_: NoFlags) -> CLIResult<Option<ProjectLocation>> {
+ let root = try!(find_project(os::getcwd(), "Cargo.toml".to_owned()).to_result(|err|
+ CLIError::new(err.to_str(), None, 1)));
+
+ let string = try!(root.as_str().to_result(|_|
+ CLIError::new(format!("Your project path contains characters not representable in Unicode: {}", os::getcwd().display()), None, 1)));
+
Ok(Some(ProjectLocation { root: string.to_owned() }))
}
--- /dev/null
+use std::fmt;
+use std::fmt::{Show,Formatter};
+use std::io::IoError;
+
+/**
+ * There are two kinds of errors returned by Cargo functions:
+ *
+ * * CargoCLIError, which represents a failure that can be directly presented
+ * to the user.
+ * * CargoInternalError, which represents an internal failure that must be
+ * converted into a CargoCLIError before it may be presented to the user.
+ *
+ * These two kinds of errors are wrapped up in a `CargoError` enum.
+ *
+ * Cargo functions must first convert all other kinds of errors (such as
+ * IoError) into one of the Cargo errors before returning.
+ *
+ * This module includes several convenience functions for working with these
+ * different kinds of errors:
+ *
+ * `to_result::<E1, E2>(|E1| -> E2) -> E2` converts any kind of error into
+ * another kind of error. It can be used together with `try!`, as in:
+ *
+ * try!(mkdir(path).to_result(|err| {
+ * let msg = format!("Couldn't make directory {}", path.display());
+ * CargoError::cli(msg, 12)
+ * })
+ *
+ * `to_result::<Option<T>, E>(|| -> E) -> E` converts a `None` value into
+ * another kind of error. It can also be used together with `try!`:
+ *
+ * try!(from_str(val).to_result(|| {
+ * CargoError::internal(StringConversionError(val))
+ * })
+ */
+
+pub type CargoResult<T> = Result<T, CargoError>;
+pub type CLIResult<T> = Result<T, CLIError>;
+
+pub enum CargoError {
+ CargoInternalError(InternalError),
+ CargoCLIError(CLIError)
+}
+
+impl Show for CargoError {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ match self {
+ &CargoInternalError(ref err) => write!(f.buf, "{}", err),
+ &CargoCLIError(ref err) => write!(f.buf, "{}", err)
+ }
+ }
+}
+
+pub struct CLIError {
+ pub msg: ~str,
+ pub detail: Option<~str>,
+ pub exit_code: uint
+}
+
+impl CLIError {
+ pub fn new<T: ToStr>(msg: T, detail: Option<~str>, exit_code: uint) -> CLIError {
+ CLIError { msg: msg.to_str(), detail: detail, exit_code: exit_code }
+ }
+}
+
+impl Show for CLIError {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(f.buf, "{}", self.msg)
+ }
+}
+
+pub enum InternalError {
+ StringConversionError(~str, &'static str),
+ MissingManifest(Path, ~str),
+ WrappedIoError(IoError),
+ PathError(~str),
+ Described(~str),
+ Other
+}
+
+impl Show for InternalError {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ match self {
+ &StringConversionError(ref string, ref type_name) => {
+ write!(f.buf, "Couldn't convert `{}` into {}", string, type_name)
+ },
+ &MissingManifest(ref path, ref file) => {
+ write!(f.buf, "Couldn't find a {} in the project (`{}` or any parent directory", file, path.display())
+ },
+ &WrappedIoError(ref io_error) => {
+ write!(f.buf, "{}", io_error)
+ },
+ &PathError(ref s) | &Described(ref s) => {
+ write!(f.buf, "{}", s)
+ },
+ &Other => write!(f.buf, "Other internal error")
+ }
+ }
+}
+
+impl CargoError {
+ pub fn cli(msg: ~str, detail: Option<~str>, exit_code: uint) -> CargoError {
+ CargoCLIError(CLIError::new(msg, detail, exit_code))
+ }
+
+ pub fn internal(error: InternalError) -> CargoError {
+ CargoInternalError(error)
+ }
+
+ pub fn cli_error(self) -> CLIError {
+ match self {
+ CargoInternalError(err) =>
+ CLIError::new("An unexpected error occurred", Some(err.to_str()), 100),
+ CargoCLIError(err) => err
+ }
+ }
+}
+
+pub trait ToResult<T,E1,E2> {
+ fn to_result(self, callback: |E1| -> E2) -> Result<T,E2>;
+}
+
+impl<T,E1,E2> ToResult<T,E1,E2> for Result<T,E1> {
+ fn to_result(self, callback: |E1| -> E2) -> Result<T,E2> {
+ match self {
+ Ok(val) => Ok(val),
+ Err(e) => Err(callback(e))
+ }
+ }
+}
+
+impl<T,E> ToResult<T,Option<T>,E> for Option<T> {
+ fn to_result(self, callback: |Option<T>| -> E) -> Result<T,E> {
+ match self {
+ Some(val) => Ok(val),
+ None => Err(callback(self))
+ }
+ }
+}
use core::NameVer;
use core::dependency::Dependency;
use collections::HashMap;
-use {CargoResult,ToCargoError};
+use core::errors::{CargoResult,CargoError,ToResult,PathError};
/*
* TODO: Make all struct fields private
}).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)))));
+
Ok(Manifest {
- root: try!(Path::new(path.to_owned()).dirname_str().to_cargo_error(format!("Could not get dirname from {}", path), 1)).to_owned(),
+ root: root.to_owned(),
project: project.clone(),
lib: lib,
bin: bin,
pub use self::dependency::Dependency;
+pub mod errors;
pub mod namever;
pub mod source;
pub mod package;
use collections::HashMap;
use core;
use core::package::PackageSet;
-use {CargoResult};
+use core::errors::CargoResult;
#[allow(dead_code)]
pub fn resolve(deps: &[core::Dependency], registry: &core::Registry) -> CargoResult<PackageSet> {
use core::{NameVer,Package};
-use CargoResult;
+use core::errors::CargoResult;
+use std::fmt::Show;
/**
* A Source finds and downloads remote packages based on names and
* versions.
*/
-pub trait Source {
+pub trait Source : Show {
/**
* The update method performs any network operations required to
* get the entire list of all names, versions and dependencies of
use serialize::{Decoder,Encoder,Decodable,Encodable,json};
use std::io;
-use std::fmt;
-use std::fmt::{Show,Formatter};
use hammer::{FlagDecoder,FlagConfig,HammerError};
+pub use core::errors::{CLIError,CLIResult,ToResult};
macro_rules! some(
($e:expr) => (
pub mod sources;
pub mod util;
-
-pub type CargoResult<T> = Result<T, CargoError>;
-
-pub struct CargoError {
- message: ~str,
- exit_code: uint
-}
-
-impl CargoError {
- pub fn new(message: ~str, exit_code: uint) -> CargoError {
- CargoError { message: message, exit_code: exit_code }
- }
-}
-
-impl Show for CargoError {
- fn fmt(&self, f: &mut Formatter) -> fmt::Result {
- write!(f.buf, "{}", self.message)
- }
-}
-
-pub trait ToCargoErrorMessage<E> {
- fn to_cargo_error_message(self, error: E) -> ~str;
-}
-
-impl<E> ToCargoErrorMessage<E> for ~str {
- fn to_cargo_error_message(self, _: E) -> ~str {
- self
- }
-}
-
-impl<'a, E> ToCargoErrorMessage<E> for |E|:'a -> ~str {
- fn to_cargo_error_message(self, err: E) -> ~str {
- self(err)
- }
-}
-
-pub trait ToCargoError<T, E> {
- fn to_cargo_error<M: ToCargoErrorMessage<E>>(self, to_message: M, exit_code: uint) -> Result<T, CargoError>;
-}
-
-impl<T,E> ToCargoError<T, E> for Result<T,E> {
- fn to_cargo_error<M: ToCargoErrorMessage<E>>(self, to_message: M, exit_code: uint) -> Result<T, CargoError> {
- match self {
- Err(err) => Err(CargoError{ message: to_message.to_cargo_error_message(err), exit_code: exit_code }),
- Ok(val) => Ok(val)
- }
- }
-}
-
-impl<T> ToCargoError<T, Option<T>> for Option<T> {
- fn to_cargo_error<M: ToCargoErrorMessage<Option<T>>>(self, to_message: M, exit_code: uint) -> Result<T, CargoError> {
- match self {
- None => Err(CargoError{ message: to_message.to_cargo_error_message(None), exit_code: exit_code }),
- Some(val) => Ok(val)
- }
- }
-}
-
trait RepresentsFlags : FlagConfig + Decodable<FlagDecoder, HammerError> {}
impl<T: FlagConfig + Decodable<FlagDecoder, HammerError>> RepresentsFlags for T {}
impl FlagConfig for NoFlags {}
-pub fn execute_main<'a, T: RepresentsFlags, U: RepresentsJSON, V: Encodable<json::Encoder<'a>, io::IoError>>(exec: fn(T, U) -> CargoResult<Option<V>>) {
- fn call<'a, T: RepresentsFlags, U: RepresentsJSON, V: Encodable<json::Encoder<'a>, io::IoError>>(exec: fn(T, U) -> CargoResult<Option<V>>) -> CargoResult<Option<V>> {
+pub fn execute_main<'a, T: RepresentsFlags, U: RepresentsJSON, V: Encodable<json::Encoder<'a>, io::IoError>>(exec: fn(T, U) -> CLIResult<Option<V>>) {
+ fn call<'a, T: RepresentsFlags, U: RepresentsJSON, V: Encodable<json::Encoder<'a>, io::IoError>>(exec: fn(T, U) -> CLIResult<Option<V>>) -> CLIResult<Option<V>> {
let flags = try!(flags_from_args::<T>());
let json = try!(json_from_stdin::<U>());
process_executed(call(exec))
}
-pub fn execute_main_without_stdin<'a, T: RepresentsFlags, V: Encodable<json::Encoder<'a>, io::IoError>>(exec: fn(T) -> CargoResult<Option<V>>) {
- fn call<'a, T: RepresentsFlags, V: Encodable<json::Encoder<'a>, io::IoError>>(exec: fn(T) -> CargoResult<Option<V>>) -> CargoResult<Option<V>> {
+pub fn execute_main_without_stdin<'a, T: RepresentsFlags, V: Encodable<json::Encoder<'a>, io::IoError>>(exec: fn(T) -> CLIResult<Option<V>>) {
+ fn call<'a, T: RepresentsFlags, V: Encodable<json::Encoder<'a>, io::IoError>>(exec: fn(T) -> CLIResult<Option<V>>) -> CLIResult<Option<V>> {
let flags = try!(flags_from_args::<T>());
exec(flags)
process_executed(call(exec))
}
-pub fn process_executed<'a, T: Encodable<json::Encoder<'a>, io::IoError>>(result: CargoResult<Option<T>>) {
+pub fn process_executed<'a, T: Encodable<json::Encoder<'a>, io::IoError>>(result: CLIResult<Option<T>>) {
match result {
Err(e) => handle_error(e),
Ok(encodable) => {
}
}
-pub fn handle_error(err: CargoError) {
- let _ = write!(&mut std::io::stderr(), "{}", err.message);
+pub fn handle_error(err: CLIError) {
+ let _ = write!(&mut std::io::stderr(), "{}", err.msg);
std::os::set_exit_status(err.exit_code as int);
}
-fn flags_from_args<T: RepresentsFlags>() -> CargoResult<T> {
+fn flags_from_args<T: RepresentsFlags>() -> CLIResult<T> {
let mut decoder = FlagDecoder::new::<T>(std::os::args().tail());
- Decodable::decode(&mut decoder).to_cargo_error(|e: HammerError| e.message, 1)
+ Decodable::decode(&mut decoder).to_result(|e: HammerError| CLIError::new(e.message, None, 1))
}
-fn json_from_stdin<T: RepresentsJSON>() -> CargoResult<T> {
+fn json_from_stdin<T: RepresentsJSON>() -> CLIResult<T> {
let mut reader = io::stdin();
- let input = try!(reader.read_to_str().to_cargo_error("Cannot read stdin to a string".to_owned(), 1));
+ let input = try!(reader.read_to_str().to_result(|_| CLIError::new("Standard in did not exist or was not UTF-8", None, 1)));
- let json = try!(json::from_str(input).to_cargo_error(format!("Cannot parse json: {}", input), 1));
+ let json = try!(json::from_str(input).to_result(|_| CLIError::new("Could not parse standard in as JSON", Some(input.clone()), 1)));
let mut decoder = json::Decoder::new(json);
- Decodable::decode(&mut decoder).to_cargo_error(|e: json::DecoderError| format!("{}", e), 1)
+ Decodable::decode(&mut decoder).to_result(|e: json::DecoderError| CLIError::new("Could not process standard in as input", Some(e.to_str()), 1))
}
use core::dependency::Dependency;
use sources::path::PathSource;
use ops::cargo_rustc;
-use {CargoError,CargoResult};
+use core::errors::{CargoError,CLIError,CLIResult,ToResult};
+
+pub fn compile(manifest_path: &str) -> CLIResult<()> {
+ let configs = try!(all_configs(os::getcwd()).to_result(|err: CargoError|
+ CLIError::new("Could not load configurations", Some(err.to_str()), 1)));
-pub fn compile(manifest_path: &str) -> CargoResult<()> {
- let configs = try!(all_configs(os::getcwd()));
let config_paths = configs.find(&("paths".to_owned())).map(|v| v.clone()).unwrap_or_else(|| ConfigValue::new());
let paths = match config_paths.get_value() {
- &config::String(_) => return Err(CargoError::new("The path was configured as a String instead of a List".to_owned(), 1)),
+ &config::String(_) => return Err(CLIError::new("The path was configured as a String instead of a List", None, 1)),
&config::List(ref list) => list.iter().map(|path| Path::new(path.as_slice())).collect()
};
let source = PathSource::new(paths);
- let names = try!(source.list());
- try!(source.download(names.as_slice()));
+ let names = try!(source.list().to_result(|err| CLIError::new(format!("Unable to list packages from {}", source), Some(err.to_str()), 1)));
+ try!(source.download(names.as_slice()).to_result(|err| CLIError::new(format!("Unable to download packages from {}", source), Some(err.to_str()), 1)));
let deps: Vec<Dependency> = names.iter().map(|namever| {
Dependency::with_namever(namever)
}).collect();
- let packages = try!(source.get(names.as_slice()));
+ let packages = try!(source.get(names.as_slice()).to_result(|err|
+ CLIError::new(format!("Unable to get packages from {} for {}", source, names), Some(err.to_str()), 1)));
+
let registry = PackageSet::new(packages.as_slice());
- let resolved = try!(resolve(deps.as_slice(), ®istry));
+ let resolved = try!(resolve(deps.as_slice(), ®istry).to_result(|err: CargoError|
+ CLIError::new("Unable to resolve dependencies", Some(err.to_str()), 1)));
try!(cargo_rustc::compile(&resolved));
use toml;
use toml::from_toml;
use core::manifest::{SerializedManifest,Manifest};
-use {CargoResult,ToCargoError};
+use core::errors::{CLIError,CLIResult,ToResult};
-pub fn read_manifest(manifest_path: &str) -> CargoResult<Manifest> {
- let root = try!(toml::parse_from_file(manifest_path.clone()).to_cargo_error(format!("Couldn't parse Toml file: {}", manifest_path), 1));
- let toml_manifest = try!(from_toml::<SerializedManifest>(root.clone()).to_cargo_error(|e: toml::Error| format!("Couldn't parse Toml file: {:?}", e), 1));
+pub fn read_manifest(manifest_path: &str) -> CLIResult<Manifest> {
+ 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)));
- Manifest::from_serialized(manifest_path.as_slice(), &toml_manifest)
+ 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|
+ CLIError::new(format!("Cargo.toml was not in the right format: {}", manifest_path), Some(err.to_str()), 1))
}
use std::io;
use std::io::process::{Process,ProcessConfig,InheritFd};
use std::path::Path;
-use {CargoResult,CargoError,ToCargoError,NoFlags};
+use core::errors::{CLIError,CLIResult,ToResult};
+use NoFlags;
use core;
use util;
type Args = Vec<~str>;
-pub fn compile(pkgs: &core::PackageSet) -> CargoResult<()> {
+pub fn compile(pkgs: &core::PackageSet) -> CLIResult<()> {
let sorted = match pkgs.sort() {
Some(pkgs) => pkgs,
- None => return Err(CargoError::new("Circular dependency detected".to_owned(), 1))
+ None => return Err(CLIError::new("Circular dependency detected", None, 1))
};
for pkg in sorted.iter() {
}
-fn compile_pkg(pkg: &core::Package, pkgs: &core::PackageSet) -> CargoResult<()> {
+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()));
// First ensure that the directory exists
- try!(mk_target(&target).to_cargo_error(format!("Could not create the target directory {}", target.display()), 1));
+ try!(mk_target(&target).to_result(|err|
+ CLIError::new(format!("Could not create the target directory {}", target.display()), Some(err.to_str()), 1)));
// compile
try!(rustc(pkg.get_root(), &src, &target, deps(pkg, pkgs)));
io::fs::mkdir_recursive(target, io::UserRWX)
}
-fn rustc(root: &Path, src: &Path, target: &Path, deps: &[core::Package]) -> CargoResult<()> {
+fn rustc(root: &Path, src: &Path, target: &Path, deps: &[core::Package]) -> CLIResult<()> {
let mut args = Vec::new();
build_base_args(&mut args, src, target);
try!(util::process("rustc")
.cwd(root.clone())
.args(args.as_slice())
- .exec().to_cargo_error(format!("Couldn't execute rustc {}", args.connect(" ")), 1));
+ .exec()
+ .to_result(|err|
+ CLIError::new(format!("Couldn't execute rustc {}", args.connect(" ")), Some(err.to_str()), 1)));
Ok(())
}
pkgs.get_all(names).iter().map(|p| (*p).clone()).collect()
}
-pub fn execute(_: NoFlags, manifest: core::Manifest) -> CargoResult<Option<core::Manifest>> {
+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 {
} else if bin.len() > 0 {
( "bin".to_owned(), bin[0].path )
} else {
- return Err(CargoError::new("bad manifest, no lib or bin specified".to_owned(), 1));
+ return Err(CLIError::new("bad manifest, no lib or bin specified", None, 1));
};
let root = Path::new(root);
config.program = "rustc";
config.args = args.as_slice();
- let mut p = try!(Process::configure(config).to_cargo_error(format!("Could not start process: rustc {}", args.as_slice()), 1));
+ 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) {
- fail!("Failed to execute")
+ return Err(CLIError::new(format!("Non-zero status code from rustc {}", args.connect(" ")), None, 1));
}
Ok(None)
+use std::fmt;
+use std::fmt::{Show,Formatter};
use core::{NameVer,Package};
use core::source::Source;
use core::manifest::Manifest;
-use CargoResult;
+use core::errors::{CargoResult,CargoCLIError,ToResult};
use cargo_read_manifest = ops::cargo_read_manifest::read_manifest;
pub struct PathSource {
}
}
+impl Show for PathSource {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(f.buf, "the paths source")
+ }
+}
+
impl Source for PathSource {
fn update(&self) -> CargoResult<()> { Ok(()) }
fn read_manifest(path: &Path) -> CargoResult<Manifest> {
let joined = path.join("Cargo.toml");
- cargo_read_manifest(joined.as_str().unwrap())
+ cargo_read_manifest(joined.as_str().unwrap()).to_result(|err| CargoCLIError(err))
}
extern crate serialize;
extern crate toml;
-use super::super::{CargoResult,ToCargoError,CargoError};
+use core::errors::{CargoResult,CargoError,ToResult,Described,Other};
use serialize::{Encodable,Encoder};
use std::{io,fmt};
}
pub fn get_config(pwd: Path, key: &str) -> CargoResult<ConfigValue> {
- find_in_tree(&pwd, |file| extract_config(file, key)).to_cargo_error(format!("Config key not found: {}", key), 1)
+ find_in_tree(&pwd, |file| extract_config(file, key)).to_result(|_|
+ CargoError::internal(Described(format!("Config key not found: {}", key))))
}
pub fn all_configs(pwd: Path) -> CargoResult<collections::HashMap<~str, ConfigValue>> {
loop {
let possible = current.join(".cargo").join("config");
if possible.exists() {
- let file = try!(io::fs::File::open(&possible).to_cargo_error("".to_owned(), 1));
+ let file = try!(io::fs::File::open(&possible).to_result(|_| CargoError::internal(Other)));
match walk(file) {
Ok(res) => return Ok(res),
_ => ()
if !current.pop() { break; }
}
- Err(CargoError::new("".to_owned(), 1))
+ Err(CargoError::internal(Other))
}
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_cargo_error("".to_owned(), 1));
+ let file = try!(io::fs::File::open(&possible).to_result(|_| CargoError::internal(Other)));
match walk(file) {
Err(_) => err = false,
_ => ()
}
}
- if err { return Err(CargoError::new("".to_owned(), 1)); }
+ if err { return Err(CargoError::internal(Other)); }
if !current.pop() { break; }
}
}
fn extract_config(file: io::fs::File, key: &str) -> CargoResult<ConfigValue> {
- let path = try!(file.path().as_str().to_cargo_error("".to_owned(), 1)).to_owned();
+ let path = try!(file.path().as_str().to_result(|_| CargoError::internal(Other))).to_owned();
let mut buf = io::BufferedReader::new(file);
- let root = try!(toml::parse_from_buffer(&mut buf).to_cargo_error("".to_owned(), 1));
- let val = try!(root.lookup(key).to_cargo_error("".to_owned(), 1));
+ let root = try!(toml::parse_from_buffer(&mut buf).to_result(|_| CargoError::internal(Other)));
+ let val = try!(root.lookup(key).to_result(|_| CargoError::internal(Other)));
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::new("".to_owned(), 1))
+ _ => return Err(CargoError::internal(Other))
};
Ok(ConfigValue{ value: v, path: vec!(path) })
}
fn extract_all_configs(file: io::fs::File, map: &mut collections::HashMap<~str, ConfigValue>) -> CargoResult<()> {
- let path = try!(file.path().as_str().to_cargo_error("".to_owned(), 1)).to_owned();
+ let path = try!(file.path().as_str().to_result(|_| CargoError::internal(Other))).to_owned();
let mut buf = io::BufferedReader::new(file);
- let root = try!(toml::parse_from_buffer(&mut buf).to_cargo_error("".to_owned(), 1));
- let table = try!(root.get_table().to_cargo_error("".to_owned(), 1));
+ let root = try!(toml::parse_from_buffer(&mut buf).to_result(|_| CargoError::internal(Other)));
+ let table = try!(root.get_table().to_result(|_| CargoError::internal(Other)));
for (key, value) in table.iter() {
match value {
fn merge_array(existing: &mut ConfigValue, val: &[toml::Value], path: &str) -> CargoResult<()> {
match existing.value {
- String(_) => return Err(CargoError::new("".to_owned(), 1)),
+ String(_) => return Err(CargoError::internal(Other)),
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::new("".to_owned(), 1));
+ return Err(CargoError::internal(Other));
} else {
let new_list: Vec<~str> = new_list.move_iter().map(|v| v.unwrap()).collect();
list.push_all(new_list.as_slice());
fn toml_string(val: &toml::Value) -> CargoResult<~str> {
match val {
&toml::String(ref str) => Ok(str.to_owned()),
- _ => Err(CargoError::new("".to_owned(), 1))
+ _ => Err(CargoError::internal(Other))
}
}
-use super::super::{CargoResult,CargoError};
+use core::errors::{CargoResult,CargoError,MissingManifest};
pub fn find_project(pwd: Path, file: ~str) -> CargoResult<Path> {
let mut current = pwd.clone();
if !current.pop() { break; }
}
- Err(CargoError::new(format!("Could not find a Cargo manifest ({}) in your current directory or any parent directory", file), 1))
+ Err(CargoError::internal(MissingManifest(pwd, file)))
}
use std::io;
use std::io::process::{Process,ProcessConfig,ProcessOutput,InheritFd};
use collections::HashMap;
-use ToCargoError;
-use CargoResult;
+use core::errors::{ToResult,CargoResult,CargoError,Described};
#[deriving(Clone,Eq)]
pub struct ProcessBuilder {
config.args = self.args.as_slice();
config.cwd = Some(&self.cwd);
- let os_path = try!(os::getenv("PATH").to_cargo_error("Could not find the PATH environment variable".to_owned(), 1));
+ let os_path = try!(os::getenv("PATH").to_result(|_|
+ CargoError::internal(Described("Could not find the PATH environment variable".to_owned()))));
+
let path = os_path + PATH_SEP + self.path.connect(PATH_SEP);
let path = [("PATH".to_owned(), path)];
config.env = Some(path.as_slice());
- Process::configure(config).map(|mut ok| ok.wait_with_output()).to_cargo_error("Could not spawn process".to_owned(), 1)
+ Process::configure(config).map(|mut ok| ok.wait_with_output()).to_result(|_|
+ CargoError::internal(Described("Could not spawn process".to_owned())))
}
fn build_config<'a>(&'a self) -> io::IoResult<ProcessConfig<'a>> {