# GitHub Copilot Instructions: Qt5/C++11 to Qt6/C++23 Migration ## Mission Migrate the legacy Qt5/C++11 desktop application to Qt6/C++23, preserve behavior unless change is strictly required, and validate the result completely in the repository’s Docker-based CI workflow. ## Operating Mode - Work autonomously from analysis through validation. - Do not stop after editing code. - Continue until configure, build, tests, and policy checks have been attempted in Docker. - Do not ask for confirmation during normal implementation. - Stop early only if required source material is missing, the task is impossible, or a destructive action would be required. ## Boundaries - Read the legacy project from `${PROJECT_DIR}`. - Write the migrated project to `qt6-after/qt6-migrated-benchmark`. - Do not modify the legacy source tree in place. - Limit changes to the target tree and only the CI/build/test files needed to support migration and validation. ## Main Migration Targets - Upgrade Qt5 to Qt6. - Upgrade C++11/14/17 code to C++23. - Keep Qt Core, Gui, and Widgets explicitly linked. - Replace `QRegExp` with `QRegularExpression`. - Replace `QDesktopWidget` and `QApplication::desktop()` with `QScreen`-based Qt6 APIs. - Remove legacy `QTextCodec` usage and adopt Qt6-safe text handling. - Replace old `SIGNAL`/`SLOT` syntax with function-pointer connect syntax. - Replace `0`/`NULL` pointer literals with `nullptr`. - Preserve `.ui` and `.qrc` integration. - Preserve behavior unless Qt6 compatibility requires adaptation. ## C++23 Modernization Rules - Preserve semantics first; modernize second. - Use `auto` when the type is obvious; avoid it when it hides important type information. - Prefer structured bindings where clearer. - Replace raw owning pointers/manual `delete` with RAII, usually `std::unique_ptr`. - Use `std::make_unique` / `std::make_shared`; use `std::shared_ptr` only for real shared ownership. - Use `std::string_view` only when lifetime safety is clear. - Prefer `std::span` for non-owning contiguous data; use `std::mdspan` only when multidimensional access clearly benefits. - Prefer `.contains()` over `find(...) != end()` where available. - Prefer algorithms and ranges over manual loops when readability improves. - Use `[[nodiscard]]` when ignoring a result is likely a bug. - Prefer early returns over deeply nested control flow. - Use `std::optional` monadic operations (`and_then`, `transform`, `or_else`) when clearer. - Prefer `constexpr`, `if constexpr`, concepts, and `requires` over legacy `std::enable_if`/SFINAE where practical. - Add `noexcept`, `override`, `final`, `= default`, and `= delete` where correct and useful. - Prefer `enum class` over unscoped enums where practical. - Prefer `std::print` / `std::println` when supported by the toolchain. - Prefer typed `std::chrono` durations and `std::jthread` where appropriate. ## Safety Rules - Do not change business logic unless explicitly requested or required for Qt6 compatibility. - Do not introduce unsupported Qt6/C++23 features. - Do not silently change ABI, ownership, lifetime, exception behavior, performance, UI behavior, or event ordering. - Do not worsen readability for the sake of modernization. - Avoid dangling references, dangling `std::string_view`, and ownership ambiguity. - Keep includes minimal and preserve repository-local formatting/style. ## Tests - For every code change inside a method, add at least three tests covering the changed behavior. - Place generated tests in `qt6-after/qt6-migrated-benchmark/tests`. - Use policy-compatible test filenames such as: - `test_.cpp` - `_test.cpp` - `test.cpp` - `gtest.cpp` - Update CMake so the migrated app and all tests build and run with CTest. - Ensure all tests are registered with CTest. ## Docker-First Validation Use `lifemaps/ci-cpp:latest` as the authoritative environment. Do not substitute host tools for missing container tools. Treat `Dockerfile.ci` as the source of truth for CI dependencies. ### Required validation sequence 1. Configure in Docker 2. Build in Docker 3. Run tests in Docker 4. If tests pass, run `python3 ci/check_pr_policies.py` in Docker ### Recommended commands - Configure: `cmake -S qt6-after/qt6-migrated-benchmark -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug` - Build: `cmake --build build --parallel` - Test: `ctest --test-dir build --output-on-failure` - Policy: `python3 ci/check_pr_policies.py` Adapt paths/flags only if repository inspection proves they must differ. ## Missing-Tool Remediation If Docker validation fails because a required tool/package is missing: - identify the exact missing dependency - update `Dockerfile.ci` minimally - rebuild `lifemaps/ci-cpp:latest` - rerun the full validation sequence Continue until: - validation succeeds, or - the next blocker is a genuine project/code issue ## Failure Classification Environment failures: - command not found - missing compiler/toolchain utility - missing Qt dev package - missing CMake/Ninja/CTest support tool - missing dependency required by `ci/check_pr_policies.py` Project failures: - compile errors - linker errors - failing tests - formatting/policy failures caused by migration changes ## Policy Awareness - `ci/check_pr_policies.py` checks formatting for changed C/C++ files, expects related tests, and verifies commit-signature conditions in its diff range. - Ensure Docker validation runs with mounted workspace and git metadata available. - Do not claim success unless the policy script passes. ## Execution Plan 1. Inspect `${PROJECT_DIR}` and the target tree. 2. Identify Qt5 and legacy C++ constructs to migrate. 3. Migrate incrementally in `qt6-after/qt6-migrated-benchmark`. 4. Add/update tests with each behavior-relevant change. 5. Update CMake/test registration. 6. Validate in Docker. 7. If missing dependencies are found, update `Dockerfile.ci`, rebuild, and rerun. 8. Repeat until success or a real project defect remains. ## Reporting Group change explanations by: - CMake / build-system migration - Qt API replacements - C++ modernization - UI/resource preservation - tests added - `Dockerfile.ci` / container updates Also provide a concise changed-files summary. ## Completion Criteria Success requires: - migrated project exists under `qt6-after/qt6-migrated-benchmark` - configure succeeds in Docker - build succeeds in Docker - tests succeed in Docker - `python3 ci/check_pr_policies.py` succeeds in Docker after tests pass ## Final Response - State whether migration is fully validated or which blocker remains. - List the exact Docker commands used for image rebuild, configure, build, test, and policy check. - For every failed attempt, include: - exact command - key error - environment vs project classification - fix applied - End with a short summary of any remaining blocker.