native macOS codings agent orchestrator
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #136 from supabitapp/issue-134-investigation

Fix orphaned run-script processes when archiving worktrees

authored by

khoi and committed by
GitHub
50baa978 00c6dda3

+60 -1
+4 -1
supacode/Features/App/Reducer/AppFeature.swift
··· 188 188 } 189 189 190 190 case .repositories(.delegate(.repositoriesChanged(let repositories))): 191 - let ids = Set(repositories.flatMap { $0.worktrees.map(\.id) }) 191 + let archivedIDs = state.repositories.archivedWorktreeIDSet 192 + let ids = Set( 193 + repositories.flatMap { $0.worktrees.map(\.id) }.filter { !archivedIDs.contains($0) } 194 + ) 192 195 let recencyIDs = CommandPaletteFeature.recencyRetentionIDs(from: repositories) 193 196 let worktrees = state.repositories.worktreesForInfoWatcher() 194 197 state.runScriptStatusByWorktreeID = state.runScriptStatusByWorktreeID.filter { ids.contains($0.key) }
+56
supacodeTests/AppFeatureArchivedSelectionTests.swift
··· 48 48 await store.finish() 49 49 #expect(saved.value.isEmpty) 50 50 } 51 + 52 + @Test(.dependencies) func repositoriesChangedPrunesArchivedWorktreesFromTerminalAndRunScriptStatus() async { 53 + let rootURL = URL(fileURLWithPath: "/tmp/repo") 54 + let activeWorktree = Worktree( 55 + id: "/tmp/repo/wt-active", 56 + name: "wt-active", 57 + detail: "", 58 + workingDirectory: URL(fileURLWithPath: "/tmp/repo/wt-active"), 59 + repositoryRootURL: rootURL 60 + ) 61 + let archivedWorktree = Worktree( 62 + id: "/tmp/repo/wt-archived", 63 + name: "wt-archived", 64 + detail: "", 65 + workingDirectory: URL(fileURLWithPath: "/tmp/repo/wt-archived"), 66 + repositoryRootURL: rootURL 67 + ) 68 + let repository = Repository( 69 + id: rootURL.path(percentEncoded: false), 70 + rootURL: rootURL, 71 + name: "repo", 72 + worktrees: IdentifiedArray(uniqueElements: [activeWorktree, archivedWorktree]) 73 + ) 74 + var repositoriesState = RepositoriesFeature.State(repositories: [repository]) 75 + repositoriesState.selection = .worktree(activeWorktree.id) 76 + repositoriesState.archivedWorktreeIDs = [archivedWorktree.id] 77 + var appState = AppFeature.State( 78 + repositories: repositoriesState, 79 + settings: SettingsFeature.State() 80 + ) 81 + appState.runScriptStatusByWorktreeID = [ 82 + activeWorktree.id: true, 83 + archivedWorktree.id: true, 84 + ] 85 + let sentCommands = LockIsolated<[TerminalClient.Command]>([]) 86 + let store = TestStore(initialState: appState) { 87 + AppFeature() 88 + } withDependencies: { 89 + $0.terminalClient.send = { command in 90 + sentCommands.withValue { $0.append(command) } 91 + } 92 + $0.worktreeInfoWatcher.send = { _ in } 93 + } 94 + store.exhaustivity = .off 95 + 96 + await store.send(.repositories(.delegate(.repositoriesChanged([repository])))) { 97 + $0.runScriptStatusByWorktreeID = [activeWorktree.id: true] 98 + } 99 + await store.finish() 100 + 101 + #expect( 102 + sentCommands.value == [ 103 + .prune([activeWorktree.id]) 104 + ] 105 + ) 106 + } 51 107 }