From 9117380ce98ff475d6a59064690564ab7632fde9 Mon Sep 17 00:00:00 2001 From: Marcus Eide Date: Fri, 6 Mar 2020 11:14:11 +0100 Subject: [PATCH] Fix paths and add spinners --- packages/cli/package.json | 2 + .../cli/src/commands/createPlugin.test.ts | 8 +- packages/cli/src/commands/createPlugin.ts | 75 +++++++++++++------ yarn.lock | 46 +++++++++++- 4 files changed, 101 insertions(+), 30 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index 49b50e2664..524a81420d 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -18,6 +18,7 @@ "@types/html-webpack-plugin": "^3.2.2", "@types/inquirer": "^6.5.0", "@types/node": "^13.7.2", + "@types/ora": "^3.2.0", "@types/react-dev-utils": "^9.0.4", "@types/recursive-readdir": "^2.2.0", "@types/webpack": "^4.41.7", @@ -38,6 +39,7 @@ "handlebars": "^4.7.3", "html-webpack-plugin": "^3.2.0", "inquirer": "^7.0.4", + "ora": "^4.0.3", "react-dev-utils": "^10.2.0", "recursive-readdir": "^2.2.2", "replace-in-file": "^5.0.2", diff --git a/packages/cli/src/commands/createPlugin.test.ts b/packages/cli/src/commands/createPlugin.test.ts index 684331e276..bb823218fe 100644 --- a/packages/cli/src/commands/createPlugin.test.ts +++ b/packages/cli/src/commands/createPlugin.test.ts @@ -92,12 +92,12 @@ describe('createPlugin', () => { const id = 'testPlugin'; const tempDir = path.join(os.tmpdir(), id); const rootDir = fs.mkdtempSync(path.join(os.tmpdir(), 'test-')); - const pluginFolder = path.join(rootDir, 'packages', 'plugins', id); + const pluginDir = path.join(rootDir, 'packages', 'plugins', id); try { createTemporaryPluginFolder(tempDir); - movePlugin(tempDir, rootDir, id); - expect(fs.existsSync(pluginFolder)).toBe(true); - expect(pluginFolder).toMatch(`/packages\/plugins\/${id}`); + movePlugin(tempDir, pluginDir, id); + expect(fs.existsSync(pluginDir)).toBe(true); + expect(pluginDir).toMatch(`/packages\/plugins\/${id}`); } finally { del.sync(tempDir, { force: true }); del.sync(rootDir, { force: true }); diff --git a/packages/cli/src/commands/createPlugin.ts b/packages/cli/src/commands/createPlugin.ts index d7b7d9969e..52c0e5debb 100644 --- a/packages/cli/src/commands/createPlugin.ts +++ b/packages/cli/src/commands/createPlugin.ts @@ -9,9 +9,10 @@ import { exec } from 'child_process'; import { resolve as resolvePath } from 'path'; import { realpathSync, existsSync } from 'fs'; import os from 'os'; +import ora from 'ora'; -const MARKER_SUCCESS = chalk.green(` ✓\n`); -const MARKER_FAILURE = chalk.red(` ✗\n`); +const MARKER_SUCCESS = chalk.green(` ✔︎\n`); +const MARKER_FAILURE = chalk.red(` ✘\n`); const checkExists = (rootDir: string, id: string) => { console.log(); @@ -20,14 +21,20 @@ const checkExists = (rootDir: string, id: string) => { const destination = path.join(rootDir, 'packages', 'plugins', id); if (fs.existsSync(destination)) { - console.log(chalk.red(` plugin ID\t${chalk.cyan(id)} already exists ✗`)); + console.log( + chalk.red( + ` plugin ID\t${chalk.cyan(id)} already exists${MARKER_FAILURE}`, + ), + ); throw new Error( `A plugin with the same name already exists: ${chalk.cyan( destination.replace(`${rootDir}/`, ''), )}\nPlease try again with a different plugin ID`, ); } - console.log(chalk.green(` plugin ID\t${chalk.cyan(id)} is available ✓`)); + console.log( + chalk.green(` plugin ID\t${chalk.cyan(id)} is available${MARKER_SUCCESS}`), + ); }; export const createTemporaryPluginFolder = (tempDir: string) => { @@ -186,10 +193,14 @@ export const createFromTemplateDir = async ( try { files = await recursive(templateFolder); console.log( - chalk.green(` reading\t${chalk.cyan(`${files.length} files`)} ✓`), + chalk.green( + ` reading\t${chalk.cyan(`${files.length} files`)}${MARKER_SUCCESS}`, + ), ); } catch (e) { - console.log(chalk.red(` reading\t${chalk.cyan('0')} files ✗`)); + console.log( + chalk.red(` reading\t${chalk.cyan('0')} files${MARKER_FAILURE}`), + ); throw new Error(`Failed to read files in template directory: ${e.message}`); } @@ -227,7 +238,7 @@ export const createFromTemplateDir = async ( }); }; -const cleanUp = (tempDir: string, id: string) => { +const cleanUp = async (tempDir: string, id: string) => { console.log( chalk.green( `It seems that something went wrong when creating the plugin 🤔 `, @@ -236,14 +247,16 @@ const cleanUp = (tempDir: string, id: string) => { console.log( chalk.green('We are going to clean up, and then you can try again.'), ); - process.stdout.write(chalk.green(` Cleaning up ${chalk.cyan(id)}`)); + const spinner = ora({ + prefixText: chalk.green(` Cleaning up\t${chalk.cyan(id)}`), + spinner: 'arc', + color: 'green', + }).start(); try { - fs.rmdirSync(tempDir, { recursive: true }); - process.stdout.write(MARKER_SUCCESS); - console.log(); + await fs.remove(tempDir); + spinner.succeed(); } catch (e) { - process.stdout.write(MARKER_FAILURE); - console.log(); + spinner.fail(); console.log(chalk.red(`Failed to cleanup: ${e.message}`)); } }; @@ -256,13 +269,17 @@ const buildPlugin = async (pluginFolder: string) => { const commands = ['yarn install', 'yarn build']; for (const command of commands) { - process.stdout.write(chalk.green(` executing\t${chalk.cyan(command)}`)); + const spinner = ora({ + prefixText: chalk.green(` executing\t${chalk.cyan(command)}`), + spinner: 'arc', + color: 'green', + }).start(); try { process.chdir(pluginFolder); await prom_exec(command, { timeout: 60000 }); - process.stdout.write(MARKER_SUCCESS); + spinner.succeed(); } catch (e) { - process.stdout.write(MARKER_FAILURE); + spinner.fail(); throw new Error( `Could not execute command ${chalk.cyan(command)}: ${e.message}`, ); @@ -270,11 +287,13 @@ const buildPlugin = async (pluginFolder: string) => { } }; -export const movePlugin = (tempDir: string, rootDir: string, id: string) => { +export const movePlugin = ( + tempDir: string, + destination: string, + id: string, +) => { console.log(); - console.log(chalk.green(` Finalizing the plugin:`)); - - const destination = path.join(rootDir, 'packages', 'plugins', id); + console.log(chalk.green(` Moving the plugin:`)); process.stdout.write( chalk.green(` moving\t${chalk.cyan(id)} to final location`), @@ -288,7 +307,7 @@ export const movePlugin = (tempDir: string, rootDir: string, id: string) => { } }; -const createPlugin = async (): Promise => { +const createPlugin = async () => { const questions: Question[] = [ { type: 'input', @@ -305,6 +324,14 @@ const createPlugin = async (): Promise => { const cliPackage = resolvePath(__dirname, '..', '..'); const templateFolder = resolvePath(cliPackage, 'templates', 'default-plugin'); const tempDir = path.join(os.tmpdir(), answers.id); + const pluginDir = path.join( + rootDir, + '..', + '..', + 'packages', + 'plugins', + answers.id, + ); console.log(); console.log(chalk.green('Creating the plugin...')); @@ -313,8 +340,8 @@ const createPlugin = async (): Promise => { checkExists(rootDir, answers.id); createTemporaryPluginFolder(tempDir); await createFromTemplateDir(templateFolder, tempDir, answers); - await buildPlugin(tempDir); - movePlugin(tempDir, rootDir, answers.id); + movePlugin(tempDir, pluginDir, answers.id); + await buildPlugin(pluginDir); if (existsSync(appPackage)) { addPluginDependencyToApp(rootDir, answers.id); @@ -334,7 +361,7 @@ const createPlugin = async (): Promise => { console.log(); console.log(`${chalk.red(e.message)}`); console.log(); - cleanUp(tempDir, answers.id); + await cleanUp(tempDir, answers.id); console.log(); console.log(`🔥 ${chalk.red('Failed to create plugin!')}`); console.log(); diff --git a/yarn.lock b/yarn.lock index f34beec44c..dbc8c8f9f3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2308,6 +2308,17 @@ dependencies: "@babel/runtime" "^7.4.4" +"@material-ui/lab@4.0.0-alpha.45": + version "4.0.0-alpha.45" + resolved "https://registry.npmjs.org/@material-ui/lab/-/lab-4.0.0-alpha.45.tgz#6e1abbdd6e44b9ef7b3eff8ef892a3da5dc52f10" + integrity sha512-zT6kUU87SHsPukiu3tlWg8V6o0tGS38c1b/xst/kPqX6eLbfqrROyxhHn1A8ZtHmqga1AKQdv/1llQoG80Afww== + dependencies: + "@babel/runtime" "^7.4.4" + "@material-ui/utils" "^4.7.1" + clsx "^1.0.4" + prop-types "^15.7.2" + react-is "^16.8.0" + "@material-ui/styles@^4.9.0": version "4.9.0" resolved "https://registry.npmjs.org/@material-ui/styles/-/styles-4.9.0.tgz#10c31859f6868cfa9d3adf6b6c3e32c9d676bc76" @@ -3176,6 +3187,13 @@ resolved "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== +"@types/ora@^3.2.0": + version "3.2.0" + resolved "https://registry.npmjs.org/@types/ora/-/ora-3.2.0.tgz#b2f65d1283a8f36d8b0f9ee767e0732a2f429362" + integrity sha512-jll99xUKpiFbIFZSQcxm4numfsLaOWBzWNaRk3PvTSE7BPqTzzOCFmS0mQ7m8qkTfmYhuYbehTGsxkvRLPC++w== + dependencies: + ora "*" + "@types/parse-json@^4.0.0": version "4.0.0" resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" @@ -4966,6 +4984,11 @@ cli-cursor@^3.1.0: dependencies: restore-cursor "^3.1.0" +cli-spinners@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.2.0.tgz#e8b988d9206c692302d8ee834e7a85c0144d8f77" + integrity sha512-tgU3fKwzYjiLEQgPMD9Jt+JjHVL9kW93FiIMX/l7rivvOD4/LL0Mf7gda3+4U2KJBloybwgj5KEoQgGRioMiKQ== + cli-table3@^0.5.0, cli-table3@^0.5.1: version "0.5.1" resolved "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" @@ -5057,7 +5080,7 @@ clone@^1.0.2: resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= -clsx@^1.0.2: +clsx@^1.0.2, clsx@^1.0.4: version "1.1.0" resolved "https://registry.npmjs.org/clsx/-/clsx-1.1.0.tgz#62937c6adfea771247c34b54d320fb99624f5702" integrity sha512-3avwM37fSK5oP6M5rQ9CNe99lwxhXDOeSWVPAOYF6OazUTgZCMb0yWlJpmdD74REy1gkEaFiub2ULv4fq9GUhA== @@ -8979,6 +9002,11 @@ is-installed-globally@^0.1.0: global-dirs "^0.1.0" is-path-inside "^1.0.0" +is-interactive@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" + integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== + is-npm@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" @@ -12299,6 +12327,20 @@ optionator@^0.8.1, optionator@^0.8.3: type-check "~0.3.2" word-wrap "~1.2.3" +ora@*, ora@^4.0.3: + version "4.0.3" + resolved "https://registry.npmjs.org/ora/-/ora-4.0.3.tgz#752a1b7b4be4825546a7a3d59256fa523b6b6d05" + integrity sha512-fnDebVFyz309A73cqCipVL1fBZewq4vwgSHfxh43vVy31mbyoQ8sCH3Oeaog/owYOs/lLlGVPCISQonTneg6Pg== + dependencies: + chalk "^3.0.0" + cli-cursor "^3.1.0" + cli-spinners "^2.2.0" + is-interactive "^1.0.0" + log-symbols "^3.0.0" + mute-stream "0.0.8" + strip-ansi "^6.0.0" + wcwidth "^1.0.1" + original@^1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" @@ -16748,7 +16790,7 @@ wbuf@^1.1.0, wbuf@^1.7.3: dependencies: minimalistic-assert "^1.0.0" -wcwidth@^1.0.0: +wcwidth@^1.0.0, wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=