Skip to content

Commit

Permalink
✨ Create in-editor diff view (#79)
Browse files Browse the repository at this point in the history
Use built-in vscode.diff editor to compare the current code(pointed via
file URI) with proposed changes(pointed via custom konveyorMemFs Uri).

Key points:
1. proposed changes (diffs) are applied to current code base and
   are written to in-memory file system. Late they can be accessed
   via custom URI scheme konveyorMemFs.
2. both left and right side of the diff is editable
3. available commands grouped using `konveyor` (global) 
   or `konveyor.diffView` prefix(diff view specific):
   a) applyAll - apply all fixes
   b) revertAll - discard local changes to the proposed fixes
   c) applyFile/revertFile - as above but on a single file
   d) copyDiff/copyPath - convenience commands (single file scope)
   e) next/prev - keyboard navigation (for now) using the same key
      bindings as reference-view extension (f4 and shift+f4)
   f) viewFix - wrapper around vscode.diff that uses konveyorMemFs

Sources:
1. tree view is based on built-in reference-view extension. Only
   file-item nodes are used. Support for history items and dynamic model
   changes have been dropped. However the original architecture is there
   and should allow adding more advance features in the future.
2. in-memory file system is taken as-it-is from fsprovider-sample
3. the approach (using hidden file tree for fixes) originates from
   Continue's DiffManager
5. check/discard icons taken from source-control-sample

Reference-Url:
https://github.com/continuedev/continue/blob/e7fe5994ffc6a3f45ad358ced7d6890deb145d96/extensions/vscode/src/diff/horizontal.ts#L34
Reference-Url:
https://github.com/microsoft/vscode/tree/main/extensions/references-view
Reference-Url:
https://github.com/microsoft/vscode-extension-samples/tree/main/fsprovider-sample
Reference-Url:
https://github.com/microsoft/vscode-extension-samples/tree/main/source-control-sample

---------

Signed-off-by: Radoslaw Szwajkowski <[email protected]>
  • Loading branch information
