From a5821063d66275bb180fae3047bdf470ec2d3375 Mon Sep 17 00:00:00 2001 From: Dennis Seah Date: Tue, 31 Mar 2020 15:48:59 -0700 Subject: [PATCH 1/2] [HOUSEKEEPING] remove eslint disable from deployment get command --- src/commands/deployment/get.ts | 511 ++++++++++++++++----------------- 1 file changed, 255 insertions(+), 256 deletions(-) diff --git a/src/commands/deployment/get.ts b/src/commands/deployment/get.ts index 3eea9c783..7bf5f11e7 100644 --- a/src/commands/deployment/get.ts +++ b/src/commands/deployment/get.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-use-before-define */ import Table from "cli-table"; import commander from "commander"; import { @@ -78,77 +77,6 @@ export interface ValidatedOptions extends CommandOptions { outputFormat: OUTPUT_FORMAT; } -/** - * Validating the options values from commander. - * - * @param opts options values from commander - * @return validated values - * @throws Error if opts.top is not a positive integer - */ -export const validateValues = (opts: CommandOptions): ValidatedOptions => { - let top = 0; // no limits - if (opts.top) { - if (isIntegerString(opts.top)) { - top = parseInt(opts.top, 10); - } else { - throw new Error("value for top option has to be a positive number"); - } - } - - return { - buildId: opts.buildId, - commitId: opts.commitId, - deploymentId: opts.deploymentId, - env: opts.env, - imageTag: opts.imageTag, - nTop: top, - output: opts.output, - outputFormat: processOutputFormat(opts.output), - service: opts.service, - top: opts.top, - watch: opts.watch, - }; -}; - -/** - * Executes the command, can all exit function with 0 or 1 - * when command completed successfully or failed respectively. - * - * @param opts validated option values - * @param exitFn exit function - */ -export const execute = async ( - opts: CommandOptions, - exitFn: (status: number) => Promise -): Promise => { - try { - const values = validateValues(opts); - const initObjects = await initialize(); - if (opts.watch) { - await watchGetDeployments(initObjects, values); - } else { - await getDeployments(initObjects, values); - await exitFn(0); - } - } catch (err) { - logger.error(`Error occurred while getting deployment(s)`); - logger.error(err); - await exitFn(1); - } -}; - -/** - * Adds the get command to the commander command object - * @param command Commander command object to decorate - */ -export const commandDecorator = (command: commander.Command): void => { - buildCmd(command, decorator).action(async (opts: CommandOptions) => { - await execute(opts, async (status: number) => { - await exitCmd(logger, process.exit, status); - }); - }); -}; - /** * Processes the output format based on defaults * @param outputFormat Output format specified by the user @@ -163,88 +91,6 @@ export const processOutputFormat = (outputFormat: string): OUTPUT_FORMAT => { return OUTPUT_FORMAT.NORMAL; }; -/** - * Gets a list of deployments for the specified filters - * @param initObj captures keys and objects during the initialization process - * @param values validated command line values - */ -export const getDeployments = ( - initObj: InitObject, - values: ValidatedOptions -): Promise => { - const syncStatusesPromise = getClusterSyncStatuses(initObj); - const deploymentsPromise = getDeploymentsBasedOnFilters( - initObj.accountName, - initObj.key, - initObj.tableName, - initObj.partitionKey, - initObj.srcPipeline, - initObj.hldPipeline, - initObj.clusterPipeline, - values.env, - values.imageTag, - values.buildId, - values.commitId, - values.service, - values.deploymentId - ); - return new Promise((resolve, reject) => { - Promise.all([deploymentsPromise, syncStatusesPromise]) - .then(async (tuple: [IDeployment[] | undefined, ITag[] | undefined]) => { - const deployments: IDeployment[] | undefined = tuple[0]; - const syncStatuses: ITag[] | undefined = tuple[1]; - const displayedDeployments = await displayDeployments( - values, - deployments, - syncStatuses, - initObj - ); - resolve(displayedDeployments); - }) - .catch((e) => { - reject(new Error(e)); - }); - }); -}; - -/** - * Displays the deployments based on output format requested and top n - * @param values validated command line values - * @param deployments list of deployments to display - * @param syncStatuses cluster sync statuses, - * @param initObj initialization object - */ -export const displayDeployments = ( - values: ValidatedOptions, - deployments: IDeployment[] | undefined, - syncStatuses: ITag[] | undefined, - initObj: InitObject -): Promise => { - return new Promise((resolve, reject) => { - if (values.outputFormat === OUTPUT_FORMAT.WIDE) { - getPRs(deployments, initObj); - } - if (values.outputFormat === OUTPUT_FORMAT.JSON) { - console.log(JSON.stringify(deployments, null, 2)); - resolve(deployments); - } else { - Promise.all(promises) - .then(() => { - printDeployments( - deployments, - values.outputFormat, - values.nTop, - syncStatuses - ); - resolve(deployments); - }) - .catch((e) => { - reject(e); - }); - } - }); -}; - /** * Gets cluster sync statuses * @param initObj captures keys and objects during the initialization process @@ -296,74 +142,70 @@ export const getClusterSyncStatuses = ( }; /** - * Initializes the pipelines assuming that the configuration has been loaded + * Fetches pull request data for deployments that complete merge into HLD + * by merging a PR + * + * @param deployment deployment for which PR has to be fetched + * @param initObj initialization object */ -export const initialize = async (): Promise => { - const config = Config(); +export const fetchPRInformation = ( + deployment: IDeployment, + initObj: InitObject +): void => { + if (deployment.hldRepo && deployment.pr) { + const repo = getRepositoryFromURL(deployment.hldRepo); + const strPr = deployment.pr.toString(); - if ( - !config.introspection || - !config.azure_devops || - !config.introspection.azure || - !config.azure_devops.org || - !config.azure_devops.project || - !config.introspection.azure.account_name || - !config.introspection.azure.table_name || - !config.introspection.azure.key || - !config.introspection.azure.partition_key || - !config.introspection.azure.key - ) { - throw Error( - "You need to run `spk init` and `spk deployment onboard` to configure `spk." - ); + if (repo) { + const promise = fetchPR(repo, strPr, initObj.accountName); + promise.then((pr) => { + if (pr) { + pullRequests[strPr] = pr; + } + }); + promises.push(promise); + } } - - return { - clusterPipeline: new AzureDevOpsPipeline( - config.azure_devops.org, - config.azure_devops.project, - false, - config.azure_devops.access_token - ), - hldPipeline: new AzureDevOpsPipeline( - config.azure_devops.org, - config.azure_devops.project, - true, - config.azure_devops.access_token - ), - key: config.introspection.azure.key, - srcPipeline: new AzureDevOpsPipeline( - config.azure_devops.org, - config.azure_devops.project, - false, - config.azure_devops.access_token - ), - accountName: config.introspection.azure.account_name, - tableName: config.introspection.azure.table_name, - partitionKey: config.introspection.azure.partition_key, - manifestRepo: config.azure_devops.manifest_repository, - accessToken: config.azure_devops.access_token, - }; }; /** - * Returns a list of deployments for the specified filters every 5 seconds + * Gets PR information for all the deployments. * - * @param initObject Initialization Object - * @param values Validated values from commander + * @param deployments all deployments to be displayed + * @param initObj initialization object */ -export const watchGetDeployments = async ( - initObjects: InitObject, - values: ValidatedOptions -): Promise => { - const timeInterval = 5000; +export const getPRs = ( + deployments: IDeployment[] | undefined, + initObj: InitObject +): void => { + (deployments || []).forEach((d) => fetchPRInformation(d, initObj)); +}; - // Call get deployments once, and then set the timer. - await getDeployments(initObjects, values); +/** + * Returns a status indicator icon + * + * @param status Status + * @return a status indicator icon + */ +export const getStatus = (status: string): string => { + if (status === "succeeded") { + return "\u2713"; + } else if (!status) { + return "..."; + } + return "\u0445"; +}; - setInterval(async () => { - await getDeployments(initObjects, values); - }, timeInterval); +/** + * Returns a matching sync status for a deployment + * @param deployment Deployment object + * @param syncStatuses list of sync statuses for manifest + */ +export const getClusterSyncStatusForDeployment = ( + deployment: IDeployment, + syncStatuses: ITag[] +): ITag | undefined => { + return syncStatuses.find((tag) => tag.commit === deployment.manifestCommitId); }; /** @@ -544,68 +386,225 @@ export const printDeployments = ( }; /** - * Gets PR information for all the deployments. - * - * @param deployments all deployments to be displayed + * Displays the deployments based on output format requested and top n + * @param values validated command line values + * @param deployments list of deployments to display + * @param syncStatuses cluster sync statuses, * @param initObj initialization object */ -export const getPRs = ( +export const displayDeployments = ( + values: ValidatedOptions, deployments: IDeployment[] | undefined, + syncStatuses: ITag[] | undefined, initObj: InitObject -): void => { - (deployments || []).forEach((d) => fetchPRInformation(d, initObj)); +): Promise => { + return new Promise((resolve, reject) => { + if (values.outputFormat === OUTPUT_FORMAT.WIDE) { + getPRs(deployments, initObj); + } + if (values.outputFormat === OUTPUT_FORMAT.JSON) { + console.log(JSON.stringify(deployments, null, 2)); + resolve(deployments); + } else { + Promise.all(promises) + .then(() => { + printDeployments( + deployments, + values.outputFormat, + values.nTop, + syncStatuses + ); + resolve(deployments); + }) + .catch((e) => { + reject(e); + }); + } + }); }; /** - * Fetches pull request data for deployments that complete merge into HLD - * by merging a PR - * - * @param deployment deployment for which PR has to be fetched - * @param initObj initialization object + * Gets a list of deployments for the specified filters + * @param initObj captures keys and objects during the initialization process + * @param values validated command line values */ -export const fetchPRInformation = ( - deployment: IDeployment, - initObj: InitObject -): void => { - if (deployment.hldRepo && deployment.pr) { - const repo = getRepositoryFromURL(deployment.hldRepo); - const strPr = deployment.pr.toString(); - - if (repo) { - const promise = fetchPR(repo, strPr, initObj.accountName); - promise.then((pr) => { - if (pr) { - pullRequests[strPr] = pr; - } +export const getDeployments = ( + initObj: InitObject, + values: ValidatedOptions +): Promise => { + const syncStatusesPromise = getClusterSyncStatuses(initObj); + const deploymentsPromise = getDeploymentsBasedOnFilters( + initObj.accountName, + initObj.key, + initObj.tableName, + initObj.partitionKey, + initObj.srcPipeline, + initObj.hldPipeline, + initObj.clusterPipeline, + values.env, + values.imageTag, + values.buildId, + values.commitId, + values.service, + values.deploymentId + ); + return new Promise((resolve, reject) => { + Promise.all([deploymentsPromise, syncStatusesPromise]) + .then(async (tuple: [IDeployment[] | undefined, ITag[] | undefined]) => { + const deployments: IDeployment[] | undefined = tuple[0]; + const syncStatuses: ITag[] | undefined = tuple[1]; + const displayedDeployments = await displayDeployments( + values, + deployments, + syncStatuses, + initObj + ); + resolve(displayedDeployments); + }) + .catch((e) => { + reject(new Error(e)); }); - promises.push(promise); - } + }); +}; + +/** + * Initializes the pipelines assuming that the configuration has been loaded + */ +export const initialize = async (): Promise => { + const config = Config(); + + if ( + !config.introspection || + !config.azure_devops || + !config.introspection.azure || + !config.azure_devops.org || + !config.azure_devops.project || + !config.introspection.azure.account_name || + !config.introspection.azure.table_name || + !config.introspection.azure.key || + !config.introspection.azure.partition_key || + !config.introspection.azure.key + ) { + throw Error( + "You need to run `spk init` and `spk deployment onboard` to configure `spk." + ); } + + return { + clusterPipeline: new AzureDevOpsPipeline( + config.azure_devops.org, + config.azure_devops.project, + false, + config.azure_devops.access_token + ), + hldPipeline: new AzureDevOpsPipeline( + config.azure_devops.org, + config.azure_devops.project, + true, + config.azure_devops.access_token + ), + key: config.introspection.azure.key, + srcPipeline: new AzureDevOpsPipeline( + config.azure_devops.org, + config.azure_devops.project, + false, + config.azure_devops.access_token + ), + accountName: config.introspection.azure.account_name, + tableName: config.introspection.azure.table_name, + partitionKey: config.introspection.azure.partition_key, + manifestRepo: config.azure_devops.manifest_repository, + accessToken: config.azure_devops.access_token, + }; }; /** - * Returns a matching sync status for a deployment - * @param deployment Deployment object - * @param syncStatuses list of sync statuses for manifest + * Returns a list of deployments for the specified filters every 5 seconds + * + * @param initObject Initialization Object + * @param values Validated values from commander */ -export const getClusterSyncStatusForDeployment = ( - deployment: IDeployment, - syncStatuses: ITag[] -): ITag | undefined => { - return syncStatuses.find((tag) => tag.commit === deployment.manifestCommitId); +export const watchGetDeployments = async ( + initObjects: InitObject, + values: ValidatedOptions +): Promise => { + const timeInterval = 5000; + + // Call get deployments once, and then set the timer. + await getDeployments(initObjects, values); + + setInterval(async () => { + await getDeployments(initObjects, values); + }, timeInterval); }; /** - * Returns a status indicator icon + * Validating the options values from commander. * - * @param status Status - * @return a status indicator icon + * @param opts options values from commander + * @return validated values + * @throws Error if opts.top is not a positive integer */ -export const getStatus = (status: string): string => { - if (status === "succeeded") { - return "\u2713"; - } else if (!status) { - return "..."; +export const validateValues = (opts: CommandOptions): ValidatedOptions => { + let top = 0; // no limits + if (opts.top) { + if (isIntegerString(opts.top)) { + top = parseInt(opts.top, 10); + } else { + throw new Error("value for top option has to be a positive number"); + } } - return "\u0445"; + + return { + buildId: opts.buildId, + commitId: opts.commitId, + deploymentId: opts.deploymentId, + env: opts.env, + imageTag: opts.imageTag, + nTop: top, + output: opts.output, + outputFormat: processOutputFormat(opts.output), + service: opts.service, + top: opts.top, + watch: opts.watch, + }; +}; + +/** + * Executes the command, can all exit function with 0 or 1 + * when command completed successfully or failed respectively. + * + * @param opts validated option values + * @param exitFn exit function + */ +export const execute = async ( + opts: CommandOptions, + exitFn: (status: number) => Promise +): Promise => { + try { + const values = validateValues(opts); + const initObjects = await initialize(); + if (opts.watch) { + await watchGetDeployments(initObjects, values); + } else { + await getDeployments(initObjects, values); + await exitFn(0); + } + } catch (err) { + logger.error(`Error occurred while getting deployment(s)`); + logger.error(err); + await exitFn(1); + } +}; + +/** + * Adds the get command to the commander command object + * @param command Commander command object to decorate + */ +export const commandDecorator = (command: commander.Command): void => { + buildCmd(command, decorator).action(async (opts: CommandOptions) => { + await execute(opts, async (status: number) => { + await exitCmd(logger, process.exit, status); + }); + }); }; From 1286d972ff718e286e0c7c145aa16f22a940bf11 Mon Sep 17 00:00:00 2001 From: Dennis Seah Date: Wed, 1 Apr 2020 14:56:23 -0700 Subject: [PATCH 2/2] Update get.ts --- src/commands/deployment/get.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/deployment/get.ts b/src/commands/deployment/get.ts index 7bf5f11e7..a4faa1b81 100644 --- a/src/commands/deployment/get.ts +++ b/src/commands/deployment/get.ts @@ -157,7 +157,7 @@ export const fetchPRInformation = ( const strPr = deployment.pr.toString(); if (repo) { - const promise = fetchPR(repo, strPr, initObj.accountName); + const promise = fetchPR(repo, strPr, initObj.accessToken); promise.then((pr) => { if (pr) { pullRequests[strPr] = pr;