Skip to content
This repository was archived by the owner on Jul 16, 2026. It is now read-only.

Commit 1dce28b

Browse files
committed
docs(migration): document Maven to Gradle workflow
Document the reminder, safe conversion, Maven Local recovery, secret handling, Gradle packaging, and Linux ARM deployment. Finalize the living ExecPlan with observed validation, end-to-end evidence, trade-offs, and remaining limitations.
1 parent 3782158 commit 1dce28b

3 files changed

Lines changed: 73 additions & 27 deletions

File tree

.agent/exec-plan-totalcross-vscode-maven-to-gradle-reminder.md

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ The feature is visible when a legacy TotalCross Maven project is opened in an Ex
3030
- [x] (2026-07-16 13:52Z) Added a reusable Gradle renderer that packages the existing Gradle 9.6.1 Wrapper resources and writes non-secret migration metadata.
3131
- [x] (2026-07-16 13:54Z) Implemented atomic Maven-to-Gradle conversion, post-validation POM backup, rollback, generated-build retry, and Maven-Local-missing retention behavior.
3232
- [x] (2026-07-16 13:56Z) Updated build-system detection and package routing so converted Gradle projects use their Wrapper while Maven projects remain supported and mixed roots require an explicit migration decision.
33-
- [ ] Add unit, migration-fixture, extension, and end-to-end validation.
34-
- [ ] Update user-facing documentation and changelog entries in English.
35-
- [ ] Record actual implementation evidence in `Outcomes & Retrospective`.
36-
- [ ] Finalize the `Editorial Report` from the completed implementation and validation evidence.
33+
- [x] (2026-07-16 14:00Z) Added focused classifier, reminder, model, renderer, transaction, and layout tests; ran compilation, the Extension Development Host test suite, governance checks, audit, VSIX inspection, local-plugin publication, and a clean conversion/package proof.
34+
- [x] (2026-07-16 14:00Z) Updated `README.md` and `CHANGELOG.md` in English with migration, recovery, security, packaging, and deployment behavior.
35+
- [x] (2026-07-16 14:00Z) Recorded final implementation and validation evidence in `Outcomes & Retrospective`.
36+
- [x] (2026-07-16 14:00Z) Finalized the `Editorial Report` from completed implementation and validation evidence.
3737

3838
Use UTC timestamps on every progress update. Split partially completed work into explicit completed and remaining portions at every stopping point.
3939

@@ -47,6 +47,12 @@ Record unexpected behavior, compatibility constraints, parser edge cases, VS Cod
4747
- Observation: The local plugin uses version `0.1.0-SNAPSHOT`, Gradle Wrapper `9.6.1`, and documents `build/totalcross` output.
4848
Evidence: `../totalcross-gradle-plugin/build.gradle`, `gradle/wrapper/gradle-wrapper.properties`, and `README.md` inspected on 2026-07-16.
4949

50+
- Observation: The public TotalCross Maven repository did not resolve SDK `7.3.0` during a packaging proof, and a legacy SDK must compile with JDK 17 plus `options.release = 8`, not require a local JDK 8 toolchain.
51+
Evidence: A converted temporary 7.3.0 fixture failed dependency resolution; a 7.2.2 fixture initially failed with `Cannot find a Java installation ... languageVersion=8`. Rendering was changed to use a JDK 17 toolchain while retaining Java 8 bytecode for old SDKs.
52+
53+
- Observation: The Gradle plugin does produce the SSH deployer's Linux ARM install layout when `linux_arm` is selected.
54+
Evidence: The successful 7.2.2 end-to-end run wrote `build/totalcross/install/linux_arm/MigrationDemo` and its `.tcz` dependencies.
55+
5056
## Decision Log
5157

5258
- Decision: Show the migration recommendation only for a root-level `pom.xml` that is recognizably a TotalCross project and only when no root-level Gradle build files exist.
@@ -85,65 +91,71 @@ Record unexpected behavior, compatibility constraints, parser edge cases, VS Cod
8591
Rationale: This makes XML failure containment and the exact 86,400,000-millisecond boundary testable in the existing Mocha suite.
8692
Date/Author: 2026-07-16 / OpenAI
8793

88-
## Outcomes & Retrospective
89-
90-
The first milestone is complete: `src/migration/project-classifier.ts` recognizes only root TotalCross Maven POMs, and `src/migration/reminder-state.ts` persists an exact per-folder 24-hour deadline. `npm run compile` and `npm test` passed with 12 tests. Notification UI, conversion, packaging alignment, and end-to-end publication validation remain.
94+
- Decision: Always render a JDK 17 Gradle toolchain and express legacy SDK compatibility through `JavaCompile.options.release`.
95+
Rationale: The checked-out generator already uses JDK 17, while SDK 7.2.2 rejected the unavailable local JDK 8 toolchain but packaged successfully when compiled to Java 8 bytecode on JDK 17.
96+
Date/Author: 2026-07-16 / OpenAI
9197

