mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-25 11:14:46 +00:00
Now can get all configs
This commit is contained in:
parent
3a15f5b786
commit
739b130975
@ -5,9 +5,9 @@ extern crate serialize;
|
||||
extern crate collections;
|
||||
|
||||
use hammer::{FlagConfig,FlagConfiguration};
|
||||
use std::{os,io};
|
||||
use serialize::{Decodable,Encodable,json};
|
||||
use cargo::{CargoResult,ToCargoError,NoFlags,execute_main_without_stdin,process_executed,handle_error};
|
||||
use std::os;
|
||||
use serialize::Encodable;
|
||||
use cargo::{CargoResult,ToCargoError,NoFlags,execute_main_without_stdin,handle_error};
|
||||
use cargo::util::important_paths::find_project;
|
||||
use cargo::util::config;
|
||||
|
||||
@ -20,13 +20,19 @@ struct ProjectLocation {
|
||||
root: ~str
|
||||
}
|
||||
|
||||
/**
|
||||
The top-level `cargo` command handles configuration and project location
|
||||
because they are fundamental (and intertwined). Other commands can rely
|
||||
on this top-level information.
|
||||
*/
|
||||
fn execute() {
|
||||
let (cmd, args) = match process(os::args()) {
|
||||
let (cmd, _) = match process(os::args()) {
|
||||
Ok((cmd, args)) => (cmd, args),
|
||||
Err(err) => return handle_error(err)
|
||||
};
|
||||
|
||||
if cmd == ~"config" { execute_main_without_stdin(config) }
|
||||
if cmd == ~"config-for-key" { execute_main_without_stdin(config_for_key) }
|
||||
else if cmd == ~"config-list" { execute_main_without_stdin(config_list) }
|
||||
else if cmd == ~"locate-project" { execute_main_without_stdin(locate_project) }
|
||||
}
|
||||
|
||||
@ -38,25 +44,24 @@ fn process(mut args: ~[~str]) -> CargoResult<(~str, ~[~str])> {
|
||||
Ok((head, tail))
|
||||
}
|
||||
|
||||
#[deriving(Decodable)]
|
||||
struct ConfigFlags {
|
||||
key: ~str,
|
||||
value: Option<~str>,
|
||||
human: bool
|
||||
}
|
||||
|
||||
impl FlagConfig for ConfigFlags {
|
||||
fn config(_: Option<ConfigFlags>, c: FlagConfiguration) -> FlagConfiguration {
|
||||
c.short("human", 'h')
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
struct ConfigOut {
|
||||
values: collections::HashMap<~str, config::ConfigValue>
|
||||
}
|
||||
|
||||
fn config(args: ConfigFlags) -> CargoResult<Option<ConfigOut>> {
|
||||
#[deriving(Decodable)]
|
||||
struct ConfigForKeyFlags {
|
||||
key: ~str,
|
||||
human: bool
|
||||
}
|
||||
|
||||
impl FlagConfig for ConfigForKeyFlags {
|
||||
fn config(_: Option<ConfigForKeyFlags>, config: FlagConfiguration) -> FlagConfiguration {
|
||||
config.short("human", 'h')
|
||||
}
|
||||
}
|
||||
|
||||
fn config_for_key(args: ConfigForKeyFlags) -> CargoResult<Option<ConfigOut>> {
|
||||
let value = try!(config::get_config(os::getcwd(), args.key.as_slice()));
|
||||
|
||||
if args.human {
|
||||
@ -69,7 +74,31 @@ fn config(args: ConfigFlags) -> CargoResult<Option<ConfigOut>> {
|
||||
}
|
||||
}
|
||||
|
||||
fn locate_project(args: NoFlags) -> CargoResult<Option<ProjectLocation>> {
|
||||
#[deriving(Decodable)]
|
||||
struct ConfigListFlags {
|
||||
human: bool
|
||||
}
|
||||
|
||||
impl FlagConfig for ConfigListFlags {
|
||||
fn config(_: Option<ConfigListFlags>, config: FlagConfiguration) -> FlagConfiguration {
|
||||
config.short("human", 'h')
|
||||
}
|
||||
}
|
||||
|
||||
fn config_list(args: ConfigListFlags) -> CargoResult<Option<ConfigOut>> {
|
||||
let configs = try!(config::all_configs(os::getcwd()));
|
||||
|
||||
if args.human {
|
||||
for (key, value) in configs.iter() {
|
||||
println!("{} = {}", key, value);
|
||||
}
|
||||
Ok(None)
|
||||
} else {
|
||||
Ok(Some(ConfigOut { values: configs }))
|
||||
}
|
||||
}
|
||||
|
||||
fn locate_project(_: NoFlags) -> CargoResult<Option<ProjectLocation>> {
|
||||
let root = try!(find_project(os::getcwd(), ~"Cargo.toml"));
|
||||
let string = try!(root.as_str().to_cargo_error(format!("Your project path contains characters not representable in Unicode: {}", os::getcwd().display()), 1));
|
||||
Ok(Some(ProjectLocation { root: string.to_owned() }))
|
||||
|
@ -1,15 +1,16 @@
|
||||
extern crate collections;
|
||||
extern crate toml;
|
||||
|
||||
use super::super::{CargoResult,CargoError,ToCargoError};
|
||||
use super::super::{CargoResult,ToCargoError};
|
||||
use std::{io,fmt};
|
||||
|
||||
#[deriving(Eq,Clone,Encodable,Decodable)]
|
||||
#[deriving(Eq,TotalEq,Clone,Encodable,Decodable)]
|
||||
pub enum Location {
|
||||
Project,
|
||||
Global
|
||||
}
|
||||
|
||||
#[deriving(Eq,Clone,Encodable,Decodable)]
|
||||
#[deriving(Eq,TotalEq,Clone,Encodable,Decodable)]
|
||||
pub struct ConfigValue {
|
||||
value: ~str,
|
||||
path: ~str
|
||||
@ -22,14 +23,29 @@ impl fmt::Show for ConfigValue {
|
||||
}
|
||||
|
||||
pub fn get_config(pwd: Path, key: &str) -> CargoResult<ConfigValue> {
|
||||
walk_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_cargo_error(format!("Config key not found: {}", key), 1)
|
||||
}
|
||||
|
||||
pub fn all_configs(pwd: Path) -> CargoResult<collections::HashMap<~str, ConfigValue>> {
|
||||
let mut map = collections::HashMap::new();
|
||||
|
||||
walk_tree(&pwd, |file| {
|
||||
let _ = extract_all_configs(file).map(|configs| {
|
||||
for (key, value) in configs.move_iter() {
|
||||
map.find_or_insert(key, value);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Ok(map)
|
||||
}
|
||||
|
||||
#[allow(unused_variable)]
|
||||
pub fn set_config(key: ~str, value: ~str, location: Location) -> CargoResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn walk_tree<T>(pwd: &Path, walk: |io::fs::File| -> CargoResult<T>) -> Option<T> {
|
||||
fn find_in_tree<T>(pwd: &Path, walk: |io::fs::File| -> CargoResult<T>) -> Option<T> {
|
||||
let mut current = pwd.clone();
|
||||
|
||||
loop {
|
||||
@ -49,6 +65,19 @@ fn walk_tree<T>(pwd: &Path, walk: |io::fs::File| -> CargoResult<T>) -> Option<T>
|
||||
None
|
||||
}
|
||||
|
||||
fn walk_tree(pwd: &Path, walk: |io::fs::File| -> ()) {
|
||||
let mut current = pwd.clone();
|
||||
|
||||
loop {
|
||||
let possible = current.join(".cargo").join("config");
|
||||
if possible.exists() {
|
||||
let _ = io::fs::File::open(&possible).map(|file| walk(file));
|
||||
}
|
||||
|
||||
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(~"", 1)).to_owned();
|
||||
let mut buf = io::BufferedReader::new(file);
|
||||
@ -56,3 +85,21 @@ fn extract_config(file: io::fs::File, key: &str) -> CargoResult<ConfigValue> {
|
||||
let val = try!(try!(root.lookup(key).to_cargo_error(~"", 1)).get_str().to_cargo_error(~"", 1));
|
||||
Ok(ConfigValue{ value: val.to_owned(), path: path })
|
||||
}
|
||||
|
||||
fn extract_all_configs(file: io::fs::File) -> CargoResult<collections::HashMap<~str, ConfigValue>> {
|
||||
let mut map = collections::HashMap::new();
|
||||
|
||||
let path = try!(file.path().as_str().to_cargo_error(~"", 1)).to_owned();
|
||||
let mut buf = io::BufferedReader::new(file);
|
||||
let root = try!(toml::parse_from_buffer(&mut buf).to_cargo_error(~"", 1));
|
||||
let table = try!(root.get_table().to_cargo_error(~"", 1));
|
||||
|
||||
for (key, value) in table.iter() {
|
||||
match value {
|
||||
&toml::String(ref val) => { map.insert(key.to_owned(), ConfigValue { value: val.to_owned(), path: path.clone() }); }
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
||||
Ok(map)
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
use std::os;
|
||||
use super::super::{CargoResult,CargoError};
|
||||
|
||||
pub fn find_project(pwd: Path, file: ~str) -> CargoResult<Path> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user