( logger: Logger, projectFolders: string[], )
| 69 | } |
| 70 | |
| 71 | function getAnalysisOptionsExcludedFolders( |
| 72 | logger: Logger, |
| 73 | projectFolders: string[], |
| 74 | ): string[] { |
| 75 | const results: string[] = []; |
| 76 | for (const projectFolder of projectFolders) { |
| 77 | const analysisOptionsPath = path.join(projectFolder, "analysis_options.yaml"); |
| 78 | try { |
| 79 | const analysisOptionsContent = fs.readFileSync(analysisOptionsPath); |
| 80 | const yaml = YAML.parse(analysisOptionsContent.toString()); |
| 81 | const excluded = yaml?.analyzer?.exclude; |
| 82 | if (excluded && Array.isArray(excluded)) { |
| 83 | for (let exclude of excluded as string[]) { |
| 84 | // Only exclude an entire folder if the /** is at the end. If it's |
| 85 | // something like foo/**/*.generated.* then it does not exclude |
| 86 | // everything in foo. |
| 87 | if (exclude.endsWith("/**")) |
| 88 | exclude = exclude.substring(0, exclude.length - 3); |
| 89 | |
| 90 | // Handle relative paths. |
| 91 | if (!exclude.startsWith("/")) |
| 92 | exclude = path.join(projectFolder, exclude); |
| 93 | |
| 94 | // Now, if no wildcards remain in the path, we can use it as an exclusion. |
| 95 | if (!exclude.includes("*")) |
| 96 | results.push(exclude); |
| 97 | } |
| 98 | } |
| 99 | } catch (e: any) { |
| 100 | if (e?.code !== "ENOENT") // Don't warn for missing files. |
| 101 | logger.error(`Failed to read ${analysisOptionsPath}: ${e}`); |
| 102 | } |
| 103 | } |
| 104 | return results; |
| 105 | } |
| 106 | |
| 107 | export class ProjectFinder { |
| 108 | constructor( |
no test coverage detected