From e4963d88a9b192c4e241c4cc2bcd08c20b72c12e Mon Sep 17 00:00:00 2001 From: Tevin Date: Fri, 21 Jul 2017 22:57:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E5=96=84=20Mac=20=E4=B8=8A=E7=82=B9?= =?UTF-8?q?=E5=8F=B7=E5=BC=80=E5=A4=B4=E7=9A=84=E6=96=87=E4=BB=B6=E5=B8=A6?= =?UTF-8?q?=E6=9D=A5=E7=9A=84=E8=AF=B8=E5=A4=9A=E9=97=AE=E9=A2=98=20#67?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bin/main.js | 3 +- build/creator.js | 9 +-- build/exportGithub.js | 34 ++++------ build/makeMounts.js | 2 +- build/manageFolder.js | 151 +++++++++++++++++++++++++++++------------- lib/main.js | 2 +- 6 files changed, 121 insertions(+), 80 deletions(-) diff --git a/bin/main.js b/bin/main.js index 69408e5..0f84530 100644 --- a/bin/main.js +++ b/bin/main.js @@ -155,8 +155,7 @@ co(function*() { if (typeof outPath === 'undefined') { outPath = yield prompt2('请输入导出文件夹:'); } - outPath = outPath.replace(/\\/g, '/'); - yield exportGithub.export(root, outPath); + yield exportGithub.export(root, outPath.replace(/\\/g, '/')); break; //显示版本号 case 'version': diff --git a/build/creator.js b/build/creator.js index 7dfd781..179738f 100644 --- a/build/creator.js +++ b/build/creator.js @@ -6,6 +6,7 @@ const fs = require('fs'); const co = require('../modules/co'); const mngWiki = require('./manageWiki'); +const mngFolder = require('./manageFolder'); const makeNav = require('./makeNavigation'); const creator = (function () { @@ -212,13 +213,7 @@ const creator = (function () { return co(function*() { const {options, config} = yield that._checkConfig(configPath, filesPath); //开始创建 - let files = []; - //忽略点开头的文件 - fs.readdirSync(options.outputPath).forEach(function (file) { - if (file.indexOf('.') != 0) { - files.push(file); - } - }); + const files = mngFolder.readFolder(options.outputPath); if (files.length > 1) { if (!(yield confirm2('此处已有一些文件或文件夹,是否仍然在此创建amWiki?'))) { return false; diff --git a/build/exportGithub.js b/build/exportGithub.js index 388f3c6..b1d880a 100644 --- a/build/exportGithub.js +++ b/build/exportGithub.js @@ -66,10 +66,10 @@ const exportGithub = (function () { navigation = navigation.replace('?file=' + path, this._githubUrl + 'wiki/' + name); } navigation = navigation - .replace('?file=首页', this._githubUrl + 'wiki') - .replace('#### [首页]', '## WIKI 导航\n\n##### [首页]'); + .replace(/\?file=(home[-_].*?\))|(首页\))/, this._githubUrl + 'wiki)') + .replace(/#### \[(.*?)]/, '## WIKI 导航\n\n##### [$1]'); navigation += '\n\n﹊﹊﹊﹊﹊﹊﹊﹊﹊﹊ \n' + - '**This wiki is created by [[amWiki](https://github.com/TevinLi/amWiki)]**'; + '**This wiki is created by [[amWiki](http://amwiki.org)]**'; fs.writeFileSync(pathTo + '/_Sidebar.md', navigation, 'utf-8'); }, /** @@ -79,7 +79,12 @@ const exportGithub = (function () { * @private */ _exportHome: function (pathFrom, pathTo) { - let file = fs.readFileSync(pathFrom + '/首页.md', 'utf-8'); + let file = null; + for (let fileName of mngFolder.readFolder(pathFrom)) { + if (/^home[-_].*?\.md$/.test(fileName) || fileName === '首页.md') { + file = fs.readFileSync(pathFrom + '/' + fileName, 'utf-8'); + } + } file = file //相对路径图片地址转换 .replace(/!\[(.*?)]\(assets(.*?)\)/g, '![$1](' + this._githubUrl + 'wiki/images$2)') @@ -88,7 +93,7 @@ const exportGithub = (function () { .replace(/ { - this._copyImg(pathFrom + '../amWiki/images/logo.png', pathTo + '\\images\\amWiki-logo.png'); + this._copyImg(pathFrom + '../amWiki/images/logo.png', pathTo + '/images/amWiki-logo.png'); return this._githubUrl + 'wiki/images/amWiki-logo.png'; }); fs.writeFileSync(pathTo + '/Home.md', file, 'utf-8'); @@ -103,23 +108,8 @@ const exportGithub = (function () { if (!fs.existsSync(pathTo + '/images/')) { fs.mkdirSync(pathTo + '/images/', 0o777); } - //文件夹拷贝 - const copyFolder = (from, to) => { - const list = fs.readdirSync(from); - let path, to2; - for (let item of list) { - path = from + '/' + item; - to2 = to + '/' + item; - if (fs.statSync(path).isDirectory(path)) { - fs.mkdirSync(to2, 0o777); - copyFolder(path, to + '/' + item); - } else { - this._copyImg(path, to + '/' + item); - } - } - }; if (fs.existsSync(pathFrom + '../assets/')) { - copyFolder(pathFrom + '../assets/', pathTo + '/images/'); + mngFolder.copyFolder(pathFrom + '../assets/', pathTo + '/images/'); } }, /** @@ -190,7 +180,7 @@ const exportGithub = (function () { _toExport: function (pathFrom, pathTo, fileList, duplicates) { const that = this; return co(function* () { - if (fs.readdirSync(pathTo).length > 0 && (yield confirm2('所选导出文件夹不为空,是否需要清空?'))) { + if (mngFolder.readFolder(pathTo).length > 0 && (yield confirm2('所选导出文件夹不为空,是否需要清空?'))) { mngFolder.cleanFolder(pathTo); } let fileList2 = []; diff --git a/build/makeMounts.js b/build/makeMounts.js index a055bc2..2158ac5 100644 --- a/build/makeMounts.js +++ b/build/makeMounts.js @@ -92,7 +92,7 @@ const makeMounts = (function () { * @private */ _getHomeMount: function (libPath) { - var list = fs.readdirSync(libPath); + const list = mngFolder.readFolder(libPath); for (let name of list) { if (/^home[-_].*?\.md$/.test(name) || name === '首页.md') { const homePath = libPath + name; diff --git a/build/manageFolder.js b/build/manageFolder.js index 153171f..b0a78ec 100644 --- a/build/manageFolder.js +++ b/build/manageFolder.js @@ -7,6 +7,35 @@ const fs = require('fs'); const manageFolder = (function () { return { + /** + * 判断一个文件夹是否为 amWiki 文库项目 + * @param {String} path - 需要判断的文件夹路径 + * @returns {Boolean|String} 判断为否时返回 false,判断为真时返回项目根目录的路径 + * @public + */ + isAmWiki: function (path) { + if (!path && typeof path !== 'string') { + return false; + } + path = path.replace(/\\/g, '/'); + path = path.indexOf('config.json') < 0 ? path : path.split('config.json')[0]; + path = path.indexOf('index.html') < 0 ? path : path.split('index.html')[0]; + //获取 library 路径 + path = this.getProjectFolder(path); + if (!path) { + return false; + } + //通过识别文件夹子项来判定 + else { + let states = [ + fs.existsSync(path + 'library/'), + fs.existsSync(path + 'amWiki/'), + fs.existsSync(path + 'config.json'), + fs.existsSync(path + 'index.html') + ]; + return states[0] && states[1] && states[2] && states[3] ? path : false; + } + }, /** * 递归分析指定文件夹下的目录结构 * @param {String} dirPath - 指定要分析的目录 @@ -20,15 +49,11 @@ const manageFolder = (function () { _listSubFolder: function (dirPath, depth = 0, tree = {}, list = [], files = []) { try { let filePath; - for (let fileName of fs.readdirSync(dirPath)) { + for (let fileName of this.readFolder(dirPath)) { //文件路径 filePath = dirPath + (depth > 0 ? '/' : '') + fileName; - //跳过点号开头的系统保留文件 - if (/^\./.test(fileName)) { - continue; - } //文件夹及其递归处理 - if (fs.statSync(filePath).isDirectory(filePath)) { + if (this.isFolder(filePath)) { //读取下一级数据 const [tempTree, tempList, tempFiles] = this._listSubFolder(filePath, depth + 1); //记录子级的树形 @@ -78,7 +103,7 @@ const manageFolder = (function () { return []; } const tree = {}; - for (let fileName of fs.readdirSync(path)) { + for (let fileName of this.readFolder(path)) { if (/^home[-_].*?\.md$/.test(fileName) || fileName === '首页.md') { tree[fileName] = false; break; @@ -87,21 +112,47 @@ const manageFolder = (function () { return this._listSubFolder(path, 0, tree); }, /** - * 递归清空文件夹 - * @param {String} path - 要清空的文件夹 + * fs 同步读取文件夹改进版,忽略以点开头的文件 + * (比如 Mac 的 .DS_Store 文件) + * @param {String} path + * @param {Boolean} [force] - 是否强制读取文件夹内所有内容 + * @returns {Array} * @public */ - cleanFolder: function (path) { - const list = fs.readdirSync(path); + readFolder: function (path, force) { + let files = []; + try { + if (force === true) { + files = fs.readdirSync(path); + } else { + fs.readdirSync(path).forEach(function (fileName) { + //忽略点开头的文件 + if (fileName.indexOf('.') !== 0) { + files.push(fileName); + } + }); + } + } catch (e) {} + return files; + }, + /** + * 递归清空文件夹 + * @param {String} path - 要清空的文件夹 + * @param {Boolean} [force] - 是否强制清理文件夹内所有文件 + * @public + */ + cleanFolder: function (path, force) { + const list = this.readFolder(path, force); let path2; for (let item of list) { - path2 = path.replace(/[\\\/]?&/, '/') + item; - if (fs.statSync(path2).isDirectory(path2)) { - if (item.indexOf('.') !== 0) { //跳过特殊文件夹 - this.cleanFolder(path2); - fs.rmdirSync(path2); - } - } else { + path2 = path.replace(/\\?$/, '/') + item; + //文件夹,递归删除 + if (this.isFolder(path2)) { + this.cleanFolder(path2, true); + fs.rmdirSync(path2); + } + //文件 + else { fs.unlinkSync(path2); } } @@ -125,6 +176,41 @@ const manageFolder = (function () { } } }, + /** + * 深度拷贝一个文件夹到指定位置 + * @param {String} from + * @param {String} to + * @public + */ + copyFolder: function (from, to) { + const list = this.readFolder(from); + let from2, to2; + for (let item of list) { + from2 = from + '/' + item; + to2 = to + '/' + item; + if (this.isFolder(from2)) { + this.createFolder(to2); + this.copyFolder(from2, to2); + } else { + fs.createReadStream(from2).pipe(fs.createWriteStream(to2)); + } + } + }, + /** + * 判断一个地址是否为文件夹 + * @param {String} path + * @returns {Boolean} + * @public + */ + isFolder: function (path) { + let state; + try { + state = fs.statSync(path).isDirectory(path); + } catch (e) { + state = false; + } + return state; + }, /** * 获取项目文件夹 * @param {String} path - 需要计算的文件夹路径 @@ -214,35 +300,6 @@ const manageFolder = (function () { } } return path.substr(libPath.length).split(/[-_]/)[0]; - }, - /** - * 判断一个文件夹是否为 amWiki 文库项目 - * @param {String} path - 需要判断的文件夹路径 - * @returns {Boolean|String} 判断为否时返回 false,判断为真时返回项目根目录的路径 - * @public - */ - isAmWiki: function (path) { - if (!path && typeof path !== 'string') { - return false; - } - path = path.replace(/\\/g, '/'); - path = path.indexOf('config.json') < 0 ? path : path.split('config.json')[0]; - path = path.indexOf('index.html') < 0 ? path : path.split('index.html')[0]; - //获取 library 路径 - path = this.getProjectFolder(path); - if (!path) { - return false; - } - //通过识别文件夹子项来判定 - else { - let states = [ - fs.existsSync(path + 'library/'), - fs.existsSync(path + 'amWiki/'), - fs.existsSync(path + 'config.json'), - fs.existsSync(path + 'index.html') - ]; - return states[0] && states[1] && states[2] && states[3] ? path : false; - } } }; })(); diff --git a/lib/main.js b/lib/main.js index 6724ca8..ed6c3ff 100644 --- a/lib/main.js +++ b/lib/main.js @@ -195,7 +195,7 @@ const main = (function () { eDialog.showOpenDialog({properties: ['openDirectory']}, (data) => { if (data && data.length) { //开始导出 - exportGithub.export(root, data[0]); + exportGithub.export(root, data[0].replace(/\\/g, '/')); } }); return;