auto merge of #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).
This commit is contained in:
commit
0604468fd5
@ -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)
|
||||
@ -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))
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
src/librustpkg/context.rs
Normal file
21
src/librustpkg/context.rs
Normal file
@ -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>,
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,34 +73,94 @@ pub fn normalize(p: ~Path) -> ~Path {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use core::{os, rand};
|
||||
use core::path::Path;
|
||||
use path_util::*;
|
||||
use core::rand::RngUtil;
|
||||
// n.b. So far this only handles local workspaces
|
||||
// n.b. The next three functions ignore the package version right
|
||||
// now. Should fix that.
|
||||
|
||||
// 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")
|
||||
/// 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
|
||||
}
|
||||
|
||||
#[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);
|
||||
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;
|
||||
|
||||
#[test]
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -36,13 +36,19 @@ use rustc::metadata::filesearch;
|
||||
use std::{getopts};
|
||||
use syntax::{ast, diagnostic};
|
||||
use util::*;
|
||||
use path_util::{dest_dir, normalize};
|
||||
use path_util::normalize;
|
||||
use path_util::{build_pkg_id_in_workspace, pkgid_src_in_workspace};
|
||||
use workspace::pkg_parent_workspaces;
|
||||
use rustc::driver::session::{lib_crate, bin_crate, crate_type};
|
||||
use context::Ctx;
|
||||
|
||||
mod conditions;
|
||||
mod context;
|
||||
mod usage;
|
||||
mod path_util;
|
||||
mod tests;
|
||||
mod util;
|
||||
mod workspace;
|
||||
|
||||
/// A PkgScript represents user-supplied custom logic for
|
||||
/// special build hooks. This only exists for packages with
|
||||
@ -70,7 +76,7 @@ impl PkgScript {
|
||||
/// Given the path name for a package script
|
||||
/// and a package ID, parse the package script into
|
||||
/// a PkgScript that we can then execute
|
||||
fn parse(script: Path, id: PkgId) -> PkgScript {
|
||||
fn parse(script: Path, workspace: &Path, id: PkgId) -> PkgScript {
|
||||
// Get the executable name that was invoked
|
||||
let binary = os::args()[0];
|
||||
// Build the rustc session data structures to pass
|
||||
@ -85,7 +91,7 @@ impl PkgScript {
|
||||
let cfg = driver::build_configuration(sess, @binary, &input);
|
||||
let (crate, _) = driver::compile_upto(sess, cfg, &input,
|
||||
driver::cu_parse, None);
|
||||
let work_dir = dest_dir(id);
|
||||
let work_dir = build_pkg_id_in_workspace(id, workspace);
|
||||
|
||||
debug!("Returning package script with id %?", id);
|
||||
|
||||
@ -153,14 +159,6 @@ impl PkgScript {
|
||||
|
||||
}
|
||||
|
||||
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>,
|
||||
}
|
||||
|
||||
impl Ctx {
|
||||
|
||||
fn run(&self, cmd: ~str, args: ~[~str]) {
|
||||
@ -193,54 +191,50 @@ impl Ctx {
|
||||
// The package id is presumed to be the first command-line
|
||||
// argument
|
||||
let pkgid = PkgId::new(args[0]);
|
||||
// Should allow the build directory to be configured.
|
||||
// Right now it's always the "build" subdirectory in
|
||||
// the package directory
|
||||
let dst_dir = dest_dir(pkgid);
|
||||
debug!("Destination dir = %s", dst_dir.to_str());
|
||||
// Right now, we assume the pkgid path is a valid dir
|
||||
// relative to the CWD. In the future, we should search
|
||||
// paths
|
||||
let cwd = os::getcwd().normalize();
|
||||
debug!("Current working directory = %s", cwd.to_str());
|
||||
for pkg_parent_workspaces(pkgid) |workspace| {
|
||||
let src_dir = pkgid_src_in_workspace(pkgid, workspace);
|
||||
let build_dir = build_pkg_id_in_workspace(pkgid, workspace);
|
||||
debug!("Destination dir = %s", build_dir.to_str());
|
||||
|
||||
// Create the package source
|
||||
let mut src = PkgSrc::new(&cwd, &dst_dir, &pkgid);
|
||||
debug!("Package src = %?", src);
|
||||
// Create the package source
|
||||
let mut src = PkgSrc::new(&workspace.push("src"), &build_dir, &pkgid);
|
||||
debug!("Package src = %?", src);
|
||||
|
||||
// Is there custom build logic? If so, use it
|
||||
let pkg_src_dir = cwd.push_rel(&pkgid.path);
|
||||
let mut custom = false;;
|
||||
debug!("Package source directory = %s", pkg_src_dir.to_str());
|
||||
let cfgs = match src.package_script_option(&pkg_src_dir) {
|
||||
Some(package_script_path) => {
|
||||
let pscript = PkgScript::parse(package_script_path,
|
||||
pkgid);
|
||||
// Limited right now -- we're only running the post_build
|
||||
// hook and probably fail otherwise
|
||||
// also post_build should be called pre_build
|
||||
let (cfgs, hook_result) = pscript.run_custom(~"post_build");
|
||||
debug!("Command return code = %?", hook_result);
|
||||
if hook_result != 0 {
|
||||
fail!(fmt!("Error running custom build command"))
|
||||
// Is there custom build logic? If so, use it
|
||||
let pkg_src_dir = src_dir;
|
||||
let mut custom = false;
|
||||
debug!("Package source directory = %s", pkg_src_dir.to_str());
|
||||
let cfgs = match src.package_script_option(&pkg_src_dir) {
|
||||
Some(package_script_path) => {
|
||||
let pscript = PkgScript::parse(package_script_path,
|
||||
workspace,
|
||||
pkgid);
|
||||
// Limited right now -- we're only running the post_build
|
||||
// hook and probably fail otherwise
|
||||
// also post_build should be called pre_build
|
||||
let (cfgs, hook_result) = pscript.run_custom(~"post_build");
|
||||
debug!("Command return code = %?", hook_result);
|
||||
if hook_result != 0 {
|
||||
fail!(fmt!("Error running custom build command"))
|
||||
}
|
||||
custom = true;
|
||||
// otherwise, the package script succeeded
|
||||
cfgs
|
||||
}
|
||||
custom = true;
|
||||
// otherwise, the package script succeeded
|
||||
cfgs
|
||||
}
|
||||
None => {
|
||||
debug!("No package script, continuing");
|
||||
~[]
|
||||
}
|
||||
};
|
||||
None => {
|
||||
debug!("No package script, continuing");
|
||||
~[]
|
||||
}
|
||||
};
|
||||
|
||||
// If there was a package script, it should have finished
|
||||
// the build already. Otherwise...
|
||||
if !custom {
|
||||
// Find crates inside the workspace
|
||||
src.find_crates();
|
||||
// Build it!
|
||||
src.build(&dst_dir, cfgs);
|
||||
// If there was a package script, it should have finished
|
||||
// the build already. Otherwise...
|
||||
if !custom {
|
||||
// Find crates inside the workspace
|
||||
src.find_crates();
|
||||
// Build it!
|
||||
src.build(&build_dir, cfgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
~"clean" => {
|
||||
@ -250,8 +244,8 @@ impl Ctx {
|
||||
// The package id is presumed to be the first command-line
|
||||
// argument
|
||||
let pkgid = PkgId::new(args[0]);
|
||||
|
||||
self.clean(pkgid);
|
||||
let cwd = os::getcwd();
|
||||
self.clean(&cwd, pkgid); // tjc: should use workspace, not cwd
|
||||
}
|
||||
~"do" => {
|
||||
if args.len() < 2 {
|
||||
@ -264,10 +258,16 @@ impl Ctx {
|
||||
self.info();
|
||||
}
|
||||
~"install" => {
|
||||
self.install(if args.len() >= 1 { Some(args[0]) }
|
||||
else { None },
|
||||
if args.len() >= 2 { Some(args[1]) }
|
||||
else { None }, false);
|
||||
if args.len() < 1 {
|
||||
return usage::install();
|
||||
}
|
||||
|
||||
// The package id is presumed to be the first command-line
|
||||
// argument
|
||||
let pkgid = PkgId::new(args[0]);
|
||||
for pkg_parent_workspaces(pkgid) |workspace| {
|
||||
self.install(workspace, pkgid);
|
||||
}
|
||||
}
|
||||
~"prefer" => {
|
||||
if args.len() < 1 {
|
||||
@ -303,58 +303,17 @@ impl Ctx {
|
||||
}
|
||||
}
|
||||
|
||||
fn do_cmd(&self, cmd: ~str, pkgname: ~str) {
|
||||
match cmd {
|
||||
~"build" | ~"test" => {
|
||||
util::error(~"that command cannot be manually called");
|
||||
fail!(~"do_cmd");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let cwd = &os::getcwd();
|
||||
let pkgid = PkgId::new(pkgname);
|
||||
// Always use the "build" subdirectory of the package dir,
|
||||
// but we should allow this to be configured
|
||||
let dst_dir = dest_dir(pkgid);
|
||||
|
||||
let mut src = PkgSrc::new(cwd, &dst_dir, &pkgid);
|
||||
match src.package_script_option(cwd) {
|
||||
Some(script_path) => {
|
||||
let script = PkgScript::parse(script_path, pkgid);
|
||||
let (_, status) = script.run_custom(cmd); // Ignore cfgs?
|
||||
if status == 42 {
|
||||
util::error(~"no fns are listening for that cmd");
|
||||
fail!(~"do_cmd");
|
||||
}
|
||||
}
|
||||
None => {
|
||||
util::error(fmt!("invoked `do`, but there is no package script in %s",
|
||||
cwd.to_str()));
|
||||
fail!(~"do_cmd");
|
||||
}
|
||||
}
|
||||
fn do_cmd(&self, _cmd: ~str, _pkgname: ~str) {
|
||||
// stub
|
||||
fail!(~"`do` not yet implemented");
|
||||
}
|
||||
|
||||
fn build(&self, _dir: &Path, _verbose: bool, _opt: bool,
|
||||
_test: bool) -> Option<PkgScript> {
|
||||
// either not needed anymore,
|
||||
// or needed only when we don't have a package script. Not sure which one.
|
||||
fail!();
|
||||
}
|
||||
|
||||
fn compile(&self, _crate: &Path, _dir: &Path, _flags: ~[~str],
|
||||
_cfgs: ~[~str], _opt: bool, _test: bool) {
|
||||
// What's the difference between build and compile?
|
||||
fail!(~"compile not yet implemented");
|
||||
}
|
||||
|
||||
fn clean(&self, id: PkgId) {
|
||||
fn clean(&self, workspace: &Path, id: PkgId) {
|
||||
// Could also support a custom build hook in the pkg
|
||||
// script for cleaning files rustpkg doesn't know about.
|
||||
// Do something reasonable for now
|
||||
|
||||
let dir = dest_dir(id);
|
||||
let dir = build_pkg_id_in_workspace(id, workspace);
|
||||
util::note(fmt!("Cleaning package %s (removing directory %s)",
|
||||
id.to_str(), dir.to_str()));
|
||||
if os::path_exists(&dir) {
|
||||
@ -370,8 +329,7 @@ impl Ctx {
|
||||
fail!(~"info not yet implemented");
|
||||
}
|
||||
|
||||
fn install(&self, _url: Option<~str>,
|
||||
_target: Option<~str>, _cache: bool) {
|
||||
fn install(&self, _workspace: &Path, _id: PkgId) {
|
||||
// stub
|
||||
fail!(~"install not yet implemented");
|
||||
}
|
||||
|
@ -9,3 +9,96 @@
|
||||
// except according to those terms.
|
||||
|
||||
// rustpkg unit tests
|
||||
|
||||
use context::Ctx;
|
||||
use core::hashmap::HashMap;
|
||||
use core::path::Path;
|
||||
use core::os;
|
||||
use core::io;
|
||||
use core::option::*;
|
||||
use std::tempfile::mkdtemp;
|
||||
use util::{PkgId, default_version};
|
||||
use path_util::{target_executable_in_workspace, target_library_in_workspace,
|
||||
target_test_in_workspace, target_bench_in_workspace,
|
||||
make_dir_rwx};
|
||||
|
||||
fn fake_ctxt() -> Ctx {
|
||||
Ctx {
|
||||
json: false,
|
||||
dep_cache: @mut HashMap::new()
|
||||
}
|
||||
}
|
||||
|
||||
fn fake_pkg() -> PkgId {
|
||||
PkgId {
|
||||
path: Path(~"bogus"),
|
||||
version: default_version()
|
||||
}
|
||||
}
|
||||
|
||||
fn mk_temp_workspace() -> Path {
|
||||
mkdtemp(&os::tmpdir(), "test").expect("couldn't create temp dir")
|
||||
}
|
||||
|
||||
fn is_rwx(p: &Path) -> bool {
|
||||
use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
|
||||
|
||||
match p.get_mode() {
|
||||
None => return false,
|
||||
Some(m) => {
|
||||
((m & S_IRUSR as uint) == S_IRUSR as uint
|
||||
&& (m & S_IWUSR as uint) == S_IWUSR as uint
|
||||
&& (m & S_IXUSR as uint) == S_IXUSR as uint)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_make_dir_rwx() {
|
||||
let temp = &os::tmpdir();
|
||||
let dir = temp.push(~"quux");
|
||||
let _ = os::remove_dir(&dir);
|
||||
assert!(make_dir_rwx(&dir));
|
||||
assert!(os::path_is_dir(&dir));
|
||||
assert!(is_rwx(&dir));
|
||||
assert!(os::remove_dir(&dir));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore(reason = "install not yet implemented")]
|
||||
fn test_install_valid() {
|
||||
let ctxt = fake_ctxt();
|
||||
let temp_pkg_id = fake_pkg();
|
||||
let temp_workspace() = mk_temp_workspace();
|
||||
// should have test, bench, lib, and main
|
||||
ctxt.install(&temp_workspace, temp_pkg_id);
|
||||
// Check that all files exist
|
||||
let exec = target_executable_in_workspace(temp_pkg_id, &temp_workspace);
|
||||
assert!(os::path_exists(&exec));
|
||||
assert!(is_rwx(&exec));
|
||||
let lib = target_library_in_workspace(temp_pkg_id, &temp_workspace);
|
||||
assert!(os::path_exists(&lib));
|
||||
assert!(is_rwx(&lib));
|
||||
// And that the test and bench executables aren't installed
|
||||
assert!(!os::path_exists(&target_test_in_workspace(temp_pkg_id, &temp_workspace)));
|
||||
assert!(!os::path_exists(&target_bench_in_workspace(temp_pkg_id, &temp_workspace)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore(reason = "install not yet implemented")]
|
||||
fn test_install_invalid() {
|
||||
use conditions::nonexistent_package::cond;
|
||||
|
||||
let ctxt = fake_ctxt();
|
||||
let pkgid = fake_pkg();
|
||||
let temp_workspace = mk_temp_workspace();
|
||||
let expected_path = Path(~"quux");
|
||||
let substituted: Path = do cond.trap(|_| {
|
||||
expected_path
|
||||
}).in {
|
||||
ctxt.install(&temp_workspace, pkgid);
|
||||
// ok
|
||||
fail!(~"test_install_invalid failed, should have raised a condition");
|
||||
};
|
||||
assert!(substituted == expected_path);
|
||||
}
|
@ -21,4 +21,4 @@ extern mod std;
|
||||
|
||||
pub mod foo;
|
||||
pub mod bar;
|
||||
#[path = "build/generated.rs"] pub mod generated;
|
||||
#[path = "../../build/fancy_lib/generated.rs"] pub mod generated;
|
@ -11,13 +11,18 @@
|
||||
use core::run;
|
||||
|
||||
pub fn main() {
|
||||
let cwd = os::getcwd();
|
||||
debug!("cwd = %s", cwd.to_str());
|
||||
let file = io::file_writer(&Path(~"fancy-lib/build/generated.rs"),
|
||||
use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
|
||||
|
||||
let out_path = Path(~"build/fancy_lib");
|
||||
if !os::path_exists(&out_path) {
|
||||
assert!(os::make_dir(&out_path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
|
||||
}
|
||||
|
||||
let file = io::file_writer(&out_path.push("generated.rs"),
|
||||
[io::Create]).get();
|
||||
file.write_str("pub fn wheeeee() { for [1, 2, 3].each() |_| { assert!(true); } }");
|
||||
|
||||
// now compile the crate itself
|
||||
run::run_program("rustc", ~[~"fancy-lib/fancy-lib.rs", ~"--lib",
|
||||
~"-o", ~"fancy-lib/build/fancy_lib"]);
|
||||
run::run_program("rustc", ~[~"src/fancy-lib/fancy-lib.rs", ~"--lib",
|
||||
~"-o", out_path.push(~"fancy_lib").to_str()]);
|
||||
}
|
@ -78,7 +78,7 @@ impl ToStr for Version {
|
||||
}
|
||||
|
||||
/// Placeholder
|
||||
fn default_version() -> Version { ExactRevision(0.1) }
|
||||
pub fn default_version() -> Version { ExactRevision(0.1) }
|
||||
|
||||
// Path-fragment identifier of a package such as
|
||||
// 'github.com/graydon/test'; path must be a relative
|
||||
@ -116,7 +116,14 @@ pub impl PkgId {
|
||||
impl ToStr for PkgId {
|
||||
fn to_str(&self) -> ~str {
|
||||
// should probably use the filestem and not the whole path
|
||||
fmt!("%s-%s", self.path.to_str(), self.version.to_str())
|
||||
fmt!("%s-%s", self.path.to_str(),
|
||||
// Replace dots with -s in the version
|
||||
// this is because otherwise rustc will think
|
||||
// that foo-0.1 has .1 as its extension
|
||||
// (Temporary hack until I figure out how to
|
||||
// get rustc to not name the object file
|
||||
// foo-0.o if I pass in foo-0.1 to build_output_filenames)
|
||||
str::replace(self.version.to_str(), ".", "-"))
|
||||
}
|
||||
}
|
||||
|
||||
@ -438,7 +445,9 @@ pub fn compile_input(sysroot: Option<Path>,
|
||||
test: bool,
|
||||
crate_type: session::crate_type) -> bool {
|
||||
|
||||
let short_name = pkg_id.to_str();
|
||||
// Want just the directory component here
|
||||
let pkg_filename = pkg_id.path.filename().expect(~"Weird pkg id");
|
||||
let short_name = fmt!("%s-%s", pkg_filename, pkg_id.version.to_str());
|
||||
|
||||
assert!(in_file.components.len() > 1);
|
||||
let input = driver::file_input(copy *in_file);
|
||||
@ -515,7 +524,7 @@ pub fn compile_crate_from_input(input: driver::input,
|
||||
out_file: Path,
|
||||
binary: ~str,
|
||||
what: driver::compile_upto) -> @ast::crate {
|
||||
debug!("Calling build_output_filenames with %?", build_dir_opt);
|
||||
debug!("Calling build_output_filenames with %? and %s", build_dir_opt, out_file.to_str());
|
||||
let outputs = driver::build_output_filenames(&input, &build_dir_opt, &Some(out_file), sess);
|
||||
debug!("Outputs are %? and output type = %?", outputs, sess.opts.output_type);
|
||||
let cfg = driver::build_configuration(sess, @binary, &input);
|
||||
|
34
src/librustpkg/workspace.rs
Normal file
34
src/librustpkg/workspace.rs
Normal file
@ -0,0 +1,34 @@
|
||||
// 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.
|
||||
|
||||
// rustpkg utilities having to do with workspaces
|
||||
|
||||
use path_util::{rust_path, workspace_contains_package_id};
|
||||
use util::PkgId;
|
||||
use core::path::Path;
|
||||
|
||||
pub fn pkg_parent_workspaces(pkgid: PkgId, action: &fn(&Path) -> bool) {
|
||||
// Using the RUST_PATH, find workspaces that contain
|
||||
// this package ID
|
||||
let workspaces = rust_path().filtered(|ws|
|
||||
workspace_contains_package_id(pkgid, ws));
|
||||
if workspaces.is_empty() {
|
||||
// tjc: make this a condition
|
||||
fail!(fmt!("Package %s not found in any of \
|
||||
the following workspaces: %s",
|
||||
pkgid.path.to_str(),
|
||||
rust_path().to_str()));
|
||||
}
|
||||
for workspaces.each |ws| {
|
||||
if action(ws) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user