From c807229e08edc22a0322bacd65218e158e1bf984 Mon Sep 17 00:00:00 2001 From: sy-records <52o@qq52o.cn> Date: Fri, 15 Jan 2021 11:56:48 +0800 Subject: [PATCH 1/4] feat: auto generate sidebar --- README.md | 20 +++++++++- e2e/cli.test.js.md | 28 ++++++++------ e2e/cli.test.js.snap | Bin 626 -> 657 bytes lib/cli.js | 17 +++++++++ lib/commands/generate.js | 79 +++++++++++++++++++++++++++++++++++++++ lib/index.js | 3 +- tools/locales/en.json | 2 + tools/locales/zh.json | 2 + 8 files changed, 136 insertions(+), 15 deletions(-) create mode 100644 lib/commands/generate.js diff --git a/README.md b/README.md index 920b0e3..cb7e1b0 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ Use `init` to generate your docs. ```shell docsify init [--local false] [--theme vue] -# docsify i [--local false] [--theme vue] +# docsify i [-l false] [-t vue] ``` `` defaults to the current directory. Use relative paths like `./docs` (or `docs`). @@ -75,7 +75,7 @@ Run a server on `localhost` with livereload. ```shell docsify serve [--open false] [--port 3000] -# docsify s [--open false] [--port 3000] +# docsify s [-o false] [-p 3000] ``` - `--open` option: @@ -89,6 +89,22 @@ docsify serve [--open false] [--port 3000] - Default: `3000` - Description: Choose a listen port, defaults to `3000`. +### `gen` command + +Docsify's generators. + +```shell +docsify generate [--sidebar _sidebar.md] + +# docsify g [-s _sidebar.md] +``` + +- `--sidebar` option: + - Shorthand: `-s` + - Type: string + - Default: `_sidebar.md` + - Description: Generate sidebar file, defaults to `_sidebar.md`. + ## Contributing Please see the [Contributing Guidelines](./CONTRIBUTING.md) diff --git a/e2e/cli.test.js.md b/e2e/cli.test.js.md index 132ce41..fd4f667 100644 --- a/e2e/cli.test.js.md +++ b/e2e/cli.test.js.md @@ -11,9 +11,10 @@ Generated by [AVA](https://avajs.dev). `Usage: docsify ␊ ␊ Commands:␊ - docsify init [path] Creates new docs [aliases: i]␊ - docsify serve [path] Run local server to preview site. [aliases: s]␊ - docsify start Server for SSR␊ + docsify init [path] Creates new docs [aliases: i]␊ + docsify serve [path] Run local server to preview site. [aliases: s]␊ + docsify start Server for SSR␊ + docsify generate Docsify's generators [aliases: g]␊ ␊ Global Options␊ --help, -h Show help [boolean]␊ @@ -35,9 +36,10 @@ Generated by [AVA](https://avajs.dev). `Usage: docsify ␊ ␊ Commands:␊ - docsify init [path] Creates new docs [aliases: i]␊ - docsify serve [path] Run local server to preview site. [aliases: s]␊ - docsify start Server for SSR␊ + docsify init [path] Creates new docs [aliases: i]␊ + docsify serve [path] Run local server to preview site. [aliases: s]␊ + docsify start Server for SSR␊ + docsify generate Docsify's generators [aliases: g]␊ ␊ Global Options␊ --help, -h Show help [boolean]␊ @@ -57,9 +59,10 @@ Generated by [AVA](https://avajs.dev). `Usage: docsify ␊ ␊ Commands:␊ - docsify init [path] Creates new docs [aliases: i]␊ - docsify serve [path] Run local server to preview site. [aliases: s]␊ - docsify start Server for SSR␊ + docsify init [path] Creates new docs [aliases: i]␊ + docsify serve [path] Run local server to preview site. [aliases: s]␊ + docsify start Server for SSR␊ + docsify generate Docsify's generators [aliases: g]␊ ␊ Global Options␊ --help, -h Show help [boolean]␊ @@ -79,9 +82,10 @@ Generated by [AVA](https://avajs.dev). `Usage: docsify ␊ ␊ Commands:␊ - docsify init [path] Creates new docs [aliases: i]␊ - docsify serve [path] Run local server to preview site. [aliases: s]␊ - docsify start Server for SSR␊ + docsify init [path] Creates new docs [aliases: i]␊ + docsify serve [path] Run local server to preview site. [aliases: s]␊ + docsify start Server for SSR␊ + docsify generate Docsify's generators [aliases: g]␊ ␊ Global Options␊ --help, -h Show help [boolean]␊ diff --git a/e2e/cli.test.js.snap b/e2e/cli.test.js.snap index f85b7aa63f283f240154376f370097c14e9a50d0..21205950d4215e531ca28f37121b0e64496c594c 100644 GIT binary patch literal 657 zcmV;C0&e|5RzVzicE5do`?A~N|liitRXYLMv(89*f zLJ^BAG>KqHW#KhZQixSFm7-W`VW(grDI#Qc?k5*aKc>SII+dh~5zsjo47TT|%bL8%7zt7^0qIGp&JC~|C*EUGYzyVF0gOjjE zM$k}zg);(Sj`=>O6`qBtON@A^6cNfutz1a3ARJLrS0uFCDq+vXobW7i%RPe1vsclm zQsglUd#$4o35J4@)Ld!6T|xBU1^G5XfkV;mLGcPLnQ0cHLc!=^+Jur&7T+b0whm77 z&JhcD?q|!|E<-rxF;kYC4}{Aomj>yyL%d)BrJYs*4y&UG*>yHMdYFuP1kve<(cs7%1k7kDJwkw>fsk^L${TVB5d9Kta zHR7=#vglQBvn}RtN%Vf0G36vPKIVdinOuHi(ilHqoE)DR)BOsBr3;3UH_GTN!lA9o z=P1COlZuWm%EmZBJRnwdvlv;e>~2f_vpDr}>i1UaGZngouTRC@+?h+Y?E3Bq>ZJq{+!{t~ky^XZI$zlkCncJ9Bp$MGG4{ zi-=fUp-B`awP~WH5UZetD2k=_3RWp1IJ3pIFIyqpu$x+j^zN>SMKU9uS2T?tA1{s5q z084jF*T=c&8&asz;nW=QR&uggYq5i&sLznO7LtUy@xt_s zId!f$Gc`SF_*GpmpEu2dS%EWv!&=z8g9!p6AWrmN7@T&__9V2DBs59r z!6h`wT9UQ@ku~k4-g9c_CZbBi#;|c#|5tD7N|NCu!w31J7uh`HP1gO-^DtLu^NwHr M2^T(oZu<%V01Q1Uga7~l diff --git a/lib/cli.js b/lib/cli.js index ce2c6d1..6354258 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -109,6 +109,23 @@ require('yargs') }), handler: argv => run.start(argv.path, argv.config, argv.port) }) + .command({ + command: 'generate ', + aliases: 'g', + desc: chalk.gray(y18n.__('generate')), + builder: yargs => + yargs.options({ + sidebar: { + alias: 's', + default: '_sidebar.md', + desc: chalk.gray(y18n.__('gen.sidebar')), + nargs: 1, + requiresArg: true, + type: 'string' + } + }), + handler: argv => run.generate(argv.path, argv.sidebar) + }) .help() .option('help', { alias: 'h', diff --git a/lib/commands/generate.js b/lib/commands/generate.js new file mode 100644 index 0000000..b04a289 --- /dev/null +++ b/lib/commands/generate.js @@ -0,0 +1,79 @@ +'use strict' + +const fs = require('fs') +const os = require('os') +const {cwd, exists} = require('../util') +const chalk = require('chalk') +const path = require('path') +const ignoreFiles = ['_navbar', '_coverpage', '_sidebar'] + +// eslint-disable-next-line +module.exports = function (path = '', sidebar) { + const cwdPath = cwd(path || '.') + + if (exists(cwdPath)) { + if (sidebar) { + const sidebarPath = cwdPath + '/' + sidebar || '_sidebar.md' + + if (!exists(sidebarPath)) { + genSidebar(cwdPath, sidebarPath) + console.log(chalk.green(`Generate sidebar file '${sidebar}' success.`)) + return true + } + + console.log(chalk.red(`${sidebarPath}`) + ' already exists.') + return false + } + } + + console.log(chalk.red(`${cwdPath}`) + ' directory does not exist.') +} + +function genSidebar(cwdPath, sidebarPath) { + let tree = '' + let lastPath = '' + let nodeName = '' + getDirFiles(cwdPath, function (pathname) { + path.relative(pathname, cwdPath) + pathname = pathname.replace(cwdPath + '/', '') + let filename = path.basename(pathname, '.md') + let splitPath = pathname.split(path.sep) + + if (ignoreFiles.indexOf(filename) === -1) { + nodeName = '- [' + filename + '](' + pathname + ')' + os.EOL + } + + if (splitPath.length > 1) { + if (splitPath[0] !== lastPath) { + lastPath = splitPath[0] + tree += os.EOL + '- ' + splitPath[0] + os.EOL + } + + tree += ' ' + nodeName + } else { + if (lastPath !== '') { + lastPath = '' + tree += os.EOL + } + + tree += nodeName + } + }) + fs.writeFile(sidebarPath, tree, 'utf8', err => { + if (err) { + console.log(chalk.red(`Generate sidebar file error, message: ${err.message}`)) + } + }) +} + +function getDirFiles(dir, callback) { + fs.readdirSync(dir).forEach(function (file) { + let pathname = path.join(dir, file) + + if (fs.statSync(pathname).isDirectory()) { + getDirFiles(pathname, callback) + } else if (path.extname(file) === '.md') { + callback(pathname) + } + }) +} diff --git a/lib/index.js b/lib/index.js index 002938f..7e3583f 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,5 +1,6 @@ module.exports = { init: require('./commands/init'), serve: require('./commands/serve'), - start: require('./commands/start') + start: require('./commands/start'), + generate: require('./commands/generate') } diff --git a/tools/locales/en.json b/tools/locales/en.json index 02f915d..f95d400 100644 --- a/tools/locales/en.json +++ b/tools/locales/en.json @@ -10,6 +10,8 @@ "serve.open": "Open docs in default browser. To explicitly set --open to false you may use --no-open.", "serve.port": "Listen port.", "serve.indexname": "Custom filename instead of index.html to serve by default", + "generate": "Docsify's generators", + "generate.sidebar": "Generate sidebar file", "livereload.port": "livereload Listen port.", "usage": "Usage", "version": "Show version number" diff --git a/tools/locales/zh.json b/tools/locales/zh.json index 58a2e68..6244da8 100644 --- a/tools/locales/zh.json +++ b/tools/locales/zh.json @@ -10,6 +10,8 @@ "serve.open": "自动打开浏览器", "serve.port": "设置端口", "serve.indexname": "Custom filename instead of index.html to serve by default", + "generate": "Docsify的生成器", + "generate.sidebar": "生成侧边栏文件", "livereload.port": "设置livereload端口", "usage": "例子", "version": "当前版本号" From cccb1dd929f083ad23bea4889aca1b95ca600c3d Mon Sep 17 00:00:00 2001 From: sy-records <52o@qq52o.cn> Date: Sat, 16 Jan 2021 13:47:15 +0800 Subject: [PATCH 2/4] test: generate _sidebar.md --- e2e/commands/generate.test.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 e2e/commands/generate.test.js diff --git a/e2e/commands/generate.test.js b/e2e/commands/generate.test.js new file mode 100644 index 0000000..7c7e1e8 --- /dev/null +++ b/e2e/commands/generate.test.js @@ -0,0 +1,28 @@ +const test = require('ava') +const fs = require('fs') +const path = require('path') + +const {run} = require('../helpers/test-utils.js') + +const genPath = path.join(__dirname, 'generate-cmd') +const docsPath = path.join(genPath, 'docs') + +test.before('create temp directory', () => { + // Cleanup if the directory already exists + if (fs.existsSync(genPath)) { + fs.rmdirSync(genPath, {recursive: true}) + } + + fs.mkdirSync(genPath) +}) + +test.after('cleanup', () => { + fs.rmdirSync(genPath, {recursive: true}) +}) + +test('generate _sidebar.md', t => { + run(['init', 'docs'], {cwd: genPath}) + run(['generate', 'docs'], {cwd: genPath}) + // Check for existence + t.true(fs.existsSync(path.join(docsPath, '_sidebar.md'))) +}) From 916479a4913b363737b534b9e078bff82edc59f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B2=88=E5=94=81?= <52o@qq52o.cn> Date: Tue, 19 Jan 2021 08:28:43 +0800 Subject: [PATCH 3/4] Apply suggestions from code review Co-authored-by: James George --- README.md | 2 +- lib/commands/generate.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index cb7e1b0..b889eb6 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ docsify serve [--open false] [--port 3000] - Default: `3000` - Description: Choose a listen port, defaults to `3000`. -### `gen` command +### `generate` command Docsify's generators. diff --git a/lib/commands/generate.js b/lib/commands/generate.js index b04a289..a96bc0f 100644 --- a/lib/commands/generate.js +++ b/lib/commands/generate.js @@ -17,16 +17,16 @@ module.exports = function (path = '', sidebar) { if (!exists(sidebarPath)) { genSidebar(cwdPath, sidebarPath) - console.log(chalk.green(`Generate sidebar file '${sidebar}' success.`)) + console.log(chalk.green(`Successfully generated the sidebar file '${sidebar}'.`)) return true } - console.log(chalk.red(`${sidebarPath}`) + ' already exists.') + console.error(chalk.red(`${sidebarPath}`) + ' already exists.') return false } } - console.log(chalk.red(`${cwdPath}`) + ' directory does not exist.') + console.error(chalk.red(`${cwdPath}`) + ' directory does not exist.') } function genSidebar(cwdPath, sidebarPath) { @@ -61,7 +61,7 @@ function genSidebar(cwdPath, sidebarPath) { }) fs.writeFile(sidebarPath, tree, 'utf8', err => { if (err) { - console.log(chalk.red(`Generate sidebar file error, message: ${err.message}`)) + console.error(chalk.red(`Couldn't generate the sidebar file, error: ${err.message}`)) } }) } From ff2c4c11a25b9239a2ded33723b2268785bb5d4e Mon Sep 17 00:00:00 2001 From: sy-records <52o@qq52o.cn> Date: Tue, 19 Jan 2021 08:46:58 +0800 Subject: [PATCH 4/4] test: Add the sidebar file already exists test --- e2e/commands/generate.test.js | 3 +++ lib/commands/generate.js | 2 +- lib/commands/init.js | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/e2e/commands/generate.test.js b/e2e/commands/generate.test.js index 7c7e1e8..4892e15 100644 --- a/e2e/commands/generate.test.js +++ b/e2e/commands/generate.test.js @@ -25,4 +25,7 @@ test('generate _sidebar.md', t => { run(['generate', 'docs'], {cwd: genPath}) // Check for existence t.true(fs.existsSync(path.join(docsPath, '_sidebar.md'))) + + const {stderr} = run(['generate', 'docs'], {cwd: genPath}) + t.is(stderr, 'The sidebar file \'_sidebar.md\' already exists.') }) diff --git a/lib/commands/generate.js b/lib/commands/generate.js index a96bc0f..df572dc 100644 --- a/lib/commands/generate.js +++ b/lib/commands/generate.js @@ -21,7 +21,7 @@ module.exports = function (path = '', sidebar) { return true } - console.error(chalk.red(`${sidebarPath}`) + ' already exists.') + console.error(chalk.red(`The sidebar file '${sidebar}' already exists.`)) return false } } diff --git a/lib/commands/init.js b/lib/commands/init.js index 3d2c451..fca59c2 100644 --- a/lib/commands/init.js +++ b/lib/commands/init.js @@ -22,7 +22,7 @@ module.exports = function (path = '', local, theme) { const cwdPath = cwd(path || '.') if (exists(cwdPath)) { - console.log(chalk.red(`${path || '.'}`) + ' already exists.') + console.log(chalk.red(`${path || '.'} already exists.`)) prompt({ type: 'confirm',