From a80980da6ba3542d660715ede1efa829fd402564 Mon Sep 17 00:00:00 2001 From: ValentinVignal Date: Mon, 14 Aug 2023 15:02:24 +0800 Subject: [PATCH 1/9] :alembic: Nested analysis options --- src/utils/IgnoredFiles.ts | 51 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/src/utils/IgnoredFiles.ts b/src/utils/IgnoredFiles.ts index 3ea5687..3587991 100644 --- a/src/utils/IgnoredFiles.ts +++ b/src/utils/IgnoredFiles.ts @@ -1,9 +1,14 @@ import * as fs from 'fs'; import * as yaml from 'js-yaml'; -import * as minimatch from 'minimatch'; +import minimatch from 'minimatch'; import * as path from 'path'; import { actionOptions } from './ActionOptions'; +type AnalysisOptions = { + exclude?: string[]; + include?: string; +} + /** * The ignore files in the analysis_options.yaml */ @@ -12,15 +17,53 @@ export class IgnoredFiles { constructor() { let patterns: string[]; try { - const yamlFile = yaml.load(fs.readFileSync(path.resolve(actionOptions.workingDirectory, 'analysis_options.yaml'), 'utf8')) as { analyzer?: { exclude?: string[] } }; - patterns = yamlFile?.analyzer?.exclude ?? []; + const yamlPath = IgnoredFiles.findClosestYamlFile(actionOptions.workingDirectory); + if (!yamlPath) { + throw new Error(`Could not find any "analysis_options.yaml" in the parent directories of "${actionOptions.workingDirectory}"`); + } + patterns = IgnoredFiles.getIgnoredPatterns(yamlPath); } catch (error) { - console.log('Could not load analysis_options.yaml:\n', error); + console.error('Could not load analysis_options.yaml:\n', error); } patterns ??= []; + console.log('partterns'); + console.log(patterns); this.patterns = patterns.map((pattern) => new minimatch.Minimatch(pattern)); } + /** + * + * @param path + */ + private static findClosestYamlFile(directoryPath: string): string | null { + const yamlPath = path.resolve(directoryPath, 'analysis_options.yaml'); + if (fs.existsSync(yamlPath)) { + return yamlPath; + } else { + const parentDirectoryPath = path.resolve(directoryPath, '..'); + if (parentDirectoryPath === directoryPath) { + return null; + } else { + return IgnoredFiles.findClosestYamlFile(parentDirectoryPath); + } + } + } + + private static getIgnoredPatterns(yamlPath: string): string[] { + const yamlFile = yaml.load(fs.readFileSync(yamlPath, 'utf8')) as AnalysisOptions; + const ignoredFiles = yamlFile?.exclude ?? []; + if (yamlFile?.include) { + const newPath = path.resolve(yamlPath, yamlFile.include); + if (fs.existsSync(newPath)) { + return [ + ...IgnoredFiles.getIgnoredPatterns(newPath), + ...ignoredFiles, + ]; + } + } + return ignoredFiles; + } + /** * Whether a file is ignored */ From 8126702cf8adb4b4d9990282926d63fa207ea62e Mon Sep 17 00:00:00 2001 From: ValentinVignal Date: Mon, 14 Aug 2023 15:24:03 +0800 Subject: [PATCH 2/9] build: Build --- dist/index.js | 53 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/dist/index.js b/dist/index.js index eff50b5..09a8922 100644 --- a/dist/index.js +++ b/dist/index.js @@ -17090,11 +17090,14 @@ var __importStar = (this && this.__importStar) || function (mod) { __setModuleDefault(result, mod); return result; }; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.IgnoredFiles = void 0; const fs = __importStar(__nccwpck_require__(5747)); const yaml = __importStar(__nccwpck_require__(1917)); -const minimatch = __importStar(__nccwpck_require__(3973)); +const minimatch_1 = __importDefault(__nccwpck_require__(3973)); const path = __importStar(__nccwpck_require__(5622)); const ActionOptions_1 = __nccwpck_require__(3615); /** @@ -17102,17 +17105,55 @@ const ActionOptions_1 = __nccwpck_require__(3615); */ class IgnoredFiles { constructor() { - var _a, _b; let patterns; try { - const yamlFile = yaml.load(fs.readFileSync(path.resolve(ActionOptions_1.actionOptions.workingDirectory, 'analysis_options.yaml'), 'utf8')); - patterns = (_b = (_a = yamlFile === null || yamlFile === void 0 ? void 0 : yamlFile.analyzer) === null || _a === void 0 ? void 0 : _a.exclude) !== null && _b !== void 0 ? _b : []; + const yamlPath = IgnoredFiles.findClosestYamlFile(ActionOptions_1.actionOptions.workingDirectory); + if (!yamlPath) { + throw new Error(`Could not find any "analysis_options.yaml" in the parent directories of "${ActionOptions_1.actionOptions.workingDirectory}"`); + } + patterns = IgnoredFiles.getIgnoredPatterns(yamlPath); } catch (error) { - console.log('Could not load analysis_options.yaml:\n', error); + console.error('Could not load analysis_options.yaml:\n', error); } patterns !== null && patterns !== void 0 ? patterns : (patterns = []); - this.patterns = patterns.map((pattern) => new minimatch.Minimatch(pattern)); + console.log('partterns'); + console.log(patterns); + this.patterns = patterns.map((pattern) => new minimatch_1.default.Minimatch(pattern)); + } + /** + * + * @param path + */ + static findClosestYamlFile(directoryPath) { + const yamlPath = path.resolve(directoryPath, 'analysis_options.yaml'); + if (fs.existsSync(yamlPath)) { + return yamlPath; + } + else { + const parentDirectoryPath = path.resolve(directoryPath, '..'); + if (parentDirectoryPath === directoryPath) { + return null; + } + else { + return IgnoredFiles.findClosestYamlFile(parentDirectoryPath); + } + } + } + static getIgnoredPatterns(yamlPath) { + var _a; + const yamlFile = yaml.load(fs.readFileSync(yamlPath, 'utf8')); + const ignoredFiles = (_a = yamlFile === null || yamlFile === void 0 ? void 0 : yamlFile.exclude) !== null && _a !== void 0 ? _a : []; + if (yamlFile === null || yamlFile === void 0 ? void 0 : yamlFile.include) { + const newPath = path.resolve(yamlPath, yamlFile.include); + if (fs.existsSync(newPath)) { + return [ + ...IgnoredFiles.getIgnoredPatterns(newPath), + ...ignoredFiles, + ]; + } + } + return ignoredFiles; } /** * Whether a file is ignored From c4932cf99aa34ff88d7ed0851c37e8ede7f9bb01 Mon Sep 17 00:00:00 2001 From: ValentinVignal Date: Mon, 14 Aug 2023 15:31:04 +0800 Subject: [PATCH 3/9] bug: Access exclude from analyzer --- dist/index.js | 6 +++--- src/utils/IgnoredFiles.ts | 8 +++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/dist/index.js b/dist/index.js index 09a8922..1d3d983 100644 --- a/dist/index.js +++ b/dist/index.js @@ -17117,7 +17117,7 @@ class IgnoredFiles { console.error('Could not load analysis_options.yaml:\n', error); } patterns !== null && patterns !== void 0 ? patterns : (patterns = []); - console.log('partterns'); + console.log('patterns'); console.log(patterns); this.patterns = patterns.map((pattern) => new minimatch_1.default.Minimatch(pattern)); } @@ -17141,9 +17141,9 @@ class IgnoredFiles { } } static getIgnoredPatterns(yamlPath) { - var _a; + var _a, _b; const yamlFile = yaml.load(fs.readFileSync(yamlPath, 'utf8')); - const ignoredFiles = (_a = yamlFile === null || yamlFile === void 0 ? void 0 : yamlFile.exclude) !== null && _a !== void 0 ? _a : []; + const ignoredFiles = (_b = (_a = yamlFile === null || yamlFile === void 0 ? void 0 : yamlFile.analyzer) === null || _a === void 0 ? void 0 : _a.exclude) !== null && _b !== void 0 ? _b : []; if (yamlFile === null || yamlFile === void 0 ? void 0 : yamlFile.include) { const newPath = path.resolve(yamlPath, yamlFile.include); if (fs.existsSync(newPath)) { diff --git a/src/utils/IgnoredFiles.ts b/src/utils/IgnoredFiles.ts index 3587991..413fd6e 100644 --- a/src/utils/IgnoredFiles.ts +++ b/src/utils/IgnoredFiles.ts @@ -5,8 +5,10 @@ import * as path from 'path'; import { actionOptions } from './ActionOptions'; type AnalysisOptions = { - exclude?: string[]; include?: string; + analyzer?: { + exclude?: string[]; + } } /** @@ -26,7 +28,7 @@ export class IgnoredFiles { console.error('Could not load analysis_options.yaml:\n', error); } patterns ??= []; - console.log('partterns'); + console.log('patterns'); console.log(patterns); this.patterns = patterns.map((pattern) => new minimatch.Minimatch(pattern)); } @@ -51,7 +53,7 @@ export class IgnoredFiles { private static getIgnoredPatterns(yamlPath: string): string[] { const yamlFile = yaml.load(fs.readFileSync(yamlPath, 'utf8')) as AnalysisOptions; - const ignoredFiles = yamlFile?.exclude ?? []; + const ignoredFiles = yamlFile?.analyzer?.exclude ?? []; if (yamlFile?.include) { const newPath = path.resolve(yamlPath, yamlFile.include); if (fs.existsSync(newPath)) { From 6029cd0903741bc10e3c5105470ccec0b8ce20d1 Mon Sep 17 00:00:00 2001 From: ValentinVignal Date: Mon, 14 Aug 2023 15:38:28 +0800 Subject: [PATCH 4/9] bug: Support exclude as string --- dist/index.js | 18 ++++++++++++++---- src/utils/IgnoredFiles.ts | 18 ++++++++++++++---- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/dist/index.js b/dist/index.js index 1d3d983..80a312e 100644 --- a/dist/index.js +++ b/dist/index.js @@ -17141,19 +17141,29 @@ class IgnoredFiles { } } static getIgnoredPatterns(yamlPath) { - var _a, _b; + var _a; const yamlFile = yaml.load(fs.readFileSync(yamlPath, 'utf8')); - const ignoredFiles = (_b = (_a = yamlFile === null || yamlFile === void 0 ? void 0 : yamlFile.analyzer) === null || _a === void 0 ? void 0 : _a.exclude) !== null && _b !== void 0 ? _b : []; + const exclude = (_a = yamlFile === null || yamlFile === void 0 ? void 0 : yamlFile.analyzer) === null || _a === void 0 ? void 0 : _a.exclude; + let patterns; + if (exclude) { + if (Array.isArray(exclude)) { + patterns = exclude; + } + else if (typeof exclude === 'string') { + patterns = [exclude]; + } + } + patterns !== null && patterns !== void 0 ? patterns : (patterns = []); if (yamlFile === null || yamlFile === void 0 ? void 0 : yamlFile.include) { const newPath = path.resolve(yamlPath, yamlFile.include); if (fs.existsSync(newPath)) { return [ ...IgnoredFiles.getIgnoredPatterns(newPath), - ...ignoredFiles, + ...patterns, ]; } } - return ignoredFiles; + return patterns; } /** * Whether a file is ignored diff --git a/src/utils/IgnoredFiles.ts b/src/utils/IgnoredFiles.ts index 413fd6e..786ff76 100644 --- a/src/utils/IgnoredFiles.ts +++ b/src/utils/IgnoredFiles.ts @@ -7,7 +7,7 @@ import { actionOptions } from './ActionOptions'; type AnalysisOptions = { include?: string; analyzer?: { - exclude?: string[]; + exclude?: string[] | string; } } @@ -53,17 +53,27 @@ export class IgnoredFiles { private static getIgnoredPatterns(yamlPath: string): string[] { const yamlFile = yaml.load(fs.readFileSync(yamlPath, 'utf8')) as AnalysisOptions; - const ignoredFiles = yamlFile?.analyzer?.exclude ?? []; + const exclude = yamlFile?.analyzer?.exclude; + let patterns: string[]; + if (exclude) { + if (Array.isArray(exclude)) { + patterns = exclude; + } else if (typeof exclude === 'string') { + patterns = [exclude]; + } + } + patterns ??= []; + if (yamlFile?.include) { const newPath = path.resolve(yamlPath, yamlFile.include); if (fs.existsSync(newPath)) { return [ ...IgnoredFiles.getIgnoredPatterns(newPath), - ...ignoredFiles, + ...patterns, ]; } } - return ignoredFiles; + return patterns; } /** From 183b2a91b62a737e26cee16bde2b5094649bc609 Mon Sep 17 00:00:00 2001 From: ValentinVignal Date: Mon, 14 Aug 2023 15:45:38 +0800 Subject: [PATCH 5/9] bug: Fix yaml include resolve --- dist/index.js | 2 +- src/utils/IgnoredFiles.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/index.js b/dist/index.js index 80a312e..e5a690e 100644 --- a/dist/index.js +++ b/dist/index.js @@ -17155,7 +17155,7 @@ class IgnoredFiles { } patterns !== null && patterns !== void 0 ? patterns : (patterns = []); if (yamlFile === null || yamlFile === void 0 ? void 0 : yamlFile.include) { - const newPath = path.resolve(yamlPath, yamlFile.include); + const newPath = path.resolve(path.dirname(yamlPath), yamlFile.include); if (fs.existsSync(newPath)) { return [ ...IgnoredFiles.getIgnoredPatterns(newPath), diff --git a/src/utils/IgnoredFiles.ts b/src/utils/IgnoredFiles.ts index 786ff76..3d2a092 100644 --- a/src/utils/IgnoredFiles.ts +++ b/src/utils/IgnoredFiles.ts @@ -65,7 +65,7 @@ export class IgnoredFiles { patterns ??= []; if (yamlFile?.include) { - const newPath = path.resolve(yamlPath, yamlFile.include); + const newPath = path.resolve(path.dirname(yamlPath), yamlFile.include); if (fs.existsSync(newPath)) { return [ ...IgnoredFiles.getIgnoredPatterns(newPath), From 2bff38ab871cb1ecf5fab0fc5767239f6bcb7835 Mon Sep 17 00:00:00 2001 From: ValentinVignal Date: Mon, 14 Aug 2023 16:46:16 +0800 Subject: [PATCH 6/9] fix: Remove logs --- src/utils/IgnoredFiles.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/utils/IgnoredFiles.ts b/src/utils/IgnoredFiles.ts index 3d2a092..4c37e32 100644 --- a/src/utils/IgnoredFiles.ts +++ b/src/utils/IgnoredFiles.ts @@ -28,8 +28,6 @@ export class IgnoredFiles { console.error('Could not load analysis_options.yaml:\n', error); } patterns ??= []; - console.log('patterns'); - console.log(patterns); this.patterns = patterns.map((pattern) => new minimatch.Minimatch(pattern)); } From b1f0d5f4f394b3bea904f8f5834ad97897e1e1b4 Mon Sep 17 00:00:00 2001 From: ValentinVignal Date: Mon, 14 Aug 2023 16:46:36 +0800 Subject: [PATCH 7/9] tests: Add test for analysis_options that is not directly in the working directory --- src/utils/IgnoredFiles.test.ts | 45 ++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/utils/IgnoredFiles.test.ts b/src/utils/IgnoredFiles.test.ts index 6d8e9db..39349b0 100644 --- a/src/utils/IgnoredFiles.test.ts +++ b/src/utils/IgnoredFiles.test.ts @@ -16,8 +16,10 @@ jest.mock('path', () => mockPath); const mockFs = { readFileSync: jest.fn(), + existsSync: jest.fn(), }; + jest.mock('fs', () => mockFs); const mockYaml = { @@ -44,6 +46,7 @@ describe('IgnoredFiles', () => { } as ActionOptions; mockPath.resolve.mockReturnValue('path/to/yaml'); + mockFs.existsSync.mockReturnValue(true); mockFs.readFileSync.mockReturnValue('yamlContent'); mockYaml.load.mockReturnValue({ analyzer: { @@ -65,6 +68,48 @@ describe('IgnoredFiles', () => { ['yamlContent'], ]); + expect(ignoredFiles.has('lib/path/to/generated/file.g.dart')).toBe(true); + expect(ignoredFiles.has('lib/path/to/normal/file')).toBe(false); + expect(ignoredFiles.has('lib/main.dart')).toBe(false); + expect(ignoredFiles.has('lib/excluded.dart')).toBe(true); + }); + test('It should return the ignored files of the closest analysis_options.yaml file', () => { + mockActionOptions.actionOptions = { + workingDirectory: 'working/directory', + } as ActionOptions; + + mockPath.resolve.mockReturnValueOnce('working/directory/analysis_options.yaml'); + mockFs.existsSync.mockReturnValueOnce(false); // The file is not found. + mockPath.resolve.mockReturnValueOnce('working'); // Returns the parent + mockPath.resolve.mockReturnValueOnce('working/analysis_options.yaml'); // Yaml higher in the file tree. + mockFs.existsSync.mockReturnValueOnce(true); // The file is not found. + mockFs.readFileSync.mockReturnValue('yamlContent'); + mockYaml.load.mockReturnValue({ + analyzer: { + exclude: [ + '**/*.g.dart', + 'lib/excluded.dart' + ], + } + }); + const ignoredFiles = new IgnoredFiles(); + + expect(mockPath.resolve.mock.calls).toEqual([ + ['working/directory', 'analysis_options.yaml'], + ['working/directory', '..'], + ['working', 'analysis_options.yaml'], + ]); + expect(mockFs.existsSync.mock.calls).toEqual([ + ['working/directory/analysis_options.yaml'], + ['working/analysis_options.yaml'], + ]); + expect(mockFs.readFileSync.mock.calls).toEqual([ + ['working/analysis_options.yaml', 'utf8'], + ]); + expect(mockYaml.load.mock.calls).toEqual([ + ['yamlContent'], + ]); + expect(ignoredFiles.has('lib/path/to/generated/file.g.dart')).toBe(true); expect(ignoredFiles.has('lib/path/to/normal/file')).toBe(false); expect(ignoredFiles.has('lib/main.dart')).toBe(false); From f4c0d83ba7b9560c9f8bc04dadae12008560f553 Mon Sep 17 00:00:00 2001 From: ValentinVignal Date: Mon, 14 Aug 2023 16:47:13 +0800 Subject: [PATCH 8/9] build: Build --- dist/index.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/dist/index.js b/dist/index.js index e5a690e..bbcde1b 100644 --- a/dist/index.js +++ b/dist/index.js @@ -17117,8 +17117,6 @@ class IgnoredFiles { console.error('Could not load analysis_options.yaml:\n', error); } patterns !== null && patterns !== void 0 ? patterns : (patterns = []); - console.log('patterns'); - console.log(patterns); this.patterns = patterns.map((pattern) => new minimatch_1.default.Minimatch(pattern)); } /** From 8ec1fb68746bf329560dc29317bbdc086504d248 Mon Sep 17 00:00:00 2001 From: ValentinVignal Date: Mon, 14 Aug 2023 16:48:34 +0800 Subject: [PATCH 9/9] docs: Update docs --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12c2fe0..c4f2a97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.16 + +- :sparkles: Supports nested analysis options. + ## 0.15 - :arrow_up: Upgrade to node 16. diff --git a/package.json b/package.json index 4b1da9c..ea0083e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "action-dart-analyze", - "version": "0.15.0", + "version": "0.16.0", "description": "", "main": "index.js", "scripts": {