Skip to content

Commit bfac584

Browse files
committed
rustpkg: Handle non-numeric versions; some cleanup
Package IDs can now be of the form a/b/c#FOO, where (if a/b/c is a git repository) FOO is any tag in the repository. Non-numeric tags only match against package IDs with the same tag, and aren't compared linearly like numeric versions. While I was at it, refactored the code that calls `git clone`, and segregated build output properly for different packages.
1 parent d7c4a10 commit bfac584

File tree

5 files changed

+117
-69
lines changed

5 files changed

+117
-69
lines changed

src/librustpkg/package_source.rs

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,13 @@
1111
use target::*;
1212
use package_id::PkgId;
1313
use std::path::Path;
14-
use std::{os, run, str};
14+
use std::{os, str};
1515
use context::*;
1616
use crate::Crate;
1717
use messages::*;
18-
use source_control::git_clone;
18+
use source_control::{git_clone, git_clone_general};
1919
use path_util::pkgid_src_in_workspace;
2020
use util::compile_crate;
21-
use version::{ExactRevision, SemanticVersion, NoVersion};
2221

2322
// An enumeration of the unpacked source of a package workspace.
2423
// This contains a list of files found in the source workspace.
@@ -102,22 +101,13 @@ impl PkgSrc {
102101
}
103102

104103
let url = fmt!("https://%s", self.id.remote_path.to_str());
105-
let branch_args = match self.id.version {
106-
NoVersion => ~[],
107-
ExactRevision(ref s) => ~[~"--branch", (*s).clone()],
108-
SemanticVersion(ref s) => ~[~"--branch", s.to_str()]
109-
};
110-
111-
112-
note(fmt!("Fetching package: git clone %s %s %?", url, local.to_str(), branch_args));
113-
114-
if run::process_output("git",
115-
~[~"clone", url.clone(), local.to_str()] + branch_args).status != 0 {
116-
note(fmt!("fetching %s failed: can't clone repository", url));
117-
None
104+
note(fmt!("Fetching package: git clone %s %s [version=%s]",
105+
url, local.to_str(), self.id.version.to_str()));
106+
if git_clone_general(url, &local, &self.id.version) {
107+
Some(local)
118108
}
119109
else {
120-
Some(local)
110+
None
121111
}
122112
}
123113

