Skip to content

Commit 0604468

Browse files
committed
auto merge of rust-lang#6054 : catamorphism/rust/rustpkg, r=graydon
r? @graydon Sorry, this pull request is a few different things at once, but I tried to make them separate commits. First, as before, this should do file searching the way that's described in the doc now. Second, there's also some preliminary work on the install command (really just tests for it).
2 parents ac69ee4 + 4e2c8f4 commit 0604468

File tree

18 files changed

+387
-178
lines changed

18 files changed

+387
-178
lines changed

src/libcore/os.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ use vec;
4343
pub use libc::fclose;
4444
pub use os::consts::*;
4545

46-
// FIXME: move these to str perhaps? #2620
47-
4846
pub fn close(fd: c_int) -> c_int {
4947
unsafe {
5048
libc::close(fd)
@@ -79,6 +77,8 @@ pub fn getcwd() -> Path {
7977
}
8078
}
8179

80+
// FIXME: move these to str perhaps? #2620
81+
8282
pub fn as_c_charp<T>(s: &str, f: &fn(*c_char) -> T) -> T {
8383
str::as_c_str(s, |b| f(b as *c_char))
8484
}

src/librustpkg/README.txt

+23-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,24 @@
1-
Right now (2013-04-11), only one package works, the branch of rust-sdl at:
2-
https://github.com/catamorphism/rust-sdl/tree/new-rustpkg
1+
Right now, commands that work are "build" and "clean".
32

4-
and only one command works, "build".
3+
`rustpkg build` and `rustpkg clean` should work
4+
5+
for example:
6+
$ cd ~/rust/src/librustpkg/testsuite/pass
7+
$ rustpkg build hello-world
8+
... some output ...
9+
$ rustpkg clean hello-world
10+
11+
-------------
12+
the following test packages in librustpkg/testsuite/pass:
13+
* hello-world
14+
* install-paths
15+
* simple-lib
16+
* deeply/nested/path
17+
* fancy-lib
18+
19+
It fails on the following test packages:
20+
* external-crate (no support for `extern mod` inference yet)
21+
22+
and should fail with proper error messages
23+
on all of the test packages in librustpkg/testsuite/fail
24+
* no-inferred-crates

src/librustpkg/conditions.rs

+5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@
1111
// Useful conditions
1212

1313
pub use core::path::Path;
14+
pub use util::PkgId;
1415

1516
condition! {
1617
bad_path: (super::Path, ~str) -> super::Path;
1718
}
19+
20+
condition! {
21+
nonexistent_package: (super::PkgId, ~str) -> super::Path;
22+
}

src/librustpkg/context.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Context data structure used by rustpkg
12+
13+
use core::hashmap::HashMap;
14+
15+
pub struct Ctx {
16+
// I'm not sure what this is for
17+
json: bool,
18+
// Cache of hashes of things already installed
19+
// though I'm not sure why the value is a bool
20+
dep_cache: @mut HashMap<~str, bool>,
21+
}

src/librustpkg/path_util.rs

+116-52
Original file line numberDiff line numberDiff line change
@@ -15,39 +15,43 @@ use core::{os, str};
1515
use core::option::*;
1616
use util::PkgId;
1717

18-
/// Returns the output directory to use.
19-
/// Right now is always the default, should
20-
/// support changing it.
21-
pub fn dest_dir(pkgid: PkgId) -> Path {
22-
default_dest_dir(&pkgid.path)
18+
#[deriving(Eq)]
19+
pub enum OutputType { Main, Lib, Bench, Test }
20+
21+
/// Returns the value of RUST_PATH, as a list
22+
/// of Paths. In general this should be read from the
23+
/// environment; for now, it's hard-wired to just be "."
24+
pub fn rust_path() -> ~[Path] {
25+
~[Path(".")]
2326
}
2427

25-
/// Returns the default output directory for compilation.
26-
/// Creates that directory if it doesn't exist.
27-
pub fn default_dest_dir(pkg_dir: &Path) -> Path {
28+
/// Creates a directory that is readable, writeable,
29+
/// and executable by the user. Returns true iff creation
30+
/// succeeded.
31+
pub fn make_dir_rwx(p: &Path) -> bool {
2832
use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
29-
use conditions::bad_path::cond;
3033

31-
// For now: assumes that pkg_dir exists and is relative
32-
// to the CWD. Change this later when we do path searching.
33-
let rslt = pkg_dir.push("build");
34-
let is_dir = os::path_is_dir(&rslt);
35-
if os::path_exists(&rslt) {
36-
if is_dir {
37-
rslt
38-
}
39-
else {
40-
cond.raise((rslt, ~"Path names a file that isn't a directory"))
41-
}
34+
os::make_dir(p, (S_IRUSR | S_IWUSR | S_IXUSR) as i32)
35+
}
36+
37+
/// Creates a directory that is readable, writeable,
38+
/// and executable by the user. Returns true iff creation
39+
/// succeeded. Also creates all intermediate subdirectories
40+
/// if they don't already exist.
41+
pub fn mkdir_recursive(p: &Path) -> bool {
42+
if os::path_is_dir(p) {
43+
return true;
44+
}
45+
let parent = p.dir_path();
46+
debug!("mkdir_recursive: parent = %s",
47+
parent.to_str());
48+
if parent.to_str() == ~"."
49+
|| parent.to_str() == ~"/" { // !!!
50+
// No parent directories to create
51+
os::path_is_dir(&parent) && make_dir_rwx(p)
4252
}
4353
else {
44-
// Create it
45-
if os::make_dir(&rslt, (S_IRUSR | S_IWUSR | S_IXUSR) as i32) {
46-
rslt
47-
}
48-
else {
49-
cond.raise((rslt, ~"Could not create directory"))
50-
}
54+
mkdir_recursive(&parent) && make_dir_rwx(p)
5155
}
5256
}
5357

@@ -69,34 +73,94 @@ pub fn normalize(p: ~Path) -> ~Path {
6973
}
7074
}
7175

76+
// n.b. So far this only handles local workspaces
77+
// n.b. The next three functions ignore the package version right
78+
// now. Should fix that.
79+
80+
/// True if there's a directory in <workspace> with
81+
/// pkgid's short name
82+
pub fn workspace_contains_package_id(pkgid: PkgId, workspace: &Path) -> bool {
83+
let pkgpath = workspace.push("src").push(pkgid.path.to_str());
84+
os::path_is_dir(&pkgpath)
85+
}
86+
87+
/// Return the directory for <pkgid>'s source files in <workspace>.
88+
/// Doesn't check that it exists.
89+
pub fn pkgid_src_in_workspace(pkgid: PkgId, workspace: &Path) -> Path {
90+
let result = workspace.push("src");
91+
result.push(pkgid.path.to_str())
92+
}
93+
94+
/// Returns the executable that would be installed for <pkgid>
95+
/// in <workspace>
96+
pub fn target_executable_in_workspace(pkgid: PkgId, workspace: &Path) -> Path {
97+
let result = workspace.push("bin");
98+
// should use a target-specific subdirectory
99+
mk_output_path(Main, pkgid.path.to_str(), result)
100+
}
101+
102+
103+
/// Returns the executable that would be installed for <pkgid>
104+
/// in <workspace>
105+
pub fn target_library_in_workspace(pkgid: PkgId, workspace: &Path) -> Path {
106+
let result = workspace.push("lib");
107+
mk_output_path(Lib, pkgid.path.to_str(), result)
108+
}
109+
110+
/// Returns the test executable that would be installed for <pkgid>
111+
/// in <workspace>
112+
pub fn target_test_in_workspace(pkgid: PkgId, workspace: &Path) -> Path {
113+
let result = workspace.push("build");
114+
mk_output_path(Test, pkgid.path.to_str(), result)
115+
}
116+
117+
/// Returns the bench executable that would be installed for <pkgid>
118+
/// in <workspace>
119+
pub fn target_bench_in_workspace(pkgid: PkgId, workspace: &Path) -> Path {
120+
let result = workspace.push("build");
121+
mk_output_path(Bench, pkgid.path.to_str(), result)
122+
}
123+
124+
/// Return the directory for <pkgid>'s build artifacts in <workspace>.
125+
/// Creates it if it doesn't exist.
126+
pub fn build_pkg_id_in_workspace(pkgid: PkgId, workspace: &Path) -> Path {
127+
use conditions::bad_path::cond;
128+
129+
let mut result = workspace.push("build");
130+
// n.b. Should actually use a target-specific
131+
// subdirectory of build/
132+
result = result.push(normalize(~pkgid.path).to_str());
133+
if os::path_exists(&result) || mkdir_recursive(&result) {
134+
result
135+
}
136+
else {
137+
cond.raise((result, fmt!("Could not create directory for package %s", pkgid.to_str())))
138+
}
139+
}
140+
141+
/// Return the output file for a given directory name,
142+
/// given whether we're building a library and whether we're building tests
143+
pub fn mk_output_path(what: OutputType, short_name: ~str, dir: Path) -> Path {
144+
match what {
145+
Lib => dir.push(os::dll_filename(short_name)),
146+
_ => dir.push(fmt!("%s%s%s", short_name,
147+
if what == Test { ~"test" } else { ~"" },
148+
os::EXE_SUFFIX))
149+
}
150+
}
151+
72152
#[cfg(test)]
73153
mod test {
74-
use core::{os, rand};
75-
use core::path::Path;
76-
use path_util::*;
77-
use core::rand::RngUtil;
78-
79-
// Helper function to create a directory name that doesn't exist
80-
pub fn mk_nonexistent(tmpdir: &Path, suffix: &str) -> Path {
81-
let r = rand::rng();
82-
for 1000.times {
83-
let p = tmpdir.push(r.gen_str(16) + suffix);
84-
if !os::path_exists(&p) {
85-
return p;
86-
}
87-
}
88-
fail!(~"Couldn't compute a non-existent path name; this is worrisome")
89-
}
154+
use core::os;
90155
91156
#[test]
92-
fn default_dir_ok() {
93-
let the_path = os::tmpdir();
94-
let substitute_path = Path("xyzzy");
95-
assert!(default_dest_dir(&the_path) == the_path.push(~"build"));
96-
let nonexistent_path = mk_nonexistent(&the_path, "quux");
97-
let bogus = do ::conditions::bad_path::cond.trap(|_| {
98-
substitute_path
99-
}).in { default_dest_dir(&nonexistent_path) };
100-
assert!(bogus == substitute_path);
157+
fn recursive_mkdir_ok() {
158+
let root = os::tmpdir();
159+
let path = "xy/z/zy";
160+
let nested = root.push(path);
161+
assert!(super::mkdir_recursive(&nested));
162+
assert!(os::path_is_dir(&root.push("xy")));
163+
assert!(os::path_is_dir(&root.push("xy/z")));
164+
assert!(os::path_is_dir(&nested));
101165
}
102166
}

0 commit comments

Comments
 (0)