just playing with tangled
1// Copyright 2023 The Jujutsu Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::path::Path;
16use std::process::Command;
17use std::str;
18
19use cargo_metadata::MetadataCommand;
20
21const GIT_HEAD_PATH: &str = "../.git/HEAD";
22const JJ_OP_HEADS_PATH: &str = "../.jj/repo/op_heads/heads";
23
24fn main() -> std::io::Result<()> {
25 let path = std::env::var("CARGO_MANIFEST_DIR").unwrap();
26 let meta = MetadataCommand::new()
27 .manifest_path("./Cargo.toml")
28 .current_dir(&path)
29 .exec()
30 .unwrap();
31 let root = meta.root_package().unwrap();
32 let version = &root.version;
33
34 if Path::new(GIT_HEAD_PATH).exists() {
35 // In colocated repo, .git/HEAD should reflect the working-copy parent.
36 println!("cargo:rerun-if-changed={GIT_HEAD_PATH}");
37 } else if Path::new(JJ_OP_HEADS_PATH).exists() {
38 // op_heads changes when working-copy files are mutated, which is way more
39 // frequent than .git/HEAD.
40 println!("cargo:rerun-if-changed={JJ_OP_HEADS_PATH}");
41 }
42 println!("cargo:rerun-if-env-changed=NIX_JJ_GIT_HASH");
43
44 if let Some(git_hash) = get_git_hash() {
45 println!("cargo:rustc-env=JJ_VERSION={}-{}", version, git_hash);
46 } else {
47 println!("cargo:rustc-env=JJ_VERSION={}", version);
48 }
49
50 Ok(())
51}
52
53fn get_git_hash() -> Option<String> {
54 if let Some(nix_hash) = std::env::var("NIX_JJ_GIT_HASH")
55 .ok()
56 .filter(|s| !s.is_empty())
57 {
58 return Some(nix_hash);
59 }
60 if let Ok(output) = Command::new("jj")
61 .args([
62 "--ignore-working-copy",
63 "--color=never",
64 "log",
65 "--no-graph",
66 "-r=@-",
67 "-T=commit_id",
68 ])
69 .output()
70 {
71 if output.status.success() {
72 return Some(String::from_utf8(output.stdout).unwrap());
73 }
74 }
75
76 if let Ok(output) = Command::new("git").args(["rev-parse", "HEAD"]).output() {
77 if output.status.success() {
78 let line = str::from_utf8(&output.stdout).unwrap();
79 return Some(line.trim_end().to_owned());
80 }
81 }
82
83 None
84}