@@ -6,19 +6,21 @@ import matter from 'gray-matter';
66import { ContextdocsLinter } from './contextdocs_linter' ;
77import { ContextignoreLinter } from './contextignore_linter' ;
88import { getContextFiles , lintFileIfExists , fileExists , printHeader } from './utils/file_utils' ;
9- import { ContextValidator } from './utils/validator' ;
9+ import { ContextValidator , ValidationResult } from './utils/validator' ;
1010
1111export class ContextLinter {
1212 private md : MarkdownIt ;
1313 private contextdocsLinter : ContextdocsLinter ;
1414 private contextignoreLinter : ContextignoreLinter ;
1515 private contextValidator : ContextValidator ;
16+ private missingFieldsSummary : Map < string , string [ ] > ;
1617
1718 constructor ( ) {
1819 this . md = new MarkdownIt ( ) ;
1920 this . contextdocsLinter = new ContextdocsLinter ( ) ;
2021 this . contextignoreLinter = new ContextignoreLinter ( ) ;
2122 this . contextValidator = new ContextValidator ( ) ;
23+ this . missingFieldsSummary = new Map ( ) ;
2224 }
2325
2426 public async lintDirectory ( directoryPath : string , packageVersion : string ) : Promise < boolean > {
@@ -29,6 +31,15 @@ export class ContextLinter {
2931 isValid = await this . handleContextFilesRecursively ( directoryPath ) && isValid ;
3032
3133 console . log ( '\nLinting completed.' ) ;
34+
35+ if ( this . missingFieldsSummary . size > 0 ) {
36+ console . log ( '\nMissing Fields Summary:' ) ;
37+ for ( const [ file , missingFields ] of this . missingFieldsSummary . entries ( ) ) {
38+ console . log ( ` ${ file } :` ) ;
39+ console . log ( ` ${ missingFields . join ( ', ' ) } ` ) ;
40+ }
41+ }
42+
3243 return isValid ;
3344 }
3445
@@ -69,16 +80,18 @@ export class ContextLinter {
6980 private async lintContextFile ( filePath : string ) : Promise < boolean > {
7081 console . log ( `\nLinting file: ${ filePath } ` ) ;
7182 return await lintFileIfExists ( filePath , async ( fileContent ) => {
72- let isValid = false ;
83+ let result : ValidationResult ;
7384 if ( filePath . endsWith ( '.context.md' ) ) {
74- isValid = await this . lintMarkdownFile ( fileContent ) ;
85+ result = await this . lintMarkdownFile ( fileContent , filePath ) ;
7586 } else if ( filePath . endsWith ( '.context.yaml' ) ) {
76- isValid = await this . lintYamlFile ( fileContent ) ;
87+ result = await this . lintYamlFile ( fileContent , filePath ) ;
7788 } else if ( filePath . endsWith ( '.context.json' ) ) {
78- isValid = await this . lintJsonFile ( fileContent ) ;
89+ result = await this . lintJsonFile ( fileContent , filePath ) ;
90+ } else {
91+ result = { isValid : false , coveragePercentage : 0 , missingFields : [ ] } ;
7992 }
80- this . printValidationResult ( isValid , filePath ) ;
81- return isValid ;
93+ this . printValidationResult ( result . isValid , filePath ) ;
94+ return result . isValid ;
8295 } ) || false ;
8396 }
8497
@@ -91,18 +104,27 @@ export class ContextLinter {
91104 }
92105 }
93106
94- private async lintMarkdownFile ( content : string ) : Promise < boolean > {
107+ private async lintMarkdownFile ( content : string , filePath : string ) : Promise < ValidationResult > {
95108 console . log ( ' - Validating Markdown structure' ) ;
96109 console . log ( ' - Checking YAML frontmatter' ) ;
97110
98111 try {
99112 const { data : frontmatterData , content : markdownContent } = matter ( content ) ;
100- const frontmatterValid = await this . contextValidator . validateContextData ( frontmatterData , 'markdown' ) ;
113+ const validationResult = this . contextValidator . validateContextData ( frontmatterData , 'markdown' ) ;
101114 const markdownValid = this . validateMarkdownContent ( markdownContent . trim ( ) ) ;
102- return frontmatterValid && markdownValid ;
115+
116+ if ( validationResult . missingFields . length > 0 ) {
117+ this . missingFieldsSummary . set ( path . basename ( filePath ) , validationResult . missingFields ) ;
118+ }
119+
120+ return {
121+ isValid : validationResult . isValid && markdownValid ,
122+ coveragePercentage : validationResult . coveragePercentage ,
123+ missingFields : validationResult . missingFields
124+ } ;
103125 } catch ( error ) {
104126 console . error ( ` Error parsing Markdown file: ${ error } ` ) ;
105- return false ;
127+ return { isValid : false , coveragePercentage : 0 , missingFields : [ ] } ;
106128 }
107129 }
108130
@@ -138,35 +160,47 @@ export class ContextLinter {
138160 return isValid ;
139161 }
140162
141- private async lintYamlFile ( content : string ) : Promise < boolean > {
163+ private async lintYamlFile ( content : string , filePath : string ) : Promise < ValidationResult > {
142164 console . log ( ' - Validating YAML structure' ) ;
143165
144166 try {
145167 const yamlData = this . parseYaml ( content ) ;
146- return await this . contextValidator . validateContextData ( yamlData , 'yaml' ) ;
168+ const validationResult = this . contextValidator . validateContextData ( yamlData , 'yaml' ) ;
169+
170+ if ( validationResult . missingFields . length > 0 ) {
171+ this . missingFieldsSummary . set ( path . basename ( filePath ) , validationResult . missingFields ) ;
172+ }
173+
174+ return validationResult ;
147175 } catch ( error ) {
148176 if ( error instanceof yaml . YAMLException ) {
149177 console . error ( ` Error parsing YAML file: ${ this . formatYamlError ( error ) } ` ) ;
150178 } else {
151179 console . error ( ` Error parsing YAML file: ${ error } ` ) ;
152180 }
153- return false ;
181+ return { isValid : false , coveragePercentage : 0 , missingFields : [ ] } ;
154182 }
155183 }
156184
157- private async lintJsonFile ( content : string ) : Promise < boolean > {
185+ private async lintJsonFile ( content : string , filePath : string ) : Promise < ValidationResult > {
158186 console . log ( ' - Validating JSON structure' ) ;
159187
160188 try {
161189 const jsonData = JSON . parse ( content ) as Record < string , unknown > ;
162- return await this . contextValidator . validateContextData ( jsonData , 'json' ) ;
190+ const validationResult = this . contextValidator . validateContextData ( jsonData , 'json' ) ;
191+
192+ if ( validationResult . missingFields . length > 0 ) {
193+ this . missingFieldsSummary . set ( path . basename ( filePath ) , validationResult . missingFields ) ;
194+ }
195+
196+ return validationResult ;
163197 } catch ( error ) {
164198 if ( error instanceof SyntaxError ) {
165199 console . error ( ` Error parsing JSON file: ${ this . formatJsonError ( error , content ) } ` ) ;
166200 } else {
167201 console . error ( ` Error parsing JSON file: ${ error } ` ) ;
168202 }
169- return false ;
203+ return { isValid : false , coveragePercentage : 0 , missingFields : [ ] } ;
170204 }
171205 }
172206
0 commit comments