Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package erldash for openSUSE:Factory checked 
in at 2023-10-22 21:02:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/erldash (Old)
 and      /work/SRC/openSUSE:Factory/.erldash.new.1945 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "erldash"

Sun Oct 22 21:02:28 2023 rev:6 rq:1119420 version:0.2.0~0

Changes:
--------
--- /work/SRC/openSUSE:Factory/erldash/erldash.changes  2023-10-19 
22:52:02.232698607 +0200
+++ /work/SRC/openSUSE:Factory/.erldash.new.1945/erldash.changes        
2023-10-22 21:02:52.179493312 +0200
@@ -1,0 +2,8 @@
+Sun Oct 22 10:17:39 UTC 2023 - Michael Vetter <mvet...@suse.com>
+
+- Update to 0.2.0:
+  * Display current time in the top-right corner of the dashboard #7
+  * Add node name column to the header #8
+  * Introduce run and replay subcommands (breaking change) #9
+
+-------------------------------------------------------------------

Old:
----
  erldash-0.1.5~0.tar.xz

New:
----
  erldash-0.2.0~0.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ erldash.spec ++++++
--- /var/tmp/diff_new_pack.iw9L4L/_old  2023-10-22 21:02:53.235531711 +0200
+++ /var/tmp/diff_new_pack.iw9L4L/_new  2023-10-22 21:02:53.239531857 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           erldash
-Version:        0.1.5~0
+Version:        0.2.0~0
 Release:        0
 Summary:        A simple, terminal-based Erlang dashboard
 License:        (Apache-2.0 OR MIT) AND MIT AND Apache-2.0 WITH LLVM-exception 
AND MPL-2.0

++++++ _service ++++++
--- /var/tmp/diff_new_pack.iw9L4L/_old  2023-10-22 21:02:53.267532875 +0200
+++ /var/tmp/diff_new_pack.iw9L4L/_new  2023-10-22 21:02:53.271533020 +0200
@@ -3,7 +3,7 @@
     <param name="url">https://github.com/sile/erldash.git</param>
     <param name="versionformat">@PARENT_TAG@~@TAG_OFFSET@</param>
     <param name="scm">git</param>
-    <param name="revision">0.1.5</param>
+    <param name="revision">0.2.0</param>
     <param name="match-tag">*</param>
     <param name="versionrewrite-pattern">v(\d+\.\d+\.\d+)</param>
     <param name="versionrewrite-replacement">\1</param>

++++++ erldash-0.1.5~0.tar.xz -> erldash-0.2.0~0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/erldash-0.1.5~0/.github/workflows/release.yml 
new/erldash-0.2.0~0/.github/workflows/release.yml
--- old/erldash-0.1.5~0/.github/workflows/release.yml   2023-10-19 
04:24:59.000000000 +0200
+++ new/erldash-0.2.0~0/.github/workflows/release.yml   2023-10-21 
03:49:17.000000000 +0200
@@ -25,7 +25,7 @@
           draft: true
 
   linux-binary:
-    name: 'Uplaod Binary for Linux'
+    name: 'Upload Binary for Linux'
     runs-on: ubuntu-latest
     needs: github-release-draft
     steps:
@@ -59,7 +59,7 @@
           asset_content_type: application/octet-stream
 
   macos-binary:
-    name: 'Uplaod Binary for MacOS'
+    name: 'Upload Binary for MacOS'
     runs-on: macos-11 # TODO: Use `macos-latest` once it supports 
`aarch64-apple-darwin`
     needs: github-release-draft
     strategy:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/erldash-0.1.5~0/Cargo.lock 
new/erldash-0.2.0~0/Cargo.lock
--- old/erldash-0.1.5~0/Cargo.lock      2023-10-19 04:24:59.000000000 +0200
+++ new/erldash-0.2.0~0/Cargo.lock      2023-10-21 03:49:17.000000000 +0200
@@ -9,6 +9,21 @@
 checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
 
 [[package]]
