// Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use std::fs; use std::path::PathBuf; use std::process; use std::slice; use getopts::Options; pub struct Flags { pub verbose: bool, pub stage: Option, pub build: String, pub host: Filter, pub target: Filter, pub step: Vec, pub config: Option, pub src: Option, pub jobs: Option, pub args: Vec, pub clean: bool, } pub struct Filter { values: Vec, } impl Flags { pub fn parse(args: &[String]) -> Flags { let mut opts = Options::new(); opts.optflag("v", "verbose", "use verbose output"); opts.optopt("", "config", "TOML configuration file for build", "FILE"); opts.optmulti("", "host", "host targets to build", "HOST"); opts.reqopt("", "build", "build target of the stage0 compiler", "BUILD"); opts.optmulti("", "target", "targets to build", "TARGET"); opts.optmulti("s", "step", "build step to execute", "STEP"); opts.optopt("", "stage", "stage to build", "N"); opts.optopt("", "src", "path to repo root", "DIR"); opts.optopt("j", "jobs", "number of jobs to run in parallel", "JOBS"); opts.optflag("", "clean", "clean output directory"); opts.optflag("h", "help", "print this help message"); let usage = |n| -> ! { let brief = format!("Usage: rust.py [options]"); print!("{}", opts.usage(&brief)); process::exit(n); }; let m = opts.parse(args).unwrap_or_else(|e| { println!("failed to parse options: {}", e); usage(1); }); if m.opt_present("h") { usage(0); } let cfg_file = m.opt_str("config").map(PathBuf::from).or_else(|| { if fs::metadata("config.toml").is_ok() { Some(PathBuf::from("config.toml")) } else { None } }); Flags { verbose: m.opt_present("v"), clean: m.opt_present("clean"), stage: m.opt_str("stage").map(|j| j.parse().unwrap()), build: m.opt_str("build").unwrap(), host: Filter { values: m.opt_strs("host") }, target: Filter { values: m.opt_strs("target") }, step: m.opt_strs("step"), config: cfg_file, src: m.opt_str("src").map(PathBuf::from), jobs: m.opt_str("jobs").map(|j| j.parse().unwrap()), args: m.free.clone(), } } } impl Filter { pub fn contains(&self, name: &str) -> bool { self.values.len() == 0 || self.values.iter().any(|s| s == name) } pub fn iter(&self) -> slice::Iter { self.values.iter() } }