From ff7dd57c804fded27038d1e5112351b825dbe468 Mon Sep 17 00:00:00 2001 From: Dennis Seah Date: Mon, 30 Mar 2020 19:12:26 -0700 Subject: [PATCH 1/2] [FEATURE] Error code and exception chain for hld init command --- src/commands/hld/init.ts | 12 ++-- src/lib/fileutils.ts | 140 +++++++++++++++++++++++---------------- src/lib/gitutils.ts | 9 ++- src/lib/i18n.json | 10 ++- 4 files changed, 106 insertions(+), 65 deletions(-) diff --git a/src/commands/hld/init.ts b/src/commands/hld/init.ts index df6c53d4a..f8a78e92a 100644 --- a/src/commands/hld/init.ts +++ b/src/commands/hld/init.ts @@ -10,6 +10,8 @@ import { checkoutCommitPushCreatePRLink } from "../../lib/gitutils"; import { hasValue } from "../../lib/validator"; import { logger } from "../../logger"; import decorator from "./init.decorator.json"; +import { build as buildError, log as logError } from "../../lib/errorBuilder"; +import { errorStatusCode } from "../../lib/errorStatusCode"; // values that we need to pull out from command operator interface CommandOptions { @@ -57,7 +59,10 @@ export const execute = async ( ): Promise => { try { if (!hasValue(hldRepoPath)) { - throw new Error("project path is not provided"); + throw buildError( + errorStatusCode.VALIDATION_ERR, + "hld-init-cmd-project-path-missing" + ); } await initialize( hldRepoPath, @@ -68,10 +73,9 @@ export const execute = async ( ); await exitFn(0); } catch (err) { - logger.error( - `Error occurred while initializing hld repository ${hldRepoPath}` + logError( + buildError(errorStatusCode.CMD_EXE_ERR, "hld-init-cmd-failed", err) ); - logger.error(err); await exitFn(1); } }; diff --git a/src/lib/fileutils.ts b/src/lib/fileutils.ts index 5206ab626..1f0de025b 100644 --- a/src/lib/fileutils.ts +++ b/src/lib/fileutils.ts @@ -617,37 +617,44 @@ const manifestGenerationPipelineYaml = (): string => { export const generateHldAzurePipelinesYaml = ( targetDirectory: string ): void => { - const absTargetPath = path.resolve(targetDirectory); - logger.info(`Generating hld manifest-generation in ${absTargetPath}`); - - const azurePipelinesYamlPath = path.join( - absTargetPath, - RENDER_HLD_PIPELINE_FILENAME - ); + try { + const absTargetPath = path.resolve(targetDirectory); + logger.info(`Generating hld manifest-generation in ${absTargetPath}`); - if (fs.existsSync(azurePipelinesYamlPath)) { - logger.warn( - `Existing ${RENDER_HLD_PIPELINE_FILENAME} found at ${azurePipelinesYamlPath}, skipping generation.` + const azurePipelinesYamlPath = path.join( + absTargetPath, + RENDER_HLD_PIPELINE_FILENAME ); - return; - } - const hldYaml = manifestGenerationPipelineYaml(); - logger.info( - `Writing ${RENDER_HLD_PIPELINE_FILENAME} file to ${azurePipelinesYamlPath}` - ); + if (fs.existsSync(azurePipelinesYamlPath)) { + logger.warn( + `Existing ${RENDER_HLD_PIPELINE_FILENAME} found at ${azurePipelinesYamlPath}, skipping generation.` + ); + return; + } + const hldYaml = manifestGenerationPipelineYaml(); + logger.info( + `Writing ${RENDER_HLD_PIPELINE_FILENAME} file to ${azurePipelinesYamlPath}` + ); - const requiredPipelineVariables = [ - `'MANIFEST_REPO' (Repository for your kubernetes manifests in AzDo. eg. 'dev.azure.com/bhnook/fabrikam/_git/materialized')`, - `'PAT' (AzDo Personal Access Token with permissions to the HLD repository.)`, - ].join(", "); + const requiredPipelineVariables = [ + `'MANIFEST_REPO' (Repository for your kubernetes manifests in AzDo. eg. 'dev.azure.com/bhnook/fabrikam/_git/materialized')`, + `'PAT' (AzDo Personal Access Token with permissions to the HLD repository.)`, + ].join(", "); - logger.info( - `Generated ${RENDER_HLD_PIPELINE_FILENAME}. Commit and push this file to master before attempting to deploy via the command 'spk hld install-manifest-pipeline'; before running the pipeline ensure the following environment variables are available to your pipeline: ${requiredPipelineVariables}` - ); + logger.info( + `Generated ${RENDER_HLD_PIPELINE_FILENAME}. Commit and push this file to master before attempting to deploy via the command 'spk hld install-manifest-pipeline'; before running the pipeline ensure the following environment variables are available to your pipeline: ${requiredPipelineVariables}` + ); - writeVersion(azurePipelinesYamlPath); - fs.appendFileSync(azurePipelinesYamlPath, hldYaml, "utf8"); + writeVersion(azurePipelinesYamlPath); + fs.appendFileSync(azurePipelinesYamlPath, hldYaml, "utf8"); + } catch (err) { + throw buildError( + errorStatusCode.FILE_IO_ERR, + "fileutils-generate-hld-pipeline-yaml", + err + ); + } }; /** @@ -682,34 +689,41 @@ export const generateDefaultHldComponentYaml = ( componentName: string, componentPath: string ): void => { - const absTargetPath = path.resolve(targetDirectory); - logger.info(`Generating component.yaml in ${absTargetPath}`); - - const fabrikateComponentPath = path.join(absTargetPath, "component.yaml"); + try { + const absTargetPath = path.resolve(targetDirectory); + logger.info(`Generating component.yaml in ${absTargetPath}`); + + const fabrikateComponentPath = path.join(absTargetPath, "component.yaml"); + + if (fs.existsSync(fabrikateComponentPath)) { + logger.warn( + `Existing component.yaml found at ${fabrikateComponentPath}, skipping generation.` + ); + return; + } + + const componentYaml = defaultComponentYaml( + componentGit, + componentName, + componentPath + ); - if (fs.existsSync(fabrikateComponentPath)) { - logger.warn( - `Existing component.yaml found at ${fabrikateComponentPath}, skipping generation.` + logger.info( + `Writing ${HLD_COMPONENT_FILENAME} file to ${fabrikateComponentPath}` ); - return; + fs.writeFileSync( + fabrikateComponentPath, + yaml.safeDump(componentYaml, { lineWidth: Number.MAX_SAFE_INTEGER }), + "utf8" + ); + } catch (err) { + throw buildError( + errorStatusCode.FILE_IO_ERR, + "fileutils-generate-default-hld-component-yaml", + err + ); } - - const componentYaml = defaultComponentYaml( - componentGit, - componentName, - componentPath - ); - - logger.info( - `Writing ${HLD_COMPONENT_FILENAME} file to ${fabrikateComponentPath}` - ); - - fs.writeFileSync( - fabrikateComponentPath, - yaml.safeDump(componentYaml, { lineWidth: Number.MAX_SAFE_INTEGER }), - "utf8" - ); }; const hldLifecyclePipelineYaml = (): string => { @@ -890,18 +904,28 @@ export const generateGitIgnoreFile = ( const absTargetPath = path.resolve(targetDirectory); logger.info(`Generating starter .gitignore in ${absTargetPath}`); - const gitIgnoreFilePath = path.join(absTargetPath, ".gitignore"); + try { + const gitIgnoreFilePath = path.join(absTargetPath, ".gitignore"); - if (fs.existsSync(gitIgnoreFilePath)) { - logger.warn( - `Existing .gitignore found at ${gitIgnoreFilePath}, skipping generation.` - ); + if (fs.existsSync(gitIgnoreFilePath)) { + logger.warn( + `Existing .gitignore found at ${gitIgnoreFilePath}, skipping generation.` + ); + return; + } - return; + logger.info(`Writing .gitignore file to ${gitIgnoreFilePath}`); + fs.writeFileSync(gitIgnoreFilePath, content, "utf8"); + } catch (err) { + throw buildError( + errorStatusCode.FILE_IO_ERR, + { + errorKey: "fileutils-generate-git-ignore-file", + values: [absTargetPath], + }, + err + ); } - - logger.info(`Writing .gitignore file to ${gitIgnoreFilePath}`); - fs.writeFileSync(gitIgnoreFilePath, content, "utf8"); }; /** diff --git a/src/lib/gitutils.ts b/src/lib/gitutils.ts index e1a84def8..98cb277cb 100644 --- a/src/lib/gitutils.ts +++ b/src/lib/gitutils.ts @@ -4,6 +4,8 @@ import path from "path"; import url from "url"; import { logger } from "../logger"; import { exec } from "./shell"; +import { build as buildError } from "./errorBuilder"; +import { errorStatusCode } from "./errorStatusCode"; /** * For git urls that you may want to log only! @@ -329,8 +331,11 @@ export const checkoutCommitPushCreatePRLink = async ( ); }); } catch (err) { - logger.error(err); - throw err; + throw buildError( + errorStatusCode.GIT_OPS_ERR, + "git-checkout-commit-push-create-PR-link", + err + ); } }; diff --git a/src/lib/i18n.json b/src/lib/i18n.json index 71bfc0ad7..d5b68632b 100644 --- a/src/lib/i18n.json +++ b/src/lib/i18n.json @@ -16,6 +16,9 @@ "storageKeVaultName": "Enter key vault name (have the value as empty and hit enter key to skip)" }, "errors": { + "hld-init-cmd-failed": "Hld init command was not successfully executed.", + "hld-init-cmd-project-path-missing": "Value for project path was not provided. Provide it.", + "infra-scaffold-cmd-failed": "Infra scaffold Command was not successfully executed.", "infra-scaffold-cmd-src-missing": "Value for source is required because it cannot be constructed with properties in spk-config.yaml. Provide value for source.", "infra-scaffold-cmd-values-missing": "Values for name, version and/or 'template were missing. Provide value for values for them.", @@ -37,6 +40,11 @@ "hld-append-var-group-cmd-failed": "HLD Append Variable Group Command was not successfully executed.", "hld-append-var-group-name-missing": "Variable group name was not provided. Provide variable group.", - "fileutils-append-variable-group-to-pipeline-yaml": "Could not append variable group name to manifest-generation.yaml file in HLD repo. Check this is file exist and if it is YAML format." + "fileutils-append-variable-group-to-pipeline-yaml": "Could not append variable group name to manifest-generation.yaml file in HLD repo. Check this is file exist and if it is YAML format.", + "fileutils-generate-hld-pipeline-yaml": "Could not generate HLD Azure pipeline YAML.", + "fileutils-generate-default-hld-component-yaml": "Could not generate default HLD component YAML.", + "fileutils-generate-git-ignore-file": "Could not generate .gitignore file in {0}.", + + "git-checkout-commit-push-create-PR-link": "Could not checkout, commit, push or create pull request" } } From eb428013af802409e2aa3f0aca1552cf6872b238 Mon Sep 17 00:00:00 2001 From: Dennis Seah Date: Tue, 31 Mar 2020 14:17:33 -0700 Subject: [PATCH 2/2] Update i18n.json --- src/lib/i18n.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/i18n.json b/src/lib/i18n.json index 89e243c1a..9f5104be4 100644 --- a/src/lib/i18n.json +++ b/src/lib/i18n.json @@ -45,7 +45,7 @@ "fileutils-generate-default-hld-component-yaml": "Could not generate default HLD component YAML.", "fileutils-generate-git-ignore-file": "Could not generate .gitignore file in {0}.", - "git-checkout-commit-push-create-PR-link": "Could not checkout, commit, push or create pull request" + "git-checkout-commit-push-create-PR-link": "Could not checkout, commit, push or create pull request", "introspect-create-cmd-failed": "Deployment create command was not successfully executed.", "introspect-create-cmd-no-ops": "No action could be performed for specified arguments.",