Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package kl for openSUSE:Factory checked in 
at 2026-04-18 21:38:56
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/kl (Old)
 and      /work/SRC/openSUSE:Factory/.kl.new.11940 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "kl"

Sat Apr 18 21:38:56 2026 rev:6 rq:1347856 version:0.9.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/kl/kl.changes    2026-04-13 23:19:47.754375395 
+0200
+++ /work/SRC/openSUSE:Factory/.kl.new.11940/kl.changes 2026-04-18 
21:38:57.675934541 +0200
@@ -1,0 +2,7 @@
+Fri Apr 17 20:02:02 UTC 2026 - Johannes Kastl 
<[email protected]>
+
+- Update to version 0.9.1:
+  * fix: keep terminated containers and logs until manually
+    deselected
+
+-------------------------------------------------------------------

Old:
----
  kl-0.9.0.obscpio

New:
----
  kl-0.9.1.obscpio

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

Other differences:
------------------
++++++ kl.spec ++++++
--- /var/tmp/diff_new_pack.i1BtJ1/_old  2026-04-18 21:38:58.731977786 +0200
+++ /var/tmp/diff_new_pack.i1BtJ1/_new  2026-04-18 21:38:58.735977950 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           kl
-Version:        0.9.0
+Version:        0.9.1
 Release:        0
 Summary:        An interactive Kubernetes log viewer for your terminal
 License:        MIT

++++++ _service ++++++
--- /var/tmp/diff_new_pack.i1BtJ1/_old  2026-04-18 21:38:58.771979425 +0200
+++ /var/tmp/diff_new_pack.i1BtJ1/_new  2026-04-18 21:38:58.775979588 +0200
@@ -3,7 +3,7 @@
     <param name="url">https://github.com/robinovitch61/kl.git</param>
     <param name="scm">git</param>
     <param name="exclude">.git</param>
-    <param name="revision">refs/tags/v0.9.0</param>
+    <param name="revision">refs/tags/v0.9.1</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="versionrewrite-pattern">v(.*)</param>
     <param name="changesgenerate">enable</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.i1BtJ1/_old  2026-04-18 21:38:58.799980571 +0200
+++ /var/tmp/diff_new_pack.i1BtJ1/_new  2026-04-18 21:38:58.807980899 +0200
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param 
name="url">https://github.com/robinovitch61/kl.git</param>
-              <param 
name="changesrevision">46461cf69f1c723ade8d5425567f4640eedb3ba4</param></service></servicedata>
+              <param 
name="changesrevision">6b0fe84afedeab1d40b5a82402a361eb07ba3152</param></service></servicedata>
 (No newline at EOF)
 

++++++ kl-0.9.0.obscpio -> kl-0.9.1.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kl-0.9.0/internal/app.go new/kl-0.9.1/internal/app.go
--- old/kl-0.9.0/internal/app.go        2026-04-13 04:18:04.000000000 +0200
+++ new/kl-0.9.1/internal/app.go        2026-04-13 20:13:48.000000000 +0200
@@ -958,8 +958,8 @@
                return m, nil
        }
 
-       var err error
        var newLogs []model.PageLog
