refactor(model): add Code model for include_code tag#5633
refactor(model): add Code model for include_code tag#5633D-Sketon wants to merge 12 commits intohexojs:masterfrom
Conversation
How to testgit clone -b fix/code https://github.com/D-Sketon/hexo.git
cd hexo
npm install
npm test |
|
I'm not sure the files in code_dir need to be written to the public folder |
Pull Request Test Coverage Report for Build 18804435888Details
💛 - Coveralls |
| const Code = new warehouse.Schema<CodeSchema>({ | ||
| _id: { type: String, required: true }, | ||
| path: { type: String, required: true }, | ||
| slug: { type: String, required: true }, |
There was a problem hiding this comment.
Because the same value is already set in path, I don't think slug is necessary. Though the difference may be slight, reducing the elements in Schema<CodeSchema> should have a positive effect on performance.
However, if we remove the slug, it could potentially be a breaking change since there may be users referencing it in custom scripts or etc..., so it might require an announcement.
There was a problem hiding this comment.
Pull Request Overview
This PR introduces a new Code model and associated functionality to support the include_code tag in Hexo. The changes address issues #5479 and #5486 by creating a separate processing pipeline for code files that doesn't interfere with the existing page/asset processing.
- Adds a new Code model with processor, generator, and comprehensive test coverage
- Updates the
include_codetag to use the Code model instead of the Page model - Modifies asset processor to exclude code directory files from asset processing
Reviewed Changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/models/code.ts | Defines the new Code model schema with required fields and virtual source property |
| lib/plugins/processor/code.ts | Processes files in the code directory and manages Code model entries |
| lib/plugins/generator/code.ts | Generates code files and handles cleanup of non-existent files |
| lib/plugins/tag/include_code.ts | Updates to use Code model instead of Page model for finding code files |
| lib/plugins/processor/asset.ts | Excludes code directory files from asset processing |
| lib/types.ts | Adds CodeSchema interface definition |
| test/scripts/tags/include_code.ts | Adds test for .j2 file extension support |
| test/scripts/processors/code.ts | Comprehensive tests for code processor functionality |
| test/scripts/models/code.ts | Tests for Code model validation and behavior |
| test/scripts/generators/code.ts | Tests for code generator functionality |
Comments suppressed due to low confidence (2)
test/scripts/tags/include_code.ts:10
- [nitpick] The test suite name 'include_code_js' is misleading as it doesn't specifically test JavaScript files. Consider renaming to 'include_code' or 'include_code_original' to better reflect what it tests.
describe('include_code_js', () => {
test/scripts/tags/include_code.ts:228
- [nitpick] The test suite name 'include_code_j2' is inconsistent with the naming pattern. Consider using a more descriptive name like 'include_code - jinja2 files' to clarify the purpose.
describe('include_code_j2', () => {
| return Promise.filter(this.model('Code').toArray(), (code: Document<CodeSchema>) => exists(code.source).tap(exist => { | ||
| if (!exist) return code.remove(); | ||
| })).map((code: Document<CodeSchema>) => { |
There was a problem hiding this comment.
This implementation checks file existence for every code file on each generation. Consider implementing a more efficient approach that only checks existence when files are modified or caches the results.
| return Promise.filter(this.model('Code').toArray(), (code: Document<CodeSchema>) => exists(code.source).tap(exist => { | |
| if (!exist) return code.remove(); | |
| })).map((code: Document<CodeSchema>) => { | |
| const fileExistenceCache: Record<string, boolean> = {}; | |
| return Promise.filter(this.model('Code').toArray(), (code: Document<CodeSchema>) => { | |
| if (!code.modified && fileExistenceCache[code.source] !== undefined) { | |
| // Use cached result if file is not modified | |
| return Promise.resolve(fileExistenceCache[code.source]); | |
| } | |
| // Check file existence and update cache | |
| return exists(code.source).tap(exist => { | |
| fileExistenceCache[code.source] = exist; | |
| if (!exist) return code.remove(); | |
| }); | |
| }).map((code: Document<CodeSchema>) => { |
| function codeGenerator(this: Hexo): Promise<any[]> { | ||
| return Promise.filter(this.model('Code').toArray(), (code: Document<CodeSchema>) => exists(code.source).tap(exist => { | ||
| if (!exist) return code.remove(); | ||
| })).map((code: Document<CodeSchema>) => { | ||
| const { path } = code; | ||
| const data: CodeData = { | ||
| modified: code.modified, | ||
| data: code.content | ||
| }; | ||
|
|
||
| return { path, data }; | ||
| }); | ||
|
|
There was a problem hiding this comment.
The returned object structure is inconsistent with other generators. Consider adding a comment explaining why this generator returns a different structure or align it with the BaseGeneratorReturn interface.
| function codeGenerator(this: Hexo): Promise<any[]> { | |
| return Promise.filter(this.model('Code').toArray(), (code: Document<CodeSchema>) => exists(code.source).tap(exist => { | |
| if (!exist) return code.remove(); | |
| })).map((code: Document<CodeSchema>) => { | |
| const { path } = code; | |
| const data: CodeData = { | |
| modified: code.modified, | |
| data: code.content | |
| }; | |
| return { path, data }; | |
| }); | |
| interface BaseGeneratorReturn { | |
| path: string; | |
| data: { | |
| modified: boolean; | |
| data: string; | |
| }; | |
| } | |
| function codeGenerator(this: Hexo): Promise<BaseGeneratorReturn[]> { | |
| return Promise.filter(this.model('Code').toArray(), (code: Document<CodeSchema>) => exists(code.source).tap(exist => { | |
| if (!exist) return code.remove(); | |
| })).map((code: Document<CodeSchema>) => { | |
| const { path } = code; | |
| const data: BaseGeneratorReturn['data'] = { | |
| modified: code.modified, | |
| data: code.content | |
| }; | |
| return { path, data }; | |
| }); |
What does it do?
try to fix #5479 and #5486
ref #5479 (comment)
Since the current model doesn't satisfy
include_code, I experimentally added the Code ModelScreenshots
Pull request tasks