diff --git a/lib/box/index.ts b/lib/box/index.ts index 4da7c69d4e..d2cbf7022b 100644 --- a/lib/box/index.ts +++ b/lib/box/index.ts @@ -113,7 +113,7 @@ class Box extends EventEmitter { const src = join(this.base, path); return Cache.compareFile( - escapeBackslash(src.substring(ctx.base_dir.length)), + src.substring(ctx.base_dir.length), () => getHash(src), () => stat(src) ).then(result => ({ @@ -129,7 +129,7 @@ class Box extends EventEmitter { if (!stats.isDirectory()) return; // Check existing files in cache - const relativeBase = escapeBackslash(base.substring(ctx.base_dir.length)); + const relativeBase = base.substring(ctx.base_dir.length); const cacheFiles = Cache.filter(item => item._id.startsWith(relativeBase)).map(item => item._id.substring(relativeBase.length)); // Handle deleted files @@ -156,11 +156,12 @@ class Box extends EventEmitter { }); return BlueBirdPromise.reduce(this.processors, (count, processor) => { - const params = processor.pattern.match(path); + // patten supports *nix style path only, replace backslashes on Windows + const params = processor.pattern.match(escapeBackslash(path)); if (!params) return count; const file = new File({ - // source is used for filesystem path, keep backslashes on Windows + // source is used for file system path, keep backslashes on Windows source: join(base, path), // path is used for URL path, replace backslashes on Windows path: escapeBackslash(path), @@ -194,7 +195,7 @@ class Box extends EventEmitter { const { base } = this; function getPath(path) { - return escapeBackslash(path.substring(base.length)); + return path.substring(base.length); } return this.process().then(() => watch(base, this.options)).then(watcher => { @@ -214,7 +215,7 @@ class Box extends EventEmitter { watcher.on('addDir', path => { let prefix = getPath(path); - if (prefix) prefix += '/'; + if (prefix) prefix += sep; this._readDir(path, prefix); }); @@ -287,7 +288,7 @@ function readDirWalker(ctx: Hexo, base: string, results: any[], ignore: any, pre const prefixPath = `${prefix}${path}`; if (stats) { if (stats.isDirectory()) { - return readDirWalker(ctx, fullpath, results, ignore, `${prefixPath}/`); + return readDirWalker(ctx, fullpath, results, ignore, prefixPath + sep); } if (!isIgnoreMatch(fullpath, ignore)) { results.push(prefixPath); diff --git a/lib/plugins/processor/asset.ts b/lib/plugins/processor/asset.ts index c56ff62052..48ccd1401d 100644 --- a/lib/plugins/processor/asset.ts +++ b/lib/plugins/processor/asset.ts @@ -109,7 +109,7 @@ function processPage(ctx: Hexo, file: _File) { } function processAsset(ctx: Hexo, file: _File) { - const id = relative(ctx.base_dir, file.source).replace(/\\/g, '/'); + const id = relative(ctx.base_dir, file.source); const Asset = ctx.model('Asset'); const doc = Asset.findById(id); diff --git a/lib/plugins/processor/post.ts b/lib/plugins/processor/post.ts index ea8762944a..5d1367eea0 100644 --- a/lib/plugins/processor/post.ts +++ b/lib/plugins/processor/post.ts @@ -233,7 +233,7 @@ function scanAssetDir(ctx: Hexo, post) { if (err && err.code === 'ENOENT') return []; throw err; }).filter(item => !isExcludedFile(item, ctx.config)).map(item => { - const id = join(assetDir, item).substring(baseDirLength).replace(/\\/g, '/'); + const id = join(assetDir, item).substring(baseDirLength); const renderablePath = id.substring(sourceDirLength + 1); const asset = PostAsset.findById(id); @@ -267,7 +267,7 @@ function shouldSkipAsset(ctx: Hexo, post, asset) { function processAsset(ctx: Hexo, file: _File) { const PostAsset = ctx.model('PostAsset'); const Post = ctx.model('Post'); - const id = file.source.substring(ctx.base_dir.length).replace(/\\/g, '/'); + const id = file.source.substring(ctx.base_dir.length); const doc = PostAsset.findById(id); if (file.type === 'delete') { diff --git a/lib/theme/processors/source.ts b/lib/theme/processors/source.ts index ac8c21a1fe..c82d4352c9 100644 --- a/lib/theme/processors/source.ts +++ b/lib/theme/processors/source.ts @@ -4,7 +4,7 @@ import type { _File } from '../../box'; function process(file: _File) { const Asset = this.model('Asset'); - const id = file.source.substring(this.base_dir.length).replace(/\\/g, '/'); + const id = file.source.substring(this.base_dir.length); const { path } = file.params; const doc = Asset.findById(id); diff --git a/test/scripts/box/box.ts b/test/scripts/box/box.ts index d6d3d35b57..55331677f2 100644 --- a/test/scripts/box/box.ts +++ b/test/scripts/box/box.ts @@ -120,7 +120,7 @@ describe('Box', () => { const box = newBox('test'); const name = 'a.txt'; const path = join(box.base, name); - const cacheId = 'test/' + name; + const cacheId = join('test/', name); const processor = spy(); box.addProcessor(processor); @@ -144,7 +144,7 @@ describe('Box', () => { const box = newBox('test'); const name = 'a.txt'; const path = join(box.base, name); - const cacheId = 'test/' + name; + const cacheId = join('test/', name); const processor = spy(); box.addProcessor(processor); @@ -167,7 +167,7 @@ describe('Box', () => { const box = newBox('test'); const name = 'a.txt'; const path = join(box.base, name); - const cacheId = 'test/' + name; + const cacheId = join('test/', name); const processor = spy(); box.addProcessor(processor); @@ -190,7 +190,7 @@ describe('Box', () => { const box = newBox('test'); const name = 'a.txt'; const path = join(box.base, name); - const cacheId = 'test/' + name; + const cacheId = join('test/', name); const processor = spy(); box.addProcessor(processor); @@ -211,7 +211,8 @@ describe('Box', () => { it('process() - delete', async () => { const box = newBox('test'); - const cacheId = 'test/a.txt'; + // join will replace backslashes on Windows + const cacheId = join('test/', 'a.txt'); const processor = spy(); box.addProcessor(processor); diff --git a/test/scripts/processors/asset.ts b/test/scripts/processors/asset.ts index 1e78bc44b1..127c9df08f 100644 --- a/test/scripts/processors/asset.ts +++ b/test/scripts/processors/asset.ts @@ -80,7 +80,7 @@ describe('asset', () => { await writeFile(file.source, 'foo'); await process(file); - const id = 'source/' + file.path; + const id = join('source/', file.path); const asset = Asset.findById(id); asset._id.should.eql(id); @@ -103,7 +103,7 @@ describe('asset', () => { await writeFile(file.source, 'foo'); await process(file); - const id = '../source/foo.jpg'; // The id should a relative path,because the 'lib/models/assets.js' use asset path by joining base path with "_id" directly. + const id = join('../source/', 'foo.jpg'); // The id should a relative path, because the 'lib/models/assets.js' use asset path by joining base path with "_id" directly. const asset = Asset.findById(id); asset._id.should.eql(id); asset.path.should.eql(file.path); @@ -122,7 +122,7 @@ describe('asset', () => { renderable: false }); - const id = 'source/' + file.path; + const id = join('source/', file.path); await Promise.all([ writeFile(file.source, 'test'), @@ -153,7 +153,7 @@ describe('asset', () => { renderable: false }); - const id = 'source/' + file.path; + const id = join('source/', file.path); await Promise.all([ writeFile(file.source, 'test'), @@ -179,7 +179,7 @@ describe('asset', () => { renderable: false }); - const id = 'source/' + file.path; + const id = join('source/', file.path); await Asset.insert({ _id: id, @@ -197,7 +197,7 @@ describe('asset', () => { renderable: false }); - const id = 'source/' + file.path; + const id = join('source/', file.path); await process(file); should.not.exist(Asset.findById(id)); diff --git a/test/scripts/processors/post.ts b/test/scripts/processors/post.ts index 3bc59bba80..c19f2f2c9c 100644 --- a/test/scripts/processors/post.ts +++ b/test/scripts/processors/post.ts @@ -118,7 +118,7 @@ describe('post', () => { }); await process(file); - const id = 'source/' + file.path; + const id = join('source/', file.path); should.not.exist(PostAsset.findById(id)); }); @@ -141,7 +141,7 @@ describe('post', () => { const postId = doc._id; await process(file); - const id = 'source/' + file.path; + const id = join('source/', file.path); const asset = PostAsset.findById(id); asset._id.should.eql(id); @@ -165,7 +165,7 @@ describe('post', () => { renderable: false }); - const id = 'source/' + file.path; + const id = join('source/', file.path); const post = await Post.insert({ source: '_posts/foo.html', @@ -200,7 +200,7 @@ describe('post', () => { renderable: false }); - const id = 'source/' + file.path; + const id = join('source/', file.path); const post = await Post.insert({ source: '_posts/foo.html', @@ -235,7 +235,7 @@ describe('post', () => { renderable: false }); - const id = 'source/' + file.path; + const id = join('source/', file.path); const post = await Post.insert({ source: '_posts/foo.html', @@ -265,7 +265,7 @@ describe('post', () => { renderable: false }); - const id = 'source/' + file.path; + const id = join('source/', file.path); const post = await Post.insert({ source: '_posts/foo.html', @@ -290,7 +290,7 @@ describe('post', () => { renderable: false }); - const id = 'source/' + file.path; + const id = join('source/', file.path); await writeFile(file.source, 'test'); await process(file); @@ -309,7 +309,7 @@ describe('post', () => { renderable: false }); - const id = 'source/' + file.path; + const id = join('source/', file.path); await Promise.all([ writeFile(file.source, 'test'), @@ -966,7 +966,7 @@ describe('post', () => { '_fizz.jpg', '_buzz.jpg' ].map(filename => { - const id = `source/_posts/foo/${filename}`; + const id = join('source/_posts/foo/', filename); const path = join(hexo.base_dir, id); const contents = filename.replace(/\.\w+$/, ''); return { @@ -1022,7 +1022,8 @@ describe('post', () => { renderable: true }); - const assetId = 'source/_posts/foo/bar.jpg'; + // join will replace backslashes on Windows + const assetId = join('source/_posts/foo/', 'bar.jpg'); const assetPath = join(hexo.base_dir, assetId); await Promise.all([ @@ -1068,7 +1069,8 @@ describe('post', () => { renderable: true }); - const assetId = 'source/_posts/foo/bar.jpg'; + // join will replace backslashes on Windows + const assetId = join('source/_posts/foo/', 'bar.jpg'); const assetPath = join(hexo.base_dir, assetId); await Promise.all([ @@ -1106,7 +1108,8 @@ describe('post', () => { renderable: true }); - const assetId = 'source/_posts/foo/bar.jpg'; + // join will replace backslashes on Windows + const assetId = join('source/_posts/foo/', 'bar.jpg'); const assetPath = join(hexo.base_dir, assetId); await Promise.all([ @@ -1283,7 +1286,7 @@ describe('post', () => { writeFile(assetFile.source, 'test') ]); await process(file); - const id = 'source/' + assetFile.path; + const id = join('source/', assetFile.path); const post = Post.findOne({ source: file.path }); PostAsset.findById(id).renderable.should.be.true; @@ -1319,7 +1322,7 @@ describe('post', () => { writeFile(assetFile.source, 'test') ]); await process(file); - const id = 'source/' + assetFile.path; + const id = join('source/', assetFile.path); const post = Post.findOne({ source: file.path }); PostAsset.findById(id).renderable.should.be.false; diff --git a/test/scripts/theme_processors/source.ts b/test/scripts/theme_processors/source.ts index 9b4f6f2979..5d9343b239 100644 --- a/test/scripts/theme_processors/source.ts +++ b/test/scripts/theme_processors/source.ts @@ -56,7 +56,7 @@ describe('source', () => { type: 'create' }); - const id = 'themes/test/' + file.path; + const id = join('themes/test/', file.path); await writeFile(file.source, 'test'); await process(file); @@ -77,7 +77,7 @@ describe('source', () => { type: 'update' }); - const id = 'themes/test/' + file.path; + const id = join('themes/test/', file.path); await Promise.all([ writeFile(file.source, 'test'), @@ -104,7 +104,7 @@ describe('source', () => { type: 'skip' }); - const id = 'themes/test/' + file.path; + const id = join('themes/test/', file.path); await Promise.all([ writeFile(file.source, 'test'), @@ -130,7 +130,7 @@ describe('source', () => { type: 'delete' }); - const id = 'themes/test/' + file.path; + const id = join('themes/test/', file.path); await Asset.insert({ _id: id, @@ -146,7 +146,7 @@ describe('source', () => { type: 'delete' }); - const id = 'themes/test/' + file.path; + const id = join('themes/test/', file.path); await process(file); should.not.exist(Asset.findById(id));