From d54c6528c640779fbd4aac37009687106fc20ced Mon Sep 17 00:00:00 2001 From: Wassim Chegham Date: Fri, 1 Nov 2019 18:34:56 +0100 Subject: [PATCH] feat: add a dry-run and verbose modes --- src/commands/init.ts | 4 +++- src/core/utils.ts | 19 +++++++++++++++---- src/features/container-registry/index.ts | 12 ++++++++---- src/features/kubernetes/index.ts | 6 +++--- src/features/resource-group/create.ts | 4 +++- src/features/storage/index.ts | 10 ++++++---- src/index.ts | 8 ++++++++ 7 files changed, 46 insertions(+), 17 deletions(-) diff --git a/src/commands/init.ts b/src/commands/init.ts index 2dff92a..630abb4 100644 --- a/src/commands/init.ts +++ b/src/commands/init.ts @@ -65,7 +65,9 @@ module.exports = async function(options?: HexaInitOptions) { } catch (error) { console.log(chalk.red(`✗ ${error.stack || error}`)); console.log(chalk.red(`✗ Abort.`)); - process.exit(1); + if (!!process.env.HEXA_DRY_RUN) { + process.exit(1); + } } } diff --git a/src/core/utils.ts b/src/core/utils.ts index 2587c34..a20c77b 100644 --- a/src/core/utils.ts +++ b/src/core/utils.ts @@ -7,7 +7,8 @@ const ora = require("ora"); const Configstore = require("configstore"); const dotenv = require("dotenv"); const packageJson = require("../../package.json"); -const debug = require("debug")(`hexa`); +const debugCli = require("debug")(`hexa`); +const debug = require("debug")(`utils`); const crypto = require("crypto"); // generate a Global UUID per execution. @@ -22,7 +23,7 @@ export const uuid = () => { }; export const sanitize = (name: string) => - name + (name || "") .replace(/[\W_]+/gim, "") .trim() .substr(0, 20); @@ -57,7 +58,7 @@ export const FEATURES = [ short: "Kubernetes" } ]; -export const WORKSPACE_FILENAME = "hexa.json"; +export const WORKSPACE_FILENAME = process.env.HEXA_DRY_RUN ? "hexa.test.json" : "hexa.json"; export const ENV_FILENAME = ".env"; const IS_DEBUG = !!process.env.DEBUG; @@ -73,7 +74,17 @@ export async function runCmd(command: string, loadingMessage?: string, options?: if (options && options.cwd) { debug(`cwd=${chalk.cyan(options.cwd)}`); } - debug(chalk.cyan(command)); + + debugCli(chalk.cyan(command)); + + if (process.env.HEXA_DRY_RUN) { + try { + spinner.succeed(); + } catch (error) { + // don't catch errors here + } + return resolve("HEXA_DRY_RUN"); + } shell.exec( command, diff --git a/src/features/container-registry/index.ts b/src/features/container-registry/index.ts index aa1db09..c7c551a 100644 --- a/src/features/container-registry/index.ts +++ b/src/features/container-registry/index.ts @@ -12,11 +12,15 @@ module.exports = async function() { debug(`Using resource group ${chalk.green(resourceGroup.name)}`); // https://docs.microsoft.com/en-us/cli/azure/acr?view=azure-cli-latest#az-acr-list - const acrList = await az( + let acrList = await az( `acr list --resource-group "${resourceGroup.name}" --subscription "${subscription.id}" --query "[].{id:id, name:name, hostname:loginServer, tags:tags}"`, `Checking Container Registry for project ${chalk.cyan(resourceGroup.name)}...` ); + if (!Array.isArray(acrList)) { + acrList = []; + } + let creationMode = process.env.HEXA_AUTO_MODE ? "AUTOMATIC" : "MANUAL"; let selectedAcrId: string | null = null; @@ -26,7 +30,7 @@ module.exports = async function() { } if (creationMode === "AUTOMATIC") { - if (acrList.length === 1) { + if (Array.isArray(acrList) && acrList.length === 1) { const acr = acrList[0]; debug(`found one container registry ${chalk.green(acr.name)}`); @@ -40,11 +44,11 @@ module.exports = async function() { // we founf one cluster but it was not created by Hexa, go ahead and automatically create one return (await require(`./create`))("AUTOMATIC"); } - } else { + } else if (Array.isArray(acrList)) { // we found many ACR accounts, let the user choose the right one selectedAcrId = (await chooseAcrAccount(acrList)).registry as (string & CreationMode); } - } else { + } else if (Array.isArray(acrList)) { selectedAcrId = (await chooseAcrAccount(acrList)).registry as (string & CreationMode); } diff --git a/src/features/kubernetes/index.ts b/src/features/kubernetes/index.ts index 0f9b669..8893929 100644 --- a/src/features/kubernetes/index.ts +++ b/src/features/kubernetes/index.ts @@ -36,11 +36,11 @@ module.exports = async function() { // fallback to either a MANUAL or AUTOMATIC creation, depending on the global config let creationMode = process.env.HEXA_AUTO_MODE ? "AUTOMATIC" : "MANUAL"; - if (kubeClustersList.length === 0) { + if (Array.isArray(kubeClustersList) && kubeClustersList.length === 0) { // no cluster found, create one using the selected creation mode await createK8sClutster(creationMode); k8s = Config.get("k8s") as AzureKubernetesCluster; - } else if (kubeClustersList.length === 1) { + } else if (Array.isArray(kubeClustersList) && kubeClustersList.length === 1) { const cluster = kubeClustersList[0]; debug(`found one cluster ${chalk.green(cluster.name)}`); @@ -56,7 +56,7 @@ module.exports = async function() { // note: the user may wanna create a new clustor k8s.id = (await chooseKubernetesCluster(kubeClustersList)).cluster as (string & CreationMode); } - } else { + } else if (Array.isArray(kubeClustersList)) { // we found many clusters, let the user choose the right one // note: the user may wanna create a new clustor k8s.id = (await chooseKubernetesCluster(kubeClustersList)).cluster as (string & CreationMode); diff --git a/src/features/resource-group/create.ts b/src/features/resource-group/create.ts index 040c146..c74dec6 100644 --- a/src/features/resource-group/create.ts +++ b/src/features/resource-group/create.ts @@ -26,7 +26,9 @@ module.exports = async function(creationMode: CreationMode) { isProjectExists = await az(`group exists --name ${name}`, `Checking for existing project ${chalk.cyan(name)}...`); } - if (isProjectExists.message.includes("true")) { + debug(`isProjectExists=${chalk.green(JSON.stringify(isProjectExists))}`); + + if (isProjectExists?.message.includes("true")) { // https://docs.microsoft.com/en-us/cli/azure/group?view=azure-cli-latest#az-group-show project = await az(`group show -n workspacetest --query "{name:name, id:id, location:location}"`, `Bootstrapping project ${chalk.cyan(name)}...`); } else { diff --git a/src/features/storage/index.ts b/src/features/storage/index.ts index ae7c188..c914a07 100644 --- a/src/features/storage/index.ts +++ b/src/features/storage/index.ts @@ -23,20 +23,22 @@ module.exports = async function() { `Checking storage for project ${chalk.cyan(resourceGroup.name)}...` ); + debug(`storageAccountsList=${chalk.green(JSON.stringify(storageAccountsList))}`); + // In case we dont find any storage account that had been created by Hexa, // fallback to either a MANUAL or AUTOMATIC creation, depending on the global config let creationMode = process.env.HEXA_AUTO_MODE ? "AUTOMATIC" : "MANUAL"; - if (storageAccountsList.length === 0) { + if (Array.isArray(storageAccountsList) && storageAccountsList.length === 0) { // no storage account found, create one using the selected creation mode await storageCreation(creationMode); storage = Config.get("storage") as AzureStorage; - } else if (storageAccountsList.length === 1) { + } else if (Array.isArray(storageAccountsList) && storageAccountsList.length === 1) { const storageAccount = storageAccountsList[0]; debug(`found one storage account ${chalk.green(storageAccount.name)}`); // has the account been created with Hexa? - if (creationMode === "AUTOMATIC" && storageAccount && storageAccount.tags && storageAccount.tags["x-created-by"] === "hexa") { + if (creationMode === "AUTOMATIC" && storageAccount?.tags?.["x-created-by"] === "hexa") { debug(`using storage account ${chalk.green(storageAccount.name)}`); // use this storage account @@ -47,7 +49,7 @@ module.exports = async function() { // note: the user may wanna create a new storage account storage.id = (await chooseAccountStorage(storageAccountsList)).storage as (string & CreationMode); } - } else { + } else if(Array.isArray(storageAccountsList)) { // we found many storage accounts, let the user choose the right one // note: the user may wanna create a new storage account storage.id = (await chooseAccountStorage(storageAccountsList)).storage as (string & CreationMode); diff --git a/src/index.ts b/src/index.ts index daad5df..1a4b93b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -50,7 +50,9 @@ let debug: Function; .option("-s, --sas", "use SAS token (only: storage and database)", false) .option("-t, --token", "generate a Storage token into a .env file", false) .option("-u, --use ", "use a specific build system (e.g. tsc,bazel)", "tsc") + .option("-v, --verbose", "enable verbose mode", false) .option("-y, --yes", "answer yes to all confirmations", false) + .option("--dry-run", "do not execute real commands.", false) .option("--yolo", "enable all modes and all services", false) .parse(process.argv); @@ -58,6 +60,9 @@ let debug: Function; // WARNING: order matters if (program.debug) { + process.env.DEBUG = "hexa"; + } + if (program.verbose) { process.env.DEBUG = "*"; } @@ -94,6 +99,9 @@ let debug: Function; if (program.use === "bazel") { process.env.HEXA_USE_BAZEL = "1"; } + if (program.dryRun) { + process.env.HEXA_DRY_RUN = "1"; + } // use process.argv not program.argv const commandName = process.argv[2];