Skip to content

Commit

Permalink
cli version: Show date as part of the version next to the commit id
Browse files Browse the repository at this point in the history
The date comes from the commiter date of the commit. This is so that
it's easy to tell at a glance how old a version is.

To make it easier to get UTC date, we first obtain it as a Unix
timestamp, which should always be UTC. This will make the
interaction with Nix in a subsequent commit easier.
  • Loading branch information
ilyagr committed Jun 2, 2024
1 parent b1e5ca5 commit 0288cf6
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 10 deletions.
1 change: 1 addition & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ name = "runner"

[build-dependencies]
cargo_metadata = { workspace = true }
chrono = { workspace = true }

[dependencies]
chrono = { workspace = true }
Expand Down
46 changes: 37 additions & 9 deletions cli/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate chrono;

use std::path::Path;
use std::process::Command;
use std::str;

use cargo_metadata::MetadataCommand;
use chrono::prelude::*;

const GIT_HEAD_PATH: &str = "../.git/HEAD";
const JJ_OP_HEADS_PATH: &str = "../.jj/repo/op_heads/heads";
Expand All @@ -41,21 +44,44 @@ fn main() -> std::io::Result<()> {
}
println!("cargo:rerun-if-env-changed=NIX_JJ_GIT_HASH");

if let Some(git_hash) = get_git_hash() {
println!("cargo:rustc-env=JJ_VERSION={}-{}", version, git_hash);
// TODO: timestamp can be "nix"
if let Some((git_hash, maybe_date)) = get_git_timestamp_and_hash() {
println!(
"cargo:rustc-env=JJ_VERSION={}-{}-{}",
version,
maybe_date
.map(|d| d.format("%Y%m%d").to_string())
.unwrap_or_else(|| "dateunknown".to_string()),
git_hash
);
} else {
println!("cargo:rustc-env=JJ_VERSION={}", version);
}

Ok(())
}

fn get_git_hash() -> Option<String> {
/// Convert a string with a unix timestamp to a date
fn timestamp_to_date(ts_str: &str) -> Option<DateTime<Utc>> {
ts_str
.parse::<i64>()
.ok()
.and_then(|ts| DateTime::<Utc>::from_timestamp(ts, 0))
}

/// Return the git hash and the committer timestamp
fn get_git_timestamp_and_hash() -> Option<(String, Option<DateTime<Utc>>)> {
if let Some(nix_hash) = std::env::var("NIX_JJ_GIT_HASH")
.ok()
.filter(|s| !s.is_empty())
{
return Some(nix_hash);
return Some((nix_hash, None));
}

fn parse_timestamp_vbar_hash(bytes: &[u8]) -> (String, Option<DateTime<Utc>>) {
let s = str::from_utf8(bytes).unwrap().trim_end();
let (ts_str, id) = s.split_once('|').unwrap();
(id.to_owned(), timestamp_to_date(ts_str))
}
if let Ok(output) = Command::new("jj")
.args([
Expand All @@ -64,19 +90,21 @@ fn get_git_hash() -> Option<String> {
"log",
"--no-graph",
"-r=@-",
"-T=commit_id",
r#"-T=committer.timestamp().utc().format("%s") ++ "|" ++ commit_id"#,
])
.output()
{
if output.status.success() {
return Some(String::from_utf8(output.stdout).unwrap());
return Some(parse_timestamp_vbar_hash(&output.stdout));
}
}

if let Ok(output) = Command::new("git").args(["rev-parse", "HEAD"]).output() {
if let Ok(output) = Command::new("git")
.args(["log", "-1", "--format=%ct|%H", "HEAD"])
.output()
{
if output.status.success() {
let line = str::from_utf8(&output.stdout).unwrap();
return Some(line.trim_end().to_owned());
return Some(parse_timestamp_vbar_hash(&output.stdout));
}
}

Expand Down
4 changes: 3 additions & 1 deletion cli/tests/test_global_opts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ fn test_version() {
let sanitized = stdout.replace(|c: char| c.is_ascii_hexdigit(), "?");
let expected = [
"jj ?.??.?\n",
"jj ?.??.?-????????????????????????????????????????\n",
"jj ?.??.?-????????-????????????????????????????????????????\n",
// `dateunknown` turns into `??t?unknown` since d,a,e are hex digits.
"jj ?.??.?-??t?unknown-????????????????????????????????????????\n",
];
assert!(
expected.contains(&sanitized.as_str()),
Expand Down

0 comments on commit 0288cf6

Please sign in to comment.