Skip to content

Rustpkg #6054

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed

Rustpkg #6054

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/libcore/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ use vec;
pub use libc::fclose;
pub use os::consts::*;

// FIXME: move these to str perhaps? #2620

pub fn close(fd: c_int) -> c_int {
unsafe {
libc::close(fd)
Expand Down Expand Up @@ -79,6 +77,8 @@ pub fn getcwd() -> Path {
}
}

// FIXME: move these to str perhaps? #2620

pub fn as_c_charp<T>(s: &str, f: &fn(*c_char) -> T) -> T {
str::as_c_str(s, |b| f(b as *c_char))
}
Expand Down
26 changes: 23 additions & 3 deletions src/librustpkg/README.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,24 @@
Right now (2013-04-11), only one package works, the branch of rust-sdl at:
https://github.com/catamorphism/rust-sdl/tree/new-rustpkg
Right now, commands that work are "build" and "clean".

and only one command works, "build".
`rustpkg build` and `rustpkg clean` should work

for example:
$ cd ~/rust/src/librustpkg/testsuite/pass
$ rustpkg build hello-world
... some output ...
$ rustpkg clean hello-world

-------------
the following test packages in librustpkg/testsuite/pass:
* hello-world
* install-paths
* simple-lib
* deeply/nested/path
* fancy-lib

It fails on the following test packages:
* external-crate (no support for `extern mod` inference yet)

and should fail with proper error messages
on all of the test packages in librustpkg/testsuite/fail
* no-inferred-crates
5 changes: 5 additions & 0 deletions src/librustpkg/conditions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@
// Useful conditions

pub use core::path::Path;
pub use util::PkgId;

condition! {
bad_path: (super::Path, ~str) -> super::Path;
}

condition! {
nonexistent_package: (super::PkgId, ~str) -> super::Path;
}
21 changes: 21 additions & 0 deletions src/librustpkg/context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Context data structure used by rustpkg

use core::hashmap::HashMap;

pub struct Ctx {
// I'm not sure what this is for
json: bool,
// Cache of hashes of things already installed
// though I'm not sure why the value is a bool
dep_cache: @mut HashMap<~str, bool>,
}
168 changes: 116 additions & 52 deletions src/librustpkg/path_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,39 +15,43 @@ use core::{os, str};
use core::option::*;
use util::PkgId;

/// Returns the output directory to use.
/// Right now is always the default, should
/// support changing it.
pub fn dest_dir(pkgid: PkgId) -> Path {
default_dest_dir(&pkgid.path)
#[deriving(Eq)]
pub enum OutputType { Main, Lib, Bench, Test }

/// Returns the value of RUST_PATH, as a list
/// of Paths. In general this should be read from the
/// environment; for now, it's hard-wired to just be "."
pub fn rust_path() -> ~[Path] {
~[Path(".")]
}

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

// For now: assumes that pkg_dir exists and is relative
// to the CWD. Change this later when we do path searching.
let rslt = pkg_dir.push("build");
let is_dir = os::path_is_dir(&rslt);
if os::path_exists(&rslt) {
if is_dir {
rslt
}
else {
cond.raise((rslt, ~"Path names a file that isn't a directory"))
}
os::make_dir(p, (S_IRUSR | S_IWUSR | S_IXUSR) as i32)
}

/// Creates a directory that is readable, writeable,
/// and executable by the user. Returns true iff creation
/// succeeded. Also creates all intermediate subdirectories
/// if they don't already exist.
pub fn mkdir_recursive(p: &Path) -> bool {
if os::path_is_dir(p) {
return true;
}
let parent = p.dir_path();
debug!("mkdir_recursive: parent = %s",
parent.to_str());
if parent.to_str() == ~"."
|| parent.to_str() == ~"/" { // !!!
// No parent directories to create
os::path_is_dir(&parent) && make_dir_rwx(p)
}
else {
// Create it
if os::make_dir(&rslt, (S_IRUSR | S_IWUSR | S_IXUSR) as i32) {
rslt
}
else {
cond.raise((rslt, ~"Could not create directory"))
}
mkdir_recursive(&parent) && make_dir_rwx(p)
}
}

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

// n.b. So far this only handles local workspaces
// n.b. The next three functions ignore the package version right
// now. Should fix that.

/// True if there's a directory in <workspace> with
/// pkgid's short name
pub fn workspace_contains_package_id(pkgid: PkgId, workspace: &Path) -> bool {
let pkgpath = workspace.push("src").push(pkgid.path.to_str());
os::path_is_dir(&pkgpath)
}

/// Return the directory for <pkgid>'s source files in <workspace>.
/// Doesn't check that it exists.
pub fn pkgid_src_in_workspace(pkgid: PkgId, workspace: &Path) -> Path {
let result = workspace.push("src");
result.push(pkgid.path.to_str())
}

/// Returns the executable that would be installed for <pkgid>
/// in <workspace>
pub fn target_executable_in_workspace(pkgid: PkgId, workspace: &Path) -> Path {
let result = workspace.push("bin");
// should use a target-specific subdirectory
mk_output_path(Main, pkgid.path.to_str(), result)
}


/// Returns the executable that would be installed for <pkgid>
/// in <workspace>
pub fn target_library_in_workspace(pkgid: PkgId, workspace: &Path) -> Path {
let result = workspace.push("lib");
mk_output_path(Lib, pkgid.path.to_str(), result)
}

/// Returns the test executable that would be installed for <pkgid>
/// in <workspace>
pub fn target_test_in_workspace(pkgid: PkgId, workspace: &Path) -> Path {
let result = workspace.push("build");
mk_output_path(Test, pkgid.path.to_str(), result)
}

/// Returns the bench executable that would be installed for <pkgid>
/// in <workspace>
pub fn target_bench_in_workspace(pkgid: PkgId, workspace: &Path) -> Path {
let result = workspace.push("build");
mk_output_path(Bench, pkgid.path.to_str(), result)
}

/// Return the directory for <pkgid>'s build artifacts in <workspace>.
/// Creates it if it doesn't exist.
pub fn build_pkg_id_in_workspace(pkgid: PkgId, workspace: &Path) -> Path {
use conditions::bad_path::cond;

let mut result = workspace.push("build");
// n.b. Should actually use a target-specific
// subdirectory of build/
result = result.push(normalize(~pkgid.path).to_str());
if os::path_exists(&result) || mkdir_recursive(&result) {
result
}
else {
cond.raise((result, fmt!("Could not create directory for package %s", pkgid.to_str())))
}
}

/// Return the output file for a given directory name,
/// given whether we're building a library and whether we're building tests
pub fn mk_output_path(what: OutputType, short_name: ~str, dir: Path) -> Path {
match what {
Lib => dir.push(os::dll_filename(short_name)),
_ => dir.push(fmt!("%s%s%s", short_name,
if what == Test { ~"test" } else { ~"" },
os::EXE_SUFFIX))
}
}

#[cfg(test)]
mod test {
use core::{os, rand};
use core::path::Path;
use path_util::*;
use core::rand::RngUtil;

// Helper function to create a directory name that doesn't exist
pub fn mk_nonexistent(tmpdir: &Path, suffix: &str) -> Path {
let r = rand::rng();
for 1000.times {
let p = tmpdir.push(r.gen_str(16) + suffix);
if !os::path_exists(&p) {
return p;
}
}
fail!(~"Couldn't compute a non-existent path name; this is worrisome")
}
use core::os;

#[test]
fn default_dir_ok() {
let the_path = os::tmpdir();
let substitute_path = Path("xyzzy");
assert!(default_dest_dir(&the_path) == the_path.push(~"build"));
let nonexistent_path = mk_nonexistent(&the_path, "quux");
let bogus = do ::conditions::bad_path::cond.trap(|_| {
substitute_path
}).in { default_dest_dir(&nonexistent_path) };
assert!(bogus == substitute_path);
fn recursive_mkdir_ok() {
let root = os::tmpdir();
let path = "xy/z/zy";
let nested = root.push(path);
assert!(super::mkdir_recursive(&nested));
assert!(os::path_is_dir(&root.push("xy")));
assert!(os::path_is_dir(&root.push("xy/z")));
assert!(os::path_is_dir(&nested));
}
}
Loading