+       var err error
        for i := range msg.NewLogs {
                shortName := k8s_model.ContainerNameAndPrefix{}
                if m.containerToShortName != nil {
@@ -1068,6 +1068,7 @@
                case entity.StopScannerKeepLogs:
                        cmds = append(cmds, command.StopLogScannerCmd(ent, 
true))
                case entity.RemoveEntity:
+                       m = m.removeLogsForContainer(ent.Container)
                        m.entityTree.Remove(ent)
                case entity.RemoveLogs:
                        m = m.removeLogsForContainer(ent.Container)
@@ -1101,16 +1102,13 @@
 }
 
 func (m Model) updateShortNamesInBuffer() (Model, error) {
-       bufferedLogs := m.pageLogBuffer
-       m.pageLogBuffer = nil
-       for i := range bufferedLogs {
-               short, err := 
m.containerToShortName(bufferedLogs[i].Log.Container)
+       for i := range m.pageLogBuffer {
+               shortName, err := 
m.containerToShortName(m.pageLogBuffer[i].Log.Container)
                if err != nil {
                        return m, err
                }
-               bufferedLogs[i].ContainerNames.Short = short
+               m.pageLogBuffer[i].ContainerNames.Short = shortName
        }
-       m.pageLogBuffer = bufferedLogs
        return m, nil
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kl-0.9.0/internal/k8s/entity/entity.go 
new/kl-0.9.1/internal/k8s/entity/entity.go
--- old/kl-0.9.0/internal/k8s/entity/entity.go  2026-04-13 04:18:04.000000000 
+0200
+++ new/kl-0.9.1/internal/k8s/entity/entity.go  2026-04-13 20:13:48.000000000 
+0200
@@ -165,7 +165,7 @@
                tree.AddOrReplace(e)
                return e, tree, []EntityAction{StopScanner}
        case Deleted:
-               return e, tree, []EntityAction{RemoveLogs, RemoveEntity}
+               return e, tree, []EntityAction{RemoveEntity}
        default:
                panic(fmt.Sprintf("Deactivate called for entity in %v state", 
e.State))
        }
@@ -194,24 +194,25 @@
        }()
        switch e.State {
        case Inactive:
-               tree.Remove(e)
-               return e, tree, []EntityAction{}
+               return e, tree, []EntityAction{RemoveEntity}
        case WantScanning:
                e.State = Deleted
                e.Container.Status = delta.Container.Status
                tree.AddOrReplace(e)
                return e, tree, []EntityAction{}
        case ScannerStarting:
-               tree.Remove(e)
-               return e, tree, []EntityAction{StopScanner}
+               return e, tree, []EntityAction{RemoveEntity, StopScanner}
        case Scanning:
                e.State = Deleted
                e.Container.Status = delta.Container.Status
                tree.AddOrReplace(e)
                return e, tree, []EntityAction{StopScannerKeepLogs, 
MarkLogsTerminated}
        case ScannerStopping:
-               tree.Remove(e)
-               return e, tree, []EntityAction{StopScanner}
+               return e, tree, []EntityAction{RemoveEntity}
+       case Deleted:
+               e.Container.Status = delta.Container.Status
+               tree.AddOrReplace(e)
+               return e, tree, []EntityAction{}
        default:
                panic(fmt.Sprintf("Delete called for entity in %v state", 
e.State))
        }
@@ -268,11 +269,18 @@
                return e, tree, actions
        case Scanning:
                if e.Container.Status.State == container.ContainerTerminated {
-                       e.State = WantScanning
+                       e.State = Deleted
                        tree.AddOrReplace(e)
                        actions = append(actions, StopScannerKeepLogs)
                }
                return e, tree, actions
+       case Deleted:
+               if e.Container.Status.State == container.ContainerRunning {
+                       e.State = ScannerStarting
+                       tree.AddOrReplace(e)
+                       actions = append(actions, StartScanner)
+               }
+               return e, tree, actions
        default:
                // an entity in any other state has its container updated and 
remains in the same entity state
                return e, tree, actions
@@ -327,6 +335,11 @@
                e.LogScanner = nil
                tree.AddOrReplace(e)
                return e, tree, []EntityAction{}
+       case ScannerStarting, Scanning:
+               // Old scanner stopped after entity was reactivated with a new 
scanner
+               // (e.g. Deleted → ScannerStarting via Update). Don't modify 
state or
+               // LogScanner as they pertain to the new scanner.
+               return e, tree, []EntityAction{}
        default:
                panic(fmt.Sprintf("ScannerStopped called for entity in %v 
state", e.State))
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kl-0.9.0/internal/k8s/entity/entity_test.go 
new/kl-0.9.1/internal/k8s/entity/entity_test.go
--- old/kl-0.9.0/internal/k8s/entity/entity_test.go     2026-04-13 
04:18:04.000000000 +0200
+++ new/kl-0.9.1/internal/k8s/entity/entity_test.go     2026-04-13 
20:13:48.000000000 +0200
@@ -174,22 +174,7 @@
 
        _, _, actions := ent.Deactivate(tree)
 
-       if len(actions) != 2 {
-               t.Fatalf("expected 2 actions, got %d: %v", len(actions), 
actions)
-       }
-       hasRemoveLogs := false
-       hasRemoveEntity := false
-       for _, a := range actions {
-               if a == entity.RemoveLogs {
-                       hasRemoveLogs = true
-               }
-               if a == entity.RemoveEntity {
-                       hasRemoveEntity = true
-               }
-       }
-       if !hasRemoveLogs || !hasRemoveEntity {
-               t.Errorf("expected RemoveLogs and RemoveEntity, got %v", 
actions)
-       }
+       assertActions(t, actions, []entity.EntityAction{entity.RemoveEntity})
 }
 
 func TestDeactivate_FromInvalidState_Panics(t *testing.T) {
@@ -240,10 +225,9 @@
 
        _, _, actions := ent.Delete(tree, 
newTestDelta(container.ContainerTerminated, true, false))
 
-       assertActions(t, actions, []entity.EntityAction{})
-       // entity should be removed from tree
-       if tree.GetEntity(ent.Container) != nil {
-               t.Error("entity should have been removed from tree")
+       assertActions(t, actions, []entity.EntityAction{entity.RemoveEntity})
+       if tree.GetEntity(ent.Container) == nil {
+               t.Error("entity should still be in tree")
        }
 }
 
@@ -269,9 +253,24 @@
 
        _, _, actions := ent.Delete(tree, 
newTestDelta(container.ContainerTerminated, true, false))
 
-       assertActions(t, actions, []entity.EntityAction{entity.StopScanner})
-       if tree.GetEntity(ent.Container) != nil {
-               t.Error("entity should have been removed from tree")
+       if len(actions) != 2 {
+               t.Fatalf("expected 2 actions, got %d: %v", len(actions), 
actions)
+       }
+       hasRemoveEntity := false
+       hasStopScanner := false
+       for _, a := range actions {
+               if a == entity.RemoveEntity {
+                       hasRemoveEntity = true
+               }
+               if a == entity.StopScanner {
+                       hasStopScanner = true
+               }
+       }
+       if !hasRemoveEntity || !hasStopScanner {
+               t.Errorf("expected RemoveEntity and StopScanner, got %v", 
actions)
+       }
+       if tree.GetEntity(ent.Container) == nil {
+               t.Error("entity should still be in tree")
        }
 }
 
@@ -308,9 +307,9 @@
 
        _, _, actions := ent.Delete(tree, 
newTestDelta(container.ContainerTerminated, true, false))
 
-       assertActions(t, actions, []entity.EntityAction{entity.StopScanner})
-       if tree.GetEntity(ent.Container) != nil {
-               t.Error("entity should have been removed from tree")
+       assertActions(t, actions, []entity.EntityAction{entity.RemoveEntity})
+       if tree.GetEntity(ent.Container) == nil {
+               t.Error("entity should still be in tree")
        }
 }
 
@@ -327,6 +326,20 @@
        }
 }
 
+func TestDelete_FromDeleted(t *testing.T) {
+       tree := newTestTree()
+       ent := newTestEntity(entity.Deleted, container.ContainerTerminated)
+       tree.AddOrReplace(ent)
+
+       result, _, actions := ent.Delete(tree, 
newTestDelta(container.ContainerTerminated, true, false))
+
+       assertState(t, result, entity.Deleted)
+       assertActions(t, actions, []entity.EntityAction{})
+       if tree.GetEntity(ent.Container) == nil {
+               t.Error("entity should still be in tree")
+       }
+}
+
 // --- Create ---
 
 func TestCreate_ToActivate_RunningContainer(t *testing.T) {
@@ -421,7 +434,7 @@
 
        result, _, actions := ent.Update(tree, 
newTestDelta(container.ContainerTerminated, false, false))
 
-       assertState(t, result, entity.WantScanning)
+       assertState(t, result, entity.Deleted)
        if len(actions) != 2 {
                t.Fatalf("expected 2 actions, got %d: %v", len(actions), 
actions)
        }
@@ -475,6 +488,42 @@
        }
 }
 