src/librustpkg/path_util.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ pub fn rust_path() -> ~[Path] {
5252
}
5353
None => ~[]
5454
};
55+
debug!("RUST_PATH entries from environment: %?", env_rust_path);
5556
let cwd = os::getcwd();
5657
// now add in default entries
5758
env_rust_path.push(cwd.clone());
@@ -345,7 +346,12 @@ fn target_file_in_workspace(pkgid: &PkgId, workspace: &Path,
345346
let subdir = match what {
346347
Lib => "lib", Main | Test | Bench => "bin"
347348
};
348-
let result = workspace.push(subdir);
349+
// Artifacts in the build directory live in a package-ID-specific subdirectory,
350+
// but installed ones don't.
351+
let result = match where {
352+
Build => workspace.push(subdir).push_rel(&*pkgid.local_path),
353+
_ => workspace.push(subdir)
354+
};
349355
if !os::path_exists(&result) && !mkdir_recursive(&result, U_RWX) {
350356
cond.raise((result.clone(), fmt!("target_file_in_workspace couldn't \
351357
create the %s dir (pkgid=%s, workspace=%s, what=%?, where=%?",

src/librustpkg/source_control.rs

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,14 @@ pub fn git_clone(source: &Path, target: &Path, v: &Version) {
1818
assert!(os::path_is_dir(source));
1919
assert!(is_git_dir(source));
2020
if !os::path_exists(target) {
21-
let version_args = match v {
22-
&ExactRevision(ref s) => ~[~"--branch", s.to_owned()],
23-
_ => ~[]
24-
};
25-
debug!("Running: git clone %s %s %s", version_args.to_str(), source.to_str(),
21+
debug!("Running: git clone %s %s", source.to_str(),
2622
target.to_str());
27-
let outp = run::process_output("git", ~[~"clone"] + version_args +
28-
~[source.to_str(), target.to_str()]);
29-
if outp.status != 0 {
30-
io::println(str::from_bytes_owned(outp.output.clone()));
31-
io::println(str::from_bytes_owned(outp.error));
32-
fail!("Couldn't `git clone` %s", source.to_str());
33-
}
23+
assert!(git_clone_general(source.to_str(), target, v));
3424
}
3525
else {
3626
// Pull changes
27+
// Note that this ignores tags, which is probably wrong. There are no tests for
28+
// it, though.
3729
debug!("Running: git --work-tree=%s --git-dir=%s pull --no-edit %s",
3830
target.to_str(), target.push(".git").to_str(), source.to_str());
3931
let outp = run::process_output("git", [fmt!("--work-tree=%s", target.to_str()),
@@ -43,6 +35,34 @@ pub fn git_clone(source: &Path, target: &Path, v: &Version) {
4335
}
4436
}
4537

38+
/// Source can be either a URL or a local file path.
39+
/// true if successful
40+
pub fn git_clone_general(source: &str, target: &Path, v: &Version) -> bool {
41+
let outp = run::process_output("git", [~"clone", source.to_str(), target.to_str()]);
42+
if outp.status != 0 {
43+
debug!(str::from_bytes_owned(outp.output.clone()));
44+
debug!(str::from_bytes_owned(outp.error));
45+
false
46+
}
47+
else {
48+
match v {
49+
&ExactRevision(ref s) | &Tagged(ref s) => {
50+
let outp = run::process_output_in_cwd("git", [~"checkout", fmt!("tags/%s", *s)],
51+
target);
52+
if outp.status != 0 {
53+
debug!(str::from_bytes_owned(outp.output.clone()));
54+
debug!(str::from_bytes_owned(outp.error));
55+
false
56+
}
57+
else {
58+
true
59+
}
60+
}
61+
_ => true
62+
}
63+
}
64+
}
65+
4666
pub fn is_git_dir(p: &Path) -> bool {
4767
os::path_is_dir(&p.push(".git"))
4868
}

src/librustpkg/tests.rs

Lines changed: 68 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::run::ProcessOutput;
1818
use installed_packages::list_installed_packages;
1919
use package_path::*;
2020
use package_id::{PkgId};
21-
use version::{ExactRevision, NoVersion, Version};
21+
use version::{ExactRevision, NoVersion, Version, Tagged};
2222
use path_util::{target_executable_in_workspace, target_library_in_workspace,
2323
target_test_in_workspace, target_bench_in_workspace,
2424
make_dir_rwx, U_RWX, library_in_workspace,
@@ -61,6 +61,16 @@ fn git_repo_pkg() -> PkgId {
6161
}
6262
}
6363

64+
fn git_repo_pkg_with_tag(a_tag: ~str) -> PkgId {
65+
let remote = RemotePath(Path("mockgithub.com/catamorphism/test-pkg"));
66+
PkgId {
67+
local_path: normalize(remote.clone()),
68+
remote_path: remote,
69+
short_name: ~"test_pkg",
70+
version: Tagged(a_tag)
71+
}
72+
}
73+
6474
fn writeFile(file_path: &Path, contents: &str) {
6575
let out: @io::Writer =
6676
result::unwrap(io::file_writer(file_path,
@@ -150,9 +160,13 @@ fn init_git_repo(p: &Path) -> Path {
150160
}
151161
}
152162

153-
fn add_git_tag(repo: &Path, tag: ~str) {
154-
assert!(repo.is_absolute());
155-
let mut prog = run::Process::new("git", [~"add", ~"-A"],
163+
fn add_all_and_commit(repo: &Path) {
164+
git_add_all(repo);
165+
git_commit(repo, ~"floop");
166+
}
167+
168+
fn git_commit(repo: &Path, msg: ~str) {
169+
let mut prog = run::Process::new("git", [~"commit", ~"-m", msg],
156170
run::ProcessOptions { env: None,
157171
dir: Some(repo),
158172
in_fd: None,
@@ -161,9 +175,14 @@ fn add_git_tag(repo: &Path, tag: ~str) {
161175
});
162176
let output = prog.finish_with_output();
163177
if output.status != 0 {
164-
fail!("Couldn't add all files in %s", repo.to_str())
178+
fail!("Couldn't commit in %s: output was %s", repo.to_str(),
179+
str::from_bytes(output.output + output.error))
165180
}
166-
prog = run::Process::new("git", [~"commit", ~"-m", ~"whatever"],
181+
182+
}
183+
184+
fn git_add_all(repo: &Path) {
185+
let mut prog = run::Process::new("git", [~"add", ~"-A"],
167186
run::ProcessOptions { env: None,
168187
dir: Some(repo),
169188
in_fd: None,
@@ -172,10 +191,16 @@ fn add_git_tag(repo: &Path, tag: ~str) {
172191
});
173192
let output = prog.finish_with_output();
174193
if output.status != 0 {
175-
fail!("Couldn't commit in %s", repo.to_str())
194+
fail!("Couldn't add all files in %s: output was %s",
195+
repo.to_str(), str::from_bytes(output.output + output.error))
176196
}
197+
}
177198

178-
prog = run::Process::new("git", [~"tag", tag.clone()],
199+
fn add_git_tag(repo: &Path, tag: ~str) {
200+
assert!(repo.is_absolute());
201+
git_add_all(repo);
202+
git_commit(repo, ~"whatever");
203+
let mut prog = run::Process::new("git", [~"tag", tag.clone()],
179204
run::ProcessOptions { env: None,
180205
dir: Some(repo),
181206
in_fd: None,
@@ -624,31 +649,6 @@ fn test_package_request_version() {
624649
writeFile(&repo_subdir.push("version-0.4-file.txt"), "hello");
625650
add_git_tag(&repo_subdir, ~"0.4");
626651
627-
/*
628-
629-
let pkg_src = PkgSrc::new(&repo, &repo, &temp_pkg_id);
630-
match temp_pkg_id.version {
631-
ExactRevision(~"0.3") => {
632-
debug!("Version matches, calling fetch_git");
633-
match pkg_src.fetch_git() {
634-
Some(p) => {
635-
debug!("does version-0.3-file exist?");
636-
assert!(os::path_exists(&p.push("version-0.3-file.txt")));
637-
debug!("does version-0.4-file exist?");
638-
assert!(!os::path_exists(&p.push("version-0.4-file.txt")));
639-
640-
}
641-
None => fail!("test_package_request_version: fetch_git failed")
642-
}
643-
}
644-
ExactRevision(n) => {
645-
fail!("n is %? and %? %s %?", n, n, if n == ~"0.3" { "==" } else { "!=" }, "0.3");
646-
}
647-
_ => fail!(fmt!("test_package_version: package version was %?, expected ExactRevision(0.3)",
648-
temp_pkg_id.version))
649-
}
650-
*/
651-
652652
command_line_test([~"install", fmt!("%s#0.3", local_path)], &repo);
653653
654654
assert!(match installed_library_in_workspace("test_pkg_version", &repo.push(".rust")) {
@@ -681,6 +681,7 @@ fn rustpkg_install_url_2() {
681681
}
682682
683683
// FIXME: #7956: temporarily disabled
684+
#[test]
684685
fn rustpkg_library_target() {
685686
let foo_repo = init_git_repo(&Path("foo"));
686687
let package_dir = foo_repo.push("foo");
@@ -707,8 +708,10 @@ fn rustpkg_local_pkg() {
707708
assert_executable_exists(&dir, "foo");
708709
}
709710
711+
// FIXME: #7956: temporarily disabled
712+
// Failing on dist-linux bot
710713
#[test]
711-
#[ignore] // XXX Failing on dist-linux bot
714+
#[ignore]
712715
fn package_script_with_default_build() {
713716
let dir = create_local_package(&PkgId::new("fancy-lib", &os::getcwd()));
714717
debug!("dir = %s", dir.to_str());
@@ -767,7 +770,7 @@ fn rustpkg_clean_no_arg() {
767770
}
768771
769772
#[test]
770-
#[ignore (reason = "Un-ignore when #7071 is fixed")]
773+
#[ignore (reason = "Specifying env doesn't work -- see #8028")]
771774
fn rust_path_test() {
772775
let dir_for_path = mkdtemp(&os::tmpdir(), "more_rust").expect("rust_path_test failed");
773776
let dir = mk_workspace(&dir_for_path, &normalize(RemotePath(Path("foo"))), &NoVersion);
@@ -776,9 +779,13 @@ fn rust_path_test() {
776779
777780
let cwd = os::getcwd();
778781
debug!("cwd = %s", cwd.to_str());
782+
debug!("Running command: cd %s; RUST_LOG=rustpkg RUST_PATH=%s rustpkg install foo",
783+
cwd.to_str(), dir_for_path.to_str());
779784
let mut prog = run::Process::new("rustpkg",
780785
[~"install", ~"foo"],
781-
run::ProcessOptions { env: Some(&[(~"RUST_PATH",
786+
run::ProcessOptions { env: Some(&[(~"RUST_LOG",
787+
~"rustpkg"),
788+
(~"RUST_PATH",
782789
dir_for_path.to_str())]),
783790
dir: Some(&cwd),
784791
in_fd: None,
@@ -956,7 +963,6 @@ fn do_rebuild_dep_only_contents_change() {
956963
}
957964
958965
#[test]
959-
#[ignore(reason = "list not yet implemented")]
960966
fn test_versions() {
961967
let workspace = create_local_package(&PkgId::new("foo#0.1", &os::getcwd()));
962968
create_local_package(&PkgId::new("foo#0.2", &os::getcwd()));
@@ -994,11 +1000,35 @@ fn test_rustpkg_test() {
9941000
}
9951001
9961002
#[test]
997-
#[ignore(reason = "uninstall not yet implemented")]
9981003
fn test_uninstall() {
9991004
let workspace = create_local_package(&PkgId::new("foo", &os::getcwd()));
10001005
let _output = command_line_test([~"info", ~"foo"], &workspace);
10011006
command_line_test([~"uninstall", ~"foo"], &workspace);
10021007
let output = command_line_test([~"list"], &workspace);
10031008
assert!(!str::from_bytes(output.output).contains("foo"));
10041009
}
1010+
1011+
#[test]
1012+
fn test_non_numeric_tag() {
1013+
let temp_pkg_id = git_repo_pkg();
1014+
let repo = init_git_repo(&Path(temp_pkg_id.local_path.to_str()));
1015+
let repo_subdir = repo.push("mockgithub.com").push("catamorphism").push("test_pkg");
1016+
writeFile(&repo_subdir.push("foo"), "foo");
1017+
writeFile(&repo_subdir.push("lib.rs"),
1018+
"pub fn f() { let _x = (); }");
1019+
add_git_tag(&repo_subdir, ~"testbranch");
1020+
writeFile(&repo_subdir.push("testbranch_only"), "hello");
1021+
add_git_tag(&repo_subdir, ~"another_tag");
1022+
writeFile(&repo_subdir.push("not_on_testbranch_only"), "bye bye");
1023+
add_all_and_commit(&repo_subdir);
1024+
1025+
1026+
command_line_test([~"install", fmt!("%s#testbranch", temp_pkg_id.remote_path.to_str())],
1027+
&repo);
1028+
let file1 = repo.push_many(["mockgithub.com", "catamorphism",
1029+
"test_pkg", "testbranch_only"]);
1030+
let file2 = repo.push_many(["mockgithub.com", "catamorphism", "test_pkg",
1031+
"master_only"]);
1032+
assert!(os::path_exists(&file1));'
1033+
assert!(!os::path_exists(&file2));
1034+
}

src/librustpkg/version.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ use extra::tempfile::mkdtemp;
2222
pub enum Version {
2323
ExactRevision(~str), // Should look like a m.n.(...).x
2424
SemanticVersion(semver::Version),
25+
Tagged(~str), // String that can't be parsed as a version.
26+
// Requirements get interpreted exactly
2527
NoVersion // user didn't specify a version -- prints as 0.1
2628
}
2729

@@ -76,7 +78,7 @@ impl Ord for Version {
7678
impl ToStr for Version {
7779
fn to_str(&self) -> ~str {
7880
match *self {
79-
ExactRevision(ref n) => fmt!("%s", n.to_str()),
81+
ExactRevision(ref n) | Tagged(ref n) => fmt!("%s", n.to_str()),
8082
SemanticVersion(ref v) => fmt!("%s", v.to_str()),
8183
NoVersion => ~"0.1"
8284
}

0 commit comments

Comments
 (0)