diff options
Diffstat (limited to 'archived/projt-launcher/docs/contributing')
8 files changed, 1113 insertions, 0 deletions
diff --git a/archived/projt-launcher/docs/contributing/ARCHITECTURE.md b/archived/projt-launcher/docs/contributing/ARCHITECTURE.md new file mode 100644 index 0000000000..a83334e604 --- /dev/null +++ b/archived/projt-launcher/docs/contributing/ARCHITECTURE.md @@ -0,0 +1,177 @@ +# Architecture + +High-level design and component interaction in ProjT Launcher. + +--- + +## Layers + +``` +┌─────────────────────────────────────────┐ +│ UI Layer │ +│ launcher/ui/ (Qt Widgets) │ +├─────────────────────────────────────────┤ +│ Core Layer │ +│ launcher/minecraft/, net/, java/ │ +├─────────────────────────────────────────┤ +│ Task System │ +│ launcher/tasks/ │ +└─────────────────────────────────────────┘ +``` + +### UI Layer + +**Location**: `launcher/ui/` + +- Qt Widgets interface +- Renders state, handles user input +- No direct I/O or network access + +### Core Layer + +**Location**: `launcher/`, `launcher/minecraft/`, `launcher/net/`, `launcher/java/` + +- Business logic +- Data models +- Network operations +- No UI dependencies + +### Task System + +**Location**: `launcher/tasks/` + +- Long-running operations +- Async work (downloads, extraction) +- Progress reporting + +--- + +## Key Principles + +### Separation of Concerns + +UI classes display state and forward user intent. They do not perform: + +- File I/O +- Network requests +- Long computations + +### Communication Pattern + +UI communicates with core via signals/slots: + +```cpp +auto task = makeShared<DownloadTask>(url); +connect(task.get(), &Task::progress, this, &MainWindow::updateProgress); +connect(task.get(), &Task::finished, this, &MainWindow::onDownloadComplete); +task->start(); +``` + +### Threading + +| Thread | Purpose | +|--------|---------| +| Main | UI rendering only | +| Worker | File I/O, networking, hashing | + +Operations > 10ms should be async. + +--- + +## Task System + +### Creating a Task + +```cpp +class MyTask : public Task { + Q_OBJECT + +protected: + void executeTask() override { + setStatus("Working..."); + setProgress(0); + + // Do work + for (int i = 0; i < 100; i++) { + if (isCancelled()) { + emitFailed("Cancelled"); + return; + } + setProgress(i); + } + + emitSucceeded(); + } +}; +``` + +### Running a Task + +```cpp +auto task = makeShared<MyTask>(); +connect(task.get(), &Task::succeeded, this, &MyClass::onSuccess); +connect(task.get(), &Task::failed, this, &MyClass::onFailure); +task->start(); +``` + +--- + +## Application Lifecycle + +1. **Startup**: `main.cpp` creates `Application` singleton +2. **Setup**: Load settings, accounts, instances +3. **UI Launch**: Create `MainWindow` +4. **Runtime**: Event loop processes user actions +5. **Shutdown**: Save state, release resources + +--- + +## Service Objects + +Long-lived non-UI classes owned by Application: + +- `AccountManager` - Microsoft/offline accounts +- `InstanceManager` - Minecraft instances +- `NetworkManager` - HTTP operations +- `SettingsManager` - Configuration + +Access via `Application::instance()->serviceName()`. + +--- + +## Common Violations + +**Don't do these**: + +| Violation | Fix | +|-----------|-----| +| `sleep()` in UI | Use Task | +| Network in UI class | Move to core service | +| UI import in core | Remove dependency | +| Direct file I/O in UI | Use Task | + +--- + +## Module Dependencies + +``` +ui/ ──→ minecraft/ ──→ net/ + │ │ + └──→ tasks/ ←──┘ + │ + └──→ java/ +``` + +**Rules**: + +- No circular dependencies +- `ui/` depends on everything +- Core modules are independent +- `tasks/` is a utility layer + +--- + +## Related + +- [Project Structure](./PROJECT_STRUCTURE.md) +- [Testing](./TESTING.md) diff --git a/archived/projt-launcher/docs/contributing/CODE_STYLE.md b/archived/projt-launcher/docs/contributing/CODE_STYLE.md new file mode 100644 index 0000000000..b51725a92d --- /dev/null +++ b/archived/projt-launcher/docs/contributing/CODE_STYLE.md @@ -0,0 +1,230 @@ +# Code Style + +Formatting and coding standards for ProjT Launcher. + +--- + +## Formatting + +All C++ code must be formatted with clang-format before committing. + +```sh +clang-format -i path/to/file.cpp +``` + +CI will reject unformatted code. + +--- + +## C++ Standards + +### Modern C++ + +| Feature | Usage | +|---------|-------| +| `auto` | Only when type is obvious | +| `nullptr` | Always (never `NULL` or `0`) | +| `override` | Required on all overrides | +| `const` | Required for non-mutating methods | + +### Memory Management + +**Smart Pointers**: + +```cpp +// Good +auto obj = std::make_unique<MyClass>(); + +// Bad - raw pointer ownership +MyClass* obj = new MyClass(); +``` + +**Qt Parent Ownership**: + +```cpp +// Good - Qt manages lifetime +new QButton(this); +``` + +### Error Handling + +- Avoid exceptions +- Use `std::optional` for missing values +- Use `std::expected` for operations that can fail + +### Lambdas + +```cpp +// Good - explicit capture +connect(btn, &QPushButton::clicked, this, [this, id]() { + handleClick(id); +}); + +// Bad - default capture +connect(btn, &QPushButton::clicked, [=]() { ... }); +``` + +--- + +## Naming Conventions + +| Type | Format | Example | +|------|--------|---------| +| Class | PascalCase | `MainWindow` | +| Private member | `m_` + camelCase | `m_currentTheme` | +| Static member | `s_` + camelCase | `s_instance` | +| Public member | camelCase | `dateOfBirth` | +| Constant | SCREAMING_SNAKE | `MAX_VALUE` | +| Function | camelCase | `getCurrentTheme()` || Enum class | PascalCase | `enum class State` | +| Enum values | PascalCase | `State::Running` | + +**SCREAMING_SNAKE scope**: Use for `constexpr` constants, `#define` macros, and legacy `enum` values only. Prefer `enum class` with PascalCase values for new code. +--- + +## Headers + +### Include Guards + +```cpp +#pragma once +``` + +### Include Order + +1. Corresponding header +2. C++ standard library +3. Qt headers +4. Third-party headers +5. Project headers + +```cpp +#include "MyClass.h" + +#include <memory> +#include <string> + +#include <QObject> +#include <QString> + +#include "OtherClass.h" +``` + +**Note**: clang-format automatically reorders includes. Always accept its output. + +### Forward Declarations + +Prefer forward declarations over includes when possible: + +```cpp +// Good +class OtherClass; + +// Avoid +#include "OtherClass.h" +``` + +**Qt warning**: Forward declarations do not work for QObject-derived classes that use `Q_OBJECT`. These must be fully included. + +--- + +## Comments + +### Documentation + +```cpp +/// @brief Short description. +/// +/// Detailed description if needed. +/// @param input Description of parameter. +/// @return Description of return value. +bool doSomething(const QString& input); +``` + +### Implementation Comments + +```cpp +// Why this approach was chosen +// NOT what the code does +``` + +### TODOs + +```cpp +// TODO(username): Description of what needs to be done +// FIXME(username): Description of broken behavior that needs fixing +``` + +- **TODO**: Planned improvement or missing feature +- **FIXME**: Known bug or broken behavior requiring attention +- Username is required for traceability +- Compatible with IDE TODO/FIXME highlighting tools + +--- + +## Qt Widgets + +### UI Files + +- Use Qt Designer for layout +- Never edit generated `ui_*.h` files +- Set meaningful `objectName` values + +### Widget Classes + +- Keep UI logic minimal +- Delegate to core services +- Use signals/slots for communication + +--- + +## File Templates + +These templates apply only to new Project Tick–owned files. Do not modify license headers in upstream forked code. + +### Header (.h) + +```cpp +// SPDX-License-Identifier: GPL-3.0-only +// SPDX-FileCopyrightText: 2026 Project Tick + +#pragma once + +#include <QObject> + +class MyClass : public QObject { + Q_OBJECT + +public: + explicit MyClass(QObject* parent = nullptr); + ~MyClass() override; + +signals: + void somethingHappened(); + +private: + QString m_data; +}; +``` + +### Source (.cpp) + +```cpp +// SPDX-License-Identifier: GPL-3.0-only +// SPDX-FileCopyrightText: 2026 Project Tick + +#include "MyClass.h" + +MyClass::MyClass(QObject* parent) + : QObject(parent) +{ +} + +MyClass::~MyClass() = default; +``` + +--- + +## Related + +- [Project Structure](./PROJECT_STRUCTURE.md) +- [Architecture](./ARCHITECTURE.md) diff --git a/archived/projt-launcher/docs/contributing/GETTING_STARTED.md b/archived/projt-launcher/docs/contributing/GETTING_STARTED.md new file mode 100644 index 0000000000..ac25232f28 --- /dev/null +++ b/archived/projt-launcher/docs/contributing/GETTING_STARTED.md @@ -0,0 +1,222 @@ +# Getting Started + +Guide to setting up your development environment for ProjT Launcher. + +--- + +## Prerequisites + +### Required Tools + +| Tool | Version | Purpose | +|------|---------|---------| +| CMake | 3.22+ | Build system | +| Qt | 6.8.0+ | GUI framework | +| Compiler | C++20 | GCC 11+, Clang 14+, MSVC 2022 | +| Ninja | 1.10+ | Build tool | +| Git | 2.30+ | Version control | + +### Optional Tools + +| Tool | Purpose | +|------|---------| +| clang-format | Code formatting | +| clang-tidy | Static analysis | +| Valgrind | Memory checking (Linux) | + +--- + +## Clone Repository + +```sh +# Fork on GitHub first, then: +git clone https://github.com/YourName/ProjT-Launcher.git +cd ProjT-Launcher + +# Add upstream remote +git remote add upstream https://github.com/Project-Tick/ProjT-Launcher.git +``` + +--- + +## Platform Setup + +### Windows + +**Visual Studio 2022**: + +1. Install VS 2022 with "Desktop development with C++" +2. Install Qt 6.8.0+ via Qt Online Installer + - Select MSVC 2022 64-bit + - Select Qt Shader Tools +3. Install dependencies via NuGet (required for CI parity): + +```powershell +nuget install ./packages.config -OutputDirectory dependencies +``` + +**Note**: NuGet dependencies are mandatory for Windows builds to ensure CI reproducibility. + +### Linux + +**Nix (Recommended)**: + +```sh +nix develop .#default +``` + +**Manual**: + +```sh +# Debian/Ubuntu +sudo apt install cmake ninja-build qt6-base-dev qt6-tools-dev + +# Fedora +sudo dnf install cmake ninja-build qt6-qtbase-devel qt6-qttools-devel + +# Arch +sudo pacman -S cmake ninja qt6-base qt6-tools +``` + +### macOS + +**Nix (Recommended)**: + +```sh +nix develop .#default +``` + +**Homebrew**: + +```sh +brew install cmake ninja qt@6 +``` + +--- + +## Build + +### Configure + +```sh +# List available presets +cmake --list-presets + +# Windows +cmake --preset windows_msvc + +# Linux +cmake --preset linux + +# macOS +cmake --preset macos +``` + +### Build + +```sh +# Debug (development) +cmake --build --preset <preset> --config Debug + +# Release (production) +cmake --build --preset <preset> --config Release +``` + +### Run + +```sh +# Windows (MSVC preset) +./build/windows_msvc/Debug/ProjT-Launcher.exe + +# Linux +./build/linux/Debug/ProjT-Launcher + +# macOS +./build/macos/Debug/ProjT-Launcher.app/Contents/MacOS/ProjT-Launcher +``` + +### Test + +```sh +ctest --preset <preset> --output-on-failure +``` + +--- + +## IDE Setup + +### VS Code (Recommended) + +Extensions: +- C/C++ (Microsoft) +- CMake Tools (Microsoft) +- clangd (LLVM) + +Settings (`.vscode/settings.json`): + +```json +{ + "cmake.configureOnOpen": true, + "cmake.generator": "Ninja" +} +``` + +### Qt Creator + +1. Open `CMakeLists.txt` as project +2. Select Qt 6.8.0+ kit +3. Import `.clang-format` in Tools > Options > C++ > Code Style + +### Visual Studio 2022 + +1. File > Open > CMake +2. Select `CMakeLists.txt` +3. Configure Qt path in CMake settings + +--- + +## Troubleshooting + +### Qt not found + +```sh +cmake --preset <preset> -DCMAKE_PREFIX_PATH="/path/to/Qt/6.8.0/gcc_64" +``` + +### Wrong Qt minor version + +CI requires exact Qt version match. Check `cmake/versions.cmake` for the required version. Mismatched Qt versions cause ABI incompatibility. + +### MSVC vs MinGW mismatch + +Qt kit must match your compiler. Use MSVC kit with Visual Studio, MinGW kit with MinGW toolchain. Do not mix. + +### clang-format version mismatch + +Use the version specified in CI. Different versions produce different output. Check `.gitlab-ci.yml` and `.gitlab/ci/` for the expected version. + +### Ninja not found + +Install Ninja or use a different generator: + +```sh +cmake -G "Unix Makefiles" .. +``` + +### C++20 not supported + +Update your compiler: +- GCC: 11+ +- Clang: 14+ +- MSVC: 2022 + +--- + +## Next Steps + +These documents must be read before submitting code: + +- [Code Style](./CODE_STYLE.md) - Formatting rules +- [Project Structure](./PROJECT_STRUCTURE.md) - Where files go +- [Architecture](./ARCHITECTURE.md) - How components interact +- [Workflow](./WORKFLOW.md) - Git workflow and PR process diff --git a/archived/projt-launcher/docs/contributing/LAUNCHER_TEST_MATRIX.md b/archived/projt-launcher/docs/contributing/LAUNCHER_TEST_MATRIX.md new file mode 100644 index 0000000000..119dbd5cb7 --- /dev/null +++ b/archived/projt-launcher/docs/contributing/LAUNCHER_TEST_MATRIX.md @@ -0,0 +1,51 @@ +# Launcher Test Matrix (UI Excluded) + +This document defines the **test coverage expectations** for all non-UI subsystems under `launcher/`. + +## Scope + +- **Included:** All core subsystems under `launcher/` +- **Excluded:** `launcher/ui/` (UI tests are tracked separately) + +## Goals + +- Each subsystem has at least **one unit/integration test** +- New or changed core behavior must be covered by tests +- All tests run via `ctest` +- Tests are platform-agnostic (Linux/Windows/macOS) + +## Subsystem Coverage List + +The table below shows the **target coverage**. “Covered” means baseline tests exist for the subsystem (UI excluded). + +| Subsystem | Path(s) | Example Tests | Status | +|---|---|---|---| +| File system & archives | `launcher/FileSystem.*`, `launcher/GZip.*`, `launcher/MMCZip.*`, `launcher/Untar.*` | `FileSystem_test`, `GZip_test` | Covered | +| Versioning | `launcher/Version.*` | `Version_test` | Covered | +| String/Json helpers | `launcher/StringUtils.*`, `launcher/Json.*` | `StringUtils_test`, `Json_test` | Covered | +| SeparatorPrefixTree | `launcher/SeparatorPrefixTree.h` | `SeparatorPrefixTree_test` | Covered | +| INI/Config | `launcher/INIFile.*` | `INIFile_test` | Covered | +| Task system | `launcher/tasks/` | `Task_test` | Covered | +| Java management | `launcher/java/` | `JavaVersion_test`, `RuntimeVersion_test` | Covered | +| Minecraft pack parsing | `launcher/minecraft/mod/` | `DataPackParse_test`, `ResourcePackParse_test`, `TexturePackParse_test`, `ShaderPackParse_test`, `WorldSaveParse_test` | Covered | +| Minecraft version formats | `launcher/minecraft/` | `MojangVersionFormat_test`, `Version_test` | Covered | +| Library/Dependency | `launcher/minecraft/Library.*`, `launcher/GradleSpecifier.*` | `Library_test`, `GradleSpecifier_test` | Covered | +| Mod platforms | `launcher/modplatform/` | `ModPlatform_test` | Covered | +| Networking/Downloads | `launcher/net/` | `NetUtils_test`, `NetHeaderProxy_test`, `NetSink_test` | Covered | +| Launch pipeline | `launcher/launch/`, `launcher/LaunchController.*` | `LaunchVariableExpander_test`, `LaunchLogModel_test`, `LaunchLineRouter_test`, `LaunchPipeline_test` | Covered | +| Instance management | `launcher/Instance*.*`, `launcher/BaseInstance.*` | `InstanceCopyPrefs_test`, `BaseInstanceSettings_test` | Covered | +| Updater | `launcher/updater/` | `ProjTExternalUpdater_test` | Covered | +| Logs/Diagnostics | `launcher/logs/`, `launcher/XmlLogs.*` | `XmlLogs_test`, `LogEventParser_test`, `MessageLevel_test` | Covered | +| Meta parsing | `launcher/meta/` | `MetaComponentParse_test` | Covered | +| Resource model | `launcher/minecraft/ResourceFolderModel.*` | `ResourceFolderModel_test` | Covered | + +## Rules For New Tests + +- New subsystems must add a row here +- “Missing” or “Covered” areas require new tests +- UI tests are tracked separately + +## CI Expectation + +- All tests run via `ctest` +- CI runs the same test set on all platforms diff --git a/archived/projt-launcher/docs/contributing/PROJECT_STRUCTURE.md b/archived/projt-launcher/docs/contributing/PROJECT_STRUCTURE.md new file mode 100644 index 0000000000..17cef52415 --- /dev/null +++ b/archived/projt-launcher/docs/contributing/PROJECT_STRUCTURE.md @@ -0,0 +1,123 @@ +# Project Structure + +Directory layout and file placement guide. + +--- + +## Directory Layout + +``` +ProjT-Launcher/ +├── launcher/ # Main application +│ ├── ui/ # Qt Widgets +│ │ ├── pages/ # Main screens +│ │ ├── widgets/ # Reusable components +│ │ ├── dialogs/ # Modal windows +│ │ └── setupwizard/ # First-run wizard +│ ├── minecraft/ # Game logic +│ │ ├── auth/ # Account authentication +│ │ ├── launch/ # Game process +│ │ ├── mod/ # Mod loading +│ │ └── versions/ # Version parsing +│ ├── net/ # Networking +│ ├── tasks/ # Background jobs +│ ├── java/ # Java runtime +│ ├── modplatform/ # Mod platform APIs +│ ├── resources/ # Images, themes +│ ├── icons/ # App icons +│ └── translations/ # Language files +├── tests/ # Unit tests +├── cmake/ # Build configuration +└── docs/ # Documentation +``` + +--- + +## File Placement + +### C++ Files + +| Location | Purpose | +|----------|---------| +| `launcher/ui/` | Qt Widgets UI | +| `launcher/minecraft/` | Game logic | +| `launcher/net/` | HTTP, downloads | +| `launcher/tasks/` | Async operations | +| `launcher/modplatform/` | Modrinth, CurseForge | + +**Note**: `minecraft/` is for Minecraft-specific logic only (versions, mods, launch process). Generic launcher functionality belongs in `launcher/` or appropriate submodules. + +### UI Files + +| Location | Purpose | +|----------|---------| +| `launcher/ui/widgets/` | Reusable widgets | +| `launcher/ui/pages/` | Main screens | +| `launcher/ui/dialogs/` | Popups, modals | +| `launcher/ui/setupwizard/` | First-run flow | + +### Assets + +| Location | Format | +|----------|--------| +| `launcher/resources/` | PNG, SVG | +| `launcher/icons/` | ICO, PNG, SVG | +| `launcher/translations/` | .ts | + +--- + +## Quick Reference + +| I want to add... | Location | +|------------------|----------| +| New screen | `launcher/ui/pages/` | +| Reusable widget | `launcher/ui/widgets/` | +| Modal dialog | `launcher/ui/dialogs/` | +| Network API | `launcher/net/` | +| Background job | `launcher/tasks/` | +| Game logic | `launcher/minecraft/` | +| Unit test | `tests/` | + +--- + +## Naming + +| Type | Convention | Example | +|------|------------|---------| +| C++ class | PascalCase | `InstanceList.cpp` | +| UI file | PascalCase | `SettingsPage.ui` | +| Asset | kebab-case | `app-icon.png` | +| Test | PascalCase_test | `FileSystem_test.cpp` | + +--- + +## Rules + +- No circular dependencies between modules +- `ui/` → `core` → `data` layering (conceptual layers, not directory names) +- Tests mirror source structure +- Do not create new top-level directories without maintainer approval + +--- + +## Third-Party Libraries + +Location: Root directory (e.g., `zlib/`, `quazip/`) + +All third-party code is maintained as detached forks. See [third-party.md](../handbook/third-party.md) for the complete list, upstream references, and patch policies. + +--- + +## Test Scope + +- `tests/` contains unit tests primarily +- Integration tests go in `tests/` but must be clearly named +- UI tests are discouraged; prefer testing core logic +- See [TESTING.md](./TESTING.md) for test standards + +--- + +## Related + +- [Architecture](./ARCHITECTURE.md) +- [Testing](./TESTING.md) diff --git a/archived/projt-launcher/docs/contributing/README.md b/archived/projt-launcher/docs/contributing/README.md new file mode 100644 index 0000000000..14a9f5584d --- /dev/null +++ b/archived/projt-launcher/docs/contributing/README.md @@ -0,0 +1,19 @@ +# Contributing Guide + +Documentation for developers who want to contribute to ProjT Launcher. + +## Getting Started + +- [Getting Started](./GETTING_STARTED.md) - Environment setup +- [Code Style](./CODE_STYLE.md) - Formatting and conventions +- [Workflow](./WORKFLOW.md) - Git workflow and DCO + +## Reference + +- [Architecture](./ARCHITECTURE.md) - Code organization +- [Project Structure](./PROJECT_STRUCTURE.md) - Directory layout +- [Testing](./TESTING.md) - Test standards + +--- + +See also: [Developer Handbook](../handbook/) diff --git a/archived/projt-launcher/docs/contributing/TESTING.md b/archived/projt-launcher/docs/contributing/TESTING.md new file mode 100644 index 0000000000..7acb1dd55e --- /dev/null +++ b/archived/projt-launcher/docs/contributing/TESTING.md @@ -0,0 +1,149 @@ +# Testing + +Testing standards and practices. + +**Framework**: QtTest is the only supported test framework. Do not introduce other frameworks. + +--- + +## Requirements + +| Change Type | Test Required | +|-------------|---------------| +| New logic | Yes | +| Bug fix | Yes (regression) | +| Refactor | Recommended | +| UI layout | No | +| Docs | No | + +--- + +## Test Structure + +```cpp +#include <QTest> +#include "MyClass.h" + +class MyClassTest : public QObject { + Q_OBJECT + +private slots: + void initTestCase(); // Before all tests + void cleanupTestCase(); // After all tests + void init(); // Before each test + void cleanup(); // After each test + + void test_methodName_condition(); +}; + +QTEST_GUILESS_MAIN(MyClassTest) +#include "MyClassTest.moc" +``` + +--- + +## Naming + +- **File**: `ClassName_test.cpp` +- **Class**: `ClassNameTest` +- **Method**: `test_method_condition` + +--- + +## Async Testing + +Use `QSignalSpy` instead of `sleep()`: + +```cpp +QSignalSpy spy(obj, &MyClass::finished); +obj->startAsync(); +QVERIFY(spy.wait(1000)); +QCOMPARE(spy.count(), 1); +``` + +--- + +## Mocking + +Create fake implementations for external dependencies: + +```cpp +class FakeNetworkService : public INetworkService { +public: + void get(const QString& url) override { + emit finished("Fake Data"); + } +}; +``` + +**Forbidden practices**: + +- Real network requests +- Real file system access outside `QTemporaryDir` +- User accounts or credentials +- `sleep()` or timing-based waits (use `QSignalSpy::wait()`) +- System-specific state dependencies + +## UI Testing + +UI tests are generally discouraged. Prefer testing core logic via unit tests. + +If UI testing is necessary: + +- Keep scope minimal (widget behavior only) +- Do not test layout or visual appearance +- Use `QTest::mouseClick()` and `QTest::keyClick()` for interaction +- Isolate widgets from services using mocks + +--- + +## Performance + +- Single test: < 100ms +- Mark slow tests clearly +- Use `QTemporaryDir` for file tests + +--- + +## Running Tests + +**VS Code**: Testing tab → Run + +**Command line (with presets)**: + +```bash +ctest --preset default --output-on-failure +``` + +**Without presets**: + +```bash +cd build +ctest --output-on-failure +``` + +**Single test**: + +```bash +./build/<preset>/tests/MyClassTest +``` + +--- + +## CI + +- All tests run via `ctest` +- Failing tests block merge +- Must pass on all platforms + +## Launcher Coverage + +- UI is excluded from core coverage requirements +- See the launcher subsystem test matrix: [Launcher Test Matrix](./LAUNCHER_TEST_MATRIX.md) + +--- + +## Related + +- [Architecture](./ARCHITECTURE.md) +- [Project Structure](./PROJECT_STRUCTURE.md) diff --git a/archived/projt-launcher/docs/contributing/WORKFLOW.md b/archived/projt-launcher/docs/contributing/WORKFLOW.md new file mode 100644 index 0000000000..2712f089e8 --- /dev/null +++ b/archived/projt-launcher/docs/contributing/WORKFLOW.md @@ -0,0 +1,142 @@ +# Workflow + +Git workflow and contribution process. + +--- + +## Branches + +| Branch | Purpose | +|--------|---------| +| `develop` | Integration branch (protected) | +| `release-X.Y.Z` | Release preparation | +| `hotfix/X.Y.Z` | Critical bug fixes | + +Never push directly to `develop`. + +--- + +## Commit Messages + +We use Conventional Commits: + +``` +<type>(<scope>): <description> + +Signed-off-by: Name <email> +``` + +### Types + +| Type | Use | +|------|-----| +| `feat` | New feature | +| `fix` | Bug fix | +| `docs` | Documentation | +| `style` | Formatting | +| `refactor` | Code change (no behavior change) | +| `perf` | Performance | +| `test` | Tests | +| `chore` | Build/tooling | + +### Example + +``` +feat(ui): add dark mode toggle + +Signed-off-by: John Doe <john@example.com> +``` + +**Forbidden**: Do not mix scopes in a single commit. A commit touching both `ui/` and `minecraft/` must be split. + +--- + +## DCO (Sign-off) + +Every commit must be signed: + +```bash +git commit -s -m "feat: my feature" +``` + +Forgot sign-off? + +```bash +git commit --amend -s --no-edit +git push --force-with-lease +``` + +--- + +## Pull Requests + +1. **One feature per PR** +2. **Merge commit only** (no squash, no rebase) +3. **CI must pass** +4. **One maintainer approval required** + +**Why merge commits?** History preservation and review traceability. Each commit remains linked to its PR and review discussion. + +--- + +## Merge Conflicts + +```bash +git fetch origin +git rebase origin/develop +# Fix conflicts +git add . +git rebase --continue +git push --force-with-lease +``` + +**Rebase policy**: Rebase is allowed only on local branches before PR submission. Never rebase protected branches or branches with open PRs. + +--- + +## Release Process + +1. Freeze `develop` +2. Create `release-X.Y.Z` +3. QA testing +4. Bug fixes to release branch +5. Merge to `develop` +6. Tag release + +--- + +## License Headers + +### Project Tick–Owned Files + +```cpp +// SPDX-License-Identifier: GPL-3.0-only +// SPDX-FileCopyrightText: 2026 Project Tick +/* + * ProjT Launcher - Minecraft Launcher + * Copyright (C) 2026 Project Tick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + */ +``` + +### Upstream Forked Files + +Do not modify existing license headers in forked code. When adding substantial changes, add a comment block below the original header: + +```cpp +// Modifications by Project Tick, 2026 +``` + +### Modified Files + +Preserve original copyright notices and add Project Tick copyright. + +--- + +## Related + +- [Getting Started](./GETTING_STARTED.md) +- [Code Style](./CODE_STYLE.md) |
