rustpkg: Allow package directories to appear in the RUST_PATH
This commit adds a rustpkg flag, --rust-path-hack, that allows rustpkg to *search* inside package directories if they appear in the RUST_PATH, while *building* libraries and executables into a different target directory. This behavior is hidden behind a flag because I believe we only want to support it temporarily, to make it easier to port servo to rustpkg. This commit also includes a fix for how rustpkg fetches sources from git repositories -- it uses a temporary directory as the target when invoking `git clone`, then moves that directory into the workspace if the clone was successful. (The old behavior was that when the `git clone` failed, the empty target directory would be left lying around anyway.)
This commit is contained in:
parent
7cbdee1663
commit
98e470ad73
@ -20,7 +20,12 @@
|
|||||||
/// Convenience functions intended for calling from pkg.rs
|
/// Convenience functions intended for calling from pkg.rs
|
||||||
|
|
||||||
fn default_ctxt(p: @Path) -> Ctx {
|
fn default_ctxt(p: @Path) -> Ctx {
|
||||||
Ctx { sysroot_opt: Some(p), json: false, dep_cache: @mut HashMap::new() }
|
Ctx {
|
||||||
|
use_rust_path_hack: false,
|
||||||
|
sysroot_opt: Some(p),
|
||||||
|
json: false,
|
||||||
|
dep_cache: @mut HashMap::new()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_lib(sysroot: @Path, root: Path, name: ~str, version: Version,
|
pub fn build_lib(sysroot: @Path, root: Path, name: ~str, version: Version,
|
||||||
|
@ -15,6 +15,11 @@
|
|||||||
use std::os;
|
use std::os;
|
||||||
|
|
||||||
pub struct Ctx {
|
pub struct Ctx {
|
||||||
|
// If use_rust_path_hack is true, rustpkg searches for sources
|
||||||
|
// in *package* directories that are in the RUST_PATH (for example,
|
||||||
|
// FOO/src/bar-0.1 instead of FOO). The flag doesn't affect where
|
||||||
|
// rustpkg stores build artifacts.
|
||||||
|
use_rust_path_hack: bool,
|
||||||
// Sysroot -- if this is None, uses rustc filesearch's
|
// Sysroot -- if this is None, uses rustc filesearch's
|
||||||
// idea of the default
|
// idea of the default
|
||||||
sysroot_opt: Option<@Path>,
|
sysroot_opt: Option<@Path>,
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
extern mod extra;
|
||||||
|
|
||||||
use target::*;
|
use target::*;
|
||||||
use package_id::PkgId;
|
use package_id::PkgId;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
@ -16,8 +18,9 @@
|
|||||||
use crate::Crate;
|
use crate::Crate;
|
||||||
use messages::*;
|
use messages::*;
|
||||||
use source_control::{git_clone, git_clone_general};
|
use source_control::{git_clone, git_clone_general};
|
||||||
use path_util::pkgid_src_in_workspace;
|
use path_util::{pkgid_src_in_workspace, find_dir_using_rust_path_hack, default_workspace};
|
||||||
use util::compile_crate;
|
use util::compile_crate;
|
||||||
|
use workspace::is_workspace;
|
||||||
|
|
||||||
// An enumeration of the unpacked source of a package workspace.
|
// An enumeration of the unpacked source of a package workspace.
|
||||||
// This contains a list of files found in the source workspace.
|
// This contains a list of files found in the source workspace.
|
||||||
@ -48,7 +51,7 @@ pub fn new(src_dir: &Path, id: &PkgId) -> PkgSrc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn check_dir(&self) -> Path {
|
fn check_dir(&self, cx: &Ctx) -> Path {
|
||||||
use conditions::nonexistent_package::cond;
|
use conditions::nonexistent_package::cond;
|
||||||
|
|
||||||
debug!("Pushing onto root: %s | %s", self.id.path.to_str(), self.root.to_str());
|
debug!("Pushing onto root: %s | %s", self.id.path.to_str(), self.root.to_str());
|
||||||
@ -59,12 +62,21 @@ fn check_dir(&self) -> Path {
|
|||||||
|
|
||||||
let dir = match path {
|
let dir = match path {
|
||||||
Some(d) => (*d).clone(),
|
Some(d) => (*d).clone(),
|
||||||
None => match self.fetch_git() {
|
None => {
|
||||||
Some(d) => d,
|
match self.fetch_git() {
|
||||||
None => cond.raise((self.id.clone(), ~"supplied path for package dir does not \
|
Some(d) => d,
|
||||||
exist, and couldn't interpret it as a URL fragment"))
|
None => {
|
||||||
|
match find_dir_using_rust_path_hack(cx, &self.id) {
|
||||||
|
Some(d) => d,
|
||||||
|
None => cond.raise((self.id.clone(),
|
||||||
|
~"supplied path for package dir does not \
|
||||||
|
exist, and couldn't interpret it as a URL fragment"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
debug!("For package id %s, returning %s", self.id.to_str(), dir.to_str());
|
||||||
if !os::path_is_dir(&dir) {
|
if !os::path_is_dir(&dir) {
|
||||||
cond.raise((self.id.clone(), ~"supplied path for package dir is a \
|
cond.raise((self.id.clone(), ~"supplied path for package dir is a \
|
||||||
non-directory"));
|
non-directory"));
|
||||||
@ -79,11 +91,19 @@ fn check_dir(&self) -> Path {
|
|||||||
/// refers to a git repo on the local version, also check it out.
|
/// refers to a git repo on the local version, also check it out.
|
||||||
/// (right now we only support git)
|
/// (right now we only support git)
|
||||||
pub fn fetch_git(&self) -> Option<Path> {
|
pub fn fetch_git(&self) -> Option<Path> {
|
||||||
|
use conditions::failed_to_create_temp_dir::cond;
|
||||||
|
|
||||||
|
// We use a temporary directory because if the git clone fails,
|
||||||
|
// it creates the target directory anyway and doesn't delete it
|
||||||
|
|
||||||
|
let scratch_dir = extra::tempfile::mkdtemp(&os::tmpdir(), "rustpkg");
|
||||||
|
let clone_target = match scratch_dir {
|
||||||
|
Some(d) => d.push("rustpkg_temp"),
|
||||||
|
None => cond.raise(~"Failed to create temporary directory for fetching git sources")
|
||||||
|
};
|
||||||
|
|
||||||
let mut local = self.root.push("src");
|
let mut local = self.root.push("src");
|
||||||
local = local.push(self.id.to_str());
|
local = local.push(self.id.to_str());
|
||||||
// Git can't clone into a non-empty directory
|
|
||||||
os::remove_dir_recursive(&local);
|
|
||||||
|
|
||||||
debug!("Checking whether %s exists locally. Cwd = %s, does it? %?",
|
debug!("Checking whether %s exists locally. Cwd = %s, does it? %?",
|
||||||
self.id.path.to_str(),
|
self.id.path.to_str(),
|
||||||
@ -93,15 +113,28 @@ pub fn fetch_git(&self) -> Option<Path> {
|
|||||||
if os::path_exists(&self.id.path) {
|
if os::path_exists(&self.id.path) {
|
||||||
debug!("%s exists locally! Cloning it into %s",
|
debug!("%s exists locally! Cloning it into %s",
|
||||||
self.id.path.to_str(), local.to_str());
|
self.id.path.to_str(), local.to_str());
|
||||||
|
// Ok to use local here; we know it will succeed
|
||||||
git_clone(&self.id.path, &local, &self.id.version);
|
git_clone(&self.id.path, &local, &self.id.version);
|
||||||
return Some(local);
|
return Some(local);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self.id.path.clone()).components().len() < 2 {
|
||||||
|
// If a non-URL, don't bother trying to fetch
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
let url = fmt!("https://%s", self.id.path.to_str());
|
let url = fmt!("https://%s", self.id.path.to_str());
|
||||||
note(fmt!("Fetching package: git clone %s %s [version=%s]",
|
note(fmt!("Fetching package: git clone %s %s [version=%s]",
|
||||||
url, local.to_str(), self.id.version.to_str()));
|
url, clone_target.to_str(), self.id.version.to_str()));
|
||||||
if git_clone_general(url, &local, &self.id.version) {
|
|
||||||
Some(local)
|
if git_clone_general(url, &clone_target, &self.id.version) {
|
||||||
|
// since the operation succeeded, move clone_target to local
|
||||||
|
if !os::rename_file(&clone_target, &local) {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Some(local)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
None
|
None
|
||||||
@ -138,10 +171,10 @@ fn push_crate(cs: &mut ~[Crate], prefix: uint, p: &Path) {
|
|||||||
|
|
||||||
/// Infers crates to build. Called only in the case where there
|
/// Infers crates to build. Called only in the case where there
|
||||||
/// is no custom build logic
|
/// is no custom build logic
|
||||||
pub fn find_crates(&mut self) {
|
pub fn find_crates(&mut self, cx: &Ctx) {
|
||||||
use conditions::missing_pkg_files::cond;
|
use conditions::missing_pkg_files::cond;
|
||||||
|
|
||||||
let dir = self.check_dir();
|
let dir = self.check_dir(cx);
|
||||||
debug!("Called check_dir, I'm in %s", dir.to_str());
|
debug!("Called check_dir, I'm in %s", dir.to_str());
|
||||||
let prefix = dir.components.len();
|
let prefix = dir.components.len();
|
||||||
debug!("Matching against %?", self.id.short_name);
|
debug!("Matching against %?", self.id.short_name);
|
||||||
@ -183,6 +216,7 @@ pub fn find_crates(&mut self) {
|
|||||||
fn build_crates(&self,
|
fn build_crates(&self,
|
||||||
ctx: &Ctx,
|
ctx: &Ctx,
|
||||||
src_dir: &Path,
|
src_dir: &Path,
|
||||||
|
destination_dir: &Path,
|
||||||
crates: &[Crate],
|
crates: &[Crate],
|
||||||
cfgs: &[~str],
|
cfgs: &[~str],
|
||||||
what: OutputType) {
|
what: OutputType) {
|
||||||
@ -194,8 +228,8 @@ fn build_crates(&self,
|
|||||||
let result = compile_crate(ctx,
|
let result = compile_crate(ctx,
|
||||||
&self.id,
|
&self.id,
|
||||||
path,
|
path,
|
||||||
// compile_crate wants the workspace
|
// compile_crate wants the destination workspace
|
||||||
&self.root,
|
destination_dir,
|
||||||
crate.flags,
|
crate.flags,
|
||||||
crate.cfgs + cfgs,
|
crate.cfgs + cfgs,
|
||||||
false,
|
false,
|
||||||
@ -209,15 +243,39 @@ fn build_crates(&self,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(&self, ctx: &Ctx, cfgs: ~[~str]) {
|
pub fn build(&self, ctx: &Ctx, cfgs: ~[~str]) -> Path {
|
||||||
let dir = self.check_dir();
|
use conditions::not_a_workspace::cond;
|
||||||
debug!("Building libs in %s", dir.to_str());
|
|
||||||
self.build_crates(ctx, &dir, self.libs, cfgs, Lib);
|
// Determine the destination workspace (which depends on whether
|
||||||
|
// we're using the rust_path_hack)
|
||||||
|
let destination_workspace = if is_workspace(&self.root) {
|
||||||
|
debug!("%s is indeed a workspace", self.root.to_str());
|
||||||
|
self.root.clone()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// It would be nice to have only one place in the code that checks
|
||||||
|
// for the use_rust_path_hack flag...
|
||||||
|
if ctx.use_rust_path_hack {
|
||||||
|
let rs = default_workspace();
|
||||||
|
debug!("Using hack: %s", rs.to_str());
|
||||||
|
rs
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cond.raise(fmt!("Package root %s is not a workspace; pass in --rust_path_hack \
|
||||||
|
if you want to treat it as a package source", self.root.to_str()))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let dir = self.check_dir(ctx);
|
||||||
|
debug!("Building libs in %s, destination = %s", dir.to_str(),
|
||||||
|
destination_workspace.to_str());
|
||||||
|
self.build_crates(ctx, &dir, &destination_workspace, self.libs, cfgs, Lib);
|
||||||
debug!("Building mains");
|
debug!("Building mains");
|
||||||
self.build_crates(ctx, &dir, self.mains, cfgs, Main);
|
self.build_crates(ctx, &dir, &destination_workspace, self.mains, cfgs, Main);
|
||||||
debug!("Building tests");
|
debug!("Building tests");
|
||||||
self.build_crates(ctx, &dir, self.tests, cfgs, Test);
|
self.build_crates(ctx, &dir, &destination_workspace, self.tests, cfgs, Test);
|
||||||
debug!("Building benches");
|
debug!("Building benches");
|
||||||
self.build_crates(ctx, &dir, self.benchs, cfgs, Bench);
|
self.build_crates(ctx, &dir, &destination_workspace, self.benchs, cfgs, Bench);
|
||||||
|
destination_workspace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
pub use target::{OutputType, Main, Lib, Test, Bench, Target, Build, Install};
|
pub use target::{OutputType, Main, Lib, Test, Bench, Target, Build, Install};
|
||||||
pub use version::{Version, NoVersion, split_version_general, try_parsing_version};
|
pub use version::{Version, NoVersion, split_version_general, try_parsing_version};
|
||||||
pub use rustc::metadata::filesearch::rust_path;
|
pub use rustc::metadata::filesearch::rust_path;
|
||||||
|
use context::Ctx;
|
||||||
|
|
||||||
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
|
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
|
||||||
use std::os::mkdir_recursive;
|
use std::os::mkdir_recursive;
|
||||||
@ -51,18 +52,23 @@ pub fn make_dir_rwx(p: &Path) -> bool { os::make_dir(p, U_RWX) }
|
|||||||
pub fn workspace_contains_package_id(pkgid: &PkgId, workspace: &Path) -> bool {
|
pub fn workspace_contains_package_id(pkgid: &PkgId, workspace: &Path) -> bool {
|
||||||
debug!("Checking in src dir of %s for %s",
|
debug!("Checking in src dir of %s for %s",
|
||||||
workspace.to_str(), pkgid.to_str());
|
workspace.to_str(), pkgid.to_str());
|
||||||
|
workspace_contains_package_id_(pkgid, workspace, |p| { p.push("src") }).is_some()
|
||||||
|
}
|
||||||
|
|
||||||
let src_dir = workspace.push("src");
|
pub fn workspace_contains_package_id_(pkgid: &PkgId, workspace: &Path,
|
||||||
|
// Returns the directory it was actually found in
|
||||||
|
workspace_to_src_dir: &fn(&Path) -> Path) -> Option<Path> {
|
||||||
|
let src_dir = workspace_to_src_dir(workspace);
|
||||||
|
|
||||||
let mut found = false;
|
let mut found = None;
|
||||||
do os::walk_dir(&src_dir) |p| {
|
do os::walk_dir(&src_dir) |p| {
|
||||||
debug!("=> p = %s", p.to_str());
|
debug!("=> p = %s", p.to_str());
|
||||||
|
|
||||||
let was_found = os::path_is_dir(p) && {
|
if os::path_is_dir(p) {
|
||||||
debug!("p = %s, path = %s [%s]", p.to_str(), pkgid.path.to_str(),
|
debug!("p = %s, path = %s [%s]", p.to_str(), pkgid.path.to_str(),
|
||||||
src_dir.push_rel(&pkgid.path).to_str());
|
src_dir.push_rel(&pkgid.path).to_str());
|
||||||
|
|
||||||
*p == src_dir.push_rel(&pkgid.path) || {
|
if *p == src_dir.push_rel(&pkgid.path) || {
|
||||||
let pf = p.filename();
|
let pf = p.filename();
|
||||||
do pf.iter().any |pf| {
|
do pf.iter().any |pf| {
|
||||||
let g = pf.to_str();
|
let g = pf.to_str();
|
||||||
@ -76,16 +82,15 @@ pub fn workspace_contains_package_id(pkgid: &PkgId, workspace: &Path) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} {
|
||||||
|
found = Some(p.clone());
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
if was_found {
|
};
|
||||||
found = true
|
|
||||||
}
|
|
||||||
true
|
true
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!(if found { fmt!("Found %s in %s", pkgid.to_str(), workspace.to_str()) }
|
debug!(if found.is_some() { fmt!("Found %s in %s", pkgid.to_str(), workspace.to_str()) }
|
||||||
else { fmt!("Didn't find %s in %s", pkgid.to_str(), workspace.to_str()) });
|
else { fmt!("Didn't find %s in %s", pkgid.to_str(), workspace.to_str()) });
|
||||||
found
|
found
|
||||||
}
|
}
|
||||||
@ -123,8 +128,7 @@ pub fn built_executable_in_workspace(pkgid: &PkgId, workspace: &Path) -> Option<
|
|||||||
Some(result)
|
Some(result)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// This is not an error, but it's worth logging it
|
debug!("built_executable_in_workspace: %s does not exist", result.to_str());
|
||||||
error!(fmt!("built_executable_in_workspace: %s does not exist", result.to_str()));
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -164,7 +168,7 @@ pub fn built_library_in_workspace(pkgid: &PkgId, workspace: &Path) -> Option<Pat
|
|||||||
|
|
||||||
/// Does the actual searching stuff
|
/// Does the actual searching stuff
|
||||||
pub fn installed_library_in_workspace(short_name: &str, workspace: &Path) -> Option<Path> {
|
pub fn installed_library_in_workspace(short_name: &str, workspace: &Path) -> Option<Path> {
|
||||||
// NOTE: this could break once we're handling multiple versions better... want a test for it
|
// This could break once we're handling multiple versions better -- I should add a test for it
|
||||||
library_in_workspace(&Path(short_name), short_name, Install, workspace, "lib", &NoVersion)
|
library_in_workspace(&Path(short_name), short_name, Install, workspace, "lib", &NoVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,8 +250,8 @@ pub fn library_in_workspace(path: &Path, short_name: &str, where: Target,
|
|||||||
} // for
|
} // for
|
||||||
|
|
||||||
if result_filename.is_none() {
|
if result_filename.is_none() {
|
||||||
warn(fmt!("library_in_workspace didn't find a library in %s for %s",
|
debug!("warning: library_in_workspace didn't find a library in %s for %s",
|
||||||
dir_to_search.to_str(), short_name));
|
dir_to_search.to_str(), short_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the filename that matches, which we now know exists
|
// Return the filename that matches, which we now know exists
|
||||||
@ -392,3 +396,25 @@ pub fn uninstall_package_from(workspace: &Path, pkgid: &PkgId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn dir_has_file(dir: &Path, file: &str) -> bool {
|
||||||
|
assert!(dir.is_absolute());
|
||||||
|
os::path_exists(&dir.push(file))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn find_dir_using_rust_path_hack(cx: &Ctx, p: &PkgId) -> Option<Path> {
|
||||||
|
if !cx.use_rust_path_hack {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let rp = rust_path();
|
||||||
|
for dir in rp.iter() {
|
||||||
|
debug!("In find_dir_using_rust_path_hack: checking dir %s", dir.to_str());
|
||||||
|
if dir_has_file(dir, "lib.rs") || dir_has_file(dir, "main.rs")
|
||||||
|
|| dir_has_file(dir, "test.rs") || dir_has_file(dir, "bench.rs") {
|
||||||
|
debug!("Did find id %s in dir %s", p.to_str(), dir.to_str());
|
||||||
|
return Some(dir.clone());
|
||||||
|
}
|
||||||
|
debug!("Didn't find id %s in dir %s", p.to_str(), dir.to_str())
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
@ -22,12 +22,7 @@
|
|||||||
extern mod rustc;
|
extern mod rustc;
|
||||||
extern mod syntax;
|
extern mod syntax;
|
||||||
|
|
||||||
use std::result;
|
use std::{io, os, result, run, str};
|
||||||
use std::io;
|
|
||||||
use std::os;
|
|
||||||
use std::run;
|
|
||||||
use std::str;
|
|
||||||
|
|
||||||
pub use std::path::Path;
|
pub use std::path::Path;
|
||||||
use std::hashmap::HashMap;
|
use std::hashmap::HashMap;
|
||||||
|
|
||||||
@ -173,7 +168,8 @@ fn hash(&self) -> ~str {
|
|||||||
pub trait CtxMethods {
|
pub trait CtxMethods {
|
||||||
fn run(&self, cmd: &str, args: ~[~str]);
|
fn run(&self, cmd: &str, args: ~[~str]);
|
||||||
fn do_cmd(&self, _cmd: &str, _pkgname: &str);
|
fn do_cmd(&self, _cmd: &str, _pkgname: &str);
|
||||||
fn build(&self, workspace: &Path, pkgid: &PkgId);
|
/// Returns the destination workspace
|
||||||
|
fn build(&self, workspace: &Path, pkgid: &PkgId) -> Path;
|
||||||
fn clean(&self, workspace: &Path, id: &PkgId);
|
fn clean(&self, workspace: &Path, id: &PkgId);
|
||||||
fn info(&self);
|
fn info(&self);
|
||||||
fn install(&self, workspace: &Path, id: &PkgId);
|
fn install(&self, workspace: &Path, id: &PkgId);
|
||||||
@ -191,15 +187,19 @@ fn run(&self, cmd: &str, args: ~[~str]) {
|
|||||||
"build" => {
|
"build" => {
|
||||||
if args.len() < 1 {
|
if args.len() < 1 {
|
||||||
match cwd_to_workspace() {
|
match cwd_to_workspace() {
|
||||||
None => { usage::build(); return }
|
None if self.use_rust_path_hack => {
|
||||||
Some((ws, pkgid)) => self.build(&ws, &pkgid)
|
let cwd = os::getcwd();
|
||||||
|
self.build(&cwd, &PkgId::new(cwd.components[cwd.components.len() - 1]));
|
||||||
|
}
|
||||||
|
None => { usage::build(); return; }
|
||||||
|
Some((ws, pkgid)) => { self.build(&ws, &pkgid); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// The package id is presumed to be the first command-line
|
// The package id is presumed to be the first command-line
|
||||||
// argument
|
// argument
|
||||||
let pkgid = PkgId::new(args[0].clone());
|
let pkgid = PkgId::new(args[0].clone());
|
||||||
do each_pkg_parent_workspace(&pkgid) |workspace| {
|
do each_pkg_parent_workspace(self, &pkgid) |workspace| {
|
||||||
debug!("found pkg %s in workspace %s, trying to build",
|
debug!("found pkg %s in workspace %s, trying to build",
|
||||||
pkgid.to_str(), workspace.to_str());
|
pkgid.to_str(), workspace.to_str());
|
||||||
self.build(workspace, &pkgid);
|
self.build(workspace, &pkgid);
|
||||||
@ -238,15 +238,20 @@ fn run(&self, cmd: &str, args: ~[~str]) {
|
|||||||
"install" => {
|
"install" => {
|
||||||
if args.len() < 1 {
|
if args.len() < 1 {
|
||||||
match cwd_to_workspace() {
|
match cwd_to_workspace() {
|
||||||
None => { usage::install(); return }
|
None if self.use_rust_path_hack => {
|
||||||
Some((ws, pkgid)) => self.install(&ws, &pkgid)
|
let cwd = os::getcwd();
|
||||||
}
|
self.install(&cwd,
|
||||||
|
&PkgId::new(cwd.components[cwd.components.len() - 1]));
|
||||||
|
}
|
||||||
|
None => { usage::install(); return; }
|
||||||
|
Some((ws, pkgid)) => self.install(&ws, &pkgid),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// The package id is presumed to be the first command-line
|
// The package id is presumed to be the first command-line
|
||||||
// argument
|
// argument
|
||||||
let pkgid = PkgId::new(args[0]);
|
let pkgid = PkgId::new(args[0]);
|
||||||
let workspaces = pkg_parent_workspaces(&pkgid);
|
let workspaces = pkg_parent_workspaces(self, &pkgid);
|
||||||
debug!("package ID = %s, found it in %? workspaces",
|
debug!("package ID = %s, found it in %? workspaces",
|
||||||
pkgid.to_str(), workspaces.len());
|
pkgid.to_str(), workspaces.len());
|
||||||
if workspaces.is_empty() {
|
if workspaces.is_empty() {
|
||||||
@ -257,7 +262,7 @@ fn run(&self, cmd: &str, args: ~[~str]) {
|
|||||||
self.install(&rp[0], &pkgid);
|
self.install(&rp[0], &pkgid);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
do each_pkg_parent_workspace(&pkgid) |workspace| {
|
do each_pkg_parent_workspace(self, &pkgid) |workspace| {
|
||||||
self.install(workspace, &pkgid);
|
self.install(workspace, &pkgid);
|
||||||
true
|
true
|
||||||
};
|
};
|
||||||
@ -294,7 +299,7 @@ fn run(&self, cmd: &str, args: ~[~str]) {
|
|||||||
else {
|
else {
|
||||||
let rp = rust_path();
|
let rp = rust_path();
|
||||||
assert!(!rp.is_empty());
|
assert!(!rp.is_empty());
|
||||||
do each_pkg_parent_workspace(&pkgid) |workspace| {
|
do each_pkg_parent_workspace(self, &pkgid) |workspace| {
|
||||||
path_util::uninstall_package_from(workspace, &pkgid);
|
path_util::uninstall_package_from(workspace, &pkgid);
|
||||||
note(fmt!("Uninstalled package %s (was installed in %s)",
|
note(fmt!("Uninstalled package %s (was installed in %s)",
|
||||||
pkgid.to_str(), workspace.to_str()));
|
pkgid.to_str(), workspace.to_str()));
|
||||||
@ -318,7 +323,9 @@ fn do_cmd(&self, _cmd: &str, _pkgname: &str) {
|
|||||||
fail!("`do` not yet implemented");
|
fail!("`do` not yet implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build(&self, workspace: &Path, pkgid: &PkgId) {
|
/// Returns the destination workspace
|
||||||
|
/// In the case of a custom build, we don't know, so we just return the source workspace
|
||||||
|
fn build(&self, workspace: &Path, pkgid: &PkgId) -> Path {
|
||||||
debug!("build: workspace = %s (in Rust path? %? is git dir? %? \
|
debug!("build: workspace = %s (in Rust path? %? is git dir? %? \
|
||||||
pkgid = %s", workspace.to_str(),
|
pkgid = %s", workspace.to_str(),
|
||||||
in_rust_path(workspace), is_git_dir(&workspace.push_rel(&pkgid.path)),
|
in_rust_path(workspace), is_git_dir(&workspace.push_rel(&pkgid.path)),
|
||||||
@ -374,9 +381,13 @@ fn build(&self, workspace: &Path, pkgid: &PkgId) {
|
|||||||
// the build already. Otherwise...
|
// the build already. Otherwise...
|
||||||
if !custom {
|
if !custom {
|
||||||
// Find crates inside the workspace
|
// Find crates inside the workspace
|
||||||
src.find_crates();
|
src.find_crates(self);
|
||||||
// Build it!
|
// Build it!
|
||||||
src.build(self, cfgs);
|
src.build(self, cfgs)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Just return the source workspace
|
||||||
|
workspace.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,12 +413,15 @@ fn info(&self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn install(&self, workspace: &Path, id: &PkgId) {
|
fn install(&self, workspace: &Path, id: &PkgId) {
|
||||||
// FIXME #7402: Use RUST_PATH to determine target dir
|
|
||||||
// Also should use workcache to not build if not necessary.
|
// Also should use workcache to not build if not necessary.
|
||||||
self.build(workspace, id);
|
let destination_workspace = self.build(workspace, id);
|
||||||
debug!("install: workspace = %s, id = %s", workspace.to_str(),
|
// See #7402: This still isn't quite right yet; we want to
|
||||||
id.to_str());
|
// install to the first workspace in the RUST_PATH if there's
|
||||||
self.install_no_build(workspace, id);
|
// a non-default RUST_PATH. This code installs to the same
|
||||||
|
// workspace the package was built in.
|
||||||
|
debug!("install: destination workspace = %s, id = %s",
|
||||||
|
destination_workspace.to_str(), id.to_str());
|
||||||
|
self.install_no_build(&destination_workspace, id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,7 +487,8 @@ pub fn main_args(args: &[~str]) {
|
|||||||
let opts = ~[getopts::optflag("h"), getopts::optflag("help"),
|
let opts = ~[getopts::optflag("h"), getopts::optflag("help"),
|
||||||
getopts::optflag("j"), getopts::optflag("json"),
|
getopts::optflag("j"), getopts::optflag("json"),
|
||||||
getopts::optmulti("c"), getopts::optmulti("cfg"),
|
getopts::optmulti("c"), getopts::optmulti("cfg"),
|
||||||
getopts::optflag("v"), getopts::optflag("version")];
|
getopts::optflag("v"), getopts::optflag("version"),
|
||||||
|
getopts::optflag("r"), getopts::optflag("rust-path-hack")];
|
||||||
let matches = &match getopts::getopts(args, opts) {
|
let matches = &match getopts::getopts(args, opts) {
|
||||||
result::Ok(m) => m,
|
result::Ok(m) => m,
|
||||||
result::Err(f) => {
|
result::Err(f) => {
|
||||||
@ -493,6 +508,9 @@ pub fn main_args(args: &[~str]) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let use_rust_path_hack = getopts::opt_present(matches, "r") ||
|
||||||
|
getopts::opt_present(matches, "rust-path-hack");
|
||||||
|
|
||||||
let mut args = matches.free.clone();
|
let mut args = matches.free.clone();
|
||||||
|
|
||||||
args.shift();
|
args.shift();
|
||||||
@ -501,33 +519,48 @@ pub fn main_args(args: &[~str]) {
|
|||||||
return usage::general();
|
return usage::general();
|
||||||
}
|
}
|
||||||
|
|
||||||
let cmd = args.shift();
|
let mut cmd_opt = None;
|
||||||
|
for a in args.iter() {
|
||||||
if !util::is_cmd(cmd) {
|
if util::is_cmd(*a) {
|
||||||
return usage::general();
|
cmd_opt = Some(a);
|
||||||
} else if help {
|
break;
|
||||||
return match cmd {
|
}
|
||||||
~"build" => usage::build(),
|
|
||||||
~"clean" => usage::clean(),
|
|
||||||
~"do" => usage::do_cmd(),
|
|
||||||
~"info" => usage::info(),
|
|
||||||
~"install" => usage::install(),
|
|
||||||
~"list" => usage::list(),
|
|
||||||
~"prefer" => usage::prefer(),
|
|
||||||
~"test" => usage::test(),
|
|
||||||
~"uninstall" => usage::uninstall(),
|
|
||||||
~"unprefer" => usage::unprefer(),
|
|
||||||
_ => usage::general()
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
let cmd = match cmd_opt {
|
||||||
|
None => return usage::general(),
|
||||||
|
Some(cmd) => if help {
|
||||||
|
return match *cmd {
|
||||||
|
~"build" => usage::build(),
|
||||||
|
~"clean" => usage::clean(),
|
||||||
|
~"do" => usage::do_cmd(),
|
||||||
|
~"info" => usage::info(),
|
||||||
|
~"install" => usage::install(),
|
||||||
|
~"list" => usage::list(),
|
||||||
|
~"prefer" => usage::prefer(),
|
||||||
|
~"test" => usage::test(),
|
||||||
|
~"uninstall" => usage::uninstall(),
|
||||||
|
~"unprefer" => usage::unprefer(),
|
||||||
|
_ => usage::general()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cmd
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Pop off all flags, plus the command
|
||||||
|
let remaining_args = args.iter().skip_while(|s| !util::is_cmd(**s));
|
||||||
|
// I had to add this type annotation to get the code to typecheck
|
||||||
|
let mut remaining_args: ~[~str] = remaining_args.map(|s| (*s).clone()).collect();
|
||||||
|
remaining_args.shift();
|
||||||
let sroot = Some(@filesearch::get_or_default_sysroot());
|
let sroot = Some(@filesearch::get_or_default_sysroot());
|
||||||
debug!("Using sysroot: %?", sroot);
|
debug!("Using sysroot: %?", sroot);
|
||||||
Ctx {
|
Ctx {
|
||||||
|
use_rust_path_hack: use_rust_path_hack,
|
||||||
sysroot_opt: sroot, // Currently, only tests override this
|
sysroot_opt: sroot, // Currently, only tests override this
|
||||||
json: json,
|
json: json,
|
||||||
dep_cache: @mut HashMap::new()
|
dep_cache: @mut HashMap::new()
|
||||||
}.run(cmd, args);
|
}.run(*cmd, remaining_args)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,6 +34,7 @@ fn datestamp(p: &Path) -> Option<libc::time_t> {
|
|||||||
|
|
||||||
fn fake_ctxt(sysroot_opt: Option<@Path>) -> Ctx {
|
fn fake_ctxt(sysroot_opt: Option<@Path>) -> Ctx {
|
||||||
Ctx {
|
Ctx {
|
||||||
|
use_rust_path_hack: false,
|
||||||
sysroot_opt: sysroot_opt,
|
sysroot_opt: sysroot_opt,
|
||||||
json: false,
|
json: false,
|
||||||
dep_cache: @mut HashMap::new()
|
dep_cache: @mut HashMap::new()
|
||||||
@ -70,8 +71,8 @@ fn writeFile(file_path: &Path, contents: &str) {
|
|||||||
out.write_line(contents);
|
out.write_line(contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mk_empty_workspace(short_name: &Path, version: &Version) -> Path {
|
fn mk_empty_workspace(short_name: &Path, version: &Version, tag: &str) -> Path {
|
||||||
let workspace_dir = mkdtemp(&os::tmpdir(), "test").expect("couldn't create temp dir");
|
let workspace_dir = mkdtemp(&os::tmpdir(), tag).expect("couldn't create temp dir");
|
||||||
mk_workspace(&workspace_dir, short_name, version);
|
mk_workspace(&workspace_dir, short_name, version);
|
||||||
workspace_dir
|
workspace_dir
|
||||||
}
|
}
|
||||||
@ -86,7 +87,7 @@ fn mk_workspace(workspace: &Path, short_name: &Path, version: &Version) -> Path
|
|||||||
|
|
||||||
fn mk_temp_workspace(short_name: &Path, version: &Version) -> Path {
|
fn mk_temp_workspace(short_name: &Path, version: &Version) -> Path {
|
||||||
let package_dir = mk_empty_workspace(short_name,
|
let package_dir = mk_empty_workspace(short_name,
|
||||||
version).push("src").push(fmt!("%s-%s",
|
version, "temp_workspace").push("src").push(fmt!("%s-%s",
|
||||||
short_name.to_str(),
|
short_name.to_str(),
|
||||||
version.to_str()));
|
version.to_str()));
|
||||||
|
|
||||||
@ -304,29 +305,54 @@ fn create_local_package_with_custom_build_hook(pkgid: &PkgId,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_lib_exists(repo: &Path, short_name: &str, _v: Version) { // ??? version?
|
fn assert_lib_exists(repo: &Path, short_name: &str, v: Version) {
|
||||||
|
assert!(lib_exists(repo, short_name, v));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lib_exists(repo: &Path, short_name: &str, _v: Version) -> bool { // ??? version?
|
||||||
debug!("assert_lib_exists: repo = %s, short_name = %s", repo.to_str(), short_name);
|
debug!("assert_lib_exists: repo = %s, short_name = %s", repo.to_str(), short_name);
|
||||||
let lib = installed_library_in_workspace(short_name, repo);
|
let lib = installed_library_in_workspace(short_name, repo);
|
||||||
debug!("assert_lib_exists: checking whether %? exists", lib);
|
debug!("assert_lib_exists: checking whether %? exists", lib);
|
||||||
assert!(lib.is_some());
|
lib.is_some() && {
|
||||||
let libname = lib.get_ref();
|
let libname = lib.get_ref();
|
||||||
assert!(os::path_exists(libname));
|
os::path_exists(libname) && is_rwx(libname)
|
||||||
assert!(is_rwx(libname));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_executable_exists(repo: &Path, short_name: &str) {
|
fn assert_executable_exists(repo: &Path, short_name: &str) {
|
||||||
|
assert!(executable_exists(repo, short_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn executable_exists(repo: &Path, short_name: &str) -> bool {
|
||||||
debug!("assert_executable_exists: repo = %s, short_name = %s", repo.to_str(), short_name);
|
debug!("assert_executable_exists: repo = %s, short_name = %s", repo.to_str(), short_name);
|
||||||
let exec = target_executable_in_workspace(&PkgId::new(short_name), repo);
|
let exec = target_executable_in_workspace(&PkgId::new(short_name), repo);
|
||||||
assert!(os::path_exists(&exec));
|
os::path_exists(&exec) && is_rwx(&exec)
|
||||||
assert!(is_rwx(&exec));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_built_executable_exists(repo: &Path, short_name: &str) {
|
fn assert_built_executable_exists(repo: &Path, short_name: &str) {
|
||||||
|
assert!(built_executable_exists(repo, short_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn built_executable_exists(repo: &Path, short_name: &str) -> bool {
|
||||||
debug!("assert_built_executable_exists: repo = %s, short_name = %s", repo.to_str(), short_name);
|
debug!("assert_built_executable_exists: repo = %s, short_name = %s", repo.to_str(), short_name);
|
||||||
let exec = built_executable_in_workspace(&PkgId::new(short_name),
|
let exec = built_executable_in_workspace(&PkgId::new(short_name), repo);
|
||||||
repo).expect("assert_built_executable_exists failed");
|
exec.is_some() && {
|
||||||
assert!(os::path_exists(&exec));
|
let execname = exec.get_ref();
|
||||||
assert!(is_rwx(&exec));
|
os::path_exists(execname) && is_rwx(execname)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assert_built_library_exists(repo: &Path, short_name: &str) {
|
||||||
|
assert!(built_library_exists(repo, short_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn built_library_exists(repo: &Path, short_name: &str) -> bool {
|
||||||
|
debug!("assert_built_library_exists: repo = %s, short_name = %s", repo.to_str(), short_name);
|
||||||
|
let lib = built_library_in_workspace(&PkgId::new(short_name), repo);
|
||||||
|
lib.is_some() && {
|
||||||
|
let libname = lib.get_ref();
|
||||||
|
os::path_exists(libname) && is_rwx(libname)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn command_line_test_output(args: &[~str]) -> ~[~str] {
|
fn command_line_test_output(args: &[~str]) -> ~[~str] {
|
||||||
@ -452,12 +478,14 @@ fn test_install_valid() {
|
|||||||
fn test_install_invalid() {
|
fn test_install_invalid() {
|
||||||
use conditions::nonexistent_package::cond;
|
use conditions::nonexistent_package::cond;
|
||||||
use cond1 = conditions::missing_pkg_files::cond;
|
use cond1 = conditions::missing_pkg_files::cond;
|
||||||
|
use cond2 = conditions::not_a_workspace::cond;
|
||||||
|
|
||||||
let ctxt = fake_ctxt(None);
|
let ctxt = fake_ctxt(None);
|
||||||
let pkgid = fake_pkg();
|
let pkgid = fake_pkg();
|
||||||
let temp_workspace = mkdtemp(&os::tmpdir(), "test").expect("couldn't create temp dir");
|
let temp_workspace = mkdtemp(&os::tmpdir(), "test").expect("couldn't create temp dir");
|
||||||
let mut error_occurred = false;
|
let mut error_occurred = false;
|
||||||
let mut error1_occurred = false;
|
let mut error1_occurred = false;
|
||||||
|
let mut error2_occurred = false;
|
||||||
do cond1.trap(|_| {
|
do cond1.trap(|_| {
|
||||||
error1_occurred = true;
|
error1_occurred = true;
|
||||||
}).inside {
|
}).inside {
|
||||||
@ -465,10 +493,15 @@ fn test_install_invalid() {
|
|||||||
error_occurred = true;
|
error_occurred = true;
|
||||||
temp_workspace.clone()
|
temp_workspace.clone()
|
||||||
}).inside {
|
}).inside {
|
||||||
ctxt.install(&temp_workspace, &pkgid);
|
do cond2.trap(|_| {
|
||||||
|
error2_occurred = true;
|
||||||
|
temp_workspace.clone()
|
||||||
|
}).inside {
|
||||||
|
ctxt.install(&temp_workspace, &pkgid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert!(error_occurred && error1_occurred);
|
assert!(error_occurred && error1_occurred && error2_occurred);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests above should (maybe) be converted to shell out to rustpkg, too
|
// Tests above should (maybe) be converted to shell out to rustpkg, too
|
||||||
@ -1087,6 +1120,152 @@ fn multiple_workspaces() {
|
|||||||
command_line_test_with_env([~"install", ~"bar"], &c_loc, env);
|
command_line_test_with_env([~"install", ~"bar"], &c_loc, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn rust_path_hack_test(hack_flag: bool) {
|
||||||
|
/*
|
||||||
|
Make a workspace containing a pkg foo [A]
|
||||||
|
Make a second, empty workspace [B]
|
||||||
|
Set RUST_PATH to B:A
|
||||||
|
rustpkg install foo
|
||||||
|
make sure built files for foo are in B
|
||||||
|
make sure nothing gets built into A or A/../build[lib,bin]
|
||||||
|
*/
|
||||||
|
let p_id = PkgId::new("foo");
|
||||||
|
let workspace = create_local_package(&p_id);
|
||||||
|
let dest_workspace = mk_empty_workspace(&Path("bar"), &NoVersion, "dest_workspace");
|
||||||
|
let rust_path = Some(~[(~"RUST_PATH",
|
||||||
|
fmt!("%s:%s", dest_workspace.to_str(), workspace.push_many(["src", "foo-0.1"]).to_str()))]);
|
||||||
|
debug!("declare -x RUST_PATH=%s:%s",
|
||||||
|
dest_workspace.to_str(), workspace.push_many(["src", "foo-0.1"]).to_str());
|
||||||
|
command_line_test_with_env(~[~"install"] + if hack_flag { ~[~"--rust-path-hack"] } else { ~[] } +
|
||||||
|
~[~"foo"], &dest_workspace, rust_path);
|
||||||
|
assert_lib_exists(&dest_workspace, "foo", NoVersion);
|
||||||
|
assert_executable_exists(&dest_workspace, "foo");
|
||||||
|
assert_built_library_exists(&dest_workspace, "foo");
|
||||||
|
assert_built_executable_exists(&dest_workspace, "foo");
|
||||||
|
assert!(!lib_exists(&workspace, "foo", NoVersion));
|
||||||
|
assert!(!executable_exists(&workspace, "foo"));
|
||||||
|
assert!(!built_library_exists(&workspace, "foo"));
|
||||||
|
assert!(!built_executable_exists(&workspace, "foo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_rust_path_can_contain_package_dirs_with_flag() {
|
||||||
|
/*
|
||||||
|
Test that the temporary hack added for bootstrapping Servo builds
|
||||||
|
works. That is: if you add $FOO/src/some_pkg to the RUST_PATH,
|
||||||
|
it will find the sources in some_pkg, build them, and install them
|
||||||
|
into the first entry in the RUST_PATH.
|
||||||
|
|
||||||
|
When the hack is removed, we should change this to a should_fail test.
|
||||||
|
*/
|
||||||
|
rust_path_hack_test(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_fail]
|
||||||
|
fn test_rust_path_can_contain_package_dirs_without_flag() {
|
||||||
|
rust_path_hack_test(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rust_path_hack_cwd() {
|
||||||
|
// Same as rust_path_hack_test, but the CWD is the dir to build out of
|
||||||
|
let cwd = mkdtemp(&os::tmpdir(), "pkg_files").expect("rust_path_hack_cwd");
|
||||||
|
writeFile(&cwd.push("lib.rs"), "pub fn f() { }");
|
||||||
|
|
||||||
|
let dest_workspace = mk_empty_workspace(&Path("bar"), &NoVersion, "dest_workspace");
|
||||||
|
let rust_path = Some(~[(~"RUST_PATH", dest_workspace.to_str())]);
|
||||||
|
debug!("declare -x RUST_PATH=%s", dest_workspace.to_str());
|
||||||
|
command_line_test_with_env([~"install", ~"--rust-path-hack", ~"foo"], &cwd, rust_path);
|
||||||
|
debug!("Checking that foo exists in %s", dest_workspace.to_str());
|
||||||
|
assert_lib_exists(&dest_workspace, "foo", NoVersion);
|
||||||
|
assert_built_library_exists(&dest_workspace, "foo");
|
||||||
|
assert!(!lib_exists(&cwd, "foo", NoVersion));
|
||||||
|
assert!(!built_library_exists(&cwd, "foo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rust_path_hack_multi_path() {
|
||||||
|
// Same as rust_path_hack_test, but with a more complex package ID
|
||||||
|
let cwd = mkdtemp(&os::tmpdir(), "pkg_files").expect("rust_path_hack_cwd");
|
||||||
|
let subdir = cwd.push_many([~"foo", ~"bar", ~"quux"]);
|
||||||
|
assert!(os::mkdir_recursive(&subdir, U_RWX));
|
||||||
|
writeFile(&subdir.push("lib.rs"), "pub fn f() { }");
|
||||||
|
let name = ~"foo/bar/quux";
|
||||||
|
|
||||||
|
let dest_workspace = mk_empty_workspace(&Path("bar"), &NoVersion, "dest_workspace");
|
||||||
|
let rust_path = Some(~[(~"RUST_PATH", dest_workspace.to_str())]);
|
||||||
|
debug!("declare -x RUST_PATH=%s", dest_workspace.to_str());
|
||||||
|
command_line_test_with_env([~"install", ~"--rust-path-hack", name.clone()], &subdir, rust_path);
|
||||||
|
debug!("Checking that %s exists in %s", name, dest_workspace.to_str());
|
||||||
|
assert_lib_exists(&dest_workspace, "quux", NoVersion);
|
||||||
|
assert_built_library_exists(&dest_workspace, name);
|
||||||
|
assert!(!lib_exists(&subdir, "quux", NoVersion));
|
||||||
|
assert!(!built_library_exists(&subdir, name));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rust_path_hack_install_no_arg() {
|
||||||
|
// Same as rust_path_hack_cwd, but making rustpkg infer the pkg id
|
||||||
|
let cwd = mkdtemp(&os::tmpdir(), "pkg_files").expect("rust_path_hack_install_no_arg");
|
||||||
|
let source_dir = cwd.push("foo");
|
||||||
|
assert!(make_dir_rwx(&source_dir));
|
||||||
|
writeFile(&source_dir.push("lib.rs"), "pub fn f() { }");
|
||||||
|
|
||||||
|
let dest_workspace = mk_empty_workspace(&Path("bar"), &NoVersion, "dest_workspace");
|
||||||
|
let rust_path = Some(~[(~"RUST_PATH", dest_workspace.to_str())]);
|
||||||
|
debug!("declare -x RUST_PATH=%s", dest_workspace.to_str());
|
||||||
|
command_line_test_with_env([~"install", ~"--rust-path-hack"], &source_dir, rust_path);
|
||||||
|
debug!("Checking that foo exists in %s", dest_workspace.to_str());
|
||||||
|
assert_lib_exists(&dest_workspace, "foo", NoVersion);
|
||||||
|
assert_built_library_exists(&dest_workspace, "foo");
|
||||||
|
assert!(!lib_exists(&source_dir, "foo", NoVersion));
|
||||||
|
assert!(!built_library_exists(&cwd, "foo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rust_path_hack_build_no_arg() {
|
||||||
|
// Same as rust_path_hack_install_no_arg, but building instead of installing
|
||||||
|
let cwd = mkdtemp(&os::tmpdir(), "pkg_files").expect("rust_path_hack_build_no_arg");
|
||||||
|
let source_dir = cwd.push("foo");
|
||||||
|
assert!(make_dir_rwx(&source_dir));
|
||||||
|
writeFile(&source_dir.push("lib.rs"), "pub fn f() { }");
|
||||||
|
|
||||||
|
let dest_workspace = mk_empty_workspace(&Path("bar"), &NoVersion, "dest_workspace");
|
||||||
|
let rust_path = Some(~[(~"RUST_PATH", dest_workspace.to_str())]);
|
||||||
|
debug!("declare -x RUST_PATH=%s", dest_workspace.to_str());
|
||||||
|
command_line_test_with_env([~"build", ~"--rust-path-hack"], &source_dir, rust_path);
|
||||||
|
debug!("Checking that foo exists in %s", dest_workspace.to_str());
|
||||||
|
assert_built_library_exists(&dest_workspace, "foo");
|
||||||
|
assert!(!built_library_exists(&source_dir, "foo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore (reason = "#7402 not yet implemented")]
|
||||||
|
fn rust_path_install_target() {
|
||||||
|
let dir_for_path = mkdtemp(&os::tmpdir(),
|
||||||
|
"source_workspace").expect("rust_path_install_target failed");
|
||||||
|
let dir = mk_workspace(&dir_for_path, &Path("foo"), &NoVersion);
|
||||||
|
debug!("dir = %s", dir.to_str());
|
||||||
|
writeFile(&dir.push("main.rs"), "fn main() { let _x = (); }");
|
||||||
|
let dir_to_install_to = mkdtemp(&os::tmpdir(),
|
||||||
|
"dest_workspace").expect("rust_path_install_target failed");
|
||||||
|
let dir = dir.pop().pop();
|
||||||
|
|
||||||
|
let rust_path = Some(~[(~"RUST_PATH", fmt!("%s:%s", dir_to_install_to.to_str(),
|
||||||
|
dir.to_str()))]);
|
||||||
|
let cwd = os::getcwd();
|
||||||
|
|
||||||
|
debug!("RUST_PATH=%s:%s", dir_to_install_to.to_str(), dir.to_str());
|
||||||
|
command_line_test_with_env([~"install", ~"foo"],
|
||||||
|
&cwd,
|
||||||
|
rust_path);
|
||||||
|
|
||||||
|
assert_executable_exists(&dir_to_install_to, "foo");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Returns true if p exists and is executable
|
/// Returns true if p exists and is executable
|
||||||
fn is_executable(p: &Path) -> bool {
|
fn is_executable(p: &Path) -> bool {
|
||||||
use std::libc::consts::os::posix88::{S_IXUSR};
|
use std::libc::consts::os::posix88::{S_IXUSR};
|
||||||
|
@ -452,6 +452,13 @@ fn test_is_cmd() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn option_to_vec<T>(x: Option<T>) -> ~[T] {
|
||||||
|
match x {
|
||||||
|
Some(y) => ~[y],
|
||||||
|
None => ~[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// tjc: cheesy
|
// tjc: cheesy
|
||||||
fn debug_flags() -> ~[~str] { ~[] }
|
fn debug_flags() -> ~[~str] { ~[] }
|
||||||
// static DEBUG_FLAGS: ~[~str] = ~[~"-Z", ~"time-passes"];
|
// static DEBUG_FLAGS: ~[~str] = ~[~"-Z", ~"time-passes"];
|
||||||
|
@ -12,15 +12,17 @@
|
|||||||
|
|
||||||
use std::{os,util};
|
use std::{os,util};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use path_util::workspace_contains_package_id;
|
use context::Ctx;
|
||||||
|
use path_util::{workspace_contains_package_id, find_dir_using_rust_path_hack};
|
||||||
|
use util::option_to_vec;
|
||||||
use package_id::PkgId;
|
use package_id::PkgId;
|
||||||
|
|
||||||
use path_util::rust_path;
|
use path_util::rust_path;
|
||||||
|
|
||||||
pub fn each_pkg_parent_workspace(pkgid: &PkgId, action: &fn(&Path) -> bool) -> bool {
|
pub fn each_pkg_parent_workspace(cx: &Ctx, pkgid: &PkgId, action: &fn(&Path) -> bool) -> bool {
|
||||||
// Using the RUST_PATH, find workspaces that contain
|
// Using the RUST_PATH, find workspaces that contain
|
||||||
// this package ID
|
// this package ID
|
||||||
let workspaces = pkg_parent_workspaces(pkgid);
|
let workspaces = pkg_parent_workspaces(cx, pkgid);
|
||||||
if workspaces.is_empty() {
|
if workspaces.is_empty() {
|
||||||
// tjc: make this a condition
|
// tjc: make this a condition
|
||||||
fail!("Package %s not found in any of \
|
fail!("Package %s not found in any of \
|
||||||
@ -36,10 +38,20 @@ pub fn each_pkg_parent_workspace(pkgid: &PkgId, action: &fn(&Path) -> bool) -> b
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pkg_parent_workspaces(pkgid: &PkgId) -> ~[Path] {
|
pub fn pkg_parent_workspaces(cx: &Ctx, pkgid: &PkgId) -> ~[Path] {
|
||||||
rust_path().move_iter()
|
let rs: ~[Path] = rust_path().move_iter()
|
||||||
.filter(|ws| workspace_contains_package_id(pkgid, ws))
|
.filter(|ws| workspace_contains_package_id(pkgid, ws))
|
||||||
.collect()
|
.collect();
|
||||||
|
if cx.use_rust_path_hack {
|
||||||
|
rs + option_to_vec(find_dir_using_rust_path_hack(cx, pkgid))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_workspace(p: &Path) -> bool {
|
||||||
|
os::path_is_dir(&p.push("src"))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a workspace and package-ID name based on the current directory.
|
/// Construct a workspace and package-ID name based on the current directory.
|
||||||
|
Loading…
Reference in New Issue
Block a user