Skip to content

Commit 24f3f6f

Browse files
committed
stability: harden chooser sorting and add merge checklist
1 parent b0d29e6 commit 24f3f6f

4 files changed

Lines changed: 95 additions & 9 deletions

File tree

app/src/main/java/com/kyhsgeekcode/filechooser/NewFileChooserAdapter.kt

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -233,16 +233,8 @@ class NewFileChooserAdapter(
233233
}
234234

235235
private fun addItemsToListSorted(subItems: List<FileItem>) {
236-
val newValues = ArrayList<FileItem>()
237-
newValues.addAll(subItems)
238-
newValues.sortWith(
239-
compareBy(
240-
{ !it.text.endsWith("/") },
241-
{ it.text[0].lowercaseChar() },
242-
{ it.text })
243-
)
244236
values.clear()
245-
values.addAll(newValues)
237+
values.addAll(sortFileItemsForDisplay(subItems))
246238
}
247239

248240
fun onBackPressedShouldFinish(): Boolean {
@@ -287,3 +279,27 @@ class NewFileChooserAdapter(
287279
return listSubItems(item) // item.cachedSubItems() ?:
288280
}
289281
}
282+
283+
fun sortFileItemsForDisplay(items: List<FileItem>): List<FileItem> {
284+
val sortedItems = ArrayList<FileItem>(items)
285+
sortedItems.sortWith(
286+
compareBy(
287+
{ fileItemSortGroup(it.text) },
288+
{ sortableFileItemLeadingChar(it.text) },
289+
{ sortableFileItemText(it.text) }
290+
)
291+
)
292+
return sortedItems
293+
}
294+
295+
fun fileItemSortGroup(text: String): Int {
296+
return if (text.endsWith("/")) 0 else 1
297+
}
298+
299+
private fun sortableFileItemLeadingChar(text: String): Char {
300+
return text.firstOrNull()?.lowercaseChar() ?: Char.MIN_VALUE
301+
}
302+
303+
fun sortableFileItemText(text: String): String {
304+
return text.lowercase()
305+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.kyhsgeekcode.disassembler
2+
3+
import com.kyhsgeekcode.filechooser.fileItemSortGroup
4+
import com.kyhsgeekcode.filechooser.sortableFileItemText
5+
import org.junit.jupiter.api.Assertions.assertEquals
6+
import org.junit.jupiter.api.Test
7+
8+
class FileChooserSortTest {
9+
@Test
10+
fun `sortableFileItemText tolerates empty labels`() {
11+
val sorted = listOf("", "beta", "alpha").sortedWith(
12+
compareBy(
13+
::fileItemSortGroup,
14+
::sortableFileItemText
15+
)
16+
)
17+
18+
assertEquals(listOf("", "alpha", "beta"), sorted)
19+
}
20+
21+
@Test
22+
fun `fileItemSortGroup keeps folders ahead of files`() {
23+
val sorted = listOf("zeta", "alpha/", "beta").sortedWith(
24+
compareBy(
25+
::fileItemSortGroup,
26+
::sortableFileItemText
27+
)
28+
)
29+
30+
assertEquals(listOf("alpha/", "beta", "zeta"), sorted)
31+
}
32+
}

docs/maintenance/implementation-log.ko.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
| PR 회귀를 잡는 instrumentation 범위 부족 | Compose UI test 의존성, import entry-point test tag, 회전 재생성 smoke test, standard/power-user mode UI 검증 테스트를 추가 | 현재 PR의 핵심 변경인 회전 재생성 경계와 `Select file`/`Advanced import` 노출 규칙을 emulator에서 직접 검증할 수 있게 했다 | `app/build.gradle`, `app/src/main/java/com/kyhsgeekcode/disassembler/ui/MainTab.kt`, `app/src/main/java/com/kyhsgeekcode/disassembler/ui/MainTestTags.kt`, `app/src/androidTest/java/com/kyhsgeekcode/disassembler/MainActivitySmokeTest.kt`, `app/src/androidTest/java/com/kyhsgeekcode/disassembler/MainActivityImportEntryPointStandardModeTest.kt`, `app/src/androidTest/java/com/kyhsgeekcode/disassembler/MainActivityImportEntryPointPowerUserModeTest.kt`, `app/src/androidTest/java/com/kyhsgeekcode/disassembler/PowerUserModePreferenceRule.kt` | 완료 |
3232
| 이슈 `#523`, `#442`, `#235` 대용량 파일/리스트 경계 | 큰 파일은 `ProjectDataStorage` 메모리 캐시에서 제외하고, 문자열 검색 결과는 5,000개로 상한을 두고 stable key로 렌더링하도록 바꿨다 | 150MB 같은 큰 파일을 한 번 열 때 캐시 맵이 오래 붙잡는 메모리 압박을 줄이고, 문자열 탭의 대형 리스트가 계속 불어나면서 Recycler/Lazy list가 불안정해지는 경로를 완화했다 | `app/src/main/java/com/kyhsgeekcode/disassembler/project/ProjectDataStorage.kt`, `app/src/main/java/com/kyhsgeekcode/disassembler/ui/components/TableView.kt`, `app/src/main/java/com/kyhsgeekcode/disassembler/ui/tabs/StringTab.kt`, `app/src/test/java/com/kyhsgeekcode/disassembler/project/ProjectDataStorageCachePolicyTest.kt`, `app/src/test/java/com/kyhsgeekcode/disassembler/ui/tabs/StringSearchResultAccumulatorTest.kt` | 완료 |
3333
| 이슈 `#235` binder payload 과대 가능성 | file chooser 결과가 `Serializable FileItem` 전체를 넘기지 않고 `filePath/nativeFilePath/projectType`만 넘기도록 축소 | chooser 결과 인텐트의 binder payload를 줄여 `TransactionTooLarge`류 상태 전송 압박을 완화하고, 결과 복원 경계도 pure helper 테스트로 고정했다 | `app/src/main/java/com/kyhsgeekcode/filechooser/NewFileChooserActivity.kt`, `app/src/main/java/com/kyhsgeekcode/disassembler/viewmodel/MainViewModel.kt`, `app/src/test/java/com/kyhsgeekcode/disassembler/FileSelectionIntentPayloadTest.kt` | 완료 |
34+
| 이슈 `#438` file chooser 정렬 크래시 | chooser 정렬을 pure helper로 분리하고 빈 라벨도 안전하게 정렬되도록 변경 | `it.text[0]` 직접 접근을 제거해서 빈/비정상 라벨이 섞인 경우에도 `Arrays.sort` 단계에서 죽지 않도록 만들고, 폴더 우선 정렬 규칙도 테스트로 고정했다 | `app/src/main/java/com/kyhsgeekcode/filechooser/NewFileChooserAdapter.kt`, `app/src/test/java/com/kyhsgeekcode/disassembler/FileChooserSortTest.kt` | 완료 |
3435
| 이슈 `#514`, `#543`, `#576` `.so`/ELF 아키텍처와 override autosetup | `x86_64`, `PPC64` ELF machine type을 64-bit disassembly mode로 매핑하고, binary overview에서 수동 설정을 적용하면 disassembly handle을 다시 열도록 바꿨다 | 일부 `.so`가 32-bit mode로 잘못 열리던 경로를 줄이고, `Override autosetup`이 값만 바꾸고 실제 disassembly는 안 바뀌던 문제를 수정했다 | `app/src/main/java/com/kyhsgeekcode/disassembler/models/Architecture.kt`, `app/src/main/java/com/kyhsgeekcode/disassembler/ui/tabs/BinaryOverviewTab.kt`, `app/src/main/java/com/kyhsgeekcode/disassembler/ui/tabs/BinaryTab.kt`, `app/src/test/java/com/kyhsgeekcode/disassembler/models/ArchitectureTest.kt`, `app/src/test/java/com/kyhsgeekcode/disassembler/ui/tabs/BinaryManualSetupConfigTest.kt` | 완료 |
3536
| 이슈 `#123`, `#720` 프로젝트 export와 details 저장 부재 | ZIP 생성기를 재귀 상대경로 방식으로 고치고, 프로젝트 overview에 SAF `CreateDocument` 기반 `Export project` 버튼을 추가했으며, binary detail 탭에는 `Save Details to file` 버튼을 구현했다 | 깨져 있던 project ZIP export 경로를 실제로 복구하고, 최신 Android 저장소 모델에 맞게 상세 정보 텍스트를 `.txt` 문서로 저장할 수 있게 했다 | `app/src/main/java/com/kyhsgeekcode/Util.kt`, `app/src/main/java/com/kyhsgeekcode/disassembler/exporting/ExportDocuments.kt`, `app/src/main/java/com/kyhsgeekcode/disassembler/project/ProjectManager.kt`, `app/src/main/java/com/kyhsgeekcode/disassembler/viewmodel/MainViewModel.kt`, `app/src/main/java/com/kyhsgeekcode/disassembler/ui/MainTab.kt`, `app/src/main/java/com/kyhsgeekcode/disassembler/ui/tabs/BinaryDetailTab.kt`, `app/src/test/java/com/kyhsgeekcode/disassembler/ProjectExportArchiveTest.kt`, `app/src/test/java/com/kyhsgeekcode/disassembler/exporting/BinaryDetailsExportTest.kt` | 완료 |
3637
| 이슈 `#129` `.ar` archive 지원 | 공용 archive extractor를 추가하고, Compose/legacy drawer의 archive 확장 경로를 ZIP 전용 구현에서 generic archive extractor로 교체했다 | archive 판정은 되는데 실제 확장은 ZIP만 되던 불일치를 제거해서 `.ar` 같은 지원 가능한 archive도 실제로 탐색 가능하게 만들었다 | `app/src/main/java/com/kyhsgeekcode/Util.kt`, `app/src/main/java/com/kyhsgeekcode/disassembler/ui/FileDrawerTree.kt`, `app/src/main/java/com/kyhsgeekcode/disassembler/FileDrawerListItem.kt`, `app/src/main/java/com/kyhsgeekcode/disassembler/FileDrawerListAdapter.kt`, `app/src/test/java/com/kyhsgeekcode/disassembler/ArchiveExtractionTest.kt` | 완료 |
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# `#728` 병합 후 정리 체크리스트
2+
3+
이 문서는 유지보수 기준선 PR `#728`이 병합된 직후, 바로 닫을 항목과 검증 후 닫을 항목을 구분해서 정리한 체크리스트다.
4+
5+
## 바로 닫을 항목
6+
7+
| 종류 | 번호 | 근거 |
8+
| --- | --- | --- |
9+
| 이슈 | `#670` | `MainActivity` launcher 노출 문제는 manifest 명시로 `#728`에 포함됨 |
10+
| 이슈 | `#396` | Hex view offset/16-byte row 개선이 `#728`에 포함됨 |
11+
| 이슈 | `#348` | disassembly horizontal scroll fix가 `#728`에 포함됨 |
12+
| 이슈 | `#160` | recreation 시 external import intent 재처리 가드가 `#728`에 포함됨 |
13+
| 이슈 | `#123` | project ZIP export 복구가 `#728`에 포함됨 |
14+
| 이슈 | `#159` | import 파일명 정규화와 fallback 규칙이 `#728`에 포함됨 |
15+
| 이슈 | `#720` | binary detail `.txt` export가 `#728`에 포함됨 |
16+
| 이슈 | `#129` | generic archive extraction으로 `.ar` 지원이 `#728`에 포함됨 |
17+
18+
## 병합 후 재확인 뒤 닫을 항목
19+
20+
| 종류 | 번호 | 병합 후 확인 포인트 |
21+
| --- | --- | --- |
22+
| 이슈 | `#514` | `.so` 샘플이 현재 64-bit architecture mapping으로 정상 해석되는지 |
23+
| 이슈 | `#543` | `Override autosetup` 이후 disassembly가 실제로 재로드되는지 |
24+
| 이슈 | `#576` | `.so` 입력 경로가 최신 baseline에서 충분히 커버되는지 |
25+
| 이슈 | `#235` | chooser payload 축소와 large-state 완화 이후 `TransactionTooLarge` 재현이 남는지 |
26+
| 이슈 | `#442` | string result cap/stable key 이후 긴 문자열 리스트에서 Recycler/List 불안정이 남는지 |
27+
| 이슈 | `#523` | large-file byte cache 제외 이후 150MB 클래스 입력에서 메모리 압박이 남는지 |
28+
| 이슈 | `#95` | 최신 Android에서 기본 import/export/open 경로가 SAF 중심으로 충분히 수렴했는지 |
29+
| PR | `#726` | `#728` 이후에도 별도 병합 가치가 남는지, 아니면 superseded 처리할지 |
30+
31+
## 정리 규칙
32+
33+
| 상황 | 액션 |
34+
| --- | --- |
35+
| `#728`로 완전히 대체된 항목 | 병합 후 바로 닫고 `fixed by #728` 코멘트 남김 |
36+
| 부분 완화만 된 항목 | `resolved`로 닫지 않고 재현/실기기 확인 후 닫음 |
37+
| 오래된 PR이 새 기준선보다 뒤처진 경우 | 별도 병합 없이 superseded/obsolete로 닫음 |

0 commit comments

Comments
 (0)