mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-10 14:57:14 +00:00
auto merge of #11478 : klutzy/rust/rustpkg-crate-id, r=cmr
This patchset consists of three parts: - rustpkg doesn't guess crate version if it is not given by user. - `rustpkg::version::Version` is replaced by `Option<~str>`. It removes some semantic versioning portions which is not currently used. (cc #8405 and #11396) `rustpkg::crate_id::CrateId` is also replaced by `syntax::crateid::CrateId`. - rustpkg now computes hash to find crate, instead of manual filename parse. cc @metajack
This commit is contained in:
commit
2b62371c20
@ -11,11 +11,9 @@
|
|||||||
use CtxMethods;
|
use CtxMethods;
|
||||||
use context::*;
|
use context::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use crate_id::*;
|
|
||||||
use package_source::*;
|
use package_source::*;
|
||||||
use path_util::{platform_library_name, target_build_dir};
|
use path_util::{platform_library_name, target_build_dir};
|
||||||
use target::*;
|
use target::*;
|
||||||
use version::Version;
|
|
||||||
use workspace::pkg_parent_workspaces;
|
use workspace::pkg_parent_workspaces;
|
||||||
use workcache_support::*;
|
use workcache_support::*;
|
||||||
pub use path_util::default_workspace;
|
pub use path_util::default_workspace;
|
||||||
@ -27,6 +25,7 @@ use extra::arc::{Arc,RWArc};
|
|||||||
use extra::workcache;
|
use extra::workcache;
|
||||||
use extra::workcache::{Database, FreshnessMap};
|
use extra::workcache::{Database, FreshnessMap};
|
||||||
use extra::treemap::TreeMap;
|
use extra::treemap::TreeMap;
|
||||||
|
use syntax::crateid::CrateId;
|
||||||
|
|
||||||
// A little sad -- duplicated from rustc::back::*
|
// A little sad -- duplicated from rustc::back::*
|
||||||
#[cfg(target_arch = "arm")]
|
#[cfg(target_arch = "arm")]
|
||||||
@ -79,20 +78,19 @@ pub fn new_workcache_context(p: &Path) -> workcache::Context {
|
|||||||
workcache::Context::new_with_freshness(db, cfg, Arc::new(freshness))
|
workcache::Context::new_with_freshness(db, cfg, Arc::new(freshness))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_lib(sysroot: Path, root: Path, name: ~str, version: Version,
|
pub fn build_lib(sysroot: Path, root: Path, name: ~str, lib: Path) {
|
||||||
lib: Path) {
|
build_lib_with_cfgs(sysroot, root, name, lib, ~[])
|
||||||
build_lib_with_cfgs(sysroot, root, name, version, lib, ~[])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_lib_with_cfgs(sysroot: Path, root: Path, name: ~str,
|
pub fn build_lib_with_cfgs(sysroot: Path, root: Path, name: ~str, lib: Path, cfgs: ~[~str]) {
|
||||||
version: Version, lib: Path, cfgs: ~[~str]) {
|
|
||||||
let cx = default_context(sysroot, root.clone());
|
let cx = default_context(sysroot, root.clone());
|
||||||
|
let crate_id: CrateId = from_str(name).expect("valid crate id");
|
||||||
let pkg_src = PkgSrc {
|
let pkg_src = PkgSrc {
|
||||||
source_workspace: root.clone(),
|
source_workspace: root.clone(),
|
||||||
build_in_destination: false,
|
build_in_destination: false,
|
||||||
destination_workspace: root.clone(),
|
destination_workspace: root.clone(),
|
||||||
start_dir: root.join_many(["src", name.as_slice()]),
|
start_dir: root.join_many(["src", name.as_slice()]),
|
||||||
id: CrateId{ version: version, ..CrateId::new(name)},
|
id: crate_id,
|
||||||
// n.b. This assumes the package only has one crate
|
// n.b. This assumes the package only has one crate
|
||||||
libs: ~[mk_crate(lib)],
|
libs: ~[mk_crate(lib)],
|
||||||
mains: ~[],
|
mains: ~[],
|
||||||
@ -102,20 +100,19 @@ pub fn build_lib_with_cfgs(sysroot: Path, root: Path, name: ~str,
|
|||||||
pkg_src.build(&cx, cfgs, []);
|
pkg_src.build(&cx, cfgs, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_exe(sysroot: Path, root: Path, name: ~str, version: Version,
|
pub fn build_exe(sysroot: Path, root: Path, name: ~str, main: Path) {
|
||||||
main: Path) {
|
build_exe_with_cfgs(sysroot, root, name, main, ~[])
|
||||||
build_exe_with_cfgs(sysroot, root, name, version, main, ~[])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_exe_with_cfgs(sysroot: Path, root: Path, name: ~str,
|
pub fn build_exe_with_cfgs(sysroot: Path, root: Path, name: ~str, main: Path, cfgs: ~[~str]) {
|
||||||
version: Version, main: Path, cfgs: ~[~str]) {
|
|
||||||
let cx = default_context(sysroot, root.clone());
|
let cx = default_context(sysroot, root.clone());
|
||||||
|
let crate_id: CrateId = from_str(name).expect("valid crate id");
|
||||||
let pkg_src = PkgSrc {
|
let pkg_src = PkgSrc {
|
||||||
source_workspace: root.clone(),
|
source_workspace: root.clone(),
|
||||||
build_in_destination: false,
|
build_in_destination: false,
|
||||||
destination_workspace: root.clone(),
|
destination_workspace: root.clone(),
|
||||||
start_dir: root.join_many(["src", name.as_slice()]),
|
start_dir: root.join_many(["src", name.as_slice()]),
|
||||||
id: CrateId{ version: version, ..CrateId::new(name)},
|
id: crate_id,
|
||||||
libs: ~[],
|
libs: ~[],
|
||||||
// n.b. This assumes the package only has one crate
|
// n.b. This assumes the package only has one crate
|
||||||
mains: ~[mk_crate(main)],
|
mains: ~[mk_crate(main)],
|
||||||
@ -129,11 +126,10 @@ pub fn build_exe_with_cfgs(sysroot: Path, root: Path, name: ~str,
|
|||||||
pub fn install_pkg(cx: &BuildContext,
|
pub fn install_pkg(cx: &BuildContext,
|
||||||
workspace: Path,
|
workspace: Path,
|
||||||
name: ~str,
|
name: ~str,
|
||||||
version: Version,
|
|
||||||
// For now, these inputs are assumed to be inputs to each of the crates
|
// For now, these inputs are assumed to be inputs to each of the crates
|
||||||
more_inputs: ~[(~str, Path)]) { // pairs of Kind and Path
|
more_inputs: ~[(~str, Path)]) { // pairs of Kind and Path
|
||||||
let crateid = CrateId{ version: version, ..CrateId::new(name)};
|
let crate_id: CrateId = from_str(name).expect("valid crate id");
|
||||||
cx.install(PkgSrc::new(workspace.clone(), workspace, false, crateid),
|
cx.install(PkgSrc::new(workspace.clone(), workspace, false, crate_id),
|
||||||
&WhatToBuild{ build_type: Inferred,
|
&WhatToBuild{ build_type: Inferred,
|
||||||
inputs_to_discover: more_inputs,
|
inputs_to_discover: more_inputs,
|
||||||
sources: Everything });
|
sources: Everything });
|
||||||
@ -157,10 +153,10 @@ pub fn build_library_in_workspace(exec: &mut workcache::Exec,
|
|||||||
let out_name = workspace_build_dir.join_many([package_name.to_str(),
|
let out_name = workspace_build_dir.join_many([package_name.to_str(),
|
||||||
platform_library_name(output)]);
|
platform_library_name(output)]);
|
||||||
// make paths absolute
|
// make paths absolute
|
||||||
let crateid = CrateId::new(package_name);
|
let crateid: CrateId = from_str(package_name).expect("valid crate id");
|
||||||
let absolute_paths = paths.map(|s| {
|
let absolute_paths = paths.map(|s| {
|
||||||
let whatever = workspace.join_many([~"src",
|
let whatever = workspace.join_many([~"src",
|
||||||
crateid.to_str(),
|
crateid.short_name_with_version(),
|
||||||
s.to_owned()]);
|
s.to_owned()]);
|
||||||
whatever.as_str().unwrap().to_owned()
|
whatever.as_str().unwrap().to_owned()
|
||||||
});
|
});
|
||||||
@ -190,7 +186,7 @@ pub fn my_workspace(context: &Context, package_name: &str) -> Path {
|
|||||||
use bad_pkg_id = conditions::bad_pkg_id::cond;
|
use bad_pkg_id = conditions::bad_pkg_id::cond;
|
||||||
|
|
||||||
// (this assumes no particular version is requested)
|
// (this assumes no particular version is requested)
|
||||||
let crateid = CrateId::new(package_name);
|
let crateid = from_str(package_name).expect("valid crate id");
|
||||||
let workspaces = pkg_parent_workspaces(context, &crateid);
|
let workspaces = pkg_parent_workspaces(context, &crateid);
|
||||||
if workspaces.is_empty() {
|
if workspaces.is_empty() {
|
||||||
bad_pkg_id.raise((Path::new(package_name), package_name.to_owned()));
|
bad_pkg_id.raise((Path::new(package_name), package_name.to_owned()));
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
// Useful conditions
|
// Useful conditions
|
||||||
|
|
||||||
pub use crate_id::CrateId;
|
pub use syntax::crateid::CrateId;
|
||||||
pub use std::io::FileStat;
|
pub use std::io::FileStat;
|
||||||
pub use std::io::process::ProcessExit;
|
pub use std::io::process::ProcessExit;
|
||||||
pub use std::path::Path;
|
pub use std::path::Path;
|
||||||
|
@ -1,150 +0,0 @@
|
|||||||
// 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.
|
|
||||||
|
|
||||||
use version::{try_getting_version, try_getting_local_version,
|
|
||||||
Version, NoVersion, ExactRevision};
|
|
||||||
use std::hash::Streaming;
|
|
||||||
use std::hash;
|
|
||||||
use syntax::crateid;
|
|
||||||
|
|
||||||
/// Path-fragment identifier of a package such as
|
|
||||||
/// 'github.com/graydon/test'; path must be a relative
|
|
||||||
/// path with >=1 component.
|
|
||||||
#[deriving(Clone)]
|
|
||||||
pub struct CrateId {
|
|
||||||
/// This is a path, on the local filesystem, referring to where the
|
|
||||||
/// files for this package live. For example:
|
|
||||||
/// github.com/mozilla/quux-whatever (it's assumed that if we're
|
|
||||||
/// working with a package ID of this form, rustpkg has already cloned
|
|
||||||
/// the sources into a local directory in the RUST_PATH).
|
|
||||||
path: Path,
|
|
||||||
/// Short name. This is the path's filestem, but we store it
|
|
||||||
/// redundantly so as to not call get() everywhere (filestem() returns an
|
|
||||||
/// option)
|
|
||||||
/// The short name does not need to be a valid Rust identifier.
|
|
||||||
/// Users can write: `extern mod foo = "...";` to get around the issue
|
|
||||||
/// of package IDs whose short names aren't valid Rust identifiers.
|
|
||||||
short_name: ~str,
|
|
||||||
/// The requested package version.
|
|
||||||
version: Version
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Eq for CrateId {
|
|
||||||
fn eq(&self, other: &CrateId) -> bool {
|
|
||||||
self.path == other.path && self.version == other.version
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CrateId {
|
|
||||||
pub fn new(s: &str) -> CrateId {
|
|
||||||
use conditions::bad_pkg_id::cond;
|
|
||||||
|
|
||||||
let raw_crateid: Option<crateid::CrateId> = from_str(s);
|
|
||||||
if raw_crateid.is_none() {
|
|
||||||
return cond.raise((Path::new(s), ~"bad crateid"))
|
|
||||||
}
|
|
||||||
let raw_crateid = raw_crateid.unwrap();
|
|
||||||
let crateid::CrateId { path, name, version } = raw_crateid;
|
|
||||||
let path = Path::new(path);
|
|
||||||
let given_version = version.map(|v| ExactRevision(v));
|
|
||||||
|
|
||||||
let version = match given_version {
|
|
||||||
Some(v) => v,
|
|
||||||
None => match try_getting_local_version(&path) {
|
|
||||||
Some(v) => v,
|
|
||||||
None => match try_getting_version(&path) {
|
|
||||||
Some(v) => v,
|
|
||||||
None => NoVersion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
CrateId {
|
|
||||||
path: path,
|
|
||||||
short_name: name,
|
|
||||||
version: version
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn hash(&self) -> ~str {
|
|
||||||
// FIXME (#9639): hash should take a &[u8] so we can hash the real path
|
|
||||||
self.path.display().with_str(|s| {
|
|
||||||
let vers = self.version.to_str();
|
|
||||||
format!("{}-{}-{}", s, hash(s + vers), vers)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn short_name_with_version(&self) -> ~str {
|
|
||||||
format!("{}{}", self.short_name, self.version.to_str())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// True if the ID has multiple components
|
|
||||||
pub fn is_complex(&self) -> bool {
|
|
||||||
self.short_name.as_bytes() != self.path.as_vec()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn prefixes(&self) -> Prefixes {
|
|
||||||
prefixes(&self.path)
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is the workcache function name for the *installed*
|
|
||||||
// binaries for this package (as opposed to the built ones,
|
|
||||||
// which are per-crate).
|
|
||||||
pub fn install_tag(&self) -> ~str {
|
|
||||||
format!("install({})", self.to_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn prefixes(p: &Path) -> Prefixes {
|
|
||||||
Prefixes {
|
|
||||||
components: p.str_components().map(|x|x.unwrap().to_owned()).to_owned_vec(),
|
|
||||||
remaining: ~[]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Prefixes {
|
|
||||||
priv components: ~[~str],
|
|
||||||
priv remaining: ~[~str]
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Iterator<(Path, Path)> for Prefixes {
|
|
||||||
#[inline]
|
|
||||||
fn next(&mut self) -> Option<(Path, Path)> {
|
|
||||||
if self.components.len() <= 1 {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
let last = self.components.pop().unwrap();
|
|
||||||
self.remaining.unshift(last);
|
|
||||||
// converting to str and then back is a little unfortunate
|
|
||||||
Some((Path::new(self.components.connect("/")),
|
|
||||||
Path::new(self.remaining.connect("/"))))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToStr for CrateId {
|
|
||||||
fn to_str(&self) -> ~str {
|
|
||||||
// should probably use the filestem and not the whole path
|
|
||||||
format!("{}-{}", self.path.as_str().unwrap(), self.version.to_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub fn write<W: Writer>(writer: &mut W, string: &str) {
|
|
||||||
writer.write(string.as_bytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn hash(data: ~str) -> ~str {
|
|
||||||
let hasher = &mut hash::default_state();
|
|
||||||
write(hasher, data);
|
|
||||||
hasher.result_str()
|
|
||||||
}
|
|
||||||
|
|
@ -11,10 +11,10 @@
|
|||||||
// Listing installed packages
|
// Listing installed packages
|
||||||
|
|
||||||
use rustc::metadata::filesearch::rust_path;
|
use rustc::metadata::filesearch::rust_path;
|
||||||
use path_util::*;
|
|
||||||
use std::os;
|
use std::os;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::fs;
|
use std::io::fs;
|
||||||
|
use syntax::crateid::CrateId;
|
||||||
|
|
||||||
pub fn list_installed_packages(f: |&CrateId| -> bool) -> bool {
|
pub fn list_installed_packages(f: |&CrateId| -> bool) -> bool {
|
||||||
let workspaces = rust_path();
|
let workspaces = rust_path();
|
||||||
@ -28,7 +28,8 @@ pub fn list_installed_packages(f: |&CrateId| -> bool) -> bool {
|
|||||||
match exec.filestem_str() {
|
match exec.filestem_str() {
|
||||||
None => (),
|
None => (),
|
||||||
Some(exec_path) => {
|
Some(exec_path) => {
|
||||||
if !f(&CrateId::new(exec_path)) {
|
let crate_id = from_str(exec_path).expect("valid crate id");
|
||||||
|
if !f(&crate_id) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,7 +51,8 @@ pub fn list_installed_packages(f: |&CrateId| -> bool) -> bool {
|
|||||||
let rel_path = rel_p.join(basename);
|
let rel_path = rel_p.join(basename);
|
||||||
rel_path.display().with_str(|s| {
|
rel_path.display().with_str(|s| {
|
||||||
debug!("Rel name: {}", s);
|
debug!("Rel name: {}", s);
|
||||||
f(&CrateId::new(s));
|
let crate_id = from_str(s).expect("valid crate id");
|
||||||
|
f(&crate_id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
None => ()
|
None => ()
|
||||||
|
@ -33,6 +33,7 @@ use rustc::metadata::filesearch;
|
|||||||
use rustc::metadata::filesearch::rust_path;
|
use rustc::metadata::filesearch::rust_path;
|
||||||
use rustc::util::sha2;
|
use rustc::util::sha2;
|
||||||
use syntax::{ast, diagnostic};
|
use syntax::{ast, diagnostic};
|
||||||
|
use syntax::crateid::CrateId;
|
||||||
use messages::{error, warn, note};
|
use messages::{error, warn, note};
|
||||||
use parse_args::{ParseResult, parse_args};
|
use parse_args::{ParseResult, parse_args};
|
||||||
use path_util::{build_pkg_id_in_workspace, built_test_in_workspace};
|
use path_util::{build_pkg_id_in_workspace, built_test_in_workspace};
|
||||||
@ -46,7 +47,6 @@ use context::{BuildContext, Trans, Nothing, Pretty, Analysis,
|
|||||||
LLVMAssemble, LLVMCompileBitcode};
|
LLVMAssemble, LLVMCompileBitcode};
|
||||||
use context::{Command, BuildCmd, CleanCmd, DoCmd, HelpCmd, InfoCmd, InstallCmd, ListCmd,
|
use context::{Command, BuildCmd, CleanCmd, DoCmd, HelpCmd, InfoCmd, InstallCmd, ListCmd,
|
||||||
PreferCmd, TestCmd, InitCmd, UninstallCmd, UnpreferCmd};
|
PreferCmd, TestCmd, InitCmd, UninstallCmd, UnpreferCmd};
|
||||||
use crate_id::CrateId;
|
|
||||||
use package_source::PkgSrc;
|
use package_source::PkgSrc;
|
||||||
use target::{WhatToBuild, Everything, is_lib, is_main, is_test, is_bench};
|
use target::{WhatToBuild, Everything, is_lib, is_main, is_test, is_bench};
|
||||||
use target::{Main, Tests, MaybeCustom, Inferred, JustOne};
|
use target::{Main, Tests, MaybeCustom, Inferred, JustOne};
|
||||||
@ -60,7 +60,6 @@ mod crate;
|
|||||||
pub mod exit_codes;
|
pub mod exit_codes;
|
||||||
mod installed_packages;
|
mod installed_packages;
|
||||||
mod messages;
|
mod messages;
|
||||||
pub mod crate_id;
|
|
||||||
pub mod package_source;
|
pub mod package_source;
|
||||||
mod parse_args;
|
mod parse_args;
|
||||||
mod path_util;
|
mod path_util;
|
||||||
@ -103,7 +102,7 @@ impl<'a> PkgScript<'a> {
|
|||||||
workspace: &Path,
|
workspace: &Path,
|
||||||
id: &'a CrateId) -> PkgScript<'a> {
|
id: &'a CrateId) -> PkgScript<'a> {
|
||||||
// Get the executable name that was invoked
|
// Get the executable name that was invoked
|
||||||
let binary = os::args()[0].to_owned();
|
let binary = os::args()[0];
|
||||||
// Build the rustc session data structures to pass
|
// Build the rustc session data structures to pass
|
||||||
// to the compiler
|
// to the compiler
|
||||||
debug!("pkgscript parse: {}", sysroot.display());
|
debug!("pkgscript parse: {}", sysroot.display());
|
||||||
@ -163,7 +162,6 @@ impl<'a> PkgScript<'a> {
|
|||||||
exe.as_str().unwrap().to_owned()
|
exe.as_str().unwrap().to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Run the contents of this package script, where <what>
|
/// Run the contents of this package script, where <what>
|
||||||
/// is the command to pass to it (e.g., "build", "clean", "install")
|
/// is the command to pass to it (e.g., "build", "clean", "install")
|
||||||
/// Returns a pair of an exit code and list of configs (obtained by
|
/// Returns a pair of an exit code and list of configs (obtained by
|
||||||
@ -243,9 +241,9 @@ impl CtxMethods for BuildContext {
|
|||||||
|
|
||||||
if args.len() < 1 {
|
if args.len() < 1 {
|
||||||
match cwd_to_workspace() {
|
match cwd_to_workspace() {
|
||||||
None if dir_has_crate_file(&cwd) => {
|
None if dir_has_crate_file(&cwd) => {
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||||
let crateid = CrateId::new(cwd.filename_str().unwrap());
|
let crateid = from_str(cwd.filename_str().unwrap()).expect("valid crate id");
|
||||||
let mut pkg_src = PkgSrc::new(cwd, default_workspace(), true, crateid);
|
let mut pkg_src = PkgSrc::new(cwd, default_workspace(), true, crateid);
|
||||||
self.build(&mut pkg_src, what);
|
self.build(&mut pkg_src, what);
|
||||||
match pkg_src {
|
match pkg_src {
|
||||||
@ -270,7 +268,7 @@ impl CtxMethods for BuildContext {
|
|||||||
} 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 crateid = CrateId::new(args[0].clone());
|
let crateid = from_str(args[0]).expect("valid crate id");
|
||||||
let mut dest_ws = default_workspace();
|
let mut dest_ws = default_workspace();
|
||||||
each_pkg_parent_workspace(&self.context, &crateid, |workspace| {
|
each_pkg_parent_workspace(&self.context, &crateid, |workspace| {
|
||||||
debug!("found pkg {} in workspace {}, trying to build",
|
debug!("found pkg {} in workspace {}, trying to build",
|
||||||
@ -289,6 +287,7 @@ impl CtxMethods for BuildContext {
|
|||||||
Some((crateid, dest_ws))
|
Some((crateid, dest_ws))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, cmd: Command, args: ~[~str]) {
|
fn run(&self, cmd: Command, args: ~[~str]) {
|
||||||
let cwd = os::getcwd();
|
let cwd = os::getcwd();
|
||||||
match cmd {
|
match cmd {
|
||||||
@ -308,7 +307,7 @@ impl CtxMethods for BuildContext {
|
|||||||
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 crateid = CrateId::new(args[0].clone());
|
let crateid = from_str(args[0]).expect("valid crate id");
|
||||||
self.clean(&cwd, &crateid); // tjc: should use workspace, not cwd
|
self.clean(&cwd, &crateid); // tjc: should use workspace, not cwd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -341,7 +340,7 @@ impl CtxMethods for BuildContext {
|
|||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||||
|
|
||||||
let inferred_crateid =
|
let inferred_crateid =
|
||||||
CrateId::new(cwd.filename_str().unwrap());
|
from_str(cwd.filename_str().unwrap()).expect("valid crate id");
|
||||||
self.install(PkgSrc::new(cwd, default_workspace(),
|
self.install(PkgSrc::new(cwd, default_workspace(),
|
||||||
true, inferred_crateid),
|
true, inferred_crateid),
|
||||||
&WhatToBuild::new(MaybeCustom, Everything));
|
&WhatToBuild::new(MaybeCustom, Everything));
|
||||||
@ -357,7 +356,7 @@ impl CtxMethods for BuildContext {
|
|||||||
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 crateid = CrateId::new(args[0]);
|
let crateid = from_str(args[0]).expect("valid crate id");
|
||||||
let workspaces = pkg_parent_workspaces(&self.context, &crateid);
|
let workspaces = pkg_parent_workspaces(&self.context, &crateid);
|
||||||
debug!("package ID = {}, found it in {:?} workspaces",
|
debug!("package ID = {}, found it in {:?} workspaces",
|
||||||
crateid.to_str(), workspaces.len());
|
crateid.to_str(), workspaces.len());
|
||||||
@ -383,7 +382,7 @@ impl CtxMethods for BuildContext {
|
|||||||
ListCmd => {
|
ListCmd => {
|
||||||
println!("Installed packages:");
|
println!("Installed packages:");
|
||||||
installed_packages::list_installed_packages(|pkg_id| {
|
installed_packages::list_installed_packages(|pkg_id| {
|
||||||
pkg_id.path.display().with_str(|s| println!("{}", s));
|
println!("{}", pkg_id.path);
|
||||||
true
|
true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -420,7 +419,7 @@ impl CtxMethods for BuildContext {
|
|||||||
return usage::uninstall();
|
return usage::uninstall();
|
||||||
}
|
}
|
||||||
|
|
||||||
let crateid = CrateId::new(args[0]);
|
let crateid = from_str(args[0]).expect("valid crate id");
|
||||||
if !installed_packages::package_is_installed(&crateid) {
|
if !installed_packages::package_is_installed(&crateid) {
|
||||||
warn(format!("Package {} doesn't seem to be installed! \
|
warn(format!("Package {} doesn't seem to be installed! \
|
||||||
Doing nothing.", args[0]));
|
Doing nothing.", args[0]));
|
||||||
@ -458,24 +457,24 @@ impl CtxMethods for BuildContext {
|
|||||||
let workspace = pkg_src.source_workspace.clone();
|
let workspace = pkg_src.source_workspace.clone();
|
||||||
let crateid = pkg_src.id.clone();
|
let crateid = pkg_src.id.clone();
|
||||||
|
|
||||||
|
let path = crateid.path.as_slice();
|
||||||
debug!("build: workspace = {} (in Rust path? {:?} is git dir? {:?} \
|
debug!("build: workspace = {} (in Rust path? {:?} is git dir? {:?} \
|
||||||
crateid = {} pkgsrc start_dir = {}", workspace.display(),
|
crateid = {} pkgsrc start_dir = {}", workspace.display(),
|
||||||
in_rust_path(&workspace), is_git_dir(&workspace.join(&crateid.path)),
|
in_rust_path(&workspace), is_git_dir(&workspace.join(path)),
|
||||||
crateid.to_str(), pkg_src.start_dir.display());
|
crateid.to_str(), pkg_src.start_dir.display());
|
||||||
debug!("build: what to build = {:?}", what_to_build);
|
debug!("build: what to build = {:?}", what_to_build);
|
||||||
|
|
||||||
// If workspace isn't in the RUST_PATH, and it's a git repo,
|
// If workspace isn't in the RUST_PATH, and it's a git repo,
|
||||||
// then clone it into the first entry in RUST_PATH, and repeat
|
// then clone it into the first entry in RUST_PATH, and repeat
|
||||||
if !in_rust_path(&workspace) && is_git_dir(&workspace.join(&crateid.path)) {
|
if !in_rust_path(&workspace) && is_git_dir(&workspace.join(path)) {
|
||||||
let mut out_dir = default_workspace().join("src");
|
let mut out_dir = default_workspace().join("src");
|
||||||
out_dir.push(&crateid.path);
|
out_dir.push(path);
|
||||||
let git_result = source_control::safe_git_clone(&workspace.join(&crateid.path),
|
let git_result = source_control::safe_git_clone(&workspace.join(path),
|
||||||
&crateid.version,
|
&crateid.version,
|
||||||
&out_dir);
|
&out_dir);
|
||||||
match git_result {
|
match git_result {
|
||||||
CheckedOutSources => make_read_only(&out_dir),
|
CheckedOutSources => make_read_only(&out_dir),
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
_ => cond.raise((path.to_owned(), out_dir.clone()))
|
||||||
_ => cond.raise((crateid.path.as_str().unwrap().to_owned(), out_dir.clone()))
|
|
||||||
};
|
};
|
||||||
let default_ws = default_workspace();
|
let default_ws = default_workspace();
|
||||||
debug!("Calling build recursively with {:?} and {:?}", default_ws.display(),
|
debug!("Calling build recursively with {:?} and {:?}", default_ws.display(),
|
||||||
@ -652,7 +651,8 @@ impl CtxMethods for BuildContext {
|
|||||||
target_exec.display(), target_lib,
|
target_exec.display(), target_lib,
|
||||||
maybe_executable, maybe_library);
|
maybe_executable, maybe_library);
|
||||||
|
|
||||||
self.workcache_context.with_prep(id.install_tag(), |prep| {
|
let install_tag = format!("install({}-{})", id.path, id.version_or_default());
|
||||||
|
self.workcache_context.with_prep(install_tag, |prep| {
|
||||||
for ee in maybe_executable.iter() {
|
for ee in maybe_executable.iter() {
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||||
prep.declare_input("binary",
|
prep.declare_input("binary",
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
extern mod extra;
|
extern mod extra;
|
||||||
|
|
||||||
use target::*;
|
use target::*;
|
||||||
use crate_id::CrateId;
|
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::fs;
|
use std::io::fs;
|
||||||
use std::os;
|
use std::os;
|
||||||
@ -27,7 +26,7 @@ use workcache_support;
|
|||||||
use workcache_support::{digest_only_date, digest_file_with_date, crate_tag};
|
use workcache_support::{digest_only_date, digest_file_with_date, crate_tag};
|
||||||
use extra::workcache;
|
use extra::workcache;
|
||||||
use extra::treemap::TreeMap;
|
use extra::treemap::TreeMap;
|
||||||
|
use syntax::crateid::CrateId;
|
||||||
use rustc::driver::session;
|
use rustc::driver::session;
|
||||||
|
|
||||||
// An enumeration of the unpacked source of a package workspace.
|
// An enumeration of the unpacked source of a package workspace.
|
||||||
@ -68,12 +67,38 @@ impl ToStr for PkgSrc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
condition! {
|
condition! {
|
||||||
// #6009: should this be pub or not, when #8215 is fixed?
|
|
||||||
build_err: (~str) -> ~str;
|
build_err: (~str) -> ~str;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PkgSrc {
|
fn prefixes(p: &Path) -> Prefixes {
|
||||||
|
Prefixes {
|
||||||
|
components: p.str_components().map(|x|x.unwrap().to_owned()).to_owned_vec(),
|
||||||
|
remaining: ~[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Prefixes {
|
||||||
|
priv components: ~[~str],
|
||||||
|
priv remaining: ~[~str]
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator<(Path, Path)> for Prefixes {
|
||||||
|
#[inline]
|
||||||
|
fn next(&mut self) -> Option<(Path, Path)> {
|
||||||
|
if self.components.len() <= 1 {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let last = self.components.pop().unwrap();
|
||||||
|
self.remaining.unshift(last);
|
||||||
|
// converting to str and then back is a little unfortunate
|
||||||
|
Some((Path::new(self.components.connect("/")),
|
||||||
|
Path::new(self.remaining.connect("/"))))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PkgSrc {
|
||||||
pub fn new(mut source_workspace: Path,
|
pub fn new(mut source_workspace: Path,
|
||||||
destination_workspace: Path,
|
destination_workspace: Path,
|
||||||
use_rust_path_hack: bool,
|
use_rust_path_hack: bool,
|
||||||
@ -98,21 +123,22 @@ impl PkgSrc {
|
|||||||
} else {
|
} else {
|
||||||
// We search for sources under both src/ and build/ , because build/ is where
|
// We search for sources under both src/ and build/ , because build/ is where
|
||||||
// automatically-checked-out sources go.
|
// automatically-checked-out sources go.
|
||||||
|
let path = Path::new(id.path.as_slice());
|
||||||
let mut result = source_workspace.join("src");
|
let mut result = source_workspace.join("src");
|
||||||
result.push(&id.path.dir_path());
|
result.push(&path.dir_path());
|
||||||
result.push(format!("{}-{}", id.short_name, id.version.to_str()));
|
result.push(id.short_name_with_version());
|
||||||
to_try.push(result);
|
to_try.push(result);
|
||||||
let mut result = source_workspace.join("src");
|
let mut result = source_workspace.join("src");
|
||||||
result.push(&id.path);
|
result.push(&path);
|
||||||
to_try.push(result);
|
to_try.push(result);
|
||||||
|
|
||||||
let mut result = build_dir.join("src");
|
let mut result = build_dir.join("src");
|
||||||
result.push(&id.path.dir_path());
|
result.push(&path.dir_path());
|
||||||
result.push(format!("{}-{}", id.short_name, id.version.to_str()));
|
result.push(id.short_name_with_version());
|
||||||
to_try.push(result.clone());
|
to_try.push(result.clone());
|
||||||
output_names.push(result);
|
output_names.push(result);
|
||||||
let mut other_result = build_dir.join("src");
|
let mut other_result = build_dir.join("src");
|
||||||
other_result.push(&id.path);
|
other_result.push(&path);
|
||||||
to_try.push(other_result.clone());
|
to_try.push(other_result.clone());
|
||||||
output_names.push(other_result);
|
output_names.push(other_result);
|
||||||
|
|
||||||
@ -132,9 +158,10 @@ impl PkgSrc {
|
|||||||
None => {
|
None => {
|
||||||
// See if any of the prefixes of this package ID form a valid package ID
|
// See if any of the prefixes of this package ID form a valid package ID
|
||||||
// That is, is this a package ID that points into the middle of a workspace?
|
// That is, is this a package ID that points into the middle of a workspace?
|
||||||
for (prefix, suffix) in id.prefixes() {
|
for (prefix, suffix) in prefixes(&Path::new(id.path.as_slice())) {
|
||||||
let crate_id = CrateId::new(prefix.as_str().unwrap());
|
let crate_id: Option<CrateId> = from_str(prefix.as_str().unwrap());
|
||||||
let path = build_dir.join(&crate_id.path);
|
let crate_id = crate_id.expect("valid crate id");
|
||||||
|
let path = build_dir.join(crate_id.path.as_slice());
|
||||||
debug!("in loop: checking if {} is a directory", path.display());
|
debug!("in loop: checking if {} is a directory", path.display());
|
||||||
if path.is_dir() {
|
if path.is_dir() {
|
||||||
let ps = PkgSrc::new(source_workspace,
|
let ps = PkgSrc::new(source_workspace,
|
||||||
@ -163,7 +190,7 @@ impl PkgSrc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ok, no prefixes work, so try fetching from git
|
// Ok, no prefixes work, so try fetching from git
|
||||||
@ -179,11 +206,12 @@ impl PkgSrc {
|
|||||||
}
|
}
|
||||||
match ok_d {
|
match ok_d {
|
||||||
Some(ref d) => {
|
Some(ref d) => {
|
||||||
if d.is_ancestor_of(&id.path)
|
let path = Path::new(id.path.as_slice());
|
||||||
|| d.is_ancestor_of(&versionize(&id.path, &id.version)) {
|
if d.is_ancestor_of(&path)
|
||||||
|
|| d.is_ancestor_of(&versionize(id.path, &id.version)) {
|
||||||
// Strip off the package ID
|
// Strip off the package ID
|
||||||
source_workspace = d.clone();
|
source_workspace = d.clone();
|
||||||
for _ in id.path.components() {
|
for _ in path.components() {
|
||||||
source_workspace.pop();
|
source_workspace.pop();
|
||||||
}
|
}
|
||||||
// Strip off the src/ part
|
// Strip off the src/ part
|
||||||
@ -226,8 +254,7 @@ impl PkgSrc {
|
|||||||
exist, and couldn't interpret it as a URL fragment"))
|
exist, and couldn't interpret it as a URL fragment"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
cond.raise((id.clone(),
|
cond.raise((id.clone(),
|
||||||
~"supplied path for package dir does not \
|
~"supplied path for package dir does not \
|
||||||
exist, and couldn't interpret it as a URL fragment"))
|
exist, and couldn't interpret it as a URL fragment"))
|
||||||
@ -268,26 +295,27 @@ impl PkgSrc {
|
|||||||
use conditions::git_checkout_failed::cond;
|
use conditions::git_checkout_failed::cond;
|
||||||
|
|
||||||
let cwd = os::getcwd();
|
let cwd = os::getcwd();
|
||||||
|
let path = Path::new(crateid.path.as_slice());
|
||||||
debug!("Checking whether {} (path = {}) exists locally. Cwd = {}, does it? {:?}",
|
debug!("Checking whether {} (path = {}) exists locally. Cwd = {}, does it? {:?}",
|
||||||
crateid.to_str(), crateid.path.display(),
|
crateid.to_str(), crateid.path,
|
||||||
cwd.display(),
|
cwd.display(),
|
||||||
crateid.path.exists());
|
path.exists());
|
||||||
|
|
||||||
match safe_git_clone(&crateid.path, &crateid.version, local) {
|
match safe_git_clone(&path, &crateid.version, local) {
|
||||||
CheckedOutSources => {
|
CheckedOutSources => {
|
||||||
make_read_only(local);
|
make_read_only(local);
|
||||||
Some(local.clone())
|
Some(local.clone())
|
||||||
}
|
}
|
||||||
DirToUse(clone_target) => {
|
DirToUse(clone_target) => {
|
||||||
if crateid.path.components().nth(1).is_none() {
|
if path.components().nth(1).is_none() {
|
||||||
// If a non-URL, don't bother trying to fetch
|
// If a non-URL, don't bother trying to fetch
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||||
let url = format!("https://{}", crateid.path.as_str().unwrap());
|
let url = format!("https://{}", path.as_str().unwrap());
|
||||||
debug!("Fetching package: git clone {} {} [version={}]",
|
debug!("Fetching package: git clone {} {} [version={}]",
|
||||||
url, clone_target.display(), crateid.version.to_str());
|
url, clone_target.display(), crateid.version_or_default());
|
||||||
|
|
||||||
let mut failed = false;
|
let mut failed = false;
|
||||||
|
|
||||||
@ -345,7 +373,7 @@ impl PkgSrc {
|
|||||||
use conditions::missing_pkg_files::cond;
|
use conditions::missing_pkg_files::cond;
|
||||||
|
|
||||||
let prefix = self.start_dir.components().len();
|
let prefix = self.start_dir.components().len();
|
||||||
debug!("Matching against {}", self.id.short_name);
|
debug!("Matching against {}", self.id.name);
|
||||||
for pth in fs::walk_dir(&self.start_dir) {
|
for pth in fs::walk_dir(&self.start_dir) {
|
||||||
let maybe_known_crate_set = match pth.filename_str() {
|
let maybe_known_crate_set = match pth.filename_str() {
|
||||||
Some(filename) if filter(filename) => match filename {
|
Some(filename) if filter(filename) => match filename {
|
||||||
|
@ -12,19 +12,20 @@
|
|||||||
|
|
||||||
#[allow(dead_code)];
|
#[allow(dead_code)];
|
||||||
|
|
||||||
pub use crate_id::CrateId;
|
|
||||||
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, ExactRevision, NoVersion, split_version, split_version_general,
|
pub use version::{Version, split_version_general};
|
||||||
try_parsing_version};
|
|
||||||
pub use rustc::metadata::filesearch::rust_path;
|
pub use rustc::metadata::filesearch::rust_path;
|
||||||
use rustc::metadata::filesearch::{libdir, relative_target_lib_path};
|
|
||||||
use rustc::driver::driver::host_triple;
|
|
||||||
|
|
||||||
use std::libc;
|
use std::libc;
|
||||||
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;
|
use std::os;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::fs;
|
use std::io::fs;
|
||||||
|
use extra::hex::ToHex;
|
||||||
|
use syntax::crateid::CrateId;
|
||||||
|
use rustc::util::sha2::{Digest, Sha256};
|
||||||
|
use rustc::metadata::filesearch::{libdir, relative_target_lib_path};
|
||||||
|
use rustc::driver::driver::host_triple;
|
||||||
use messages::*;
|
use messages::*;
|
||||||
|
|
||||||
pub fn default_workspace() -> Path {
|
pub fn default_workspace() -> Path {
|
||||||
@ -78,14 +79,14 @@ pub fn workspace_contains_crate_id_(crateid: &CrateId, workspace: &Path,
|
|||||||
let mut found = None;
|
let mut found = None;
|
||||||
for p in fs::walk_dir(&src_dir) {
|
for p in fs::walk_dir(&src_dir) {
|
||||||
if p.is_dir() {
|
if p.is_dir() {
|
||||||
if p == src_dir.join(&crateid.path) || {
|
if p == src_dir.join(crateid.path.as_slice()) || {
|
||||||
let pf = p.filename_str();
|
let pf = p.filename_str();
|
||||||
pf.iter().any(|&g| {
|
pf.iter().any(|&g| {
|
||||||
match split_version_general(g, '-') {
|
match split_version_general(g, '-') {
|
||||||
None => false,
|
None => false,
|
||||||
Some((ref might_match, ref vers)) => {
|
Some((ref might_match, ref vers)) => {
|
||||||
*might_match == crateid.short_name
|
*might_match == crateid.name
|
||||||
&& (crateid.version == *vers || crateid.version == NoVersion)
|
&& (crateid.version == *vers || crateid.version == None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -173,151 +174,63 @@ fn output_in_workspace(crateid: &CrateId, workspace: &Path, what: OutputType) ->
|
|||||||
/// Figure out what the library name for <crateid> in <workspace>'s build
|
/// Figure out what the library name for <crateid> in <workspace>'s build
|
||||||
/// directory is, and if the file exists, return it.
|
/// directory is, and if the file exists, return it.
|
||||||
pub fn built_library_in_workspace(crateid: &CrateId, workspace: &Path) -> Option<Path> {
|
pub fn built_library_in_workspace(crateid: &CrateId, workspace: &Path) -> Option<Path> {
|
||||||
library_in_workspace(&crateid.path, crateid.short_name, Build, workspace, "build",
|
library_in_workspace(crateid, Build, workspace)
|
||||||
&crateid.version)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Does the actual searching stuff
|
/// Does the actual searching stuff
|
||||||
pub fn installed_library_in_workspace(pkg_path: &Path, workspace: &Path) -> Option<Path> {
|
pub fn installed_library_in_workspace(crate_id: &CrateId, workspace: &Path) -> Option<Path> {
|
||||||
// This could break once we're handling multiple versions better -- I should add a test for it
|
// This could break once we're handling multiple versions better -- I should add a test for it
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
let path = Path::new(crate_id.path.as_slice());
|
||||||
match pkg_path.filename_str() {
|
match path.filename_str() {
|
||||||
None => None,
|
None => None,
|
||||||
Some(short_name) => library_in_workspace(pkg_path,
|
Some(_short_name) => library_in_workspace(crate_id, Install, workspace)
|
||||||
short_name,
|
|
||||||
Install,
|
|
||||||
workspace,
|
|
||||||
libdir(),
|
|
||||||
&NoVersion)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `workspace` is used to figure out the directory to search.
|
/// `workspace` is used to figure out the directory to search.
|
||||||
/// `short_name` is taken as the link name of the library.
|
/// `name` is taken as the link name of the library.
|
||||||
pub fn library_in_workspace(path: &Path, short_name: &str, where: Target,
|
pub fn library_in_workspace(crate_id: &CrateId, where: Target, workspace: &Path) -> Option<Path> {
|
||||||
workspace: &Path, prefix: &str, version: &Version) -> Option<Path> {
|
|
||||||
debug!("library_in_workspace: checking whether a library named {} exists",
|
debug!("library_in_workspace: checking whether a library named {} exists",
|
||||||
short_name);
|
crate_id.name);
|
||||||
|
|
||||||
// We don't know what the hash is, so we have to search through the directory
|
|
||||||
// contents
|
|
||||||
|
|
||||||
debug!("short_name = {} where = {:?} workspace = {} \
|
|
||||||
prefix = {}", short_name, where, workspace.display(), prefix);
|
|
||||||
|
|
||||||
let dir_to_search = match where {
|
let dir_to_search = match where {
|
||||||
Build => target_build_dir(workspace).join(path),
|
Build => target_build_dir(workspace).join(crate_id.path.as_slice()),
|
||||||
Install => target_lib_dir(workspace)
|
Install => target_lib_dir(workspace)
|
||||||
};
|
};
|
||||||
|
|
||||||
library_in(short_name, version, &dir_to_search)
|
library_in(crate_id, &dir_to_search)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn system_library(sysroot: &Path, crate_id: &str) -> Option<Path> {
|
pub fn system_library(sysroot: &Path, crate_id: &CrateId) -> Option<Path> {
|
||||||
let (lib_name, version) = split_crate_id(crate_id);
|
library_in(crate_id, &sysroot.join(relative_target_lib_path(host_triple())))
|
||||||
library_in(lib_name, &version, &sysroot.join(relative_target_lib_path(host_triple())))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn library_in(short_name: &str, version: &Version, dir_to_search: &Path) -> Option<Path> {
|
fn library_in(crate_id: &CrateId, dir_to_search: &Path) -> Option<Path> {
|
||||||
debug!("Listing directory {}", dir_to_search.display());
|
let mut hasher = Sha256::new();
|
||||||
let dir_contents = {
|
hasher.reset();
|
||||||
let _guard = io::ignore_io_error();
|
hasher.input_str(crate_id.to_str());
|
||||||
fs::readdir(dir_to_search)
|
let hash = hasher.result_bytes().to_hex();
|
||||||
};
|
let hash = hash.slice_chars(0, 8);
|
||||||
debug!("dir has {:?} entries", dir_contents.len());
|
|
||||||
|
|
||||||
let dll_prefix = format!("{}{}", os::consts::DLL_PREFIX, short_name);
|
let lib_name = format!("{}-{}-{}", crate_id.name, hash, crate_id.version_or_default());
|
||||||
let dll_filetype = os::consts::DLL_EXTENSION;
|
let filenames = [
|
||||||
let rlib_prefix = format!("{}{}", "lib", short_name);
|
format!("{}{}.{}", "lib", lib_name, "rlib"),
|
||||||
let rlib_filetype = "rlib";
|
format!("{}{}{}", os::consts::DLL_PREFIX, lib_name, os::consts::DLL_SUFFIX),
|
||||||
|
];
|
||||||
|
|
||||||
debug!("dll_prefix = {} and dll_filetype = {}", dll_prefix, dll_filetype);
|
for filename in filenames.iter() {
|
||||||
debug!("rlib_prefix = {} and rlib_filetype = {}", rlib_prefix, rlib_filetype);
|
debug!("filename = {}", filename.as_slice());
|
||||||
|
let path = dir_to_search.join(filename.as_slice());
|
||||||
// Find a filename that matches the pattern:
|
if path.exists() {
|
||||||
// (lib_prefix)-hash-(version)(lib_suffix)
|
debug!("found: {}", path.display());
|
||||||
let mut libraries = dir_contents.iter().filter(|p| {
|
return Some(path);
|
||||||
let extension = p.extension_str();
|
|
||||||
debug!("p = {}, p's extension is {:?}", p.display(), extension);
|
|
||||||
match extension {
|
|
||||||
None => false,
|
|
||||||
Some(ref s) => dll_filetype == *s || rlib_filetype == *s,
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
let mut result_filename = None;
|
|
||||||
for p_path in libraries {
|
|
||||||
// Find a filename that matches the pattern: (lib_prefix)-hash-(version)(lib_suffix)
|
|
||||||
// and remember what the hash was
|
|
||||||
let mut f_name = match p_path.filestem_str() {
|
|
||||||
Some(s) => s, None => continue
|
|
||||||
};
|
|
||||||
// Already checked the filetype above
|
|
||||||
|
|
||||||
// This is complicated because library names and versions can both contain dashes
|
|
||||||
loop {
|
|
||||||
if f_name.is_empty() { break; }
|
|
||||||
match f_name.rfind('-') {
|
|
||||||
Some(i) => {
|
|
||||||
debug!("Maybe {} is a version", f_name.slice(i + 1, f_name.len()));
|
|
||||||
match try_parsing_version(f_name.slice(i + 1, f_name.len())) {
|
|
||||||
Some(ref found_vers) if version == found_vers => {
|
|
||||||
match f_name.slice(0, i).rfind('-') {
|
|
||||||
Some(j) => {
|
|
||||||
let lib_prefix = match p_path.extension_str() {
|
|
||||||
Some(ref s) if dll_filetype == *s => &dll_prefix,
|
|
||||||
_ => &rlib_prefix,
|
|
||||||
};
|
|
||||||
debug!("Maybe {} equals {}", f_name.slice(0, j), *lib_prefix);
|
|
||||||
if f_name.slice(0, j) == *lib_prefix {
|
|
||||||
result_filename = Some(p_path.clone());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
None => break
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
_ => { f_name = f_name.slice(0, i); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => break
|
|
||||||
} // match
|
|
||||||
} // loop
|
|
||||||
} // for
|
|
||||||
|
|
||||||
if result_filename.is_none() {
|
|
||||||
debug!("warning: library_in_workspace didn't find a library in {} for {}",
|
|
||||||
dir_to_search.display(), short_name);
|
|
||||||
}
|
}
|
||||||
|
debug!("warning: library_in_workspace didn't find a library in {} for {}",
|
||||||
// Return the filename that matches, which we now know exists
|
dir_to_search.display(), crate_id.to_str());
|
||||||
// (if result_filename != None)
|
return None;
|
||||||
let abs_path = result_filename.map(|result_filename| {
|
|
||||||
let absolute_path = dir_to_search.join(&result_filename);
|
|
||||||
debug!("result_filename = {}", absolute_path.display());
|
|
||||||
absolute_path
|
|
||||||
});
|
|
||||||
|
|
||||||
abs_path
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split_crate_id<'a>(crate_id: &'a str) -> (&'a str, Version) {
|
|
||||||
match split_version(crate_id) {
|
|
||||||
Some((name, vers)) =>
|
|
||||||
match vers {
|
|
||||||
ExactRevision(ref v) => match v.find('-') {
|
|
||||||
Some(pos) => (name, ExactRevision(v.slice(0, pos).to_owned())),
|
|
||||||
None => (name, ExactRevision(v.to_owned()))
|
|
||||||
},
|
|
||||||
_ => (name, vers)
|
|
||||||
},
|
|
||||||
None => (crate_id, NoVersion)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Returns the executable that would be installed for <crateid>
|
/// Returns the executable that would be installed for <crateid>
|
||||||
/// in <workspace>
|
/// in <workspace>
|
||||||
/// As a side effect, creates the bin-dir if it doesn't exist
|
/// As a side effect, creates the bin-dir if it doesn't exist
|
||||||
@ -366,7 +279,7 @@ fn target_file_in_workspace(crateid: &CrateId, workspace: &Path,
|
|||||||
// Artifacts in the build directory live in a package-ID-specific subdirectory,
|
// Artifacts in the build directory live in a package-ID-specific subdirectory,
|
||||||
// but installed ones don't.
|
// but installed ones don't.
|
||||||
let result = match (where, what) {
|
let result = match (where, what) {
|
||||||
(Build, _) => target_build_dir(workspace).join(&crateid.path),
|
(Build, _) => target_build_dir(workspace).join(crateid.path.as_slice()),
|
||||||
(Install, Lib) => target_lib_dir(workspace),
|
(Install, Lib) => target_lib_dir(workspace),
|
||||||
(Install, _) => target_bin_dir(workspace)
|
(Install, _) => target_bin_dir(workspace)
|
||||||
};
|
};
|
||||||
@ -382,7 +295,7 @@ fn target_file_in_workspace(crateid: &CrateId, workspace: &Path,
|
|||||||
/// Creates it if it doesn't exist.
|
/// Creates it if it doesn't exist.
|
||||||
pub fn build_pkg_id_in_workspace(crateid: &CrateId, workspace: &Path) -> Path {
|
pub fn build_pkg_id_in_workspace(crateid: &CrateId, workspace: &Path) -> Path {
|
||||||
let mut result = target_build_dir(workspace);
|
let mut result = target_build_dir(workspace);
|
||||||
result.push(&crateid.path);
|
result.push(crateid.path.as_slice());
|
||||||
debug!("Creating build dir {} for package id {}", result.display(),
|
debug!("Creating build dir {} for package id {}", result.display(),
|
||||||
crateid.to_str());
|
crateid.to_str());
|
||||||
fs::mkdir_recursive(&result, io::UserRWX);
|
fs::mkdir_recursive(&result, io::UserRWX);
|
||||||
@ -392,25 +305,24 @@ pub fn build_pkg_id_in_workspace(crateid: &CrateId, workspace: &Path) -> Path {
|
|||||||
/// Return the output file for a given directory name,
|
/// Return the output file for a given directory name,
|
||||||
/// given whether we're building a library and whether we're building tests
|
/// given whether we're building a library and whether we're building tests
|
||||||
pub fn mk_output_path(what: OutputType, where: Target,
|
pub fn mk_output_path(what: OutputType, where: Target,
|
||||||
pkg_id: &CrateId, workspace: Path) -> Path {
|
crate_id: &CrateId, workspace: Path) -> Path {
|
||||||
let short_name_with_version = format!("{}-{}", pkg_id.short_name,
|
let short_name_with_version = crate_id.short_name_with_version();
|
||||||
pkg_id.version.to_str());
|
|
||||||
// Not local_path.dir_path()! For package foo/bar/blat/, we want
|
// Not local_path.dir_path()! For package foo/bar/blat/, we want
|
||||||
// the executable blat-0.5 to live under blat/
|
// the executable blat-0.5 to live under blat/
|
||||||
let dir = match where {
|
let dir = match where {
|
||||||
// If we're installing, it just goes under <workspace>...
|
// If we're installing, it just goes under <workspace>...
|
||||||
Install => workspace,
|
Install => workspace,
|
||||||
// and if we're just building, it goes in a package-specific subdir
|
// and if we're just building, it goes in a package-specific subdir
|
||||||
Build => workspace.join(&pkg_id.path)
|
Build => workspace.join(crate_id.path.as_slice())
|
||||||
};
|
};
|
||||||
debug!("[{:?}:{:?}] mk_output_path: short_name = {}, path = {}", what, where,
|
debug!("[{:?}:{:?}] mk_output_path: name = {}, path = {}", what, where,
|
||||||
if what == Lib { short_name_with_version.clone() } else { pkg_id.short_name.clone() },
|
if what == Lib { short_name_with_version.clone() } else { crate_id.name.clone() },
|
||||||
dir.display());
|
dir.display());
|
||||||
let mut output_path = match what {
|
let mut output_path = match what {
|
||||||
// this code is duplicated from elsewhere; fix this
|
// this code is duplicated from elsewhere; fix this
|
||||||
Lib => dir.join(os::dll_filename(short_name_with_version)),
|
Lib => dir.join(os::dll_filename(short_name_with_version)),
|
||||||
// executable names *aren't* versioned
|
// executable names *aren't* versioned
|
||||||
_ => dir.join(format!("{}{}{}", pkg_id.short_name,
|
_ => dir.join(format!("{}{}{}", crate_id.name,
|
||||||
match what {
|
match what {
|
||||||
Test => "test",
|
Test => "test",
|
||||||
Bench => "bench",
|
Bench => "bench",
|
||||||
@ -457,11 +369,12 @@ fn dir_has_file(dir: &Path, file: &str) -> bool {
|
|||||||
|
|
||||||
pub fn find_dir_using_rust_path_hack(p: &CrateId) -> Option<Path> {
|
pub fn find_dir_using_rust_path_hack(p: &CrateId) -> Option<Path> {
|
||||||
let rp = rust_path();
|
let rp = rust_path();
|
||||||
|
let path = Path::new(p.path.as_slice());
|
||||||
for dir in rp.iter() {
|
for dir in rp.iter() {
|
||||||
// Require that the parent directory match the package ID
|
// Require that the parent directory match the package ID
|
||||||
// Note that this only matches if the package ID being searched for
|
// Note that this only matches if the package ID being searched for
|
||||||
// has a name that's a single component
|
// has a name that's a single component
|
||||||
if dir.ends_with_path(&p.path) || dir.ends_with_path(&versionize(&p.path, &p.version)) {
|
if dir.ends_with_path(&path) || dir.ends_with_path(&versionize(p.path, &p.version)) {
|
||||||
debug!("In find_dir_using_rust_path_hack: checking dir {}", dir.display());
|
debug!("In find_dir_using_rust_path_hack: checking dir {}", dir.display());
|
||||||
if dir_has_crate_file(dir) {
|
if dir_has_crate_file(dir) {
|
||||||
debug!("Did find id {} in dir {}", p.to_str(), dir.display());
|
debug!("Did find id {} in dir {}", p.to_str(), dir.display());
|
||||||
@ -483,11 +396,12 @@ pub fn user_set_rust_path() -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Append the version string onto the end of the path's filename
|
/// Append the version string onto the end of the path's filename
|
||||||
pub fn versionize(p: &Path, v: &Version) -> Path {
|
pub fn versionize(p: &str, v: &Version) -> Path {
|
||||||
|
let p = Path::new(p);
|
||||||
let q = p.filename().expect("path is a directory");
|
let q = p.filename().expect("path is a directory");
|
||||||
let mut q = q.to_owned();
|
let mut q = q.to_owned();
|
||||||
q.push('-' as u8);
|
q.push('-' as u8);
|
||||||
let vs = v.to_str();
|
let vs = match v { &Some(ref s) => s.to_owned(), &None => ~"0.0" };
|
||||||
q.push_all(vs.as_bytes());
|
q.push_all(vs.as_bytes());
|
||||||
p.with_filename(q)
|
p.with_filename(q)
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@ use std::{run, str};
|
|||||||
use std::run::{ProcessOutput, ProcessOptions, Process};
|
use std::run::{ProcessOutput, ProcessOptions, Process};
|
||||||
use std::io::fs;
|
use std::io::fs;
|
||||||
use extra::tempfile::TempDir;
|
use extra::tempfile::TempDir;
|
||||||
use version::*;
|
|
||||||
use path_util::chmod_read_only;
|
use path_util::chmod_read_only;
|
||||||
|
|
||||||
/// Attempts to clone `source`, a local git repository, into `target`, a local
|
/// Attempts to clone `source`, a local git repository, into `target`, a local
|
||||||
@ -22,7 +21,7 @@ use path_util::chmod_read_only;
|
|||||||
/// Returns `DirToUse(p)` if the clone fails, where `p` is a newly created temporary
|
/// Returns `DirToUse(p)` if the clone fails, where `p` is a newly created temporary
|
||||||
/// directory (that the callee may use, for example, to check out remote sources into).
|
/// directory (that the callee may use, for example, to check out remote sources into).
|
||||||
/// Returns `CheckedOutSources` if the clone succeeded.
|
/// Returns `CheckedOutSources` if the clone succeeded.
|
||||||
pub fn safe_git_clone(source: &Path, v: &Version, target: &Path) -> CloneResult {
|
pub fn safe_git_clone(source: &Path, v: &Option<~str>, target: &Path) -> CloneResult {
|
||||||
if source.exists() {
|
if source.exists() {
|
||||||
debug!("{} exists locally! Cloning it into {}",
|
debug!("{} exists locally! Cloning it into {}",
|
||||||
source.display(), target.display());
|
source.display(), target.display());
|
||||||
@ -44,7 +43,7 @@ pub fn safe_git_clone(source: &Path, v: &Version, target: &Path) -> CloneResult
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
match v {
|
match v {
|
||||||
&ExactRevision(ref s) => {
|
&Some(ref s) => {
|
||||||
let git_dir = target.join(".git");
|
let git_dir = target.join(".git");
|
||||||
debug!("`Running: git --work-tree={} --git-dir={} checkout {}",
|
debug!("`Running: git --work-tree={} --git-dir={} checkout {}",
|
||||||
*s, target.display(), git_dir.display());
|
*s, target.display(), git_dir.display());
|
||||||
@ -65,7 +64,7 @@ pub fn safe_git_clone(source: &Path, v: &Version, target: &Path) -> CloneResult
|
|||||||
} else {
|
} else {
|
||||||
// Check that no version was specified. There's no reason to not handle the
|
// Check that no version was specified. There's no reason to not handle the
|
||||||
// case where a version was requested, but I haven't implemented it.
|
// case where a version was requested, but I haven't implemented it.
|
||||||
assert!(*v == NoVersion);
|
assert!(*v == None);
|
||||||
let git_dir = target.join(".git");
|
let git_dir = target.join(".git");
|
||||||
debug!("Running: git --work-tree={} --git-dir={} pull --no-edit {}",
|
debug!("Running: git --work-tree={} --git-dir={} pull --no-edit {}",
|
||||||
target.display(), git_dir.display(), source.display());
|
target.display(), git_dir.display(), source.display());
|
||||||
@ -106,7 +105,7 @@ pub fn make_read_only(target: &Path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Source can be either a URL or a local file path.
|
/// Source can be either a URL or a local file path.
|
||||||
pub fn git_clone_url(source: &str, target: &Path, v: &Version) {
|
pub fn git_clone_url(source: &str, target: &Path, v: &Option<~str>) {
|
||||||
use conditions::git_checkout_failed::cond;
|
use conditions::git_checkout_failed::cond;
|
||||||
|
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||||
@ -120,7 +119,7 @@ pub fn git_clone_url(source: &str, target: &Path, v: &Version) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
match v {
|
match v {
|
||||||
&ExactRevision(ref s) | &Tagged(ref s) => {
|
&Some(ref s) => {
|
||||||
let opt_outp = process_output_in_cwd("git", [~"checkout", s.to_owned()],
|
let opt_outp = process_output_in_cwd("git", [~"checkout", s.to_owned()],
|
||||||
target);
|
target);
|
||||||
let outp = opt_outp.expect("Failed to exec `git`");
|
let outp = opt_outp.expect("Failed to exec `git`");
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -13,7 +13,7 @@ extern mod rustc;
|
|||||||
|
|
||||||
use std::{os, task};
|
use std::{os, task};
|
||||||
use rustpkg::api;
|
use rustpkg::api;
|
||||||
use rustpkg::version::NoVersion;
|
use rustpkg::version::None;
|
||||||
use rustpkg::workcache_support::digest_file_with_date;
|
use rustpkg::workcache_support::digest_file_with_date;
|
||||||
use rustpkg::exit_codes::COPY_FAILED_CODE;
|
use rustpkg::exit_codes::COPY_FAILED_CODE;
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ pub fn main() {
|
|||||||
api::install_pkg(&mut cc,
|
api::install_pkg(&mut cc,
|
||||||
os::getcwd(),
|
os::getcwd(),
|
||||||
~"cdep",
|
~"cdep",
|
||||||
NoVersion,
|
None,
|
||||||
~[(~"binary", out_lib_path.clone()), (~"file", foo_c_name.clone())]);
|
~[(~"binary", out_lib_path.clone()), (~"file", foo_c_name.clone())]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ extern mod rustc;
|
|||||||
use std::os;
|
use std::os;
|
||||||
use std::io::File;
|
use std::io::File;
|
||||||
use rustpkg::api;
|
use rustpkg::api;
|
||||||
use rustpkg::version::NoVersion;
|
use rustpkg::version::None;
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let args = os::args();
|
let args = os::args();
|
||||||
@ -48,5 +48,5 @@ pub fn main() {
|
|||||||
for _ in xs.iter() { assert!(true); } }".as_bytes());
|
for _ in xs.iter() { assert!(true); } }".as_bytes());
|
||||||
|
|
||||||
let context = api::default_context(sysroot, api::default_workspace());
|
let context = api::default_context(sysroot, api::default_workspace());
|
||||||
api::install_pkg(&context, os::getcwd(), ~"fancy-lib", NoVersion, ~[]);
|
api::install_pkg(&context, os::getcwd(), ~"fancy-lib", None, ~[]);
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,10 @@
|
|||||||
|
|
||||||
#[allow(dead_code)];
|
#[allow(dead_code)];
|
||||||
|
|
||||||
|
pub use target::{OutputType, Main, Lib, Bench, Test, JustOne, lib_name_of, lib_crate_filename};
|
||||||
|
pub use target::{Target, Build, Install};
|
||||||
|
pub use target::{lib_name_of, lib_crate_filename, WhatToBuild, MaybeCustom, Inferred};
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::libc;
|
use std::libc;
|
||||||
use std::os;
|
use std::os;
|
||||||
@ -17,7 +21,7 @@ use std::io;
|
|||||||
use std::io::fs;
|
use std::io::fs;
|
||||||
use extra::workcache;
|
use extra::workcache;
|
||||||
use rustc::metadata::creader::Loader;
|
use rustc::metadata::creader::Loader;
|
||||||
use rustc::driver::{driver, session};
|
use extra::treemap::TreeMap;
|
||||||
use extra::getopts::groups::getopts;
|
use extra::getopts::groups::getopts;
|
||||||
use syntax;
|
use syntax;
|
||||||
use syntax::codemap::{DUMMY_SP, Spanned};
|
use syntax::codemap::{DUMMY_SP, Spanned};
|
||||||
@ -28,19 +32,16 @@ use syntax::attr::AttrMetaMethods;
|
|||||||
use syntax::fold::Folder;
|
use syntax::fold::Folder;
|
||||||
use syntax::visit::Visitor;
|
use syntax::visit::Visitor;
|
||||||
use syntax::util::small_vector::SmallVector;
|
use syntax::util::small_vector::SmallVector;
|
||||||
|
use syntax::crateid::CrateId;
|
||||||
use rustc::back::link::OutputTypeExe;
|
use rustc::back::link::OutputTypeExe;
|
||||||
use rustc::back::link;
|
use rustc::back::link;
|
||||||
|
use rustc::driver::{driver, session};
|
||||||
use CtxMethods;
|
use CtxMethods;
|
||||||
use context::{in_target, StopBefore, Link, Assemble, BuildContext};
|
use context::{in_target, StopBefore, Link, Assemble, BuildContext};
|
||||||
use crate_id::CrateId;
|
|
||||||
use package_source::PkgSrc;
|
use package_source::PkgSrc;
|
||||||
use workspace::pkg_parent_workspaces;
|
use workspace::pkg_parent_workspaces;
|
||||||
use path_util::{system_library, target_build_dir};
|
use path_util::{system_library, target_build_dir};
|
||||||
use path_util::{default_workspace, built_library_in_workspace};
|
use path_util::{default_workspace, built_library_in_workspace};
|
||||||
pub use target::{OutputType, Main, Lib, Bench, Test, JustOne, lib_name_of, lib_crate_filename};
|
|
||||||
pub use target::{Target, Build, Install};
|
|
||||||
use extra::treemap::TreeMap;
|
|
||||||
pub use target::{lib_name_of, lib_crate_filename, WhatToBuild, MaybeCustom, Inferred};
|
|
||||||
use workcache_support::{digest_file_with_date, digest_only_date};
|
use workcache_support::{digest_file_with_date, digest_only_date};
|
||||||
use messages::error;
|
use messages::error;
|
||||||
|
|
||||||
@ -135,7 +136,7 @@ struct CrateSetup<'a> {
|
|||||||
ctx: &'a mut ReadyCtx<'a>,
|
ctx: &'a mut ReadyCtx<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> fold::Folder for CrateSetup<'a> {
|
impl<'a> Folder for CrateSetup<'a> {
|
||||||
fn fold_item(&mut self, item: @ast::Item) -> SmallVector<@ast::Item> {
|
fn fold_item(&mut self, item: @ast::Item) -> SmallVector<@ast::Item> {
|
||||||
fold_item(item, self)
|
fold_item(item, self)
|
||||||
}
|
}
|
||||||
@ -162,7 +163,7 @@ pub fn ready_crate(sess: session::Session,
|
|||||||
|
|
||||||
pub fn compile_input(context: &BuildContext,
|
pub fn compile_input(context: &BuildContext,
|
||||||
exec: &mut workcache::Exec,
|
exec: &mut workcache::Exec,
|
||||||
pkg_id: &CrateId,
|
crate_id: &CrateId,
|
||||||
in_file: &Path,
|
in_file: &Path,
|
||||||
workspace: &Path,
|
workspace: &Path,
|
||||||
deps: &mut DepMap,
|
deps: &mut DepMap,
|
||||||
@ -177,11 +178,11 @@ pub fn compile_input(context: &BuildContext,
|
|||||||
// not sure if we should support anything else
|
// not sure if we should support anything else
|
||||||
|
|
||||||
let mut out_dir = target_build_dir(workspace);
|
let mut out_dir = target_build_dir(workspace);
|
||||||
out_dir.push(&pkg_id.path);
|
out_dir.push(crate_id.path.as_slice());
|
||||||
// Make the output directory if it doesn't exist already
|
// Make the output directory if it doesn't exist already
|
||||||
fs::mkdir_recursive(&out_dir, io::UserRWX);
|
fs::mkdir_recursive(&out_dir, io::UserRWX);
|
||||||
|
|
||||||
let binary = os::args()[0].to_owned();
|
let binary = os::args()[0];
|
||||||
|
|
||||||
debug!("flags: {}", flags.connect(" "));
|
debug!("flags: {}", flags.connect(" "));
|
||||||
debug!("cfgs: {}", cfgs.connect(" "));
|
debug!("cfgs: {}", cfgs.connect(" "));
|
||||||
@ -276,7 +277,7 @@ pub fn compile_input(context: &BuildContext,
|
|||||||
let (mut crate, ast_map) = {
|
let (mut crate, ast_map) = {
|
||||||
let installer = CrateInstaller {
|
let installer = CrateInstaller {
|
||||||
context: context,
|
context: context,
|
||||||
parent: pkg_id,
|
parent: crate_id,
|
||||||
parent_crate: in_file,
|
parent_crate: in_file,
|
||||||
sess: sess,
|
sess: sess,
|
||||||
exec: exec,
|
exec: exec,
|
||||||
@ -312,10 +313,7 @@ pub fn compile_input(context: &BuildContext,
|
|||||||
if !attr::contains_name(crate.attrs, "crate_id") {
|
if !attr::contains_name(crate.attrs, "crate_id") {
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||||
let crateid_attr =
|
let crateid_attr =
|
||||||
attr::mk_name_value_item_str(@"crate_id",
|
attr::mk_name_value_item_str(@"crate_id", crate_id.to_str().to_managed());
|
||||||
format!("{}\\#{}",
|
|
||||||
pkg_id.path.as_str().unwrap(),
|
|
||||||
pkg_id.version.to_str()).to_managed());
|
|
||||||
|
|
||||||
debug!("crateid attr: {:?}", crateid_attr);
|
debug!("crateid attr: {:?}", crateid_attr);
|
||||||
crate.attrs.push(attr::mk_attr(crateid_attr));
|
crate.attrs.push(attr::mk_attr(crateid_attr));
|
||||||
@ -333,7 +331,7 @@ pub fn compile_input(context: &BuildContext,
|
|||||||
what);
|
what);
|
||||||
// Discover the output
|
// Discover the output
|
||||||
let discovered_output = if what == Lib {
|
let discovered_output = if what == Lib {
|
||||||
built_library_in_workspace(pkg_id, workspace) // Huh???
|
built_library_in_workspace(crate_id, workspace) // Huh???
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result
|
result
|
||||||
@ -435,7 +433,7 @@ pub fn exe_suffix() -> ~str { ~"" }
|
|||||||
// Called by build_crates
|
// Called by build_crates
|
||||||
pub fn compile_crate(ctxt: &BuildContext,
|
pub fn compile_crate(ctxt: &BuildContext,
|
||||||
exec: &mut workcache::Exec,
|
exec: &mut workcache::Exec,
|
||||||
pkg_id: &CrateId,
|
crate_id: &CrateId,
|
||||||
crate: &Path,
|
crate: &Path,
|
||||||
workspace: &Path,
|
workspace: &Path,
|
||||||
deps: &mut DepMap,
|
deps: &mut DepMap,
|
||||||
@ -444,11 +442,11 @@ pub fn compile_crate(ctxt: &BuildContext,
|
|||||||
opt: session::OptLevel,
|
opt: session::OptLevel,
|
||||||
what: OutputType) -> Option<Path> {
|
what: OutputType) -> Option<Path> {
|
||||||
debug!("compile_crate: crate={}, workspace={}", crate.display(), workspace.display());
|
debug!("compile_crate: crate={}, workspace={}", crate.display(), workspace.display());
|
||||||
debug!("compile_crate: short_name = {}, flags =...", pkg_id.to_str());
|
debug!("compile_crate: name = {}, flags =...", crate_id.to_str());
|
||||||
for fl in flags.iter() {
|
for fl in flags.iter() {
|
||||||
debug!("+++ {}", *fl);
|
debug!("+++ {}", *fl);
|
||||||
}
|
}
|
||||||
compile_input(ctxt, exec, pkg_id, crate, workspace, deps, flags, cfgs, opt, what)
|
compile_input(ctxt, exec, crate_id, crate, workspace, deps, flags, cfgs, opt, what)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CrateInstaller<'a> {
|
struct CrateInstaller<'a> {
|
||||||
@ -473,8 +471,9 @@ impl<'a> CrateInstaller<'a> {
|
|||||||
None => self.sess.str_of(lib_ident)
|
None => self.sess.str_of(lib_ident)
|
||||||
};
|
};
|
||||||
debug!("Finding and installing... {}", lib_name);
|
debug!("Finding and installing... {}", lib_name);
|
||||||
|
let crate_id: CrateId = from_str(lib_name).expect("valid crate id");
|
||||||
// Check standard Rust library path first
|
// Check standard Rust library path first
|
||||||
let whatever = system_library(&self.context.sysroot_to_use(), lib_name);
|
let whatever = system_library(&self.context.sysroot_to_use(), &crate_id);
|
||||||
debug!("system library returned {:?}", whatever);
|
debug!("system library returned {:?}", whatever);
|
||||||
match whatever {
|
match whatever {
|
||||||
Some(ref installed_path) => {
|
Some(ref installed_path) => {
|
||||||
@ -494,13 +493,11 @@ impl<'a> CrateInstaller<'a> {
|
|||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// FIXME #8711: need to parse version out of path_opt
|
// FIXME #8711: need to parse version out of path_opt
|
||||||
debug!("Trying to install library {}, rebuilding it",
|
debug!("Trying to install library {}, rebuilding it", crate_id.to_str());
|
||||||
lib_name.to_str());
|
|
||||||
// Try to install it
|
// Try to install it
|
||||||
let pkg_id = CrateId::new(lib_name);
|
|
||||||
// Find all the workspaces in the RUST_PATH that contain this package.
|
// Find all the workspaces in the RUST_PATH that contain this package.
|
||||||
let workspaces = pkg_parent_workspaces(&self.context.context,
|
let workspaces = pkg_parent_workspaces(&self.context.context,
|
||||||
&pkg_id);
|
&crate_id);
|
||||||
// Three cases:
|
// Three cases:
|
||||||
// (a) `workspaces` is empty. That means there's no local source
|
// (a) `workspaces` is empty. That means there's no local source
|
||||||
// for this package. In that case, we pass the default workspace
|
// for this package. In that case, we pass the default workspace
|
||||||
@ -529,8 +526,8 @@ impl<'a> CrateInstaller<'a> {
|
|||||||
// Nonexistent package? Then print a better error
|
// Nonexistent package? Then print a better error
|
||||||
error(format!("Package {} depends on {}, but I don't know \
|
error(format!("Package {} depends on {}, but I don't know \
|
||||||
how to find it",
|
how to find it",
|
||||||
self.parent.path.display(),
|
self.parent.path,
|
||||||
pkg_id.path.display()));
|
crate_id.path));
|
||||||
fail!()
|
fail!()
|
||||||
}).inside(|| {
|
}).inside(|| {
|
||||||
PkgSrc::new(source_workspace.clone(),
|
PkgSrc::new(source_workspace.clone(),
|
||||||
@ -538,7 +535,7 @@ impl<'a> CrateInstaller<'a> {
|
|||||||
// Use the rust_path_hack to search for dependencies iff
|
// Use the rust_path_hack to search for dependencies iff
|
||||||
// we were already using it
|
// we were already using it
|
||||||
self.context.context.use_rust_path_hack,
|
self.context.context.use_rust_path_hack,
|
||||||
pkg_id.clone())
|
crate_id.clone())
|
||||||
});
|
});
|
||||||
let (outputs_disc, inputs_disc) =
|
let (outputs_disc, inputs_disc) =
|
||||||
self.context.install(
|
self.context.install(
|
||||||
|
@ -13,170 +13,9 @@
|
|||||||
|
|
||||||
extern mod std;
|
extern mod std;
|
||||||
|
|
||||||
use extra::semver;
|
use std::char;
|
||||||
use std::{char, result, run, str};
|
|
||||||
use extra::tempfile::TempDir;
|
|
||||||
use path_util::rust_path;
|
|
||||||
|
|
||||||
#[deriving(Clone)]
|
pub type Version = Option<~str>;
|
||||||
pub enum Version {
|
|
||||||
ExactRevision(~str), // Should look like a m.n.(...).x
|
|
||||||
SemanticVersion(semver::Version),
|
|
||||||
Tagged(~str), // String that can't be parsed as a version.
|
|
||||||
// Requirements get interpreted exactly
|
|
||||||
NoVersion // user didn't specify a version -- prints as 0.0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Equality on versions is non-symmetric: if self is NoVersion, it's equal to
|
|
||||||
// anything; but if self is a precise version, it's not equal to NoVersion.
|
|
||||||
// We should probably make equality symmetric, and use less-than and greater-than
|
|
||||||
// where we currently use eq
|
|
||||||
impl Eq for Version {
|
|
||||||
fn eq(&self, other: &Version) -> bool {
|
|
||||||
match (self, other) {
|
|
||||||
(&ExactRevision(ref s1), &ExactRevision(ref s2)) => *s1 == *s2,
|
|
||||||
(&SemanticVersion(ref v1), &SemanticVersion(ref v2)) => *v1 == *v2,
|
|
||||||
(&NoVersion, _) => true,
|
|
||||||
_ => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Ord for Version {
|
|
||||||
fn lt(&self, other: &Version) -> bool {
|
|
||||||
match (self, other) {
|
|
||||||
(&NoVersion, _) => true,
|
|
||||||
(&ExactRevision(ref f1), &ExactRevision(ref f2)) => f1 < f2,
|
|
||||||
(&SemanticVersion(ref v1), &SemanticVersion(ref v2)) => v1 < v2,
|
|
||||||
_ => false // incomparable, really
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn le(&self, other: &Version) -> bool {
|
|
||||||
match (self, other) {
|
|
||||||
(&NoVersion, _) => true,
|
|
||||||
(&ExactRevision(ref f1), &ExactRevision(ref f2)) => f1 <= f2,
|
|
||||||
(&SemanticVersion(ref v1), &SemanticVersion(ref v2)) => v1 <= v2,
|
|
||||||
_ => false // incomparable, really
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn ge(&self, other: &Version) -> bool {
|
|
||||||
match (self, other) {
|
|
||||||
(&ExactRevision(ref f1), &ExactRevision(ref f2)) => f1 > f2,
|
|
||||||
(&SemanticVersion(ref v1), &SemanticVersion(ref v2)) => v1 > v2,
|
|
||||||
_ => false // incomparable, really
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn gt(&self, other: &Version) -> bool {
|
|
||||||
match (self, other) {
|
|
||||||
(&ExactRevision(ref f1), &ExactRevision(ref f2)) => f1 >= f2,
|
|
||||||
(&SemanticVersion(ref v1), &SemanticVersion(ref v2)) => v1 >= v2,
|
|
||||||
_ => false // incomparable, really
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToStr for Version {
|
|
||||||
fn to_str(&self) -> ~str {
|
|
||||||
match *self {
|
|
||||||
ExactRevision(ref n) | Tagged(ref n) => format!("{}", n.to_str()),
|
|
||||||
SemanticVersion(ref v) => format!("{}", v.to_str()),
|
|
||||||
NoVersion => ~"0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse_vers(vers: ~str) -> result::Result<semver::Version, ~str> {
|
|
||||||
match semver::parse(vers) {
|
|
||||||
Some(vers) => result::Ok(vers),
|
|
||||||
None => result::Err(~"could not parse version: invalid")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If `local_path` is a git repo in the RUST_PATH, and the most recent tag
|
|
||||||
/// in that repo denotes a version, return it; otherwise, `None`
|
|
||||||
pub fn try_getting_local_version(local_path: &Path) -> Option<Version> {
|
|
||||||
let rustpath = rust_path();
|
|
||||||
for rp in rustpath.iter() {
|
|
||||||
let local_path = rp.join(local_path);
|
|
||||||
let git_dir = local_path.join(".git");
|
|
||||||
if !git_dir.is_dir() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
|
||||||
let opt_outp = run::process_output("git",
|
|
||||||
["--git-dir=" + git_dir.as_str().unwrap(), ~"tag", ~"-l"]);
|
|
||||||
let outp = opt_outp.expect("Failed to exec `git`");
|
|
||||||
|
|
||||||
debug!("git --git-dir={} tag -l ~~~> {:?}", git_dir.display(), outp.status);
|
|
||||||
|
|
||||||
if !outp.status.success() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut output = None;
|
|
||||||
let output_text = str::from_utf8(outp.output).unwrap();
|
|
||||||
for l in output_text.lines() {
|
|
||||||
if !l.is_whitespace() {
|
|
||||||
output = Some(l);
|
|
||||||
}
|
|
||||||
match output.and_then(try_parsing_version) {
|
|
||||||
Some(v) => return Some(v),
|
|
||||||
None => ()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If `remote_path` refers to a git repo that can be downloaded,
|
|
||||||
/// and the most recent tag in that repo denotes a version, return it;
|
|
||||||
/// otherwise, `None`
|
|
||||||
pub fn try_getting_version(remote_path: &Path) -> Option<Version> {
|
|
||||||
if is_url_like(remote_path) {
|
|
||||||
let tmp_dir = TempDir::new("test");
|
|
||||||
let tmp_dir = tmp_dir.expect("try_getting_version: couldn't create temp dir");
|
|
||||||
let tmp_dir = tmp_dir.path();
|
|
||||||
debug!("(to get version) executing \\{git clone https://{} {}\\}",
|
|
||||||
remote_path.display(),
|
|
||||||
tmp_dir.display());
|
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
|
||||||
let opt_outp = run::process_output("git", [~"clone", format!("https://{}",
|
|
||||||
remote_path.as_str().unwrap()),
|
|
||||||
tmp_dir.as_str().unwrap().to_owned()]);
|
|
||||||
let outp = opt_outp.expect("Failed to exec `git`");
|
|
||||||
if outp.status.success() {
|
|
||||||
debug!("Cloned it... ( {}, {} )",
|
|
||||||
str::from_utf8(outp.output).unwrap(),
|
|
||||||
str::from_utf8(outp.error).unwrap());
|
|
||||||
let mut output = None;
|
|
||||||
let git_dir = tmp_dir.join(".git");
|
|
||||||
debug!("(getting version, now getting tags) executing \\{git --git-dir={} tag -l\\}",
|
|
||||||
git_dir.display());
|
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
|
||||||
let opt_outp = run::process_output("git",
|
|
||||||
["--git-dir=" + git_dir.as_str().unwrap(),
|
|
||||||
~"tag", ~"-l"]);
|
|
||||||
let outp = opt_outp.expect("Failed to exec `git`");
|
|
||||||
let output_text = str::from_utf8(outp.output).unwrap();
|
|
||||||
debug!("Full output: ( {} ) [{:?}]", output_text, outp.status);
|
|
||||||
for l in output_text.lines() {
|
|
||||||
debug!("A line of output: {}", l);
|
|
||||||
if !l.is_whitespace() {
|
|
||||||
output = Some(l);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
output.and_then(try_parsing_version)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Being lazy since we don't have a regexp library now
|
// Being lazy since we don't have a regexp library now
|
||||||
#[deriving(Eq)]
|
#[deriving(Eq)]
|
||||||
@ -186,7 +25,7 @@ enum ParseState {
|
|||||||
SawDot
|
SawDot
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_parsing_version(s: &str) -> Option<Version> {
|
pub fn try_parsing_version(s: &str) -> Option<~str> {
|
||||||
let s = s.trim();
|
let s = s.trim();
|
||||||
debug!("Attempting to parse: {}", s);
|
debug!("Attempting to parse: {}", s);
|
||||||
let mut parse_state = Start;
|
let mut parse_state = Start;
|
||||||
@ -202,17 +41,11 @@ pub fn try_parsing_version(s: &str) -> Option<Version> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
match parse_state {
|
match parse_state {
|
||||||
SawDigit => Some(ExactRevision(s.to_owned())),
|
SawDigit => Some(s.to_owned()),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Just an approximation
|
|
||||||
fn is_url_like(p: &Path) -> bool {
|
|
||||||
// check if there are more than 2 /-separated components
|
|
||||||
p.as_vec().split(|b| *b == '/' as u8).nth(2).is_some()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If s is of the form foo#bar, where bar is a valid version
|
/// If s is of the form foo#bar, where bar is a valid version
|
||||||
/// number, return the prefix before the # and the version.
|
/// number, return the prefix before the # and the version.
|
||||||
/// Otherwise, return None.
|
/// Otherwise, return None.
|
||||||
@ -229,7 +62,7 @@ pub fn split_version_general<'a>(s: &'a str, sep: char) -> Option<(&'a str, Vers
|
|||||||
Some(i) => {
|
Some(i) => {
|
||||||
let path = s.slice(0, i);
|
let path = s.slice(0, i);
|
||||||
// n.b. for now, assuming an exact revision is intended, not a SemVer
|
// n.b. for now, assuming an exact revision is intended, not a SemVer
|
||||||
Some((path, ExactRevision(s.slice(i + 1, s.len()).to_owned())))
|
Some((path, Some(s.slice(i + 1, s.len()).to_owned())))
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
None
|
None
|
||||||
@ -239,11 +72,11 @@ pub fn split_version_general<'a>(s: &'a str, sep: char) -> Option<(&'a str, Vers
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_version() {
|
fn test_parse_version() {
|
||||||
assert!(try_parsing_version("1.2") == Some(ExactRevision(~"1.2")));
|
assert!(try_parsing_version("1.2") == Some(~"1.2"));
|
||||||
assert!(try_parsing_version("1.0.17") == Some(ExactRevision(~"1.0.17")));
|
assert!(try_parsing_version("1.0.17") == Some(~"1.0.17"));
|
||||||
assert!(try_parsing_version("you're_a_kitty") == None);
|
assert!(try_parsing_version("you're_a_kitty") == None);
|
||||||
assert!(try_parsing_version("42..1") == None);
|
assert!(try_parsing_version("42..1") == None);
|
||||||
assert!(try_parsing_version("17") == Some(ExactRevision(~"17")));
|
assert!(try_parsing_version("17") == Some(~"17"));
|
||||||
assert!(try_parsing_version(".1.2.3") == None);
|
assert!(try_parsing_version(".1.2.3") == None);
|
||||||
assert!(try_parsing_version("2.3.") == None);
|
assert!(try_parsing_version("2.3.") == None);
|
||||||
}
|
}
|
||||||
@ -252,9 +85,9 @@ fn test_parse_version() {
|
|||||||
fn test_split_version() {
|
fn test_split_version() {
|
||||||
let s = "a/b/c#0.1";
|
let s = "a/b/c#0.1";
|
||||||
debug!("== {:?} ==", split_version(s));
|
debug!("== {:?} ==", split_version(s));
|
||||||
assert!(split_version(s) == Some((s.slice(0, 5), ExactRevision(~"0.1"))));
|
assert!(split_version(s) == Some((s.slice(0, 5), Some(~"0.1"))));
|
||||||
assert!(split_version("a/b/c") == None);
|
assert!(split_version("a/b/c") == None);
|
||||||
let s = "a#1.2";
|
let s = "a#1.2";
|
||||||
assert!(split_version(s) == Some((s.slice(0, 1), ExactRevision(~"1.2"))));
|
assert!(split_version(s) == Some((s.slice(0, 1), Some(~"1.2"))));
|
||||||
assert!(split_version("a#a#3.4") == None);
|
assert!(split_version("a#a#3.4") == None);
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,11 @@
|
|||||||
// rustpkg utilities having to do with workspaces
|
// rustpkg utilities having to do with workspaces
|
||||||
|
|
||||||
use std::os;
|
use std::os;
|
||||||
use std::path::Path;
|
|
||||||
use context::Context;
|
use context::Context;
|
||||||
use path_util::{workspace_contains_crate_id, find_dir_using_rust_path_hack, default_workspace};
|
use path_util::{workspace_contains_crate_id, find_dir_using_rust_path_hack, default_workspace};
|
||||||
use path_util::rust_path;
|
use path_util::rust_path;
|
||||||
use util::option_to_vec;
|
use util::option_to_vec;
|
||||||
use crate_id::CrateId;
|
use syntax::crateid::CrateId;
|
||||||
|
|
||||||
pub fn each_pkg_parent_workspace(cx: &Context,
|
pub fn each_pkg_parent_workspace(cx: &Context,
|
||||||
crateid: &CrateId,
|
crateid: &CrateId,
|
||||||
@ -29,7 +28,7 @@ pub fn each_pkg_parent_workspace(cx: &Context,
|
|||||||
// tjc: make this a condition
|
// tjc: make this a condition
|
||||||
fail!("Package {} not found in any of \
|
fail!("Package {} not found in any of \
|
||||||
the following workspaces: {}",
|
the following workspaces: {}",
|
||||||
crateid.path.display(),
|
crateid.path,
|
||||||
rust_path().map(|p| p.display().to_str()).to_str());
|
rust_path().map(|p| p.display().to_str()).to_str());
|
||||||
}
|
}
|
||||||
for ws in workspaces.iter() {
|
for ws in workspaces.iter() {
|
||||||
@ -64,7 +63,8 @@ pub fn cwd_to_workspace() -> Option<(Path, CrateId)> {
|
|||||||
let rel = cwd.path_relative_from(&srcpath);
|
let rel = cwd.path_relative_from(&srcpath);
|
||||||
let rel_s = rel.as_ref().and_then(|p|p.as_str());
|
let rel_s = rel.as_ref().and_then(|p|p.as_str());
|
||||||
if rel_s.is_some() {
|
if rel_s.is_some() {
|
||||||
return Some((path, CrateId::new(rel_s.unwrap())));
|
let crate_id = from_str(rel_s.unwrap()).expect("valid crate id");
|
||||||
|
return Some((path, crate_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,11 @@ impl FromStr for CrateId {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let version = if !hash_version.is_empty() {
|
let version = if !hash_version.is_empty() {
|
||||||
Some(hash_version.to_owned())
|
if hash_version == "0.0" {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(hash_version.to_owned())
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
@ -93,6 +97,10 @@ impl CrateId {
|
|||||||
Some(ref version) => version.as_slice(),
|
Some(ref version) => version.as_slice(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn short_name_with_version(&self) -> ~str {
|
||||||
|
format!("{}-{}", self.name, self.version_or_default())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
Reference in New Issue
Block a user