diff --git a/src/librustpkg/api.rs b/src/librustpkg/api.rs index 5233b87f7e4..17cb3521eb7 100644 --- a/src/librustpkg/api.rs +++ b/src/librustpkg/api.rs @@ -28,8 +28,8 @@ pub fn build_lib(sysroot: @Path, root: Path, dest: Path, name: ~str, version: Ve let pkg_src = PkgSrc { root: root, - dst_dir: dest, - id: PkgId{ version: version, ..PkgId::new(name)}, + dst_dir: dest.clone(), + id: PkgId{ version: version, ..PkgId::new(name, &dest.pop())}, libs: ~[mk_crate(lib)], mains: ~[], tests: ~[], @@ -42,8 +42,8 @@ pub fn build_exe(sysroot: @Path, root: Path, dest: Path, name: ~str, version: Ve main: Path) { let pkg_src = PkgSrc { root: root, - dst_dir: dest, - id: PkgId{ version: version, ..PkgId::new(name)}, + dst_dir: dest.clone(), + id: PkgId{ version: version, ..PkgId::new(name, &dest.pop())}, libs: ~[], mains: ~[mk_crate(main)], tests: ~[], @@ -62,7 +62,7 @@ pub fn install_lib(sysroot: @Path, debug!("sysroot = %s", sysroot.to_str()); debug!("workspace = %s", workspace.to_str()); // make a PkgSrc - let pkg_id = PkgId{ version: version, ..PkgId::new(name)}; + let pkg_id = PkgId{ version: version, ..PkgId::new(name, &workspace)}; let build_dir = workspace.push("build"); let dst_dir = build_dir.push_rel(&*pkg_id.local_path); let pkg_src = PkgSrc { @@ -81,7 +81,7 @@ pub fn install_lib(sysroot: @Path, pub fn install_exe(sysroot: @Path, workspace: Path, name: ~str, version: Version) { default_ctxt(sysroot).install(&workspace, &PkgId{ version: version, - ..PkgId::new(name)}); + ..PkgId::new(name, &workspace)}); } diff --git a/src/librustpkg/installed_packages.rs b/src/librustpkg/installed_packages.rs index 980b00d3864..6b28b7ed6a1 100644 --- a/src/librustpkg/installed_packages.rs +++ b/src/librustpkg/installed_packages.rs @@ -18,11 +18,11 @@ pub fn list_installed_packages(f: &fn(&PkgId) -> bool) -> bool { for workspaces.iter().advance |p| { let binfiles = os::list_dir(&p.push("bin")); for binfiles.iter().advance() |exec| { - f(&PkgId::new(*exec)); + f(&PkgId::new(*exec, p)); } let libfiles = os::list_dir(&p.push("lib")); for libfiles.iter().advance() |lib| { - f(&PkgId::new(*lib)); + f(&PkgId::new(*lib, p)); } } true diff --git a/src/librustpkg/package_id.rs b/src/librustpkg/package_id.rs index b11f9820960..d1000f7f845 100644 --- a/src/librustpkg/package_id.rs +++ b/src/librustpkg/package_id.rs @@ -9,7 +9,8 @@ // except according to those terms. pub use package_path::{RemotePath, LocalPath, normalize, hash}; -use version::{try_getting_version, Version, NoVersion, split_version}; +use version::{try_getting_version, try_getting_local_version, + Version, NoVersion, split_version}; /// Path-fragment identifier of a package such as /// 'github.com/graydon/test'; path must be a relative @@ -40,7 +41,10 @@ impl Eq for PkgId { } impl PkgId { - pub fn new(s: &str) -> PkgId { + // The PkgId constructor takes a Path argument so as + // to be able to infer the version if the path refers + // to a local git repository + pub fn new(s: &str, work_dir: &Path) -> PkgId { use conditions::bad_pkg_id::cond; let mut given_version = None; @@ -71,9 +75,12 @@ impl PkgId { let version = match given_version { Some(v) => v, - None => match try_getting_version(&remote_path) { + None => match try_getting_local_version(&work_dir.push_rel(&*local_path)) { Some(v) => v, - None => NoVersion + None => match try_getting_version(&remote_path) { + Some(v) => v, + None => NoVersion + } } }; diff --git a/src/librustpkg/package_source.rs b/src/librustpkg/package_source.rs index 54ad888e2ae..668157bebb9 100644 --- a/src/librustpkg/package_source.rs +++ b/src/librustpkg/package_source.rs @@ -15,6 +15,7 @@ use std::{os, run, str}; use context::*; use crate::Crate; use messages::*; +use source_control::git_clone; use path_util::pkgid_src_in_workspace; use util::compile_crate; use version::{ExactRevision, SemanticVersion, NoVersion}; @@ -76,9 +77,10 @@ impl PkgSrc { dir } - /// Try interpreting self's package id as a remote package, and try + /// Try interpreting self's package id as a git repository, and try /// fetching it and caching it in a local directory. Return the cached directory - /// if this was successful, None otherwise + /// if this was successful, None otherwise. Similarly, if the package id + /// refers to a git repo on the local version, also check it out. /// (right now we only support git) pub fn fetch_git(&self) -> Option { @@ -87,6 +89,18 @@ impl PkgSrc { // Git can't clone into a non-empty directory os::remove_dir_recursive(&local); + debug!("Checking whether %s exists locally. Cwd = %s, does it? %?", + self.id.local_path.to_str(), + os::getcwd().to_str(), + os::path_exists(&*self.id.local_path)); + + if os::path_exists(&*self.id.local_path) { + debug!("%s exists locally! Cloning it into %s", + self.id.local_path.to_str(), local.to_str()); + git_clone(&*self.id.local_path, &local, &self.id.version); + return Some(local); + } + let url = fmt!("https://%s", self.id.remote_path.to_str()); let branch_args = match self.id.version { NoVersion => ~[], diff --git a/src/librustpkg/path_util.rs b/src/librustpkg/path_util.rs index 44bbe36feb8..e4a345733ea 100644 --- a/src/librustpkg/path_util.rs +++ b/src/librustpkg/path_util.rs @@ -54,6 +54,7 @@ pub fn rust_path() -> ~[Path] { }; let cwd = os::getcwd(); // now add in default entries + env_rust_path.push(cwd.push(".rust")); env_rust_path.push(copy cwd); do cwd.each_parent() |p| { push_if_exists(&mut env_rust_path, p) }; let h = os::homedir(); @@ -61,6 +62,22 @@ pub fn rust_path() -> ~[Path] { env_rust_path } +pub fn default_workspace() -> Path { + let p = rust_path(); + if p.is_empty() { + fail!("Empty RUST_PATH"); + } + let result = p[0]; + if !os::path_is_dir(&result) { + os::mkdir_recursive(&result, U_RWX); + } + result +} + +pub fn in_rust_path(p: &Path) -> bool { + rust_path().contains(p) +} + pub static U_RWX: i32 = (S_IRUSR | S_IWUSR | S_IXUSR) as i32; /// Creates a directory that is readable, writeable, diff --git a/src/librustpkg/rustpkg.rs b/src/librustpkg/rustpkg.rs index 5e9b9ffa788..46f2d5eb37e 100644 --- a/src/librustpkg/rustpkg.rs +++ b/src/librustpkg/rustpkg.rs @@ -38,9 +38,10 @@ use syntax::{ast, diagnostic}; use util::*; use messages::*; use path_util::{build_pkg_id_in_workspace, first_pkgid_src_in_workspace}; -use path_util::{U_RWX, rust_path}; -use path_util::{built_executable_in_workspace, built_library_in_workspace}; +use path_util::{U_RWX, rust_path, in_rust_path}; +use path_util::{built_executable_in_workspace, built_library_in_workspace, default_workspace}; use path_util::{target_executable_in_workspace, target_library_in_workspace}; +use source_control::is_git_dir; use workspace::{each_pkg_parent_workspace, pkg_parent_workspaces}; use context::Ctx; use package_id::PkgId; @@ -57,6 +58,7 @@ mod package_path; mod package_source; mod path_util; mod search; +mod source_control; mod target; #[cfg(test)] mod tests; @@ -201,8 +203,10 @@ impl CtxMethods for Ctx { } // The package id is presumed to be the first command-line // argument - let pkgid = PkgId::new(copy args[0]); + let pkgid = PkgId::new(copy args[0], &os::getcwd()); for each_pkg_parent_workspace(&pkgid) |workspace| { + debug!("found pkg %s in workspace %s, trying to build", + pkgid.to_str(), workspace.to_str()); self.build(workspace, &pkgid); } } @@ -212,7 +216,7 @@ impl CtxMethods for Ctx { } // The package id is presumed to be the first command-line // argument - let pkgid = PkgId::new(copy args[0]); + let pkgid = PkgId::new(copy args[0], &os::getcwd()); let cwd = os::getcwd(); self.clean(&cwd, &pkgid); // tjc: should use workspace, not cwd } @@ -233,9 +237,10 @@ impl CtxMethods for Ctx { // The package id is presumed to be the first command-line // argument - let pkgid = PkgId::new(args[0]); + let pkgid = PkgId::new(args[0], &os::getcwd()); let workspaces = pkg_parent_workspaces(&pkgid); if workspaces.is_empty() { + debug!("install! workspaces was empty"); let rp = rust_path(); assert!(!rp.is_empty()); let src = PkgSrc::new(&rp[0], &build_pkg_id_in_workspace(&pkgid, &rp[0]), @@ -245,6 +250,9 @@ impl CtxMethods for Ctx { } else { for each_pkg_parent_workspace(&pkgid) |workspace| { + debug!("install: found pkg %s in workspace %s, trying to build", + pkgid.to_str(), workspace.to_str()); + self.install(workspace, &pkgid); } } @@ -272,7 +280,7 @@ impl CtxMethods for Ctx { return usage::uninstall(); } - let pkgid = PkgId::new(args[0]); + let pkgid = PkgId::new(args[0], &os::getcwd()); // ?? if !installed_packages::package_is_installed(&pkgid) { warn(fmt!("Package %s doesn't seem to be installed! Doing nothing.", args[0])); return; @@ -304,12 +312,29 @@ impl CtxMethods for Ctx { } fn build(&self, workspace: &Path, pkgid: &PkgId) { - debug!("build: workspace = %s pkgid = %s", workspace.to_str(), + debug!("build: workspace = %s (in Rust path? %? is git dir? %? \ + pkgid = %s", workspace.to_str(), + in_rust_path(workspace), is_git_dir(&workspace.push_rel(&*pkgid.local_path)), pkgid.to_str()); let src_dir = first_pkgid_src_in_workspace(pkgid, workspace); let build_dir = build_pkg_id_in_workspace(pkgid, workspace); debug!("Destination dir = %s", build_dir.to_str()); + // If workspace isn't in the RUST_PATH, and it's a git repo, + // then clone it into the first entry in RUST_PATH, and repeat + debug!("%? %? %s", in_rust_path(workspace), + is_git_dir(&workspace.push_rel(&*pkgid.local_path)), + workspace.to_str()); + if !in_rust_path(workspace) && is_git_dir(&workspace.push_rel(&*pkgid.local_path)) { + let out_dir = default_workspace().push("src").push_rel(&*pkgid.local_path); + source_control::git_clone(&workspace.push_rel(&*pkgid.local_path), + &out_dir, &pkgid.version); + let default_ws = default_workspace(); + debug!("Calling build recursively with %? and %?", default_ws.to_str(), + pkgid.to_str()); + return self.build(&default_ws, pkgid); + } + // Create the package source let mut src = PkgSrc::new(workspace, &build_dir, pkgid); debug!("Package src = %?", src); diff --git a/src/librustpkg/source_control.rs b/src/librustpkg/source_control.rs new file mode 100644 index 00000000000..8d125300a33 --- /dev/null +++ b/src/librustpkg/source_control.rs @@ -0,0 +1,48 @@ +// 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. + +// Utils for working with version control repositories. Just git right now. + +use std::{io, os, run, str}; +use version::*; + +/// For a local git repo +pub fn git_clone(source: &Path, target: &Path, v: &Version) { + assert!(os::path_is_dir(source)); + assert!(is_git_dir(source)); + if !os::path_exists(target) { + let version_args = match v { + &ExactRevision(ref s) => ~[~"--branch", s.to_owned()], + _ => ~[] + }; + debug!("Running: git clone %s %s %s", version_args.to_str(), source.to_str(), + target.to_str()); + let outp = run::process_output("git", ~[~"clone"] + version_args + + ~[source.to_str(), target.to_str()]); + if outp.status != 0 { + io::println(str::from_bytes_owned(outp.output.clone())); + io::println(str::from_bytes_owned(outp.error)); + fail!("Couldn't `git clone` %s", source.to_str()); + } + } + else { + // Pull changes + debug!("Running: git --work-tree=%s --git-dir=%s pull --no-edit %s", + target.to_str(), target.push(".git").to_str(), source.to_str()); + let outp = run::process_output("git", [fmt!("--work-tree=%s", target.to_str()), + fmt!("--git-dir=%s", target.push(".git").to_str()), + ~"pull", ~"--no-edit", source.to_str()]); + assert!(outp.status == 0); + } +} + +pub fn is_git_dir(p: &Path) -> bool { + os::path_is_dir(&p.push(".git")) +} diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs index c1bf72e8509..722f01a2564 100644 --- a/src/librustpkg/tests.rs +++ b/src/librustpkg/tests.rs @@ -18,7 +18,6 @@ use std::run::ProcessOutput; use installed_packages::list_installed_packages; use package_path::*; use package_id::{PkgId}; -use package_source::*; use version::{ExactRevision, NoVersion, Version}; use path_util::{target_executable_in_workspace, target_library_in_workspace, target_test_in_workspace, target_bench_in_workspace, @@ -52,8 +51,8 @@ fn fake_pkg() -> PkgId { } } -fn remote_pkg() -> PkgId { - let remote = RemotePath(Path("github.com/catamorphism/test-pkg")); +fn git_repo_pkg() -> PkgId { + let remote = RemotePath(Path("mockgithub.com/catamorphism/test-pkg")); PkgId { local_path: normalize(copy remote), remote_path: remote, @@ -109,6 +108,86 @@ fn mk_temp_workspace(short_name: &LocalPath, version: &Version) -> Path { package_dir } +/// Should create an empty git repo in p, relative to the tmp dir, and return the new +/// absolute path +fn init_git_repo(p: &Path) -> Path { + assert!(!p.is_absolute()); + let tmp = mkdtemp(&os::tmpdir(), "git_local").expect("couldn't create temp dir"); + let work_dir = tmp.push_rel(p); + let work_dir_for_opts = work_dir.clone(); + assert!(os::mkdir_recursive(&work_dir, U_RWX)); + debug!("Running: git init in %s", work_dir.to_str()); + let opts = run::ProcessOptions { + env: None, + dir: Some(&work_dir_for_opts), + in_fd: None, + out_fd: None, + err_fd: None + }; + let mut prog = run::Process::new("git", [~"init"], opts); + let mut output = prog.finish_with_output(); + if output.status == 0 { + // Add stuff to the dir so that git tag succeeds + writeFile(&work_dir.push("README"), ""); + prog = run::Process::new("git", [~"add", ~"README"], opts); + output = prog.finish_with_output(); + if output.status == 0 { + prog = run::Process::new("git", [~"commit", ~"-m", ~"whatever"], opts); + output = prog.finish_with_output(); + if output.status == 0 { + tmp + } + else { + fail!("Couldn't commit in %s", work_dir.to_str()); + } + } + else { + fail!("Couldn't add in %s", work_dir.to_str()); + } + } + else { + fail!("Couldn't initialize git repository in %s", work_dir.to_str()) + } +} + +fn add_git_tag(repo: &Path, tag: ~str) { + assert!(repo.is_absolute()); + let mut prog = run::Process::new("git", [~"add", ~"-A"], + run::ProcessOptions { env: None, + dir: Some(repo), + in_fd: None, + out_fd: None, + err_fd: None + }); + let output = prog.finish_with_output(); + if output.status != 0 { + fail!("Couldn't add all files in %s", repo.to_str()) + } + prog = run::Process::new("git", [~"commit", ~"-m", ~"whatever"], + run::ProcessOptions { env: None, + dir: Some(repo), + in_fd: None, + out_fd: None, + err_fd: None + }); + let output = prog.finish_with_output(); + if output.status != 0 { + fail!("Couldn't commit in %s", repo.to_str()) + } + + prog = run::Process::new("git", [~"tag", tag.clone()], + run::ProcessOptions { env: None, + dir: Some(repo), + in_fd: None, + out_fd: None, + err_fd: None + }); + let output = prog.finish_with_output(); + if output.status != 0 { + fail!("Couldn't add git tag %s in %s", tag, repo.to_str()) + } +} + fn is_rwx(p: &Path) -> bool { use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR}; @@ -168,16 +247,6 @@ to make sure the command succeeded output } -fn make_git_repo(short_name: &str) -> Path { - let temp_d = mk_temp_workspace(&normalize(RemotePath(Path(short_name))), &NoVersion); - debug!("Dry run: would initialize %s as a git repository", temp_d.pop().pop().to_str()); - temp_d.pop().pop() -} - -fn add_git_tag(repo: &Path, tag: &str) { - debug!("Dry run: would add tag %s to repo %s", tag, repo.to_str()); -} - fn create_local_package(pkgid: &PkgId) -> Path { let parent_dir = mk_temp_workspace(&pkgid.local_path, &pkgid.version); debug!("Created empty package dir for %s, returning %s", pkgid.to_str(), parent_dir.to_str()); @@ -236,16 +305,19 @@ fn create_local_package_with_custom_build_hook(pkgid: &PkgId, } -fn assert_lib_exists(repo: &Path, short_name: &str) { +fn assert_lib_exists(repo: &Path, short_name: &str, v: Version) { debug!("assert_lib_exists: repo = %s, short_name = %s", repo.to_str(), short_name); - let lib = target_library_in_workspace(&PkgId::new(short_name), repo); + let lib = target_library_in_workspace(&(PkgId { + version: v, ..PkgId::new(short_name, repo)} + ), repo); + debug!("assert_lib_exists: checking whether %s exists", lib.to_str()); assert!(os::path_exists(&lib)); assert!(is_rwx(&lib)); } fn assert_executable_exists(repo: &Path, short_name: &str) { debug!("assert_executable_exists: repo = %s, short_name = %s", repo.to_str(), short_name); - let exec = target_executable_in_workspace(&PkgId::new(short_name), repo); + let exec = target_executable_in_workspace(&PkgId::new(short_name, repo), repo); assert!(os::path_exists(&exec)); assert!(is_rwx(&exec)); } @@ -394,38 +466,54 @@ fn test_install_invalid() { assert!(error_occurred && error1_occurred); } +// Tests above should (maybe) be converted to shell out to rustpkg, too + #[test] #[ignore(cfg(target_arch = "x86"))] -fn test_install_url() { - let workspace = mkdtemp(&os::tmpdir(), "test").expect("couldn't create temp dir"); +fn test_install_git() { let sysroot = test_sysroot(); debug!("sysroot = %s", sysroot.to_str()); - let ctxt = fake_ctxt(Some(@sysroot)); - let temp_pkg_id = remote_pkg(); + let temp_pkg_id = git_repo_pkg(); + let repo = init_git_repo(&Path(temp_pkg_id.local_path.to_str())); + let repo_subdir = repo.push("mockgithub.com").push("catamorphism").push("test_pkg"); + writeFile(&repo_subdir.push("main.rs"), + "fn main() { let _x = (); }"); + writeFile(&repo_subdir.push("lib.rs"), + "pub fn f() { let _x = (); }"); + writeFile(&repo_subdir.push("test.rs"), + "#[test] pub fn f() { (); }"); + writeFile(&repo_subdir.push("bench.rs"), + "#[bench] pub fn f() { (); }"); + add_git_tag(&repo_subdir, ~"0.1"); // this has the effect of committing the files + + debug!("test_install_git: calling rustpkg install %s in %s", + temp_pkg_id.local_path.to_str(), repo.to_str()); // should have test, bench, lib, and main - ctxt.install(&workspace, &temp_pkg_id); + command_line_test([~"install", temp_pkg_id.local_path.to_str()], &repo); // Check that all files exist - let exec = target_executable_in_workspace(&temp_pkg_id, &workspace); + let ws = repo.push(".rust"); + debug!("Checking for files in %s", ws.to_str()); + let exec = target_executable_in_workspace(&temp_pkg_id, &ws); debug!("exec = %s", exec.to_str()); assert!(os::path_exists(&exec)); assert!(is_rwx(&exec)); let _built_lib = built_library_in_workspace(&temp_pkg_id, - &workspace).expect("test_install_url: built lib should exist"); - let lib = target_library_in_workspace(&temp_pkg_id, &workspace); + &ws).expect("test_install_git: built lib should exist"); + let lib = target_library_in_workspace(&temp_pkg_id, &ws); debug!("lib = %s", lib.to_str()); assert!(os::path_exists(&lib)); assert!(is_rwx(&lib)); let built_test = built_test_in_workspace(&temp_pkg_id, - &workspace).expect("test_install_url: built test should exist"); + &ws).expect("test_install_git: built test should exist"); assert!(os::path_exists(&built_test)); let built_bench = built_bench_in_workspace(&temp_pkg_id, - &workspace).expect("test_install_url: built bench should exist"); + &ws).expect("test_install_git: built bench should exist"); assert!(os::path_exists(&built_bench)); // And that the test and bench executables aren't installed - let test = target_test_in_workspace(&temp_pkg_id, &workspace); + let test = target_test_in_workspace(&temp_pkg_id, &ws); assert!(!os::path_exists(&test)); debug!("test = %s", test.to_str()); - let bench = target_bench_in_workspace(&temp_pkg_id, &workspace); + let bench = target_bench_in_workspace(&temp_pkg_id, &ws); debug!("bench = %s", bench.to_str()); assert!(!os::path_exists(&bench)); } @@ -445,18 +533,18 @@ fn test_package_ids_must_be_relative_path_like() { */ - let whatever = PkgId::new("foo"); + let whatever = PkgId::new("foo", &os::getcwd()); assert_eq!(~"foo-0.1", whatever.to_str()); assert!("github.com/catamorphism/test_pkg-0.1" == - PkgId::new("github.com/catamorphism/test-pkg").to_str()); + PkgId::new("github.com/catamorphism/test-pkg", &os::getcwd()).to_str()); do cond.trap(|(p, e)| { assert!("" == p.to_str()); assert!("0-length pkgid" == e); copy whatever }).in { - let x = PkgId::new(""); + let x = PkgId::new("", &os::getcwd()); assert_eq!(~"foo-0.1", x.to_str()); } @@ -465,7 +553,8 @@ fn test_package_ids_must_be_relative_path_like() { assert!("absolute pkgid" == e); copy whatever }).in { - let z = PkgId::new(os::make_absolute(&Path("foo/bar/quux")).to_str()); + let z = PkgId::new(os::make_absolute(&Path("foo/bar/quux")).to_str(), + &os::getcwd()); assert_eq!(~"foo-0.1", z.to_str()); } @@ -473,39 +562,71 @@ fn test_package_ids_must_be_relative_path_like() { #[test] #[ignore(cfg(target_arch = "x86"))] fn test_package_version() { - let temp_pkg_id = PkgId::new("github.com/catamorphism/test_pkg_version"); + let local_path = "mockgithub.com/catamorphism/test_pkg_version"; + let repo = init_git_repo(&Path(local_path)); + let repo_subdir = repo.push("mockgithub.com").push("catamorphism").push("test_pkg_version"); + debug!("Writing files in: %s", repo_subdir.to_str()); + writeFile(&repo_subdir.push("main.rs"), + "fn main() { let _x = (); }"); + writeFile(&repo_subdir.push("lib.rs"), + "pub fn f() { let _x = (); }"); + writeFile(&repo_subdir.push("test.rs"), + "#[test] pub fn f() { (); }"); + writeFile(&repo_subdir.push("bench.rs"), + "#[bench] pub fn f() { (); }"); + add_git_tag(&repo_subdir, ~"0.4"); + + let temp_pkg_id = PkgId::new("mockgithub.com/catamorphism/test_pkg_version", &repo); match temp_pkg_id.version { ExactRevision(~"0.4") => (), _ => fail!(fmt!("test_package_version: package version was %?, expected Some(0.4)", temp_pkg_id.version)) } - let temp = mk_empty_workspace(&LocalPath(Path("test_pkg_version")), &temp_pkg_id.version); - let ctx = fake_ctxt(Some(@test_sysroot())); - ctx.build(&temp, &temp_pkg_id); - assert!(match built_library_in_workspace(&temp_pkg_id, &temp) { + // This should look at the prefix, clone into a workspace, then build. + command_line_test([~"install", ~"mockgithub.com/catamorphism/test_pkg_version"], + &repo); + assert!(match built_library_in_workspace(&temp_pkg_id, + &repo.push(".rust")) { Some(p) => p.to_str().ends_with(fmt!("0.4%s", os::consts::DLL_SUFFIX)), None => false }); - assert!(built_executable_in_workspace(&temp_pkg_id, &temp) - == Some(temp.push("build"). - push("github.com"). + assert!(built_executable_in_workspace(&temp_pkg_id, &repo.push(".rust")) + == Some(repo.push(".rust").push("build"). + push("mockgithub.com"). push("catamorphism"). push("test_pkg_version"). push("test_pkg_version"))); } -// FIXME #7006: Fails on linux for some reason -#[test] -#[ignore] fn test_package_request_version() { - let temp_pkg_id = PkgId::new("github.com/catamorphism/test_pkg_version#0.3"); - let temp = mk_empty_workspace(&LocalPath(Path("test_pkg_version")), &ExactRevision(~"0.3")); - let pkg_src = PkgSrc::new(&temp, &temp, &temp_pkg_id); + let local_path = "mockgithub.com/catamorphism/test_pkg_version"; + let repo = init_git_repo(&Path(local_path)); + let repo_subdir = repo.push("mockgithub.com").push("catamorphism").push("test_pkg_version"); + debug!("Writing files in: %s", repo_subdir.to_str()); + writeFile(&repo_subdir.push("main.rs"), + "fn main() { let _x = (); }"); + writeFile(&repo_subdir.push("lib.rs"), + "pub fn f() { let _x = (); }"); + writeFile(&repo_subdir.push("test.rs"), + "#[test] pub fn f() { (); }"); + writeFile(&repo_subdir.push("bench.rs"), + "#[bench] pub fn f() { (); }"); + writeFile(&repo_subdir.push("version-0.3-file.txt"), "hi"); + add_git_tag(&repo_subdir, ~"0.3"); + writeFile(&repo_subdir.push("version-0.4-file.txt"), "hello"); + add_git_tag(&repo_subdir, ~"0.4"); + +/* + + let pkg_src = PkgSrc::new(&repo, &repo, &temp_pkg_id); match temp_pkg_id.version { ExactRevision(~"0.3") => { + debug!("Version matches, calling fetch_git"); match pkg_src.fetch_git() { Some(p) => { + debug!("does version-0.3-file exist?"); assert!(os::path_exists(&p.push("version-0.3-file.txt"))); + debug!("does version-0.4-file exist?"); assert!(!os::path_exists(&p.push("version-0.4-file.txt"))); } @@ -518,24 +639,31 @@ fn test_package_request_version() { _ => fail!(fmt!("test_package_version: package version was %?, expected ExactRevision(0.3)", temp_pkg_id.version)) } - let c = fake_ctxt(Some(@test_sysroot())); - c.install(&temp, &temp_pkg_id); - debug!("installed_library_in_workspace(%s, %s) = %?", temp_pkg_id.short_name, temp.to_str(), - installed_library_in_workspace(temp_pkg_id.short_name, &temp)); - assert!(match installed_library_in_workspace(temp_pkg_id.short_name, &temp) { +*/ + + command_line_test([~"install", fmt!("%s#0.3", local_path)], &repo); + + assert!(match installed_library_in_workspace("test_pkg_version", &repo.push(".rust")) { Some(p) => { debug!("installed: %s", p.to_str()); p.to_str().ends_with(fmt!("0.3%s", os::consts::DLL_SUFFIX)) } None => false }); - assert!(target_executable_in_workspace(&temp_pkg_id, &temp) - == temp.push("bin").push("test_pkg_version")); + let temp_pkg_id = PkgId::new("mockgithub.com/catamorphism/test_pkg_version#0.3", &repo); + assert!(target_executable_in_workspace(&temp_pkg_id, &repo.push(".rust")) + == repo.push(".rust").push("bin").push("test_pkg_version")); + assert!(os::path_exists(&repo.push(".rust").push("src") + .push("mockgithub.com").push("catamorphism") + .push("test_pkg_version-0.3") + .push("version-0.3-file.txt"))); + assert!(!os::path_exists(&repo.push(".rust").push("src") + .push("mockgithub.com").push("catamorphism") + .push("test_pkg_version-0.3") + .push("version-0.4-file.txt"))); } -// Tests above should (maybe) be converted to shell out to rustpkg, too - #[test] #[ignore (reason = "http-client not ported to rustpkg yet")] fn rustpkg_install_url_2() { @@ -546,15 +674,27 @@ fn rustpkg_install_url_2() { #[test] fn rustpkg_library_target() { - let foo_repo = make_git_repo("foo"); - add_git_tag(&foo_repo, "1.0"); + let foo_repo = init_git_repo(&Path("foo")); + let package_dir = foo_repo.push("foo"); + + debug!("Writing files in: %s", package_dir.to_str()); + writeFile(&package_dir.push("main.rs"), + "fn main() { let _x = (); }"); + writeFile(&package_dir.push("lib.rs"), + "pub fn f() { let _x = (); }"); + writeFile(&package_dir.push("test.rs"), + "#[test] pub fn f() { (); }"); + writeFile(&package_dir.push("bench.rs"), + "#[bench] pub fn f() { (); }"); + + add_git_tag(&package_dir, ~"1.0"); command_line_test([~"install", ~"foo"], &foo_repo); - assert_lib_exists(&foo_repo, "foo"); + assert_lib_exists(&foo_repo.push(".rust"), "foo", ExactRevision(~"1.0")); } #[test] fn rustpkg_local_pkg() { - let dir = create_local_package(&PkgId::new("foo")); + let dir = create_local_package(&PkgId::new("foo", &os::getcwd())); command_line_test([~"install", ~"foo"], &dir); assert_executable_exists(&dir, "foo"); } @@ -562,7 +702,7 @@ fn rustpkg_local_pkg() { #[test] #[ignore] // XXX Failing on dist-linux bot fn package_script_with_default_build() { - let dir = create_local_package(&PkgId::new("fancy-lib")); + let dir = create_local_package(&PkgId::new("fancy-lib", &os::getcwd())); debug!("dir = %s", dir.to_str()); let source = test_sysroot().pop().pop().pop().push("src").push("librustpkg"). push("testsuite").push("pass").push("src").push("fancy-lib").push("pkg.rs"); @@ -572,7 +712,7 @@ fn package_script_with_default_build() { fail!("Couldn't copy file"); } command_line_test([~"install", ~"fancy-lib"], &dir); - assert_lib_exists(&dir, "fancy-lib"); + assert_lib_exists(&dir, "fancy-lib", NoVersion); assert!(os::path_exists(&dir.push("build").push("fancy_lib").push("generated.rs"))); } @@ -633,12 +773,12 @@ fn rust_path_parse() { #[test] fn test_list() { - let foo = PkgId::new("foo"); let dir = mkdtemp(&os::tmpdir(), "test_list").expect("test_list failed"); + let foo = PkgId::new("foo", &dir); create_local_package_in(&foo, &dir); - let bar = PkgId::new("bar"); + let bar = PkgId::new("bar", &dir); create_local_package_in(&bar, &dir); - let quux = PkgId::new("quux"); + let quux = PkgId::new("quux", &dir); create_local_package_in(&quux, &dir); command_line_test([~"install", ~"foo"], &dir); @@ -660,10 +800,10 @@ fn test_list() { #[test] fn install_remove() { - let foo = PkgId::new("foo"); - let bar = PkgId::new("bar"); - let quux = PkgId::new("quux"); let dir = mkdtemp(&os::tmpdir(), "install_remove").expect("install_remove"); + let foo = PkgId::new("foo", &dir); + let bar = PkgId::new("bar", &dir); + let quux = PkgId::new("quux", &dir); create_local_package_in(&foo, &dir); create_local_package_in(&bar, &dir); create_local_package_in(&quux, &dir); @@ -688,7 +828,7 @@ fn install_check_duplicates() { // ("Is already installed -- doing nothing") // check invariant that there are no dups in the pkg database let dir = mkdtemp(&os::tmpdir(), "install_remove").expect("install_remove"); - let foo = PkgId::new("foo"); + let foo = PkgId::new("foo", &dir); create_local_package_in(&foo, &dir); command_line_test([~"install", ~"foo"], &dir); @@ -709,7 +849,7 @@ fn install_check_duplicates() { #[test] #[ignore(reason = "Workcache not yet implemented -- see #7075")] fn no_rebuilding() { - let p_id = PkgId::new("foo"); + let p_id = PkgId::new("foo", &os::getcwd()); let workspace = create_local_package(&p_id); command_line_test([~"build", ~"foo"], &workspace); let date = datestamp(&built_library_in_workspace(&p_id, @@ -723,8 +863,8 @@ fn no_rebuilding() { #[test] #[ignore(reason = "Workcache not yet implemented -- see #7075")] fn no_rebuilding_dep() { - let p_id = PkgId::new("foo"); - let dep_id = PkgId::new("bar"); + let p_id = PkgId::new("foo", &os::getcwd()); + let dep_id = PkgId::new("bar", &os::getcwd()); let workspace = create_local_package_with_dep(&p_id, &dep_id); command_line_test([~"build", ~"foo"], &workspace); let bar_date = datestamp(&lib_output_file_name(&workspace, @@ -736,8 +876,8 @@ fn no_rebuilding_dep() { #[test] fn do_rebuild_dep_dates_change() { - let p_id = PkgId::new("foo"); - let dep_id = PkgId::new("bar"); + let p_id = PkgId::new("foo", &os::getcwd()); + let dep_id = PkgId::new("bar", &os::getcwd()); let workspace = create_local_package_with_dep(&p_id, &dep_id); command_line_test([~"build", ~"foo"], &workspace); let bar_date = datestamp(&lib_output_file_name(&workspace, "build", "bar")); @@ -749,8 +889,8 @@ fn do_rebuild_dep_dates_change() { #[test] fn do_rebuild_dep_only_contents_change() { - let p_id = PkgId::new("foo"); - let dep_id = PkgId::new("bar"); + let p_id = PkgId::new("foo", &os::getcwd()); + let dep_id = PkgId::new("bar", &os::getcwd()); let workspace = create_local_package_with_dep(&p_id, &dep_id); command_line_test([~"build", ~"foo"], &workspace); let bar_date = datestamp(&lib_output_file_name(&workspace, "build", "bar")); @@ -764,8 +904,8 @@ fn do_rebuild_dep_only_contents_change() { #[test] #[ignore(reason = "list not yet implemented")] fn test_versions() { - let workspace = create_local_package(&PkgId::new("foo#0.1")); - create_local_package(&PkgId::new("foo#0.2")); + let workspace = create_local_package(&PkgId::new("foo#0.1", &os::getcwd())); + create_local_package(&PkgId::new("foo#0.2", &os::getcwd())); command_line_test([~"install", ~"foo#0.1"], &workspace); let output = command_line_test_output([~"list"]); // make sure output includes versions @@ -775,7 +915,8 @@ fn test_versions() { #[test] #[ignore(reason = "do not yet implemented")] fn test_build_hooks() { - let workspace = create_local_package_with_custom_build_hook(&PkgId::new("foo"), "frob"); + let workspace = create_local_package_with_custom_build_hook(&PkgId::new("foo", &os::getcwd()), + "frob"); command_line_test([~"do", ~"foo", ~"frob"], &workspace); } @@ -784,7 +925,7 @@ fn test_build_hooks() { #[ignore(reason = "info not yet implemented")] fn test_info() { let expected_info = ~"package foo"; // fill in - let workspace = create_local_package(&PkgId::new("foo")); + let workspace = create_local_package(&PkgId::new("foo", &os::getcwd())); let output = command_line_test([~"info", ~"foo"], &workspace); assert_eq!(str::from_bytes(output.output), expected_info); } @@ -793,7 +934,7 @@ fn test_info() { #[ignore(reason = "test not yet implemented")] fn test_rustpkg_test() { let expected_results = ~"1 out of 1 tests passed"; // fill in - let workspace = create_local_package_with_test(&PkgId::new("foo")); + let workspace = create_local_package_with_test(&PkgId::new("foo", &os::getcwd())); let output = command_line_test([~"test", ~"foo"], &workspace); assert_eq!(str::from_bytes(output.output), expected_results); } @@ -801,7 +942,7 @@ fn test_rustpkg_test() { #[test] #[ignore(reason = "uninstall not yet implemented")] fn test_uninstall() { - let workspace = create_local_package(&PkgId::new("foo")); + let workspace = create_local_package(&PkgId::new("foo", &os::getcwd())); let _output = command_line_test([~"info", ~"foo"], &workspace); command_line_test([~"uninstall", ~"foo"], &workspace); let output = command_line_test([~"list"], &workspace); diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index 1ee7caf6d24..c9b9415f872 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -344,7 +344,7 @@ pub fn find_and_install_dependencies(ctxt: &Ctx, } None => { // Try to install it - let pkg_id = PkgId::new(lib_name); + let pkg_id = PkgId::new(lib_name, &os::getcwd()); my_ctxt.install(&my_workspace, &pkg_id); // Also, add an additional search path debug!("let installed_path...") diff --git a/src/librustpkg/version.rs b/src/librustpkg/version.rs index 28c3143d8de..5b291164287 100644 --- a/src/librustpkg/version.rs +++ b/src/librustpkg/version.rs @@ -89,6 +89,29 @@ pub fn parse_vers(vers: ~str) -> result::Result { } } +/// If `local_path` is a git repo, and the most recent tag in that repo denotes a version, +/// return it; otherwise, `None` +pub fn try_getting_local_version(local_path: &Path) -> Option { + debug!("in try_getting_local_version"); + let outp = run::process_output("git", + [fmt!("--git-dir=%s", local_path.push(".git").to_str()), + ~"tag", ~"-l"]); + + debug!("git --git-dir=%s tag -l ~~~> %?", local_path.push(".git").to_str(), outp.status); + + if outp.status != 0 { + return None; + } + + let mut output = None; + let output_text = str::from_bytes(outp.output); + for output_text.line_iter().advance |l| { + if !l.is_whitespace() { + output = Some(l); + } + } + output.chain(try_parsing_version) +} /// 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;