about summary refs log tree commit diff
path: root/src/librustpkg
diff options
context:
space:
mode:
authorNiels langager Ellegaard <niels.ellegaard@gmail.com>2014-01-05 10:17:51 +0100
committerNiels langager Ellegaard <niels.ellegaard@gmail.com>2014-01-05 11:25:12 +0100
commit177f740311639165fb1464688752c01a039fa577 (patch)
treebb4c6c796bd3570605ac18ef5dd3f7961cde0efb /src/librustpkg
parent4eceb0050c107c4ed18221bde9e5046613a710b6 (diff)
Command is now an enum
Diffstat (limited to 'src/librustpkg')
-rw-r--r--src/librustpkg/context.rs69
-rw-r--r--src/librustpkg/lib.rs66
-rw-r--r--src/librustpkg/usage.rs21
-rw-r--r--src/librustpkg/util.rs30
4 files changed, 98 insertions, 88 deletions
diff --git a/src/librustpkg/context.rs b/src/librustpkg/context.rs
index 31515f0cb72..3fb6f9caeb8 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<Command>  {
+       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 7051c7de058..43f190f37a2 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<Command> = 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 ef6ac485b72..a41e99f6d66 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] <cmd> [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 7e43fde7b32..5f5c34dc04b 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<T>(x: Option<T>) -> ~[T] {
     match x {
        Some(y) => ~[y],