Skip to content

Commit

Permalink
cargo: Add local mode and use it by default
Browse files Browse the repository at this point in the history
  • Loading branch information
tychosci authored and brson committed Feb 9, 2012
1 parent 0b4851c commit 48e206e
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 31 deletions.
93 changes: 62 additions & 31 deletions src/cargo/cargo.rs
Expand Up @@ -5,7 +5,7 @@ use std;

import rustc::syntax::{ast, codemap};
import rustc::syntax::parse::parser;
import rustc::util::filesearch::get_cargo_root;
import rustc::util::filesearch::{get_cargo_root, get_cargo_root_nearest};
import rustc::driver::diagnostic;

import std::fs;
Expand All @@ -19,6 +19,8 @@ import std::run;
import str;
import std::tempfile;
import vec;
import std::getopts;
import getopts::{optflag, opt_present};

enum _src {
/* Break cycles in package <-> source */
Expand Down Expand Up @@ -53,7 +55,7 @@ type cargo = {
workdir: str,
sourcedir: str,
sources: map::hashmap<str, source>,
mutable test: bool
opts: options
};

type pkg = {
Expand All @@ -65,6 +67,16 @@ type pkg = {
crate_type: option<str>
};

type options = {
test: bool,
cwd: bool,
free: [str],
};

fn opts() -> [getopts::opt] {
[optflag("g"), optflag("global"), optflag("test")]
}

fn info(msg: str) {
io::stdout().write_line("info: " + msg);
}
Expand Down Expand Up @@ -322,8 +334,28 @@ fn load_source_packages(&c: cargo, &src: source) {
};
}

fn configure() -> cargo {
let p = alt get_cargo_root() {
fn build_cargo_options(argv: [str]) -> options {
let match = alt getopts::getopts(argv, opts()) {
result::ok(m) { m }
result::err(f) {
fail #fmt["%s", getopts::fail_str(f)];
}
};

let test = opt_present(match, "test");
let cwd = !(opt_present(match, "g") || opt_present(match, "global"));

{test: test, cwd: cwd, free: match.free}
}

fn configure(opts: options) -> cargo {
let get_cargo_dir = if opts.cwd {
get_cargo_root_nearest
} else {
get_cargo_root
};

let p = alt get_cargo_dir() {
result::ok(p) { p }
result::err(e) { fail e }
};
Expand All @@ -339,7 +371,7 @@ fn configure() -> cargo {
workdir: fs::connect(p, "work"),
sourcedir: fs::connect(p, "sources"),
sources: sources,
mutable test: false
opts: opts
};

need_dir(c.root);
Expand Down Expand Up @@ -430,7 +462,7 @@ fn install_source(c: cargo, path: str) {
alt p {
none { cont; }
some(_p) {
if c.test {
if c.opts.test {
test_one_crate(c, path, cf, _p);
}
install_one_crate(c, path, cf, _p);
Expand Down Expand Up @@ -573,19 +605,14 @@ fn install_named_specific(c: cargo, wd: str, src: str, name: str) {
error("Can't find package " + src + "/" + name);
}

fn cmd_install(c: cargo, argv: [str]) unsafe {
fn cmd_install(c: cargo) unsafe {
// cargo install <pkg>
if vec::len(argv) < 3u {
if vec::len(c.opts.free) < 3u {
cmd_usage();
ret;
}

let target = argv[2];
// TODO: getopts
if vec::len(argv) > 3u && argv[2] == "--test" {
c.test = true;
target = argv[3];
}
let target = c.opts.free[2];

let wd = alt tempfile::mkdtemp(c.workdir + fs::path_sep(), "") {
some(_wd) { _wd }
Expand Down Expand Up @@ -671,9 +698,9 @@ fn sync_one(c: cargo, name: str, src: source) {
run::run_program("cp", [pkgfile, destpkgfile]);
}

fn cmd_sync(c: cargo, argv: [str]) {
if vec::len(argv) == 3u {
sync_one(c, argv[2], c.sources.get(argv[2]));
fn cmd_sync(c: cargo) {
if vec::len(c.opts.free) == 3u {
sync_one(c, c.opts.free[2], c.sources.get(c.opts.free[2]));
} else {
cargo_suggestion(c, true, { || } );
c.sources.items { |k, v|
Expand Down Expand Up @@ -721,22 +748,22 @@ fn print_pkg(s: source, p: package) {
print(" >> " + p.description + "\n")
}
}
fn cmd_list(c: cargo, argv: [str]) {
fn cmd_list(c: cargo) {
for_each_package(c, { |s, p|
if vec::len(argv) <= 2u || argv[2] == s.name {
if vec::len(c.opts.free) <= 2u || c.opts.free[2] == s.name {
print_pkg(s, p);
}
});
}

fn cmd_search(c: cargo, argv: [str]) {
if vec::len(argv) < 3u {
fn cmd_search(c: cargo) {
if vec::len(c.opts.free) < 3u {
cmd_usage();
ret;
}
let n = 0;
let name = argv[2];
let tags = vec::slice(argv, 3u, vec::len(argv));
let name = c.opts.free[2];
let tags = vec::slice(c.opts.free, 3u, vec::len(c.opts.free));
for_each_package(c, { |s, p|
if (str::contains(p.name, name) || name == "*") &&
vec::all(tags, { |t| vec::member(t, p.tags) }) {
Expand All @@ -749,7 +776,7 @@ fn cmd_search(c: cargo, argv: [str]) {

fn cmd_usage() {
print("Usage: cargo <verb> [args...]");
print(" init Set up ~/.cargo");
print(" init Set up .cargo");
print(" install [--test] [source/]package-name Install by name");
print(" install [--test] uuid:[source/]package-uuid Install by uuid");
print(" list [source] List packages");
Expand All @@ -759,17 +786,21 @@ fn cmd_usage() {
}

fn main(argv: [str]) {
if vec::len(argv) < 2u {
let o = build_cargo_options(argv);

if vec::len(o.free) < 2u {
cmd_usage();
ret;
}
let c = configure();
alt argv[1] {

let c = configure(o);

alt o.free[1] {
"init" { cmd_init(c); }
"install" { cmd_install(c, argv); }
"list" { cmd_list(c, argv); }
"search" { cmd_search(c, argv); }
"sync" { cmd_sync(c, argv); }
"install" { cmd_install(c); }
"list" { cmd_list(c); }
"search" { cmd_search(c); }
"sync" { cmd_sync(c); }
"usage" { cmd_usage(); }
_ { cmd_usage(); }
}
Expand Down
37 changes: 37 additions & 0 deletions src/comp/util/filesearch.rs
Expand Up @@ -11,6 +11,7 @@ export pick_file;
export search;
export relative_target_lib_path;
export get_cargo_root;
export get_cargo_root_nearest;
export libdir;

type pick<T> = fn(path: fs::path) -> option<T>;
Expand Down Expand Up @@ -38,6 +39,10 @@ fn mk_filesearch(maybe_sysroot: option<fs::path>,
fn lib_search_paths() -> [fs::path] {
self.addl_lib_search_paths
+ [make_target_lib_path(self.sysroot, self.target_triple)]
+ alt get_cargo_lib_path_nearest() {
result::ok(p) { [p] }
result::err(p) { [] }
}
+ alt get_cargo_lib_path() {
result::ok(p) { [p] }
result::err(p) { [] }
Expand Down Expand Up @@ -116,12 +121,44 @@ fn get_cargo_root() -> result::t<fs::path, str> {
}
}

fn get_cargo_root_nearest() -> result::t<fs::path, str> {
result::chain(get_cargo_root()) { |p|
let cwd = os::getcwd();
let dirname = fs::dirname(cwd);
let dirpath = fs::split(dirname);
let cwd_cargo = fs::connect(cwd, ".cargo");
let par_cargo = fs::connect(dirname, ".cargo");

// FIXME: this duplicates lib path
if cwd_cargo == p {
ret result::ok(p);
}

while vec::is_not_empty(dirpath) && par_cargo != p {
if fs::path_is_dir(par_cargo) {
ret result::ok(par_cargo);
}
vec::pop(dirpath);
dirname = fs::dirname(dirname);
par_cargo = fs::connect(dirname, ".cargo");
}

result::ok(cwd_cargo)
}
}

fn get_cargo_lib_path() -> result::t<fs::path, str> {
result::chain(get_cargo_root()) { |p|
result::ok(fs::connect(p, libdir()))
}
}

fn get_cargo_lib_path_nearest() -> result::t<fs::path, str> {
result::chain(get_cargo_root_nearest()) { |p|
result::ok(fs::connect(p, libdir()))
}
}

// The name of the directory rustc expects libraries to be located.
// On Unix should be "lib", on windows "bin"
fn libdir() -> str {
Expand Down

0 comments on commit 48e206e

Please sign in to comment.