mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-28 00:15:23 +00:00
rustpkg: Extract version number from git, as per #5684
For now, the test I added just checks that PkgId::new parses the version number out of a git repo's tags list, where relevant.
This commit is contained in:
parent
a014088da1
commit
53b8352552
@ -12,9 +12,8 @@ pub use package_path::{RemotePath, LocalPath, normalize, hash};
|
||||
use extra::semver;
|
||||
use core::prelude::*;
|
||||
use core::result;
|
||||
|
||||
/// Placeholder
|
||||
pub fn default_version() -> Version { ExactRevision(0.1) }
|
||||
use core::prelude::*;
|
||||
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
|
||||
@ -49,11 +48,17 @@ impl PkgId {
|
||||
let remote_path = RemotePath(p);
|
||||
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) {
|
||||
Some(v) => v,
|
||||
None => default_version()
|
||||
};
|
||||
|
||||
PkgId {
|
||||
local_path: local_path,
|
||||
remote_path: remote_path,
|
||||
short_name: short_name,
|
||||
version: default_version()
|
||||
version: version
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,59 +79,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<semver::Version, ~str> {
|
||||
match semver::parse(vers) {
|
||||
Some(vers) => result::Ok(vers),
|
||||
None => result::Err(~"could not parse version: invalid")
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#[license = "MIT/ASL2"];
|
||||
#[crate_type = "lib"];
|
||||
|
||||
#[no_core];
|
||||
#[no_std];
|
||||
|
||||
extern mod core(name = "std");
|
||||
@ -53,6 +54,7 @@ mod target;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
mod util;
|
||||
mod version;
|
||||
mod workspace;
|
||||
|
||||
pub mod usage;
|
||||
|
@ -18,7 +18,8 @@ use core::prelude::*;
|
||||
use core::result;
|
||||
use extra::tempfile::mkdtemp;
|
||||
use package_path::*;
|
||||
use package_id::{PkgId, default_version};
|
||||
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,
|
||||
@ -53,6 +54,16 @@ fn remote_pkg() -> PkgId {
|
||||
}
|
||||
}
|
||||
|
||||
fn remote_versioned_pkg() -> PkgId {
|
||||
let remote = RemotePath(Path("github.com/catamorphism/test_pkg_version"));
|
||||
PkgId {
|
||||
local_path: normalize(copy remote),
|
||||
remote_path: remote,
|
||||
short_name: ~"test_pkg_version",
|
||||
version: default_version()
|
||||
}
|
||||
}
|
||||
|
||||
fn writeFile(file_path: &Path, contents: &str) {
|
||||
let out: @io::Writer =
|
||||
result::get(&io::file_writer(file_path,
|
||||
@ -242,3 +253,18 @@ 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) => (),
|
||||
_ => fail!(fmt!("test_package_version: package version was %?, expected Some(0.2)",
|
||||
temp_pkg_id.version))
|
||||
}
|
||||
// also check that file paths are right
|
||||
}
|
||||
|
140
src/librustpkg/version.rs
Normal file
140
src/librustpkg/version.rs
Normal file
@ -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 <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.
|
||||
|
||||
/// 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<semver::Version, ~str> {
|
||||
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<Version> {
|
||||
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<Version> {
|
||||
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
|
||||
}
|
Loading…
Reference in New Issue
Block a user