git-checks 1.0.0

Checks to run against a topic in git to enforce coding standards.
Documentation
// Copyright 2016 Kitware, Inc.
//
// 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.

extern crate git_workarea;
use self::git_workarea::{CommitId, GitContext};

extern crate tempdir;
use self::tempdir::TempDir;

pub use super::super::*;

use std::env;
use std::path::Path;
use std::process::Command;

// pub static ROOT_COMMIT: &'static str = "1b2c7b3dad2fb7d14fbf0b619bf7faca4dd01243";
pub static FILLER_COMMIT: &'static str = "d02f015907371738253a22b9a7fec78607a969b2";
pub static TARGET_COMMIT: &'static str = "27ff3ef5532d76afa046f76f4dd8f588dc3e83c3";
pub static SUBMODULE_TARGET_COMMIT: &'static str = "fe90ee22ae3ce4b4dc41f8d0876e59355ff1e21c";

fn make_context() -> GitContext {
    let gitdir = Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/.git"));
    if !gitdir.exists() {
        panic!("The tests must be run from a git checkout!");
    }

    GitContext::new(gitdir)
}

fn make_context_submodule(gitdir: &Path, commit: &CommitId) -> GitContext {
    let gitdir = gitdir.join("origin");
    let clone = Command::new("git")
        .arg("clone")
        .arg(concat!(env!("CARGO_MANIFEST_DIR"), "/.git"))
        .arg(&gitdir)
        .output()
        .unwrap();
    if !clone.status.success() {
        panic!("origin clone failed: {}",
               String::from_utf8_lossy(&clone.stderr));
    }

    let ctx = GitContext::new(gitdir.join(".git"));

    let checkout = ctx.git()
        .arg("checkout")
        .arg(commit.as_str())
        .current_dir(&gitdir)
        .output()
        .unwrap();
    if !checkout.status.success() {
        panic!("checkout failed: {}",
               String::from_utf8_lossy(&checkout.stderr));
    }

    let submodule_update = ctx.git()
        .arg("submodule")
        .arg("update")
        .arg("--init")
        .current_dir(&gitdir)
        .output()
        .unwrap();
    if !submodule_update.status.success() {
        panic!("submodule update failed: {}",
               String::from_utf8_lossy(&submodule_update.stderr));
    }

    ctx
}

fn test_check_custom<'a>(ctx: &GitContext, test_name: &str, topic: &str, base: &str,
                         conf: &GitCheckConfiguration<'a>)
                         -> CheckResult {
    let refs = conf.list(&ctx, test_name, &CommitId::new(base), &CommitId::new(topic))
        .unwrap();

    assert!(!refs.is_empty());

    conf.run(&ctx,
             &refs,
             &Identity::new("Rust Git Checks Tests", "rust-git-checks@example.com"))
        .unwrap()
}

pub fn test_check_base<'a>(test_name: &str, topic: &str, base: &str,
                           conf: &GitCheckConfiguration<'a>)
                           -> CheckResult {
    let ctx = make_context();
    test_check_custom(&ctx, test_name, topic, base, conf)
}

pub fn test_check<'a>(test_name: &str, topic: &str, conf: &GitCheckConfiguration<'a>)
                      -> CheckResult {
    test_check_base(test_name, topic, TARGET_COMMIT, conf)
}

pub fn test_check_submodule_base<'a>(test_name: &str, topic: &str, base: &str,
                                     conf: &GitCheckConfiguration<'a>)
                                     -> CheckResult {
    let mut working_dir = env::current_exe().unwrap();
    working_dir.pop();

    let tempdir = TempDir::new_in(working_dir, test_name).unwrap();

    let ctx = make_context_submodule(tempdir.path(), &CommitId::new(base));
    test_check_custom(&ctx, test_name, topic, base, conf)
}

pub fn test_check_submodule<'a>(test_name: &str, topic: &str, conf: &GitCheckConfiguration<'a>)
                                -> CheckResult {
    test_check_submodule_base(test_name, topic, SUBMODULE_TARGET_COMMIT, conf)
}