+func TestUpdate_Deleted_ContainerRestarted(t *testing.T) {
+       tree := newTestTree()
+       ent := newTestEntity(entity.Deleted, container.ContainerTerminated)
+       tree.AddOrReplace(ent)
+
+       result, _, actions := ent.Update(tree, 
newTestDelta(container.ContainerRunning, false, false))
+
+       assertState(t, result, entity.ScannerStarting)
+       assertActions(t, actions, []entity.EntityAction{entity.StartScanner})
+}
+
+func TestUpdate_Deleted_ContainerStillTerminated(t *testing.T) {
+       tree := newTestTree()
+       ent := newTestEntity(entity.Deleted, container.ContainerTerminated)
+       tree.AddOrReplace(ent)
+
+       // Repeated terminated updates (common during rollout restarts) should 
NOT
+       // restart scanning — we already have the terminated logs.
+       result, _, actions := ent.Update(tree, 
newTestDelta(container.ContainerTerminated, false, false))
+
+       assertState(t, result, entity.Deleted)
+       // MarkLogsTerminated is expected (idempotent) because 
MayHaveLogs()=true for Deleted
+       assertActions(t, actions, 
[]entity.EntityAction{entity.MarkLogsTerminated})
+}
+
+func TestUpdate_Deleted_ContainerStillWaiting(t *testing.T) {
+       tree := newTestTree()
+       ent := newTestEntity(entity.Deleted, container.ContainerTerminated)
+       tree.AddOrReplace(ent)
+
+       result, _, actions := ent.Update(tree, 
newTestDelta(container.ContainerWaiting, false, false))
+
+       assertState(t, result, entity.Deleted)
+       assertActions(t, actions, []entity.EntityAction{})
+}
+
 // --- ScannerStarted ---
 
 func TestScannerStarted_Success(t *testing.T) {
@@ -597,8 +646,37 @@
        }
 }
 
