Skip to content

rustpkg: Handle local git repositories #7681

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions src/librustpkg/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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: ~[],
Expand All @@ -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: ~[],
Expand All @@ -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 {
Expand All @@ -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)});

}

Expand Down
4 changes: 2 additions & 2 deletions src/librustpkg/installed_packages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 11 additions & 4 deletions src/librustpkg/package_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
}
}
};

Expand Down
18 changes: 16 additions & 2 deletions src/librustpkg/package_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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<Path> {

Expand All @@ -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 => ~[],
Expand Down
17 changes: 17 additions & 0 deletions src/librustpkg/path_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,30 @@ 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();
for h.iter().advance |h| { push_if_exists(&mut env_rust_path, h); }
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,
Expand Down
39 changes: 32 additions & 7 deletions src/librustpkg/rustpkg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -57,6 +58,7 @@ mod package_path;
mod package_source;
mod path_util;
mod search;
mod source_control;
mod target;
#[cfg(test)]
mod tests;
Expand Down Expand Up @@ -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);
}
}
Expand All @@ -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
}
Expand All @@ -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]),
Expand All @@ -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);
}
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
48 changes: 48 additions & 0 deletions src/librustpkg/source_control.rs
Original file line number Diff line number Diff line change
@@ -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 <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.

// 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"))
}
Loading