Skip to content

Commit 9ffeeba

Browse files
committed
rustpkg: Handle requested versions in extern mod directives properly
Closes rust-lang#8711
1 parent ade310c commit 9ffeeba

File tree

9 files changed

+309
-138
lines changed

9 files changed

+309
-138
lines changed

src/librustc/metadata/creader.rs

+25-11
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,11 @@
1313

1414
use metadata::cstore;
1515
use metadata::decoder;
16-
use metadata::filesearch::FileSearch;
16+
use metadata::filesearch::{FileSearch, split_version};
1717
use metadata::loader;
1818

1919
use std::hashmap::HashMap;
2020
use syntax::ast;
21-
use std::vec;
2221
use syntax::attr;
2322
use syntax::attr::AttrMetaMethods;
2423
use syntax::codemap::{Span, dummy_sp};
@@ -143,15 +142,30 @@ fn visit_view_item(e: @mut Env, i: &ast::view_item) {
143142
let meta_items = match path_opt {
144143
None => meta_items.clone(),
145144
Some((p, _path_str_style)) => {
146-
let p_path = Path::new(p);
147-
match p_path.filestem_str() {
148-
None|Some("") =>
149-
e.diag.span_bug(i.span, "Bad package path in `extern mod` item"),
150-
Some(s) =>
151-
vec::append(
152-
~[attr::mk_name_value_item_str(@"package_id", p),
153-
attr::mk_name_value_item_str(@"name", s.to_managed())],
154-
*meta_items)
145+
match split_version(p) {
146+
None => {
147+
let p_path = Path::new(p);
148+
let s = match p_path.filestem_str() {
149+
None|Some("") =>
150+
e.diag.span_bug(i.span,
151+
"Bad package path in `extern mod` item"),
152+
Some(s) => s,
153+
};
154+
~[attr::mk_name_value_item_str(@"package_id", p),
155+
attr::mk_name_value_item_str(@"name", s.to_managed())]
156+
}
157+
Some((name, version)) => {
158+
let p_path = Path::new(name);
159+
let s = match p_path.filestem_str() {
160+
None|Some("") =>
161+
e.diag.span_bug(i.span,
162+
"Bad package path in `extern mod` item"),
163+
Some(s) => s,
164+
};
165+
~[attr::mk_name_value_item_str(@"package_id", name.to_managed()),
166+
attr::mk_name_value_item_str(@"name", s.to_managed()),
167+
attr::mk_name_value_item_str(@"vers", version.to_managed())]
168+
}
155169
}
156170
}
157171
};

src/librustc/metadata/filesearch.rs

+24
Original file line numberDiff line numberDiff line change
@@ -236,3 +236,27 @@ pub fn rust_path() -> ~[Path] {
236236
pub fn libdir() -> ~str {
237237
(env!("CFG_LIBDIR")).to_owned()
238238
}
239+
240+
241+
/// If s is of the form foo#bar, where bar is a valid version
242+
/// number, return the prefix before the # and the version.
243+
/// Otherwise, return None.
244+
pub fn split_version<'a>(s: &'a str) -> Option<(&'a str, &'a str)> {
245+
// Check for extra '#' characters separately
246+
if s.split_iter('#').len() > 2 {
247+
return None;
248+
}
249+
split_version_general(s, '#')
250+
}
251+
252+
pub fn split_version_general<'a>(s: &'a str, sep: char) -> Option<(&'a str, &'a str)> {
253+
match s.rfind(sep) {
254+
Some(i) => {
255+
let path = s.slice(0, i);
256+
Some((path, s.slice(i + 1, s.len())))
257+
}
258+
None => {
259+
None
260+
}
261+
}
262+
}

src/librustpkg/lib.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -433,17 +433,19 @@ impl CtxMethods for BuildContext {
433433
let pkgid = pkg_src.id.clone();
434434

435435
debug!("build: workspace = {} (in Rust path? {:?} is git dir? {:?} \
436-
pkgid = {} pkgsrc start_dir = {}", workspace.display(),
436+
pkgid = {} pkgsrc start_dir = {}", workspace.display(),
437437
in_rust_path(&workspace), is_git_dir(&workspace.join(&pkgid.path)),
438-
pkgid.to_str(), pkg_src.start_dir.display());
438+
pkgid.to_str(),
439+
pkg_src.start_dir.display());
440+
let pkg_dir = workspace.join(&pkgid.path);
439441
debug!("build: what to build = {:?}", what_to_build);
440442

441443
// If workspace isn't in the RUST_PATH, and it's a git repo,
442444
// then clone it into the first entry in RUST_PATH, and repeat
443-
if !in_rust_path(&workspace) && is_git_dir(&workspace.join(&pkgid.path)) {
445+
if !in_rust_path(&workspace) && is_git_dir(&pkg_dir) {
444446
let mut out_dir = default_workspace().join("src");
445447
out_dir.push(&pkgid.path);
446-
let git_result = source_control::safe_git_clone(&workspace.join(&pkgid.path),
448+
let git_result = source_control::safe_git_clone(&pkg_dir,
447449
&pkgid.version,
448450
&out_dir);
449451
match git_result {
@@ -516,7 +518,7 @@ impl CtxMethods for BuildContext {
516518
JustOne(ref p) => {
517519
// We expect that p is relative to the package source's start directory,
518520
// so check that assumption
519-
debug!("JustOne: p = {}", p.display());
521+
debug!("JustOne: p = {} and {}", p.display(), pkg_src.start_dir.display());
520522
assert!(pkg_src.start_dir.join(p).exists());
521523
if is_lib(p) {
522524
PkgSrc::push_crate(&mut pkg_src.libs, 0, p);

0 commit comments

Comments
 (0)