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}