Skip to content

Commit

Permalink
auto merge of #6418 : catamorphism/rust/rustpkg, r=catamorphism
Browse files Browse the repository at this point in the history
r? @brson This patch implements package IDs like
github.com/catamorphism/test-pkg.

To support such package IDs, I changed the PkgId struct to contain
a LocalPath and a RemotePath field, where the RemotePath reflects
the actual URL and the LocalPath reflects the file name of the cached
copy. Right now, the only difference is that the local path doesn't
contain dashes, but this will change when we implement #6407.

Also, PkgIds now have a short_name field -- though the short name
can be derived from the LocalPath, I thought it was cleaner not to
call option::get() wantonly.
  • Loading branch information
bors committed May 15, 2013
2 parents 8a15333 + 80a7e26 commit 6a9c3bd
Show file tree
Hide file tree
Showing 7 changed files with 297 additions and 432 deletions.
4 changes: 4 additions & 0 deletions src/librustpkg/conditions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,7 @@ condition! {
condition! {
missing_pkg_files: (super::PkgId) -> ();
}

condition! {
bad_pkg_id: (super::Path, ~str) -> ::util::PkgId;
}
108 changes: 60 additions & 48 deletions src/librustpkg/path_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@

// rustpkg utilities having to do with paths and directories

use util::PkgId;
pub use util::{PkgId, RemotePath, LocalPath};
use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
use core::os::mkdir_recursive;

#[deriving(Eq)]
pub enum OutputType { Main, Lib, Bench, Test }
pub use util::{normalize, OutputType, Main, Lib, Bench, Test};

/// Returns the value of RUST_PATH, as a list
/// of Paths. In general this should be read from the
Expand All @@ -31,67 +29,73 @@ pub static u_rwx: i32 = (S_IRUSR | S_IWUSR | S_IXUSR) as i32;
/// succeeded.
pub fn make_dir_rwx(p: &Path) -> bool { os::make_dir(p, u_rwx) }

/// Replace all occurrences of '-' in the stem part of path with '_'
/// This is because we treat rust-foo-bar-quux and rust_foo_bar_quux
/// as the same name
pub fn normalize(p: ~Path) -> ~Path {
match p.filestem() {
None => p,
Some(st) => {
let replaced = str::replace(st, "-", "_");
if replaced != st {
~p.with_filestem(replaced)
}
else {
p
}
}
}
}

// 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());
let pkgpath = workspace.push("src").push(pkgid.local_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())
result.push(pkgid.local_path.to_str())
}

/// Figure out what the executable name for <pkgid> in <workspace>'s build
/// directory is, and if the file exists, return it.
pub fn built_executable_in_workspace(pkgid: &PkgId, workspace: &Path) -> Option<Path> {
let mut result = workspace.push("build");
result = result.push_rel(&pkgid.path);
// should use a target-specific subdirectory
result = mk_output_path(Main, fmt!("%s-%s", pkgid.path.to_str(), pkgid.version.to_str()),
result);
result = mk_output_path(Main, pkgid, &result);
debug!("built_executable_in_workspace: checking whether %s exists",
result.to_str());
if os::path_exists(&result) {
Some(result)
}
else {
// This is not an error, but it's worth logging it
error!(fmt!("built_executable_in_workspace: %s does not exist", result.to_str()));
None
}
}