rszwajko authored Nov 11, 2024
1 parent 2403cf1 commit d2faf02
Show file tree
Hide file tree
Showing 25 changed files with 1,001 additions and 15 deletions.
16 changes: 8 additions & 8 deletions mocks/coolstore_fixEverywhere_javax_ejb_Stateless.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,32 @@
{
"original": "pom.xml",
"modified": "pom.xml",
"diff": "diff --git a/pom.xml b/pom.xml\\nindex 0e760b8..afa5e9c 100644\\n--- a/pom.xml\\n+++ b/pom.xml\\n@@ -21,6 +21,11 @@\\n <version>7.0</version>\\n <scope>provided</scope>\\n </dependency>\\n+ <dependency>\\n+ <groupId>jakarta.enterprise</groupId>\\n+ <artifactId>jakarta.enterprise.cdi-api</artifactId>\\n+ <version>4.1.0</version>\\n+ </dependency>\\n <dependency>\\n <groupId>javax</groupId>\\n <artifactId>javaee-api</artifactId>\\n"
"diff": "diff --git a/pom.xml b/pom.xml\nindex 0e760b8..afa5e9c 100644\n--- a/pom.xml\n+++ b/pom.xml\n@@ -21,6 +21,11 @@\n <version>7.0</version>\n <scope>provided</scope>\n </dependency>\n+ <dependency>\n+ <groupId>jakarta.enterprise</groupId>\n+ <artifactId>jakarta.enterprise.cdi-api</artifactId>\n+ <version>4.1.0</version>\n+ </dependency>\n <dependency>\n <groupId>javax</groupId>\n <artifactId>javaee-api</artifactId>\n"
},
{
"original": "src/main/java/com/redhat/coolstore/service/CatalogService.java",
"modified": "src/main/java/com/redhat/coolstore/service/CatalogService.java",
"diff": "diff --git a/src/main/java/com/redhat/coolstore/service/CatalogService.java b/src/main/java/com/redhat/coolstore/service/CatalogService.java\\nindex 422a3f4..9a6feff 100644\\n--- a/src/main/java/com/redhat/coolstore/service/CatalogService.java\\n+++ b/src/main/java/com/redhat/coolstore/service/CatalogService.java\\n@@ -9,\\n12 +9,\\n12 @@ import javax.persistence.criteria.CriteriaBuilder;\\n import javax.persistence.criteria.CriteriaQuery;\\n import javax.persistence.criteria.Root;\\n \\n-import javax.ejb.Stateless;\\n+import jakarta.enterprise.context.ApplicationScoped;\\n import javax.persistence.EntityManager;\\n \\n import com.redhat.coolstore.model.*;\\n \\n-@Stateless\\n+@ApplicationScoped\\n public class CatalogService {\\n \\n @Inject\\n"
"diff": "diff --git a/src/main/java/com/redhat/coolstore/service/CatalogService.java b/src/main/java/com/redhat/coolstore/service/CatalogService.java\nindex 422a3f4..9a6feff 100644\n--- a/src/main/java/com/redhat/coolstore/service/CatalogService.java\n+++ b/src/main/java/com/redhat/coolstore/service/CatalogService.java\n@@ -9,12 +9,12 @@ import javax.persistence.criteria.CriteriaBuilder;\n import javax.persistence.criteria.CriteriaQuery;\n import javax.persistence.criteria.Root;\n \n-import javax.ejb.Stateless;\n+import jakarta.enterprise.context.ApplicationScoped;\n import javax.persistence.EntityManager;\n \n import com.redhat.coolstore.model.*;\n \n-@Stateless\n+@ApplicationScoped\n public class CatalogService {\n \n @Inject\n"
},
{
"original": "src/main/java/com/redhat/coolstore/service/OrderService.java",
"modified": "src/main/java/com/redhat/coolstore/service/OrderService.java",
"diff": "diff --git a/src/main/java/com/redhat/coolstore/service/OrderService.java b/src/main/java/com/redhat/coolstore/service/OrderService.java\\nindex 748e413..07ad379 100644\\n--- a/src/main/java/com/redhat/coolstore/service/OrderService.java\\n+++ b/src/main/java/com/redhat/coolstore/service/OrderService.java\\n@@ -2,\\n 14 +2,\\n 14 @@ package com.redhat.coolstore.service;\\n \\n import com.redhat.coolstore.model.Order;\\n import java.util.List;\\n-import javax.ejb.Stateless;\\n+import jakarta.enterprise.context.ApplicationScoped;\\n import javax.inject.Inject;\\n import javax.persistence.EntityManager;\\n import javax.persistence.criteria.CriteriaBuilder;\\n import javax.persistence.criteria.CriteriaQuery;\\n import javax.persistence.criteria.Root;\\n \\n-@Stateless\\n+@ApplicationScoped\\n public class OrderService {\\n \\n @Inject\\n"
"diff": "diff --git a/src/main/java/com/redhat/coolstore/service/OrderService.java b/src/main/java/com/redhat/coolstore/service/OrderService.java\nindex 748e413..07ad379 100644\n--- a/src/main/java/com/redhat/coolstore/service/OrderService.java\n+++ b/src/main/java/com/redhat/coolstore/service/OrderService.java\n@@ -2,14 +2,14 @@ package com.redhat.coolstore.service;\n \n import com.redhat.coolstore.model.Order;\n import java.util.List;\n-import javax.ejb.Stateless;\n+import jakarta.enterprise.context.ApplicationScoped;\n import javax.inject.Inject;\n import javax.persistence.EntityManager;\n import javax.persistence.criteria.CriteriaBuilder;\n import javax.persistence.criteria.CriteriaQuery;\n import javax.persistence.criteria.Root;\n \n-@Stateless\n+@ApplicationScoped\n public class OrderService {\n \n @Inject\n"
},
{
"original": "src/main/java/com/redhat/coolstore/service/ProductService.java",
"modified": "src/main/java/com/redhat/coolstore/service/ProductService.java",
"diff": "diff --git a/src/main/java/com/redhat/coolstore/service/ProductService.java b/src/main/java/com/redhat/coolstore/service/ProductService.java\\nindex 33002fd..0e4b157 100644\\n--- a/src/main/java/com/redhat/coolstore/service/ProductService.java\\n+++ b/src/main/java/com/redhat/coolstore/service/ProductService.java\\n@@ -4,\\n14 +4,\\n14 @@ import com.redhat.coolstore.model.CatalogItemEntity;\\n import com.redhat.coolstore.model.Product;\\n import com.redhat.coolstore.utils.Transformers;\\n \\n-import javax.ejb.Stateless;\\n+import jakarta.enterprise.context.ApplicationScoped;\\n import javax.inject.Inject;\\n import java.util.List;\\n import java.util.stream.Collectors;\\n \\n import static com.redhat.coolstore.utils.Transformers.toProduct;\\n \\n-@Stateless\\n+@ApplicationScoped\\n public class ProductService {\\n \\n @Inject\\n"
"diff": "diff --git a/src/main/java/com/redhat/coolstore/service/ProductService.java b/src/main/java/com/redhat/coolstore/service/ProductService.java\nindex 33002fd..0e4b157 100644\n--- a/src/main/java/com/redhat/coolstore/service/ProductService.java\n+++ b/src/main/java/com/redhat/coolstore/service/ProductService.java\n@@ -4,14 +4,14 @@ import com.redhat.coolstore.model.CatalogItemEntity;\n import com.redhat.coolstore.model.Product;\n import com.redhat.coolstore.utils.Transformers;\n \n-import javax.ejb.Stateless;\n+import jakarta.enterprise.context.ApplicationScoped;\n import javax.inject.Inject;\n import java.util.List;\n import java.util.stream.Collectors;\n \n import static com.redhat.coolstore.utils.Transformers.toProduct;\n \n-@Stateless\n+@ApplicationScoped\n public class ProductService {\n \n @Inject\n"
},
{
"original": "src/main/java/com/redhat/coolstore/service/ShippingService.java",
"modified": "src/main/java/com/redhat/coolstore/service/ShippingService.java",
"diff": "diff --git a/src/main/java/com/redhat/coolstore/service/ShippingService.java b/src/main/java/com/redhat/coolstore/service/ShippingService.java\\nindex c820fcd..d92ef4f 100644\\n--- a/src/main/java/com/redhat/coolstore/service/ShippingService.java\\n+++ b/src/main/java/com/redhat/coolstore/service/ShippingService.java\\n@@ -4,\\n 11 +4,\\n 11 @@ import java.math.BigDecimal;\\n import java.math.RoundingMode;\\n \\n import javax.ejb.Remote;\\n-import javax.ejb.Stateless;\\n+import jakarta.enterprise.context.ApplicationScoped;\\n \\n import com.redhat.coolstore.model.ShoppingCart;\\n \\n-@Stateless\\n+@ApplicationScoped\\n @Remote\\n public class ShippingService implements ShippingServiceRemote {\\n \\n"
"diff": "diff --git a/src/main/java/com/redhat/coolstore/service/ShippingService.java b/src/main/java/com/redhat/coolstore/service/ShippingService.java\nindex c820fcd..d92ef4f 100644\n--- a/src/main/java/com/redhat/coolstore/service/ShippingService.java\n+++ b/src/main/java/com/redhat/coolstore/service/ShippingService.java\n@@ -4,11 +4,11 @@ import java.math.BigDecimal;\n import java.math.RoundingMode;\n \n import javax.ejb.Remote;\n-import javax.ejb.Stateless;\n+import jakarta.enterprise.context.ApplicationScoped;\n \n import com.redhat.coolstore.model.ShoppingCart;\n \n-@Stateless\n+@ApplicationScoped\n @Remote\n public class ShippingService implements ShippingServiceRemote {\n \n"
},
{
"original": "src/main/java/com/redhat/coolstore/service/ShoppingCartOrderProcessor.java b/src/main/java/com/redhat/coolstore/service/ShoppingCartOrderProcessor.java",
"modified": "src/main/java/com/redhat/coolstore/service/ShoppingCartOrderProcessor.java b/src/main/java/com/redhat/coolstore/service/ShoppingCartOrderProcessor.java",
"diff": "diff --git a/src/main/java/com/redhat/coolstore/service/ShoppingCartOrderProcessor.java b/src/main/java/com/redhat/coolstore/service/ShoppingCartOrderProcessor.java\\nindex e6ee388..5f9a1b6 100644\\n--- a/src/main/java/com/redhat/coolstore/service/ShoppingCartOrderProcessor.java\\n+++ b/src/main/java/com/redhat/coolstore/service/ShoppingCartOrderProcessor.java\\n@@ -1,\\n 7 +1,\\n 7 @@\\n package com.redhat.coolstore.service;\\n \\n import java.util.logging.Logger;\\n-import javax.ejb.Stateless;\\n+import jakarta.enterprise.context.ApplicationScoped;\\n import javax.annotation.Resource;\\n import javax.inject.Inject;\\n import javax.jms.JMSContext;\\n@@ -10,\\n 7 +10,\\n 7 @@ import javax.jms.Topic;\\n import com.redhat.coolstore.model.ShoppingCart;\\n import com.redhat.coolstore.utils.Transformers;\\n \\n-@Stateless\\n+@ApplicationScoped\\n public class ShoppingCartOrderProcessor {\\n \\n @Inject\\n"
"original": "src/main/java/com/redhat/coolstore/service/ShoppingCartOrderProcessor.java",
"modified": "src/main/java/com/redhat/coolstore/service/ShoppingCartOrderProcessor.java",
"diff": "diff --git a/src/main/java/com/redhat/coolstore/service/ShoppingCartOrderProcessor.java b/src/main/java/com/redhat/coolstore/service/ShoppingCartOrderProcessor.java\nindex e6ee388..5f9a1b6 100644\n--- a/src/main/java/com/redhat/coolstore/service/ShoppingCartOrderProcessor.java\n+++ b/src/main/java/com/redhat/coolstore/service/ShoppingCartOrderProcessor.java\n@@ -1,7 +1,7 @@\n package com.redhat.coolstore.service;\n \n import java.util.logging.Logger;\n-import javax.ejb.Stateless;\n+import jakarta.enterprise.context.ApplicationScoped;\n import javax.annotation.Resource;\n import javax.inject.Inject;\n import javax.jms.JMSContext;\n@@ -10,7 +10,7 @@ import javax.jms.Topic;\n import com.redhat.coolstore.model.ShoppingCart;\n import com.redhat.coolstore.utils.Transformers;\n \n-@Stateless\n+@ApplicationScoped\n public class ShoppingCartOrderProcessor {\n \n @Inject\n"
}
]
}
20 changes: 19 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

