|
1 | 1 | # Repository Guidelines |
2 | 2 |
|
| 3 | +## Project Overview |
| 4 | + |
| 5 | +ComposeHooks 是一个 Kotlin Multiplatform 库,在 Jetpack Compose 中提供 React 风格的 Hooks。灵感来自 [alibaba/hooks](https://github.com/alibaba/hooks)。 |
| 6 | + |
| 7 | +**支持平台**: Android, Desktop (JVM), iOS (arm64, x64, simulator-arm64) |
| 8 | + |
| 9 | +**Artifact**: `xyz.junerver.compose:hooks2:<version>` |
| 10 | + |
3 | 11 | ## Project Structure & Module Organization |
| 12 | + |
4 | 13 | ComposeHooks is split into the `hooks` Kotlin Multiplatform library and the `app` multiplatform showcase client. Library sources live in `hooks/src/*` with platform folders like `commonMain`, `commonTest`, `androidMain`, `desktopMain`, and the `ios*` targets. Example screens and demo scaffolding reside under `app/src/...`, mirroring the platform folders, while shared assets and docs sit in `art/` and `docs/`. Gradle wiring remains at the root (`build.gradle.kts`, `settings.gradle.kts`, `gradle.properties`) alongside contributor resources. |
5 | 14 |
|
| 15 | +``` |
| 16 | +hooks/src/ |
| 17 | +├── commonMain/kotlin/xyz/junerver/compose/hooks/ |
| 18 | +│ ├── userequest/ # 网络请求管理 (插件架构) |
| 19 | +│ ├── useform/ # 表单验证框架 |
| 20 | +│ ├── useref/ # Ref 相关 hooks |
| 21 | +│ └── *.kt # 各种 hooks (useState, useEffect, useReducer 等) |
| 22 | +├── commonJvmAndroid/ # JVM+Android 共享代码 |
| 23 | +├── androidMain/ # Android 专属 hooks (useBiometric, useNetwork 等) |
| 24 | +├── desktopMain/ # Desktop 专属代码 |
| 25 | +└── iosMain/ # iOS 专属代码 |
| 26 | +
|
| 27 | +app/src/commonMain/ # 示例代码,展示各 hook 用法 |
| 28 | +``` |
| 29 | + |
6 | 30 | ## Build, Test, and Development Commands |
7 | | -- `./gradlew :hooks:build` compiles the library for every configured publication target and runs platform compilation checks. |
8 | | -- `./gradlew :app:run` launches the desktop sample; pass `-Pcompose.desktop.target` when you need a specific runtime. |
9 | | -- `./gradlew lintKotlin` executes kotlinter across modules; auto-fix formatting with `./gradlew formatKotlin`. |
10 | | -- `./gradlew :hooks:publishToMavenLocal` validates the Maven Central publication pipeline before cutting a release. |
| 31 | + |
| 32 | +```bash |
| 33 | +# 构建 |
| 34 | +./gradlew build |
| 35 | +./gradlew :hooks:build # 仅构建库 |
| 36 | + |
| 37 | +# 格式化代码 (提交前必须运行) |
| 38 | +./gradlew formatKotlin |
| 39 | + |
| 40 | +# 检查格式 |
| 41 | +./gradlew lintKotlin |
| 42 | + |
| 43 | +# 测试 |
| 44 | +./gradlew test # 单元测试 |
| 45 | +./gradlew desktopTest # Desktop 测试 |
| 46 | +./gradlew :hooks:check # 完整检查 |
| 47 | +./gradlew androidInstrumentedTest # Android 插桩测试 |
| 48 | + |
| 49 | +# 运行示例应用 |
| 50 | +./gradlew :app:run # Desktop |
| 51 | +./gradlew :app:installDebug # Android |
| 52 | + |
| 53 | +# 发布 |
| 54 | +./gradlew :hooks:publishToMavenLocal # 本地验证 |
| 55 | +./gradlew publishToMavenCentral # 正式发布 |
| 56 | +``` |
11 | 57 |
|
12 | 58 | ## Coding Style & Naming Conventions |
13 | | -Indent with four spaces and keep Kotlin lines under 140 characters as enforced by `.editorconfig`. Use Kotlin Official formatting with trailing commas enabled and never introduce wildcard imports. Hook results must expose an `XxxHolder` where stable `State<T>` values appear before helper lambdas, reusing existing hooks (`useState`, `useEffect`, `useRef`, `useCreation`) instead of raw Compose primitives. Include the standard header comment block in every new Kotlin file and favor descriptive, imperative function names. |
| 59 | + |
| 60 | +Indent with four spaces and keep Kotlin lines under 140 characters as enforced by `.editorconfig`. Use Kotlin Official formatting with trailing commas enabled and never introduce wildcard imports. Include the standard header comment block in every new Kotlin file and favor descriptive, imperative function names. |
| 61 | + |
| 62 | +## Hook Development Standards |
| 63 | + |
| 64 | +### 命名和返回值 |
| 65 | +- Hook 函数名以 `use` 开头,如 `useNetwork` |
| 66 | +- 返回值类型命名为 `XxxHolder` |
| 67 | +- 所有 `use` 函数都有对应的 `remember` 签名别名 |
| 68 | + |
| 69 | +### 实现规范 |
| 70 | +- 不直接返回状态值,包装在 `State` 中 |
| 71 | +- Holder 中 `State` 放在前面,函数放在后面 |
| 72 | +- 优先使用现有 hooks 而非原生 Compose 函数: |
| 73 | + - `useState` 代替 `derivedStateOf` |
| 74 | + - `useCreation` 或 `useRef` 代替 `remember` |
| 75 | + - `useEffect` 代替 `LaunchedEffect` |
| 76 | +- 函数成员声明类型别名 |
| 77 | + |
| 78 | +### useRequest 插件系统 |
| 79 | +位于 `userequest/` 目录,核心功能通过插件实现:缓存、防抖、节流、重试、轮询等。 |
14 | 80 |
|
15 | 81 | ## Testing Guidelines |
| 82 | + |
16 | 83 | Add shared coverage in `hooks/src/commonTest/kotlin` with `kotlin.test` and `kotlinx.coroutines.test`; desktop-only verifications belong in `hooks/src/desktopTest`. UI behavior should use Compose testing APIs in the relevant platform source set. Run `./gradlew :hooks:check` before opening a PR, and complement feature work with focused tests. Android instrumentation lives in `hooks/src/androidInstrumentedTest` and can be executed on a device or emulator via `./gradlew :hooks:connectedDebugAndroidTest`. |
17 | 84 |
|
| 85 | +### TDD Practice Requirements |
| 86 | + |
| 87 | +Tests exist to discover implementation defects, not merely to pass. Follow these principles: |
| 88 | + |
| 89 | +1. **Write tests that challenge the implementation**: Design test cases based on expected behavior and edge cases, not by mimicking the implementation logic. Avoid "copy-paste" tests that simply mirror what the code does. |
| 90 | + |
| 91 | +2. **When a test fails, fix the implementation first**: If a well-designed test case fails, the default action is to fix the implementation, not the test. Only modify a test when it genuinely contains a logical error or misunderstands the requirement. |
| 92 | + |
| 93 | +3. **Test boundary conditions and error paths**: Include tests for null inputs, empty collections, concurrent access, timeout scenarios, and other edge cases that reveal hidden bugs. |
| 94 | + |
| 95 | +4. **Verify behavior, not implementation details**: Assert on observable outcomes (return values, state changes, side effects) rather than internal method calls or private state. |
| 96 | + |
| 97 | +5. **Red-Green-Refactor cycle**: When adding new functionality, write a failing test first, implement the minimum code to pass, then refactor while keeping tests green. |
| 98 | + |
18 | 99 | ## Commit & Pull Request Guidelines |
19 | | -Prefix commits with a Gitmoji and module tag, such as `:sparkles: [Hooks]: Add useToggleHolder`, keeping the subject under 50 characters and in present tense. Expand on context in the body when behavior is non-trivial and reference issues after the first line. Pull requests should summarize the change, link related issues, note verification commands, and include screenshots or recordings for UI-facing updates. Keep PR scope tight, ensure CI passes, and request review only when the branch is green. |
| 100 | + |
| 101 | +使用 Gitmoji 格式: |
| 102 | +``` |
| 103 | +[Gitmoji] [Module]: Short description |
| 104 | +
|
| 105 | +✨ - 新功能 🐛 - Bug修复 📝 - 文档 ⚡️ - 优化 |
| 106 | +🩹 - 小修复 ⬆️ - 依赖更新 🔖 - 版本 🧪 - 测试 |
| 107 | +``` |
| 108 | + |
| 109 | +示例:`✨ [Hooks]: Add useToggleHolder` |
| 110 | + |
| 111 | +Keep the subject under 50 characters and in present tense. Expand on context in the body when behavior is non-trivial and reference issues after the first line. Pull requests should summarize the change, link related issues, note verification commands, and include screenshots or recordings for UI-facing updates. Keep PR scope tight, ensure CI passes, and request review only when the branch is green. |
0 commit comments