Skip to content

Commit 48e206e

Browse files
tychoscibrson
authored andcommitted
cargo: Add local mode and use it by default
1 parent 0b4851c commit 48e206e

File tree

2 files changed

+99
-31
lines changed

2 files changed

+99
-31
lines changed

src/cargo/cargo.rs

Lines changed: 62 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std;
55

66
import rustc::syntax::{ast, codemap};
77
import rustc::syntax::parse::parser;
8-
import rustc::util::filesearch::get_cargo_root;
8+
import rustc::util::filesearch::{get_cargo_root, get_cargo_root_nearest};
99
import rustc::driver::diagnostic;
1010

1111
import std::fs;
@@ -19,6 +19,8 @@ import std::run;
1919
import str;
2020
import std::tempfile;
2121
import vec;
22+
import std::getopts;
23+
import getopts::{optflag, opt_present};
2224

2325
enum _src {
2426
/* Break cycles in package <-> source */
@@ -53,7 +55,7 @@ type cargo = {
5355
workdir: str,
5456
sourcedir: str,
5557
sources: map::hashmap<str, source>,
56-
mutable test: bool
58+
opts: options
5759
};
5860

5961
type pkg = {
@@ -65,6 +67,16 @@ type pkg = {
6567
crate_type: option<str>
6668
};
6769

70+
type options = {
71+
test: bool,
72+
cwd: bool,
73+
free: [str],
74+
};
75+
76+
fn opts() -> [getopts::opt] {
77+
[optflag("g"), optflag("global"), optflag("test")]
78+
}
79+
6880
fn info(msg: str) {
6981
io::stdout().write_line("info: " + msg);
7082
}
@@ -322,8 +334,28 @@ fn load_source_packages(&c: cargo, &src: source) {
322334
};
323335
}
324336

325-
fn configure() -> cargo {
326-
let p = alt get_cargo_root() {
337+
fn build_cargo_options(argv: [str]) -> options {
338+
let match = alt getopts::getopts(argv, opts()) {
339+
result::ok(m) { m }
340+
result::err(f) {
341+
fail #fmt["%s", getopts::fail_str(f)];
342+
}
343+
};
344+
345+
let test = opt_present(match, "test");
346+
let cwd = !(opt_present(match, "g") || opt_present(match, "global"));
347+
348+
{test: test, cwd: cwd, free: match.free}
349+
}
350+
351+
fn configure(opts: options) -> cargo {
352+
let get_cargo_dir = if opts.cwd {
353+
get_cargo_root_nearest
354+
} else {
355+
get_cargo_root
356+
};
357+
358+
let p = alt get_cargo_dir() {
327359
result::ok(p) { p }
328360
result::err(e) { fail e }
329361
};
@@ -339,7 +371,7 @@ fn configure() -> cargo {
339371
workdir: fs::connect(p, "work"),
340372
sourcedir: fs::connect(p, "sources"),
341373
sources: sources,
342-
mutable test: false
374+
opts: opts
343375
};
344376

345377
need_dir(c.root);
@@ -430,7 +462,7 @@ fn install_source(c: cargo, path: str) {
430462
alt p {
431463
none { cont; }
432464
some(_p) {
433-
if c.test {
465+
if c.opts.test {
434466
test_one_crate(c, path, cf, _p);
435467
}
436468
install_one_crate(c, path, cf, _p);
@@ -573,19 +605,14 @@ fn install_named_specific(c: cargo, wd: str, src: str, name: str) {
573605
error("Can't find package " + src + "/" + name);
574606
}
575607

576-
fn cmd_install(c: cargo, argv: [str]) unsafe {
608+
fn cmd_install(c: cargo) unsafe {
577609
// cargo install <pkg>
578-
if vec::len(argv) < 3u {
610+
if vec::len(c.opts.free) < 3u {
579611
cmd_usage();
580612
ret;
581613
}
582614

583-
let target = argv[2];
584-
// TODO: getopts
585-
if vec::len(argv) > 3u && argv[2] == "--test" {
586-
c.test = true;
587-
target = argv[3];
588-
}
615+
let target = c.opts.free[2];
589616

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

674-
fn cmd_sync(c: cargo, argv: [str]) {
675-
if vec::len(argv) == 3u {
676-
sync_one(c, argv[2], c.sources.get(argv[2]));
701+
fn cmd_sync(c: cargo) {
702+
if vec::len(c.opts.free) == 3u {
703+
sync_one(c, c.opts.free[2], c.sources.get(c.opts.free[2]));
677704
} else {
678705
cargo_suggestion(c, true, { || } );
679706
c.sources.items { |k, v|
@@ -721,22 +748,22 @@ fn print_pkg(s: source, p: package) {
721748
print(" >> " + p.description + "\n")
722749
}
723750
}
724-
fn cmd_list(c: cargo, argv: [str]) {
751+
fn cmd_list(c: cargo) {
725752
for_each_package(c, { |s, p|
726-
if vec::len(argv) <= 2u || argv[2] == s.name {
753+
if vec::len(c.opts.free) <= 2u || c.opts.free[2] == s.name {
727754
print_pkg(s, p);
728755
}
729756
});
730757
}
731758

732-
fn cmd_search(c: cargo, argv: [str]) {
733-
if vec::len(argv) < 3u {
759+
fn cmd_search(c: cargo) {
760+
if vec::len(c.opts.free) < 3u {
734761
cmd_usage();
735762
ret;
736763
}
737764
let n = 0;
738-
let name = argv[2];
739-
let tags = vec::slice(argv, 3u, vec::len(argv));
765+
let name = c.opts.free[2];
766+
let tags = vec::slice(c.opts.free, 3u, vec::len(c.opts.free));
740767
for_each_package(c, { |s, p|
741768
if (str::contains(p.name, name) || name == "*") &&
742769
vec::all(tags, { |t| vec::member(t, p.tags) }) {
@@ -749,7 +776,7 @@ fn cmd_search(c: cargo, argv: [str]) {
749776

750777
fn cmd_usage() {
751778
print("Usage: cargo <verb> [args...]");
752-
print(" init Set up ~/.cargo");
779+
print(" init Set up .cargo");
753780
print(" install [--test] [source/]package-name Install by name");
754781
print(" install [--test] uuid:[source/]package-uuid Install by uuid");
755782
print(" list [source] List packages");
@@ -759,17 +786,21 @@ fn cmd_usage() {
759786
}
760787

761788
fn main(argv: [str]) {
762-
if vec::len(argv) < 2u {
789+
let o = build_cargo_options(argv);
790+
791+
if vec::len(o.free) < 2u {
763792
cmd_usage();
764793
ret;
765794
}
766-
let c = configure();
767-
alt argv[1] {
795+
796+
let c = configure(o);
797+
798+
alt o.free[1] {
768799
"init" { cmd_init(c); }
769-
"install" { cmd_install(c, argv); }
770-
"list" { cmd_list(c, argv); }
771-
"search" { cmd_search(c, argv); }
772-
"sync" { cmd_sync(c, argv); }
800+
"install" { cmd_install(c); }
801+
"list" { cmd_list(c); }
802+
"search" { cmd_search(c); }
803+
"sync" { cmd_sync(c); }
773804
"usage" { cmd_usage(); }
774805
_ { cmd_usage(); }
775806
}

src/comp/util/filesearch.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export pick_file;
1111
export search;
1212
export relative_target_lib_path;
1313
export get_cargo_root;
14+
export get_cargo_root_nearest;
1415
export libdir;
1516

1617
type pick<T> = fn(path: fs::path) -> option<T>;
@@ -38,6 +39,10 @@ fn mk_filesearch(maybe_sysroot: option<fs::path>,
3839
fn lib_search_paths() -> [fs::path] {
3940
self.addl_lib_search_paths
4041
+ [make_target_lib_path(self.sysroot, self.target_triple)]
42+
+ alt get_cargo_lib_path_nearest() {
43+
result::ok(p) { [p] }
44+
result::err(p) { [] }
45+
}
4146
+ alt get_cargo_lib_path() {
4247
result::ok(p) { [p] }
4348
result::err(p) { [] }
@@ -116,12 +121,44 @@ fn get_cargo_root() -> result::t<fs::path, str> {
116121
}
117122
}
118123

124+
fn get_cargo_root_nearest() -> result::t<fs::path, str> {
125+
result::chain(get_cargo_root()) { |p|
126+
let cwd = os::getcwd();
127+
let dirname = fs::dirname(cwd);
128+
let dirpath = fs::split(dirname);
129+
let cwd_cargo = fs::connect(cwd, ".cargo");
130+
let par_cargo = fs::connect(dirname, ".cargo");
131+
132+
// FIXME: this duplicates lib path
133+
if cwd_cargo == p {
134+
ret result::ok(p);
135+
}
136+
137+
while vec::is_not_empty(dirpath) && par_cargo != p {
138+
if fs::path_is_dir(par_cargo) {
139+
ret result::ok(par_cargo);
140+
}
141+
vec::pop(dirpath);
142+
dirname = fs::dirname(dirname);
143+
par_cargo = fs::connect(dirname, ".cargo");
144+
}
145+
146+
result::ok(cwd_cargo)
147+
}
148+
}
149+
119150
fn get_cargo_lib_path() -> result::t<fs::path, str> {
120151
result::chain(get_cargo_root()) { |p|
121152
result::ok(fs::connect(p, libdir()))
122153
}
123154
}
124155

156+
fn get_cargo_lib_path_nearest() -> result::t<fs::path, str> {
157+
result::chain(get_cargo_root_nearest()) { |p|
158+
result::ok(fs::connect(p, libdir()))
159+
}
160+
}
161+
125162
// The name of the directory rustc expects libraries to be located.
126163
// On Unix should be "lib", on windows "bin"
127164
fn libdir() -> str {

0 commit comments

Comments
 (0)