+name = "android-tzdata"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
+
+[[package]]
+name = "android_system_properties"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
+dependencies = [
+ "libc",
+]
+
+[[package]]
 name = "anstream"
 version = "0.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -221,6 +236,12 @@
 ]
 
 [[package]]
+name = "bumpalo"
+version = "3.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
+
+[[package]]
 name = "byteorder"
 version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -233,12 +254,36 @@
 checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
 
 [[package]]
+name = "cc"
+version = "1.0.83"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
+dependencies = [
+ "libc",
+]
+
+[[package]]
 name = "cfg-if"
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
+name = "chrono"
+version = "0.4.31"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
+dependencies = [
+ "android-tzdata",
+ "iana-time-zone",
+ "js-sys",
+ "num-traits",
+ "serde",
+ "wasm-bindgen",
+ "windows-targets",
+]
+
+[[package]]
 name = "clap"
 version = "4.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -294,6 +339,12 @@
 ]
 
 [[package]]
+name = "core-foundation-sys"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
+
+[[package]]
 name = "crc32fast"
 version = "1.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -425,9 +476,10 @@
 
 [[package]]
 name = "erldash"
-version = "0.1.5"
+version = "0.2.0"
 dependencies = [
  "anyhow",
+ "chrono",
  "clap",
  "crossterm 0.27.0",
  "dirs",
@@ -612,6 +664,29 @@
 checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
 
 [[package]]
+name = "iana-time-zone"
+version = "0.1.58"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20"
+dependencies = [
+ "android_system_properties",
+ "core-foundation-sys",
+ "iana-time-zone-haiku",
+ "js-sys",
+ "wasm-bindgen",
+ "windows-core",
+]
+
+[[package]]
+name = "iana-time-zone-haiku"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
+dependencies = [
+ "cc",
+]
+
+[[package]]
 name = "instant"
 version = "0.1.12"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -638,6 +713,15 @@
 checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
 
 [[package]]
+name = "js-sys"
+version = "0.3.64"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
 name = "libc"
 version = "0.2.149"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -801,6 +885,12 @@
 ]
 
 [[package]]
+name = "once_cell"
+version = "1.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
+
+[[package]]
 name = "option-ext"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -1274,6 +1364,60 @@
 checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 
 [[package]]
+name = "wasm-bindgen"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
+
+[[package]]
 name = "winapi"
 version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -1305,6 +1449,15 @@
 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 
 [[package]]
+name = "windows-core"
+version = "0.51.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
 name = "windows-sys"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/erldash-0.1.5~0/Cargo.toml 
new/erldash-0.2.0~0/Cargo.toml
--- old/erldash-0.1.5~0/Cargo.toml      2023-10-19 04:24:59.000000000 +0200
+++ new/erldash-0.2.0~0/Cargo.toml      2023-10-21 03:49:17.000000000 +0200
@@ -1,6 +1,6 @@
 [package]
 name = "erldash"
-version = "0.1.5"
+version = "0.2.0"
 edition = "2021"
 authors = ["Takeru Ohta <phjgt...@gmail.com>"]
 license = "MIT OR Apache-2.0"
@@ -13,6 +13,7 @@
 
 [dependencies]
 anyhow = "1"
+chrono = { version = "0.4.31", features = ["serde"] }
 clap = { version = "4", features = ["derive"] }
 crossterm = "0.27"
 dirs = "5"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/erldash-0.1.5~0/README.md 
new/erldash-0.2.0~0/README.md
--- old/erldash-0.1.5~0/README.md       2023-10-19 04:24:59.000000000 +0200
+++ new/erldash-0.2.0~0/README.md       2023-10-21 03:49:17.000000000 +0200
@@ -32,7 +32,7 @@
 
 ```console
 // An example to download the binary for Linux.
-$ VERSION=...  # Set the target erldash version such as "0.1.2"
+$ VERSION=...  # Set the target erldash version such as "0.2.0"
 $ curl -L 
https://github.com/sile/erldash/releases/download/${VERSION}/erldash-${VERSION}.x86_64-unknown-linux-musl
 -o erldash
 $ chmod +x erldash
 $ ./erldash
@@ -54,9 +54,11 @@
 Just execute the following command:
 
 ```console