/// Figure out what the library name for <pkgid> in <workspace>'s build
/// Figure out what the test name for <pkgid> in <workspace>'s build
/// directory is, and if the file exists, return it.
pub fn built_library_in_workspace(pkgid: &PkgId, workspace: &Path) -> Option<Path> {
pub fn built_test_in_workspace(pkgid: &PkgId, workspace: &Path) -> Option<Path> {
output_in_workspace(pkgid, workspace, Test)
}

/// Figure out what the test name for <pkgid> in <workspace>'s build
/// directory is, and if the file exists, return it.
pub fn built_bench_in_workspace(pkgid: &PkgId, workspace: &Path) -> Option<Path> {
output_in_workspace(pkgid, workspace, Bench)
}

fn output_in_workspace(pkgid: &PkgId, workspace: &Path, what: OutputType) -> Option<Path> {
let mut result = workspace.push("build");
result = result.push_rel(&pkgid.path);
// should use a target-specific subdirectory
result = mk_output_path(Lib, pkgid.path.to_str(), result);
result = mk_output_path(what, pkgid, &result);
debug!("output_in_workspace: checking whether %s exists",
result.to_str());
if os::path_exists(&result) {
Some(result)
}
else {
error!(fmt!("output_in_workspace: %s does not exist", result.to_str()));
None
}
}

/// Figure out what the library name for <pkgid> in <workspace>'s build
/// directory is, and if the file exists, return it.
pub fn built_library_in_workspace(pkgid: &PkgId, workspace: &Path) -> Option<Path> {
let result = mk_output_path(Lib, pkgid, &workspace.push("build"));
debug!("built_library_in_workspace: checking whether %s exists",
result.to_str());

Expand All @@ -100,8 +104,7 @@ pub fn built_library_in_workspace(pkgid: &PkgId, workspace: &Path) -> Option<Pat
let dir_contents = os::list_dir(&result.pop());
debug!("dir has %? entries", dir_contents.len());

// n.b. This code assumes the pkgid's path only has one element
let lib_prefix = fmt!("%s%s", os::consts::DLL_PREFIX, pkgid.path.to_str());
let lib_prefix = fmt!("%s%s", os::consts::DLL_PREFIX, pkgid.short_name);
let lib_filetype = fmt!("%s%s", pkgid.version.to_str(), os::consts::DLL_SUFFIX);

debug!("lib_prefix = %s and lib_filetype = %s", lib_prefix, lib_filetype);
Expand Down Expand Up @@ -173,12 +176,14 @@ pub fn target_library_in_workspace(pkgid: &PkgId, workspace: &Path) -> Path {

/// Returns the test executable that would be installed for <pkgid>
/// in <workspace>
/// note that we *don't* install test executables, so this is just for unit testing
pub fn target_test_in_workspace(pkgid: &PkgId, workspace: &Path) -> Path {
target_file_in_workspace(pkgid, workspace, Test)
}

/// Returns the bench executable that would be installed for <pkgid>
/// in <workspace>
/// note that we *don't* install bench executables, so this is just for unit testing
pub fn target_bench_in_workspace(pkgid: &PkgId, workspace: &Path) -> Path {
target_file_in_workspace(pkgid, workspace, Bench)
}
Expand All @@ -187,18 +192,14 @@ fn target_file_in_workspace(pkgid: &PkgId, workspace: &Path,
what: OutputType) -> Path {
use conditions::bad_path::cond;

let (subdir, create_dir) = match what {
Main => ("bin", true), Lib => ("lib", true), Test | Bench => ("build", false)
let subdir = match what {
Lib => "lib", Main | Test | Bench => "bin"
};
let result = workspace.push(subdir);
if create_dir {
if !os::path_exists(&result) && !mkdir_recursive(&result, u_rwx) {
cond.raise((copy result,
fmt!("I couldn't create the %s dir", subdir)));
}
if !os::path_exists(&result) && !mkdir_recursive(&result, u_rwx) {
cond.raise((copy result, fmt!("I couldn't create the %s dir", subdir)));
}
mk_output_path(what, pkgid.path.to_str(), result)

mk_output_path(what, pkgid, &result)
}

/// Return the directory for <pkgid>'s build artifacts in <workspace>.
Expand All @@ -209,7 +210,7 @@ pub fn build_pkg_id_in_workspace(pkgid: &PkgId, workspace: &Path) -> Path {
let mut result = workspace.push("build");
// n.b. Should actually use a target-specific
// subdirectory of build/
result = result.push(normalize(~copy pkgid.path).to_str());
result = result.push_rel(&*pkgid.local_path);
if os::path_exists(&result) || os::mkdir_recursive(&result, u_rwx) {
result
}
Expand All @@ -220,15 +221,26 @@ pub fn build_pkg_id_in_workspace(pkgid: &PkgId, workspace: &Path) -> Path {

/// 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,
pub fn mk_output_path(what: OutputType, pkg_id: &PkgId, workspace: &Path) -> Path {
let short_name_with_version = pkg_id.short_name_with_version();
// Not local_path.dir_path()! For package foo/bar/blat/, we want
// the executable blat-0.5 to live under blat/
let dir = workspace.push_rel(&*pkg_id.local_path);
debug!("mk_output_path: short_name = %s, path = %s",
if what == Lib { copy short_name_with_version } else { copy pkg_id.short_name },
dir.to_str());
let output_path = match what {
// this code is duplicated from elsewhere; fix this
Lib => dir.push(os::dll_filename(short_name_with_version)),
// executable names *aren't* versioned
_ => dir.push(fmt!("%s%s%s", copy pkg_id.short_name,
match what {
Test => "test",
Bench => "bench",
_ => ""
}
os::EXE_SUFFIX))
}
};
debug!("mk_output_path: returning %s", output_path.to_str());
output_path
}
Loading

0 comments on commit 6a9c3bd

Please sign in to comment.