Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package kubetui for openSUSE:Factory checked 
in at 2025-06-10 09:08:21
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/kubetui (Old)
 and      /work/SRC/openSUSE:Factory/.kubetui.new.19631 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "kubetui"

Tue Jun 10 09:08:21 2025 rev:11 rq:1284248 version:1.8.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/kubetui/kubetui.changes  2025-05-12 
16:51:26.999149055 +0200
+++ /work/SRC/openSUSE:Factory/.kubetui.new.19631/kubetui.changes       
2025-06-10 09:10:38.352714745 +0200
@@ -1,0 +2,40 @@
+Mon Jun 09 15:32:57 UTC 2025 - Johannes Kastl 
<opensuse_buildserv...@ojkastl.de>
+
+- Update to version 1.8.1:
+  * Fixed
+    - Updated README.md to document the --pod-columns feature
+      introduced in v1.8.0.
+      - Added usage examples for --pod-columns.
+      - Clarified behavior of the full keyword and required Name
+        column.
+    - No functional changes to the application.
+  * What's Changed
+    - Update docs by @sarub0b0 in #777
+- Update to version 1.8.0:
+  * Added
+    - --pod-columns flag to customize displayed pod columns
+      (name,status,age, etc.).
+    - Support for full keyword to show all available columns.
+    - ZSH/Bash completion for --pod-columns.
+    - Panic hook logging for better error traceability.
+  * Fixed
+    - Better error handling in internal column lookup logic.
+  * Dependencies
+    - Updated crates: flate2, clap, tokio, bitflags, ctrlc.
+  * What's Changed
+    - fix(deps): update rust crate clap to v4.5.38 by @renovate in
+      #768
+    - fix(deps): update rust crate ctrlc to v3.4.7 by @renovate in
+      #769
+    - fix(deps): update rust crate bitflags to v2.9.1 by @renovate
+      in #770
+    - fix(deps): update rust crate tokio to v1.45.1 by @renovate in
+      #773
+    - fix(deps): update rust crate clap to v4.5.39 by @renovate in
+      #774
+    - fix(deps): update rust crate flate2 to v1.1.2 by @renovate in
+      #775
+    - Add customizable pod columns via --pod-columns flag by
+      @sarub0b0 in #776
+
+-------------------------------------------------------------------

Old:
----
  kubetui-1.7.1.obscpio

New:
----
  kubetui-1.8.1.obscpio

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

Other differences:
------------------
++++++ kubetui.spec ++++++
--- /var/tmp/diff_new_pack.n7lQKb/_old  2025-06-10 09:10:41.592848730 +0200
+++ /var/tmp/diff_new_pack.n7lQKb/_new  2025-06-10 09:10:41.592848730 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           kubetui
-Version:        1.7.1
+Version:        1.8.1
 Release:        0
 Summary:        A terminal UI for Kubernetes
 License:        MIT

++++++ _service ++++++
--- /var/tmp/diff_new_pack.n7lQKb/_old  2025-06-10 09:10:41.640850716 +0200
+++ /var/tmp/diff_new_pack.n7lQKb/_new  2025-06-10 09:10:41.640850716 +0200
@@ -3,7 +3,7 @@
     <param name="url">https://github.com/sarub0b0/kubetui.git</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="scm">git</param>
-    <param name="revision">v1.7.1</param>
+    <param name="revision">v1.8.1</param>
     <param name="match-tag">*</param>
     <param name="versionrewrite-pattern">v(\d+\.\d+\.\d+)</param>
     <param name="versionrewrite-replacement">\1</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.n7lQKb/_old  2025-06-10 09:10:41.660851543 +0200
+++ /var/tmp/diff_new_pack.n7lQKb/_new  2025-06-10 09:10:41.664851709 +0200
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param 
name="url">https://github.com/sarub0b0/kubetui.git</param>
-              <param 
name="changesrevision">95db426560374d95073205adf48d22708c583063</param></service></servicedata>
+              <param 
name="changesrevision">09111b9d4a84f78b5153a3e156acda72a0eb938a</param></service></servicedata>
 (No newline at EOF)
 

++++++ kubetui-1.7.1.obscpio -> kubetui-1.8.1.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubetui-1.7.1/Cargo.lock new/kubetui-1.8.1/Cargo.lock
--- old/kubetui-1.7.1/Cargo.lock        2025-05-10 07:49:18.000000000 +0200
+++ new/kubetui-1.8.1/Cargo.lock        2025-06-08 19:42:14.000000000 +0200
@@ -181,9 +181,9 @@
 
 [[package]]
 name = "bitflags"
-version = "2.9.0"
+version = "2.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
+checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
 dependencies = [
  "serde",
 ]
@@ -268,9 +268,9 @@
 
 [[package]]
 name = "clap"
-version = "4.5.37"
+version = "4.5.39"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071"
+checksum = "fd60e63e9be68e5fb56422e397cf9baddded06dae1d2e523401542383bc72a9f"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -278,9 +278,9 @@
 
 [[package]]
 name = "clap_builder"
