Skip to content

Commit

Permalink
rustpkg: Implement URL-like package IDs
Browse files Browse the repository at this point in the history
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 rust-lang#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
catamorphism committed May 15, 2013
1 parent c30414f commit c3875e8
Show file tree
Hide file tree
Showing 6 changed files with 223 additions and 208 deletions.
107 changes: 59 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());
pub fn workspace_contains_package_id(pkgid: PkgId, workspace: &Path) -> bool {
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_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_library_in_workspace(pkgid: &PkgId, workspace: &Path) -> Option<Path> {
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,13 +176,15 @@ pub fn target_library_in_workspace(pkgid: &PkgId, workspace: &Path) -> Path {

/// Returns the test executable that would be installed for <pkgid>
/// in <workspace>
pub fn target_test_in_workspace(pkgid: &PkgId, workspace: &Path) -> Path {
/// 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>
pub fn target_bench_in_workspace(pkgid: &PkgId, workspace: &Path) -> Path {
/// 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 @@ -188,17 +193,14 @@ fn target_file_in_workspace(pkgid: &PkgId, workspace: &Path,
use conditions::bad_path::cond;

let (subdir, create_dir) = match what {
Main => ("bin", true), Lib => ("lib", true), Test | Bench => ("build", false)
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)));
}
debug!("target_file_in_workspace: %s %?", result.to_str(), create_dir);
if !os::path_exists(&result) && !mkdir_recursive(&result, u_rwx) {
cond.raise((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 +211,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,8 +222,15 @@ 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 {
pub fn mk_output_path(what: OutputType, pkg_id: PkgId, workspace: &Path) -> Path {
let short_name = 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",
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)),
_ => dir.push(fmt!("%s%s%s", short_name,
match what {
Expand All @@ -230,5 +239,7 @@ pub fn mk_output_path(what: OutputType, short_name: ~str, dir: Path) -> Path {
_ => ""
}
os::EXE_SUFFIX))
}
};
debug!("mk_output_path: returning %s", output_path.to_str());
output_path
}
Loading

0 comments on commit c3875e8

Please sign in to comment.