Skip to content

Commit

Permalink
Command is now an enum
Browse files Browse the repository at this point in the history
  • Loading branch information
nielsle committed Jan 5, 2014
1 parent 4eceb00 commit 177f740
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 88 deletions.
69 changes: 53 additions & 16 deletions src/librustpkg/context.rs
Expand Up @@ -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
}
}

66 changes: 24 additions & 42 deletions src/librustpkg/lib.rs
Expand Up @@ -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};
Expand Down Expand Up @@ -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)>;
Expand Down Expand Up @@ -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 }
Expand All @@ -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) => {
Expand Down Expand Up @@ -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));
Expand All @@ -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();
}
Expand All @@ -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)
}
}

Expand Down Expand Up @@ -864,38 +865,19 @@ 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;
}
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;
}
Expand All @@ -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),
Expand All @@ -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 {
Expand All @@ -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,
Expand Down
21 changes: 21 additions & 0 deletions src/librustpkg/usage.rs
Expand Up @@ -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..]
Expand Down Expand Up @@ -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(),
};
}



0 comments on commit 177f740

Please sign in to comment.