This repository has been archived by the owner on Jun 29, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: comments + linting for change-analysis + postinstall fifinet (#7)
- Loading branch information
1 parent
767c7d4
commit 028ed56
Showing
62 changed files
with
3,214 additions
and
2,732 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
42 changes: 21 additions & 21 deletions
42
packages/change-analysis/aggregations/add-aggregation-descriptions.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,31 @@ | ||
import { AggCharacteristicValue, Aggregation, getAllCharacteristics } from "cdk-change-analyzer-models"; | ||
import { AggCharacteristicValue, Aggregation } from 'cdk-change-analyzer-models'; | ||
|
||
export type AggDescriptionCreator = | ||
export type AggDescriptionCreator = | ||
(characteristics: Record<string, AggCharacteristicValue>) => { | ||
describedCharacteristics?: string[], | ||
descriptions?: string[] | ||
describedCharacteristics?: string[], | ||
descriptions?: string[] | ||
}; | ||
|
||
export function addAggDescriptions<T>( | ||
aggRoots: Aggregation<T>[], descriptionCreators: AggDescriptionCreator[] | ||
aggRoots: Aggregation<T>[], descriptionCreators: AggDescriptionCreator[], | ||
): Aggregation<T>[]{ | ||
const aggStack: Aggregation<T>[] = [...aggRoots]; | ||
const aggStack: Aggregation<T>[] = [...aggRoots]; | ||
|
||
while(aggStack.length){ | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
const agg = aggStack.pop()!; | ||
aggStack.push(...agg?.subAggs ?? []); | ||
if(!agg.descriptions) | ||
agg.descriptions = []; | ||
const undescribedCharacteristics = new Set(Object.keys(agg.characteristics)); | ||
agg.descriptions.push(...descriptionCreators.flatMap(creator => { | ||
const { descriptions, describedCharacteristics } = creator(agg.characteristics); | ||
describedCharacteristics?.forEach(c => undescribedCharacteristics.delete(c)); | ||
return descriptions ?? []; | ||
})); | ||
while(aggStack.length){ | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
const agg = aggStack.pop()!; | ||
aggStack.push(...agg?.subAggs ?? []); | ||
if(!agg.descriptions) | ||
agg.descriptions = []; | ||
const undescribedCharacteristics = new Set(Object.keys(agg.characteristics)); | ||
agg.descriptions.push(...descriptionCreators.flatMap(creator => { | ||
const { descriptions, describedCharacteristics } = creator(agg.characteristics); | ||
describedCharacteristics?.forEach(c => undescribedCharacteristics.delete(c)); | ||
return descriptions ?? []; | ||
})); | ||
|
||
agg.descriptions.push(...[...undescribedCharacteristics].map(c => `${c}: ${agg.characteristics[c]}`)); | ||
} | ||
agg.descriptions.push(...[...undescribedCharacteristics].map(c => `${c}: ${agg.characteristics[c]}`)); | ||
} | ||
|
||
return aggRoots; | ||
return aggRoots; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
49 changes: 24 additions & 25 deletions
49
packages/change-analysis/aggregations/aggregation-module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,47 @@ | ||
import { groupArrayBy } from "cdk-change-analyzer-models"; | ||
import { Aggregation } from "cdk-change-analyzer-models"; | ||
import { Aggregation, groupArrayBy } from 'cdk-change-analyzer-models'; | ||
|
||
/** | ||
* Defines an Aggregation | ||
*/ | ||
export abstract class AggModule<T> { | ||
constructor( | ||
public readonly label: string | ||
){} | ||
constructor( | ||
public readonly label: string, | ||
){} | ||
|
||
public abstract extractGroups(entities: Set<T>): Aggregation<T>[]; | ||
public abstract extractGroups(entities: Set<T>): Aggregation<T>[]; | ||
} | ||
|
||
/** | ||
* Defines an Aggregation module that groups entities based on | ||
* an indexable value (obtained using indexValueGetter) | ||
*/ | ||
export class EqualityAggModule<T> extends AggModule<T> { | ||
constructor( | ||
label: string, | ||
public readonly indexValueGetter: (e: T) => string | number | boolean | undefined | ||
){super(label);} | ||
constructor( | ||
label: string, | ||
public readonly indexValueGetter: (e: T) => string | number | boolean | undefined, | ||
){super(label);} | ||
|
||
extractGroups(entities: Set<T>): Aggregation<T>[] { | ||
return [...groupArrayBy([...entities], this.indexValueGetter)].map(([key, ops]) => ({ | ||
entities: new Set(ops), | ||
characteristics: { | ||
[this.label]: key | ||
} | ||
})); | ||
} | ||
extractGroups(entities: Set<T>): Aggregation<T>[] { | ||
return [...groupArrayBy([...entities], this.indexValueGetter)].map(([key, ops]) => ({ | ||
entities: new Set(ops), | ||
characteristics: { | ||
[this.label]: key, | ||
}, | ||
})); | ||
} | ||
} | ||
|
||
/** | ||
* Defines an Aggregation module that groups entities based on | ||
* similarity between each pair of entities (obtained using similarityChecker) | ||
*/ | ||
export class SimilarityAggModule<T> extends AggModule<T> { | ||
constructor( | ||
label: string, | ||
public readonly similarityChecker: (e: T) => boolean | ||
){super(label);} | ||
constructor( | ||
label: string, | ||
public readonly similarityChecker: (e: T) => boolean, | ||
){super(label);} | ||
|
||
extractGroups(): Aggregation<T>[] { | ||
throw Error("Similarity Agg Module does not have an implementation yet"); | ||
} | ||
extractGroups(): Aggregation<T>[] { | ||
throw Error('Similarity Agg Module does not have an implementation yet'); | ||
} | ||
} |
138 changes: 71 additions & 67 deletions
138
packages/change-analysis/aggregations/aggregations-extractor.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,82 +1,86 @@ | ||
import { setsEqual } from "cdk-change-analyzer-models"; | ||
import { AggModuleTreeNode } from "./aggregation-module-tree-node"; | ||
import { AggCharacteristicValue, Aggregation } from "cdk-change-analyzer-models"; | ||
import { AggCharacteristicValue, Aggregation, setsEqual } from 'cdk-change-analyzer-models'; | ||
import { AggModuleTreeNode } from './aggregation-module-tree-node'; | ||
|
||
export class ModuleTreeAggsExtractor { | ||
|
||
public static extract<T>( | ||
moduleNode: AggModuleTreeNode<T>, | ||
entities: T[], | ||
): Aggregation<T>[] { | ||
return this.extractTreeRoot(moduleNode, new Set(entities)); | ||
} | ||
public static extract<T>( | ||
moduleNode: AggModuleTreeNode<T>, | ||
entities: T[], | ||
): Aggregation<T>[] { | ||
return this.extractTreeRoot(moduleNode, new Set(entities)); | ||
} | ||
|
||
private static extractTreeRoot<T>( | ||
moduleNode: AggModuleTreeNode<T>, | ||
entities: Set<T>, | ||
characteristics: Record<string, AggCharacteristicValue> = {} | ||
): Aggregation<T>[] { | ||
if(moduleNode.requiredCharacteristics){ | ||
const isValid = Object.entries(moduleNode.requiredCharacteristics).every(([c, v]) => { | ||
return characteristics[c] === v; | ||
}); | ||
if(!isValid) return []; | ||
} | ||
private static extractTreeRoot<T>( | ||
moduleNode: AggModuleTreeNode<T>, | ||
entities: Set<T>, | ||
characteristics: Record<string, AggCharacteristicValue> = {}, | ||
): Aggregation<T>[] { | ||
if(moduleNode.requiredCharacteristics){ | ||
const isValid = Object.entries(moduleNode.requiredCharacteristics).every(([c, v]) => { | ||
return characteristics[c] === v; | ||
}); | ||
if(!isValid) return []; | ||
} | ||
|
||
const directAggs = moduleNode.module.extractGroups(entities); | ||
const directAggs = moduleNode.module.extractGroups(entities); | ||
|
||
if(moduleNode.disableOnNoExtraInfo && directAggs.length <= 1) | ||
return []; | ||
if(moduleNode.disableOnNoExtraInfo && directAggs.length <= 1) | ||
return []; | ||
|
||
const finalAggs = directAggs.flatMap(g => { | ||
const gs = ModuleTreeAggsExtractor.findAggsIntersections<T>( | ||
moduleNode.submodules?.flatMap( | ||
sm => ModuleTreeAggsExtractor.extractTreeRoot(sm, g.entities, {...characteristics, ...g.characteristics}) | ||
) ?? [] | ||
); | ||
const finalAggs = directAggs.flatMap(g => { | ||
const gs = ModuleTreeAggsExtractor.findAggsIntersections<T>( | ||
moduleNode.submodules?.flatMap( | ||
sm => ModuleTreeAggsExtractor.extractTreeRoot(sm, g.entities, {...characteristics, ...g.characteristics}), | ||
) ?? [], | ||
); | ||
|
||
if(moduleNode.forceSubmoduleCollapse | ||
|| (!moduleNode.disableSubmoduleCollapse && gs.length === 1 && setsEqual(g.entities, gs[0].entities))){ | ||
return gs.map(gSubGroup => ({...gSubGroup, characteristics: {...g.characteristics, ...gSubGroup.characteristics} })); | ||
} else if(gs && gs.length) { | ||
g.subAggs = gs; | ||
gs.forEach(gSubGroup => gSubGroup.parentAgg = g); | ||
} | ||
|
||
return [g]; | ||
} | ||
if(moduleNode.forceSubmoduleCollapse || | ||
(!moduleNode.disableSubmoduleCollapse && gs.length === 1&& setsEqual(g.entities, gs[0].entities))) { | ||
return gs.map(gSubGroup => | ||
({ | ||
...gSubGroup, | ||
characteristics: {...g.characteristics, ...gSubGroup.characteristics}, | ||
}), | ||
); | ||
} else if(gs && gs.length) { | ||
g.subAggs = gs; | ||
gs.forEach(gSubGroup => gSubGroup.parentAgg = g); | ||
} | ||
|
||
return finalAggs; | ||
} | ||
return [g]; | ||
}, | ||
); | ||
|
||
return finalAggs; | ||
} | ||
|
||
private static findAggsIntersections<T>(groups: Aggregation<T>[]): Aggregation<T>[]{ | ||
const resultingIntersections: Record<string, Aggregation<T>> = {}; | ||
const indexGetter = (originalAggs: number[]) => originalAggs.join(','); | ||
private static findAggsIntersections<T>(groups: Aggregation<T>[]): Aggregation<T>[]{ | ||
const resultingIntersections: Record<string, Aggregation<T>> = {}; | ||
const indexGetter = (originalAggs: number[]) => originalAggs.join(','); | ||
|
||
for(let agg = 0; agg< groups.length; agg++){ // for each original Agg | ||
for(const operation of [...groups[agg].entities]){ // each operation in Agg | ||
const aggsContainingOperation: number[] = [agg]; | ||
for(let agg2 = agg+1; agg2 < groups.length; agg2++){ // check all other original Aggs for same operation | ||
if(groups[agg2].entities.has(operation)){ | ||
aggsContainingOperation.push(agg2); // add it to the intersection identifier | ||
groups[agg2].entities.delete(operation); | ||
} | ||
} | ||
if(aggsContainingOperation.length > 1){ | ||
const intersectionIndex = indexGetter(aggsContainingOperation); | ||
if(!resultingIntersections[intersectionIndex]){ | ||
resultingIntersections[intersectionIndex] = { | ||
entities: new Set([operation]), | ||
characteristics: Object.assign({}, ...aggsContainingOperation.map(i => groups[i].characteristics)) | ||
}; | ||
} else { | ||
resultingIntersections[intersectionIndex].entities.add(operation); | ||
} | ||
groups[agg].entities.delete(operation); | ||
} | ||
} | ||
for(let agg = 0; agg< groups.length; agg++){ // for each original Agg | ||
for(const operation of [...groups[agg].entities]){ // each operation in Agg | ||
const aggsContainingOperation: number[] = [agg]; | ||
for(let agg2 = agg+1; agg2 < groups.length; agg2++){ // check all other original Aggs for same operation | ||
if(groups[agg2].entities.has(operation)){ | ||
aggsContainingOperation.push(agg2); // add it to the intersection identifier | ||
groups[agg2].entities.delete(operation); | ||
} | ||
} | ||
if(aggsContainingOperation.length > 1){ | ||
const intersectionIndex = indexGetter(aggsContainingOperation); | ||
if(!resultingIntersections[intersectionIndex]){ | ||
resultingIntersections[intersectionIndex] = { | ||
entities: new Set([operation]), | ||
characteristics: Object.assign({}, ...aggsContainingOperation.map(i => groups[i].characteristics)), | ||
}; | ||
} else { | ||
resultingIntersections[intersectionIndex].entities.add(operation); | ||
} | ||
groups[agg].entities.delete(operation); | ||
} | ||
return [...groups, ...Object.values(resultingIntersections)].filter(agg => agg.entities.size > 0); | ||
} | ||
} | ||
return [...groups, ...Object.values(resultingIntersections)].filter(agg => agg.entities.size > 0); | ||
} | ||
} |
Oops, something went wrong.