Skip to content

Commit

Permalink
rustpkg: Add do command and get cmd listeners working correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
z0w0 authored and graydon committed Feb 16, 2013
1 parent 7079441 commit e34e072
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 25 deletions.
29 changes: 20 additions & 9 deletions src/librustpkg/api.rs
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
}
Expand Down
47 changes: 44 additions & 3 deletions src/librustpkg/rustpkg.rc
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
_ => {}
}
}
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 },
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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(),
Expand Down
7 changes: 7 additions & 0 deletions src/librustpkg/usage.rs
Expand Up @@ -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]

Expand Down
61 changes: 48 additions & 13 deletions src/librustpkg/util.rs
Expand Up @@ -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)
}
Expand Down Expand Up @@ -74,6 +74,7 @@ fn mk_rustpkg_use(ctx: @ReadyCtx) -> @ast::view_item {
}

struct ListenerFn {
cmds: ~[~str],
span: codemap::span,
path: ~[ast::ident]
}
Expand Down Expand Up @@ -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
});
Expand Down Expand Up @@ -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(),
Expand All @@ -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,
});

Expand Down Expand Up @@ -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");
Expand All @@ -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);
Expand Down Expand Up @@ -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)]
Expand Down Expand Up @@ -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");
Expand Down

0 comments on commit e34e072

Please sign in to comment.