From cb0226f93d9ddbdb4c157ac6e8e52e94b8f503e4 Mon Sep 17 00:00:00 2001 From: Catalin Hoha <20538711+catalinhoha@users.noreply.github.com> Date: Mon, 27 Sep 2021 13:08:20 +0300 Subject: [PATCH] fix: missing ref nodes when key path is the same --- src/models/k8sresource.ts | 2 +- src/redux/services/resource.ts | 2 +- src/redux/services/resourceRefs.ts | 125 ++++++++++++++++------------- 3 files changed, 73 insertions(+), 56 deletions(-) diff --git a/src/models/k8sresource.ts b/src/models/k8sresource.ts index b04b0cbe9a..20c1b9784a 100644 --- a/src/models/k8sresource.ts +++ b/src/models/k8sresource.ts @@ -56,7 +56,7 @@ interface K8sResource { /** temporary object used for ref positioning */ lineCounter?: LineCounter; /** temporary object used for parsing refs */ - refNodeByPath?: Record; + refNodesByPath?: Record; } export enum ResourceRefType { diff --git a/src/redux/services/resource.ts b/src/redux/services/resource.ts index f255a8ae79..83c8cb3a6c 100644 --- a/src/redux/services/resource.ts +++ b/src/redux/services/resource.ts @@ -340,7 +340,7 @@ export function clearResourcesTemporaryObjects(resourceMap: ResourceMapType) { Object.values(resourceMap).forEach(r => { r.parsedDoc = undefined; r.lineCounter = undefined; - r.refNodeByPath = undefined; + r.refNodesByPath = undefined; }); return resourceMap; diff --git a/src/redux/services/resourceRefs.ts b/src/redux/services/resourceRefs.ts index f2ee5795ee..c0003bcfa3 100644 --- a/src/redux/services/resourceRefs.ts +++ b/src/redux/services/resourceRefs.ts @@ -51,6 +51,14 @@ const joinPathParts = (pathParts: string[]) => { return pathParts.join(REF_PATH_SEPARATOR); }; +const addRefNodeAtPath = (refNode: RefNode, path: string, refNodesByPath: Record) => { + if (refNodesByPath[path]) { + refNodesByPath[path].push(refNode); + } else { + refNodesByPath[path] = [refNode]; + } +}; + export function processResourceRefNodes(resource: K8sResource) { const parsedDoc = getParsedDoc(resource); @@ -69,27 +77,28 @@ export function processResourceRefNodes(resource: K8sResource) { traverseDocument(parsedDoc, (parentKeyPathParts, keyPathParts, key, scalar) => { refMappers.forEach(refMapper => { - if (!resource.refNodeByPath) { - resource.refNodeByPath = {}; + if (!resource.refNodesByPath) { + resource.refNodesByPath = {}; } - const keyPath = joinPathParts(keyPathParts); const parentKeyPath = joinPathParts(parentKeyPathParts); const refMapperSourcePath = joinPathParts(refMapper.source.pathParts); const refMapperTargetPath = joinPathParts(refMapper.target.pathParts); + const refNode = {scalar, key, parentKeyPath}; + if (refMapper.matchPairs) { if (refMapperSourcePath === parentKeyPath || refMapperTargetPath === parentKeyPath) { - resource.refNodeByPath[keyPath] = {scalar, key, parentKeyPath}; + addRefNodeAtPath(refNode, keyPath, resource.refNodesByPath); } } else { if (keyPath.endsWith(refMapperSourcePath)) { - resource.refNodeByPath[refMapperSourcePath] = {scalar, key, parentKeyPath}; + addRefNodeAtPath(refNode, refMapperSourcePath, resource.refNodesByPath); } if (keyPath.endsWith(refMapperTargetPath)) { - resource.refNodeByPath[refMapperTargetPath] = {scalar, key, parentKeyPath}; + addRefNodeAtPath(refNode, refMapperTargetPath, resource.refNodesByPath); } } }); @@ -134,16 +143,18 @@ function handleRefMappingByParentKey( outgoingRefMapper: RefMapper ) { const sourceRefNodes: RefNode[] = []; - if (!sourceResource.refNodeByPath) { + if (!sourceResource.refNodesByPath) { return; } - Object.values(sourceResource.refNodeByPath).forEach(({scalar, key, parentKeyPath}) => { - const outgoingRefMapperSourcePath = joinPathParts(outgoingRefMapper.source.pathParts); - if (outgoingRefMapperSourcePath === parentKeyPath) { - sourceRefNodes.push({scalar, key, parentKeyPath}); - } - }); + Object.values(sourceResource.refNodesByPath) + .flat() + .forEach(({scalar, key, parentKeyPath}) => { + const outgoingRefMapperSourcePath = joinPathParts(outgoingRefMapper.source.pathParts); + if (outgoingRefMapperSourcePath === parentKeyPath) { + sourceRefNodes.push({scalar, key, parentKeyPath}); + } + }); // if no target resources are found, then mark all source ref nodes as unsatisfied if (targetResources.length === 0) { @@ -164,15 +175,17 @@ function handleRefMappingByParentKey( targetResources.forEach(targetResource => { const targetNodes: RefNode[] = []; - if (!targetResource.refNodeByPath) { + if (!targetResource.refNodesByPath) { return; } - Object.values(targetResource.refNodeByPath).forEach(({scalar, key, parentKeyPath}) => { - const outgoingRefMapperTargetPath = joinPathParts(outgoingRefMapper.target.pathParts); - if (outgoingRefMapperTargetPath === parentKeyPath) { - targetNodes.push({scalar, key, parentKeyPath}); - } - }); + Object.values(targetResource.refNodesByPath) + .flat() + .forEach(({scalar, key, parentKeyPath}) => { + const outgoingRefMapperTargetPath = joinPathParts(outgoingRefMapper.target.pathParts); + if (outgoingRefMapperTargetPath === parentKeyPath) { + targetNodes.push({scalar, key, parentKeyPath}); + } + }); targetNodes.forEach(targetNode => { if (sourceRefNode.key === targetNode.key && sourceRefNode.scalar.value === targetNode.scalar.value) { foundMatchByTargetResourceId[targetResource.id] = true; @@ -206,44 +219,17 @@ function handleRefMappingByKey( outgoingRefMapper: RefMapper ) { const outgoingRefMapperSourcePath = joinPathParts(outgoingRefMapper.source.pathParts); - const sourceRefNode = sourceResource.refNodeByPath - ? sourceResource.refNodeByPath[outgoingRefMapperSourcePath] + const sourceRefNodes = sourceResource.refNodesByPath + ? sourceResource.refNodesByPath[outgoingRefMapperSourcePath] : undefined; - if (!sourceRefNode) { + if (!sourceRefNodes) { return; } - // if no target resources are found, then mark the source ref as unsatisfied - if (targetResources.length === 0) { - createResourceRef( - sourceResource, - ResourceRefType.Unsatisfied, - new NodeWrapper(sourceRefNode.scalar, sourceResource.lineCounter), - undefined, - outgoingRefMapper.target.kind - ); - } else { - let hasSatisfiedRefs = false; - - targetResources.forEach(targetResource => { - const outgoingRefMapperTargetPath = joinPathParts(outgoingRefMapper.target.pathParts); - const targetNode = targetResource.refNodeByPath - ? targetResource.refNodeByPath[outgoingRefMapperTargetPath] - : undefined; - - if (targetNode && sourceRefNode.scalar.value === targetNode.scalar.value) { - hasSatisfiedRefs = true; - linkResources( - sourceResource, - targetResource, - new NodeWrapper(sourceRefNode.scalar, sourceResource.lineCounter), - new NodeWrapper(targetNode.scalar, targetResource.lineCounter) - ); - } - }); - - if (!hasSatisfiedRefs) { + sourceRefNodes.forEach(sourceRefNode => { + // if no target resources are found, then mark the source ref as unsatisfied + if (targetResources.length === 0) { createResourceRef( sourceResource, ResourceRefType.Unsatisfied, @@ -251,8 +237,39 @@ function handleRefMappingByKey( undefined, outgoingRefMapper.target.kind ); + } else { + let hasSatisfiedRefs = false; + + targetResources.forEach(targetResource => { + const outgoingRefMapperTargetPath = joinPathParts(outgoingRefMapper.target.pathParts); + const targetNodes = targetResource.refNodesByPath + ? targetResource.refNodesByPath[outgoingRefMapperTargetPath] + : undefined; + + targetNodes?.forEach(targetNode => { + if (sourceRefNode.scalar.value === targetNode.scalar.value) { + hasSatisfiedRefs = true; + linkResources( + sourceResource, + targetResource, + new NodeWrapper(sourceRefNode.scalar, sourceResource.lineCounter), + new NodeWrapper(targetNode.scalar, targetResource.lineCounter) + ); + } + }); + }); + + if (!hasSatisfiedRefs) { + createResourceRef( + sourceResource, + ResourceRefType.Unsatisfied, + new NodeWrapper(sourceRefNode.scalar, sourceResource.lineCounter), + undefined, + outgoingRefMapper.target.kind + ); + } } - } + }); } /*