Skip to content

Commit

Permalink
fix: missing ref nodes when key path is the same
Browse files Browse the repository at this point in the history
  • Loading branch information
devcatalin committed Sep 27, 2021
1 parent bae3a39 commit cb0226f
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 56 deletions.
2 changes: 1 addition & 1 deletion src/models/k8sresource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ interface K8sResource {
/** temporary object used for ref positioning */
lineCounter?: LineCounter;
/** temporary object used for parsing refs */
refNodeByPath?: Record<string, RefNode>;
refNodesByPath?: Record<string, RefNode[]>;
}

export enum ResourceRefType {
Expand Down
2 changes: 1 addition & 1 deletion src/redux/services/resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
125 changes: 71 additions & 54 deletions src/redux/services/resourceRefs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ const joinPathParts = (pathParts: string[]) => {
return pathParts.join(REF_PATH_SEPARATOR);
};

const addRefNodeAtPath = (refNode: RefNode, path: string, refNodesByPath: Record<string, RefNode[]>) => {
if (refNodesByPath[path]) {
refNodesByPath[path].push(refNode);
} else {
refNodesByPath[path] = [refNode];
}
};

export function processResourceRefNodes(resource: K8sResource) {
const parsedDoc = getParsedDoc(resource);

Expand All @@ -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);
}
}
});
Expand Down Expand Up @@ -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) {
Expand All @@ -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;
Expand Down Expand Up @@ -206,53 +219,57 @@ 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,
new NodeWrapper(sourceRefNode.scalar, sourceResource.lineCounter),
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
);
}
}
}
});
}

/*
Expand Down

0 comments on commit cb0226f

Please sign in to comment.