Skip to content

Commit 53b8352

Browse files
committed
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.
1 parent a014088 commit 53b8352

File tree

4 files changed

+178
-61
lines changed

4 files changed

+178
-61
lines changed

src/librustpkg/package_id.rs

Lines changed: 9 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@ pub use package_path::{RemotePath, LocalPath, normalize, hash};
1212
use extra::semver;
1313
use core::prelude::*;
1414
use core::result;
15-
16-
/// Placeholder
17-
pub fn default_version() -> Version { ExactRevision(0.1) }
15+
use core::prelude::*;
16+
use version::{default_version, try_getting_version, Version};
1817

1918
/// Path-fragment identifier of a package such as
2019
/// 'github.com/graydon/test'; path must be a relative
@@ -49,11 +48,17 @@ impl PkgId {
4948
let remote_path = RemotePath(p);
5049
let local_path = normalize(copy remote_path);
5150
let short_name = (copy local_path).filestem().expect(fmt!("Strange path! %s", s));
51+
52+
let version = match try_getting_version(remote_path) {
53+
Some(v) => v,
54+
None => default_version()
55+
};
56+
5257
PkgId {
5358
local_path: local_path,
5459
remote_path: remote_path,
5560
short_name: short_name,
56-
version: default_version()
61+
version: version
5762
}
5863
}
5964

@@ -74,59 +79,3 @@ impl ToStr for PkgId {
7479
fmt!("%s-%s", self.local_path.to_str(), self.version.to_str())
7580
}
7681
}
77-
78-
/// A version is either an exact revision,
79-
/// or a semantic version
80-
pub enum Version {
81-
ExactRevision(float),
82-
SemVersion(semver::Version)
83-
}
84-
85-
86-
impl Ord for Version {
87-
fn lt(&self, other: &Version) -> bool {
88-
match (self, other) {
89-
(&ExactRevision(f1), &ExactRevision(f2)) => f1 < f2,
90-
(&SemVersion(ref v1), &SemVersion(ref v2)) => v1 < v2,
91-
_ => false // incomparable, really
92-
}
93-
}
94-
fn le(&self, other: &Version) -> bool {
95-
match (self, other) {
96-
(&ExactRevision(f1), &ExactRevision(f2)) => f1 <= f2,
97-
(&SemVersion(ref v1), &SemVersion(ref v2)) => v1 <= v2,
98-
_ => false // incomparable, really
99-
}
100-
}
101-
fn ge(&self, other: &Version) -> bool {
102-
match (self, other) {
103-
(&ExactRevision(f1), &ExactRevision(f2)) => f1 > f2,
104-
(&SemVersion(ref v1), &SemVersion(ref v2)) => v1 > v2,
105-
_ => false // incomparable, really
106-
}
107-
}
108-
fn gt(&self, other: &Version) -> bool {
109-
match (self, other) {
110-
(&ExactRevision(f1), &ExactRevision(f2)) => f1 >= f2,
111-
(&SemVersion(ref v1), &SemVersion(ref v2)) => v1 >= v2,
112-
_ => false // incomparable, really
113-
}
114-
}
115-
116-
}
117-
118-
impl ToStr for Version {
119-
fn to_str(&self) -> ~str {
120-
match *self {
121-
ExactRevision(ref n) => n.to_str(),
122-
SemVersion(ref v) => v.to_str()
123-
}
124-
}
125-
}
126-
127-
pub fn parse_vers(vers: ~str) -> result::Result<semver::Version, ~str> {
128-
match semver::parse(vers) {
129-
Some(vers) => result::Ok(vers),
130-
None => result::Err(~"could not parse version: invalid")
131-
}
132-
}

src/librustpkg/rustpkg.rc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#[license = "MIT/ASL2"];
1919
#[crate_type = "lib"];
2020

21+
#[no_core];
2122
#[no_std];
2223

2324
extern mod core(name = "std");
@@ -53,6 +54,7 @@ mod target;
5354
#[cfg(test)]
5455
mod tests;
5556
mod util;
57+
mod version;
5658
mod workspace;
5759

5860
pub mod usage;

src/librustpkg/tests.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ use core::prelude::*;
1818
use core::result;
1919
use extra::tempfile::mkdtemp;
2020
use package_path::*;
21-
use package_id::{PkgId, default_version};
21+
use package_id::PkgId;
22+
use version::{default_version, ExactRevision};
2223
use path_util::{target_executable_in_workspace, target_library_in_workspace,
2324
target_test_in_workspace, target_bench_in_workspace,
2425
make_dir_rwx, u_rwx,
@@ -53,6 +54,16 @@ fn remote_pkg() -> PkgId {
5354
}
5455
}
5556

