mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +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;
|
extern crate collections;
|
||||||
|
|
||||||
use hammer::{FlagConfig,FlagConfiguration};
|
use hammer::{FlagConfig,FlagConfiguration};
|
||||||
use std::{os,io};
|
use std::os;
|
||||||
use serialize::{Decodable,Encodable,json};
|
use serialize::Encodable;
|
||||||
use cargo::{CargoResult,ToCargoError,NoFlags,execute_main_without_stdin,process_executed,handle_error};
|
use cargo::{CargoResult,ToCargoError,NoFlags,execute_main_without_stdin,handle_error};
|
||||||
use cargo::util::important_paths::find_project;
|
use cargo::util::important_paths::find_project;
|
||||||
use cargo::util::config;
|
use cargo::util::config;
|
||||||
|
|
||||||
@ -20,13 +20,19 @@ struct ProjectLocation {
|
|||||||
root: ~str
|
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() {
|
fn execute() {
|
||||||
let (cmd, args) = match process(os::args()) {
|
let (cmd, _) = match process(os::args()) {
|
||||||
Ok((cmd, args)) => (cmd, args),
|
Ok((cmd, args)) => (cmd, args),
|
||||||
Err(err) => return handle_error(err)
|
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) }
|
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))
|
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)]
|
#[deriving(Encodable)]
|
||||||
struct ConfigOut {
|
struct ConfigOut {
|
||||||
values: collections::HashMap<~str, config::ConfigValue>
|
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()));
|
let value = try!(config::get_config(os::getcwd(), args.key.as_slice()));
|
||||||
|
|
||||||
if args.human {
|
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 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));
|
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() }))
|
Ok(Some(ProjectLocation { root: string.to_owned() }))
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
|
extern crate collections;
|
||||||
extern crate toml;
|
extern crate toml;
|
||||||
|
|
||||||
use super::super::{CargoResult,CargoError,ToCargoError};
|
use super::super::{CargoResult,ToCargoError};
|
||||||
use std::{io,fmt};
|
use std::{io,fmt};
|
||||||
|
|
||||||
#[deriving(Eq,Clone,Encodable,Decodable)]
|
#[deriving(Eq,TotalEq,Clone,Encodable,Decodable)]
|
||||||
pub enum Location {
|
pub enum Location {
|
||||||
Project,
|
Project,
|
||||||
Global
|
Global
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Eq,Clone,Encodable,Decodable)]
|
#[deriving(Eq,TotalEq,Clone,Encodable,Decodable)]
|
||||||
pub struct ConfigValue {
|
pub struct ConfigValue {
|
||||||
value: ~str,
|
value: ~str,
|
||||||
path: ~str
|
path: ~str
|
||||||
@ -22,14 +23,29 @@ impl fmt::Show for ConfigValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_config(pwd: Path, key: &str) -> CargoResult<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<()> {
|
pub fn set_config(key: ~str, value: ~str, location: Location) -> CargoResult<()> {
|
||||||
Ok(())
|
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();
|
let mut current = pwd.clone();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
@ -49,6 +65,19 @@ fn walk_tree<T>(pwd: &Path, walk: |io::fs::File| -> CargoResult<T>) -> Option<T>
|
|||||||
None
|
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> {
|
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 path = try!(file.path().as_str().to_cargo_error(~"", 1)).to_owned();
|
||||||
let mut buf = io::BufferedReader::new(file);
|
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));
|
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 })
|
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};
|
use super::super::{CargoResult,CargoError};
|
||||||
|
|
||||||
pub fn find_project(pwd: Path, file: ~str) -> CargoResult<Path> {
|
pub fn find_project(pwd: Path, file: ~str) -> CargoResult<Path> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user