-
Notifications
You must be signed in to change notification settings - Fork 13k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rustpkg: Accept package IDs like github.com/foo/bar#0.3
If the package ID is of the form s#v, where v is a valid version string, fetch tag v of that package.
- Loading branch information
1 parent
53b8352
commit d92b435
Showing
8 changed files
with
542 additions
and
341 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// Copyright 2012-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 core::path::Path; | ||
use core::vec; | ||
|
||
/// A crate is a unit of Rust code to be compiled into a binary or library | ||
pub struct Crate { | ||
file: Path, | ||
flags: ~[~str], | ||
cfgs: ~[~str] | ||
} | ||
|
||
impl Crate { | ||
|
||
pub fn new(p: &Path) -> Crate { | ||
Crate { | ||
file: copy *p, | ||
flags: ~[], | ||
cfgs: ~[] | ||
} | ||
} | ||
|
||
fn flag(&self, flag: ~str) -> Crate { | ||
Crate { | ||
flags: vec::append(copy self.flags, [flag]), | ||
.. copy *self | ||
} | ||
} | ||
|
||
fn flags(&self, flags: ~[~str]) -> Crate { | ||
Crate { | ||
flags: vec::append(copy self.flags, flags), | ||
.. copy *self | ||
} | ||
} | ||
|
||
fn cfg(&self, cfg: ~str) -> Crate { | ||
Crate { | ||
cfgs: vec::append(copy self.cfgs, [cfg]), | ||
.. copy *self | ||
} | ||
} | ||
|
||
fn cfgs(&self, cfgs: ~[~str]) -> Crate { | ||
Crate { | ||
cfgs: vec::append(copy self.cfgs, cfgs), | ||
.. copy *self | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,239 @@ | ||
// Copyright 2012-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 target::*; | ||
use package_id::PkgId; | ||
use core::path::Path; | ||
use core::option::*; | ||
use core::{os, run, str, vec}; | ||
use context::*; | ||
use crate::Crate; | ||
use path_util::pkgid_src_in_workspace; | ||
use util::{compile_crate, note}; | ||
use version::{ExactRevision, SemanticVersion, NoVersion}; | ||
|
||
// An enumeration of the unpacked source of a package workspace. | ||
// This contains a list of files found in the source workspace. | ||
pub struct PkgSrc { | ||
root: Path, // root of where the package source code lives | ||
dst_dir: Path, // directory where we will put the compiled output | ||
id: PkgId, | ||
libs: ~[Crate], | ||
mains: ~[Crate], | ||
tests: ~[Crate], | ||
benchs: ~[Crate], | ||
} | ||
|
||
condition! { | ||
build_err: (~str) -> (); | ||
} | ||
|
||
impl PkgSrc { | ||
|
||
pub fn new(src_dir: &Path, dst_dir: &Path, | ||
id: &PkgId) -> PkgSrc { | ||
PkgSrc { | ||
root: copy *src_dir, | ||
dst_dir: copy *dst_dir, | ||
id: copy *id, | ||
libs: ~[], | ||
mains: ~[], | ||
tests: ~[], | ||
benchs: ~[] | ||
} | ||
} | ||
|
||
|
||
fn check_dir(&self) -> Path { | ||
use conditions::nonexistent_package::cond; | ||
|
||
debug!("Pushing onto root: %s | %s", self.id.remote_path.to_str(), | ||
self.root.to_str()); | ||
let dir; | ||
let dirs = pkgid_src_in_workspace(&self.id, &self.root); | ||
debug!("Checking dirs: %?", dirs); | ||
let path = dirs.find(|d| os::path_exists(d)); | ||
match path { | ||
Some(d) => dir = d, | ||
None => dir = match self.fetch_git() { | ||
None => cond.raise((copy self.id, ~"supplied path for package dir does not \ | ||
exist, and couldn't interpret it as a URL fragment")), | ||
Some(d) => d | ||
} | ||
} | ||
if !os::path_is_dir(&dir) { | ||
cond.raise((copy self.id, ~"supplied path for package dir is a \ | ||
non-directory")); | ||
} | ||
|
||
dir | ||
} | ||
|
||
/// Try interpreting self's package id as a remote package, and try | ||
/// fetching it and caching it in a local directory. Return the cached directory | ||
/// if this was successful, None otherwise | ||
/// (right now we only support git) | ||
pub fn fetch_git(&self) -> Option<Path> { | ||
|
||
let mut local = self.root.push("src"); | ||
local = local.push(self.id.to_str()); | ||
// Git can't clone into a non-empty directory | ||
os::remove_dir_recursive(&local); | ||
|
||
let url = fmt!("https://%s", self.id.remote_path.to_str()); | ||
let branch_args = match self.id.version { | ||
NoVersion => ~[], | ||
ExactRevision(ref s) => ~[~"--branch", copy *s], | ||
SemanticVersion(ref s) => ~[~"--branch", s.to_str()] | ||
}; | ||
|
||
|
||
note(fmt!("git clone %s %s %?", url, local.to_str(), branch_args)); | ||
|
||
if run::process_output("git", | ||
~[~"clone", copy url, local.to_str()] + branch_args).status != 0 { | ||
note(fmt!("fetching %s failed: can't clone repository", url)); | ||
None | ||
} | ||
else { | ||
Some(local) | ||
} | ||
} | ||
|
||
|
||
// If a file named "pkg.rs" in the current directory exists, | ||
// return the path for it. Otherwise, None | ||
pub fn package_script_option(&self, cwd: &Path) -> Option<Path> { | ||
let maybe_path = cwd.push("pkg.rs"); | ||
if os::path_exists(&maybe_path) { | ||
Some(maybe_path) | ||
} | ||
else { | ||
None | ||
} | ||
} | ||
|
||
/// True if the given path's stem is self's pkg ID's stem | ||
/// or if the pkg ID's stem is <rust-foo> and the given path's | ||
/// stem is foo | ||
/// Requires that dashes in p have already been normalized to | ||
/// underscores | ||
fn stem_matches(&self, p: &Path) -> bool { | ||
let self_id = self.id.local_path.filestem(); | ||
if self_id == p.filestem() { | ||
return true; | ||
} | ||
else { | ||
for self_id.each |pth| { | ||
if pth.starts_with("rust_") // because p is already normalized | ||
&& match p.filestem() { | ||
Some(s) => str::eq_slice(s, pth.slice(5, pth.len())), | ||
None => false | ||
} { return true; } | ||
} | ||
} | ||
false | ||
} | ||
|
||
fn push_crate(cs: &mut ~[Crate], prefix: uint, p: &Path) { | ||
assert!(p.components.len() > prefix); | ||
let mut sub = Path(""); | ||
for vec::slice(p.components, prefix, | ||
p.components.len()).each |c| { | ||
sub = sub.push(*c); | ||
} | ||
debug!("found crate %s", sub.to_str()); | ||
cs.push(Crate::new(&sub)); | ||
} | ||
|
||
/// Infers crates to build. Called only in the case where there | ||
/// is no custom build logic | ||
pub fn find_crates(&mut self) { | ||
use conditions::missing_pkg_files::cond; | ||
|
||
let dir = self.check_dir(); | ||
debug!("Called check_dir, I'm in %s", dir.to_str()); | ||
let prefix = dir.components.len(); | ||
debug!("Matching against %?", self.id.local_path.filestem()); | ||
for os::walk_dir(&dir) |pth| { | ||
match pth.filename() { | ||
Some(~"lib.rs") => PkgSrc::push_crate(&mut self.libs, | ||
prefix, | ||
pth), | ||
Some(~"main.rs") => PkgSrc::push_crate(&mut self.mains, | ||
prefix, | ||
pth), | ||
Some(~"test.rs") => PkgSrc::push_crate(&mut self.tests, | ||
prefix, | ||
pth), | ||
Some(~"bench.rs") => PkgSrc::push_crate(&mut self.benchs, | ||
prefix, | ||
pth), | ||
_ => () | ||
} | ||
} | ||
|
||
if self.libs.is_empty() && self.mains.is_empty() | ||
&& self.tests.is_empty() && self.benchs.is_empty() { | ||
|
||
note(~"Couldn't infer any crates to build.\n\ | ||
Try naming a crate `main.rs`, `lib.rs`, \ | ||
`test.rs`, or `bench.rs`."); | ||
cond.raise(copy self.id); | ||
} | ||
|
||
debug!("found %u libs, %u mains, %u tests, %u benchs", | ||
self.libs.len(), | ||
self.mains.len(), | ||
self.tests.len(), | ||
self.benchs.len()) | ||
} | ||
|
||
fn build_crates(&self, | ||
ctx: &Ctx, | ||
dst_dir: &Path, | ||
src_dir: &Path, | ||
crates: &[Crate], | ||
cfgs: &[~str], | ||
what: OutputType) { | ||
for crates.each |&crate| { | ||
let path = &src_dir.push_rel(&crate.file).normalize(); | ||
note(fmt!("build_crates: compiling %s", path.to_str())); | ||
note(fmt!("build_crates: destination dir is %s", dst_dir.to_str())); | ||
|
||
let result = compile_crate(ctx, | ||
&self.id, | ||
path, | ||
dst_dir, | ||
crate.flags, | ||
crate.cfgs + cfgs, | ||
false, | ||
what); | ||
if !result { | ||
build_err::cond.raise(fmt!("build failure on %s", | ||
path.to_str())); | ||
} | ||
debug!("Result of compiling %s was %?", | ||
path.to_str(), result); | ||
} | ||
} | ||
|
||
pub fn build(&self, ctx: &Ctx, dst_dir: Path, cfgs: ~[~str]) { | ||
let dir = self.check_dir(); | ||
debug!("Building libs in %s", dir.to_str()); | ||
self.build_crates(ctx, &dst_dir, &dir, self.libs, cfgs, Lib); | ||
debug!("Building mains"); | ||
self.build_crates(ctx, &dst_dir, &dir, self.mains, cfgs, Main); | ||
debug!("Building tests"); | ||
self.build_crates(ctx, &dst_dir, &dir, self.tests, cfgs, Test); | ||
debug!("Building benches"); | ||
self.build_crates(ctx, &dst_dir, &dir, self.benchs, cfgs, Bench); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
d92b435
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
saw approval from catamorphism
at catamorphism@d92b435
d92b435
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
merging catamorphism/rust/rustpkg_version_vcs = d92b435 into auto
d92b435
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
catamorphism/rust/rustpkg_version_vcs = d92b435 merged ok, testing candidate = 94f72dd
d92b435
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all tests pass:
http://buildbot.rust-lang.org/builders/auto-linux/builds/1622
http://buildbot.rust-lang.org/builders/auto-win/builds/1617
http://buildbot.rust-lang.org/builders/auto-mac/builds/1636
d92b435
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fast-forwarding incoming to auto = 94f72dd