-version = "4.5.37"
+version = "4.5.39"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2"
+checksum = "89cc6392a1f72bbeb820d71f32108f61fdaf18bc526e1d23954168a67759ef51"
 dependencies = [
  "anstream",
  "anstyle",
@@ -474,9 +474,9 @@
 
 [[package]]
 name = "ctrlc"
-version = "3.4.6"
+version = "3.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "697b5419f348fd5ae2478e8018cb016c00a5881c7f46c717de98ffd135a5651c"
+checksum = "46f93780a459b7d656ef7f071fe699c4d3d2cb201c4b24d085b6ddc505276e73"
 dependencies = [
  "nix",
  "windows-sys 0.59.0",
@@ -624,7 +624,7 @@
 checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e"
 dependencies = [
  "libc",
- "windows-sys 0.59.0",
+ "windows-sys 0.52.0",
 ]
 
 [[package]]
@@ -661,9 +661,9 @@
 
 [[package]]
 name = "flate2"
-version = "1.1.1"
+version = "1.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece"
+checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d"
 dependencies = [
  "crc32fast",
  "miniz_oxide",
@@ -1246,7 +1246,7 @@
 
 [[package]]
 name = "kubetui"
-version = "1.7.1"
+version = "1.8.1"
 dependencies = [
  "anyhow",
  "arboard",
@@ -1453,9 +1453,9 @@
 
 [[package]]
 name = "nix"
-version = "0.29.0"
+version = "0.30.1"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
+checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
 dependencies = [
  "bitflags",
  "cfg-if",
@@ -2017,7 +2017,7 @@
  "errno",
  "libc",
  "linux-raw-sys 0.4.15",
- "windows-sys 0.59.0",
+ "windows-sys 0.52.0",
 ]
 
 [[package]]
@@ -2030,7 +2030,7 @@
  "errno",
  "libc",
  "linux-raw-sys 0.9.4",
- "windows-sys 0.59.0",
+ "windows-sys 0.52.0",
 ]
 
 [[package]]
@@ -2453,7 +2453,7 @@
  "getrandom 0.3.2",
  "once_cell",
  "rustix 1.0.7",
- "windows-sys 0.59.0",
+ "windows-sys 0.52.0",
 ]
 
 [[package]]
@@ -2534,9 +2534,9 @@
 
 [[package]]
 name = "tokio"
-version = "1.45.0"
+version = "1.45.1"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "2513ca694ef9ede0fb23fe71a4ee4107cb102b9dc1930f6d0fd77aae068ae165"
+checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779"
 dependencies = [
  "backtrace",
  "bytes",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubetui-1.7.1/Cargo.toml new/kubetui-1.8.1/Cargo.toml
--- old/kubetui-1.7.1/Cargo.toml        2025-05-10 07:49:18.000000000 +0200
+++ new/kubetui-1.8.1/Cargo.toml        2025-06-08 19:42:14.000000000 +0200
@@ -1,6 +1,6 @@
 [package]
 name = "kubetui"
-version = "1.7.1"
+version = "1.8.1"
 authors = ["kosay <ekr59u...@gmail.com>"]
 edition = "2021"
 license = "MIT"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubetui-1.7.1/README.md new/kubetui-1.8.1/README.md
--- old/kubetui-1.7.1/README.md 2025-05-10 07:49:18.000000000 +0200
+++ new/kubetui-1.8.1/README.md 2025-06-08 19:42:14.000000000 +0200
@@ -20,6 +20,8 @@
   - [Using `cargo install`](#using-cargo-install)
   - [Downloading the binary](#downloading-the-binary)
 - [Usage](#usage)
+  - [Pod Column Customization](#pod-column-customization)
+  - [Shell Completion](#shell-completion)
   - [Custom Configuration](#custom-configuration)
 - [Log Query](#log-query)
   - [Usage Example](#usage-example)
@@ -34,6 +36,7 @@
   - [Table View](#table-view)
   - [Dialog](#dialog)
   - [Input Form](#input-form)
+  - [Container Logs View](#container-logs-view)
 - [Contributing](#contributing)
 - [License](#license)
 
@@ -55,6 +58,7 @@
 - **Pods List and Container Logs**:
   - View a list of pods and their container logs.
   - JSON logs display mode switching: toggle between pretty print and 
single-line display using the <kbd>f</kbd> or <kbd>p</kbd> keys.
+  - **(new) Customizable pod columns**: Use `--pod-columns` to control which 
columns are shown in the pod table view. Supports comma-separated lists or 
`full` to show all columns.
 - **ConfigMap and Secret Watching**: Monitor ConfigMaps and secrets, and 
decode their data.
 - **Network-related Resources**: Explore a list of network-related resources 
and their descriptions.
 - **Events Watching**: Stay updated with a real-time view of Kubernetes events.
@@ -166,9 +170,25 @@
       --config-file <CONFIG_FILE>      Config file path
   -l, --logging                        Logging
   -n, --namespaces <NAMESPACES>        Namespaces (e.g. -n val1,val2,val3 | -n 
val1 -n val2 -n val3)
+      --pod-columns <POD_COLUMNS>      Comma-separated list of columns to show 
in pod table (e.g. name,status,ip). Use "full" to show all available columns 
[default: name,ready,status,age]
   -s, --split-direction <v|h>          Window split direction [default: v]
 ```
 
+### Pod Column Customization
+
+Use `--pod-columns` to customize the columns displayed in the pod table.
+
+- Specify columns using a comma-separated list:  
+  `--pod-columns=ready,status,age`
+
+- Use `full` to show all available columns:  
+  `--pod-columns=full`
+
+Notes:
+- The `Name` column is always included even if not specified.
+- The `full` keyword cannot be combined with other columns.
+
+
 ### Shell Completion
 
 Kubetui supports shell completion for Bash and Zsh. You can enable the 
completion by adding the following to your shell configuration file:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubetui-1.7.1/shell-completion/kubetui.bash 
new/kubetui-1.8.1/shell-completion/kubetui.bash
--- old/kubetui-1.7.1/shell-completion/kubetui.bash     2025-05-10 
07:49:18.000000000 +0200
+++ new/kubetui-1.8.1/shell-completion/kubetui.bash     2025-06-08 
19:42:14.000000000 +0200
@@ -14,6 +14,7 @@
                "-c" "--context"
                "-C" "--kubeconfig"
                "--config-file"
+               "--pod-columns"
                "-l" "--logging"
                "-n" "--namespaces"
                "-s" "--split-direction"
@@ -52,6 +53,10 @@
                COMPREPLY=($(compgen -f "${cur}"))
                return 0
                ;;
+       --pod-columns)
+               __kubetui_pod_columns "${cur}"
+               return 0
+               ;;
        esac
 
        COMPREPLY=($(compgen -W "${options[*]}" -- "${cur}"))
@@ -101,10 +106,91 @@
        __kubetui_get_kubernetes_resources "context"
 }
 
+__kubetui_pod_columns() {
+       local cur="$1"
+
+       local all_values=(name ready status restarts age ip node nominatednode 
readinessgates full)
+
+       local old_ifs="$IFS"
+       IFS=',' read -ra used <<<"$cur"
+       IFS="$old_ifs"
+
+       local last=""
+       if [[ "$cur" == *, ]]; then
+               last=""
+       elif [[ ${#used[@]} -gt 0 ]]; then
+               last="${used[${#used[@]} - 1]}"
+       fi
+
+       for u in "${used[@]}"; do
+               [[ "$u" == "full" ]] && return 0
+       done
+
+       # すでに何か指定済みの場合、候補から full を除外
+       if [[ ${#used[@]} -gt 1 || "$cur" == *,* ]]; then
+               local filtered=()
+               for val in "${all_values[@]}"; do
+                       [[ "$val" == "full" ]] && continue
+                       filtered+=("$val")
+               done
+               all_values=("${filtered[@]}")
+       fi
+
+       local candidates=()
+       for val in "${all_values[@]}"; do
+               local found=false
+               for u in "${used[@]}"; do
+                       [[ "$u" == "$val" ]] && {
+                               found=true
+                               break
+                       }
+               done
+               ! $found && candidates+=("$val")
+       done
+
+       COMPREPLY=($(compgen -W "${candidates[*]}" -- "$last"))
+
+       if [[ ${#used[@]} -gt 1 || "$cur" == *, ]]; then
+               __kubetui_debug "Used values: ${used[*]}, length: ${#used[@]}"
+               local -a prefix_parts
+               local last="${used[-1]}"
+               local exact_match=false
+               for v in "${all_values[@]}"; do
+                       if [[ "$v" == "$last" ]]; then
+                               exact_match=true
+                               break
+                       fi
+               done
+
+               if $exact_match; then
+                       prefix_parts=("${used[@]}")
+                       last=""
+               else
+                       prefix_parts=("${used[@]:0:${#used[@]}-1}")
+                       last="${used[-1]}"
+               fi
+
+               local old_ifs="$IFS"
+               IFS=,
+               local prefix="${prefix_parts[*]}"
+               IFS="$old_ifs"
+
+               __kubetui_debug "Prefix: '${prefix}'"
+               for i in "${!COMPREPLY[@]}"; do
+                       if [[ -n "$prefix" ]]; then
+                               COMPREPLY[$i]="${prefix},${COMPREPLY[$i]}"
+                       fi
+               done
+
+               __kubetui_debug "Updated COMPREPLY: ${COMPREPLY[*]}"
+       fi
+
+}
+
 if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || 
"${BASH_VERSINFO[0]}" -gt 4 ]]; then
        complete -F _kubetui -o nosort kubetui
 else
        complete -F _kubetui kubetui
 fi
 
-# ex: ts=4 sw=4 et filetype=sh
+# vim: ts=4 sw=4 sts=4 noet filetype=sh
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubetui-1.7.1/shell-completion/kubetui.zsh 
new/kubetui-1.8.1/shell-completion/kubetui.zsh
--- old/kubetui-1.7.1/shell-completion/kubetui.zsh      2025-05-10 
07:49:18.000000000 +0200
+++ new/kubetui-1.8.1/shell-completion/kubetui.zsh      2025-06-08 
19:42:14.000000000 +0200
@@ -30,6 +30,7 @@
         '(-h --help)'{-h,--help}'[Print help]'
         '(-V --version)'{-V,--version}'[Print version]'
         '(-A --all-namespaces)'\*{-n,--namespaces}'[Namespaces (e.g. -n 
val1,val2,val3 | -n val1 -n val2 -n val3)]:NAMESPACES:_sequence 
__kubetui_get_kubernetes_namespaces'
+        '--pod-columns[Comma-separated list of columns to show in pod table 
(e.g. name,status,ip). Use "full" to show all available 
columns.]:POD_COLUMNS:_sequence __kubetui_pod_columns'
         '--config-file[Config file path]:CONFIG_FILE:_files'
     )
 
@@ -86,6 +87,74 @@
     __kubetui_get_kubernetes_resources "context"
 }
 
+(( $+functions[__kubetui_pod_columns] )) ||
+__kubetui_pod_columns() {
+    local pod_columns_values=(
+        name
+        ready
+        status
+        restarts
+        age
+        ip
+        node
+        nominatednode
+        readinessgates
+    )
+
+    ## 入力済み値を取得(カンマで分割)
+    local cur="${words[CURRENT]##*,}"
+    local used=("${(s:,:)words[CURRENT]}")
+    local last_param="${used[-1]}"
+
+    __kubetui_debug "Current value: ${cur}"
+    __kubetui_debug "Used values: ${used[*]}, length: ${#used[@]}"
+    __kubetui_debug "Last parameter: ${last_param}"
+
+    # usedの要素数が0のときpod_columns_valuesにfullを追加
+    if [[ ${#used[@]} -eq 1 ]]; then
+        pod_columns_values+=("full")
+    fi
+
+    __kubetui_debug "Pod columns values: ${pod_columns_values[*]}"
+
+    # `full` が入っていたら補完を無効化
+    if [[ "${used[*]}" =~ "full" ]]; then
+        _message -e 'pod columns' "The 'full' option is already selected, no 
further columns can be added."
+        return
+    fi
+
+    # 候補にない値が入力さている場合は、処理を停止
+    if [[ -n "${cur}" && ! "${pod_columns_values[*]}" =~ "${cur}" ]]; then
+        _message -e 'pod columns' "Invalid pod column: '${cur}'."
+        return
+    fi
+
+    ## 補完候補リストから used を除外
+    local -a filtered_values=()
+    for val in "${pod_columns_values[@]}"; do
+        local is_used=false
+
+        for used_val in "${used[@]}"; do
+            if [[ "${val}" == "${used_val}" ]] && [[ "$last_param" != 
"${used_val}" ]]; then
+                is_used=true
+                break
+            fi
+        done
+
+        if [[ "${is_used}" == false ]]; then
+            filtered_values+=("${val}")
+        fi
+    done
+
+    __kubetui_debug "Filtered values: ${filtered_values[*]}"
+
+    if [[ -n "${filtered_values[*]}" ]]; then
+        _describe -t 'pod columns' 'pod columns' filtered_values
+    else
+        _message -e 'pod columns' "No more pod columns available to add."
+    fi
+}
+
 if [ "$funcstack[1]" = "_kubetui" ]; then
     _kubetui "$@"
 else
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubetui-1.7.1/src/app.rs new/kubetui-1.8.1/src/app.rs
--- old/kubetui-1.7.1/src/app.rs        2025-05-10 07:49:18.000000000 +0200
+++ new/kubetui-1.8.1/src/app.rs        2025-06-08 19:42:14.000000000 +0200
@@ -29,6 +29,7 @@
         let user_input = UserInput::new(tx_input.clone(), tx_shutdown.clone());
 
         kube_worker_config.pod_config = PodConfig::from(config.theme.clone());
+        kube_worker_config.pod_config.columns = cmd.pod_columns.columns;
         kube_worker_config.event_config = 
EventConfig::from(config.theme.clone());
         kube_worker_config.api_config = ApiConfig::from(config.theme.clone());
         kube_worker_config.apis_config = 
ApisConfig::from(config.theme.clone());
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubetui-1.7.1/src/cmd/args/pod_columns.rs 
new/kubetui-1.8.1/src/cmd/args/pod_columns.rs
--- old/kubetui-1.7.1/src/cmd/args/pod_columns.rs       1970-01-01 
01:00:00.000000000 +0100
+++ new/kubetui-1.8.1/src/cmd/args/pod_columns.rs       2025-06-08 
19:42:14.000000000 +0200
@@ -0,0 +1,222 @@
+use std::collections::HashMap;
+
+use anyhow::Result;
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct PodColumns {
+    pub columns: Vec<&'static str>,
+}
+
+impl PodColumns {
+    #[allow(dead_code)]
+    pub fn new(columns: impl IntoIterator<Item = &'static str>) -> Self {
+        Self {
+            columns: columns.into_iter().collect(),
+        }
+    }
+}
+
+const COLUMN_MAP: [(&str, &str); 9] = [
+    ("name", "Name"),
+    ("ready", "Ready"),
+    ("status", "Status"),
+    ("restarts", "Restarts"),
+    ("age", "Age"),
+    ("ip", "IP"),
+    ("node", "Node"),
+    ("nominatednode", "Nominated Node"),
+    ("readinessgates", "Readiness Gates"),
+];
+
+fn valid_columns() -> String {
+    COLUMN_MAP
+        .iter()
+        .map(|(k, _)| *k)
+        .collect::<Vec<&str>>()
+        .join(", ")
+}
+
+pub fn parse_pod_columns(input: &str) -> Result<PodColumns> {
+    let entries: Vec<&str> = input
+        .split(',')
+        .map(str::trim)
+        .filter(|s| !s.is_empty())
+        .collect();
+
+    if entries.is_empty() {
+        return Err(anyhow::anyhow!("Columns list must not be empty",));
+    }
+
+    let has_full = entries.iter().any(|e| normalize_column(e) == "full");
+    if has_full && entries.len() > 1 {
+        return Err(anyhow::anyhow!(
+            "Cannot specify 'full' with other columns. Use 'full' alone to get 
all columns."
+        ));
+    }
+
+    if entries.len() == 1 && has_full {
+        return Ok(PodColumns {
+            columns: COLUMN_MAP.iter().map(|(_, v)| *v).collect::<Vec<&str>>(),
+        });
+    }
+
+    let column_map: HashMap<&str, &str> = COLUMN_MAP.into_iter().collect();
+
+    let mut result = Vec::new();
+
+    for column in entries {
+        let normalized = normalize_column(column);
+
+        if let Some(&display_name) = column_map.get(normalized.as_str()) {
+            result.push(display_name);
+        } else {
+            return Err(anyhow::anyhow!(
+                "Invalid column name: {}. Valid options are: {}",
+                column,
+                valid_columns()
+            ));
+        }
+    }
+
+    if !result.contains(&"Name") {
+        result.insert(0, "Name");
+    }
+
+    Ok(PodColumns { columns: result })
+}
+
+fn normalize_column(column: &str) -> String {
+    column.to_lowercase().replace([' ', '_', '-'], "")
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    mod parse_pod_columns {
+        use super::*;
+        use pretty_assertions::assert_eq;
+
+        #[test]
+        fn 空文字列を渡すとパニックする() {
+            let input = "";
+            let result = parse_pod_columns(input);
+            assert!(result.is_err());
+        }
+
+        #[test]
+        fn フルを渡すと全カラムを返す() {
+            let input = "full";
+            let actual = parse_pod_columns(input).unwrap();
+            let expected: Vec<String> = COLUMN_MAP.iter().map(|(_, v)| 
v.to_string()).collect();
+            assert_eq!(actual.columns, expected);
+        }
+
+        #[test]
+        fn カンマ区切りのカラム名を渡すと対応するカラム名を返す() {
+            let input = "name, ready, status";
+            let actual = parse_pod_columns(input).unwrap();
+            let expected = vec!["Name", "Ready", "Status"];
+            assert_eq!(actual.columns, expected);
+        }
+
+        #[test]
+        fn カラム名に空白が含まれていても正しく処理される() {
+            let input = "  name ,  ready , status ";
+            let actual = parse_pod_columns(input).unwrap();
+            let expected = vec!["Name", "Ready", "Status"];
+            assert_eq!(actual.columns, expected);
+        }
+
+        #[test]
+        fn アンダースコアやハイフンを含むカラム名も正しく処理される() {
+            let input = "name, nominated_node, readiness-gates";
+            let actual = parse_pod_columns(input).unwrap();
+            let expected = vec!["Name", "Nominated Node", "Readiness Gates"];
+            assert_eq!(actual.columns, expected);
+        }
+
+        #[test]
+        fn 無効なカラム名が含まれているとエラーを返す() {
+            let input = "name, invalid_column";
+            let result = parse_pod_columns(input);
+            assert!(result.is_err());
+            assert_eq!(
+                result.unwrap_err().to_string(),
+                "Invalid column name: invalid_column. Valid options are: name, 
ready, status, restarts, age, ip, node, nominatednode, readinessgates"
+            );
+        }
+
+        #[test]
+        #[allow(non_snake_case)]
+        fn Nameカラムが常に含まれる() {
+            let input = "ready, status";
+            let actual = parse_pod_columns(input).unwrap();
+            assert!(actual.columns.contains(&"Name"));
+        }
+
+        #[test]
+        fn fullと他のカラムを同時に指定するとエラー() {
+            let input = "full, ready";
+            let result = parse_pod_columns(input);
+            assert!(result.is_err());
+            assert_eq!(
+                result.unwrap_err().to_string(),
+                "Cannot specify 'full' with other columns. Use 'full' alone to 
get all columns."
+            );
+        }
+
+        #[test]
+        #[allow(non_snake_case)]
+        fn full単体ならOK() {
+            let input = "full";
+            let actual = parse_pod_columns(input).unwrap();
+            let expected: Vec<&str> = COLUMN_MAP.iter().map(|(_, v)| 
*v).collect();
+            assert_eq!(actual.columns, expected);
+        }
+
+        #[test]
+        fn 空要素が含まれていても無視される() {
+            let input = "ready,,status";
+            let actual = parse_pod_columns(input).unwrap();
+            let expected = vec!["Name", "Ready", "Status"];
+            assert_eq!(actual.columns, expected);
+        }
+
+        #[test]
+        fn 空要素だけだとエラーになる() {
+            let input = ", , ";
+            let result = parse_pod_columns(input);
+            assert!(result.is_err());
+            assert_eq!(
+                result.unwrap_err().to_string(),
+                "Columns list must not be empty"
+            );
+        }
+    }
+
+    mod normalize_column {
+        use super::*;
+
+        #[test]
+        fn 空白を削除して小文字に変換する() {
+            let name = "  Name  ";
+            let actual = normalize_column(name);
+            assert_eq!(actual, "name");
+        }
+
+        #[test]
+        fn アンダースコアを削除して小文字に変換する() {
+            let name = "Nominated_Node";
+            let actual = normalize_column(name);
+            assert_eq!(actual, "nominatednode");
+        }
+
+        #[test]
+        fn ハイフンを削除して小文字に変換する() {
+            let name = "Readiness-Gates";
+            let actual = normalize_column(name);
+            assert_eq!(actual, "readinessgates");
+        }
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubetui-1.7.1/src/cmd/args.rs 
new/kubetui-1.8.1/src/cmd/args.rs
--- old/kubetui-1.7.1/src/cmd/args.rs   2025-05-10 07:49:18.000000000 +0200
+++ new/kubetui-1.8.1/src/cmd/args.rs   2025-06-08 19:42:14.000000000 +0200
@@ -1,5 +1,7 @@
 mod all_namespaces;
+mod pod_columns;
 mod split_direction;
 
 pub use all_namespaces::*;
+pub use pod_columns::*;
 pub use split_direction::*;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubetui-1.7.1/src/cmd/command.rs 
new/kubetui-1.8.1/src/cmd/command.rs
--- old/kubetui-1.7.1/src/cmd/command.rs        2025-05-10 07:49:18.000000000 
+0200
+++ new/kubetui-1.8.1/src/cmd/command.rs        2025-06-08 19:42:14.000000000 
+0200
@@ -6,7 +6,7 @@
 use crate::{config::ConfigLoadOption, workers::kube::KubeWorkerConfig};
 
 use super::{
-    args::{AllNamespaces, SplitDirection},
+    args::{parse_pod_columns, AllNamespaces, PodColumns, SplitDirection},
     SubCommand,
 };
 
@@ -74,6 +74,14 @@
     #[arg(long, display_order = 1000)]
     pub config_file: Option<PathBuf>,
 
+    /// Comma-separated list of columns to show in pod table (e.g. 
name,status,ip). Use "full" to show all available columns.
+    #[arg(
+        long,
+        value_parser = parse_pod_columns,
+        default_value = "name,ready,status,age",
+        display_order = 1000)]
+    pub pod_columns: PodColumns,
+
     #[command(subcommand)]
     pub subcommand: Option<SubCommand>,
 }
@@ -246,4 +254,47 @@
             assert_eq!(cmd.unwrap_err().kind(), ErrorKind::ArgumentConflict)
         }
     }
+
+    mod pod_columns {
+        use pretty_assertions::assert_eq;
+
+        use crate::features::pod::kube::POD_DEFAULT_COLUMNS;
+
+        use super::*;
+
+        #[test]
+        fn デフォルトのカラムを設定する() {
+            let cmd = Command::try_parse_from(["kubetui"]).unwrap();
+            assert_eq!(cmd.pod_columns, PodColumns::new(POD_DEFAULT_COLUMNS));
+        }
+
+        #[test]
+        fn フルを設定すると全カラムを設定する() {
+            let cmd = Command::try_parse_from(["kubetui", 
"--pod-columns=full"]).unwrap();
+            assert_eq!(
+                cmd.pod_columns,
+                PodColumns::new([
+                    "Name",
+                    "Ready",
+                    "Status",
+                    "Restarts",
+                    "Age",
+                    "IP",
+                    "Node",
+                    "Nominated Node",
+                    "Readiness Gates"
+                ])
+            );
+        }
+
+        #[test]
+        fn カンマ区切りでカラムを指定できる() {
+            let cmd =
+                Command::try_parse_from(["kubetui", 
"--pod-columns=name,ready,status"]).unwrap();
+            assert_eq!(
+                cmd.pod_columns,
+                PodColumns::new(["Name", "Ready", "Status"])
+            );
+        }
+    }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubetui-1.7.1/src/config/theme.rs 
new/kubetui-1.8.1/src/config/theme.rs
--- old/kubetui-1.7.1/src/config/theme.rs       2025-05-10 07:49:18.000000000 
+0200
+++ new/kubetui-1.8.1/src/config/theme.rs       2025-06-08 19:42:14.000000000 
+0200
@@ -114,6 +114,7 @@
                     style: hi.style.into(),
                 })
                 .collect(),
+            ..Default::default()
         }
     }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubetui-1.7.1/src/features/network/kube/network.rs 
new/kubetui-1.8.1/src/features/network/kube/network.rs
--- old/kubetui-1.7.1/src/features/network/kube/network.rs      2025-05-10 
07:49:18.000000000 +0200
+++ new/kubetui-1.8.1/src/features/network/kube/network.rs      2025-06-08 
19:42:14.000000000 +0200
@@ -340,7 +340,7 @@
 ) -> Result<Vec<NetworkTableRow>> {
     let table = kind.fetch_table(client, ns).await?;
 
-    let indexes = table.find_indexes(target_columns);
+    let indexes = table.find_indexes(target_columns)?;
 
     let rows = table
         .rows
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubetui-1.7.1/src/features/pod/kube/pod.rs 
new/kubetui-1.8.1/src/features/pod/kube/pod.rs
--- old/kubetui-1.7.1/src/features/pod/kube/pod.rs      2025-05-10 
07:49:18.000000000 +0200
+++ new/kubetui-1.8.1/src/features/pod/kube/pod.rs      2025-06-08 
19:42:14.000000000 +0200
@@ -19,9 +19,12 @@
     workers::kube::{message::Kube, SharedTargetNamespaces, Worker, 
WorkerResult},
 };
 
+pub const POD_DEFAULT_COLUMNS: [&str; 4] = ["Name", "Ready", "Status", "Age"];
+
 #[derive(Debug, Clone)]
 pub struct PodConfig {
     pub pod_highlight_rules: Vec<PodHighlightRule>,
+    pub columns: Vec<&'static str>,
 }
 
 impl Default for PodConfig {
@@ -37,6 +40,7 @@
                     style: Style::default().fg(Color::Red),
                 },
             ],
+            columns: POD_DEFAULT_COLUMNS.into_iter().collect(),
         }
     }
 }
@@ -99,18 +103,19 @@
 
         let ok_only: Vec<KubeTableRow> = jobs?.into_iter().flatten().collect();
 
+        let mut display_columns: Vec<String> = self
+            .config
+            .columns
+            .iter()
+            .map(|col| col.to_uppercase())
+            .collect();
+
+        if namespaces.len() != 1 {
+            display_columns.insert(0, "NAMESPACE".to_string());
+        }
+
         let mut table = KubeTable {
-            header: if namespaces.len() == 1 {
-                ["NAME", "READY", "STATUS", "AGE"]
-                    .iter()
-                    .map(ToString::to_string)
-                    .collect()
-            } else {
-                ["NAMESPACE", "NAME", "READY", "STATUS", "AGE"]
-                    .iter()
-                    .map(ToString::to_string)
-                    .collect()
-            },
+            header: display_columns,
             ..Default::default()
         };
 
@@ -124,25 +129,38 @@
         namespaces: &[String],
     ) -> Result<Vec<Vec<KubeTableRow>>> {
         let insert_ns = insert_ns(namespaces);
+
+        let name_index = self
+            .config
+            .columns
+            .iter()
+            .position(|&col| col == "Name")
+            .expect("Name column must be present in pod columns");
+
+        let status_index = self.config.columns.iter().position(|&col| col == 
"Status");
+
         try_join_all(namespaces.iter().map(|ns| {
             get_resource_per_namespace(
                 &self.kube_client,
                 format!("api/v1/namespaces/{}/{}", ns, "pods"),
-                &["Name", "Ready", "Status", "Age"],
+                self.config.columns.as_slice(),
                 move |row: &TableRow, indexes: &[usize]| {
                     let mut row: Vec<String> =
                         indexes.iter().map(|i| 
row.cells[*i].to_string()).collect();
 
-                    let name = row[0].clone();
+                    let name = row[name_index].clone();
 
-                    let status = row[2].as_str();
+                    let color = if let Some(index) = status_index {
+                        let status = row[index].as_str();
 
-                    let color = self
-                        .config
-                        .pod_highlight_rules
-                        .iter()
-                        .find(|rule| rule.status_regex.is_match(status))
-                        .map(|rule| style_to_ansi(rule.style));
+                        self.config
+                            .pod_highlight_rules
+                            .iter()
+                            .find(|rule| rule.status_regex.is_match(status))
+                            .map(|rule| style_to_ansi(rule.style))
+                    } else {
+                        None
+                    };
 
                     if insert_ns {
                         row.insert(0, ns.to_string())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubetui-1.7.1/src/kube/apis/v1_table.rs 
new/kubetui-1.8.1/src/kube/apis/v1_table.rs
--- old/kubetui-1.7.1/src/kube/apis/v1_table.rs 2025-05-10 07:49:18.000000000 
+0200
+++ new/kubetui-1.8.1/src/kube/apis/v1_table.rs 2025-06-08 19:42:14.000000000 
+0200
@@ -164,11 +164,29 @@
             .position(|cd| cd.name == target)
     }
 
-    pub fn find_indexes(&self, targets: &[&str]) -> Vec<usize> {
-        targets
-            .iter()
-            .filter_map(|target| self.find_index(target))
-            .collect()
+    pub fn find_indexes(&self, targets: &[&str]) -> Result<Vec<usize>> {
+        let mut ret = Vec::with_capacity(targets.len());
+
+        for target in targets {
+            if let Some(index) = self.find_index(target) {
+                ret.push(index);
+            } else {
+                let cols = self
+                    .column_definitions
+                    .iter()
+                    .map(|cd| cd.name.as_str())
+                    .collect::<Vec<&str>>()
+                    .join(", ");
+
+                anyhow::bail!(
+                    "Column '{}' not found in table. Available columns: {}",
+                    target,
+                    cols
+                );
+            }
+        }
+
+        Ok(ret)
     }
 
     #[allow(dead_code)]
@@ -317,11 +335,30 @@
 
             let targets = vec!["A", "B", "C", "D"];
 
-            assert_eq!(table.find_indexes(&targets), vec![0, 1, 2, 3]);
+            assert_eq!(table.find_indexes(&targets).unwrap(), vec![0, 1, 2, 
3]);
+        }
+
+        #[test]
+        fn indexes_with_error() {
+            let table = Table {
+                type_meta: Default::default(),
+                metadata: Default::default(),
+                column_definitions: vec![
+                    TableColumnDefinition {
+                        name: "A".to_string(),
+                        ..Default::default()
+                    },
+                    TableColumnDefinition {
+                        name: "B".to_string(),
+                        ..Default::default()
+                    },
+                ],
+                rows: Default::default(),
+            };
 
-            let targets = vec!["A", "B", "E"];
+            let targets = vec!["A", "B", "C"];
 
-            assert_eq!(table.find_indexes(&targets), vec![0, 1]);
+            assert!(table.find_indexes(&targets).is_err());
         }
     }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubetui-1.7.1/src/kube/table.rs 
new/kubetui-1.8.1/src/kube/table.rs
--- old/kubetui-1.7.1/src/kube/table.rs 2025-05-10 07:49:18.000000000 +0200
+++ new/kubetui-1.8.1/src/kube/table.rs 2025-06-08 19:42:14.000000000 +0200
@@ -84,7 +84,7 @@
 {
     let table: Table = client.table_request(&path).await?;
 
-    let indexes = table.find_indexes(target_values);
+    let indexes = table.find_indexes(target_values)?;
 
     Ok(table
         .rows
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubetui-1.7.1/src/message.rs 
new/kubetui-1.8.1/src/message.rs
--- old/kubetui-1.7.1/src/message.rs    2025-05-10 07:49:18.000000000 +0200
+++ new/kubetui-1.8.1/src/message.rs    2025-06-08 19:42:14.000000000 +0200
@@ -49,6 +49,8 @@
         let default_hook = panic::take_hook();
 
         panic::set_hook(Box::new(move |info| {
+            logger!(error, "{}", info);
+
             $t;
 
             default_hook(info);

++++++ kubetui.obsinfo ++++++
--- /var/tmp/diff_new_pack.n7lQKb/_old  2025-06-10 09:10:42.136871227 +0200
+++ /var/tmp/diff_new_pack.n7lQKb/_new  2025-06-10 09:10:42.140871392 +0200
@@ -1,5 +1,5 @@
 name: kubetui
-version: 1.7.1
-mtime: 1746856158
-commit: 95db426560374d95073205adf48d22708c583063
+version: 1.8.1
+mtime: 1749404534
+commit: 09111b9d4a84f78b5153a3e156acda72a0eb938a
 

++++++ vendor.tar.zst ++++++
/work/SRC/openSUSE:Factory/kubetui/vendor.tar.zst 
/work/SRC/openSUSE:Factory/.kubetui.new.19631/vendor.tar.zst differ: char 7, 
line 1

Reply via email to