| 
									
										
										
										
											2022-06-29 19:25:31 +08:00
										 |  |  | import { BettererFileTest } from '@betterer/betterer'; | 
					
						
							| 
									
										
										
										
											2024-11-15 22:01:39 +08:00
										 |  |  | import { ESLint } from 'eslint'; | 
					
						
							| 
									
										
										
										
											2024-11-07 23:31:06 +08:00
										 |  |  | import { promises as fs } from 'fs'; | 
					
						
							| 
									
										
										
										
											2022-02-09 20:41:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-06 18:48:15 +08:00
										 |  |  | // Why are we ignoring these?
 | 
					
						
							| 
									
										
										
										
											2024-02-16 22:35:26 +08:00
										 |  |  | // They're all deprecated/being removed so doesn't make sense to fix types
 | 
					
						
							| 
									
										
										
										
											2023-10-06 18:48:15 +08:00
										 |  |  | const eslintPathsToIgnore = [ | 
					
						
							| 
									
										
										
										
											2024-09-13 16:50:55 +08:00
										 |  |  |   'packages/grafana-ui/src/graveyard', // will be removed alongside angular in Grafana 12
 | 
					
						
							|  |  |  |   'public/app/angular', // will be removed in Grafana 12
 | 
					
						
							|  |  |  |   'public/app/plugins/panel/graph', // will be removed alongside angular in Grafana 12
 | 
					
						
							|  |  |  |   'public/app/plugins/panel/table-old', // will be removed alongside angular in Grafana 12
 | 
					
						
							| 
									
										
										
										
											2023-10-06 18:48:15 +08:00
										 |  |  | ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-15 18:12:56 +08:00
										 |  |  | // Avoid using functions that report the position of the issues, as this causes a lot of merge conflicts
 | 
					
						
							| 
									
										
										
										
											2022-02-09 20:41:39 +08:00
										 |  |  | export default { | 
					
						
							| 
									
										
										
										
											2023-03-29 23:02:53 +08:00
										 |  |  |   'better eslint': () => | 
					
						
							|  |  |  |     countEslintErrors() | 
					
						
							|  |  |  |       .include('**/*.{ts,tsx}') | 
					
						
							| 
									
										
										
										
											2023-10-06 18:48:15 +08:00
										 |  |  |       .exclude(new RegExp(eslintPathsToIgnore.join('|'))), | 
					
						
							| 
									
										
										
										
											2023-05-11 20:26:12 +08:00
										 |  |  |   'no undocumented stories': () => countUndocumentedStories().include('**/!(*.internal).story.tsx'), | 
					
						
							| 
									
										
										
										
											2023-12-15 18:12:56 +08:00
										 |  |  |   'no gf-form usage': () => | 
					
						
							| 
									
										
										
										
											2024-09-13 16:50:55 +08:00
										 |  |  |     regexp(/gf-form/gm, 'gf-form usage has been deprecated. Use a component from @grafana/ui or custom CSS instead.') | 
					
						
							|  |  |  |       .include('**/*.{ts,tsx,html}') | 
					
						
							|  |  |  |       .exclude(new RegExp('packages/grafana-ui/src/themes/GlobalStyles')), | 
					
						
							| 
									
										
										
										
											2022-02-09 20:41:39 +08:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2022-06-29 19:25:31 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | function countUndocumentedStories() { | 
					
						
							|  |  |  |   return new BettererFileTest(async (filePaths, fileTestResult) => { | 
					
						
							| 
									
										
										
										
											2023-03-31 00:11:30 +08:00
										 |  |  |     await Promise.all( | 
					
						
							|  |  |  |       filePaths.map(async (filePath) => { | 
					
						
							|  |  |  |         // look for .mdx import in the story file
 | 
					
						
							| 
									
										
										
										
											2024-02-16 19:13:50 +08:00
										 |  |  |         const mdxImportRegex = new RegExp("^import.*\\.mdx';$", 'gm'); | 
					
						
							|  |  |  |         // Looks for the "autodocs" string in the file
 | 
					
						
							|  |  |  |         const autodocsStringRegex = /autodocs/; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-31 00:11:30 +08:00
										 |  |  |         const fileText = await fs.readFile(filePath, 'utf8'); | 
					
						
							| 
									
										
										
										
											2024-02-16 19:13:50 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         const hasMdxImport = mdxImportRegex.test(fileText); | 
					
						
							|  |  |  |         const hasAutodocsString = autodocsStringRegex.test(fileText); | 
					
						
							|  |  |  |         // If both .mdx import and autodocs string are missing, add an issue
 | 
					
						
							|  |  |  |         if (!hasMdxImport && !hasAutodocsString) { | 
					
						
							| 
									
										
										
										
											2023-03-31 00:11:30 +08:00
										 |  |  |           // In this case the file contents don't matter:
 | 
					
						
							|  |  |  |           const file = fileTestResult.addFile(filePath, ''); | 
					
						
							|  |  |  |           // Add the issue to the first character of the file:
 | 
					
						
							|  |  |  |           file.addIssue(0, 0, 'No undocumented stories are allowed, please add an .mdx file with some documentation'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2022-06-29 19:25:31 +08:00
										 |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-07-04 19:13:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-15 18:12:56 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  *  Generic regexp pattern matcher, similar to @betterer/regexp. | 
					
						
							|  |  |  |  *  The only difference is that the positions of the errors are not reported, as this may cause a lot of merge conflicts. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | function regexp(pattern: RegExp, issueMessage: string) { | 
					
						
							|  |  |  |   return new BettererFileTest(async (filePaths, fileTestResult) => { | 
					
						
							|  |  |  |     await Promise.all( | 
					
						
							|  |  |  |       filePaths.map(async (filePath) => { | 
					
						
							|  |  |  |         const fileText = await fs.readFile(filePath, 'utf8'); | 
					
						
							|  |  |  |         const matches = fileText.match(pattern); | 
					
						
							|  |  |  |         if (matches) { | 
					
						
							|  |  |  |           // File contents doesn't matter, since we're not reporting the position
 | 
					
						
							|  |  |  |           const file = fileTestResult.addFile(filePath, ''); | 
					
						
							|  |  |  |           matches.forEach(() => { | 
					
						
							|  |  |  |             file.addIssue(0, 0, issueMessage); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-04 19:13:20 +08:00
										 |  |  | function countEslintErrors() { | 
					
						
							| 
									
										
										
										
											2024-12-05 20:14:09 +08:00
										 |  |  |   return new BettererFileTest(async (filePaths, fileTestResult) => { | 
					
						
							| 
									
										
										
										
											2024-05-30 17:09:30 +08:00
										 |  |  |     // Just bail early if there's no files to test. Prevents trying to get the base config from failing
 | 
					
						
							|  |  |  |     if (filePaths.length === 0) { | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const runner = new ESLint({ | 
					
						
							| 
									
										
										
										
											2024-12-05 20:14:09 +08:00
										 |  |  |       overrideConfigFile: './.betterer.eslint.config.js', | 
					
						
							| 
									
										
										
										
											2024-11-07 23:31:06 +08:00
										 |  |  |       warnIgnored: false, | 
					
						
							| 
									
										
										
										
											2024-05-30 17:09:30 +08:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const lintResults = await runner.lintFiles(Array.from(filePaths)); | 
					
						
							| 
									
										
										
										
											2024-11-07 23:31:06 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     lintResults.forEach(({ messages, filePath }) => { | 
					
						
							|  |  |  |       const file = fileTestResult.addFile(filePath, ''); | 
					
						
							| 
									
										
										
										
											2025-01-07 22:56:12 +08:00
										 |  |  |       messages | 
					
						
							|  |  |  |         .sort((a, b) => (a.message > b.message ? 1 : -1)) | 
					
						
							|  |  |  |         .forEach((message, index) => { | 
					
						
							|  |  |  |           file.addIssue(0, 0, message.message, `${index}`); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2024-11-07 23:31:06 +08:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2022-07-04 19:13:20 +08:00
										 |  |  |   }); | 
					
						
							|  |  |  | } |