From 4775a2c82de5b53157329e0ae86281da4a583ec2 Mon Sep 17 00:00:00 2001 From: Seaoak Date: Sat, 23 Nov 2019 03:13:16 +0900 Subject: [PATCH] Enable "exclude:" and "include:" options for files in asset folder (fix #3881) --- lib/plugins/processor/asset.js | 6 +---- lib/plugins/processor/common.js | 20 +++++++++++---- lib/plugins/processor/post.js | 2 +- test/scripts/processors/post.js | 43 +++++++++++++++++++++++++++------ 4 files changed, 52 insertions(+), 19 deletions(-) diff --git a/lib/plugins/processor/asset.js b/lib/plugins/processor/asset.js index 302f20a7c7..e7131d579f 100644 --- a/lib/plugins/processor/asset.js +++ b/lib/plugins/processor/asset.js @@ -108,11 +108,7 @@ module.exports = ctx => { return { pattern: new Pattern(path => { - if (common.isTmpFile(path) || common.isMatch(path, ctx.config.exclude)) return; - - if (common.isHiddenFile(path) && !common.isMatch(path, ctx.config.include)) { - return; - } + if (common.isExcludedFile(path, ctx.config)) return; return { renderable: ctx.render.isRenderable(path) && !common.isMatch(path, ctx.config.skip_render) diff --git a/lib/plugins/processor/common.js b/lib/plugins/processor/common.js index edf32c3a41..900df605b2 100644 --- a/lib/plugins/processor/common.js +++ b/lib/plugins/processor/common.js @@ -6,6 +6,12 @@ const micromatch = require('micromatch'); const DURATION_MINUTE = 1000 * 60; +function isMatch(path, patterns) { + if (!patterns) return false; + + return micromatch.isMatch(path, patterns); +} + function isTmpFile(path) { const last = path[path.length - 1]; return last === '%' || last === '~'; @@ -15,6 +21,13 @@ function isHiddenFile(path) { return /(^|\/)[_.]/.test(path); } +function isExcludedFile(path, config) { + if (isTmpFile(path)) return true; + if (isMatch(path, config.exclude)) return true; + if (isHiddenFile(path) && !isMatch(path, config.include)) return true; + return false; +} + exports.ignoreTmpAndHiddenFile = new Pattern(path => { if (isTmpFile(path) || isHiddenFile(path)) return false; return true; @@ -22,6 +35,7 @@ exports.ignoreTmpAndHiddenFile = new Pattern(path => { exports.isTmpFile = isTmpFile; exports.isHiddenFile = isHiddenFile; +exports.isExcludedFile = isExcludedFile; exports.toDate = date => { if (!date || moment.isMoment(date)) return date; @@ -46,8 +60,4 @@ exports.timezone = (date, timezone) => { return new Date(ms - diff); }; -exports.isMatch = (path, patterns) => { - if (!patterns) return false; - - return micromatch.isMatch(path, patterns); -}; +exports.isMatch = isMatch; diff --git a/lib/plugins/processor/post.js b/lib/plugins/processor/post.js index 205c241a0f..973ce580b3 100644 --- a/lib/plugins/processor/post.js +++ b/lib/plugins/processor/post.js @@ -159,7 +159,7 @@ module.exports = ctx => { }).catch(err => { if (err.cause && err.cause.code === 'ENOENT') return []; throw err; - }).filter(item => !common.isTmpFile(item) && !common.isHiddenFile(item)).map(item => { + }).filter(item => !common.isExcludedFile(item, ctx.config)).map(item => { const id = join(assetDir, item).substring(baseDirLength).replace(/\\/g, '/'); const asset = PostAsset.findById(id); if (asset) return undefined; diff --git a/test/scripts/processors/post.js b/test/scripts/processors/post.js index fc770dd559..a31e296b89 100644 --- a/test/scripts/processors/post.js +++ b/test/scripts/processors/post.js @@ -791,6 +791,8 @@ describe('post', () => { it('post - post_asset_folder enabled', () => { hexo.config.post_asset_folder = true; + hexo.config.exclude = ['**.png']; + hexo.config.include = ['**/_fizz.*']; const body = [ 'title: "Hello world"', @@ -804,27 +806,52 @@ describe('post', () => { renderable: true }); - const assetId = 'source/_posts/foo/bar.jpg'; - const assetPath = pathFn.join(hexo.base_dir, assetId); + const assetFiles = [ + 'bar.jpg', + 'baz.png', + '_fizz.jpg', + '_buzz.jpg' + ].map(filename => { + const id = `source/_posts/foo/${filename}`; + const path = pathFn.join(hexo.base_dir, id); + const contents = filename.replace(/\.\w+$/, ''); + return { + id, + path, + contents + }; + }); return Promise.all([ fs.writeFile(file.source, body), - fs.writeFile(assetPath, '') + ...assetFiles.map(obj => fs.writeFile(obj.path, obj.contents)) ]).then(() => process(file)).then(() => { const post = Post.findOne({source: file.path}); - const asset = PostAsset.findById(assetId); + const assets = assetFiles.map(obj => PostAsset.findById(obj.id)); - asset._id.should.eql(assetId); - asset.post.should.eql(post._id); - asset.modified.should.be.true; + [assets[0]].should.not.eql([undefined]); + assets[0]._id.should.eql(assetFiles[0].id); + assets[0].post.should.eql(post._id); + assets[0].modified.should.be.true; + + [assets[1]].should.eql([undefined]); + + [assets[2]].should.not.eql([undefined]); + assets[2]._id.should.eql(assetFiles[2].id); + assets[2].post.should.eql(post._id); + assets[2].modified.should.be.true; + + [assets[3]].should.eql([undefined]); return post.remove(); }).finally(() => { hexo.config.post_asset_folder = false; + hexo.config.exclude = undefined; + hexo.config.include = undefined; return Promise.all([ fs.unlink(file.source), - fs.unlink(assetPath) + ...assetFiles.map(obj => fs.unlink(obj.path)) ]); }); });