From 26796afecfe3283dbf45f98ff1caf1c32460fa2d Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Fri, 17 Aug 2018 10:44:28 +0200 Subject: [PATCH] fix(aws-cdk): report and continue on git errors (#587) Don't stop the 'cdk init' process if there's a problem with 'git init/add/commit'. Instead, report an error and continue. This makes sure 'cdk init' doesn't break for people with custom git setups. Fixes #530. --- packages/aws-cdk/lib/init.ts | 46 +++++++++++++++++---------- packages/aws-cdk/test/test.init.ts | 50 ++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 17 deletions(-) create mode 100644 packages/aws-cdk/test/test.init.ts diff --git a/packages/aws-cdk/lib/init.ts b/packages/aws-cdk/lib/init.ts index c736a1db62bb5..9f0372817ab85 100644 --- a/packages/aws-cdk/lib/init.ts +++ b/packages/aws-cdk/lib/init.ts @@ -16,7 +16,7 @@ const CDK_HOME = process.env.CDK_HOME ? path.resolve(process.env.CDK_HOME) : pat /** * Initialize a CDK package in the current directory */ -export async function cliInit(type: string, language: string | undefined) { +export async function cliInit(type: string, language: string | undefined, canUseNetwork?: boolean) { const template = (await availableInitTemplates).find(t => t.hasName(type)); if (!template) { await printAvailableTemplates(language); @@ -30,7 +30,7 @@ export async function cliInit(type: string, language: string | undefined) { print(`Available languages for ${colors.green(type)}: ${template.languages.map(l => colors.blue(l)).join(', ')}`); throw new Error('No language was selected'); } - await initializeProject(template, language); + await initializeProject(template, language, canUseNetwork !== undefined ? canUseNetwork : true); } const INFO_DOT_JSON = 'info.json'; @@ -160,16 +160,12 @@ export async function printAvailableTemplates(language?: string) { } } -async function initializeProject(template: InitTemplate, language: string) { +async function initializeProject(template: InitTemplate, language: string, canUseNetwork: boolean) { await assertIsEmptyDirectory(); - const useGit = await initializeGitRepository(); print(`Applying project template ${colors.green(template.name)} for ${colors.blue(language)}`); await template.install(language, process.cwd()); - await postInstall(language); - if (useGit) { - await execute('git', 'add', '.'); - await execute('git', 'commit', '--message="Initial commit"', '--no-gpg-sign'); - } + await initializeGitRepository(); + await postInstall(language, canUseNetwork); if (await fs.pathExists('README.md')) { print(colors.green(await fs.readFile('README.md', { encoding: 'utf-8' }))); } else { @@ -185,23 +181,34 @@ async function assertIsEmptyDirectory() { } async function initializeGitRepository() { - if (await isInGitRepository(process.cwd())) { return false; } + if (await isInGitRepository(process.cwd())) { return; } print('Initializing a new git repository...'); - await execute('git', 'init'); - return true; + try { + await execute('git', 'init'); + await execute('git', 'add', '.'); + await execute('git', 'commit', '--message="Initial commit"', '--no-gpg-sign'); + } catch (e) { + warning('Unable to initialize git repository for your project.'); + } } -async function postInstall(language: string) { +async function postInstall(language: string, canUseNetwork: boolean) { switch (language) { case 'typescript': - return await postInstallTypescript(); + return await postInstallTypescript(canUseNetwork); case 'java': - return await postInstallJava(); + return await postInstallJava(canUseNetwork); } } -async function postInstallTypescript() { +async function postInstallTypescript(canUseNetwork: boolean) { const command = 'npm'; + + if (!canUseNetwork) { + print(`Please run ${colors.green(`${command} install`)}!`); + return; + } + print(`Executing ${colors.green(`${command} install`)}...`); try { await execute(command, 'install'); @@ -210,7 +217,12 @@ async function postInstallTypescript() { } } -async function postInstallJava() { +async function postInstallJava(canUseNetwork: boolean) { + if (!canUseNetwork) { + print(`Please run ${colors.green(`mvn package`)}!`); + return; + } + print(`Executing ${colors.green('mvn package')}...`); await execute('mvn', 'package'); } diff --git a/packages/aws-cdk/test/test.init.ts b/packages/aws-cdk/test/test.init.ts new file mode 100644 index 0000000000000..b51cfb17468e6 --- /dev/null +++ b/packages/aws-cdk/test/test.init.ts @@ -0,0 +1,50 @@ +import fs = require('fs-extra'); +import { Test } from 'nodeunit'; +import os = require('os'); +import path = require('path'); +import { cliInit } from '../lib/init'; + +const state: { + previousWorkingDir?: string; + tempDir?: string; +} = {}; + +export = { + async "setUp"(callback: () => void) { + state.previousWorkingDir = process.cwd(); + state.tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'aws-cdk-test')); + // tslint:disable-next-line:no-console + console.log('Temporary working directory:', state.tempDir); + process.chdir(state.tempDir); + callback(); + }, + + async "tearDown"(callback: () => void) { + // tslint:disable-next-line:no-console + console.log('Switching back to', state.previousWorkingDir, 'cleaning up', state.tempDir); + process.chdir(state.previousWorkingDir!); + await fs.remove(state.tempDir!); + + callback(); + }, + + async 'create a TypeScript library project'(test: Test) { + await cliInit('lib', 'typescript', false); + + // Check that package.json and lib/ got created in the current directory + test.equal(true, await fs.pathExists('package.json')); + test.equal(true, await fs.pathExists('lib')); + + test.done(); + }, + + async 'create a TypeScript app project'(test: Test) { + await cliInit('app', 'typescript', false); + + // Check that package.json and bin/ got created in the current directory + test.equal(true, await fs.pathExists('package.json')); + test.equal(true, await fs.pathExists('bin')); + + test.done(); + } +}; \ No newline at end of file