92-
The second milestone is complete: `src/migration/migration-reminder.ts` presents the requested English prompt only once per activation and routes `Convert Now` using the selected folder URI. `package.json` exposes the retryable command. `npm run compile` and `npm test` passed with 14 tests.
98+
- Decision: Retain Gradle SSH deployment using `build/totalcross/install/linux_arm`.
99+
Rationale: The end-to-end `linux_arm` package confirmed that the plugin creates the same install directory shape expected by the existing deployer.
100+
Date/Author: 2026-07-16 / OpenAI
93101

94-
The third and fourth milestones are complete: `src/migration/maven-project.ts` normalizes supported POM values, and `src/migration/gradle-renderer.ts` builds Groovy Gradle files, wrapper resources, and `.totalcross/project.json` in memory. The renderer draws the wrapper from the pre-existing packaged `resources/gradle` tree, whose version is Gradle 9.6.1. `npm run compile` and `npm test` passed with 16 tests.
102+
## Outcomes & Retrospective
95103

96-
The fifth milestone is complete: `src/migration/convert-project.ts` writes generated files through sibling temporary paths, merges a pre-existing `gradle.properties` conservatively, validates with an argument-array Wrapper invocation, and renames the POM only after success. It preserves generated files and the original POM if Maven Local lacks the plugin, but restores ordinary failures. `npm run compile` and `npm test` passed with 18 tests before the final missing-local-plugin regression was added.
104+
All planned implementation milestones are complete. The extension now classifies eligible Maven roots, presents the exact two-action reminder, converts a selected folder transactionally, and packages/deploys converted Gradle projects through the established layout. The POM parser, renderer, transaction, reminder policy, and project-layout behaviors are covered by 20 extension tests.
97105

98-
The sixth milestone is complete: `src/project-layout.ts` identifies mixed Maven/Gradle roots instead of guessing, while `src/packager.ts` uses the project Wrapper with `--console=plain` for Gradle-only projects and preserves Maven packaging. The SSH deployer now reports that Gradle's verified `.tcz` output is not an install directory, rather than attempting an invalid upload. `npm run compile` and `npm test` passed with 20 tests.
106+
The final validation observed `npm run compile`, `npm test` (20 passing), `npm run validate:governance`, `npm run test:governance` (17 tests), and `npm run audit` (0 vulnerabilities). The sibling plugin's `./gradlew clean test publishToMavenLocal --console=plain` completed successfully. A clean 7.2.2 Maven fixture was converted, preserved its POM as `pom.xml.maven-backup`, passed Wrapper validation, and completed `./gradlew clean totalcrossPackage --console=plain`, producing Linux ARM output under `build/totalcross/install/linux_arm`. `/private/tmp/totalcross-migration.vsix` included all Wrapper resources.
99107

100108
## Editorial Report
101109

102-
This section is mandatory at completion. It must describe only observed results and remain synchronized with the final repository state.
110+
This report describes the completed repository state and only validation that was actually observed.
103111

104112
### Editorial Summary
105113

106-
To be completed from implementation evidence.
114+
Legacy TotalCross Maven workspaces needed a safe path to the Gradle plugin without suddenly removing Maven support. The completed extension recognizes only root TotalCross Maven POMs, offers a two-button English migration reminder, and can retry a folder-specific conversion from the Command Palette.
115+
116+
The conversion renders a Groovy Gradle project and Wrapper, validates the Wrapper before moving `pom.xml`, preserves source files, and protects activation keys. A clean SDK 7.2.2 fixture converted and ran `totalcrossPackage`, creating the expected Linux ARM install output.
107117

108118
### Original Plan versus Actual Outcome
109119

110-
To be completed from implementation evidence.
120+
The original plan's notification, reminder, parsing, rendering, safe conversion, Maven compatibility, local plugin resolution, and VSIX-resource goals were implemented. The renderer was adjusted during execution: legacy SDKs compile on a JDK 17 toolchain with Java 8 bytecode rather than requiring JDK 8. The initial assumption that Gradle output was unsuitable for SSH deployment was rejected after a Linux ARM proof showed the expected install directory.
111121

112122
### What Changed
113123

