git 0.2.0

The library provides basic operations with Git repositories.
use std::{env, process};
use std::path::PathBuf;

macro_rules! cmd(
    ($name:expr) => (process::Command::new($name));
);

macro_rules! get(
    ($name:expr) => (env::var($name).unwrap());
);

macro_rules! run(
    ($command:expr) => (
        assert!($command.stdout(process::Stdio::inherit())
                        .stderr(process::Stdio::inherit())
                        .status().unwrap().success());
    );
);

macro_rules! link(
    ($kind:expr, $name:expr) => (
        println!("cargo:rustc-link-lib={}={}", $kind, $name)
    );
);

macro_rules! look(
    ($path:expr) => (
        println!("cargo:rustc-link-search={}", $path)
    );
);

fn main() {
    let ssh = require("libssh2", None);
    require("openssl", Some("-lssl -lcrypto"));
    require("zlib", Some("-lz"));

    if get!("TARGET").contains("apple") {
       link!("dylib", "iconv");
    }

    let from = PathBuf::from(&get!("CARGO_MANIFEST_DIR")).join("build").join("libgit2");
    let cmake = PathBuf::from(&get!("CARGO_MANIFEST_DIR")).join("build").join("cmake");
    let into = PathBuf::from(&get!("OUT_DIR"));

    run!(cmd!("cmake").current_dir(&into)
                      .arg(&from)
                      .arg("-DBUILD_CLAR=OFF")
                      .arg("-DBUILD_EXAMPLES=OFF")
                      .arg("-DBUILD_SHARED_LIBS=OFF")
                      .arg("-DCMAKE_C_FLAGS=-fPIC")
                      .arg("-DTHREADSAFE=ON")
                      .arg(&format!("-DCMAKE_MODULE_PATH={}", cmake.display()))
                      .arg(&format!("-DUSE_SSH={}", if ssh { "ON" } else { "OFF" })));

    run!(cmd!("make").current_dir(&into).arg(&format!("-j{}", get!("NUM_JOBS"))));

    look!(into.display());
    link!("static", "git2");
}

fn require(name: &str, fallback: Option<&str>) -> bool {
    macro_rules! rescue(
        ($fallback:expr) => ({
            match $fallback {
                Some(output) => instruct(output),
                None => {},
            }
            return false;
        });
    );

    let result = match cmd!("pkg-config").arg("--libs").arg(name).output() {
        Ok(result) => result,
        Err(_) => rescue!(fallback),
    };

    if !result.status.success() {
        rescue!(fallback);
    }

    instruct(std::str::from_utf8(&result.stdout).unwrap());

    true
}

fn instruct(output: &str) {
    for chunk in output.split(' ') {
        if chunk.starts_with("-l") {
            link!("dylib", &chunk[2..]);
        } else if chunk.starts_with("-L") {
            look!(&chunk[2..]);
        }
    }
}