diff --git a/src/librustpkg/package_id.rs b/src/librustpkg/package_id.rs index 0de6e5435a51f..83db925442aa0 100644 --- a/src/librustpkg/package_id.rs +++ b/src/librustpkg/package_id.rs @@ -11,11 +11,8 @@ extern mod std; pub use package_path::{RemotePath, LocalPath, normalize, hash}; -use std::semver; use core::prelude::*; - -/// Placeholder -pub fn default_version() -> Version { ExactRevision(0.1) } +use version::{default_version, try_getting_version, Version}; /// Path-fragment identifier of a package such as /// 'github.com/graydon/test'; path must be a relative @@ -51,7 +48,7 @@ pub impl PkgId { let local_path = normalize(copy remote_path); let short_name = (copy local_path).filestem().expect(fmt!("Strange path! %s", s)); - let version = match try_getting_version(remote_path) { + let version = match try_getting_version(&remote_path) { Some(v) => v, None => default_version() }; @@ -81,59 +78,3 @@ impl ToStr for PkgId { fmt!("%s-%s", self.local_path.to_str(), self.version.to_str()) } } - -/// A version is either an exact revision, -/// or a semantic version -pub enum Version { - ExactRevision(float), - SemVersion(semver::Version) -} - - -impl Ord for Version { - fn lt(&self, other: &Version) -> bool { - match (self, other) { - (&ExactRevision(f1), &ExactRevision(f2)) => f1 < f2, - (&SemVersion(ref v1), &SemVersion(ref v2)) => v1 < v2, - _ => false // incomparable, really - } - } - fn le(&self, other: &Version) -> bool { - match (self, other) { - (&ExactRevision(f1), &ExactRevision(f2)) => f1 <= f2, - (&SemVersion(ref v1), &SemVersion(ref v2)) => v1 <= v2, - _ => false // incomparable, really - } - } - fn ge(&self, other: &Version) -> bool { - match (self, other) { - (&ExactRevision(f1), &ExactRevision(f2)) => f1 > f2, - (&SemVersion(ref v1), &SemVersion(ref v2)) => v1 > v2, - _ => false // incomparable, really - } - } - fn gt(&self, other: &Version) -> bool { - match (self, other) { - (&ExactRevision(f1), &ExactRevision(f2)) => f1 >= f2, - (&SemVersion(ref v1), &SemVersion(ref v2)) => v1 >= v2, - _ => false // incomparable, really - } - } - -} - -impl ToStr for Version { - fn to_str(&self) -> ~str { - match *self { - ExactRevision(ref n) => n.to_str(), - SemVersion(ref v) => v.to_str() - } - } -} - -pub fn parse_vers(vers: ~str) -> result::Result { - match semver::parse(vers) { - Some(vers) => result::Ok(vers), - None => result::Err(~"could not parse version: invalid") - } -} diff --git a/src/librustpkg/path_util.rs b/src/librustpkg/path_util.rs index ad5ed54d3e425..d3dc8895c00c3 100644 --- a/src/librustpkg/path_util.rs +++ b/src/librustpkg/path_util.rs @@ -16,7 +16,8 @@ use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR}; use core::os::mkdir_recursive; use core::os; pub use package_path::{RemotePath, LocalPath}; -pub use package_id::{PkgId, Version}; +pub use package_id::PkgId; +pub use version::Version; pub use target::{OutputType, Main, Lib, Test, Bench, Target, Build, Install}; /// Returns the value of RUST_PATH, as a list diff --git a/src/librustpkg/rustpkg.rc b/src/librustpkg/rustpkg.rc index 7c3667c74f520..636a0365cb024 100644 --- a/src/librustpkg/rustpkg.rc +++ b/src/librustpkg/rustpkg.rc @@ -54,6 +54,7 @@ mod target; #[cfg(test)] mod tests; mod util; +mod version; mod workspace; pub mod usage; diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs index 902f318de3b81..52c7ba18d6032 100644 --- a/src/librustpkg/tests.rs +++ b/src/librustpkg/tests.rs @@ -18,7 +18,8 @@ use core::prelude::*; use core::result; use extra::tempfile::mkdtemp; use package_path::*; -use package_id::{PkgId, default_version, ExactRevision}; +use package_id::{PkgId}; +use version::{default_version, ExactRevision}; use path_util::{target_executable_in_workspace, target_library_in_workspace, target_test_in_workspace, target_bench_in_workspace, make_dir_rwx, u_rwx, @@ -255,10 +256,8 @@ fn test_package_ids_must_be_relative_path_like() { #[test] fn test_package_version() { - let workspace = mkdtemp(&os::tmpdir(), "test").expect("couldn't create temp dir"); let sysroot = test_sysroot(); debug!("sysroot = %s", sysroot.to_str()); - let ctxt = fake_ctxt(Some(@sysroot)); let temp_pkg_id = PkgId::new("github.com/catamorphism/test_pkg_version"); match temp_pkg_id.version { ExactRevision(0.2) => (), diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index 9a69cab9d76cc..daf68f5802a34 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -239,7 +239,7 @@ pub fn compile_input(ctxt: &Ctx, + flags + cfgs.flat_map(|&c| { ~[~"--cfg", c] }), driver::optgroups()).get(); - let mut options = @session::options { + let options = @session::options { crate_type: crate_type, optimize: if opt { session::Aggressive } else { session::No }, test: what == Test || what == Bench, diff --git a/src/librustpkg/version.rs b/src/librustpkg/version.rs new file mode 100644 index 0000000000000..2de020970210d --- /dev/null +++ b/src/librustpkg/version.rs @@ -0,0 +1,140 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +/// A version is either an exact revision, +/// or a semantic version + +extern mod std; + +use std::semver; +use core::prelude::*; +use core::run; +use package_path::RemotePath; +use std::tempfile::mkdtemp; + +pub enum Version { + ExactRevision(float), + SemVersion(semver::Version) +} + + +impl Ord for Version { + fn lt(&self, other: &Version) -> bool { + match (self, other) { + (&ExactRevision(f1), &ExactRevision(f2)) => f1 < f2, + (&SemVersion(ref v1), &SemVersion(ref v2)) => v1 < v2, + _ => false // incomparable, really + } + } + fn le(&self, other: &Version) -> bool { + match (self, other) { + (&ExactRevision(f1), &ExactRevision(f2)) => f1 <= f2, + (&SemVersion(ref v1), &SemVersion(ref v2)) => v1 <= v2, + _ => false // incomparable, really + } + } + fn ge(&self, other: &Version) -> bool { + match (self, other) { + (&ExactRevision(f1), &ExactRevision(f2)) => f1 > f2, + (&SemVersion(ref v1), &SemVersion(ref v2)) => v1 > v2, + _ => false // incomparable, really + } + } + fn gt(&self, other: &Version) -> bool { + match (self, other) { + (&ExactRevision(f1), &ExactRevision(f2)) => f1 >= f2, + (&SemVersion(ref v1), &SemVersion(ref v2)) => v1 >= v2, + _ => false // incomparable, really + } + } + +} + +impl ToStr for Version { + fn to_str(&self) -> ~str { + match *self { + ExactRevision(ref n) => n.to_str(), + SemVersion(ref v) => v.to_str() + } + } +} + +pub fn parse_vers(vers: ~str) -> result::Result { + match semver::parse(vers) { + Some(vers) => result::Ok(vers), + None => result::Err(~"could not parse version: invalid") + } +} + + +/// 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: &RemotePath) -> Option { + debug!("try_getting_version: %s", remote_path.to_str()); + if is_url_like(remote_path) { + debug!("Trying to fetch its sources.."); + let tmp_dir = mkdtemp(&os::tmpdir(), + "test").expect("try_getting_version: couldn't create temp dir"); + debug!("executing {git clone https://%s %s}", remote_path.to_str(), tmp_dir.to_str()); + let outp = run::process_output("git", [~"clone", fmt!("https://%s", remote_path.to_str()), + tmp_dir.to_str()]); + if outp.status == 0 { + debug!("Cloned it... ( %s, %s )", str::from_bytes(outp.output), str::from_bytes(outp.error)); + let mut output = None; + debug!("executing {git --git-dir=%s tag -l}", tmp_dir.push(".git").to_str()); + let outp = run::process_output("git", [fmt!("--git-dir=%s", tmp_dir.push(".git").to_str()), + ~"tag", ~"-l"]); + let output_text = str::from_bytes(outp.output); + debug!("Full output: ( %s ) [%?]", output_text, outp.status); + for output_text.each_split_char('\n') |l| { + debug!("A line of output: %s", l); + if !l.is_whitespace() { + output = Some(l); + } + } + + output.chain(try_parsing_version) + } + else { + None + } + } + else { + None + } +} + +fn try_parsing_version(s: &str) -> Option { + let s = s.trim(); + debug!("Attempting to parse: %s", s); + match float::from_str(s) { + Some(f) => { + debug!("%s -> %f", s, f); + Some(ExactRevision(f)) // semver not handled yet + } + None => { + debug!("None!!"); + None + } + } +} + +/// Placeholder +pub fn default_version() -> Version { ExactRevision(0.1) } + +/// Just an approximation +fn is_url_like(p: &RemotePath) -> bool { + let mut n = 0; + for p.to_str().each_split_char('/') |_| { + n += 1; + } + n > 2 +} \ No newline at end of file