114-
To be completed with repository-relative paths, stable command names, templates, tests, and generated artifacts.
124+
`src/migration/` contains the classifier, reminder state/coordinator, POM model, renderer, and conversion transaction. `extension.convertMavenProjectToGradle` is contributed in `package.json` and registered by `src/extension.ts`. `src/project-layout.ts`, `src/packager.ts`, and `src/deployer.ts` distinguish Maven, Gradle, and mixed roots. `README.md` and `CHANGELOG.md` document the workflow. Existing `resources/gradle/` Wrapper assets are rendered into migrated projects and verified inside the VSIX.
115125

116126
### Decisions and Trade-offs
117127

118-
To be completed from the final `Decision Log`, including reminder persistence, dismissal behavior, Maven compatibility, and local Gradle plugin resolution.
128+
Reminder deadlines are per workspace URI, and dismissal equals a 24-hour postponement. Generated builds resolve the unpublished plugin from Maven Local and retain an incomplete conversion for retry when it is absent. The converter refuses unrelated Gradle roots. It keeps Maven support while a conversion is postponed. The JDK 17 toolchain choice costs no Java-8-only host requirement while `options.release` retains old-SDK bytecode compatibility.
119129

120130
### Unexpected Problems and Discoveries
121131

122-
To be completed from `Surprises & Discoveries`.
132+
SDK 7.3.0 could not be resolved from the configured Maven repository during an exploratory package run. More importantly, a 7.2.2 generated build failed when its toolchain was set to Java 8 because the host had no JDK 8; that directly motivated the renderer correction. A successful Linux ARM package disproved the earlier deployment-layout concern.
123133

124134
### Validation and Measurable Results
125135

126-
To be completed with exact commands and observed results only.
136+
Observed results: `npm test` passed with 20 tests; governance validation passed; its Python regression suite passed 17 tests; `npm audit --audit-level=low` reported 0 vulnerabilities. `../totalcross-gradle-plugin` completed `./gradlew clean test publishToMavenLocal --console=plain` with 15 tasks. The clean converted fixture completed `./gradlew clean totalcrossPackage --console=plain` and wrote `MigrationDemo`, `MigrationDemo.tcz`, runtime `.tcz` files, and `libtcvm.so` beneath `build/totalcross/install/linux_arm`.
127137

128138
### Useful Evidence and Examples
129139

130-
To be completed with concise references to tests, fixtures, logs, generated projects, commits, issues, or pull requests.
140+
Useful evidence includes `src/test/suite/migration-classifier.test.ts`, `maven-project.test.ts`, `migration-reminder.test.ts`, and `convert-project.test.ts`; the conversion commits beginning at `0443e77`; and the temporary validation archive `/private/tmp/totalcross-migration.vsix`. The generated fixture at `/private/tmp/totalcross-migration-e2e-final` contained `pom.xml.maven-backup`, Gradle Wrapper files, and the successful Linux ARM output during validation.
131141

132142
### Limitations, Remaining Work, and Open Questions
133143

134-
To be completed honestly. At minimum, reassess whether remote publication of the Gradle plugin, Kotlin DSL support, multi-module Maven projects, and multi-root notification sequencing remain limitations.
144+
The Gradle plugin remains unpublished remotely and must be installed with `publishToMavenLocal`. Migration emits only Groovy DSL, supports one root Maven project rather than complete multi-module Maven model building, and shows at most one prompt per activation in a multi-root workspace. The exact visual notification was not manually clicked in an interactive Extension Development Host during this non-interactive run; action routing and timing are covered by automated tests. SDK 7.3.0 availability at the configured Maven repository remains unverified for packaging.
135145

136146
### Possible Article Angles
137147

138-
To be completed with technically honest, problem-oriented article ideas.
148+
- For VS Code extension maintainers: "A safe build-system migration prompt without breaking existing workspaces" — reminder persistence and transaction boundaries.
149+
- For Gradle plugin authors: "Migrating a Maven POM without pretending to implement Maven" — constrained property resolution and clear rejection paths.
150+
- For Java build engineers: "Compile legacy bytecode with a modern JDK" — JDK 17 toolchains plus Java 8 release targets.
139151

140152
### Suggested Narrative
141153

142-
To be completed as an evidence-based outline rather than a finished article.
154+
Start with the cost of forcing legacy workspaces to migrate. Explain root-only classification and the 24-hour opt-out. Describe extracting a small POM model, rendering a marked Gradle build, and delaying the POM rename until Wrapper validation. Cover the JDK 8 toolchain discovery, the JDK 17/release-8 correction, the local plugin publication proof, Linux ARM output evidence, and the remaining remote-publication and multi-module limits.
143155

144156
### Claims Requiring Human Review
145157

