|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Build & Test Commands |
| 6 | + |
| 7 | +```bash |
| 8 | +# Build |
| 9 | +./gradlew assembleDebug |
| 10 | +./gradlew assembleRelease # requires signing env vars |
| 11 | + |
| 12 | +# Unit tests (all flavors) |
| 13 | +./gradlew testDebugUnitTest testMdmDebugUnitTest --continue |
| 14 | + |
| 15 | +# Single module unit tests |
| 16 | +./gradlew :owncloudApp:testOriginalDebugUnitTest |
| 17 | +./gradlew :owncloudData:testDebugUnitTest |
| 18 | + |
| 19 | +# Instrumented tests (requires running emulator/device) |
| 20 | +./gradlew :owncloudData:connectedAndroidTest |
| 21 | + |
| 22 | +# Lint & static analysis |
| 23 | +./gradlew detekt # maxIssues: 0 — any issue fails CI |
| 24 | +./gradlew lintDebug |
| 25 | +./gradlew ktlintCheck |
| 26 | +./gradlew ktlintFormat # auto-fix formatting |
| 27 | +``` |
| 28 | + |
| 29 | +## Architecture |
| 30 | + |
| 31 | +Four modules in a strict dependency chain: |
| 32 | + |
| 33 | +``` |
| 34 | +owncloudComLibrary → owncloudData → owncloudDomain ← owncloudApp |
| 35 | +``` |
| 36 | + |
| 37 | +- **owncloudComLibrary** — networking layer: OkHttp, DAV4Android (WebDAV), OAuth/OIDC, Moshi |
| 38 | +- **owncloudDomain** — business layer: UseCases, domain Models, Repository interfaces, Exceptions |
| 39 | +- **owncloudData** — data layer: Repository implementations, Room DB, Remote/Local DataSources |
| 40 | +- **owncloudApp** — presentation layer: Activities, Fragments, ViewModels, Koin wiring |
| 41 | +- **owncloudTestUtil** — shared test factories, mocks, and extensions (test-only dependency) |
| 42 | + |
| 43 | +**Pattern:** MVVM + Clean Architecture. Data flows strictly in one direction: |
| 44 | + |
| 45 | +``` |
| 46 | +Fragment → ViewModel → UseCase → Repository → DataSource → ownCloud server (WebDAV/Graph API) |
| 47 | +``` |
| 48 | + |
| 49 | +UseCases extend `BaseUseCase<R>` or `BaseUseCaseWithResult<P, R>`. ViewModels call them via coroutines and expose `Flow` (preferred) or `LiveData` to the UI. |
| 50 | + |
| 51 | +**DI:** Koin with module-per-layer structure under `owncloudApp/.../dependecyinjection/`: |
| 52 | +`CommonModule`, `RemoteDataSourceModule`, `LocalDataSourceModule`, `RepositoryModule`, `UseCaseModule`, `ViewModelModule`. |
| 53 | + |
| 54 | +## Product Flavors |
| 55 | + |
| 56 | +Dimension: `management` |
| 57 | + |
| 58 | +| Flavor | Purpose | |
| 59 | +|--------|---------| |
| 60 | +| `original` | Standard ownCloud app | |
| 61 | +| `mdm` | Mobile Device Management — custom branding/policies | |
| 62 | +| `qa` | QA variant for automated testing | |
| 63 | + |
| 64 | +Build types: `debug` / `release`. Combined targets follow the pattern `assembleOriginalDebug`, `testMdmDebugUnitTest`, etc. |
| 65 | + |
| 66 | +## SDK & Toolchain |
| 67 | + |
| 68 | +- Min SDK 28 (Android 9), Target/Compile SDK 36 |
| 69 | +- Kotlin 2.3.10, JDK 17, AGP 9.2.1 |
| 70 | +- Version catalog: `gradle/libs.versions.toml` |
| 71 | + |
| 72 | +## Git & Commit Conventions |
| 73 | + |
| 74 | +All commits must be **GPG-signed** and include a **DCO sign-off**: |
| 75 | + |
| 76 | +```bash |
| 77 | +git commit -s -S -m "type: description" |
| 78 | +``` |
| 79 | + |
| 80 | +**Conventional Commits** format is enforced by CI: |
| 81 | +- `feat:` introduces a new capability visible to the user or other modules (new screen, new API, new setting) |
| 82 | +- `fix:` corrects a defect — something that was broken and is now working as intended |
| 83 | +- `refactor:` restructuring existing code (rename, extract, move, simplify) with no change to observable behavior |
| 84 | +- `test:` adds or updates tests only — no production code changes |
| 85 | +- `build:` changes to dependencies (adding, removing, or upgrading libraries in `libs.versions.toml` or any `build.gradle`) |
| 86 | +- `chore:` maintenance that has no user-facing effect (changelog entries, build config, tooling) — do not use for dependency changes |
| 87 | + |
| 88 | +Branch naming follows OneFlow: `feature/feature_name`, `fix/fix_name`, `improvement/improvement_name`, `technical/technical_description`. |
| 89 | + |
| 90 | +Rebase on the target branch before opening a PR. No merge commits. |
| 91 | + |
| 92 | +## Changelog |
| 93 | + |
| 94 | +Every PR must include a file in `changelog/unreleased/` named after the PR number (e.g., `4936`): |
| 95 | + |
| 96 | +``` |
| 97 | +Enhancement: Short title under 80 chars |
| 98 | +
|
| 99 | +Description in present perfect passive tense. |
| 100 | +
|
| 101 | +https://github.com/owncloud/android/issues/<issue> ← optional, omit if there is no linked issue |
| 102 | +https://github.com/owncloud/android/pull/<pr> |
| 103 | +``` |
| 104 | + |
| 105 | +Types: `Bugfix`, `Change`, `Enhancement`, `Security`. Calens reads these files to auto-generate `CHANGELOG.md` after merge. |
| 106 | + |
| 107 | +## Key Constraints |
| 108 | + |
| 109 | +- **No translation PRs** — submit translations to Transifex only. |
| 110 | +- **Detekt is zero-tolerance** (`maxIssues: 0`). Run `./gradlew detekt` locally before pushing. |
| 111 | +- **Max line length: 150** (enforced by `.editorconfig`). |
| 112 | +- **GitHub Actions** must use SHA-pinned refs and come from the owncloud org, `actions/*`, or verified Marketplace publishers. |
| 113 | +- **License migration in progress** (GPL-2.0 → Apache 2.0): do not introduce new copyleft dependencies without discussion. |
| 114 | +- **Security issues** go to security.owncloud.com, not GitHub issues. |
0 commit comments