From e65e8086f328a20adf3f941e1be988d0d757dc0f Mon Sep 17 00:00:00 2001 From: Alexander Mills Date: Fri, 7 Aug 2026 14:01:31 -0500 Subject: [PATCH 1/3] feat: add Eclipse workspace marker model --- .github/workflows/ci.yml | 25 ++++++++++ README.md | 16 ++++-- conformance/ide-integration.json | 24 +++++++++ .../tech/zpkg/eclipse/ZedWorkspaceModel.java | 50 +++++++++++++++++++ .../zpkg/eclipse/ZedWorkspaceModelTest.java | 43 ++++++++++++++++ 5 files changed, 155 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 conformance/ide-integration.json create mode 100644 src/main/java/tech/zpkg/eclipse/ZedWorkspaceModel.java create mode 100644 src/test/java/tech/zpkg/eclipse/ZedWorkspaceModelTest.java diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..b886041 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,25 @@ +name: ci + +on: + pull_request: + push: + branches: [main] + +permissions: + contents: read + +jobs: + java: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '21' + cache: maven + - run: mvn --batch-mode test diff --git a/README.md b/README.md index 4fba735..5270c73 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,17 @@ # zed-eclipse -Buildable Eclipse core candidate for Zed Package Manager state, diagnostics, and recommended actions. +Eclipse integration work for Zed Package Manager state, diagnostics, and confirmation-gated recommended actions. -The Java process adapter uses an argv vector, a bounded timeout, schema validation, failure redaction, and rejects command actions that do not require explicit confirmation. `mvn test` exercises the safety boundary. +The dedicated repository now contains: -A dedicated repository still needs the PDE/OSGi bundle, Zed Packages view, workspace markers, quick fixes, p2 update site, and clean Eclipse application tests. +- a Java 21 process adapter using argv execution, bounded timeout, schema validation, failure redaction, and unsafe-action rejection; +- a multi-root workspace model for the future **Zed Packages** view; +- Problems-marker projections with file-specific resources and `.zpkg.toml` fallback markers; +- confirmation-gated quick-fix command previews carrying exact executable, argv, and working directory; +- JUnit coverage and cross-platform Maven CI. + +```sh +mvn test +``` + +Remaining native work is the PDE/OSGi bundle, resource listeners, view and quick-fix UI wiring, clean Eclipse application tests, and p2 feature/update-site packaging. diff --git a/conformance/ide-integration.json b/conformance/ide-integration.json new file mode 100644 index 0000000..76c64f2 --- /dev/null +++ b/conformance/ide-integration.json @@ -0,0 +1,24 @@ +{ + "schema": "zed-pkg/ide-integration-conformance/v1", + "integration": "eclipse", + "repository": "zed-pkg/zed-eclipse", + "contractVersion": 1, + "level": {"core": "pass", "nativeShell": "workspace-marker-model", "distribution": "repository"}, + "capabilities": { + "multiRootDiscovery": "workspace-model", + "manifestDiagnostics": true, + "lockDiagnostics": true, + "materializationDiagnostics": true, + "stagingRecovery": true, + "argvExecution": true, + "boundedExecution": true, + "outputRedaction": true, + "explicitMutationConfirmation": true, + "problemsMarkerProjection": true, + "versionedInspectAdapter": "pending-zed-cli-191", + "nativeUnitTests": true, + "repoLocalCI": true + }, + "remaining": ["PDE/OSGi bundle", "Zed Packages view", "workspace resource listeners", "quick-fix UI wiring", "Eclipse application test", "p2 update site"], + "linearIssue": "DEN-2508" +} diff --git a/src/main/java/tech/zpkg/eclipse/ZedWorkspaceModel.java b/src/main/java/tech/zpkg/eclipse/ZedWorkspaceModel.java new file mode 100644 index 0000000..f08f2c3 --- /dev/null +++ b/src/main/java/tech/zpkg/eclipse/ZedWorkspaceModel.java @@ -0,0 +1,50 @@ +package tech.zpkg.eclipse; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +public final class ZedWorkspaceModel { + public record PackageNode(String root, long errors, long warnings, List issues) {} + public record Marker(String workspaceRoot, String resource, String severity, String issueId, String message) {} + public record ActionPreview(String executable, List arguments, String workingDirectory, boolean requiresConfirmation) {} + public record Snapshot(List packages, List markers) {} + + private ZedWorkspaceModel() {} + + public static Snapshot project(List reports) { + var packages = new ArrayList(); + var markers = new ArrayList(); + for (var report : reports == null ? List.of() : reports) { + var root = Path.of(report.workspaceRoot()).toAbsolutePath().normalize(); + var issues = report.issues() == null ? List.of() : report.issues(); + long errors = issues.stream().filter(issue -> "error".equalsIgnoreCase(issue.severity())).count(); + long warnings = issues.stream().filter(issue -> "warning".equalsIgnoreCase(issue.severity())).count(); + packages.add(new PackageNode(root.toString(), errors, warnings, List.copyOf(issues))); + for (var issue : issues) { + var files = issue.files() == null || issue.files().isEmpty() ? List.of(".zpkg.toml") : issue.files(); + for (var file : files) { + var resourcePath = Path.of(file); + var resource = resourcePath.isAbsolute() ? resourcePath.normalize() : root.resolve(resourcePath).normalize(); + markers.add(new Marker(root.toString(), resource.toString(), issue.severity(), issue.id(), issue.title() + ": " + issue.detail())); + } + } + } + packages.sort(Comparator.comparing(PackageNode::root)); + markers.sort(Comparator.comparing(Marker::resource).thenComparing(Marker::issueId)); + return new Snapshot(List.copyOf(packages), List.copyOf(markers)); + } + + public static ActionPreview preview(ZedInspector.Action action, Path root) { + if (!"command".equals(action.kind())) throw new IllegalArgumentException("only command actions have an execution preview"); + if (!action.requiresConfirmation()) throw new IllegalArgumentException("command actions must require explicit confirmation"); + if (action.command() == null || action.command().isBlank()) throw new IllegalArgumentException("command executable must not be blank"); + return new ActionPreview( + action.command(), + List.copyOf(action.arguments() == null ? List.of() : action.arguments()), + root.toAbsolutePath().normalize().toString(), + true + ); + } +} diff --git a/src/test/java/tech/zpkg/eclipse/ZedWorkspaceModelTest.java b/src/test/java/tech/zpkg/eclipse/ZedWorkspaceModelTest.java new file mode 100644 index 0000000..f751ad3 --- /dev/null +++ b/src/test/java/tech/zpkg/eclipse/ZedWorkspaceModelTest.java @@ -0,0 +1,43 @@ +package tech.zpkg.eclipse; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.nio.file.Path; +import java.util.List; +import org.junit.jupiter.api.Test; + +class ZedWorkspaceModelTest { + @Test + void projectsPackagesAndProblemsMarkersAcrossWorkspaceRoots() { + var warning = new ZedInspector.Issue( + "lock.stale", "warning", "Stale lock", "lock is stale", List.of(".zpkg.lock"), + List.of(new ZedInspector.Action("install", "Install", "command", "zed", List.of("install"), true)) + ); + var error = new ZedInspector.Issue("manifest.invalid", "error", "Invalid manifest", "bad toml", List.of(), List.of()); + var snapshot = ZedWorkspaceModel.project(List.of( + new ZedInspector.Report(1, "zeta", null, List.of(warning)), + new ZedInspector.Report(1, "alpha", null, List.of(error)) + )); + assertEquals(2, snapshot.packages().size()); + assertTrue(snapshot.packages().get(0).root().endsWith("alpha")); + assertEquals(1, snapshot.packages().get(0).errors()); + assertEquals(1, snapshot.packages().get(1).warnings()); + assertEquals(2, snapshot.markers().size()); + assertTrue(snapshot.markers().stream().anyMatch(marker -> marker.resource().endsWith(".zpkg.toml"))); + assertTrue(snapshot.markers().stream().anyMatch(marker -> marker.resource().endsWith(".zpkg.lock"))); + } + + @Test + void previewsOnlyConfirmationGatedQuickFixCommands() { + var action = new ZedInspector.Action("install", "Install", "command", "zed", List.of("install"), true); + var preview = ZedWorkspaceModel.preview(action, Path.of("workspace")); + assertEquals("zed", preview.executable()); + assertEquals(List.of("install"), preview.arguments()); + assertTrue(preview.requiresConfirmation()); + assertThrows(IllegalArgumentException.class, () -> ZedWorkspaceModel.preview( + new ZedInspector.Action("bad", "Bad", "command", "zed", List.of("install"), false), Path.of("workspace") + )); + } +} From 58394c48e704f041bb29be7e9079806e25abd41e Mon Sep 17 00:00:00 2001 From: Alexander Mills Date: Fri, 7 Aug 2026 22:59:00 -0500 Subject: [PATCH 2/3] ci: pin Eclipse workflow inputs --- .github/workflows/ci.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b886041..6187535 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,14 +10,17 @@ permissions: jobs: java: + timeout-minutes: 20 strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-24.04, macos-15, windows-2025] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v6 - - uses: actions/setup-java@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5.6.0 with: distribution: temurin java-version: '21' From 246b46048cced1d1072afd3bedc9849efe3a8a8f Mon Sep 17 00:00:00 2001 From: Alexander Mills Date: Fri, 7 Aug 2026 23:18:04 -0500 Subject: [PATCH 3/3] docs: record immutable Eclipse CI conformance --- conformance/ide-integration.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/conformance/ide-integration.json b/conformance/ide-integration.json index 76c64f2..fc7a315 100644 --- a/conformance/ide-integration.json +++ b/conformance/ide-integration.json @@ -17,7 +17,10 @@ "problemsMarkerProjection": true, "versionedInspectAdapter": "pending-zed-cli-191", "nativeUnitTests": true, - "repoLocalCI": true + "repoLocalCI": true, + "immutableWorkflowInputs": true, + "fixedRunnerImages": true, + "checkoutCredentialsPersisted": false }, "remaining": ["PDE/OSGi bundle", "Zed Packages view", "workspace resource listeners", "quick-fix UI wiring", "Eclipse application test", "p2 update site"], "linearIssue": "DEN-2508"