57+
fn remote_versioned_pkg() -> PkgId {
58+
let remote = RemotePath(Path("github.com/catamorphism/test_pkg_version"));
59+
PkgId {
60+
local_path: normalize(copy remote),
61+
remote_path: remote,
62+
short_name: ~"test_pkg_version",
63+
version: default_version()
64+
}
65+
}
66+
5667
fn writeFile(file_path: &Path, contents: &str) {
5768
let out: @io::Writer =
5869
result::get(&io::file_writer(file_path,
@@ -242,3 +253,18 @@ fn test_package_ids_must_be_relative_path_like() {
242253
}
243254

244255
}
256+
257+
#[test]
258+
fn test_package_version() {
259+
let workspace = mkdtemp(&os::tmpdir(), "test").expect("couldn't create temp dir");
260+
let sysroot = test_sysroot();
261+
debug!("sysroot = %s", sysroot.to_str());
262+
let ctxt = fake_ctxt(Some(@sysroot));
263+
let temp_pkg_id = PkgId::new("github.com/catamorphism/test_pkg_version");
264+
match temp_pkg_id.version {
265+
ExactRevision(0.2) => (),
266+
_ => fail!(fmt!("test_package_version: package version was %?, expected Some(0.2)",
267+
temp_pkg_id.version))
268+
}
269+
// also check that file paths are right
270+
}

src/librustpkg/version.rs

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
/// A version is either an exact revision,
12+
/// or a semantic version
13+
14+
extern mod std;
15+
16+
use std::semver;
17+
use core::prelude::*;
18+
use core::run;
19+
use package_path::RemotePath;
20+
use std::tempfile::mkdtemp;
21+
22+
pub enum Version {
23+
ExactRevision(float),
24+
SemVersion(semver::Version)
25+
}
26+
27+
28+
impl Ord for Version {
29+
fn lt(&self, other: &Version) -> bool {
30+
match (self, other) {
31+
(&ExactRevision(f1), &ExactRevision(f2)) => f1 < f2,
32+
(&SemVersion(ref v1), &SemVersion(ref v2)) => v1 < v2,
33+
_ => false // incomparable, really
34+
}
35+
}
36+
fn le(&self, other: &Version) -> bool {
37+
match (self, other) {
38+
(&ExactRevision(f1), &ExactRevision(f2)) => f1 <= f2,
39+
(&SemVersion(ref v1), &SemVersion(ref v2)) => v1 <= v2,
40+
_ => false // incomparable, really
41+
}
42+
}
43+
fn ge(&self, other: &Version) -> bool {
44+
match (self, other) {
45+
(&ExactRevision(f1), &ExactRevision(f2)) => f1 > f2,
46+
(&SemVersion(ref v1), &SemVersion(ref v2)) => v1 > v2,
47+
_ => false // incomparable, really
48+
}
49+
}
50+
fn gt(&self, other: &Version) -> bool {
51+
match (self, other) {
52+
(&ExactRevision(f1), &ExactRevision(f2)) => f1 >= f2,
53+
(&SemVersion(ref v1), &SemVersion(ref v2)) => v1 >= v2,
54+
_ => false // incomparable, really
55+
}
56+
}
57+
58+
}
59+
60+
impl ToStr for Version {
61+
fn to_str(&self) -> ~str {
62+
match *self {
63+
ExactRevision(ref n) => n.to_str(),
64+
SemVersion(ref v) => v.to_str()
65+
}
66+
}
67+
}
68+
69+
pub fn parse_vers(vers: ~str) -> result::Result<semver::Version, ~str> {
70+
match semver::parse(vers) {
71+
Some(vers) => result::Ok(vers),
72+
None => result::Err(~"could not parse version: invalid")
73+
}
74+
}
75+
76+
77+
/// If `remote_path` refers to a git repo that can be downloaded,
78+
/// and the most recent tag in that repo denotes a version, return it;
79+
/// otherwise, `None`
80+
pub fn try_getting_version(remote_path: &RemotePath) -> Option<Version> {
81+
debug!("try_getting_version: %s", remote_path.to_str());
82+
if is_url_like(remote_path) {
83+
debug!("Trying to fetch its sources..");
84+
let tmp_dir = mkdtemp(&os::tmpdir(),
85+
"test").expect("try_getting_version: couldn't create temp dir");
86+
debug!("executing {git clone https://%s %s}", remote_path.to_str(), tmp_dir.to_str());
87+
let outp = run::process_output("git", [~"clone", fmt!("https://%s", remote_path.to_str()),
88+
tmp_dir.to_str()]);
89+
if outp.status == 0 {
90+
debug!("Cloned it... ( %s, %s )", str::from_bytes(outp.output), str::from_bytes(outp.error));
91+
let mut output = None;
92+
debug!("executing {git --git-dir=%s tag -l}", tmp_dir.push(".git").to_str());
93+
let outp = run::process_output("git", [fmt!("--git-dir=%s", tmp_dir.push(".git").to_str()),
94+
~"tag", ~"-l"]);
95+
let output_text = str::from_bytes(outp.output);
96+
debug!("Full output: ( %s ) [%?]", output_text, outp.status);
97+
for output_text.each_split_char('\n') |l| {
98+
debug!("A line of output: %s", l);
99+
if !l.is_whitespace() {
100+
output = Some(l);
101+
}
102+
}
103+
104+
output.chain(try_parsing_version)
105+
}
106+
else {
107+
None
108+
}
109+
}
110+
else {
111+
None
112+
}
113+
}
114+
115+
fn try_parsing_version(s: &str) -> Option<Version> {
116+
let s = s.trim();
117+
debug!("Attempting to parse: %s", s);
118+
match float::from_str(s) {
119+
Some(f) => {
120+
debug!("%s -> %f", s, f);
121+
Some(ExactRevision(f)) // semver not handled yet
122+
}
123+
None => {
124+
debug!("None!!");
125+
None
126+
}
127+
}
128+
}
129+
130+
/// Placeholder
131+
pub fn default_version() -> Version { ExactRevision(0.1) }
132+
133+
/// Just an approximation
134+
fn is_url_like(p: &RemotePath) -> bool {
135+
let mut n = 0;
136+
for p.to_str().each_split_char('/') |_| {
137+
n += 1;
138+
}
139+
n > 2
140+
}

0 commit comments

Comments
 (0)