This is an automated email from the ASF dual-hosted git repository.
thiagoelg pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-tools.git
The following commit(s) were added to refs/heads/main by this push:
new 2ee0df609d3 [kie-issues#2145] Loading WID File from /global or
location of a BPMN file (#3371)
2ee0df609d3 is described below
commit 2ee0df609d355ae07d4343939a46818764726fae
Author: Jozef Marko <[email protected]>
AuthorDate: Wed Jan 7 12:30:26 2026 +0100
[kie-issues#2145] Loading WID File from /global or location of a BPMN file
(#3371)
Co-authored-by: Thiago Lugli <[email protected]>
---
packages/kie-editors-standalone/src/bpmn/index.ts | 4 +-
.../StandaloneEditorsEditorChannelApiImpl.ts | 7 +-
.../client/session/BPMNSessionInitializer.java | 23 +-
.../client/session/BPMNSessionInitializerTest.java | 19 +-
.../WorkItemDefinitionStandaloneClientService.java | 44 +++-
.../selenium/BPMNDesignerKogitoSeleniumIT.java | 2 +-
.../services/BPMNStaticResourceContentService.java | 12 +-
.../marshall/service/BPMNClientDiagramService.java | 11 +-
.../src/VsCodeKieEditorControllerFactory.ts | 7 -
...VsCodeResourceContentServiceForDanglingFiles.ts | 1 -
.../VsCodeResourceContentServiceForWorkspaces.ts | 144 ++++++-----
.../VsCodeResourceContentServiceIsomorphicGitFs.ts | 9 +
...eResourceContentServiceForDanglingFiles.test.ts | 1 -
...CodeResourceContentServiceForWorkspaces.test.ts | 285 +++++++++++++++++++++
.../vscode-extension/tests/__mocks__/vscode.ts | 33 ++-
.../src/context/WorkspacesContextProvider.tsx | 4 +-
.../src/services/WorkspaceService.tsx | 13 +-
.../src/worker/WorkspacesWorkerApiImpl.ts | 1 -
pnpm-lock.yaml | 28 +-
19 files changed, 503 insertions(+), 145 deletions(-)
diff --git a/packages/kie-editors-standalone/src/bpmn/index.ts
b/packages/kie-editors-standalone/src/bpmn/index.ts
index 412d633f1ed..0edee4c21bb 100644
--- a/packages/kie-editors-standalone/src/bpmn/index.ts
+++ b/packages/kie-editors-standalone/src/bpmn/index.ts
@@ -88,7 +88,9 @@ export function open(args: {
stateControl,
{
normalizedPosixPathRelativeToTheWorkspaceRoot: "", // FIXME:
https://github.com/apache/incubator-kie-issues/issues/811
- fileName: "", // FIXME:
https://github.com/apache/incubator-kie-issues/issues/811
+ // `fileName` is needed for `widService` that loads Work Item
Definitions in `BPMNClientDiagramService`
+ // see `transform` and `doTransform` in `BPMNClientDiagramService` and
`WorkItemDefinitionStandaloneClientService` implementation
+ fileName: "default", // FIXME:
https://github.com/apache/incubator-kie-issues/issues/811
fileExtension: "bpmn",
getFileContents: () => Promise.resolve(args.initialContent),
isReadOnly: args.readOnly ?? false,
diff --git
a/packages/kie-editors-standalone/src/envelope/StandaloneEditorsEditorChannelApiImpl.ts
b/packages/kie-editors-standalone/src/envelope/StandaloneEditorsEditorChannelApiImpl.ts
index c85c703b52d..8df8ab7e64e 100644
---
a/packages/kie-editors-standalone/src/envelope/StandaloneEditorsEditorChannelApiImpl.ts
+++
b/packages/kie-editors-standalone/src/envelope/StandaloneEditorsEditorChannelApiImpl.ts
@@ -23,7 +23,6 @@ import {
ResourceContentRequest,
ResourceListRequest,
ResourcesList,
- ContentType,
} from "@kie-tools-core/workspace/dist/api";
import {
EditorContent,
@@ -107,7 +106,11 @@ export class StandaloneEditorsEditorChannelApiImpl
implements KogitoEditorChanne
}
const matcher = new Minimatch(request.pattern);
- const matches = Array.from(this.resources.keys()).filter((path) =>
matcher.match(path));
+ const matches = Array.from(this.resources.keys()).filter((path) => {
+ const pathAdaptedForSlashPrefixedPattern =
+ (request.pattern.startsWith("/") && !path.startsWith("/") ? "/" : "")
+ path;
+ return matcher.match(pathAdaptedForSlashPrefixedPattern);
+ });
return new ResourcesList(request.pattern, matches);
}
diff --git
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-client/src/main/java/org/kie/workbench/common/stunner/bpmn/client/session/BPMNSessionInitializer.java
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-client/src/main/java/org/kie/workbench/common/stunner/bpmn/client/session/BPMNSessionInitializer.java
index dfc5ec3e0ab..96cf87f9973 100644
---
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-client/src/main/java/org/kie/workbench/common/stunner/bpmn/client/session/BPMNSessionInitializer.java
+++
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-client/src/main/java/org/kie/workbench/common/stunner/bpmn/client/session/BPMNSessionInitializer.java
@@ -20,19 +20,15 @@
package org.kie.workbench.common.stunner.bpmn.client.session;
-import java.util.Collection;
import java.util.logging.Logger;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
-import elemental2.promise.Promise;
import
org.kie.workbench.common.stunner.bpmn.client.dataproviders.CalledElementFormProvider;
import
org.kie.workbench.common.stunner.bpmn.client.dataproviders.RuleFlowGroupFormProvider;
import
org.kie.workbench.common.stunner.bpmn.client.diagram.DiagramTypeClientService;
-import
org.kie.workbench.common.stunner.bpmn.client.workitem.WorkItemDefinitionClientService;
import org.kie.workbench.common.stunner.bpmn.qualifiers.BPMN;
-import org.kie.workbench.common.stunner.bpmn.workitem.WorkItemDefinition;
import
org.kie.workbench.common.stunner.core.client.session.impl.SessionInitializer;
import org.kie.workbench.common.stunner.core.diagram.Metadata;
import org.uberfire.mvp.Command;
@@ -43,18 +39,15 @@ public class BPMNSessionInitializer implements
SessionInitializer {
private static Logger LOGGER =
Logger.getLogger(BPMNSessionInitializer.class.getName());
- private final WorkItemDefinitionClientService workItemDefinitionService;
private final DiagramTypeClientService diagramTypeService;
// CDI proxy.
protected BPMNSessionInitializer() {
- this(null, null);
+ this(null);
}
@Inject
- public BPMNSessionInitializer(final WorkItemDefinitionClientService
workItemDefinitionService,
- final DiagramTypeClientService
diagramTypeService) {
- this.workItemDefinitionService = workItemDefinitionService;
+ public BPMNSessionInitializer(final DiagramTypeClientService
diagramTypeService) {
this.diagramTypeService = diagramTypeService;
}
@@ -64,16 +57,6 @@ public class BPMNSessionInitializer implements
SessionInitializer {
diagramTypeService.loadDiagramType(metadata);
CalledElementFormProvider.initServerData();
RuleFlowGroupFormProvider.initServerData();
- workItemDefinitionService
- .call(metadata)
- .then(workItemDefinitions -> {
- completeCallback.execute();
- return null;
- })
-
.catch_((Promise.CatchOnRejectedCallbackFn<Collection<WorkItemDefinition>>)
error -> {
- LOGGER.severe("Error obtaining the work item definitions
[error=" + error + "]");
- completeCallback.execute();
- return null;
- });
+ completeCallback.execute();
}
}
diff --git
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-client/src/test/java/org/kie/workbench/common/stunner/bpmn/client/session/BPMNSessionInitializerTest.java
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-client/src/test/java/org/kie/workbench/common/stunner/bpmn/client/session/BPMNSessionInitializerTest.java
index c9ce04aa08c..5b84788a740 100644
---
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-client/src/test/java/org/kie/workbench/common/stunner/bpmn/client/session/BPMNSessionInitializerTest.java
+++
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-client/src/test/java/org/kie/workbench/common/stunner/bpmn/client/session/BPMNSessionInitializerTest.java
@@ -20,34 +20,21 @@
package org.kie.workbench.common.stunner.bpmn.client.session;
-import elemental2.promise.IThenable;
-import elemental2.promise.Promise;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import
org.kie.workbench.common.stunner.bpmn.client.diagram.DiagramTypeClientService;
-import
org.kie.workbench.common.stunner.bpmn.client.workitem.WorkItemDefinitionClientService;
import org.kie.workbench.common.stunner.core.diagram.Metadata;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.uberfire.mvp.Command;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@RunWith(MockitoJUnitRunner.class)
public class BPMNSessionInitializerTest {
- @Mock
- private WorkItemDefinitionClientService workItemDefinitionService;
-
- @Mock
- private Promise promise;
-
@Mock
private DiagramTypeClientService diagramTypeService;
@@ -56,10 +43,7 @@ public class BPMNSessionInitializerTest {
@Before
@SuppressWarnings("unchecked")
public void setUp() {
-
doReturn(promise).when(workItemDefinitionService).call(any(Metadata.class));
-
doReturn(promise).when(promise).then(any(IThenable.ThenOnFulfilledCallbackFn.class));
-
doReturn(promise).when(promise).catch_(any(Promise.CatchOnRejectedCallbackFn.class));
- tested = new BPMNSessionInitializer(workItemDefinitionService,
diagramTypeService);
+ tested = new BPMNSessionInitializer(diagramTypeService);
}
@Test
@@ -68,6 +52,5 @@ public class BPMNSessionInitializerTest {
Command callback = mock(Command.class);
tested.init(metadata, callback);
verify(diagramTypeService).loadDiagramType(metadata);
- verify(workItemDefinitionService, times(1)).call(eq(metadata));
}
}
diff --git
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/main/java/org/kie/workbench/common/stunner/kogito/client/services/WorkItemDefinitionStandaloneClientService.java
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/main/java/org/kie/workbench/common/stunner/kogito/client/services/WorkI
[...]
index a5d682bc211..a7a624f4f4f 100644
---
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/main/java/org/kie/workbench/common/stunner/kogito/client/services/WorkItemDefinitionStandaloneClientService.java
+++
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/main/java/org/kie/workbench/common/stunner/kogito/client/services/WorkItemDefinitionStandaloneClientService.java
@@ -25,6 +25,8 @@ import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@@ -43,18 +45,22 @@ import
org.kie.workbench.common.stunner.bpmn.workitem.WorkItemDefinitionRegistry
import org.kie.workbench.common.stunner.core.diagram.Metadata;
import
org.kie.workbench.common.stunner.kogito.client.services.util.WidPresetResources;
import
org.kie.workbench.common.stunner.kogito.client.services.util.WorkItemIconCache;
+import org.uberfire.backend.vfs.Path;
import org.uberfire.client.promise.Promises;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static
org.kie.workbench.common.stunner.bpmn.client.workitem.WorkItemDefinitionClientParser.parse;
+import static org.kie.workbench.common.stunner.core.util.StringUtils.isEmpty;
import static org.kie.workbench.common.stunner.core.util.StringUtils.nonEmpty;
@ApplicationScoped
public class WorkItemDefinitionStandaloneClientService implements
WorkItemDefinitionClientService {
+ private static Logger LOGGER =
Logger.getLogger(WorkItemDefinitionStandaloneClientService.class.getName());
+
private static final String RESOURCE_ALL_WID_PATTERN = "*.wid";
- private static final String RESOURCE_GLOBAL_DIRECTORY_WID_PATTERN =
"global/*.wid";
+ private static final String RESOURCE_GLOBAL_DIRECTORY_WID_PATTERN =
"/global/*.wid";
private static final String MILESTONE_ICON = "defaultmilestoneicon.png";
private static final String MILESTONE_NAME = "Milestone";
@@ -63,10 +69,6 @@ public class WorkItemDefinitionStandaloneClientService
implements WorkItemDefini
private final ResourceContentService resourceContentService;
private final WorkItemIconCache workItemIconCache;
- // Cache the promise, as by definition will be performed just once,
- // so the available work item definitions will be also just registered
once, by app.
- private Promise<Collection<WorkItemDefinition>> loader;
-
@Inject
public WorkItemDefinitionStandaloneClientService(final Promises promises,
final
WorkItemDefinitionCacheRegistry registry,
@@ -81,7 +83,6 @@ public class WorkItemDefinitionStandaloneClientService
implements WorkItemDefini
@PostConstruct
public void init() {
- loader = allWorkItemsLoader();
}
@Produces
@@ -93,24 +94,38 @@ public class WorkItemDefinitionStandaloneClientService
implements WorkItemDefini
@Override
public Promise<Collection<WorkItemDefinition>> call(final Metadata input) {
- return loader;
+ return allWorkItemsLoader(input.getPath());
}
@PreDestroy
public void destroy() {
registry.clear();
- loader = null;
}
- private Promise<Collection<WorkItemDefinition>> allWorkItemsLoader() {
+
+ private Promise<Collection<WorkItemDefinition>> allWorkItemsLoader(Path
openedDiagramPath) {
+
+ final int lastSlashIndex = openedDiagramPath != null ?
openedDiagramPath.toURI().lastIndexOf('/') : -1;
+ final String openedDiagramFolderRelativeToTheWorkspace =
(lastSlashIndex != -1)
+ ? openedDiagramPath.toURI().substring(0, lastSlashIndex + 1)
+ : "";
+
+ // We construct the `widPattern` in this complicated manner because of
multiple ResourceContentImplementations
+ // VsCodeResourceContentServiceForWorkspaces - that has access to the
currently opened file location - SearchType.ASSET_FOLDER could be used
+ // WorkspaceService - that has no access to the currently opened file
location - SearchType.ASSET_FOLDER could not be used
+ // As a workaround we include folder into `widPattern` and use
SearchType.TRAVERSAL
+ final String widPattern = "/" + ((openedDiagramPath == null ||
isEmpty(openedDiagramFolderRelativeToTheWorkspace)) ? RESOURCE_ALL_WID_PATTERN
: openedDiagramFolderRelativeToTheWorkspace + RESOURCE_ALL_WID_PATTERN);
+
return promises.create((success, failure) -> {
registry.clear();
final List<WorkItemDefinition> loaded = new LinkedList<>();
+ LOGGER.log(Level.FINE, "Searching WID using pattern: " +
RESOURCE_GLOBAL_DIRECTORY_WID_PATTERN);
resourceContentService
.list(RESOURCE_GLOBAL_DIRECTORY_WID_PATTERN,
ResourceListOptions.traversal())
.then(paths1 -> {
+ LOGGER.log(Level.FINE, "Searching WID using pattern: "
+ widPattern);
resourceContentService
- .list(RESOURCE_ALL_WID_PATTERN,
ResourceListOptions.assetFolder())
+ .list(widPattern,
ResourceListOptions.traversal())
.then(paths2 -> {
String[] paths = mergeTwoArrays(paths1,
paths2);
if (paths.length > 0) {
@@ -158,11 +173,11 @@ public class WorkItemDefinitionStandaloneClientService
implements WorkItemDefini
private Promise<Collection<WorkItemDefinition>> workItemsLoader(final
String path,
final
Collection<WorkItemDefinition> loaded) {
int lastDirIndex = path.lastIndexOf('/');
- final String directory = (lastDirIndex >= 0) ? path.substring(0,
lastDirIndex) + "/" : path;
+ final String openedDiagramFolderRelativeToTheWorkspace = (lastDirIndex
>= 0) ? path.substring(0, lastDirIndex) + "/" : "";
if (nonEmpty(path)) {
return resourceContentService
.get(path)
- .then(value -> getPromises(parse(value), loaded,
directory));
+ .then(value -> getPromises(parse(value), loaded,
openedDiagramFolderRelativeToTheWorkspace));
}
return promises.resolve(emptyList());
}
@@ -198,7 +213,10 @@ public class WorkItemDefinitionStandaloneClientService
implements WorkItemDefini
}
private Promise<Collection<WorkItemDefinition>> getPromises(final
List<WorkItemDefinition> wids, final Collection<WorkItemDefinition> loaded,
final String path) {
- wids.forEach(w -> w.getIconDefinition().setUri(path +
w.getIconDefinition().getUri()));
+ wids.forEach(w -> {
+ LOGGER.log(Level.FINE, "WID Icon: " + path +
w.getIconDefinition().getUri());
+ w.getIconDefinition().setUri(path +
w.getIconDefinition().getUri());
+ });
return promises.create((success, failure) -> {
promises.all(wids, this::workItemIconLoader)
.then(wid -> {
diff --git
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/test/java/org/kie/workbench/common/stunner/kogito/client/selenium/BPMNDesignerKogitoSeleniumIT.java
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/test/java/org/kie/workbench/common/stunner/kogito/client/selenium/BPMNDesignerKogito
[...]
index 6970f970dd8..c5bbfb3e2b5 100644
---
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/test/java/org/kie/workbench/common/stunner/kogito/client/selenium/BPMNDesignerKogitoSeleniumIT.java
+++
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/test/java/org/kie/workbench/common/stunner/kogito/client/selenium/BPMNDesignerKogitoSeleniumIT.java
@@ -60,7 +60,7 @@ public class BPMNDesignerKogitoSeleniumIT {
private static final Logger LOG =
LoggerFactory.getLogger(BPMNDesignerKogitoSeleniumIT.class);
private static final String SET_CONTENT_TEMPLATE =
- "gwtEditorBeans.get(\"BPMNDiagramEditor\").get().setContent(\"\",
'%s')";
+
"gwtEditorBeans.get(\"BPMNDiagramEditor\").get().setContent(\"default\", '%s')";
private static final String GET_CONTENT_TEMPLATE =
"return
gwtEditorBeans.get(\"BPMNDiagramEditor\").get().getContent()";
diff --git
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/test/java/org/kie/workbench/common/stunner/kogito/client/services/BPMNStaticResourceContentService.java
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/test/java/org/kie/workbench/common/stunner/kogito/client/services/BPMNStaticReso
[...]
index 12c5656728f..8f36218bb5b 100644
---
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/test/java/org/kie/workbench/common/stunner/kogito/client/services/BPMNStaticResourceContentService.java
+++
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/test/java/org/kie/workbench/common/stunner/kogito/client/services/BPMNStaticResourceContentService.java
@@ -95,8 +95,6 @@ public class BPMNStaticResourceContentService implements
ResourceContentService
" ]\n" +
"]";
- private static final String PATTERN_ALL_WID = "*.wid";
- private static final String PATTERN_GLOBAL_WID = "global/*.wid";
private static final Map<String, String> GLOBAL_WID_ENTRIES =
new HashMap<String, String>() {{
put("global/default.wid", DEFAULT_DECLARATIONS);
@@ -144,14 +142,14 @@ public class BPMNStaticResourceContentService implements
ResourceContentService
@Override
public Promise<String[]> list(final String pattern) {
- switch (pattern) {
- case PATTERN_GLOBAL_WID:
+ if (pattern.endsWith(".wid")) {
+ if (pattern.contains("global")) {
return
promises.resolve(GLOBAL_WID_ENTRIES.keySet().toArray(new String[0]));
- case PATTERN_ALL_WID:
+ } else {
return promises.resolve(ALL_WID_ENTRIES.keySet().toArray(new
String[0]));
- default:
- return promises.resolve(new String[0]);
+ }
}
+ return promises.resolve(new String[0]);
}
@Override
diff --git
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-marshalling/src/main/java/org/kie/workbench/common/stunner/bpmn/client/marshall/service/BPMNClientDiagramService.java
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-marshalling/src/main/java/org/kie/workbench/common/stunner/bpmn/client/marshall/service/BPMNClientDiagra
[...]
index aeef760ffba..2ef7d0d5934 100644
---
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-marshalling/src/main/java/org/kie/workbench/common/stunner/bpmn/client/marshall/service/BPMNClientDiagramService.java
+++
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-marshalling/src/main/java/org/kie/workbench/common/stunner/bpmn/client/marshall/service/BPMNClientDiagramService.java
@@ -22,6 +22,7 @@ package
org.kie.workbench.common.stunner.bpmn.client.marshall.service;
import java.util.Collection;
import java.util.Objects;
+import java.util.logging.Level;
import java.util.logging.Logger;
import javax.enterprise.context.ApplicationScoped;
@@ -51,6 +52,7 @@ import
org.kie.workbench.common.stunner.core.graph.content.definition.Definition
import
org.kie.workbench.common.stunner.core.graph.content.definition.DefinitionSet;
import org.kie.workbench.common.stunner.core.graph.util.GraphUtils;
import
org.kie.workbench.common.stunner.kogito.client.service.AbstractKogitoClientDiagramService;
+import org.uberfire.backend.vfs.PathFactory;
import org.uberfire.client.promise.Promises;
import static
org.kie.workbench.common.stunner.bpmn.util.XmlUtils.createValidId;
@@ -96,20 +98,23 @@ public class BPMNClientDiagramService extends
AbstractKogitoClientDiagramService
@Override
public void transform(final String xml,
final ServiceCallback<Diagram> callback) {
- doTransform(DEFAULT_DIAGRAM_ID, xml, callback);
+ doTransform(DEFAULT_DIAGRAM_ID, DEFAULT_DIAGRAM_ID, xml, callback);
}
@Override
public void transform(final String fileName,
final String xml,
final ServiceCallback<Diagram> callback) {
- doTransform(createDiagramTitleFromFilePath(fileName), xml, callback);
+ doTransform(createDiagramTitleFromFilePath(fileName), fileName, xml,
callback);
}
private void doTransform(final String fileName,
+ final String fileRelativePath,
final String xml,
final ServiceCallback<Diagram> callback) {
- final Metadata metadata = createMetadata();
+ final Metadata metadata = createMetadata();
+ metadata.setPath(PathFactory.newPath(fileName, fileRelativePath));
+ LOGGER.log(Level.INFO, "Loading a file: [fileRelativePath: " +
fileRelativePath + ", fileName: " + fileName + "]");
widService
.call(metadata)
.then(wid -> {
diff --git a/packages/vscode-extension/src/VsCodeKieEditorControllerFactory.ts
b/packages/vscode-extension/src/VsCodeKieEditorControllerFactory.ts
index 79701998c8f..4095c5cab0b 100644
--- a/packages/vscode-extension/src/VsCodeKieEditorControllerFactory.ts
+++ b/packages/vscode-extension/src/VsCodeKieEditorControllerFactory.ts
@@ -155,11 +155,4 @@ export class VsCodeKieEditorControllerFactory {
private getWebviewPath(webview: Webview, relativeUriPath: string) {
return webview.asWebviewUri(Uri.joinPath(this.context.extensionUri,
relativeUriPath)).toString();
}
-
- private getParentFolder(absoluteFsPath: string) {
- if (absoluteFsPath.includes(__path.sep)) {
- return absoluteFsPath.substring(0,
absoluteFsPath.lastIndexOf(__path.sep) + 1);
- }
- return "";
- }
}
diff --git
a/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceForDanglingFiles.ts
b/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceForDanglingFiles.ts
index 1e21bd24503..ce2b9b3d3b7 100644
---
a/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceForDanglingFiles.ts
+++
b/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceForDanglingFiles.ts
@@ -18,7 +18,6 @@
*/
import {
- ContentType,
ResourceContent,
ResourceContentOptions,
ResourceContentService,
diff --git
a/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceForWorkspaces.ts
b/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceForWorkspaces.ts
index e05423b23c6..31ab9f2a021 100644
---
a/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceForWorkspaces.ts
+++
b/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceForWorkspaces.ts
@@ -18,7 +18,6 @@
*/
import {
- ContentType,
ResourceContent,
ResourceContentOptions,
ResourceContentService,
@@ -27,15 +26,14 @@ import {
SearchType,
} from "@kie-tools-core/workspace/dist/api";
-import * as vscode from "vscode";
import * as __path from "path";
+import * as vscode from "vscode";
import { RelativePattern } from "vscode";
-import { listFiles } from "isomorphic-git";
-import { Minimatch } from "minimatch";
-import { ReadonlyIsomorphicGitFsForVsCodeWorkspaceFolders } from
"./VsCodeResourceContentServiceIsomorphicGitFs";
+import { isIgnored } from "isomorphic-git";
import { toFsPath } from "../paths/paths";
-import { getNormalizedPosixPathRelativeToWorkspaceRoot } from
"./workspaceRoot";
import { KogitoEditorDocument } from "../VsCodeKieEditorController";
+import { getNormalizedPosixPathRelativeToWorkspaceRoot } from
"./workspaceRoot";
+import { ReadonlyIsomorphicGitFsForVsCodeWorkspaceFolders } from
"./VsCodeResourceContentServiceIsomorphicGitFs";
/**
* Implementation of a ResourceContentService using the vscode apis to
list/get assets.
@@ -60,61 +58,89 @@ export class VsCodeResourceContentServiceForWorkspaces
implements ResourceConten
)
: this.args.workspaceRootAbsoluteFsPath;
- // The vscode API will read all files, including the .gitignore ones,
- // making this action is less performatic than the git ls-files which will
- // automatically exclude the .gitignore files.
- try {
- console.debug("VS CODE RESOURCE CONTENT API IMPL FOR WORKSPACES: Trying
to use isomorphic-git to read dir.");
- const normalizedPosixPathsRelativeToTheBasePath = await listFiles({
- fs: this.isomorphicGitFs,
- dir: this.args.workspaceRootAbsoluteFsPath,
- });
- console.debug("VS CODE RESOURCE CONTENT API IMPL FOR WORKSPACES: Success
on using isomorphic-git!");
-
- const minimatch = new Minimatch(pattern);
- const regexp = minimatch.makeRe(); // The regexp is ~50x faster than the
direct match using glob.
- const openFileDirectoryNormalizedPosixPathRelativeToTheWorkspaceRoot =
__path.dirname(
- getNormalizedPosixPathRelativeToWorkspaceRoot(this.args.document)
- );
+ // Normalize incoming pattern to POSIX for VS Code globbing
+ const posixPattern = pattern.replace(/\\/g, "/");
+ const { leadingFolderOfPattern, trailingPattern } =
+ this.splitPosixPatternForLeadingFolderAndTrailingPattern(posixPattern);
- const matchingNormalizedPosixPathsRelativeToTheBasePath =
normalizedPosixPathsRelativeToTheBasePath.filter(
- (p) => {
- const matchesPattern =
- // Adding a leading slash here to make the regex have the same
behavior as the glob with **/* pattern.
- regexp.test("/" + p) ||
- // check on the asset folder for *.{ext} pattern
- // the regex doesn't support "\" from Windows paths, requiring to
test againts POSIX paths
-
regexp.test(__path.posix.relative(openFileDirectoryNormalizedPosixPathRelativeToTheWorkspaceRoot,
p));
-
- const conformsToSearchType =
- !opts ||
- opts.type === SearchType.TRAVERSAL ||
- (opts.type === SearchType.ASSET_FOLDER &&
- __path
- .join(baseAbsoluteFsPath, toFsPath(p))
- .startsWith(
- __path.join(
- baseAbsoluteFsPath,
-
toFsPath(openFileDirectoryNormalizedPosixPathRelativeToTheWorkspaceRoot)
- )
- ));
-
- return matchesPattern && conformsToSearchType;
- }
- );
- return new ResourcesList(pattern,
matchingNormalizedPosixPathsRelativeToTheBasePath);
- } catch (error) {
- console.debug(
- "VS CODE RESOURCE CONTENT API IMPL FOR WORKSPACES: Failed to use
isomorphic-git to read dir. Falling back to vscode's API.",
- error
- );
- const relativePattern = new RelativePattern(baseAbsoluteFsPath, pattern);
- const files = await vscode.workspace.findFiles(relativePattern);
- const normalizedPosixPathsRelativeToTheWorkspaceRoot = files.map((uri) =>
- vscode.workspace.asRelativePath(uri, false)
- );
- return new ResourcesList(pattern,
normalizedPosixPathsRelativeToTheWorkspaceRoot);
+ let theMostSpecificFolder = baseAbsoluteFsPath;
+ let globRelativeToBase = posixPattern;
+
+ // In case of ASSET_FOLDER we are done, see baseAbsoluteFsPath creation
+ if (opts?.type !== SearchType.ASSET_FOLDER) {
+ theMostSpecificFolder = leadingFolderOfPattern
+ ? __path.join(baseAbsoluteFsPath, leadingFolderOfPattern)
+ : baseAbsoluteFsPath;
+ globRelativeToBase = trailingPattern || posixPattern;
}
+
+ const relativePattern = new RelativePattern(theMostSpecificFolder,
globRelativeToBase);
+
+ const defaultExcludes = "**/{target,dist,node_modules}";
+ const vscodeNormalizedPosixPathsRelativeToTheBasePath = (
+ await vscode.workspace.findFiles(relativePattern, defaultExcludes)
+ ).map((uri) => vscode.workspace.asRelativePath(uri, false).replace(/\\/g,
"/"));
+
+ const isNotIgnoredPath = await Promise.all(
+ vscodeNormalizedPosixPathsRelativeToTheBasePath.map(
+ async (relativePath) =>
+ !(await isIgnored({
+ fs: this.isomorphicGitFs,
+ dir: this.args.workspaceRootAbsoluteFsPath,
+ gitdir: __path.join(this.args.workspaceRootAbsoluteFsPath, ".git"),
+ filepath: relativePath,
+ }))
+ )
+ );
+ const results = vscodeNormalizedPosixPathsRelativeToTheBasePath.filter((_,
i) => isNotIgnoredPath[i]);
+ console.debug("VS CODE RESOURCE CONTENT API IMPL FOR WORKSPACES: VS Code
found files %s", results);
+
+ return new ResourcesList(pattern, results);
+ }
+
+ /**
+ * Detects if a path segment contains glob "magic" characters (e.g., *, ?,
[], {}, !, or extglobs like +(…), *(…), ?(…), !(…)).
+ * @param pathSegment - The path segment to check.
+ * @returns True if the segment contains glob magic, false otherwise.
+ */
+ private hasGlobMagic(pathSegment: string): boolean {
+ // *, ?, [], {}, !, and simple extglobs like +(…), *(…), ?(…), !(…)
+ return /[*?[\]{},!]/.test(pathSegment) || /\([^)]+\)/.test(pathSegment);
+ }
+
+ /**
+ * Splits a POSIX-style path (e.g., "a/b/c") into its non-empty segments
["a", "b", "c"].
+ * @param path - The POSIX path string to split.
+ * @returns An array of non-empty path segments.
+ */
+ private splitPosixSegments(path: string): string[] {
+ return path.split("/").filter((s) => s.length > 0);
+ }
+
+ /**
+ * Given a posix pattern (e.g. org/model/*.txt), returns:
+ * - staticPrefix (org/model): leading directory segments with no glob
magic, may be empty
+ * - remainingGlob (*.txt): the rest of the pattern (dirs + filename)
relative to staticPrefix
+ */
+ private splitPosixPatternForLeadingFolderAndTrailingPattern(pattern:
string): {
+ leadingFolderOfPattern: string;
+ trailingPattern: string;
+ } {
+ const segments = this.splitPosixSegments(pattern);
+
+ if (segments.length === 1) {
+ return { leadingFolderOfPattern: "", trailingPattern: segments[0] };
+ }
+
+ let i = 0;
+ while (i < segments.length && !this.hasGlobMagic(segments[i])) {
+ i++;
+ }
+
+ const leadingFolderOfPattern = segments.slice(0, i).join("/");
+ const trailingPattern = segments.slice(i).join("/") || "";
+
+ return { leadingFolderOfPattern, trailingPattern };
}
public async get(
diff --git
a/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceIsomorphicGitFs.ts
b/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceIsomorphicGitFs.ts
index 4e61fb9b569..1bf43d66148 100644
---
a/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceIsomorphicGitFs.ts
+++
b/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceIsomorphicGitFs.ts
@@ -83,4 +83,13 @@ export class
ReadonlyIsomorphicGitFsForVsCodeWorkspaceFolders {
console.debug("ERROR on vscode.workspace.fs.stat", "error:", error,
"path:", contentPath);
}
}
+
+ async exists(path: string): Promise<boolean> {
+ try {
+ await vscode.workspace.fs.stat(vscode.Uri.file(path));
+ return true;
+ } catch {
+ return false;
+ }
+ }
}
diff --git
a/packages/vscode-extension/tests/VsCodeResourceContentServiceForDanglingFiles.test.ts
b/packages/vscode-extension/tests/VsCodeResourceContentServiceForDanglingFiles.test.ts
index b6f90afa2bf..68974fae77e 100644
---
a/packages/vscode-extension/tests/VsCodeResourceContentServiceForDanglingFiles.test.ts
+++
b/packages/vscode-extension/tests/VsCodeResourceContentServiceForDanglingFiles.test.ts
@@ -19,7 +19,6 @@
import * as __path from "path";
import { VsCodeResourceContentServiceForDanglingFiles } from
"@kie-tools-core/vscode-extension/dist/workspace/VsCodeResourceContentServiceForDanglingFiles";
-import { ContentType } from "@kie-tools-core/workspace/dist/api";
const testWorkspaceAbsoluteFsPath = __path.resolve(__dirname,
"test-workspace") + __path.sep;
diff --git
a/packages/vscode-extension/tests/VsCodeResourceContentServiceForWorkspaces.test.ts
b/packages/vscode-extension/tests/VsCodeResourceContentServiceForWorkspaces.test.ts
new file mode 100644
index 00000000000..9204814223e
--- /dev/null
+++
b/packages/vscode-extension/tests/VsCodeResourceContentServiceForWorkspaces.test.ts
@@ -0,0 +1,285 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import * as __path from "path";
+import { VsCodeResourceContentServiceForWorkspaces } from
"@kie-tools-core/vscode-extension/dist/workspace/VsCodeResourceContentServiceForWorkspaces";
+import { TextDocument, Uri } from "vscode";
+import * as vscode from "./__mocks__/vscode";
+import { SearchType } from "@kie-tools-core/workspace/dist/api";
+
+describe("VsCodeResourceContentServiceForWorkspaces.list", () => {
+ const defaultExcludes = "**/{target,dist,node_modules}";
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ describe("SearchType.Traversal from workspace root", () => {
+ const wsRoot = __path.resolve(__dirname, "test-workspace");
+ const docUri = Uri.file(__path.join(wsRoot, "resource1.txt"));
+ const listOptions = { type: SearchType.TRAVERSAL };
+
+ const resourceContentService = new
VsCodeResourceContentServiceForWorkspaces({
+ workspaceRootAbsoluteFsPath: wsRoot,
+ document: { uri: docUri } as unknown as TextDocument,
+ });
+
+ test("Simple pattern", async () => {
+ const pattern = "*.txt";
+ await resourceContentService.list(pattern, listOptions);
+
+ expect(vscode.workspace.findFiles).toHaveBeenCalledWith({ base: wsRoot,
pattern: "*.txt" }, defaultExcludes);
+ });
+
+ test("Anywhere pattern", async () => {
+ const pattern = "**/*.txt";
+ await resourceContentService.list(pattern, listOptions);
+
+ expect(vscode.workspace.findFiles).toHaveBeenCalledWith({ base: wsRoot,
pattern: "**/*.txt" }, defaultExcludes);
+ });
+
+ test("Specific folder pattern", async () => {
+ const pattern = "submodule/*.txt";
+ await resourceContentService.list(pattern, listOptions);
+
+ expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+ {
+ base: __path.join(wsRoot, "submodule"),
+ pattern: "*.txt",
+ },
+ defaultExcludes
+ );
+ });
+
+ test("Nested specific folder pattern", async () => {
+ const pattern = "**/submodule/*.txt";
+ await resourceContentService.list(pattern, listOptions);
+
+ expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+ { base: wsRoot, pattern: "**/submodule/*.txt" },
+ defaultExcludes
+ );
+ });
+
+ test("Absolute pattern", async () => {
+ const pattern = "/submodule/*.txt";
+ await resourceContentService.list(pattern, listOptions);
+
+ expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+ {
+ base: __path.join(wsRoot, "submodule"),
+ pattern: "*.txt",
+ },
+ defaultExcludes
+ );
+ });
+ });
+
+ describe("SearchType.Traversal from workspace submodule", () => {
+ const wsRoot = __path.resolve(__dirname, "test-workspace");
+ const docUri = Uri.file(__path.join(wsRoot, "submodule", "resource1.txt"));
+ const listOptions = { type: SearchType.TRAVERSAL };
+
+ const resourceContentService = new
VsCodeResourceContentServiceForWorkspaces({
+ workspaceRootAbsoluteFsPath: wsRoot,
+ document: { uri: docUri } as unknown as TextDocument,
+ });
+
+ test("Simple pattern", async () => {
+ const pattern = "*.txt";
+ await resourceContentService.list(pattern, listOptions);
+
+ expect(vscode.workspace.findFiles).toHaveBeenCalledWith({ base: wsRoot,
pattern: "*.txt" }, defaultExcludes);
+ });
+
+ test("Anywhere pattern", async () => {
+ const pattern = "**/*.txt";
+ await resourceContentService.list(pattern, listOptions);
+
+ expect(vscode.workspace.findFiles).toHaveBeenCalledWith({ base: wsRoot,
pattern: "**/*.txt" }, defaultExcludes);
+ });
+
+ test("Specific folder pattern", async () => {
+ const pattern = "submodule/*.txt";
+ await resourceContentService.list(pattern, listOptions);
+
+ expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+ {
+ base: __path.join(wsRoot, "submodule"),
+ pattern: "*.txt",
+ },
+ defaultExcludes
+ );
+ });
+
+ test("Nested specific folder pattern", async () => {
+ const pattern = "**/submodule/*.txt";
+ await resourceContentService.list(pattern, listOptions);
+
+ expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+ { base: wsRoot, pattern: "**/submodule/*.txt" },
+ defaultExcludes
+ );
+ });
+
+ test("Absolute pattern", async () => {
+ const pattern = "/submodule/*.txt";
+ await resourceContentService.list(pattern, listOptions);
+
+ expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+ {
+ base: __path.join(wsRoot, "submodule"),
+ pattern: "*.txt",
+ },
+ defaultExcludes
+ );
+ });
+ });
+
+ describe("SearchType.AssetFolder from workspace root", () => {
+ const wsRoot = __path.resolve(__dirname, "test-workspace");
+ const docUri = Uri.file(__path.join(wsRoot, "resource1.txt"));
+ const listOptions = { type: SearchType.ASSET_FOLDER };
+
+ const resourceContentService = new
VsCodeResourceContentServiceForWorkspaces({
+ workspaceRootAbsoluteFsPath: wsRoot,
+ document: { uri: docUri } as unknown as TextDocument,
+ });
+
+ test("Simple pattern", async () => {
+ const pattern = "*.txt";
+ await resourceContentService.list(pattern, listOptions);
+
+ expect(vscode.workspace.findFiles).toHaveBeenCalledWith({ base: wsRoot,
pattern: "*.txt" }, defaultExcludes);
+ });
+
+ test("Anywhere pattern", async () => {
+ const pattern = "**/*.txt";
+ await resourceContentService.list(pattern, listOptions);
+
+ expect(vscode.workspace.findFiles).toHaveBeenCalledWith({ base: wsRoot,
pattern: "**/*.txt" }, defaultExcludes);
+ });
+
+ test("Specific folder pattern", async () => {
+ const pattern = "submodule/*.txt";
+ await resourceContentService.list(pattern, listOptions);
+
+ expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+ { base: wsRoot, pattern: "submodule/*.txt" },
+ defaultExcludes
+ );
+ });
+
+ test("Nested specific folder pattern", async () => {
+ const pattern = "**/submodule/*.txt";
+ await resourceContentService.list(pattern, listOptions);
+
+ expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+ { base: wsRoot, pattern: "**/submodule/*.txt" },
+ defaultExcludes
+ );
+ });
+
+ test("Absolute pattern", async () => {
+ const pattern = "/submodule/*.txt";
+ await resourceContentService.list(pattern, listOptions);
+
+ expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+ { base: wsRoot, pattern: "/submodule/*.txt" },
+ defaultExcludes
+ );
+ });
+ });
+
+ describe("SearchType.AssetFolder from workspace submodule", () => {
+ const wsRoot = __path.resolve(__dirname, "test-workspace");
+ const docUri = Uri.file(__path.join(wsRoot, "submodule", "resource1.txt"));
+ const listOptions = { type: SearchType.ASSET_FOLDER };
+
+ const resourceContentService = new
VsCodeResourceContentServiceForWorkspaces({
+ workspaceRootAbsoluteFsPath: wsRoot,
+ document: { uri: docUri } as unknown as TextDocument,
+ });
+
+ test("Simple pattern", async () => {
+ const pattern = "*.txt";
+ await resourceContentService.list(pattern, listOptions);
+
+ expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+ {
+ base: __path.join(wsRoot, "submodule"),
+ pattern: "*.txt",
+ },
+ defaultExcludes
+ );
+ });
+
+ test("Anywhere pattern", async () => {
+ const pattern = "**/*.txt";
+ await resourceContentService.list(pattern, listOptions);
+
+ expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+ {
+ base: __path.join(wsRoot, "submodule"),
+ pattern: "**/*.txt",
+ },
+ defaultExcludes
+ );
+ });
+
+ test("Specific folder pattern", async () => {
+ const pattern = "submodule/*.txt";
+ await resourceContentService.list(pattern, listOptions);
+
+ expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+ {
+ base: __path.join(wsRoot, "submodule"),
+ pattern: "submodule/*.txt",
+ },
+ defaultExcludes
+ );
+ });
+
+ test("Nested specific folder pattern", async () => {
+ const pattern = "**/submodule/*.txt";
+ await resourceContentService.list(pattern, listOptions);
+
+ expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+ {
+ base: __path.join(wsRoot, "submodule"),
+ pattern: "**/submodule/*.txt",
+ },
+ defaultExcludes
+ );
+ });
+
+ test("Absolute pattern", async () => {
+ const pattern = "/submodule/*.txt";
+ await resourceContentService.list(pattern, listOptions);
+
+ expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+ {
+ base: __path.join(wsRoot, "submodule"),
+ pattern: "/submodule/*.txt",
+ },
+ defaultExcludes
+ );
+ });
+ });
+});
diff --git a/packages/vscode-extension/tests/__mocks__/vscode.ts
b/packages/vscode-extension/tests/__mocks__/vscode.ts
index cbdbe305fa6..dd69e6f8337 100644
--- a/packages/vscode-extension/tests/__mocks__/vscode.ts
+++ b/packages/vscode-extension/tests/__mocks__/vscode.ts
@@ -20,6 +20,7 @@
// vscode.js
import * as fs from "fs";
+import * as __path from "path";
const languages = {
createDiagnosticCollection: jest.fn(),
@@ -36,9 +37,11 @@ const vscodeWindow = {
createTextEditorDecorationType: jest.fn(),
};
-const workspace = {
+const wsRoot = __path.resolve(__dirname, "..", "test-workspace");
+
+export const workspace = {
getConfiguration: jest.fn(),
- workspaceFolders: [],
+ workspaceFolders: [{ uri: { fsPath: wsRoot } }],
onDidSaveTextDocument: jest.fn(),
fs: {
readDirectory: (uri: any) => ({
@@ -64,6 +67,23 @@ const workspace = {
},
}),
},
+
+ asRelativePath: jest.fn((uri: string | { fsPath: string },
_includeWorkspace?: boolean) => {
+ const abs = typeof uri === "string" ? uri : uri.fsPath;
+ console.debug(wsRoot);
+ console.debug(uri);
+ let rel = abs.startsWith(wsRoot + __path.sep) ? abs.slice(wsRoot.length +
1) : abs;
+ return rel.replace(/\\/g, "/");
+ }),
+
+ /**
+ * This is mock for unit testing. I do not want to implement any search
mechanism.
+ * We do not want to test correctnes of the VSCode implementation in Apache
KIE test suite
+ * We just want to be able assert `findFiles` parameters
+ */
+ findFiles: jest.fn(async (include: RelativePattern, exclude?: any,
maxResults?: number, token?: any) => {
+ return [];
+ }),
};
const OverviewRulerLane = {
@@ -87,6 +107,14 @@ const commands = {
executeCommand: jest.fn(),
};
+/** Just te get unit test working and be able assert `base` and `pattern` */
+class RelativePattern {
+ constructor(
+ public base: string,
+ public pattern: string
+ ) {}
+}
+
const vscode = {
languages,
StatusBarAlignment,
@@ -99,6 +127,7 @@ const vscode = {
DiagnosticSeverity,
debug,
commands,
+ RelativePattern,
};
module.exports = vscode;
diff --git
a/packages/workspaces-git-fs/src/context/WorkspacesContextProvider.tsx
b/packages/workspaces-git-fs/src/context/WorkspacesContextProvider.tsx
index 84f1de1d3a0..665b89d7065 100644
--- a/packages/workspaces-git-fs/src/context/WorkspacesContextProvider.tsx
+++ b/packages/workspaces-git-fs/src/context/WorkspacesContextProvider.tsx
@@ -19,7 +19,7 @@
import React, { useEffect, useState } from "react";
import { useCallback, useMemo } from "react";
-import { ResourceContentOptions } from "@kie-tools-core/workspace/dist/api";
+import { ResourceContentOptions, ResourceListOptions } from
"@kie-tools-core/workspace/dist/api";
import { WorkspaceFile, WorkspacesContext } from "./WorkspacesContext";
import { LocalFile } from "../worker/api/LocalFile";
import {
@@ -486,7 +486,7 @@ export function WorkspacesContextProvider(props: Props) {
);
const resourceContentList = useCallback(
- async (args: { workspaceId: string; globPattern: string }) =>
+ async (args: { workspaceId: string; globPattern: string; opts?:
ResourceListOptions }) =>
workspacesSharedWorker.withBus((workspacesWorkerBus) =>
workspacesWorkerBus.clientApi.requests.kieSandboxWorkspacesStorage_resourceContentList(args)
),
diff --git a/packages/workspaces-git-fs/src/services/WorkspaceService.tsx
b/packages/workspaces-git-fs/src/services/WorkspaceService.tsx
index 41d69fa3196..bef8ced4bbe 100644
--- a/packages/workspaces-git-fs/src/services/WorkspaceService.tsx
+++ b/packages/workspaces-git-fs/src/services/WorkspaceService.tsx
@@ -21,7 +21,7 @@ import { encoder } from "../encoderdecoder/EncoderDecoder";
import { downloadZip, predictLength } from "client-zip";
import { WorkspaceDescriptor } from "../worker/api/WorkspaceDescriptor";
import { StorageFile, StorageService } from "./StorageService";
-import { basename, join, relative } from "path";
+import { join, relative } from "path";
import { Minimatch } from "minimatch";
import { WorkspaceDescriptorService } from "./WorkspaceDescriptorService";
import { BroadcasterDispatch } from "./FsService";
@@ -105,15 +105,20 @@ export class WorkspaceService {
workspaceId: string,
globPattern?: string
): Promise<WorkspaceWorkerFileDescriptor[]> {
+ const isGlobPatternSlashPrefixed = globPattern?.startsWith("/");
const matcher = globPattern ? new Minimatch(globPattern, { dot: true }) :
undefined;
const gitDirAbsolutePath = this.getAbsolutePath({ workspaceId,
relativePath: ".git" });
+ const workspaceBaseAbsolutePath = this.getAbsolutePath({ workspaceId });
return this.storageService.walk({
schema,
- baseAbsolutePath: this.getAbsolutePath({ workspaceId }),
+ baseAbsolutePath: workspaceBaseAbsolutePath,
shouldExcludeAbsolutePath: (absolutePath) =>
absolutePath.startsWith(gitDirAbsolutePath),
- onVisit: async ({ relativePath }) => {
- if (matcher && !matcher.match(basename(relativePath))) {
+ onVisit: async ({ absolutePath, relativePath }) => {
+ const searchedPath = isGlobPatternSlashPrefixed
+ ? absolutePath.slice(workspaceBaseAbsolutePath.length)
+ : relativePath;
+ if (matcher && !matcher.match(searchedPath)) {
return undefined;
} else {
return { workspaceId, relativePath };
diff --git a/packages/workspaces-git-fs/src/worker/WorkspacesWorkerApiImpl.ts
b/packages/workspaces-git-fs/src/worker/WorkspacesWorkerApiImpl.ts
index 9954bf79f3f..455ecdd935a 100644
--- a/packages/workspaces-git-fs/src/worker/WorkspacesWorkerApiImpl.ts
+++ b/packages/workspaces-git-fs/src/worker/WorkspacesWorkerApiImpl.ts
@@ -22,7 +22,6 @@ import {
ResourcesList,
ResourceContentOptions,
ResourceContent,
- ContentType,
} from "@kie-tools-core/workspace/dist/api";
import { join } from "path";
import { GIT_DEFAULT_BRANCH } from "../constants/GitConstants";
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 5d19d1b89a1..3cf45846a1a 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -13146,19 +13146,19 @@ importers:
version: 3.0.5
jest:
specifier: ^29.7.0
- version:
29.7.0(@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected]))
+ version:
29.7.0(@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected]))
jest-junit:
specifier: ^16.0.0
version: 16.0.0
jest-when:
specifier: ^3.6.0
- version:
3.6.0([email protected](@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected])))
+ version:
3.6.0([email protected](@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected])))
rimraf:
specifier: ^3.0.2
version: 3.0.2
ts-jest:
specifier: ^29.1.5
- version:
29.1.5(@babel/[email protected])(@jest/[email protected])(@jest/[email protected])([email protected](@babel/[email protected]))([email protected](@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected])))([email protected])
+ version:
29.1.5(@babel/[email protected])(@jest/[email protected])(@jest/[email protected])([email protected](@babel/[email protected]))([email protected](@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected])))([email protected])
typescript:
specifier: ^5.5.3
version: 5.5.3
@@ -53176,6 +53176,10 @@ snapshots:
dependencies:
jest:
29.7.0(@types/[email protected])([email protected])([email protected](@swc/[email protected])(@types/[email protected])([email protected]))
+
[email protected]([email protected](@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected]))):
+ dependencies:
+ jest:
29.7.0(@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected]))
+
[email protected]([email protected](@types/[email protected])([email protected])([email protected](@swc/[email protected])(@types/[email protected])([email protected]))):
dependencies:
jest:
29.7.0(@types/[email protected])([email protected])([email protected](@swc/[email protected])(@types/[email protected])([email protected]))
@@ -58674,6 +58678,24 @@ snapshots:
babel-jest: 29.7.0(@babel/[email protected])
esbuild: 0.18.20
+
[email protected](@babel/[email protected])(@jest/[email protected])(@jest/[email protected])([email protected](@babel/[email protected]))([email protected](@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected])))([email protected]):
+ dependencies:
+ bs-logger: 0.2.6
+ fast-json-stable-stringify: 2.1.0
+ jest:
29.7.0(@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected]))
+ jest-util: 29.7.0
+ json5: 2.2.3
+ lodash.memoize: 4.1.2
+ make-error: 1.3.6
+ semver: 7.5.4
+ typescript: 5.5.3
+ yargs-parser: 21.1.1
+ optionalDependencies:
+ '@babel/core': 7.16.12
+ '@jest/transform': 29.7.0
+ '@jest/types': 29.6.3
+ babel-jest: 29.7.0(@babel/[email protected])
+
[email protected](@babel/[email protected])(@jest/[email protected])(@jest/[email protected])([email protected](@babel/[email protected]))([email protected](@types/[email protected])([email protected])([email protected](@swc/[email protected])(@types/[email protected])([email protected])))([email protected]):
dependencies:
bs-logger: 0.2.6
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]