git_build_version/
lib.rs

1extern crate git2;
2#[macro_use]
3extern crate quick_error;
4
5use git2::{Repository, DescribeOptions};
6use std::env;
7use std::convert::AsRef;
8use std::fs::{File, create_dir_all};
9use std::io::{Write, Read, BufWriter};
10use std::path::Path;
11
12quick_error! {
13    #[derive(Debug)]
14    pub enum Error {
15        Io(err: std::io::Error) {
16            from()
17        }
18        Git(err: git2::Error) {
19            from()
20        }
21        MissingEnvVar {
22        }
23    }
24}
25
26
27fn same_content_as<P: AsRef<Path>>(path: P, content: &str) -> Result<bool, Error> {
28
29    let mut f = try!(File::open(path));
30    let mut current = String::new();
31    try!(f.read_to_string(&mut current));
32
33    Ok(current == content)
34}
35
36pub fn write_version <P: AsRef<Path>>(topdir: P) -> Result<(), Error> {
37    let path = try!(env::var_os("OUT_DIR").ok_or(Error::MissingEnvVar));
38    let path : &Path = path.as_ref();
39
40    try!(create_dir_all(path));
41
42    let path = path.join("version.rs");
43
44    let repo = try!(Repository::discover(topdir));
45    let desc = try!(repo.describe(&DescribeOptions::new().describe_tags().show_commit_oid_as_fallback(true)));
46
47
48    let content = format!("static VERSION: &'static str = {:?};\n", try!(desc.format(None)));
49
50    let is_fresh = if path.exists() {
51        try!(same_content_as(&path, &content))
52    } else {
53        false
54    };
55
56    if !is_fresh {
57      let mut file = BufWriter::new(try!(File::create(&path)));
58
59      try!(write!(file, "{}", content));
60    }
61    Ok(())
62}
63
64#[test]
65fn test() {
66    write_version(".").expect("write version");
67}