From 177f740311639165fb1464688752c01a039fa577 Mon Sep 17 00:00:00 2001 From: Niels langager Ellegaard Date: Sun, 5 Jan 2014 10:17:51 +0100 Subject: [PATCH] Command is now an enum --- src/librustpkg/context.rs | 69 ++++++++++++++++++++++++++++++--------- src/librustpkg/lib.rs | 66 ++++++++++++++----------------------- src/librustpkg/usage.rs | 21 ++++++++++++ src/librustpkg/util.rs | 30 ----------------- 4 files changed, 98 insertions(+), 88 deletions(-) diff --git a/src/librustpkg/context.rs b/src/librustpkg/context.rs index 31515f0cb727..3fb6f9caeb82 100644 --- a/src/librustpkg/context.rs +++ b/src/librustpkg/context.rs @@ -234,85 +234,122 @@ impl RustcFlags { } } + +#[deriving(Eq)] +pub enum Command { + BuildCmd, + CleanCmd, + DoCmd, + InfoCmd, + InstallCmd, + ListCmd, + PreferCmd, + TestCmd, + InitCmd, + UninstallCmd, + UnpreferCmd, +} + +impl FromStr for Command { + + fn from_str(s: &str) -> Option { + match s { + &"build" => Some(BuildCmd), + &"clean" => Some(CleanCmd), + &"do" => Some(DoCmd), + &"info" => Some(InfoCmd), + &"install" => Some(InstallCmd), + &"list" => Some(ListCmd), + &"prefer" => Some(PreferCmd), + &"test" => Some(TestCmd), + &"init" => Some(InitCmd), + &"uninstall" => Some(UninstallCmd), + &"unprefer" => Some(UnpreferCmd), + _ => None + } + } +} + /// Returns true if any of the flags given are incompatible with the cmd pub fn flags_forbidden_for_cmd(flags: &RustcFlags, cfgs: &[~str], - cmd: &str, user_supplied_opt_level: bool) -> bool { + cmd: Command, user_supplied_opt_level: bool) -> bool { let complain = |s| { println!("The {} option can only be used with the `build` command: rustpkg [options..] build {} [package-ID]", s, s); }; - if flags.linker.is_some() && cmd != "build" && cmd != "install" { + if flags.linker.is_some() && cmd != BuildCmd && cmd != InstallCmd { println("The --linker option can only be used with the build or install commands."); return true; } - if flags.link_args.is_some() && cmd != "build" && cmd != "install" { + if flags.link_args.is_some() && cmd != BuildCmd && cmd != InstallCmd { println("The --link-args option can only be used with the build or install commands."); return true; } - if !cfgs.is_empty() && cmd != "build" && cmd != "install" && cmd != "test" { + if !cfgs.is_empty() && cmd != BuildCmd && cmd != InstallCmd && cmd != TestCmd { println("The --cfg option can only be used with the build, test, or install commands."); return true; } - if user_supplied_opt_level && cmd != "build" && cmd != "install" { + if user_supplied_opt_level && cmd != BuildCmd && cmd != InstallCmd { println("The -O and --opt-level options can only be used with the build \ or install commands."); return true; } - if flags.save_temps && cmd != "build" && cmd != "install" { + if flags.save_temps && cmd != BuildCmd && cmd != InstallCmd { println("The --save-temps option can only be used with the build \ or install commands."); return true; } - if flags.target.is_some() && cmd != "build" && cmd != "install" { + if flags.target.is_some() && cmd != BuildCmd && cmd != InstallCmd { println("The --target option can only be used with the build \ or install commands."); return true; } - if flags.target_cpu.is_some() && cmd != "build" && cmd != "install" { + if flags.target_cpu.is_some() && cmd != BuildCmd && cmd != InstallCmd { println("The --target-cpu option can only be used with the build \ or install commands."); return true; } - if flags.experimental_features.is_some() && cmd != "build" && cmd != "install" { + if flags.experimental_features.is_some() && cmd != BuildCmd && cmd != InstallCmd { println("The -Z option can only be used with the build or install commands."); return true; } match flags.compile_upto { - Link if cmd != "build" => { + Link if cmd != BuildCmd => { complain("--no-link"); true } - Trans if cmd != "build" => { + Trans if cmd != BuildCmd => { complain("--no-trans"); true } - Assemble if cmd != "build" => { + Assemble if cmd != BuildCmd => { complain("-S"); true } - Pretty if cmd != "build" => { + Pretty if cmd != BuildCmd => { complain("--pretty"); true } - Analysis if cmd != "build" => { + Analysis if cmd != BuildCmd => { complain("--parse-only"); true } - LLVMCompileBitcode if cmd != "build" => { + LLVMCompileBitcode if cmd != BuildCmd => { complain("--emit-llvm"); true } - LLVMAssemble if cmd != "build" => { + LLVMAssemble if cmd != BuildCmd => { complain("--emit-llvm"); true } _ => false } } + diff --git a/src/librustpkg/lib.rs b/src/librustpkg/lib.rs index 7051c7de058f..43f190f37a23 100644 --- a/src/librustpkg/lib.rs +++ b/src/librustpkg/lib.rs @@ -45,6 +45,8 @@ use workspace::determine_destination; use context::{Context, BuildContext, RustcFlags, Trans, Link, Nothing, Pretty, Analysis, Assemble, LLVMAssemble, LLVMCompileBitcode}; +use context::{Command, BuildCmd, CleanCmd, DoCmd, InfoCmd, InstallCmd, ListCmd, + PreferCmd, TestCmd, InitCmd, UninstallCmd, UnpreferCmd}; use crate_id::CrateId; use package_source::PkgSrc; use target::{WhatToBuild, Everything, is_lib, is_main, is_test, is_bench}; @@ -205,7 +207,7 @@ impl<'a> PkgScript<'a> { } pub trait CtxMethods { - fn run(&self, cmd: &str, args: ~[~str]); + fn run(&self, cmd: Command, args: ~[~str]); fn do_cmd(&self, _cmd: &str, _pkgname: &str); /// Returns a pair of the selected package ID, and the destination workspace fn build_args(&self, args: ~[~str], what: &WhatToBuild) -> Option<(CrateId, Path)>; @@ -281,13 +283,13 @@ impl CtxMethods for BuildContext { Some((crateid, dest_ws)) } } - fn run(&self, cmd: &str, args: ~[~str]) { + fn run(&self, cmd: Command, args: ~[~str]) { let cwd = os::getcwd(); match cmd { - "build" => { + BuildCmd => { self.build_args(args, &WhatToBuild::new(MaybeCustom, Everything)); } - "clean" => { + CleanCmd => { if args.len() < 1 { match cwd_to_workspace() { None => { usage::clean(); return } @@ -304,17 +306,17 @@ impl CtxMethods for BuildContext { self.clean(&cwd, &crateid); // tjc: should use workspace, not cwd } } - "do" => { + DoCmd => { if args.len() < 2 { return usage::do_cmd(); } self.do_cmd(args[0].clone(), args[1].clone()); } - "info" => { + InfoCmd => { self.info(); } - "install" => { + InstallCmd => { if args.len() < 1 { match cwd_to_workspace() { None if dir_has_crate_file(&cwd) => { @@ -360,21 +362,21 @@ impl CtxMethods for BuildContext { } } } - "list" => { + ListCmd => { println("Installed packages:"); installed_packages::list_installed_packages(|pkg_id| { pkg_id.path.display().with_str(|s| println(s)); true }); } - "prefer" => { + PreferCmd => { if args.len() < 1 { return usage::uninstall(); } self.prefer(args[0], None); } - "test" => { + TestCmd => { // Build the test executable let maybe_id_and_workspace = self.build_args(args, &WhatToBuild::new(MaybeCustom, Tests)); @@ -388,14 +390,14 @@ impl CtxMethods for BuildContext { } } } - "init" => { + InitCmd => { if args.len() != 0 { return usage::init(); } else { self.init(); } } - "uninstall" => { + UninstallCmd => { if args.len() < 1 { return usage::uninstall(); } @@ -417,14 +419,13 @@ impl CtxMethods for BuildContext { }); } } - "unprefer" => { + UnpreferCmd => { if args.len() < 1 { return usage::unprefer(); } self.unprefer(args[0], None); } - _ => fail!("I don't know the command `{}`", cmd) } } @@ -864,14 +865,8 @@ pub fn main_args(args: &[~str]) -> int { experimental_features: experimental_features }; - let mut cmd_opt = None; - for a in args.iter() { - if util::is_cmd(*a) { - cmd_opt = Some(a); - break; - } - } - let cmd = match cmd_opt { + let cmd_opt = args.iter().filter_map( |s| from_str(s.clone())).next(); + let command = match(cmd_opt) { None => { usage::general(); return 0; @@ -879,23 +874,10 @@ pub fn main_args(args: &[~str]) -> int { Some(cmd) => { let bad_option = context::flags_forbidden_for_cmd(&rustc_flags, cfgs, - *cmd, + cmd, user_supplied_opt_level); if help || bad_option { - match *cmd { - ~"build" => usage::build(), - ~"clean" => usage::clean(), - ~"do" => usage::do_cmd(), - ~"info" => usage::info(), - ~"install" => usage::install(), - ~"list" => usage::list(), - ~"prefer" => usage::prefer(), - ~"test" => usage::test(), - ~"init" => usage::init(), - ~"uninstall" => usage::uninstall(), - ~"unprefer" => usage::unprefer(), - _ => usage::general() - }; + usage::usage_for_command(cmd); if bad_option { return BAD_FLAG_CODE; } @@ -909,9 +891,10 @@ pub fn main_args(args: &[~str]) -> int { }; // Pop off all flags, plus the command - let remaining_args = args.iter().skip_while(|s| !util::is_cmd(**s)); - // I had to add this type annotation to get the code to typecheck - let mut remaining_args: ~[~str] = remaining_args.map(|s| (*s).clone()).collect(); + let mut remaining_args: ~[~str] = args.iter().skip_while(|&s| { + let maybe_command: Option = from_str(*s); + maybe_command.is_none() + }).map(|s| s.clone()).collect(); remaining_args.shift(); let sroot = match supplied_sysroot { Some(s) => Path::new(s), @@ -923,7 +906,6 @@ pub fn main_args(args: &[~str]) -> int { debug!("Will store workcache in {}", ws.display()); let rm_args = remaining_args.clone(); - let sub_cmd = cmd.clone(); // Wrap the rest in task::try in case of a condition failure in a task let result = do task::try { BuildContext { @@ -935,7 +917,7 @@ pub fn main_args(args: &[~str]) -> int { }, workcache_context: api::default_context(sroot.clone(), default_workspace()).workcache_context - }.run(sub_cmd, rm_args.clone()) + }.run(command, rm_args.clone()) }; // FIXME #9262: This is using the same error code for all errors, // and at least one test case succeeds if rustpkg returns COPY_FAILED_CODE, diff --git a/src/librustpkg/usage.rs b/src/librustpkg/usage.rs index ef6ac485b729..a41e99f6d663 100644 --- a/src/librustpkg/usage.rs +++ b/src/librustpkg/usage.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use context::Command; + pub fn general() { println("Usage: rustpkg [options] [args..] @@ -154,3 +156,22 @@ This will turn the current working directory into a workspace. The first command you run when starting off a new project. "); } + +pub fn usage_for_command(command: Command){ + match command { + BuildCmd => build(), + CleanCmd => clean(), + DoCmd => do_cmd(), + InfoCmd => info(), + InstallCmd => install(), + ListCmd => list(), + PreferCmd => prefer(), + TestCmd => test(), + InitCmd => init(), + UninstallCmd => uninstall(), + UnpreferCmd => unprefer(), + }; +} + + + diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index 7e43fde7b323..5f5c34dc04b8 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -41,13 +41,6 @@ pub use target::{lib_name_of, lib_crate_filename, WhatToBuild, MaybeCustom, Infe use workcache_support::{digest_file_with_date, digest_only_date}; use messages::error; -// It would be nice to have the list of commands in just one place -- for example, -// you could update the match in rustpkg.rc but forget to update this list. I think -// that should be fixed. -static COMMANDS: &'static [&'static str] = - &["build", "clean", "do", "info", "init", "install", "list", "prefer", "test", "uninstall", - "unprefer"]; - pub type ExitCode = int; // For now @@ -63,10 +56,6 @@ impl ToStr for Pkg { } } -pub fn is_cmd(cmd: &str) -> bool { - COMMANDS.iter().any(|&c| c == cmd) -} - struct ListenerFn { cmds: ~[~str], span: codemap::Span, @@ -634,25 +623,6 @@ pub fn mk_string_lit(s: @str) -> ast::lit { } } -#[cfg(test)] -mod test { - use super::is_cmd; - - #[test] - fn test_is_cmd() { - assert!(is_cmd("build")); - assert!(is_cmd("clean")); - assert!(is_cmd("do")); - assert!(is_cmd("info")); - assert!(is_cmd("install")); - assert!(is_cmd("prefer")); - assert!(is_cmd("test")); - assert!(is_cmd("uninstall")); - assert!(is_cmd("unprefer")); - } - -} - pub fn option_to_vec(x: Option) -> ~[T] { match x { Some(y) => ~[y],