142 changes: 140 additions & 2 deletions vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,56 @@
"command": "konveyor.loadSolution",
"title": "Load solution",
"category": "Konveyor"
},
{
"command": "konveyor.diffView.applyAll",
"title": "Apply All",
"category": "Resolutions",
"icon": {
"light": "resources/icons/light/check.svg",
"dark": "resources/icons/dark/check.svg"
}
},
{
"command": "konveyor.diffView.revertAll",
"title": "Discard local changes to Resolutions",
"category": "Resolutions",
"icon": {
"light": "resources/icons/light/discard.svg",
"dark": "resources/icons/dark/discard.svg"
}
},
{
"command": "konveyor.diffView.applyFile",
"title": "Apply",
"icon": {
"light": "resources/icons/light/check.svg",
"dark": "resources/icons/dark/check.svg"
}
},
{
"command": "konveyor.diffView.revertFile",
"title": "Discard local changes to Resolutions",
"icon": {
"light": "resources/icons/light/discard.svg",
"dark": "resources/icons/dark/discard.svg"
}
},
{
"command": "konveyor.diffView.copyDiff",
"title": "Copy Diff"
},
{
"command": "konveyor.diffView.copyPath",
"title": "Copy Path"
},
{
"command": "konveyor.diffView.next",
"title": "Go to Next File"
},
{
"command": "konveyor.diffView.prev",
"title": "Go to Previous File"
}
],
"submenus": [
Expand All @@ -118,6 +168,10 @@
"id": "konveyor.konveyorGUIView",
"name": "Konveyor",
"visibility": "visible"
},
{
"id": "konveyor.diffView",
"name": "Konveyor Resolutions"
}
]
},
Expand All @@ -127,6 +181,48 @@
"command": "konveyor.toggleFullScreen",
"group": "navigation@1",
"when": "view == konveyor.konveyorGUIView"
},
{
"command": "konveyor.diffView.applyAll",
"group": "navigation@1",
"when": "view == konveyor.diffView"
},
{
"command": "konveyor.diffView.revertAll",
"group": "navigation@2",
"when": "view == konveyor.diffView"
}
],
"view/item/context": [
{
"command": "konveyor.diffView.applyFile",
"group": "inline",
"when": "view == konveyor.diffView && viewItem == file-item"
},
{
"command": "konveyor.diffView.revertFile",
"group": "inline",
"when": "view == konveyor.diffView && viewItem == file-item"
},
{
"command": "konveyor.diffView.applyFile",
"group": "1@1",
"when": "view == konveyor.diffView && viewItem == file-item"
},
{
"command": "konveyor.diffView.revertFile",
"group": "1@2",
"when": "view == konveyor.diffView && viewItem == file-item"
},
{
"command": "konveyor.diffView.copyDiff",
"group": "2@1",
"when": "view == konveyor.diffView && viewItem == file-item"
},
{
"command": "konveyor.diffView.copyPath",
"group": "2@2",
"when": "view == konveyor.diffView && viewItem == file-item"
}
],
"editor/title": [
Expand All @@ -151,6 +247,36 @@
{
"command": "konveyor.loadSolution",
"when": "never"
},
{
"command": "konveyor.diffView.applyFile",
"when": "never"
},
{
"command": "konveyor.diffView.revertFile",
"when": "never"
},
{
"command": "konveyor.diffView.copyDiff",
"when": "never"
},
{
"command": "konveyor.diffView.copyPath",
"when": "never"
},
{
"command": "konveyor.diffView.next",
"when": "never"
},
{
"command": "konveyor.diffView.prev",
"when": "never"
},
{
"command": "konveyor.diffView.applyAll"
},
{
"command": "konveyor.diffView.revertAll"
}
]
},
Expand Down Expand Up @@ -289,6 +415,16 @@
}
]
}
],
"keybindings": [
{
"command": "konveyor.diffView.next",
"key": "f4"
},
{
"command": "konveyor.diffView.prev",
"key": "shift+f4"
}
]
},
"scripts": {
Expand All @@ -303,6 +439,7 @@
},
"devDependencies": {
"@types/chai": "^5.0.0",
"@types/diff": "^6.0.0",
"@types/mocha": "^10.0.9",
"@types/node": "20.x",
"@types/react": "^18.3.8",
Expand All @@ -323,6 +460,7 @@
},
"dependencies": {
"@shared/types": "^1.0.0",
"babel-loader": "^9.2.1"
"babel-loader": "^9.2.1",
"diff": "^7.0.0"
}
}
}
1 change: 1 addition & 0 deletions vscode/resources/icons/dark/check.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions vscode/resources/icons/dark/discard.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions vscode/resources/icons/light/check.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions vscode/resources/icons/light/discard.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 9 additions & 1 deletion vscode/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from "vscode";
import { cleanRuleSets, loadRuleSets, loadSolution, loadStaticResults } from "./data";
import { GetSolutionResult, RuleSet } from "@shared/types";
import { applyAll, revertAll, copyDiff, copyPath, FileItem, viewFix } from "./diffView";

let fullScreenPanel: WebviewPanel | undefined;

Expand Down Expand Up @@ -320,7 +321,14 @@ const commandsMap: (state: ExtensionState) => {
"konveyor.loadRuleSets": (ruleSets: RuleSet[]): void => loadRuleSets(state, ruleSets),
"konveyor.cleanRuleSets": () => cleanRuleSets(state),
"konveyor.loadStaticResults": loadStaticResults,
"konveyor.loadSolution": (solution: GetSolutionResult): void => loadSolution(state, solution),
"konveyor.loadSolution": async (solution: GetSolutionResult) => loadSolution(state, solution),
"konveyor.applyAll": () => applyAll(state),
"konveyor.applyFile": (item: FileItem) => item.apply(),
"konveyor.copyDiff": copyDiff,
"konveyor.copyPath": copyPath,
"konveyor.diffView.viewFix": viewFix,
"konveyor.diffView.revertAll": () => revertAll(state),
"konveyor.diffView.revertFile": (item: FileItem) => item.revert(),
};
};

Expand Down
Loading

0 comments on commit d2faf02

Please sign in to comment.