From f9ce1184fb4121dbe7b6c1642031aa4d1821182d Mon Sep 17 00:00:00 2001 From: Anton Moiseev Date: Thu, 30 Apr 2020 09:47:13 +0400 Subject: [PATCH 01/24] WIP: add destroy for components (#80) --- packages/cli/src/commands/destroy.js | 6 ++++ .../cli/src/commands/destroy/component.js | 13 +++++++ packages/cli/src/commands/generate/helpers.js | 34 ++++++++++++++++++- packages/cli/src/lib/index.js | 20 +++++++++++ 4 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 packages/cli/src/commands/destroy.js create mode 100644 packages/cli/src/commands/destroy/component.js diff --git a/packages/cli/src/commands/destroy.js b/packages/cli/src/commands/destroy.js new file mode 100644 index 000000000000..f6d17115b1b9 --- /dev/null +++ b/packages/cli/src/commands/destroy.js @@ -0,0 +1,6 @@ +export const command = 'destroy ' +export const aliases = ['d'] +export const desc = 'Rollback changes made by generate command.' + +export const builder = (yargs) => + yargs.commandDir('./destroy', { recurse: true }).demandCommand().argv diff --git a/packages/cli/src/commands/destroy/component.js b/packages/cli/src/commands/destroy/component.js new file mode 100644 index 000000000000..9b4e8531f54f --- /dev/null +++ b/packages/cli/src/commands/destroy/component.js @@ -0,0 +1,13 @@ +import { createYargsForComponentDestroy } from 'src/lib' + +import { files as componentFiles } from '../generate/component/component' + +export const { + command, + desc, + builder, + handler, +} = createYargsForComponentDestroy({ + componentName: 'component', + filesFn: componentFiles, +}) diff --git a/packages/cli/src/commands/generate/helpers.js b/packages/cli/src/commands/generate/helpers.js index 7ac71a1a0daf..4d4138d3204a 100644 --- a/packages/cli/src/commands/generate/helpers.js +++ b/packages/cli/src/commands/generate/helpers.js @@ -6,7 +6,12 @@ import Listr from 'listr' import pascalcase from 'pascalcase' import { paramCase } from 'param-case' -import { generateTemplate, getPaths, writeFilesTask } from 'src/lib' +import { + deleteFilesTask, + generateTemplate, + getPaths, + writeFilesTask, +} from 'src/lib' import c from 'src/lib/colors' /** @@ -90,6 +95,33 @@ export const createYargsForComponentGeneration = ({ } } +export const createYargsForComponentDestroy = ({ componentName, filesFn }) => { + return { + command: `${componentName} `, + desc: `Destroy a ${componentName} component.`, + handler: async (names) => { + const tasks = new Listr( + [ + { + title: `Destroying ${componentName} files...`, + task: async () => { + const f = await filesFn(names) + return deleteFilesTask(f) + }, + }, + ], + { collapse: false, exitOnError: true } + ) + + try { + await tasks.run() + } catch (e) { + console.log(c.error(e.message)) + } + }, + } +} + // Returns all relations to other models export const relationsForModel = (model) => { return model.fields diff --git a/packages/cli/src/lib/index.js b/packages/cli/src/lib/index.js index 474403584add..034ac201ba9f 100644 --- a/packages/cli/src/lib/index.js +++ b/packages/cli/src/lib/index.js @@ -147,6 +147,8 @@ export const generateTemplate = (templateFilename, { name, root, ...rest }) => { export const readFile = (target) => fs.readFileSync(target) +export const deleteFile = (target) => fs.unlinkSync(target) + export const writeFile = async ( target, contents, @@ -206,6 +208,24 @@ export const writeFilesTask = (files, options) => { ) } +/** + * Creates a list of tasks that delete files from the disk. + * + * @param files - {[filepath]: contents} + */ +export const deleteFilesTask = (files) => { + const { base } = getPaths() + return new Listr( + Object.keys(files).map((file) => { + return { + title: `Destroying \`./${path.relative(base, file)}\`...`, + skip: () => !fs.existsSync(file), + task: () => deleteFile(file), + } + }) + ) +} + /** * Update the project's routes file. */ From f25c9a2757ce58faa3509eae0846dd60373f1136 Mon Sep 17 00:00:00 2001 From: Anton Moiseev Date: Thu, 30 Apr 2020 11:18:35 +0400 Subject: [PATCH 02/24] WIP: fix import path --- packages/cli/src/commands/destroy/component.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/cli/src/commands/destroy/component.js b/packages/cli/src/commands/destroy/component.js index 9b4e8531f54f..cc0f6205beb9 100644 --- a/packages/cli/src/commands/destroy/component.js +++ b/packages/cli/src/commands/destroy/component.js @@ -1,5 +1,4 @@ -import { createYargsForComponentDestroy } from 'src/lib' - +import { createYargsForComponentDestroy } from '../generate/helpers' import { files as componentFiles } from '../generate/component/component' export const { From 43d66ccbd4aa8f0756d6911adc72520e1caf4284 Mon Sep 17 00:00:00 2001 From: Anton Moiseev Date: Thu, 30 Apr 2020 13:07:01 +0400 Subject: [PATCH 03/24] WIP: move destroy component command's file into subfolder. --- packages/cli/src/commands/destroy/component.js | 12 ------------ .../cli/src/commands/destroy/component/component.js | 12 ++++++++++++ 2 files changed, 12 insertions(+), 12 deletions(-) delete mode 100644 packages/cli/src/commands/destroy/component.js create mode 100644 packages/cli/src/commands/destroy/component/component.js diff --git a/packages/cli/src/commands/destroy/component.js b/packages/cli/src/commands/destroy/component.js deleted file mode 100644 index cc0f6205beb9..000000000000 --- a/packages/cli/src/commands/destroy/component.js +++ /dev/null @@ -1,12 +0,0 @@ -import { createYargsForComponentDestroy } from '../generate/helpers' -import { files as componentFiles } from '../generate/component/component' - -export const { - command, - desc, - builder, - handler, -} = createYargsForComponentDestroy({ - componentName: 'component', - filesFn: componentFiles, -}) diff --git a/packages/cli/src/commands/destroy/component/component.js b/packages/cli/src/commands/destroy/component/component.js new file mode 100644 index 000000000000..b594663bc9bc --- /dev/null +++ b/packages/cli/src/commands/destroy/component/component.js @@ -0,0 +1,12 @@ +import { createYargsForComponentDestroy } from '../../generate/helpers' +import { files } from '../../generate/component/component' + +export const { + command, + desc, + builder, + handler, +} = createYargsForComponentDestroy({ + componentName: 'component', + filesFn: files, +}) From 79a93b5811249f0925718af7f9c4e9d07af5f82e Mon Sep 17 00:00:00 2001 From: Anton Moiseev Date: Thu, 30 Apr 2020 13:11:28 +0400 Subject: [PATCH 04/24] WIP: add `destroy service` command --- .../src/commands/destroy/service/service.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 packages/cli/src/commands/destroy/service/service.js diff --git a/packages/cli/src/commands/destroy/service/service.js b/packages/cli/src/commands/destroy/service/service.js new file mode 100644 index 000000000000..dfad16e07a7a --- /dev/null +++ b/packages/cli/src/commands/destroy/service/service.js @@ -0,0 +1,19 @@ +import { createYargsForComponentDestroy } from '../../generate/helpers' +import { files } from '../../generate/service/service' + +// This function wraps files(), so we can pass templateVars. templateVars +// referenced in a file template must be defined, otherwise template rendering +// fails. This way we can pass stub values for templateVars and do not define +// fake builder flags for destroy command just to make templates work. +// +// Better solution would be to split file paths resolving and template +// rendering into separate functions. See more in this PR discussion: +// https://github.com/redwoodjs/redwood/pull/487#issue-411204396 +export const filesWithTemplateVars = (templateVars) => { + return (args) => files({ ...args, ...templateVars }) +} + +export const { command, desc, handler } = createYargsForComponentDestroy({ + componentName: 'service', + filesFn: filesWithTemplateVars({ crud: false }), +}) From 385ffe31eb728ee705f69439338b68410f963c71 Mon Sep 17 00:00:00 2001 From: Anton Moiseev Date: Fri, 1 May 2020 07:35:49 +0400 Subject: [PATCH 05/24] WIP: add destroy for cell and layout components --- packages/cli/src/commands/destroy/cell/cell.js | 12 ++++++++++++ .../cli/src/commands/destroy/component/component.js | 9 +++------ packages/cli/src/commands/destroy/layout/layout.js | 12 ++++++++++++ 3 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 packages/cli/src/commands/destroy/cell/cell.js create mode 100644 packages/cli/src/commands/destroy/layout/layout.js diff --git a/packages/cli/src/commands/destroy/cell/cell.js b/packages/cli/src/commands/destroy/cell/cell.js new file mode 100644 index 000000000000..dc286cdb0d12 --- /dev/null +++ b/packages/cli/src/commands/destroy/cell/cell.js @@ -0,0 +1,12 @@ +import { createYargsForComponentDestroy } from '../../generate/helpers' +import { files } from '../../generate/cell/cell' + +export const { + command, + desc, + builder, + handler, +} = createYargsForComponentDestroy({ + componentName: 'cell', + filesFn: files, +}) diff --git a/packages/cli/src/commands/destroy/component/component.js b/packages/cli/src/commands/destroy/component/component.js index b594663bc9bc..f49d9b152b19 100644 --- a/packages/cli/src/commands/destroy/component/component.js +++ b/packages/cli/src/commands/destroy/component/component.js @@ -1,12 +1,9 @@ import { createYargsForComponentDestroy } from '../../generate/helpers' import { files } from '../../generate/component/component' -export const { - command, - desc, - builder, - handler, -} = createYargsForComponentDestroy({ +export const desc = 'Destroy a component.' + +export const { command, builder, handler } = createYargsForComponentDestroy({ componentName: 'component', filesFn: files, }) diff --git a/packages/cli/src/commands/destroy/layout/layout.js b/packages/cli/src/commands/destroy/layout/layout.js new file mode 100644 index 000000000000..3ddec9419903 --- /dev/null +++ b/packages/cli/src/commands/destroy/layout/layout.js @@ -0,0 +1,12 @@ +import { createYargsForComponentDestroy } from '../../generate/helpers' +import { files } from '../../generate/layout/layout' + +export const { + command, + desc, + builder, + handler, +} = createYargsForComponentDestroy({ + componentName: 'layout', + filesFn: files, +}) From b1956c2619100b1217605916f81434ddf9bdab4a Mon Sep 17 00:00:00 2001 From: Anton Moiseev Date: Fri, 1 May 2020 07:58:14 +0400 Subject: [PATCH 06/24] WIP: improve desc for generate and destroy tasks --- .../cli/src/commands/generate/component/component.js | 9 +++------ packages/cli/src/commands/generate/page/page.js | 2 +- packages/cli/src/lib/index.js | 2 +- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/cli/src/commands/generate/component/component.js b/packages/cli/src/commands/generate/component/component.js index 19edeaa80c8e..070438b540d0 100644 --- a/packages/cli/src/commands/generate/component/component.js +++ b/packages/cli/src/commands/generate/component/component.js @@ -33,12 +33,9 @@ export const files = ({ name }) => { }, {}) } -export const { - command, - desc, - builder, - handler, -} = createYargsForComponentGeneration({ +export const desc = 'Generate a component.' + +export const { command, builder, handler } = createYargsForComponentGeneration({ componentName: 'component', filesFn: files, }) diff --git a/packages/cli/src/commands/generate/page/page.js b/packages/cli/src/commands/generate/page/page.js index 17332ee15ac2..7aab4e628a34 100644 --- a/packages/cli/src/commands/generate/page/page.js +++ b/packages/cli/src/commands/generate/page/page.js @@ -51,7 +51,7 @@ export const routes = ({ name, path }) => { } export const command = 'page [path]' -export const desc = 'Generates a page component.' +export const desc = 'Generate a page component.' export const builder = { force: { type: 'boolean', default: false } } export const handler = async ({ name, path, force }) => { diff --git a/packages/cli/src/lib/index.js b/packages/cli/src/lib/index.js index 034ac201ba9f..cd8ee6dc19d6 100644 --- a/packages/cli/src/lib/index.js +++ b/packages/cli/src/lib/index.js @@ -219,7 +219,7 @@ export const deleteFilesTask = (files) => { Object.keys(files).map((file) => { return { title: `Destroying \`./${path.relative(base, file)}\`...`, - skip: () => !fs.existsSync(file), + skip: () => !fs.existsSync(file) && `File doesn't exist`, task: () => deleteFile(file), } }) From b0a2f7b44172ad9187cd46692265a625e507099a Mon Sep 17 00:00:00 2001 From: Anton Moiseev Date: Fri, 1 May 2020 12:00:28 +0400 Subject: [PATCH 07/24] WIP: add destroy for page components --- .../cli/src/commands/destroy/page/page.js | 36 +++++++++++++++++++ packages/cli/src/lib/index.js | 20 ++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 packages/cli/src/commands/destroy/page/page.js diff --git a/packages/cli/src/commands/destroy/page/page.js b/packages/cli/src/commands/destroy/page/page.js new file mode 100644 index 000000000000..59a088788c51 --- /dev/null +++ b/packages/cli/src/commands/destroy/page/page.js @@ -0,0 +1,36 @@ +import camelcase from 'camelcase' +import Listr from 'listr' + +import { deleteFilesTask, removeRoutesFromRouterTask } from 'src/lib' +import c from 'src/lib/colors' + +import { pathName } from '../../generate/helpers' +import { files } from '../../generate/page/page' + +export const command = 'page [path]' +export const desc = 'Destroy a page component.' + +export const handler = async ({ name, path }) => { + const tasks = new Listr( + [ + { + title: 'Destroying page files...', + task: async () => { + const f = files({ name, path: pathName(path, name) }) + return deleteFilesTask(f) + }, + }, + { + title: 'Cleaning up routes file...', + task: async () => removeRoutesFromRouterTask([camelcase(name)]), + }, + ], + { collapse: false } + ) + + try { + await tasks.run() + } catch (e) { + console.log(c.error(e.message)) + } +} diff --git a/packages/cli/src/lib/index.js b/packages/cli/src/lib/index.js index cd8ee6dc19d6..e0e83cf0fa08 100644 --- a/packages/cli/src/lib/index.js +++ b/packages/cli/src/lib/index.js @@ -149,7 +149,7 @@ export const readFile = (target) => fs.readFileSync(target) export const deleteFile = (target) => fs.unlinkSync(target) -export const writeFile = async ( +export const writeFile = ( target, contents, { overwriteExisting = false } = {} @@ -243,6 +243,24 @@ export const addRoutesToRouterTask = (routes) => { }) } +/** + * Remove named routes from the project's routes file. + * + * @param {string[]} routes - Route names + */ +export const removeRoutesFromRouterTask = (routes) => { + const redwoodPaths = getPaths() + const routesContent = readFile(redwoodPaths.web.routes).toString() + const newRoutesContent = routes.reduce((content, route) => { + const matchRouteByName = new RegExp(`\\s*]*name="${route}"[^>]*/>`) + return content.replace(matchRouteByName, '') + }, routesContent) + + writeFile(redwoodPaths.web.routes, newRoutesContent, { + overwriteExisting: true, + }) +} + export const runCommandTask = async (commands, { verbose }) => { const tasks = new Listr( commands.map(({ title, cmd, args, opts = {} }) => ({ From f5a13161134b35219bfea4b2963dc137afc159e9 Mon Sep 17 00:00:00 2001 From: Anton Moiseev Date: Fri, 1 May 2020 14:37:22 +0400 Subject: [PATCH 08/24] WIP: add destroy for sdl components --- .../cli/src/commands/destroy/page/page.js | 2 +- packages/cli/src/commands/destroy/sdl/sdl.js | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 packages/cli/src/commands/destroy/sdl/sdl.js diff --git a/packages/cli/src/commands/destroy/page/page.js b/packages/cli/src/commands/destroy/page/page.js index 59a088788c51..71b4e6a5bce1 100644 --- a/packages/cli/src/commands/destroy/page/page.js +++ b/packages/cli/src/commands/destroy/page/page.js @@ -25,7 +25,7 @@ export const handler = async ({ name, path }) => { task: async () => removeRoutesFromRouterTask([camelcase(name)]), }, ], - { collapse: false } + { collapse: false, exitOnError: true } ) try { diff --git a/packages/cli/src/commands/destroy/sdl/sdl.js b/packages/cli/src/commands/destroy/sdl/sdl.js new file mode 100644 index 000000000000..3f0ed30b65c8 --- /dev/null +++ b/packages/cli/src/commands/destroy/sdl/sdl.js @@ -0,0 +1,30 @@ +import Listr from 'listr' + +import { deleteFilesTask } from 'src/lib' +import c from 'src/lib/colors' + +import { files } from '../../generate/sdl/sdl' + +export const command = 'sdl ' +export const desc = 'Destroy a GraphQL schema and service object.' + +export const handler = async ({ model }) => { + const tasks = new Listr( + [ + { + title: 'Destroying GraphQL schema and service object files...', + task: async () => { + const f = await files({ name: model, crud: false }) + return deleteFilesTask(f) + }, + }, + ], + { collapse: false, exitOnError: true } + ) + + try { + await tasks.run() + } catch (e) { + console.log(c.error(e.message)) + } +} From e8a426e0d320add10b968dd37e0248c35892ba55 Mon Sep 17 00:00:00 2001 From: Anton Moiseev Date: Sat, 2 May 2020 08:52:57 +0400 Subject: [PATCH 09/24] WIP: add destroy for scaffold components --- .../src/commands/destroy/scaffold/scaffold.js | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 packages/cli/src/commands/destroy/scaffold/scaffold.js diff --git a/packages/cli/src/commands/destroy/scaffold/scaffold.js b/packages/cli/src/commands/destroy/scaffold/scaffold.js new file mode 100644 index 000000000000..f88122d51eb8 --- /dev/null +++ b/packages/cli/src/commands/destroy/scaffold/scaffold.js @@ -0,0 +1,42 @@ +import Listr from 'listr' + +import { deleteFilesTask, removeRoutesFromRouterTask } from 'src/lib' +import c from 'src/lib/colors' + +import { files, routes as routesFn } from '../../generate/scaffold/scaffold' + +export const command = 'scaffold ' +export const desc = 'Destroy pages, SDL, and a services object.' + +export const handler = async ({ model }) => { + const tasks = new Listr( + [ + { + title: 'Destroying scaffold files...', + task: async () => { + const f = await files({ model }) + return deleteFilesTask(f) + }, + }, + { + title: 'Cleaning up scaffold routes...', + task: async () => { + const routes = await routesFn({ model }) + const routeNames = routes.map(extractRouteName) + return removeRoutesFromRouterTask(routeNames) + }, + }, + ], + { collapse: false, exitOnError: true } + ) + try { + await tasks.run() + } catch (e) { + console.log(c.error(e.message)) + } +} + +const extractRouteName = (route) => { + const { groups } = route.match(/.*name="?(?\w+)"?/) + return groups.routeName +} From bd9b5b6faa1a660bf01878e8b8c5a6b4343ff480 Mon Sep 17 00:00:00 2001 From: Anton Moiseev Date: Sat, 2 May 2020 11:48:59 +0400 Subject: [PATCH 10/24] WIP: clean up empty dirs after destroy --- packages/cli/src/lib/index.js | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/lib/index.js b/packages/cli/src/lib/index.js index e0e83cf0fa08..b78a0490c3b1 100644 --- a/packages/cli/src/lib/index.js +++ b/packages/cli/src/lib/index.js @@ -215,13 +215,43 @@ export const writeFilesTask = (files, options) => { */ export const deleteFilesTask = (files) => { const { base } = getPaths() - return new Listr( - Object.keys(files).map((file) => { + return new Listr([ + ...Object.keys(files).map((file) => { return { title: `Destroying \`./${path.relative(base, file)}\`...`, skip: () => !fs.existsSync(file) && `File doesn't exist`, task: () => deleteFile(file), } + }), + { + title: 'Cleaning up empty directories...', + task: () => cleanupEmptyDirsTask(files), + }, + ]) +} + +/** + * @param files - {[filepath]: contents} + */ +export const cleanupEmptyDirsTask = (files) => { + const { base } = getPaths() + const allDirs = Object.keys(files).map((file) => path.dirname(file)) + const uniqueDirs = [...new Set(allDirs)] + return new Listr( + uniqueDirs.map((dir) => { + return { + title: `Removing \`./${path.relative(base, dir)}\`...`, + task: () => fs.rmdirSync(dir), + skip: () => { + if (!fs.existsSync(dir)) { + return `Doesn't exist` + } + if (fs.readdirSync(dir).length > 0) { + return 'Not empty' + } + return false + }, + } }) ) } From ffe5fc21735cb415a870b8c7fef9c16a787235eb Mon Sep 17 00:00:00 2001 From: Anton Moiseev Date: Sun, 3 May 2020 10:30:09 +0400 Subject: [PATCH 11/24] Minor cleanup, renaming --- .../cli/src/commands/destroy/cell/cell.js | 6 ++-- .../commands/destroy/component/component.js | 6 ++-- packages/cli/src/commands/destroy/helpers.js | 31 +++++++++++++++++ .../cli/src/commands/destroy/layout/layout.js | 6 ++-- .../cli/src/commands/destroy/page/page.js | 4 +-- .../src/commands/destroy/scaffold/scaffold.js | 7 ++-- .../src/commands/destroy/service/service.js | 2 +- packages/cli/src/commands/generate/helpers.js | 34 +------------------ packages/cli/src/lib/index.js | 4 +-- 9 files changed, 51 insertions(+), 49 deletions(-) create mode 100644 packages/cli/src/commands/destroy/helpers.js diff --git a/packages/cli/src/commands/destroy/cell/cell.js b/packages/cli/src/commands/destroy/cell/cell.js index dc286cdb0d12..7657043d903d 100644 --- a/packages/cli/src/commands/destroy/cell/cell.js +++ b/packages/cli/src/commands/destroy/cell/cell.js @@ -1,5 +1,5 @@ -import { createYargsForComponentDestroy } from '../../generate/helpers' -import { files } from '../../generate/cell/cell' +import { files as cellFiles } from '../../generate/cell/cell' +import { createYargsForComponentDestroy } from '../helpers' export const { command, @@ -8,5 +8,5 @@ export const { handler, } = createYargsForComponentDestroy({ componentName: 'cell', - filesFn: files, + filesFn: cellFiles, }) diff --git a/packages/cli/src/commands/destroy/component/component.js b/packages/cli/src/commands/destroy/component/component.js index f49d9b152b19..26f86a8a6bbb 100644 --- a/packages/cli/src/commands/destroy/component/component.js +++ b/packages/cli/src/commands/destroy/component/component.js @@ -1,9 +1,9 @@ -import { createYargsForComponentDestroy } from '../../generate/helpers' -import { files } from '../../generate/component/component' +import { files as componentFiles } from '../../generate/component/component' +import { createYargsForComponentDestroy } from '../helpers' export const desc = 'Destroy a component.' export const { command, builder, handler } = createYargsForComponentDestroy({ componentName: 'component', - filesFn: files, + filesFn: componentFiles, }) diff --git a/packages/cli/src/commands/destroy/helpers.js b/packages/cli/src/commands/destroy/helpers.js new file mode 100644 index 000000000000..73ecdd43cc63 --- /dev/null +++ b/packages/cli/src/commands/destroy/helpers.js @@ -0,0 +1,31 @@ +import Listr from 'listr' + +import { deleteFilesTask } from 'src/lib' +import c from 'src/lib/colors' + +export const createYargsForComponentDestroy = ({ componentName, filesFn }) => { + return { + command: `${componentName} `, + desc: `Destroy a ${componentName} component.`, + handler: async (names) => { + const tasks = new Listr( + [ + { + title: `Destroying ${componentName} files...`, + task: async () => { + const f = await filesFn(names) + return deleteFilesTask(f) + }, + }, + ], + { collapse: false, exitOnError: true } + ) + + try { + await tasks.run() + } catch (e) { + console.log(c.error(e.message)) + } + }, + } +} diff --git a/packages/cli/src/commands/destroy/layout/layout.js b/packages/cli/src/commands/destroy/layout/layout.js index 3ddec9419903..cc820eebbca6 100644 --- a/packages/cli/src/commands/destroy/layout/layout.js +++ b/packages/cli/src/commands/destroy/layout/layout.js @@ -1,5 +1,5 @@ -import { createYargsForComponentDestroy } from '../../generate/helpers' -import { files } from '../../generate/layout/layout' +import { files as layoutFiles } from '../../generate/layout/layout' +import { createYargsForComponentDestroy } from '../helpers' export const { command, @@ -8,5 +8,5 @@ export const { handler, } = createYargsForComponentDestroy({ componentName: 'layout', - filesFn: files, + filesFn: layoutFiles, }) diff --git a/packages/cli/src/commands/destroy/page/page.js b/packages/cli/src/commands/destroy/page/page.js index 71b4e6a5bce1..89755ae16f43 100644 --- a/packages/cli/src/commands/destroy/page/page.js +++ b/packages/cli/src/commands/destroy/page/page.js @@ -5,7 +5,7 @@ import { deleteFilesTask, removeRoutesFromRouterTask } from 'src/lib' import c from 'src/lib/colors' import { pathName } from '../../generate/helpers' -import { files } from '../../generate/page/page' +import { files as pageFiles } from '../../generate/page/page' export const command = 'page [path]' export const desc = 'Destroy a page component.' @@ -16,7 +16,7 @@ export const handler = async ({ name, path }) => { { title: 'Destroying page files...', task: async () => { - const f = files({ name, path: pathName(path, name) }) + const f = pageFiles({ name, path: pathName(path, name) }) return deleteFilesTask(f) }, }, diff --git a/packages/cli/src/commands/destroy/scaffold/scaffold.js b/packages/cli/src/commands/destroy/scaffold/scaffold.js index f88122d51eb8..a202faf9f88b 100644 --- a/packages/cli/src/commands/destroy/scaffold/scaffold.js +++ b/packages/cli/src/commands/destroy/scaffold/scaffold.js @@ -3,7 +3,10 @@ import Listr from 'listr' import { deleteFilesTask, removeRoutesFromRouterTask } from 'src/lib' import c from 'src/lib/colors' -import { files, routes as routesFn } from '../../generate/scaffold/scaffold' +import { + files, + routes as scaffoldRoutes, +} from '../../generate/scaffold/scaffold' export const command = 'scaffold ' export const desc = 'Destroy pages, SDL, and a services object.' @@ -21,7 +24,7 @@ export const handler = async ({ model }) => { { title: 'Cleaning up scaffold routes...', task: async () => { - const routes = await routesFn({ model }) + const routes = await scaffoldRoutes({ model }) const routeNames = routes.map(extractRouteName) return removeRoutesFromRouterTask(routeNames) }, diff --git a/packages/cli/src/commands/destroy/service/service.js b/packages/cli/src/commands/destroy/service/service.js index dfad16e07a7a..2534b9989b15 100644 --- a/packages/cli/src/commands/destroy/service/service.js +++ b/packages/cli/src/commands/destroy/service/service.js @@ -1,5 +1,5 @@ -import { createYargsForComponentDestroy } from '../../generate/helpers' import { files } from '../../generate/service/service' +import { createYargsForComponentDestroy } from '../helpers' // This function wraps files(), so we can pass templateVars. templateVars // referenced in a file template must be defined, otherwise template rendering diff --git a/packages/cli/src/commands/generate/helpers.js b/packages/cli/src/commands/generate/helpers.js index 4d4138d3204a..7ac71a1a0daf 100644 --- a/packages/cli/src/commands/generate/helpers.js +++ b/packages/cli/src/commands/generate/helpers.js @@ -6,12 +6,7 @@ import Listr from 'listr' import pascalcase from 'pascalcase' import { paramCase } from 'param-case' -import { - deleteFilesTask, - generateTemplate, - getPaths, - writeFilesTask, -} from 'src/lib' +import { generateTemplate, getPaths, writeFilesTask } from 'src/lib' import c from 'src/lib/colors' /** @@ -95,33 +90,6 @@ export const createYargsForComponentGeneration = ({ } } -export const createYargsForComponentDestroy = ({ componentName, filesFn }) => { - return { - command: `${componentName} `, - desc: `Destroy a ${componentName} component.`, - handler: async (names) => { - const tasks = new Listr( - [ - { - title: `Destroying ${componentName} files...`, - task: async () => { - const f = await filesFn(names) - return deleteFilesTask(f) - }, - }, - ], - { collapse: false, exitOnError: true } - ) - - try { - await tasks.run() - } catch (e) { - console.log(c.error(e.message)) - } - }, - } -} - // Returns all relations to other models export const relationsForModel = (model) => { return model.fields diff --git a/packages/cli/src/lib/index.js b/packages/cli/src/lib/index.js index b78a0490c3b1..ff808501e463 100644 --- a/packages/cli/src/lib/index.js +++ b/packages/cli/src/lib/index.js @@ -24,7 +24,7 @@ export const asyncForEach = async (array, callback) => { /** * Returns the database schema for the given `name` database table parsed from - * the schema.prisma of the target applicaiton. If no `name` is given then the + * the schema.prisma of the target application. If no `name` is given then the * entire schema is returned. */ export const getSchema = async (name) => { @@ -240,7 +240,7 @@ export const cleanupEmptyDirsTask = (files) => { return new Listr( uniqueDirs.map((dir) => { return { - title: `Removing \`./${path.relative(base, dir)}\`...`, + title: `Removing empty \`./${path.relative(base, dir)}\`...`, task: () => fs.rmdirSync(dir), skip: () => { if (!fs.existsSync(dir)) { From 4bf03fbff5717201048d4a2b611b8cdcf35fccbb Mon Sep 17 00:00:00 2001 From: Anton Moiseev Date: Mon, 11 May 2020 16:04:24 +0400 Subject: [PATCH 12/24] Add test for destroy page command --- packages/cli/__mocks__/fs.js | 34 ++++++++++++ .../destroy/page/__tests__/page.test.js | 53 +++++++++++++++++++ .../cli/src/commands/destroy/page/page.js | 6 ++- 3 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 packages/cli/__mocks__/fs.js create mode 100644 packages/cli/src/commands/destroy/page/__tests__/page.test.js diff --git a/packages/cli/__mocks__/fs.js b/packages/cli/__mocks__/fs.js new file mode 100644 index 000000000000..8bc6e80dc206 --- /dev/null +++ b/packages/cli/__mocks__/fs.js @@ -0,0 +1,34 @@ +import { isString } from 'lodash' + +const fs = { + ...require.requireActual('fs'), +} + +// This is a custom function that our tests can use during setup to specify +// what the files on the "mock" filesystem should look like when any of the +// `fs` APIs are used. +let mockFiles = {} +/** @param newMockFiles - {[filepath]: contents} */ +fs.__setMockFiles = (newMockFiles) => { + mockFiles = { ...newMockFiles } +} + +fs.existsSync = (path) => { + return isString(mockFiles[path]) +} + +fs.mkdirSync = () => {} + +fs.readFileSync = (path) => { + return mockFiles[path] +} + +fs.writeFileSync = (path, contents) => { + mockFiles[path] = contents +} + +fs.unlinkSync = (path) => { + delete mockFiles[path] +} + +module.exports = fs diff --git a/packages/cli/src/commands/destroy/page/__tests__/page.test.js b/packages/cli/src/commands/destroy/page/__tests__/page.test.js new file mode 100644 index 000000000000..46ac035efff5 --- /dev/null +++ b/packages/cli/src/commands/destroy/page/__tests__/page.test.js @@ -0,0 +1,53 @@ +global.__dirname = __dirname +jest.mock('fs') +jest.mock('src/lib', () => { + return { + ...require.requireActual('src/lib'), + generateTemplate: () => '', + } +}) + +import fs from 'fs' + +import 'src/lib/test' +import { getPaths } from 'src/lib' + +import { files } from '../../../generate/page/page' +import { tasks } from '../page' + +beforeEach(() => { + fs.__setMockFiles({ + ...files({ name: 'About' }), + [getPaths().web.routes]: [ + '', + ' ', + ' ', + ' ', + '', + ].join('\n'), + }) +}) + +test('destroys a page and route', async () => { + const unlinkSpy = jest.spyOn(fs, 'unlinkSync') + const t = tasks({ name: 'About' }) + t.setRenderer('silent') + + return t.run().then(() => { + // Make sure all generated files were destroyed. + const generatedFiles = Object.keys(files({ name: 'About' })) + expect(generatedFiles.length).toEqual(unlinkSpy.mock.calls.length) + generatedFiles.forEach((f) => expect(unlinkSpy).toHaveBeenCalledWith(f)) + + // Make sure Routes.js has been cleaned up. + const routes = fs.readFileSync(getPaths().web.routes) + expect(routes).toEqual( + [ + '', + ' ', + ' ', + '', + ].join('\n') + ) + }) +}) diff --git a/packages/cli/src/commands/destroy/page/page.js b/packages/cli/src/commands/destroy/page/page.js index 89755ae16f43..9fdf13e293d9 100644 --- a/packages/cli/src/commands/destroy/page/page.js +++ b/packages/cli/src/commands/destroy/page/page.js @@ -10,8 +10,8 @@ import { files as pageFiles } from '../../generate/page/page' export const command = 'page [path]' export const desc = 'Destroy a page component.' -export const handler = async ({ name, path }) => { - const tasks = new Listr( +export const tasks = ({ name, path }) => + new Listr( [ { title: 'Destroying page files...', @@ -28,6 +28,8 @@ export const handler = async ({ name, path }) => { { collapse: false, exitOnError: true } ) +export const handler = async ({ name, path }) => { + const tasks = tasks({ name, path }) try { await tasks.run() } catch (e) { From dd1a6b45a99e81e3eab36d4c3400c1ae285f186d Mon Sep 17 00:00:00 2001 From: Anton Moiseev Date: Tue, 12 May 2020 07:36:10 +0400 Subject: [PATCH 13/24] Split page destroy test into three --- .../destroy/page/__tests__/page.test.js | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/packages/cli/src/commands/destroy/page/__tests__/page.test.js b/packages/cli/src/commands/destroy/page/__tests__/page.test.js index 46ac035efff5..5479bb8cb2d6 100644 --- a/packages/cli/src/commands/destroy/page/__tests__/page.test.js +++ b/packages/cli/src/commands/destroy/page/__tests__/page.test.js @@ -28,18 +28,40 @@ beforeEach(() => { }) }) -test('destroys a page and route', async () => { +test('destroys page files', async () => { const unlinkSpy = jest.spyOn(fs, 'unlinkSync') const t = tasks({ name: 'About' }) t.setRenderer('silent') - return t.run().then(() => { - // Make sure all generated files were destroyed. + return t._tasks[0].run().then(() => { const generatedFiles = Object.keys(files({ name: 'About' })) expect(generatedFiles.length).toEqual(unlinkSpy.mock.calls.length) generatedFiles.forEach((f) => expect(unlinkSpy).toHaveBeenCalledWith(f)) + }) +}) + +test('cleans up route from Routes.js', async () => { + const t = tasks({ name: 'About' }) + t.setRenderer('silent') + + return t._tasks[1].run().then(() => { + const routes = fs.readFileSync(getPaths().web.routes) + expect(routes).toEqual( + [ + '', + ' ', + ' ', + '', + ].join('\n') + ) + }) +}) + +test('cleans up route with a custom path from Routes.js', async () => { + const t = tasks({ name: 'About', path: '/about-us' }) + t.setRenderer('silent') - // Make sure Routes.js has been cleaned up. + return t._tasks[1].run().then(() => { const routes = fs.readFileSync(getPaths().web.routes) expect(routes).toEqual( [ From f4ac09c681cda7c5a98dc6a8775c2a1e426a21d2 Mon Sep 17 00:00:00 2001 From: Anton Moiseev Date: Mon, 18 May 2020 19:02:45 +0400 Subject: [PATCH 14/24] Adjust scaffold destroy to #423 changes --- .../src/commands/destroy/scaffold/scaffold.js | 10 ++++--- .../commands/generate/scaffold/scaffold.js | 29 ++++++++++++------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/packages/cli/src/commands/destroy/scaffold/scaffold.js b/packages/cli/src/commands/destroy/scaffold/scaffold.js index a202faf9f88b..f7043e586cf1 100644 --- a/packages/cli/src/commands/destroy/scaffold/scaffold.js +++ b/packages/cli/src/commands/destroy/scaffold/scaffold.js @@ -5,26 +5,28 @@ import c from 'src/lib/colors' import { files, + resolveScaffoldPath, routes as scaffoldRoutes, } from '../../generate/scaffold/scaffold' -export const command = 'scaffold ' +export const command = 'scaffold ' export const desc = 'Destroy pages, SDL, and a services object.' -export const handler = async ({ model }) => { +export const handler = async ({ pathSlashModel }) => { + const { model, path } = resolveScaffoldPath({ pathSlashModel }) const tasks = new Listr( [ { title: 'Destroying scaffold files...', task: async () => { - const f = await files({ model }) + const f = await files({ model, path }) return deleteFilesTask(f) }, }, { title: 'Cleaning up scaffold routes...', task: async () => { - const routes = await scaffoldRoutes({ model }) + const routes = await scaffoldRoutes({ model, path }) const routeNames = routes.map(extractRouteName) return removeRoutesFromRouterTask(routeNames) }, diff --git a/packages/cli/src/commands/generate/scaffold/scaffold.js b/packages/cli/src/commands/generate/scaffold/scaffold.js index 773b8253285c..2228f7290c06 100644 --- a/packages/cli/src/commands/generate/scaffold/scaffold.js +++ b/packages/cli/src/commands/generate/scaffold/scaffold.js @@ -313,17 +313,7 @@ const addScaffoldImport = () => { return 'Added scaffold import to index.js' } -export const command = 'scaffold ' -export const desc = 'Generate pages, SDL, and a services object.' -export const builder = { - force: { type: 'boolean', default: false }, - // So the user can specify a path to nest the generated files under. - // E.g. yarn rw g scaffold post --path=admin - path: { type: 'string', default: false }, -} -// The user can also specify a path in the argument. -// E.g. yarn rw g scaffold admin/post -export const handler = async ({ pathSlashModel, force, path: pathFlag }) => { +export const resolveScaffoldPath = ({ pathSlashModel, pathFlag }) => { let path // If path is specified by both pathSlashModel and pathFlag, // we give pathFlag precedence. @@ -336,6 +326,23 @@ export const handler = async ({ pathSlashModel, force, path: pathFlag }) => { // path.split('/') will return ['post']. const model = pathSlashModel.split('/').pop() + return { model, path } +} + +export const command = 'scaffold ' +export const desc = 'Generate pages, SDL, and a services object.' +export const builder = { + force: { type: 'boolean', default: false }, + // So the user can specify a path to nest the generated files under. + // E.g. yarn rw g scaffold post --path=admin + path: { type: 'string', default: false }, +} + +// The user can also specify a path in the argument. +// E.g. yarn rw g scaffold admin/post +export const handler = async ({ pathSlashModel, force, path: pathFlag }) => { + const { model, path } = resolveScaffoldPath({ pathSlashModel, pathFlag }) + const tasks = new Listr( [ { From ae7037c9b7596c622cafe5888863b366302e1559 Mon Sep 17 00:00:00 2001 From: Anton Moiseev Date: Mon, 18 May 2020 21:32:17 +0400 Subject: [PATCH 15/24] Add test for destroy component command --- .../component/__tests__/component.test.js | 35 +++++++++++++++++++ .../commands/destroy/component/component.js | 7 +++- packages/cli/src/commands/destroy/helpers.js | 32 +++++++++-------- .../cli/src/commands/destroy/page/page.js | 4 +-- 4 files changed, 61 insertions(+), 17 deletions(-) create mode 100644 packages/cli/src/commands/destroy/component/__tests__/component.test.js diff --git a/packages/cli/src/commands/destroy/component/__tests__/component.test.js b/packages/cli/src/commands/destroy/component/__tests__/component.test.js new file mode 100644 index 000000000000..0be4310df38e --- /dev/null +++ b/packages/cli/src/commands/destroy/component/__tests__/component.test.js @@ -0,0 +1,35 @@ +global.__dirname = __dirname +jest.mock('fs') +jest.mock('src/lib', () => { + return { + ...require.requireActual('src/lib'), + generateTemplate: () => '', + } +}) + +import fs from 'fs' + +import 'src/lib/test' + +import { files } from '../../../generate/component/component' +import { tasks } from '../component' + +beforeEach(() => { + fs.__setMockFiles({ + ...files({ name: 'About' }), + }) +}) + +test('destroys component files', async () => { + const unlinkSpy = jest.spyOn(fs, 'unlinkSync') + const t = tasks({ componentName: 'component', filesFn: files, name: 'About' }) + t.setRenderer('silent') + + return t.run().then(() => { + console.log(unlinkSpy.mock.calls) + + const generatedFiles = Object.keys(files({ name: 'About' })) + expect(generatedFiles.length).toEqual(unlinkSpy.mock.calls.length) + generatedFiles.forEach((f) => expect(unlinkSpy).toHaveBeenCalledWith(f)) + }) +}) diff --git a/packages/cli/src/commands/destroy/component/component.js b/packages/cli/src/commands/destroy/component/component.js index 26f86a8a6bbb..949f1cffaed9 100644 --- a/packages/cli/src/commands/destroy/component/component.js +++ b/packages/cli/src/commands/destroy/component/component.js @@ -3,7 +3,12 @@ import { createYargsForComponentDestroy } from '../helpers' export const desc = 'Destroy a component.' -export const { command, builder, handler } = createYargsForComponentDestroy({ +export const { + command, + builder, + handler, + tasks, +} = createYargsForComponentDestroy({ componentName: 'component', filesFn: componentFiles, }) diff --git a/packages/cli/src/commands/destroy/helpers.js b/packages/cli/src/commands/destroy/helpers.js index 73ecdd43cc63..b4b72ec480d2 100644 --- a/packages/cli/src/commands/destroy/helpers.js +++ b/packages/cli/src/commands/destroy/helpers.js @@ -3,29 +3,33 @@ import Listr from 'listr' import { deleteFilesTask } from 'src/lib' import c from 'src/lib/colors' +const tasks = ({ componentName, filesFn, name }) => + new Listr( + [ + { + title: `Destroying ${componentName} files...`, + task: async () => { + const f = await filesFn({ name }) + return deleteFilesTask(f) + }, + }, + ], + { collapse: false, exitOnError: true } + ) + export const createYargsForComponentDestroy = ({ componentName, filesFn }) => { return { command: `${componentName} `, desc: `Destroy a ${componentName} component.`, - handler: async (names) => { - const tasks = new Listr( - [ - { - title: `Destroying ${componentName} files...`, - task: async () => { - const f = await filesFn(names) - return deleteFilesTask(f) - }, - }, - ], - { collapse: false, exitOnError: true } - ) + handler: async (name) => { + const t = tasks({ componentName, filesFn, name }) try { - await tasks.run() + await t.run() } catch (e) { console.log(c.error(e.message)) } }, + tasks, } } diff --git a/packages/cli/src/commands/destroy/page/page.js b/packages/cli/src/commands/destroy/page/page.js index 9fdf13e293d9..244e53fb311d 100644 --- a/packages/cli/src/commands/destroy/page/page.js +++ b/packages/cli/src/commands/destroy/page/page.js @@ -29,9 +29,9 @@ export const tasks = ({ name, path }) => ) export const handler = async ({ name, path }) => { - const tasks = tasks({ name, path }) + const t = tasks({ name, path }) try { - await tasks.run() + await t.run() } catch (e) { console.log(c.error(e.message)) } From 4b54fc393b52bacbe8eec7cc813538d1532936d2 Mon Sep 17 00:00:00 2001 From: Anton Moiseev Date: Mon, 18 May 2020 21:36:19 +0400 Subject: [PATCH 16/24] Add test for destroy cell command --- .../destroy/cell/__tests__/cell.test.js | 33 +++++++++++++++++++ .../cli/src/commands/destroy/cell/cell.js | 1 + .../component/__tests__/component.test.js | 2 -- 3 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 packages/cli/src/commands/destroy/cell/__tests__/cell.test.js diff --git a/packages/cli/src/commands/destroy/cell/__tests__/cell.test.js b/packages/cli/src/commands/destroy/cell/__tests__/cell.test.js new file mode 100644 index 000000000000..f6a0ae5cb1b8 --- /dev/null +++ b/packages/cli/src/commands/destroy/cell/__tests__/cell.test.js @@ -0,0 +1,33 @@ +global.__dirname = __dirname +jest.mock('fs') +jest.mock('src/lib', () => { + return { + ...require.requireActual('src/lib'), + generateTemplate: () => '', + } +}) + +import fs from 'fs' + +import 'src/lib/test' + +import { files } from '../../../generate/cell/cell' +import { tasks } from '../cell' + +beforeEach(() => { + fs.__setMockFiles({ + ...files({ name: 'User' }), + }) +}) + +test('destroys cell files', async () => { + const unlinkSpy = jest.spyOn(fs, 'unlinkSync') + const t = tasks({ componentName: 'cell', filesFn: files, name: 'User' }) + t.setRenderer('silent') + + return t.run().then(() => { + const generatedFiles = Object.keys(files({ name: 'User' })) + expect(generatedFiles.length).toEqual(unlinkSpy.mock.calls.length) + generatedFiles.forEach((f) => expect(unlinkSpy).toHaveBeenCalledWith(f)) + }) +}) diff --git a/packages/cli/src/commands/destroy/cell/cell.js b/packages/cli/src/commands/destroy/cell/cell.js index 7657043d903d..edb66f07d91d 100644 --- a/packages/cli/src/commands/destroy/cell/cell.js +++ b/packages/cli/src/commands/destroy/cell/cell.js @@ -6,6 +6,7 @@ export const { desc, builder, handler, + tasks, } = createYargsForComponentDestroy({ componentName: 'cell', filesFn: cellFiles, diff --git a/packages/cli/src/commands/destroy/component/__tests__/component.test.js b/packages/cli/src/commands/destroy/component/__tests__/component.test.js index 0be4310df38e..0f64a35fba67 100644 --- a/packages/cli/src/commands/destroy/component/__tests__/component.test.js +++ b/packages/cli/src/commands/destroy/component/__tests__/component.test.js @@ -26,8 +26,6 @@ test('destroys component files', async () => { t.setRenderer('silent') return t.run().then(() => { - console.log(unlinkSpy.mock.calls) - const generatedFiles = Object.keys(files({ name: 'About' })) expect(generatedFiles.length).toEqual(unlinkSpy.mock.calls.length) generatedFiles.forEach((f) => expect(unlinkSpy).toHaveBeenCalledWith(f)) From a412fe4c907b56b981a9c57bde9097846b3480b0 Mon Sep 17 00:00:00 2001 From: Anton Moiseev Date: Mon, 18 May 2020 21:41:15 +0400 Subject: [PATCH 17/24] Add test for destroy layout command --- .../destroy/layout/__tests__/layout.test.js | 33 +++++++++++++++++++ .../cli/src/commands/destroy/layout/layout.js | 1 + 2 files changed, 34 insertions(+) create mode 100644 packages/cli/src/commands/destroy/layout/__tests__/layout.test.js diff --git a/packages/cli/src/commands/destroy/layout/__tests__/layout.test.js b/packages/cli/src/commands/destroy/layout/__tests__/layout.test.js new file mode 100644 index 000000000000..bcc832d029f2 --- /dev/null +++ b/packages/cli/src/commands/destroy/layout/__tests__/layout.test.js @@ -0,0 +1,33 @@ +global.__dirname = __dirname +jest.mock('fs') +jest.mock('src/lib', () => { + return { + ...require.requireActual('src/lib'), + generateTemplate: () => '', + } +}) + +import fs from 'fs' + +import 'src/lib/test' + +import { files } from '../../../generate/layout/layout' +import { tasks } from '../layout' + +beforeEach(() => { + fs.__setMockFiles({ + ...files({ name: 'Blog' }), + }) +}) + +test('destroys layout files', async () => { + const unlinkSpy = jest.spyOn(fs, 'unlinkSync') + const t = tasks({ componentName: 'layout', filesFn: files, name: 'Blog' }) + t.setRenderer('silent') + + return t.run().then(() => { + const generatedFiles = Object.keys(files({ name: 'Blog' })) + expect(generatedFiles.length).toEqual(unlinkSpy.mock.calls.length) + generatedFiles.forEach((f) => expect(unlinkSpy).toHaveBeenCalledWith(f)) + }) +}) diff --git a/packages/cli/src/commands/destroy/layout/layout.js b/packages/cli/src/commands/destroy/layout/layout.js index cc820eebbca6..c44da5371a0f 100644 --- a/packages/cli/src/commands/destroy/layout/layout.js +++ b/packages/cli/src/commands/destroy/layout/layout.js @@ -6,6 +6,7 @@ export const { desc, builder, handler, + tasks, } = createYargsForComponentDestroy({ componentName: 'layout', filesFn: layoutFiles, From db31736ceb089bfc8b424c365a43cddf026c789d Mon Sep 17 00:00:00 2001 From: Anton Moiseev Date: Mon, 18 May 2020 21:43:22 +0400 Subject: [PATCH 18/24] Add test for destroy service command --- .../destroy/service/__tests__/service.test.js | 33 +++++++++++++++++++ .../src/commands/destroy/service/service.js | 10 +++--- 2 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 packages/cli/src/commands/destroy/service/__tests__/service.test.js diff --git a/packages/cli/src/commands/destroy/service/__tests__/service.test.js b/packages/cli/src/commands/destroy/service/__tests__/service.test.js new file mode 100644 index 000000000000..331a4107f445 --- /dev/null +++ b/packages/cli/src/commands/destroy/service/__tests__/service.test.js @@ -0,0 +1,33 @@ +global.__dirname = __dirname +jest.mock('fs') +jest.mock('src/lib', () => { + return { + ...require.requireActual('src/lib'), + generateTemplate: () => '', + } +}) + +import fs from 'fs' + +import 'src/lib/test' + +import { files } from '../../../generate/service/service' +import { tasks } from '../service' + +beforeEach(() => { + fs.__setMockFiles({ + ...files({ name: 'User' }), + }) +}) + +test('destroys service files', async () => { + const unlinkSpy = jest.spyOn(fs, 'unlinkSync') + const t = tasks({ componentName: 'service', filesFn: files, name: 'User' }) + t.setRenderer('silent') + + return t.run().then(() => { + const generatedFiles = Object.keys(files({ name: 'User' })) + expect(generatedFiles.length).toEqual(unlinkSpy.mock.calls.length) + generatedFiles.forEach((f) => expect(unlinkSpy).toHaveBeenCalledWith(f)) + }) +}) diff --git a/packages/cli/src/commands/destroy/service/service.js b/packages/cli/src/commands/destroy/service/service.js index 2534b9989b15..bf23acadcf32 100644 --- a/packages/cli/src/commands/destroy/service/service.js +++ b/packages/cli/src/commands/destroy/service/service.js @@ -13,7 +13,9 @@ export const filesWithTemplateVars = (templateVars) => { return (args) => files({ ...args, ...templateVars }) } -export const { command, desc, handler } = createYargsForComponentDestroy({ - componentName: 'service', - filesFn: filesWithTemplateVars({ crud: false }), -}) +export const { command, desc, handler, tasks } = createYargsForComponentDestroy( + { + componentName: 'service', + filesFn: filesWithTemplateVars({ crud: false }), + } +) From 92f2c31bf3b2f120f3bf52bba00c7ae51d7ced47 Mon Sep 17 00:00:00 2001 From: Anton Moiseev Date: Tue, 19 May 2020 09:15:17 +0400 Subject: [PATCH 19/24] Add test for destroy scaffold command --- .../scaffold/__tests__/fixtures/post.json | 50 +++++++ .../scaffold/__tests__/scaffold.test.js | 124 ++++++++++++++++++ .../src/commands/destroy/scaffold/scaffold.js | 10 +- packages/cli/src/commands/generate/sdl/sdl.js | 2 +- 4 files changed, 181 insertions(+), 5 deletions(-) create mode 100644 packages/cli/src/commands/destroy/scaffold/__tests__/fixtures/post.json create mode 100644 packages/cli/src/commands/destroy/scaffold/__tests__/scaffold.test.js diff --git a/packages/cli/src/commands/destroy/scaffold/__tests__/fixtures/post.json b/packages/cli/src/commands/destroy/scaffold/__tests__/fixtures/post.json new file mode 100644 index 000000000000..632723657e97 --- /dev/null +++ b/packages/cli/src/commands/destroy/scaffold/__tests__/fixtures/post.json @@ -0,0 +1,50 @@ +{ + "name": "Post", + "isEmbedded": false, + "dbName": null, + "fields": [ + { + "name": "id", + "kind": "scalar", + "isList": false, + "isRequired": true, + "isUnique": false, + "isId": true, + "isReadOnly": false, + "type": "Int", + "default": { + "name": "autoincrement", + "args": [] + }, + "isGenerated": false, + "isUpdatedAt": false + }, + { + "name": "title", + "kind": "scalar", + "isList": false, + "isRequired": true, + "isUnique": false, + "isId": false, + "isReadOnly": false, + "type": "String", + "isGenerated": false, + "isUpdatedAt": false + }, + { + "name": "content", + "kind": "scalar", + "isList": false, + "isRequired": false, + "isUnique": false, + "isId": false, + "isReadOnly": false, + "type": "String", + "isGenerated": false, + "isUpdatedAt": false + } + ], + "isGenerated": false, + "idFields": [], + "uniqueFields": [] +} diff --git a/packages/cli/src/commands/destroy/scaffold/__tests__/scaffold.test.js b/packages/cli/src/commands/destroy/scaffold/__tests__/scaffold.test.js new file mode 100644 index 000000000000..795fc4f5d116 --- /dev/null +++ b/packages/cli/src/commands/destroy/scaffold/__tests__/scaffold.test.js @@ -0,0 +1,124 @@ +global.__dirname = __dirname +jest.mock('fs') +jest.mock('src/lib', () => { + const path = require('path') + return { + ...require.requireActual('src/lib'), + generateTemplate: () => '', + getSchema: () => + require(path.join(global.__dirname, 'fixtures', 'post.json')), + } +}) + +import fs from 'fs' + +import 'src/lib/test' +import { getPaths } from 'src/lib' + +import { files } from '../../../generate/scaffold/scaffold' +import { tasks } from '../scaffold' + +describe('destroy scaffold post', () => { + beforeEach(async () => { + fs.__setMockFiles({ + ...(await files({ model: 'Post' })), + [getPaths().web.routes]: [ + '', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + '', + ].join('\n'), + }) + }) + + afterAll(() => { + fs.__setMockFiles({}) + jest.spyOn(fs, 'unlinkSync').mockClear() + }) + + test('destroys files', async () => { + const unlinkSpy = jest.spyOn(fs, 'unlinkSync') + const t = tasks({ model: 'Post' }) + t.setRenderer('silent') + + return t._tasks[0].run().then(async () => { + const generatedFiles = Object.keys(await files({ model: 'Post' })) + expect(generatedFiles.length).toEqual(unlinkSpy.mock.calls.length) + generatedFiles.forEach((f) => expect(unlinkSpy).toHaveBeenCalledWith(f)) + }) + }) + + test('cleans up routes from Routes.js', async () => { + const t = tasks({ model: 'Post' }) + t.setRenderer('silent') + + return t._tasks[1].run().then(() => { + const routes = fs.readFileSync(getPaths().web.routes) + expect(routes).toEqual( + [ + '', + ' ', + ' ', + '', + ].join('\n') + ) + }) + }) +}) + +describe('destroy namespaced scaffold post', () => { + beforeEach(async () => { + fs.__setMockFiles({ + ...(await files({ model: 'Post', path: 'admin' })), + [getPaths().web.routes]: [ + '', + ' ', + ' ', + ' ', + ' ', + ' ', + '', + ].join('\n'), + }) + }) + + afterAll(() => { + fs.__setMockFiles({}) + jest.spyOn(fs, 'unlinkSync').mockClear() + }) + + test('destroys files', async () => { + const unlinkSpy = jest.spyOn(fs, 'unlinkSync') + const t = tasks({ model: 'Post', path: 'admin' }) + t.setRenderer('silent') + + return t._tasks[0].run().then(async () => { + const generatedFiles = Object.keys( + await files({ model: 'Post', path: 'admin' }) + ) + expect(generatedFiles.length).toEqual(unlinkSpy.mock.calls.length) + generatedFiles.forEach((f) => expect(unlinkSpy).toHaveBeenCalledWith(f)) + }) + }) + + test('cleans up routes from Routes.js', async () => { + const t = tasks({ model: 'Post', path: 'admin' }) + t.setRenderer('silent') + + return t._tasks[1].run().then(() => { + const routes = fs.readFileSync(getPaths().web.routes) + expect(routes).toEqual( + [ + '', + ' ', + ' ', + '', + ].join('\n') + ) + }) + }) +}) diff --git a/packages/cli/src/commands/destroy/scaffold/scaffold.js b/packages/cli/src/commands/destroy/scaffold/scaffold.js index f7043e586cf1..1073273b0d3d 100644 --- a/packages/cli/src/commands/destroy/scaffold/scaffold.js +++ b/packages/cli/src/commands/destroy/scaffold/scaffold.js @@ -12,9 +12,8 @@ import { export const command = 'scaffold ' export const desc = 'Destroy pages, SDL, and a services object.' -export const handler = async ({ pathSlashModel }) => { - const { model, path } = resolveScaffoldPath({ pathSlashModel }) - const tasks = new Listr( +export const tasks = ({ model, path }) => + new Listr( [ { title: 'Destroying scaffold files...', @@ -34,8 +33,11 @@ export const handler = async ({ pathSlashModel }) => { ], { collapse: false, exitOnError: true } ) + +export const handler = async ({ pathSlashModel }) => { + const t = tasks(resolveScaffoldPath({ pathSlashModel })) try { - await tasks.run() + await t.run() } catch (e) { console.log(c.error(e.message)) } diff --git a/packages/cli/src/commands/generate/sdl/sdl.js b/packages/cli/src/commands/generate/sdl/sdl.js index 466eb7b8dc9b..a47ab538dfea 100644 --- a/packages/cli/src/commands/generate/sdl/sdl.js +++ b/packages/cli/src/commands/generate/sdl/sdl.js @@ -78,7 +78,7 @@ const sdlFromSchemaModel = async (name) => { ) ).reduce((acc, cur) => ({ ...acc, [cur.name]: cur }), {}) - // Get enum definiton and fields from user-defined types + // Get enum definition and fields from user-defined types const enums = ( await Promise.all( model.fields From e4bd9718c7eedc9ac2a747bc1415a40238b680b1 Mon Sep 17 00:00:00 2001 From: Anton Moiseev Date: Tue, 19 May 2020 09:56:31 +0400 Subject: [PATCH 20/24] Add test for destroy sdl command --- .../destroy/cell/__tests__/cell.test.js | 9 ++-- .../component/__tests__/component.test.js | 9 ++-- .../destroy/layout/__tests__/layout.test.js | 9 ++-- .../destroy/page/__tests__/page.test.js | 5 ++ .../scaffold/__tests__/scaffold.test.js | 4 +- .../destroy/sdl/__tests__/fixtures/post.json | 50 +++++++++++++++++++ .../destroy/sdl/__tests__/sdl.test.js | 39 +++++++++++++++ packages/cli/src/commands/destroy/sdl/sdl.js | 9 ++-- .../destroy/service/__tests__/service.test.js | 5 ++ 9 files changed, 125 insertions(+), 14 deletions(-) create mode 100644 packages/cli/src/commands/destroy/sdl/__tests__/fixtures/post.json create mode 100644 packages/cli/src/commands/destroy/sdl/__tests__/sdl.test.js diff --git a/packages/cli/src/commands/destroy/cell/__tests__/cell.test.js b/packages/cli/src/commands/destroy/cell/__tests__/cell.test.js index f6a0ae5cb1b8..8408c5af4ac4 100644 --- a/packages/cli/src/commands/destroy/cell/__tests__/cell.test.js +++ b/packages/cli/src/commands/destroy/cell/__tests__/cell.test.js @@ -15,9 +15,12 @@ import { files } from '../../../generate/cell/cell' import { tasks } from '../cell' beforeEach(() => { - fs.__setMockFiles({ - ...files({ name: 'User' }), - }) + fs.__setMockFiles(files({ name: 'User' })) +}) + +afterEach(() => { + fs.__setMockFiles({}) + jest.spyOn(fs, 'unlinkSync').mockClear() }) test('destroys cell files', async () => { diff --git a/packages/cli/src/commands/destroy/component/__tests__/component.test.js b/packages/cli/src/commands/destroy/component/__tests__/component.test.js index 0f64a35fba67..06ab059f10a3 100644 --- a/packages/cli/src/commands/destroy/component/__tests__/component.test.js +++ b/packages/cli/src/commands/destroy/component/__tests__/component.test.js @@ -15,9 +15,12 @@ import { files } from '../../../generate/component/component' import { tasks } from '../component' beforeEach(() => { - fs.__setMockFiles({ - ...files({ name: 'About' }), - }) + fs.__setMockFiles(files({ name: 'About' })) +}) + +afterEach(() => { + fs.__setMockFiles({}) + jest.spyOn(fs, 'unlinkSync').mockClear() }) test('destroys component files', async () => { diff --git a/packages/cli/src/commands/destroy/layout/__tests__/layout.test.js b/packages/cli/src/commands/destroy/layout/__tests__/layout.test.js index bcc832d029f2..a5829724dad3 100644 --- a/packages/cli/src/commands/destroy/layout/__tests__/layout.test.js +++ b/packages/cli/src/commands/destroy/layout/__tests__/layout.test.js @@ -15,9 +15,12 @@ import { files } from '../../../generate/layout/layout' import { tasks } from '../layout' beforeEach(() => { - fs.__setMockFiles({ - ...files({ name: 'Blog' }), - }) + fs.__setMockFiles(files({ name: 'Blog' })) +}) + +afterEach(() => { + fs.__setMockFiles({}) + jest.spyOn(fs, 'unlinkSync').mockClear() }) test('destroys layout files', async () => { diff --git a/packages/cli/src/commands/destroy/page/__tests__/page.test.js b/packages/cli/src/commands/destroy/page/__tests__/page.test.js index 5479bb8cb2d6..c08f2ef47def 100644 --- a/packages/cli/src/commands/destroy/page/__tests__/page.test.js +++ b/packages/cli/src/commands/destroy/page/__tests__/page.test.js @@ -28,6 +28,11 @@ beforeEach(() => { }) }) +afterEach(() => { + fs.__setMockFiles({}) + jest.spyOn(fs, 'unlinkSync').mockClear() +}) + test('destroys page files', async () => { const unlinkSpy = jest.spyOn(fs, 'unlinkSync') const t = tasks({ name: 'About' }) diff --git a/packages/cli/src/commands/destroy/scaffold/__tests__/scaffold.test.js b/packages/cli/src/commands/destroy/scaffold/__tests__/scaffold.test.js index 795fc4f5d116..b14886bfd062 100644 --- a/packages/cli/src/commands/destroy/scaffold/__tests__/scaffold.test.js +++ b/packages/cli/src/commands/destroy/scaffold/__tests__/scaffold.test.js @@ -35,7 +35,7 @@ describe('destroy scaffold post', () => { }) }) - afterAll(() => { + afterEach(() => { fs.__setMockFiles({}) jest.spyOn(fs, 'unlinkSync').mockClear() }) @@ -86,7 +86,7 @@ describe('destroy namespaced scaffold post', () => { }) }) - afterAll(() => { + afterEach(() => { fs.__setMockFiles({}) jest.spyOn(fs, 'unlinkSync').mockClear() }) diff --git a/packages/cli/src/commands/destroy/sdl/__tests__/fixtures/post.json b/packages/cli/src/commands/destroy/sdl/__tests__/fixtures/post.json new file mode 100644 index 000000000000..632723657e97 --- /dev/null +++ b/packages/cli/src/commands/destroy/sdl/__tests__/fixtures/post.json @@ -0,0 +1,50 @@ +{ + "name": "Post", + "isEmbedded": false, + "dbName": null, + "fields": [ + { + "name": "id", + "kind": "scalar", + "isList": false, + "isRequired": true, + "isUnique": false, + "isId": true, + "isReadOnly": false, + "type": "Int", + "default": { + "name": "autoincrement", + "args": [] + }, + "isGenerated": false, + "isUpdatedAt": false + }, + { + "name": "title", + "kind": "scalar", + "isList": false, + "isRequired": true, + "isUnique": false, + "isId": false, + "isReadOnly": false, + "type": "String", + "isGenerated": false, + "isUpdatedAt": false + }, + { + "name": "content", + "kind": "scalar", + "isList": false, + "isRequired": false, + "isUnique": false, + "isId": false, + "isReadOnly": false, + "type": "String", + "isGenerated": false, + "isUpdatedAt": false + } + ], + "isGenerated": false, + "idFields": [], + "uniqueFields": [] +} diff --git a/packages/cli/src/commands/destroy/sdl/__tests__/sdl.test.js b/packages/cli/src/commands/destroy/sdl/__tests__/sdl.test.js new file mode 100644 index 000000000000..e45ffc87192e --- /dev/null +++ b/packages/cli/src/commands/destroy/sdl/__tests__/sdl.test.js @@ -0,0 +1,39 @@ +global.__dirname = __dirname +jest.mock('fs') +jest.mock('src/lib', () => { + const path = require('path') + return { + ...require.requireActual('src/lib'), + generateTemplate: () => '', + getSchema: () => + require(path.join(global.__dirname, 'fixtures', 'post.json')), + } +}) + +import fs from 'fs' + +import 'src/lib/test' + +import { files } from '../../../generate/sdl/sdl' +import { tasks } from '../sdl' + +beforeEach(async () => { + fs.__setMockFiles(await files({ name: 'Post' })) +}) + +afterEach(() => { + fs.__setMockFiles({}) + jest.spyOn(fs, 'unlinkSync').mockClear() +}) + +test('destroys sdl files', async () => { + const unlinkSpy = jest.spyOn(fs, 'unlinkSync') + const t = tasks({ model: 'Post' }) + t.setRenderer('silent') + + return t._tasks[0].run().then(async () => { + const generatedFiles = Object.keys(await files({ name: 'Post' })) + expect(generatedFiles.length).toEqual(unlinkSpy.mock.calls.length) + generatedFiles.forEach((f) => expect(unlinkSpy).toHaveBeenCalledWith(f)) + }) +}) diff --git a/packages/cli/src/commands/destroy/sdl/sdl.js b/packages/cli/src/commands/destroy/sdl/sdl.js index 3f0ed30b65c8..4e15556be70c 100644 --- a/packages/cli/src/commands/destroy/sdl/sdl.js +++ b/packages/cli/src/commands/destroy/sdl/sdl.js @@ -8,8 +8,8 @@ import { files } from '../../generate/sdl/sdl' export const command = 'sdl ' export const desc = 'Destroy a GraphQL schema and service object.' -export const handler = async ({ model }) => { - const tasks = new Listr( +export const tasks = ({ model }) => + new Listr( [ { title: 'Destroying GraphQL schema and service object files...', @@ -22,8 +22,11 @@ export const handler = async ({ model }) => { { collapse: false, exitOnError: true } ) +export const handler = async ({ model }) => { + const t = tasks({ model }) + try { - await tasks.run() + await t.run() } catch (e) { console.log(c.error(e.message)) } diff --git a/packages/cli/src/commands/destroy/service/__tests__/service.test.js b/packages/cli/src/commands/destroy/service/__tests__/service.test.js index 331a4107f445..8eb1b5080669 100644 --- a/packages/cli/src/commands/destroy/service/__tests__/service.test.js +++ b/packages/cli/src/commands/destroy/service/__tests__/service.test.js @@ -20,6 +20,11 @@ beforeEach(() => { }) }) +afterEach(() => { + fs.__setMockFiles({}) + jest.spyOn(fs, 'unlinkSync').mockClear() +}) + test('destroys service files', async () => { const unlinkSpy = jest.spyOn(fs, 'unlinkSync') const t = tasks({ componentName: 'service', filesFn: files, name: 'User' }) From 2ca9be8c0ccf93bddb85fbae11d4469ec6d0a8c6 Mon Sep 17 00:00:00 2001 From: Anton Moiseev Date: Tue, 19 May 2020 10:18:59 +0400 Subject: [PATCH 21/24] Add destroy function command --- .../cli/src/commands/destroy/function/function.js | 14 ++++++++++++++ packages/cli/src/commands/destroy/helpers.js | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 packages/cli/src/commands/destroy/function/function.js diff --git a/packages/cli/src/commands/destroy/function/function.js b/packages/cli/src/commands/destroy/function/function.js new file mode 100644 index 000000000000..64962f6026b0 --- /dev/null +++ b/packages/cli/src/commands/destroy/function/function.js @@ -0,0 +1,14 @@ +import { files as functionFiles } from '../../generate/function/function' +import { createYargsForComponentDestroy } from '../helpers' + +export const desc = 'Destroy a function' + +export const { + builder, + command, + handler, + tasks, +} = createYargsForComponentDestroy({ + componentName: 'function', + filesFn: functionFiles, +}) diff --git a/packages/cli/src/commands/destroy/helpers.js b/packages/cli/src/commands/destroy/helpers.js index b4b72ec480d2..f648b526c873 100644 --- a/packages/cli/src/commands/destroy/helpers.js +++ b/packages/cli/src/commands/destroy/helpers.js @@ -21,7 +21,7 @@ export const createYargsForComponentDestroy = ({ componentName, filesFn }) => { return { command: `${componentName} `, desc: `Destroy a ${componentName} component.`, - handler: async (name) => { + handler: async ({ name }) => { const t = tasks({ componentName, filesFn, name }) try { From 49b8568599c7e161f2941dcb1742c6ae2828a313 Mon Sep 17 00:00:00 2001 From: Anton Moiseev Date: Tue, 19 May 2020 10:34:54 +0400 Subject: [PATCH 22/24] Add test for destroy function command --- .../function/__tests__/function.test.js | 40 +++++++++++++++++++ .../destroy/service/__tests__/service.test.js | 10 ++--- 2 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 packages/cli/src/commands/destroy/function/__tests__/function.test.js diff --git a/packages/cli/src/commands/destroy/function/__tests__/function.test.js b/packages/cli/src/commands/destroy/function/__tests__/function.test.js new file mode 100644 index 000000000000..4d10b72673ef --- /dev/null +++ b/packages/cli/src/commands/destroy/function/__tests__/function.test.js @@ -0,0 +1,40 @@ +global.__dirname = __dirname +jest.mock('fs') +jest.mock('src/lib', () => { + return { + ...require.requireActual('src/lib'), + generateTemplate: () => '', + } +}) + +import fs from 'fs' + +import 'src/lib/test' + +import { files } from '../../../generate/function/function' +import { tasks } from '../function' + +beforeEach(async () => { + fs.__setMockFiles(await files({ name: 'sendMail' })) +}) + +afterEach(() => { + fs.__setMockFiles({}) + jest.spyOn(fs, 'unlinkSync').mockClear() +}) + +test('destroys service files', async () => { + const unlinkSpy = jest.spyOn(fs, 'unlinkSync') + const t = tasks({ + componentName: 'service', + filesFn: files, + name: 'sendMail', + }) + t.setRenderer('silent') + + return t.run().then(async () => { + const generatedFiles = Object.keys(await files({ name: 'sendMail' })) + expect(generatedFiles.length).toEqual(unlinkSpy.mock.calls.length) + generatedFiles.forEach((f) => expect(unlinkSpy).toHaveBeenCalledWith(f)) + }) +}) diff --git a/packages/cli/src/commands/destroy/service/__tests__/service.test.js b/packages/cli/src/commands/destroy/service/__tests__/service.test.js index 8eb1b5080669..2503a33673e1 100644 --- a/packages/cli/src/commands/destroy/service/__tests__/service.test.js +++ b/packages/cli/src/commands/destroy/service/__tests__/service.test.js @@ -14,10 +14,8 @@ import 'src/lib/test' import { files } from '../../../generate/service/service' import { tasks } from '../service' -beforeEach(() => { - fs.__setMockFiles({ - ...files({ name: 'User' }), - }) +beforeEach(async () => { + fs.__setMockFiles(await files({ name: 'User' })) }) afterEach(() => { @@ -30,8 +28,8 @@ test('destroys service files', async () => { const t = tasks({ componentName: 'service', filesFn: files, name: 'User' }) t.setRenderer('silent') - return t.run().then(() => { - const generatedFiles = Object.keys(files({ name: 'User' })) + return t.run().then(async () => { + const generatedFiles = Object.keys(await files({ name: 'User' })) expect(generatedFiles.length).toEqual(unlinkSpy.mock.calls.length) generatedFiles.forEach((f) => expect(unlinkSpy).toHaveBeenCalledWith(f)) }) From b3475f2f3d271bbed4694f8ac737c5472b9ff7c1 Mon Sep 17 00:00:00 2001 From: Anton Moiseev Date: Wed, 20 May 2020 08:39:13 +0400 Subject: [PATCH 23/24] Fix destroy scaffold after removing --path flag --- .../src/commands/destroy/scaffold/scaffold.js | 10 ++++--- .../commands/generate/scaffold/scaffold.js | 28 +++++++++++++------ 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/packages/cli/src/commands/destroy/scaffold/scaffold.js b/packages/cli/src/commands/destroy/scaffold/scaffold.js index 1073273b0d3d..e99607e464c2 100644 --- a/packages/cli/src/commands/destroy/scaffold/scaffold.js +++ b/packages/cli/src/commands/destroy/scaffold/scaffold.js @@ -5,11 +5,11 @@ import c from 'src/lib/colors' import { files, - resolveScaffoldPath, routes as scaffoldRoutes, + splitPathAndModel, } from '../../generate/scaffold/scaffold' -export const command = 'scaffold ' +export const command = 'scaffold ' export const desc = 'Destroy pages, SDL, and a services object.' export const tasks = ({ model, path }) => @@ -34,8 +34,10 @@ export const tasks = ({ model, path }) => { collapse: false, exitOnError: true } ) -export const handler = async ({ pathSlashModel }) => { - const t = tasks(resolveScaffoldPath({ pathSlashModel })) +export const handler = async ({ model: modelArg }) => { + const { model, path } = splitPathAndModel(modelArg) + + const t = tasks({ model, path }) try { await t.run() } catch (e) { diff --git a/packages/cli/src/commands/generate/scaffold/scaffold.js b/packages/cli/src/commands/generate/scaffold/scaffold.js index 95ef968fb7a9..2cff717496f6 100644 --- a/packages/cli/src/commands/generate/scaffold/scaffold.js +++ b/packages/cli/src/commands/generate/scaffold/scaffold.js @@ -326,14 +326,8 @@ export const builder = (yargs) => { type: 'boolean', }) } -export const handler = async ({ model: modelArg, force }) => { - let path = modelArg.split('/').slice(0, -1).join('/') - // This code will work whether or not there's a path in model - // E.g. if model is just 'post', - // path.split('/') will return ['post']. - const model = modelArg.split('/').pop() - - const tasks = new Listr( +const tasks = ({ model, path, force }) => { + return new Listr( [ { title: 'Generating scaffold files...', @@ -355,9 +349,25 @@ export const handler = async ({ model: modelArg, force }) => { ], { collapse: false, exitOnError: true } ) +} + +export const handler = async ({ model: modelArg, force }) => { + const { model, path } = splitPathAndModel(modelArg) + + const t = tasks({ model, path, force }) try { - await tasks.run() + await t.run() } catch (e) { console.log(c.error(e.message)) } } + +export const splitPathAndModel = (pathSlashModel) => { + const path = pathSlashModel.split('/').slice(0, -1).join('/') + // This code will work whether or not there's a path in model + // E.g. if model is just 'post', + // path.split('/') will return ['post']. + const model = pathSlashModel.split('/').pop() + + return { model, path } +} From 18f29d754c0bf57f0f21fa5b89e96b5f0d3ff5f3 Mon Sep 17 00:00:00 2001 From: Peter Pistorius Date: Mon, 25 May 2020 21:05:44 +0200 Subject: [PATCH 24/24] Remove `argv` to make command work. --- packages/cli/src/commands/destroy.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/commands/destroy.js b/packages/cli/src/commands/destroy.js index f6d17115b1b9..294d709f2e61 100644 --- a/packages/cli/src/commands/destroy.js +++ b/packages/cli/src/commands/destroy.js @@ -1,6 +1,6 @@ export const command = 'destroy ' export const aliases = ['d'] -export const desc = 'Rollback changes made by generate command.' +export const desc = 'Rollback changes made by the generate command.' export const builder = (yargs) => - yargs.commandDir('./destroy', { recurse: true }).demandCommand().argv + yargs.commandDir('./destroy', { recurse: true }).demandCommand()