UNPKG

appcenter-cli

Version:

Command line tool for Visual Studio App Center

134 lines (108 loc) 5.72 kB
import { AppCommand, CommandArgs, CommandResult, help, failure, ErrorCodes, success, shortName, longName } from "../../../util/commandline"; import { out } from "../../../util/interaction"; import { inspect } from "util"; import { AppCenterClient, models, clientRequest } from "../../../util/apis"; import * as chalk from "chalk"; import { scriptName } from "../../../util/misc"; import { formatDate } from "./lib/date-helper"; const debug = require("debug")("appcenter-cli:commands:codepush:deployments:list"); @help("List the deployments associated with an app") export default class CodePushDeploymentListListCommand extends AppCommand { @help("Specifies whether to display the deployment keys") @shortName("k") @longName("displayKeys") public displayKeys: boolean; constructor(args: CommandArgs) { super(args); } async run(client: AppCenterClient): Promise<CommandResult> { const app = this.app; let deployments: models.Deployment[]; try { const httpRequest = await out.progress("Getting CodePush deployments...", clientRequest<models.Deployment[]>( (cb) => client.codePushDeployments.list(app.ownerName, app.appName, cb))); deployments = httpRequest.result; if (this.displayKeys) { out.table(out.getCommandOutputTableOptions(this.generateColoredTableTitles(["Name", "Key"])), deployments.map((deployment) => [deployment.name, deployment.key]) ); } else { out.text("Note: To display deployment keys add -k|--displayKeys option"); out.table(out.getCommandOutputTableOptions(this.generateColoredTableTitles(["Name", "Update Metadata", "Install Metrics"])), await this.generateTableInfoRows(deployments, client) ); } return success(); } catch (error) { debug(`Failed to get list of Codepush deployments - ${inspect(error)}`); if (error.statusCode === 404) { const appNotFoundErrorMsg = `The app ${this.identifier} does not exist. Please double check the name, and provide it in the form owner/appname. \nRun the command ${chalk.bold(`${scriptName} apps list`)} to see what apps you have access to.`; return failure(ErrorCodes.InvalidParameter, appNotFoundErrorMsg); } else { return failure(ErrorCodes.Exception, "Failed to get list of deployments for the app"); } } } private generateColoredTableTitles(tableTitles: string[]): string[] { return tableTitles.map((title) => chalk.cyan(title)); } private async generateTableInfoRows(deployments: models.Deployment[], client: AppCenterClient): Promise<string[][]> { return await Promise.all(deployments.map(async (deployment: models.Deployment): Promise<string[]> => { let metadataString: string = ""; let metricsString: string = ""; if (deployment.latestRelease) { metadataString = this.generateMetadataString(deployment.latestRelease); metricsString = await this.getMetricsString(deployment, client); } else { metadataString = chalk.magenta("No updates released"); metricsString = chalk.magenta("No installs recorded"); } return [deployment.name, metadataString, metricsString]; })); } private async getMetricsString(deployment: models.Deployment, client: AppCenterClient): Promise<string> { let metrics: models.CodePushReleaseMetric[]; const httpRequest = await out.progress("Getting CodePush deployments metrics...", clientRequest<models.CodePushReleaseMetric[]>( (cb) => client.codePushDeploymentMetrics.get(deployment.name, this.app.ownerName, this.app.appName, cb))); metrics = httpRequest.result; let releasesTotalActive: number = 0; metrics.forEach((metric) => releasesTotalActive += metric.active); const releaseMetrics: models.CodePushReleaseMetric = metrics.find((metric) => metric.label === deployment.latestRelease.label); return this.generateMetricsString(releaseMetrics, releasesTotalActive); } private generateMetricsString(releaseMetrics: models.CodePushReleaseMetric, releasesTotalActive: number): string { if (releaseMetrics) { let metricsString: string = ""; const activePercent: number = (releasesTotalActive) ? releaseMetrics.active / releasesTotalActive * 100 : 0.0; let percentString: string; if (activePercent === 100.0) { percentString = "100%"; } else if (activePercent === 0.0) { percentString = "0%"; } else { percentString = activePercent.toPrecision(2) + "%"; } metricsString += chalk.green("Active: ") + percentString + ` (${releaseMetrics.active} of ${releasesTotalActive})\n`; if (releaseMetrics.installed != null) { metricsString += chalk.green("Installed: ") + releaseMetrics.installed; } const pending: number = releaseMetrics.downloaded - releaseMetrics.installed - releaseMetrics.failed; if (pending) { metricsString += ` (${pending} pending)`; } return metricsString; } else { return chalk.magenta("No installs recorded"); } } private generateMetadataString(release: models.CodePushRelease): string { let metadataString: string = ""; const lineFeed: string = "\n"; metadataString += chalk.green("Label: ") + release.label + lineFeed; metadataString += chalk.green("App Version: ") + release.targetBinaryRange + lineFeed; metadataString += chalk.green("Mandatory: ") + (release.isMandatory ? "Yes" : "No") + lineFeed; metadataString += chalk.green("Release Time: ") + formatDate(release.uploadTime) + lineFeed; metadataString += chalk.green("Released By: ") + release.releasedBy; return metadataString; } }