@atomist/sdm-pack-fingerprints
Version:
an Atomist SDM Extension Pack for fingerprinting code
371 lines • 17.8 kB
JavaScript
;
/*
* Copyright © 2019 Atomist, Inc.
*
* Licensed 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.
*/
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const automation_client_1 = require("@atomist/automation-client");
const sdm_1 = require("@atomist/sdm");
const slack_messages_1 = require("@atomist/slack-messages");
const fingerprints_1 = require("../../adhoc/fingerprints");
const preferences_1 = require("../../adhoc/preferences");
const Aspects_1 = require("../../machine/Aspects");
const broadcast_1 = require("./broadcast");
let SetTargetFingerprintFromLatestMasterParameters = class SetTargetFingerprintFromLatestMasterParameters {
constructor() {
this.branch = "master";
}
};
__decorate([
automation_client_1.MappedParameter(automation_client_1.MappedParameters.GitHubOwner),
__metadata("design:type", String)
], SetTargetFingerprintFromLatestMasterParameters.prototype, "owner", void 0);
__decorate([
automation_client_1.MappedParameter(automation_client_1.MappedParameters.GitHubRepository),
__metadata("design:type", String)
], SetTargetFingerprintFromLatestMasterParameters.prototype, "repo", void 0);
__decorate([
automation_client_1.MappedParameter(automation_client_1.MappedParameters.GitHubRepositoryProvider),
__metadata("design:type", String)
], SetTargetFingerprintFromLatestMasterParameters.prototype, "providerId", void 0);
__decorate([
automation_client_1.Parameter({
required: true,
pattern: /[\w-]+::[\w-]+(::[\w-]+)?/,
description: `Please enter the fingerprint (format type::name)`,
displayName: `Please enter the fingerprint (format type::name)`,
}),
__metadata("design:type", String)
], SetTargetFingerprintFromLatestMasterParameters.prototype, "fingerprint", void 0);
__decorate([
automation_client_1.Parameter({ required: false, displayable: false }),
__metadata("design:type", String)
], SetTargetFingerprintFromLatestMasterParameters.prototype, "branch", void 0);
__decorate([
automation_client_1.Parameter({ required: false, displayable: false }),
__metadata("design:type", String)
], SetTargetFingerprintFromLatestMasterParameters.prototype, "msgId", void 0);
SetTargetFingerprintFromLatestMasterParameters = __decorate([
automation_client_1.Parameters()
], SetTargetFingerprintFromLatestMasterParameters);
exports.SetTargetFingerprintFromLatestMasterParameters = SetTargetFingerprintFromLatestMasterParameters;
/**
* bootstraps a Fingerprint from a project
* looks up the fingerprint before setting it but name of fingerprint is in the parameter list
*/
function setTargetFingerprintFromLatestMaster(sdm, aspects) {
return {
name: "SetTargetFingerprintFromLatestMaster",
intent: [
`set fingerprint target from master ${sdm.configuration.name.replace("@", "")}`,
`setFingerprintGoalFromMaster ${sdm.configuration.name.replace("@", "")}`,
],
description: "set a new target for a team to consume a particular version",
paramsMaker: SetTargetFingerprintFromLatestMasterParameters,
listener: (cli) => __awaiter(this, void 0, void 0, function* () {
const branch = cli.parameters.branch || "master";
const query = yield cli.context.graphClient.query({
name: "GetFpByBranch",
options: automation_client_1.QueryNoCacheOptions,
variables: {
owner: cli.parameters.owner,
repo: cli.parameters.repo,
branch,
},
});
const { type, name } = preferences_1.fromName(cli.parameters.fingerprint);
const fp = query.Repo[0].branches[0].commit.analysis.find(x => x.name === name && x.type === type);
automation_client_1.logger.info(`found sha ${fp.sha}`);
fp.data = JSON.parse(fp.data);
if (!!fp.sha) {
yield (preferences_1.setFPTarget(cli.context.graphClient))(fp.type, fp.name, fp);
return broadcast_1.askAboutBroadcast(cli, aspects, {
name: fp.name,
type: fp.type,
data: fp.data,
sha: fp.sha,
}, cli.parameters.msgId);
}
else {
return automation_client_1.FailurePromise;
}
}),
};
}
exports.setTargetFingerprintFromLatestMaster = setTargetFingerprintFromLatestMaster;
let UpdateTargetFingerprintParameters = class UpdateTargetFingerprintParameters {
};
__decorate([
automation_client_1.Parameter({ required: false, displayable: false }),
__metadata("design:type", String)
], UpdateTargetFingerprintParameters.prototype, "msgId", void 0);
__decorate([
automation_client_1.Parameter({ required: true }),
__metadata("design:type", String)
], UpdateTargetFingerprintParameters.prototype, "sha", void 0);
__decorate([
automation_client_1.Parameter({ required: true }),
__metadata("design:type", String)
], UpdateTargetFingerprintParameters.prototype, "targetfingerprint", void 0);
__decorate([
automation_client_1.Parameter({ required: false, type: "boolean" }),
__metadata("design:type", Boolean)
], UpdateTargetFingerprintParameters.prototype, "broadcast", void 0);
UpdateTargetFingerprintParameters = __decorate([
automation_client_1.Parameters()
], UpdateTargetFingerprintParameters);
exports.UpdateTargetFingerprintParameters = UpdateTargetFingerprintParameters;
exports.UpdateTargetFingerprintName = "RegisterTargetFingerprint";
/**
* Used by MessageMaker to implement SetNewTarget
* (knows the name, type, and sha of the potential target fingerprint)
*/
function updateTargetFingerprint(sdm, aspects) {
return {
name: exports.UpdateTargetFingerprintName,
description: "set a new target for a team to consume a particular version",
paramsMaker: UpdateTargetFingerprintParameters,
intent: [
`register fingerprint target ${sdm.configuration.name.replace("@", "")}`,
],
listener: (cli) => __awaiter(this, void 0, void 0, function* () {
const { type, name } = preferences_1.fromName(cli.parameters.targetfingerprint);
const query = yield cli.context.graphClient.query({
options: automation_client_1.QueryNoCacheOptions,
name: "GetFpBySha",
variables: {
type,
name,
sha: cli.parameters.sha,
},
});
const fp = query.SourceFingerprint;
fp.data = JSON.parse(fp.data);
const fingerprint = {
name: fp.name,
type: fp.type,
data: fp.data,
sha: fp.sha,
};
yield (preferences_1.setFPTarget(cli.context.graphClient))(type, name, fingerprint);
if (!!cli.parameters.broadcast) {
return broadcast_1.askAboutBroadcast(cli, aspects, fingerprint, cli.parameters.msgId);
}
else {
yield cli.addressChannels(sdm_1.slackSuccessMessage("New Fingerprint Target", `Successfully set new target for fingerprint ${slack_messages_1.codeLine(preferences_1.toName(fp.type, fp.name))}`));
}
}),
};
}
exports.updateTargetFingerprint = updateTargetFingerprint;
let SetTargetFingerprintParameters = class SetTargetFingerprintParameters {
};
__decorate([
automation_client_1.Parameter({ required: true, displayable: false, control: "textarea", pattern: /.*/ }),
__metadata("design:type", String)
], SetTargetFingerprintParameters.prototype, "fp", void 0);
__decorate([
automation_client_1.Parameter({ required: false, displayable: false }),
__metadata("design:type", String)
], SetTargetFingerprintParameters.prototype, "msgId", void 0);
SetTargetFingerprintParameters = __decorate([
automation_client_1.Parameters()
], SetTargetFingerprintParameters);
exports.SetTargetFingerprintParameters = SetTargetFingerprintParameters;
/**
* Used by other diff handlers to change or bootstrap a target because coordinates have changed
* (knows the whole json structure of the fingerprint)
*/
function setTargetFingerprint(aspects) {
return {
name: "SetTargetFingerprint",
description: "set a target fingerprint",
paramsMaker: SetTargetFingerprintParameters,
listener: (cli) => __awaiter(this, void 0, void 0, function* () {
automation_client_1.logger.info(`set target fingerprint for ${cli.parameters.fp}`);
const fp = Object.assign({ user: { id: cli.context.source.slack.user.id } }, JSON.parse(cli.parameters.fp));
yield (preferences_1.setFPTarget(cli.context.graphClient))(fp.type, fp.name, fp);
return broadcast_1.askAboutBroadcast(cli, aspects, fp, cli.parameters.msgId);
}),
};
}
exports.setTargetFingerprint = setTargetFingerprint;
let DeleteTargetFingerprintParameters = class DeleteTargetFingerprintParameters {
};
__decorate([
automation_client_1.Parameter({ required: true }),
__metadata("design:type", String)
], DeleteTargetFingerprintParameters.prototype, "type", void 0);
__decorate([
automation_client_1.Parameter({ required: true }),
__metadata("design:type", String)
], DeleteTargetFingerprintParameters.prototype, "name", void 0);
__decorate([
automation_client_1.Parameter({ required: false, displayable: false }),
__metadata("design:type", String)
], DeleteTargetFingerprintParameters.prototype, "msgId", void 0);
DeleteTargetFingerprintParameters = __decorate([
automation_client_1.Parameters()
], DeleteTargetFingerprintParameters);
exports.DeleteTargetFingerprintParameters = DeleteTargetFingerprintParameters;
function deleteTargetFingerprint(sdm) {
return {
name: "DeleteTargetFingerprint",
intent: [
`delete fingerprint target ${sdm.configuration.name.replace("@", "")}`,
`deleteFingerprintTarget ${sdm.configuration.name.replace("@", "")}`,
],
description: "remove the team target for a particular fingerprint",
paramsMaker: DeleteTargetFingerprintParameters,
listener: (cli) => __awaiter(this, void 0, void 0, function* () {
return (preferences_1.deleteFPTarget(cli.context.graphClient))(cli.parameters.type, cli.parameters.name)
.then(result => {
return {
code: 0,
message: `successfully deleted ${cli.parameters.name}`,
};
})
.catch(error => {
automation_client_1.logger.error(error);
return {
code: 1,
message: `failed to delete target`,
};
});
}),
};
}
exports.deleteTargetFingerprint = deleteTargetFingerprint;
/**
* Used in other diff handlers to maybe choose to set a new target because one of them has changed
* (assumed to be a new message - not updating anything)
*
* @param ctx
* @param feature
* @param fp
* @param channel
*/
function setNewTargetFingerprint(ctx, aspect, fp, channel) {
return __awaiter(this, void 0, void 0, function* () {
// TODO this FP doesn't necessarily hold an FP with a version
const message = sdm_1.slackQuestionMessage("Fingerprint Target", `Shall we update the target of ${Aspects_1.displayName(aspect, fp)} to \`${Aspects_1.displayValue(aspect, fp)}\` for all projects?`, {
actions: [
sdm_1.actionableButton({
text: "Set Target",
}, setTargetFingerprint([aspect]), {
fp: JSON.stringify(fp),
}),
],
callback_id: "atm-confirm-done",
});
yield ctx.messageClient.addressChannels(message, channel);
// I don't want to vote on whether there was a compliance issue here
return { abstain: true };
});
}
exports.setNewTargetFingerprint = setNewTargetFingerprint;
let SelectTargetFingerprintFromCurrentProjectParameters = class SelectTargetFingerprintFromCurrentProjectParameters {
};
__decorate([
automation_client_1.MappedParameter(automation_client_1.MappedParameters.GitHubOwner),
__metadata("design:type", String)
], SelectTargetFingerprintFromCurrentProjectParameters.prototype, "owner", void 0);
__decorate([
automation_client_1.MappedParameter(automation_client_1.MappedParameters.GitHubRepository),
__metadata("design:type", String)
], SelectTargetFingerprintFromCurrentProjectParameters.prototype, "repo", void 0);
__decorate([
automation_client_1.MappedParameter(automation_client_1.MappedParameters.GitHubRepositoryProvider),
__metadata("design:type", String)
], SelectTargetFingerprintFromCurrentProjectParameters.prototype, "providerId", void 0);
__decorate([
automation_client_1.Parameter({ required: false, description: "pull fingerprints from a branch ref" }),
__metadata("design:type", String)
], SelectTargetFingerprintFromCurrentProjectParameters.prototype, "branch", void 0);
__decorate([
automation_client_1.Parameter({ required: false, displayable: false }),
__metadata("design:type", String)
], SelectTargetFingerprintFromCurrentProjectParameters.prototype, "msgId", void 0);
SelectTargetFingerprintFromCurrentProjectParameters = __decorate([
automation_client_1.Parameters()
], SelectTargetFingerprintFromCurrentProjectParameters);
exports.SelectTargetFingerprintFromCurrentProjectParameters = SelectTargetFingerprintFromCurrentProjectParameters;
function shortenName(s) {
if (s.length >= 30) {
return "..." + s.substring(s.length - 27);
}
else {
return s;
}
}
/**
* Bootstrap a fingerprint target by selecting one out of the current set
*/
function selectTargetFingerprintFromCurrentProject(sdm) {
return {
name: "SelectTargetFingerprintFromCurrentProject",
intent: [
`set fingerprint target ${sdm.configuration.name.replace("@", "")}`,
`setFingerprintTarget ${sdm.configuration.name.replace("@", "")}`,
`setTargetFingerprint ${sdm.configuration.name.replace("@", "")}`,
],
description: "select a fingerprint in this project to become a target fingerprint",
paramsMaker: SelectTargetFingerprintFromCurrentProjectParameters,
listener: (cli) => __awaiter(this, void 0, void 0, function* () {
// this has got to be wrong. ugh
const branch = cli.parameters.branch || "master";
const fps = yield fingerprints_1.queryFingerprintsByBranchRef(cli.context.graphClient)(cli.parameters.repo, cli.parameters.owner, branch);
const message = sdm_1.slackQuestionMessage("Fingerprint Target", "Choose one of the current fingerprints:", {
actions: [
automation_client_1.menuForCommand({
text: "select fingerprint",
options: [
...fps.map(x => {
return {
value: preferences_1.toName(x.type, x.name),
text: shortenName(x.name),
};
}),
],
}, setTargetFingerprintFromLatestMaster(sdm, []).name, "fingerprint", {
owner: cli.parameters.owner,
repo: cli.parameters.repo,
branch,
providerId: cli.parameters.providerId,
}),
],
});
return cli.addressChannels(message);
}),
};
}
exports.selectTargetFingerprintFromCurrentProject = selectTargetFingerprintFromCurrentProject;
//# sourceMappingURL=updateTarget.js.map