146-
To be completed. Normal editorial and technical review is required even if no special claims are identified.
158+
The local plugin version, local Maven publication, and observed fixture output should receive normal technical review before publication. The configured repository's lack of SDK 7.3.0 during this run should not be generalized without separate verification. No other special claims were identified.
147159

148160
## Context and Orientation
149161

@@ -756,4 +768,4 @@ Keep VS Code UI calls in the coordinator and command layer. Keep classification,
756768

757769
Initial version created on 2026-07-16. This plan adds a one-day English-language migration recommendation and a safe assisted conversion path from legacy TotalCross Maven projects to the unpublished TotalCross Gradle plugin resolved through Maven Local.
758770

759-
Revision 2026-07-16: recorded the checked-out Gradle support and local plugin facts, then completed the classifier, reminder, UI routing, Maven-model, Gradle-rendering, transactional-conversion, and packaging-alignment milestones with deterministic tests.
771+
Revision 2026-07-16: completed all milestones, corrected legacy-SDK toolchain rendering from end-to-end evidence, confirmed Gradle Linux ARM deployment output, and finalized validation and the editorial report.

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
The default unpublished plugin version must be installed with
1111
`publishToMavenLocal`; existing Maven-only workspaces remain supported for
1212
packaging and deployment.
13+
- Legacy TotalCross Maven projects can be converted through a one-day,
14+
per-workspace Gradle migration reminder or the `TotalCross: Convert Maven
15+
Project to Gradle` command. Conversion preserves the POM until Wrapper
16+
validation succeeds, keeps activation keys out of build scripts and metadata,
17+
and can be retried after the local Gradle plugin is published.
18+
- Gradle packaging uses the project Wrapper. Mixed Maven/Gradle roots require a
19+
migration decision, while Gradle Linux ARM package output is deployed from
20+
`build/totalcross/install/linux_arm`.
1321

1422
## [0.0.15] - 2021-04-27
1523
### Changed

README.md

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,44 @@ commands:
1818
- `TotalCross: Package`
1919
- `TotalCross: Deploy`
2020
- `TotalCross: Deploy&Run`
21+
- `TotalCross: Convert Maven Project to Gradle`
2122

2223
New projects use the Gradle Wrapper included in the generated project, so a
2324
separate Gradle or Maven installation is not required. Package a project with
2425
`TotalCross: Package` or from the project directory with:
2526

2627
./gradlew totalcrossPackage
2728

28-
On Windows, use `gradlew.bat totalcrossPackage`. Generated output is rooted at
29-
`build/totalcross`; Linux ARM packages are uploaded from
30-
`build/totalcross/install/linux_arm`. Existing Maven-only projects remain
29+
On Windows, use `gradlew.bat totalcrossPackage --console=plain`. Generated
30+
output is rooted at `build/totalcross`. Existing Maven-only projects remain
3131
supported and continue to package with `mvn package` and use `target/install`.
3232

33+
## Migrating a Maven project
34+
35+
When a workspace root contains a TotalCross `pom.xml` and no root Gradle build
36+
files, the extension asks in English whether to convert it. The only actions
37+
are `Convert Now` and `Remind Me Tomorrow`. Dismissing the notification has the
38+
same effect as the reminder action: that workspace is not prompted again for
39+
exactly 24 hours. Other workspace folders have independent reminders.
40+
41+
`Convert Now` reads the TotalCross SDK and plugin configuration from the POM,
42+
creates a marked Groovy Gradle project and Wrapper, and runs `./gradlew tasks
43+
--console=plain`. The Java source tree is unchanged. The POM becomes
44+
`pom.xml.maven-backup` only after that validation succeeds. If the unpublished
45+
plugin is missing from Maven Local, the generated Gradle files and original POM
46+
remain so that publishing the plugin and retrying the command is safe.
47+
48+
The conversion writes activation keys only to project-local `gradle.properties`,
49+
which it adds to `.gitignore`; it does not put the key in `build.gradle` or
50+
`.totalcross/project.json`. A root with unrelated Maven and Gradle files is
51+
deliberately not packaged or deployed automatically, because the extension
52+
cannot know which build is authoritative.
53+
54+
For a project configured with the `linux_arm` platform, the Gradle plugin writes
55+
the SSH deployer's install directory beneath
56+
`build/totalcross/install/linux_arm`, so `TotalCross: Deploy` uses that output
57+
after packaging.
58+
3359
## Using the unpublished Gradle plugin locally
3460

3561
Before creating a project with the default `0.1.0-SNAPSHOT` plugin version,

0 commit comments

Comments
 (0)