-$ erldash $TARGET_ERLANG_NODE
+$ erldash run $TARGET_ERLANG_NODE
 ```
 
 If you need to specify a cookie value other than `$HOME/.erlang.cookie`, 
please specify that to `--cookie` option.
 
 `$ erldash --help` shows the detailed help message.
+
+You can record the collected metrics to a file via `--record <FILE>` option 
and replay the recorded run using `$ erldash replay <FILE>` command.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/erldash-0.1.5~0/src/lib.rs 
new/erldash-0.2.0~0/src/lib.rs
--- old/erldash-0.1.5~0/src/lib.rs      2023-10-19 04:24:59.000000000 +0200
+++ new/erldash-0.2.0~0/src/lib.rs      2023-10-21 03:49:17.000000000 +0200
@@ -4,8 +4,17 @@
 pub mod metrics;
 pub mod ui;
 
-#[derive(Debug, Clone, clap::Parser)]
-pub struct Options {
+#[derive(Debug, Clone, clap::Subcommand)]
+pub enum Command {
+    /// Run the dashboard.
+    Run(RunArgs),
+
+    /// Replay a previously recorded dashboard session.
+    Replay(ReplayArgs),
+}
+
+#[derive(Debug, Clone, clap::Args)]
+pub struct RunArgs {
     /// Target Erlang node name.
     pub erlang_node: erl_dist::node::NodeName,
 
@@ -22,13 +31,9 @@
     /// If specified, the collected metrics will be recorded to the given file 
and can be replayed later.
     #[clap(long, value_name = "FILE")]
     pub record: Option<PathBuf>,
-
-    /// If specified, the recorded metrics will be replayed.
-    #[clap(long, requires = "record")]
-    pub replay: bool,
 }
 
-impl Options {
+impl RunArgs {
     pub fn find_cookie(&self) -> anyhow::Result<String> {
         if let Some(cookie) = &self.cookie {
             Ok(cookie.clone())
@@ -37,3 +42,9 @@
         }
     }
 }
+
+#[derive(Debug, Clone, clap::Args)]
+pub struct ReplayArgs {
+    /// Path to a file containing recorded metrics.
+    pub file: PathBuf,
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/erldash-0.1.5~0/src/main.rs 
new/erldash-0.2.0~0/src/main.rs
--- old/erldash-0.1.5~0/src/main.rs     2023-10-19 04:24:59.000000000 +0200
+++ new/erldash-0.2.0~0/src/main.rs     2023-10-21 03:49:17.000000000 +0200
@@ -6,8 +6,8 @@
 #[derive(Debug, Parser)]
 #[clap(version)]
 struct Args {
-    #[clap(flatten)]
-    options: erldash::Options,
+    #[clap(subcommand)]
+    command: erldash::Command,
 
     #[clap(hide = true, long)]
     logfile: Option<std::path::PathBuf>,
@@ -23,7 +23,7 @@
     let args = Args::parse();
     setup_logger(&args)?;
 
-    let poller = metrics::MetricsPoller::start_thread(args.options)?;
+    let poller = metrics::MetricsPoller::start_thread(args.command)?;
     let app = ui::App::new(poller)?;
     app.run()?;
     Ok(())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/erldash-0.1.5~0/src/metrics.rs 
new/erldash-0.2.0~0/src/metrics.rs
--- old/erldash-0.1.5~0/src/metrics.rs  2023-10-19 04:24:59.000000000 +0200
+++ new/erldash-0.2.0~0/src/metrics.rs  2023-10-21 03:49:17.000000000 +0200
@@ -1,5 +1,5 @@
 use crate::erlang::{MSAccThread, RpcClient, SystemVersion};
-use crate::Options;
+use crate::{Command, ReplayArgs, RunArgs};
 use anyhow::Context;
 use serde::{Deserialize, Serialize};
 use smol::fs::File;
@@ -241,11 +241,10 @@
 }
 
 impl MetricsPoller {
-    pub fn start_thread(options: Options) -> anyhow::Result<Self> {
-        if options.replay {
-            ReplayMetricsPoller::new(options).map(Self::Replay)
-        } else {
-            RealtimeMetricsPoller::start_thread(options).map(Self::Realtime)
+    pub fn start_thread(command: Command) -> anyhow::Result<Self> {
+        match command {
+            Command::Run(args) => 
RealtimeMetricsPoller::start_thread(args).map(Self::Realtime),
+            Command::Replay(args) => 
ReplayMetricsPoller::new(args).map(Self::Replay),
         }
     }
 
@@ -253,10 +252,10 @@
         matches!(self, Self::Replay(_))
     }
 
-    pub fn system_version(&self) -> &SystemVersion {
+    pub fn header(&self) -> &Header {
         match self {
-            Self::Realtime(poller) => &poller.system_version,
-            Self::Replay(poller) => &poller.system_version,
+            Self::Realtime(poller) => &poller.header,
+            Self::Replay(poller) => &poller.header,
         }
     }
 
@@ -295,28 +294,33 @@
     }
 }
 
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct Header {
+    pub system_version: SystemVersion,
+    pub node_name: String,
+    pub start_time: chrono::DateTime<chrono::Local>,
+}
+
 #[derive(Debug)]
 pub struct ReplayMetricsPoller {
-    system_version: SystemVersion,
+    header: Header,
     metrics_log: Vec<Metrics>,
 }
 
 impl ReplayMetricsPoller {
-    fn new(options: Options) -> anyhow::Result<Self> {
-        let Some(record_file_path) = options.record else {
-            anyhow::bail!("`--record` is required for replay mode");
-        };
+    fn new(args: ReplayArgs) -> anyhow::Result<Self> {
+        let record_file_path = args.file;
         let file = std::fs::File::open(&record_file_path).with_context(|| {
             format!("failed to open record file: {}", 
record_file_path.display())
         })?;
         let reader = std::io::BufReader::new(file);
 
-        let mut system_version = None;
+        let mut header = None;
         let mut metrics_log = Vec::new();
         for (i, line) in reader.lines().enumerate() {
             let line = line?;
             if i == 0 {
-                system_version = Some(
+                header = Some(
                     serde_json::from_str(&line)
                         .with_context(|| format!("failed to parse record file: 
line={}", i + 1))?,
                 );
@@ -326,10 +330,9 @@
                 .with_context(|| format!("failed to parse record file: 
line={}", i + 1))?;
             metrics_log.push(metrics);
         }
-        let system_version =
-            system_version.ok_or_else(|| anyhow::anyhow!("record file is 
empty"))?;
+        let header = header.ok_or_else(|| anyhow::anyhow!("record file is 
empty"))?;
         Ok(Self {
-            system_version,
+            header,
             metrics_log,
         })
     }
@@ -338,14 +341,14 @@
 #[derive(Debug)]
 pub struct RealtimeMetricsPoller {
     rx: MetricsReceiver,
-    system_version: SystemVersion,
+    header: Header,
     rpc_client: RpcClient,
     old_microstate_accounting_flag: bool,
 }
 
 impl RealtimeMetricsPoller {
-    fn start_thread(options: Options) -> anyhow::Result<Self> {
-        MetricsPollerThread::start_thread(options)
+    fn start_thread(args: RunArgs) -> anyhow::Result<Self> {
+        MetricsPollerThread::start_thread(args)
     }
 }
 
@@ -366,22 +369,22 @@
 
 #[derive(Debug)]
 struct MetricsPollerThread {
-    options: Options,
+    args: RunArgs,
     rpc_client: RpcClient,
     tx: MetricsSender,
     prev_metrics: Metrics,
     start: Instant,
-    system_version: SystemVersion,
+    header: Header,
     record_file: Option<File>,
 }
 
 impl MetricsPollerThread {
-    fn start_thread(options: Options) -> anyhow::Result<RealtimeMetricsPoller> 
{
+    fn start_thread(args: RunArgs) -> anyhow::Result<RealtimeMetricsPoller> {
         let (tx, rx) = mpsc::channel();
 
         let rpc_client: RpcClient = smol::block_on(async {
-            let cookie = options.find_cookie()?;
-            let client = RpcClient::connect(&options.erlang_node, 
&cookie).await?;
+            let cookie = args.find_cookie()?;
+            let client = RpcClient::connect(&args.erlang_node, &cookie).await?;
             Ok(client) as anyhow::Result<_>
         })?;
         let system_version = smol::block_on(rpc_client.get_system_version())?;
@@ -391,14 +394,19 @@
             "enabled microstate accounting (old flag state is 
{old_microstate_accounting_flag})"
         );
 
+        let header = Header {
+            system_version: system_version.clone(),
+            node_name: args.erlang_node.to_string(),
+            start_time: chrono::Local::now(),
+        };
         let poller = RealtimeMetricsPoller {
             rx,
-            system_version: system_version.clone(),
+            header: header.clone(),
             rpc_client: rpc_client.clone(),
             old_microstate_accounting_flag,
         };
 
-        let record_file = if let Some(path) = &options.record {
+        let record_file = if let Some(path) = &args.record {
             Some(File::from(std::fs::File::create(path).with_context(
                 || format!("failed to record file {}", path.display()),
             )?))
@@ -409,12 +417,12 @@
         std::thread::spawn(|| {
             let start = Instant::now();
             Self {
-                options,
+                args,
                 rpc_client,
                 tx,
                 prev_metrics: Metrics::new(start),
                 start,
-                system_version,
+                header,
                 record_file,
             }
             .run()
@@ -433,10 +441,10 @@
     }
 
     fn run(mut self) {
-        let interval = Duration::from_secs(self.options.polling_interval.get() 
as u64);
+        let interval = Duration::from_secs(self.args.polling_interval.get() as 
u64);
         let mut next_time = Duration::from_secs(0);
         smol::block_on(async {
-            if let Err(e) = 
self.write_json_line(&self.system_version.clone()).await {
+            if let Err(e) = self.write_json_line(&self.header.clone()).await {
                 log::error!("faild to write record file: {e}");
                 return;
             }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/erldash-0.1.5~0/src/ui.rs 
new/erldash-0.2.0~0/src/ui.rs
--- old/erldash-0.1.5~0/src/ui.rs       2023-10-19 04:24:59.000000000 +0200
+++ new/erldash-0.2.0~0/src/ui.rs       2023-10-21 03:49:17.000000000 +0200
@@ -1,5 +1,4 @@
-use crate::erlang::SystemVersion;
-use crate::metrics::{format_u64, MetricValue, Metrics, MetricsPoller};
+use crate::metrics::{format_u64, Header, MetricValue, Metrics, MetricsPoller};
 use crossterm::event::{KeyCode, KeyEvent};
 use std::collections::{BTreeMap, VecDeque};
 use std::sync::mpsc;
@@ -32,11 +31,11 @@
         log::debug!("setup terminal");
 
         let replay_mode = poller.is_replay();
-        let system_version = poller.system_version().clone();
+        let header = poller.header().clone();
         Ok(Self {
             terminal,
             poller,
-            ui: UiState::new(system_version, replay_mode),
+            ui: UiState::new(header, replay_mode),
             replay_cursor_time: Duration::default(),
         })
     }
@@ -92,6 +91,7 @@
                     }
                     log::debug!("remove old metrics");
                 }
+                self.ui.elapsed = self.ui.start.elapsed();
                 self.render_ui()?;
             }
         }
@@ -186,18 +186,13 @@
         let time = self.replay_cursor_time;
 
         self.ui.history.clear();
+        self.ui.averages.clear();
         for metrics in self
             .poller
             .get_metrics_range(time, time + 
Duration::from_secs(CHART_DURATION))?
         {
             self.ui.history.push_back(metrics.clone());
-        }
 
-        self.ui.averages.clear();
-        for metrics in self.poller.get_metrics_range(
-            time.saturating_sub(Duration::from_secs(CHART_DURATION)),
-            time,
-        )? {
             for (name, item) in &metrics.items {
                 if let Some(avg) = self.ui.averages.get_mut(name) {
                     avg.add(item.clone());
@@ -209,6 +204,13 @@
             }
         }
 
+        self.ui.elapsed = self
+            .ui
+            .history
+            .back()
+            .map(|x| x.timestamp)
+            .unwrap_or_default();
+
         self.render_ui()?;
         Ok(())
     }
@@ -246,7 +248,8 @@
 #[derive(Debug)]
 struct UiState {
     start: Instant,
-    system_version: SystemVersion,
+    header: Header,
+    elapsed: Duration,
     pause: bool,
     history: VecDeque<Metrics>,
     averages: BTreeMap<String, AvgValue>,
@@ -257,10 +260,11 @@
 }
 
 impl UiState {
-    fn new(system_version: SystemVersion, replay_mode: bool) -> Self {
+    fn new(header: Header, replay_mode: bool) -> Self {
         Self {
             start: Instant::now(),
-            system_version,
+            header,
+            elapsed: Duration::default(),
             pause: false,
             history: VecDeque::new(),
             averages: BTreeMap::new(),
@@ -282,10 +286,35 @@
     }
 
     fn render_header(&mut self, f: &mut Frame, area: Rect) {
-        let paragraph = 
Paragraph::new(vec![Spans::from(self.system_version.get())])
+        let chunks = Layout::default()
+            .direction(Direction::Horizontal)
+            .constraints(
+                [
+                    Constraint::Percentage(20),
+                    Constraint::Percentage(60),
+                    Constraint::Percentage(20),
+                ]
+                .as_ref(),
+            )
+            .split(area);
+
+        let paragraph = 
Paragraph::new(vec![Spans::from(self.header.node_name.clone())])
+            .block(self.make_block("Node"))
+            .alignment(Alignment::Left);
+        f.render_widget(paragraph, chunks[0]);
+
+        let paragraph = 
Paragraph::new(vec![Spans::from(self.header.system_version.get())])
             .block(self.make_block("System Version"))
             .alignment(Alignment::Left);
-        f.render_widget(paragraph, area);
+        f.render_widget(paragraph, chunks[1]);
+
+        let now = self.header.start_time + self.elapsed;
+        let paragraph = Paragraph::new(vec![Spans::from(
+            now.to_rfc3339_opts(chrono::SecondsFormat::Secs, true),
+        )])
+        .block(self.make_block("Time"))
+        .alignment(Alignment::Left);
+        f.render_widget(paragraph, chunks[2]);
     }
 
     fn render_body(&mut self, f: &mut Frame, area: Rect) {
@@ -322,7 +351,7 @@
         let header = Row::new(header_cells).bottom_margin(1);
 
         let items = self.latest_metrics().root_items().collect::<Vec<_>>();
-        let is_avg_available = self.start.elapsed().as_secs() >= ONE_MINUTE;
+        let is_avg_available = self.elapsed.as_secs() >= (ONE_MINUTE - 1);
         let mut value_width = 0;
         let mut avg_width = 0;
         let mut row_items = Vec::with_capacity(items.len());

++++++ vendor.tar.xz ++++++
/work/SRC/openSUSE:Factory/erldash/vendor.tar.xz 
/work/SRC/openSUSE:Factory/.erldash.new.1945/vendor.tar.xz differ: char 25, 
line 1

Reply via email to