Help debugging build.rs that fails only on travis-ci

I'd love to hear suggestions as to how to debug my build.rs script which fails on travis-ci. It's relatively simple. One part does some C compiling with the gcc crate (and probably works fine), but the other bit tries to use git to create a module storing version information. It works fine for me (on two different versions of Debian), but fails on travis. Here is the code:

use std::process::Command;
use std::io::{Write};

fn main() {
    let mut stat = Command::new("git")
        .args(&["describe", "--dirty"])
        .output().expect("unable to call git describe?");
    if !stat.status.success() || stat.stdout.len() < 5 {
        stat = Command::new("git")
            .args(&["revparse", "HEAD"])
            .output().expect("unable to call git revparse?");
    }

    let mut version = stat.stdout;
    if version.len() > 1 {
        let newlen = version.len()-1;
        version.truncate(newlen);
    }
    if version.len() < 5 {
        version.extend(b"(unknown version)");
    }

    // The following attempts to atomically create version.rs, in case
    // two cargos are running simultaneously.  Rust does not document
    // rename as atomic, but on posix systems it currently is.
    {
        let mut file = std::fs::File::create("src/version.rs~").expect("error creating version.rs");
        file.write(b"/// The version of fac\npub static VERSION: &'static str = \"")
            .expect("error writing to file");
        file.write(&version).expect("error writing to file");
        file.write(b"\";\n").expect("error writing to file");
    }
    std::fs::rename("src/version.rs~", "src/version.rs")
        .expect("failed to rename version.rs");
}

Travis fails with:

thread 'main' panicked at 'unable to call git describe?: Error { repr: Os { code: 2, message: "No such file or directory" } }', /checkout/src/libcore/result.rs:859

but I'm puzzled. I've verified that git is in the path, so I can't see what file or directory git describe could have failed to find. Any suggestions as to what might be wrong? Or can any of you suggest a better way to extract git version information for a detailed --version flag?

Here is the travis output:

and a link to the actual build script I used (which has a few debug prints):
https://github.com/droundy/fac/blob/master/build.rs

It definitely seems like it's git not being on the PATH, that's the only file that seem like they will be being opened in Rust during that call, you would get a different error message if it's git itself that can't find some file path. If you have checked the path and ensured that it's available then I'm not sure what's happening.

One alternative would be to use libgit2 via the git2 crate, it should be relatively simple to do the same commands via that.

I've avoided the git2 crate because I feel like a dependency on the git executable is more friendly to users than a dependency on libgit2. I suppose for CI a simple workaround is to simply report the version as unknown and move on... although actually that's not very good, as I've got a test that verifies the correctness of the version information!

Keep in mind that the git2 crate builds its own copy of libgit2, so users won't need to worry about tracking down a copy themselves.

I hadn't realized that, and may try it then.

It turns out the problem was caused by japaric/cross via trust. Switching to using cargo enabled the build to succeed. Not sure what was going on there, but it seemed like the filesystem was not even writeable.

1 Like