rustpkg: Add do command and get cmd listeners working correctly
This commit is contained in:
parent
7079441843
commit
e34e072d17
src/librustpkg
@ -19,21 +19,29 @@ pub struct Crate {
|
||||
}
|
||||
|
||||
pub struct Listener {
|
||||
cmd: ~str,
|
||||
cmds: ~[~str],
|
||||
cb: fn~()
|
||||
}
|
||||
|
||||
pub fn run(listeners: ~[Listener]) {
|
||||
io::println(src_dir().to_str());
|
||||
io::println(work_dir().to_str());
|
||||
|
||||
let cmd = os::args()[1];
|
||||
let rcmd = os::args()[2];
|
||||
let mut found = false;
|
||||
|
||||
for listeners.each |listener| {
|
||||
if listener.cmd == cmd {
|
||||
(listener.cb)();
|
||||
for listener.cmds.each |&cmd| {
|
||||
if cmd == rcmd {
|
||||
(listener.cb)();
|
||||
|
||||
found = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
os::set_exit_status(1);
|
||||
}
|
||||
}
|
||||
|
||||
pub impl Crate {
|
||||
@ -108,19 +116,22 @@ pub fn build(crates: ~[Crate]) -> bool {
|
||||
let dir = src_dir();
|
||||
let work_dir = work_dir();
|
||||
let mut success = true;
|
||||
let sysroot = Path(os::args()[1]);
|
||||
|
||||
for crates.each |&crate| {
|
||||
let path = &dir.push_rel(&Path(crate.file)).normalize();
|
||||
|
||||
note(fmt!("compiling %s", path.to_str()));
|
||||
|
||||
success = compile_crate(path, &work_dir, crate.flags, crate.cfgs,
|
||||
success = compile_crate(Some(sysroot), path, &work_dir, crate.flags, crate.cfgs,
|
||||
false, false);
|
||||
|
||||
if !success { break; }
|
||||
}
|
||||
|
||||
os::set_exit_status(101);
|
||||
if !success {
|
||||
os::set_exit_status(2);
|
||||
}
|
||||
|
||||
success
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ use io::{ReaderUtil, WriterUtil};
|
||||
use std::getopts;
|
||||
use std::net::url;
|
||||
use send_map::linear::LinearMap;
|
||||
use rustc::metadata::filesearch;
|
||||
use rustc::driver::{driver, session};
|
||||
use syntax::{ast, attr, codemap, diagnostic, parse, visit};
|
||||
use semver::Version;
|
||||
@ -184,7 +185,11 @@ impl PackageScript {
|
||||
// the build API.
|
||||
for crate.node.module.items.each |i| {
|
||||
match i.node {
|
||||
ast::item_fn(_, _, _, _) => custom = true,
|
||||
ast::item_fn(_, _, _, _) => {
|
||||
custom = true;
|
||||
|
||||
break;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@ -228,10 +233,11 @@ impl PackageScript {
|
||||
let outputs = driver::build_output_filenames(input, &Some(work_dir),
|
||||
&None, sess);
|
||||
let exe = work_dir.push(~"package" + util::exe_suffix());
|
||||
let root = filesearch::get_rustpkg_sysroot().get().pop().pop();
|
||||
|
||||
driver::compile_rest(sess, cfg, driver::cu_parse,
|
||||
Some(outputs), Some(crate));
|
||||
run::run_program(exe.to_str(), ~[cmd])
|
||||
run::run_program(exe.to_str(), ~[root.to_str(), cmd])
|
||||
}
|
||||
|
||||
fn hash() -> ~str {
|
||||
@ -282,6 +288,13 @@ impl Ctx {
|
||||
~"clean" => {
|
||||
self.clean();
|
||||
}
|
||||
~"do" => {
|
||||
if args.len() < 1 {
|
||||
return usage::do_cmd();
|
||||
}
|
||||
|
||||
self.do_cmd(args[0]);
|
||||
}
|
||||
~"install" => {
|
||||
self.install(if args.len() >= 1 { Some(args[0]) }
|
||||
else { None },
|
||||
@ -322,6 +335,33 @@ impl Ctx {
|
||||
}
|
||||
}
|
||||
|
||||
fn do_cmd(cmd: ~str) -> bool {
|
||||
if cmd == ~"build" {
|
||||
util::error(~"the build cmd is reserved");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
let cwd = &os::getcwd();
|
||||
let script = match PackageScript::parse(cwd) {
|
||||
result::Ok(script) => script,
|
||||
result::Err(err) => {
|
||||
util::error(err);
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
let status = script.run(cmd);
|
||||
|
||||
if status == 1 {
|
||||
util::error(~"no fns are listening for that cmd");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
status == 0
|
||||
}
|
||||
|
||||
fn build(dir: &Path, verbose: bool, opt: bool,
|
||||
test: bool) -> Option<PackageScript> {
|
||||
let cwd = &os::getcwd();
|
||||
@ -399,7 +439,7 @@ impl Ctx {
|
||||
|
||||
fn compile(crate: &Path, dir: &Path, flags: ~[~str],
|
||||
cfgs: ~[~str], opt: bool, test: bool) -> bool {
|
||||
util::compile_crate(crate, dir, flags, cfgs, opt, test)
|
||||
util::compile_crate(None, crate, dir, flags, cfgs, opt, test)
|
||||
}
|
||||
|
||||
fn clean() -> bool {
|
||||
@ -759,6 +799,7 @@ pub fn main() {
|
||||
return match cmd {
|
||||
~"build" => usage::build(),
|
||||
~"clean" => usage::clean(),
|
||||
~"do" => usage::do_cmd(),
|
||||
~"install" => usage::install(),
|
||||
~"prefer" => usage::prefer(),
|
||||
~"test" => usage::test(),
|
||||
|
@ -39,6 +39,13 @@ Remove all build files in the work cache for the package in the current
|
||||
directory.");
|
||||
}
|
||||
|
||||
pub fn do_cmd() {
|
||||
io::println(~"rustpkg do <cmd>
|
||||
|
||||
Runs a command in the package script. You can listen to a command
|
||||
by tagging a function with the attribute `#[pkg_do(cmd)]`.");
|
||||
}
|
||||
|
||||
pub fn install() {
|
||||
io::println(~"rustpkg [options..] install [url] [target]
|
||||
|
||||
|
@ -34,8 +34,8 @@ pub fn root() -> Path {
|
||||
}
|
||||
|
||||
pub fn is_cmd(cmd: ~str) -> bool {
|
||||
let cmds = &[~"build", ~"clean", ~"install", ~"prefer", ~"test",
|
||||
~"uninstall", ~"unprefer"];
|
||||
let cmds = &[~"build", ~"clean", ~"do", ~"install", ~"prefer",
|
||||
~"test", ~"uninstall", ~"unprefer"];
|
||||
|
||||
vec::contains(cmds, &cmd)
|
||||
}
|
||||
@ -74,6 +74,7 @@ fn mk_rustpkg_use(ctx: @ReadyCtx) -> @ast::view_item {
|
||||
}
|
||||
|
||||
struct ListenerFn {
|
||||
cmds: ~[~str],
|
||||
span: codemap::span,
|
||||
path: ~[ast::ident]
|
||||
}
|
||||
@ -119,8 +120,27 @@ fn fold_item(ctx: @ReadyCtx, &&item: @ast::item,
|
||||
|
||||
ctx.path.push(item.ident);
|
||||
|
||||
if attr::find_attrs_by_name(item.attrs, ~"pkg_do").is_not_empty() {
|
||||
let attrs = attr::find_attrs_by_name(item.attrs, ~"pkg_do");
|
||||
|
||||
if attrs.len() > 0 {
|
||||
let mut cmds = ~[];
|
||||
|
||||
for attrs.each |attr| {
|
||||
match attr.node.value.node {
|
||||
ast::meta_list(_, mis) => {
|
||||
for mis.each |mi| {
|
||||
match mi.node {
|
||||
ast::meta_word(cmd) => cmds.push(cmd),
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
_ => cmds.push(~"build")
|
||||
};
|
||||
}
|
||||
|
||||
ctx.fns.push(ListenerFn {
|
||||
cmds: cmds,
|
||||
span: item.span,
|
||||
path: /*bad*/copy ctx.path
|
||||
});
|
||||
@ -284,13 +304,26 @@ fn mk_listener_vec(ctx: @ReadyCtx) -> @ast::expr {
|
||||
fn mk_listener_rec(ctx: @ReadyCtx, listener: ListenerFn) -> @ast::expr {
|
||||
let span = listener.span;
|
||||
let path = /*bad*/copy listener.path;
|
||||
let cmd_lit = no_span(ast::lit_str(@path_name_i(path,
|
||||
ctx.sess.parse_sess.interner)));
|
||||
let descs = do listener.cmds.map |&cmd| {
|
||||
let inner = @{
|
||||
id: ctx.sess.next_node_id(),
|
||||
callee_id: ctx.sess.next_node_id(),
|
||||
node: ast::expr_lit(@no_span(ast::lit_str(@cmd))),
|
||||
span: span
|
||||
};
|
||||
|
||||
@{
|
||||
id: ctx.sess.next_node_id(),
|
||||
callee_id: ctx.sess.next_node_id(),
|
||||
node: ast::expr_vstore(inner, ast::expr_vstore_uniq),
|
||||
span: dummy_sp()
|
||||
}
|
||||
};
|
||||
let cmd_expr_inner = @{
|
||||
id: ctx.sess.next_node_id(),
|
||||
callee_id: ctx.sess.next_node_id(),
|
||||
node: ast::expr_lit(@cmd_lit),
|
||||
span: span
|
||||
node: ast::expr_vec(descs, ast::m_imm),
|
||||
span: dummy_sp()
|
||||
};
|
||||
let cmd_expr = {
|
||||
id: ctx.sess.next_node_id(),
|
||||
@ -300,7 +333,7 @@ fn mk_listener_rec(ctx: @ReadyCtx, listener: ListenerFn) -> @ast::expr {
|
||||
};
|
||||
let cmd_field = no_span(ast::field_ {
|
||||
mutbl: ast::m_imm,
|
||||
ident: ctx.sess.ident_of(~"cmd"),
|
||||
ident: ctx.sess.ident_of(~"cmds"),
|
||||
expr: @cmd_expr,
|
||||
});
|
||||
|
||||
@ -827,7 +860,7 @@ pub fn remove_pkg(pkg: &Package) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn compile_input(input: driver::input, dir: &Path,
|
||||
pub fn compile_input(sysroot: Option<Path>, input: driver::input, dir: &Path,
|
||||
flags: ~[~str], cfgs: ~[~str], opt: bool, test: bool) -> bool {
|
||||
let lib_dir = dir.push(~"lib");
|
||||
let bin_dir = dir.push(~"bin");
|
||||
@ -838,6 +871,7 @@ pub fn compile_input(input: driver::input, dir: &Path,
|
||||
crate_type: session::unknown_crate,
|
||||
optimize: if opt { session::Aggressive } else { session::No },
|
||||
test: test,
|
||||
maybe_sysroot: sysroot,
|
||||
.. *session::basic_options()
|
||||
};
|
||||
let sess = driver::build_session(options, diagnostic::emit);
|
||||
@ -966,14 +1000,14 @@ pub fn exe_suffix() -> ~str { ~".exe" }
|
||||
#[cfg(target_os = "macos")]
|
||||
pub fn exe_suffix() -> ~str { ~"" }
|
||||
|
||||
pub fn compile_crate(crate: &Path, dir: &Path, flags: ~[~str],
|
||||
pub fn compile_crate(sysroot: Option<Path>, crate: &Path, dir: &Path, flags: ~[~str],
|
||||
cfgs: ~[~str], opt: bool, test: bool) -> bool {
|
||||
compile_input(driver::file_input(*crate), dir, flags, cfgs, opt, test)
|
||||
compile_input(sysroot, driver::file_input(*crate), dir, flags, cfgs, opt, test)
|
||||
}
|
||||
|
||||
pub fn compile_str(code: ~str, dir: &Path, flags: ~[~str],
|
||||
pub fn compile_str(sysroot: Option<Path>, code: ~str, dir: &Path, flags: ~[~str],
|
||||
cfgs: ~[~str], opt: bool, test: bool) -> bool {
|
||||
compile_input(driver::str_input(code), dir, flags, cfgs, opt, test)
|
||||
compile_input(sysroot, driver::str_input(code), dir, flags, cfgs, opt, test)
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
@ -1002,6 +1036,7 @@ pub fn link_exe(src: &Path, dest: &Path) -> bool unsafe {
|
||||
fn test_is_cmd() {
|
||||
assert is_cmd(~"build");
|
||||
assert is_cmd(~"clean");
|
||||
assert is_cmd(~"do");
|
||||
assert is_cmd(~"install");
|
||||
assert is_cmd(~"prefer");
|
||||
assert is_cmd(~"test");
|
||||
|
Loading…
x
Reference in New Issue
Block a user