+func TestScannerStopped_FromScannerStarting(t *testing.T) {
+       tree := newTestTree()
+       ent := newTestEntity(entity.ScannerStarting, container.ContainerRunning)
+       tree.AddOrReplace(ent)
+
+       result, _, actions := ent.ScannerStopped(tree)
+
+       // Old scanner stopped after entity was reactivated — no state change
+       assertState(t, result, entity.ScannerStarting)
+       assertActions(t, actions, []entity.EntityAction{})
+}
+
+func TestScannerStopped_FromScanning(t *testing.T) {
+       tree := newTestTree()
+       ent := newTestEntity(entity.Scanning, container.ContainerRunning)
+       scanner := newTestScanner()
+       ent.LogScanner = &scanner
+       tree.AddOrReplace(ent)
+
+       result, _, actions := ent.ScannerStopped(tree)
+
+       // Old scanner stopped after entity was reactivated — no state change, 
keep LogScanner
+       assertState(t, result, entity.Scanning)
+       assertActions(t, actions, []entity.EntityAction{})
+       if result.LogScanner == nil {
+               t.Error("expected LogScanner to be preserved (it belongs to the 
new scanner)")
+       }
+}
+
 func TestScannerStopped_FromInvalidState_Panics(t *testing.T) {
-       for _, state := range []entity.EntityState{entity.Inactive, 
entity.ScannerStarting, entity.Scanning} {
+       for _, state := range []entity.EntityState{entity.Inactive} {
                t.Run(state.String(), func(t *testing.T) {
                        tree := newTestTree()
                        ent := newTestEntity(state, container.ContainerRunning)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kl-0.9.0/internal/k8s/entity/entity_tree.go 
new/kl-0.9.1/internal/k8s/entity/entity_tree.go
--- old/kl-0.9.0/internal/k8s/entity/entity_tree.go     2026-04-13 
04:18:04.000000000 +0200
+++ new/kl-0.9.1/internal/k8s/entity/entity_tree.go     2026-04-13 
20:13:48.000000000 +0200
@@ -653,10 +653,9 @@
                                toJoin = append(toJoin, v)
                        }
                }
-               name := k8s_model.ContainerNameAndPrefix{
+               return k8s_model.ContainerNameAndPrefix{
                        Prefix:        strings.Join(toJoin, "/"),
                        ContainerName: container.Name,
-               }
-               return name, nil
+               }, nil
        }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kl-0.9.0/internal/k8s/entity/entity_tree_test.go 
new/kl-0.9.1/internal/k8s/entity/entity_tree_test.go
--- old/kl-0.9.0/internal/k8s/entity/entity_tree_test.go        2026-04-13 
04:18:04.000000000 +0200
+++ new/kl-0.9.1/internal/k8s/entity/entity_tree_test.go        2026-04-13 
20:13:48.000000000 +0200
@@ -588,7 +588,7 @@
                for c, short := range expected {
                        n, err := f(c)
                        if err != nil {
-                               t.Errorf("Expected no error, got %v", err)
+                               t.Fatalf("Unexpected error for container %s: 
%v", c.Name, err)
                        }
                        if n != short {
                                t.Errorf("Expected short name %s, got %s", 
short, n)
@@ -644,9 +644,11 @@
                },
        }
        compare(f, expected)
+
+       // looking up a container not in the tree should return an error
        _, err := f(container.Container{Name: "doesntexist"})
        if err == nil {
-               t.Errorf("Expected error, got nil")
+               t.Errorf("Expected error for nonexistent container, got nil")
        }
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kl-0.9.0/internal/page/logs.go 
new/kl-0.9.1/internal/page/logs.go
--- old/kl-0.9.0/internal/page/logs.go  2026-04-13 04:18:04.000000000 +0200
+++ new/kl-0.9.1/internal/page/logs.go  2026-04-13 20:13:48.000000000 +0200
@@ -301,11 +301,11 @@
 func (p LogsPage) WithUpdatedShortNames(f func(container.Container) 
(k8s_model.ContainerNameAndPrefix, error)) (LogsPage, error) {
        allLogs := p.logContainer.GetOrderedLogs()
        for i := range allLogs {
-               short, err := f(allLogs[i].Log.Container)
+               shortName, err := f(allLogs[i].Log.Container)
                if err != nil {
                        return p, err
                }
-               allLogs[i].ContainerNames.Short = short
+               allLogs[i].ContainerNames.Short = shortName
                allLogs[i].CurrentName = getContainerName(allLogs[i], 
nameFormats[p.nameFormatIdx])
        }
        p.setLogs(allLogs)

++++++ kl.obsinfo ++++++
--- /var/tmp/diff_new_pack.i1BtJ1/_old  2026-04-18 21:38:59.159995314 +0200
+++ /var/tmp/diff_new_pack.i1BtJ1/_new  2026-04-18 21:38:59.167995641 +0200
@@ -1,5 +1,5 @@
 name: kl
-version: 0.9.0
-mtime: 1776046684
-commit: 46461cf69f1c723ade8d5425567f4640eedb3ba4
+version: 0.9.1
+mtime: 1776104028
+commit: 6b0fe84afedeab1d40b5a82402a361eb07ba3152
 

++++++ vendor.tar.gz ++++++
/work/SRC/openSUSE:Factory/kl/vendor.tar.gz 
/work/SRC/openSUSE:Factory/.kl.new.11940/vendor.tar.gz differ: char 139, line 1

Reply via email to