Skip to content

Commit

Permalink
refactor(artifacts): clean up ArtifactReferenceService (spinnaker#8075)
Browse files Browse the repository at this point in the history
* refactor(artifacts): clean up and add docs to ArtifactReferenceService

* feat(artifacts): add method for removing multiple artifact references from stages

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
maggieneterval and mergify[bot] committed Mar 23, 2020
1 parent e2217c0 commit 11f2563
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,29 @@ describe('ArtifactReferenceService', () => {
expect(remover).toHaveBeenCalledTimes(0);
});
});

describe('removeReferencesFromStages', () => {
it('removes each specified artifact reference from the given stages', () => {
registerTestStage(['pathToId', 'pathToListOfIds', 'nestedPathTo.id', 'nestedPathToListOf.ids']);
const stages = [
stage({
type: 'testStage',
pathToId: 'artifact-1',
pathToListOfIds: ['artifact-2', 'artifact-3'],
nestedPathTo: { id: 'artifact-4' },
nestedPathToListOf: { ids: ['artifact-5'] },
unregisteredPath: 'artifact-1',
}),
];
ArtifactReferenceService.removeReferencesFromStages(
['artifact-1', 'artifact-2', 'artifact-4', 'artifact-5'],
stages,
);
expect(stages[0].pathToId).toBe(null);
expect(stages[0].pathToListOfIds).toEqual(['artifact-3']);
expect(stages[0].nestedPathTo.id).toBe(null);
expect(stages[0].nestedPathToListOf.ids).toEqual([]);
expect(stages[0].unregisteredPath).toEqual('artifact-1');
});
});
});
60 changes: 52 additions & 8 deletions app/scripts/modules/core/src/artifact/ArtifactReferenceService.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,75 @@
import { IStage } from 'core/domain';
import { get, noop, set } from 'lodash';

import { IStage } from 'core/domain';
import { Registry } from 'core/registry';

export class ArtifactReferenceService {
public static removeReferenceFromStages(reference: string, stages: IStage[]) {
/**
* Removes an artifact reference from each of a list of stages with a
* registered `artifactRemover` method.
*
* @param reference The ID of the artifact to remove.
* @param stages The stages from which to remove artifact references.
*/

public static removeReferenceFromStages(reference: string, stages: IStage[]): void {
(stages || []).forEach(stage => {
const stageConfig = Registry.pipeline.getStageConfig(stage);
const artifactRemover = get(stageConfig, ['artifactRemover'], noop);
artifactRemover(stage, reference);
});
}

public static removeArtifactFromField(field: string, obj: { [key: string]: string | string[] }, artifactId: string) {
const reference = get(obj, field);
/**
* Removes each of a list of artifact references from each of a list of
* stages with a registered `artifactRemover` method.
*
* @param references The list of artifact IDs to remove.
* @param stages The stages from which to remove artifact references.
*/
public static removeReferencesFromStages(references: string[], stages: IStage[]): void {
references.forEach(reference => ArtifactReferenceService.removeReferenceFromStages(reference, stages));
}

/**
* Removes an artifact reference from a field of an object. The field can
* be either a single artifact ID or a list of artifact IDs.
*
* @param path The path to the field from which to remove an artifact
* reference. A nested path (e.g., `keyA.keyB`) is valid.
* @param obj The object from which to remove the artifact reference at a
* given field.
* @param artifactId The ID of the artifact to remove.
*/
public static removeArtifactFromField(
path: string,
obj: { [key: string]: string | string[] },
artifactId: string,
): void {
const reference: string | string[] = get(obj, path);
if (Array.isArray(reference)) {
set(
obj,
field,
path,
reference.filter((a: string) => a !== artifactId),
);
} else if (reference === artifactId) {
set(obj, field, null);
set(obj, path, null);
}
}

public static removeArtifactFromFields(fields: string[]): (stage: IStage, artifactId: string) => void {
/**
* Given a list of paths, returns a callback that removes an artifact
* reference from a stage at those paths. This callback can be registered as
* the `artifactRemover` of an {IStageTypeConfig}.
*
* @param paths The paths to the fields from which to remove an artifact.
* Nested paths (e.g., `keyA.keyB`) are valid.
* @returns A function that removes references to a given `artifactId` from
* a given `stage` at each of the specified paths.
*/
public static removeArtifactFromFields(paths: string[]): (stage: IStage, artifactId: string) => void {
return (stage: IStage, artifactId: string) =>
fields.forEach(field => this.removeArtifactFromField(field, stage, artifactId));
paths.forEach(path => this.removeArtifactFromField(path, stage, artifactId));
}
}

0 comments on commit 11f2563

Please sign in to comment.