forked from mirrors/jj
jj op log
: Show durations with relative timestamps
Before, the humanized versions of start and end times often were identical.
This commit is contained in:
parent
a48b4855be
commit
e32342a6c4
3 changed files with 33 additions and 30 deletions
|
@ -26,7 +26,7 @@ use clap::builder::NonEmptyStringValueParser;
|
|||
use clap::{ArgGroup, ArgMatches, CommandFactory, FromArgMatches, Subcommand};
|
||||
use config::Source;
|
||||
use itertools::Itertools;
|
||||
use jujutsu_lib::backend::{CommitId, ObjectId, Timestamp, TreeValue};
|
||||
use jujutsu_lib::backend::{CommitId, ObjectId, TreeValue};
|
||||
use jujutsu_lib::commit::Commit;
|
||||
use jujutsu_lib::dag_walk::topo_order_reverse;
|
||||
use jujutsu_lib::git::{GitFetchError, GitRefUpdate};
|
||||
|
@ -61,7 +61,7 @@ use crate::formatter::{Formatter, PlainTextFormatter};
|
|||
use crate::graphlog::{AsciiGraphDrawer, Edge};
|
||||
use crate::progress::Progress;
|
||||
use crate::template_parser::{
|
||||
format_absolute_timestamp, format_timestamp_relative_to_now, TemplateParser,
|
||||
format_absolute_timestamp, format_duration, format_timestamp_relative_to_now, TemplateParser,
|
||||
};
|
||||
use crate::templater::Template;
|
||||
use crate::ui::Ui;
|
||||
|
@ -3359,15 +3359,6 @@ fn cmd_op_log(
|
|||
struct OpTemplate {
|
||||
relative_timestamps: bool,
|
||||
}
|
||||
impl OpTemplate {
|
||||
fn format_timestamp(&self, timestamp: &Timestamp) -> String {
|
||||
if self.relative_timestamps {
|
||||
format_timestamp_relative_to_now(timestamp)
|
||||
} else {
|
||||
format_absolute_timestamp(timestamp)
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Template<Operation> for OpTemplate {
|
||||
fn format(&self, op: &Operation, formatter: &mut dyn Formatter) -> io::Result<()> {
|
||||
// TODO: Make this templated
|
||||
|
@ -3379,11 +3370,25 @@ fn cmd_op_log(
|
|||
})?;
|
||||
formatter.write_str(" ")?;
|
||||
formatter.with_label("time", |formatter| {
|
||||
formatter.write_str(&format!(
|
||||
"{} - {}",
|
||||
self.format_timestamp(&metadata.start_time),
|
||||
self.format_timestamp(&metadata.end_time)
|
||||
))
|
||||
formatter.write_str(
|
||||
&(if self.relative_timestamps {
|
||||
let mut f = timeago::Formatter::new();
|
||||
f.min_unit(timeago::TimeUnit::Microseconds).ago("");
|
||||
let mut duration =
|
||||
format_duration(&metadata.start_time, &metadata.end_time, &f);
|
||||
if duration == "now" {
|
||||
duration = "less than a microsecond".to_string()
|
||||
}
|
||||
let start = format_timestamp_relative_to_now(&metadata.start_time);
|
||||
format!("{start}, lasted {duration}",)
|
||||
} else {
|
||||
format!(
|
||||
"{} - {}",
|
||||
format_absolute_timestamp(&metadata.start_time),
|
||||
format_absolute_timestamp(&metadata.end_time)
|
||||
)
|
||||
}),
|
||||
)
|
||||
})?;
|
||||
formatter.write_str("\n")?;
|
||||
formatter.with_label("description", |formatter| {
|
||||
|
|
|
@ -123,20 +123,18 @@ pub fn format_absolute_timestamp(timestamp: &Timestamp) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn format_timestamp_relative_to_now(timestamp: &Timestamp) -> String {
|
||||
datetime_from_timestamp(timestamp)
|
||||
.and_then(|datetime| {
|
||||
let now = chrono::Local::now();
|
||||
|
||||
now.signed_duration_since(datetime).to_std().ok()
|
||||
})
|
||||
.map(|duration| {
|
||||
let f = timeago::Formatter::new();
|
||||
f.convert(duration)
|
||||
})
|
||||
pub fn format_duration(from: &Timestamp, to: &Timestamp, format: &timeago::Formatter) -> String {
|
||||
datetime_from_timestamp(from)
|
||||
.zip(datetime_from_timestamp(to))
|
||||
.and_then(|(from, to)| to.signed_duration_since(from).to_std().ok())
|
||||
.map(|duration| format.convert(duration))
|
||||
.unwrap_or_else(|| "<out-of-range date>".to_string())
|
||||
}
|
||||
|
||||
pub fn format_timestamp_relative_to_now(timestamp: &Timestamp) -> String {
|
||||
format_duration(timestamp, &Timestamp::now(), &timeago::Formatter::new())
|
||||
}
|
||||
|
||||
struct RelativeTimestampString;
|
||||
|
||||
impl TemplateProperty<Timestamp, String> for RelativeTimestampString {
|
||||
|
|
|
@ -44,12 +44,12 @@ fn test_op_log() {
|
|||
);
|
||||
let regex = Regex::new(r"\d\d years").unwrap();
|
||||
insta::assert_snapshot!(regex.replace_all(&stdout, "NN years"), @r###"
|
||||
@ 45108169c0f8 test-username@host.example.com NN years ago - NN years ago
|
||||
@ 45108169c0f8 test-username@host.example.com NN years ago, lasted less than a microsecond
|
||||
| describe commit 230dd059e1b059aefc0da06a2e5a7dbf22362f22
|
||||
| args: jj describe -m 'description 0'
|
||||
o a99a3fd5c51e test-username@host.example.com NN years ago - NN years ago
|
||||
o a99a3fd5c51e test-username@host.example.com NN years ago, lasted less than a microsecond
|
||||
| add workspace 'default'
|
||||
o 56b94dfc38e7 test-username@host.example.com NN years ago - NN years ago
|
||||
o 56b94dfc38e7 test-username@host.example.com NN years ago, lasted less than a microsecond
|
||||
initialize repo
|
||||
"###);
|
||||
let add_workspace_id = "a99a3fd5c51e";
|
||||
|
|
Loading…
Reference in a new issue