This is an automated email from the ASF dual-hosted git repository.

spetz pushed a commit to branch banner
in repository https://gitbox.apache.org/repos/asf/iggy.git

commit ef94c4961bf0860e8b9bd3e6a90e98c4c0ff2b7e
Author: spetz <[email protected]>
AuthorDate: Mon Sep 7 15:34:59 2026 +0200

    chore: add Iggy banner to server startup
---
 core/server/src/banner.rs | 76 +++++++++++++++++++++++++++++++++++++++++++++++
 core/server/src/main.rs   |  2 ++
 2 files changed, 78 insertions(+)

diff --git a/core/server/src/banner.rs b/core/server/src/banner.rs
new file mode 100644
index 000000000..b383cbc07
--- /dev/null
+++ b/core/server/src/banner.rs
@@ -0,0 +1,76 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use std::env;
+use std::io::{self, IsTerminal, Write};
+
+use figlet_rs::FIGlet;
+
+const IGGY: &str = r"
+              ⢀⣀⣀⡀  ⢀⣀⣤⡤⠤⠤⠤⢶⣟⣛⠓⢦⡀
+           ⢀⡴⠛⢉⣉⣉⠉⠛⠚⠋⠁       ⠈⠙⢷⣽⡄
+          ⢀⡟⡠⢚⡽⠛⢿⣿⠟⠁  ⣀⣀⡀     ⡴⢾⢳⢳⡀
+         ⢀⡾  ⣼   ⠛   ⢸⣍⣷⠙     ⠹⡿⢠⣷⣿⣤⡀
+        ⣠⠞⠁⢀⣠⠟⠶⠶⣤⡀    ⠙⠋       ⠈⠻⣟⠛⠉
+        ⠉⠛⠛⠉⠁   ⢸⣧               ⣈⠱⣤
+                ⢸⡇⠳   ⣀⣀       ⢰⣫⣤⣤⣶⣷
+                ⣼⠃    ⢿⣻⣿⣦⣄⣀   ⠘⠿⠿⣿⡿⠓⢤⡀
+                ⣿   ⠑⢤⡈⢳⡝⢿⣿⣿⣿⣷⣶⠒⠒⠒⠋⠣⣄ ⠙⠢⡀
+                ⣿    ⠙⢿⣦⡙⠶⣿⣿⣿⣿⣿⣷⡄   ⠈⠳⣄ ⠈⢢⡀
+                ⣿     ⠈⢻⣿⣶⣌⠙⣟⠿⠿⣿⣿⡆    ⠈⠣⡀ ⠙⣄
+                ⡇       ⢻⣿⣿⡷⣼⣆⠘⣇⠁⣿      ⠙⣄ ⠈⢦
+             ⣀ ⢸⡇        ⢿⣿⣇ ⠉⠳⠶⠶⠋       ⠘⡆ ⠈⡆
+   ⢀⡞⠙⠲⢤⣀⣠⣤⣴⠟⠛⠻⣿⣤⣀       ⢸⡇⢿⡀    ⣀⣀⣀      ⢹  ⢹
+  ⢀⡞   ⢀⣾⠋ ⡀   ⠉⠉⢻⣧       ⣷⠘⣷⣠⣶⠿⠾⠟⠉⠙⢷⣤⣤⡀  ⡼  ⣸
+  ⢾⣐⠤⢄ ⢸⡏ ⡼ ⢀⡎  ⡀ ⣿⣀⣀     ⠸ ⢸⣿⠁       ⠙⣷⣀⡴⠁ ⢠⠇
+   ⠉⠙⠲⠮⣼⣇⢠⠇ ⣼  ⢸⠁⢠⡿ ⠉⠉⠛⠒⠶⠤⢤⣤⣼⡏ ⢸  ⢰  ⣧ ⢹⡇ ⢀⡴⠃
+        ⠙⢻⡀⢀⡇  ⣿⣤⣾⡃          ⣿ ⢸⡇ ⠘⡇ ⢸ ⣸⡧⠖⠉
+         ⠈⠻⠾⢷⣤⣾⠋⠉⠉⠉⠉⠛⠓⠒⠲⠶⠦⠤⠤⠤⠽⠷⣾⣇ ⢰⡇ ⣼⡶⠟
+             ⠉                  ⠻⣶⡾⠻⠿⠃
+";
+
+pub fn print(version: &str) {
+    let stdout = io::stdout();
+    if !stdout.is_terminal() || env::var_os("TERM").is_some_and(|term| term == 
"dumb") {
+        return;
+    }
+
+    let color = env::var_os("NO_COLOR").is_none_or(|value| value.is_empty());
+    let _ = render(&mut stdout.lock(), version, color);
+}
+
+fn render(output: &mut impl Write, version: &str, color: bool) -> 
io::Result<()> {
+    let wordmark = FIGlet::standard()
+        .ok()
+        .and_then(|font| font.convert("Iggy").map(|figure| figure.to_string()))
+        .unwrap_or_else(|| "Iggy".to_owned());
+    let width = wordmark.lines().map(str::len).max().unwrap_or_default();
+    let padding = 2 + 44_usize.saturating_sub(width) / 2;
+    let (orange, reset) = if color {
+        ("\x1b[38;5;208m", "\x1b[0m")
+    } else {
+        ("", "")
+    };
+
+    writeln!(output, "{IGGY}")?;
+    for line in wordmark.lines() {
+        writeln!(output, "{orange}{:padding$}{}{reset}", "", line.trim_end())?;
+    }
+    writeln!(output)?;
+    writeln!(output, "  {:^44}", format!("Apache Iggy v{version}"))?;
+    writeln!(output)
+}
diff --git a/core/server/src/main.rs b/core/server/src/main.rs
index 5706a3260..14d559272 100644
--- a/core/server/src/main.rs
+++ b/core/server/src/main.rs
@@ -18,6 +18,7 @@
 #![allow(clippy::future_not_send)]
 
 mod args;
+mod banner;
 
 use args::Args;
 use clap::Parser;
@@ -37,6 +38,7 @@ fn main() -> Result<(), ServerError> {
     // visible. `create_shard_executor` also reads its capacity knob from the
     // environment, which is why the `.env` load has to precede it.
     let args = Args::parse();
+    banner::print(server::VERSION);
     // `logging` owns the tracing appender worker guards; it must outlive the
     // shard threads or every log line after bootstrap is silently dropped.
     let mut logging = Logging::new(server::VERSION);

Reply via email to