Skip to content

Commit 8fe1670

Browse files
committed
fix(build): try to fix version numbering in release builds
On Windows, I was getting: $ cargo install gloam ... $ gloam --version gloam 0.1.7 But on Linux: $ cargo install gloam ... $ gloam --version gloam 6910508 Which *is* the right SHA, but it failed to resolve the tag properly for whatever reason. Going to try removing `--always` and see if we get something more valid. Signed-off-by: Steven Noonan <steven@uplinklabs.net>
1 parent 6910508 commit 8fe1670

1 file changed

Lines changed: 36 additions & 14 deletions

File tree

build.rs

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,38 @@ fn git_ok(repo_dir: &Path, args: &[&str]) -> Option<bool> {
4242
.map(|o| o.status.success())
4343
}
4444

45-
/// Walk up from `start` looking for `.git` (file or directory).
46-
/// Returns the directory *containing* `.git`, not `.git` itself.
47-
fn find_repo_root(start: &Path) -> Option<PathBuf> {
48-
let mut dir = start.to_path_buf();
49-
loop {
50-
let candidate = dir.join(".git");
51-
if candidate.exists() {
52-
return Some(dir);
53-
}
54-
if !dir.pop() {
55-
return None;
56-
}
45+
/// Find the git repo root for the crate being built.
46+
///
47+
/// Uses `git rev-parse --show-toplevel` from CARGO_MANIFEST_DIR, which
48+
/// lets git itself determine whether we're inside a repo. This avoids
49+
/// the problem of manually walking up the directory tree and accidentally
50+
/// finding an unrelated `.git` in a parent directory (e.g. when
51+
/// `cargo install` extracts into `~/.cargo/registry/src/` and some
52+
/// ancestor has a `.git`).
53+
///
54+
/// Returns None if git isn't installed, we're not in a repo (crates.io
55+
/// tarball), or the detected repo root isn't an ancestor of our manifest
56+
/// directory (sanity check).
57+
fn find_repo_root(manifest_dir: &Path) -> Option<PathBuf> {
58+
let toplevel = git(manifest_dir, &["rev-parse", "--show-toplevel"])?;
59+
let root = PathBuf::from(&toplevel);
60+
61+
// Sanity check: the manifest dir must be inside the detected repo.
62+
// This guards against pathological setups where a completely unrelated
63+
// git repo contains our extraction directory.
64+
let canonical_root = root.canonicalize().unwrap_or_else(|_| root.clone());
65+
let canonical_manifest = manifest_dir
66+
.canonicalize()
67+
.unwrap_or_else(|_| manifest_dir.to_path_buf());
68+
if !canonical_manifest.starts_with(&canonical_root) {
69+
println!(
70+
"cargo:warning=build.rs: git toplevel {:?} is not an ancestor of manifest dir {:?}, ignoring",
71+
canonical_root, canonical_manifest
72+
);
73+
return None;
5774
}
75+
76+
Some(root)
5877
}
5978

6079
/// Write `contents` to `path`, but only if the file doesn't already exist
@@ -139,8 +158,11 @@ fn main() {
139158
Some(ref root) => (
140159
// --tags: match lightweight tags too (not just annotated).
141160
// --dirty: append "-dirty" if the worktree has uncommitted changes.
142-
// --always: fall back to abbreviated SHA if no tag is reachable.
143-
git(root, &["describe", "--tags", "--dirty", "--always"]),
161+
// Deliberately no --always: if no tag is reachable (shallow
162+
// clone, tags not fetched), we want this to fail so we fall
163+
// through to the PKG_VERSION+sha format instead of emitting
164+
// a bare SHA as the version string.
165+
git(root, &["describe", "--tags", "--dirty"]),
144166
git(root, &["rev-parse", "HEAD"]),
145167
git(root, &["rev-parse", "--short", "HEAD"]),
146168
git(root, &["symbolic-ref", "--short", "-q", "HEAD"]),

0 commit comments

Comments
 (0)