From 0dbcf760bf74c361417752a0ba5943e7517f2f00 Mon Sep 17 00:00:00 2001 From: Nogic <24802730+nogic1008@users.noreply.github.com> Date: Mon, 13 Jan 2025 20:37:11 +0900 Subject: [PATCH 1/6] feat: add problem matcher file for dotnet-format --- .github/dotnet-format.json | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/dotnet-format.json diff --git a/.github/dotnet-format.json b/.github/dotnet-format.json new file mode 100644 index 0000000..673d086 --- /dev/null +++ b/.github/dotnet-format.json @@ -0,0 +1,19 @@ +{ + "problemMatcher": [ + { + "owner": "dotnet-format", + "pattern": [ + { + "regexp": "^\\s*(.*)\\((\\d+),(\\d+)\\):\\s+(error|warning|info)\\s+:\\s+(.*)\\s+\\[(.+)\\]$", + "file": 1, + "line": 2, + "column": 3, + "severity": 4, + "code": 5, + "message": 6, + "fromPath": 7 + } + ] + } + ] +} From 16e40a26d71a4ef76584dd439e8eb8692418287a Mon Sep 17 00:00:00 2001 From: Nogic <24802730+nogic1008@users.noreply.github.com> Date: Mon, 13 Jan 2025 20:49:34 +0900 Subject: [PATCH 2/6] feat: register problem matcher on action --- dist/setup/index.js | 10 ++++++++-- src/setup-dotnet.ts | 13 +++++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/dist/setup/index.js b/dist/setup/index.js index d415cbd..8cbadd2 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -94047,6 +94047,11 @@ const qualityOptions = [ 'preview', 'ga' ]; +/** + * The problem matcher files to be registered with the runner. + * https://github.com/actions/toolkit/blob/main/docs/problem-matchers.md + */ +const problemMatchers = ['csc.json', 'dotnet-format.json']; function run() { return __awaiter(this, void 0, void 0, function* () { try { @@ -94104,8 +94109,9 @@ function run() { const cacheDependencyPath = core.getInput('cache-dependency-path'); yield (0, cache_restore_1.restoreCache)(cacheDependencyPath); } - const matchersPath = path_1.default.join(__dirname, '..', '..', '.github'); - core.info(`##[add-matcher]${path_1.default.join(matchersPath, 'csc.json')}`); + for (const file of problemMatchers) { + core.info(`##[add-matcher]${path_1.default.join(__dirname, '..', '..', '.github', file)}`); + } } catch (error) { core.setFailed(error.message); diff --git a/src/setup-dotnet.ts b/src/setup-dotnet.ts index 2a628a5..dfbabad 100644 --- a/src/setup-dotnet.ts +++ b/src/setup-dotnet.ts @@ -19,6 +19,12 @@ const qualityOptions = [ export type QualityOptions = (typeof qualityOptions)[number]; +/** + * The problem matcher files to be registered with the runner. + * https://github.com/actions/toolkit/blob/main/docs/problem-matchers.md + */ +const problemMatchers = ['csc.json', 'dotnet-format.json']; + export async function run() { try { // @@ -89,8 +95,11 @@ export async function run() { await restoreCache(cacheDependencyPath); } - const matchersPath = path.join(__dirname, '..', '..', '.github'); - core.info(`##[add-matcher]${path.join(matchersPath, 'csc.json')}`); + for (const file of problemMatchers) { + core.info( + `##[add-matcher]${path.join(__dirname, '..', '..', '.github', file)}` + ); + } } catch (error) { core.setFailed(error.message); } From 91e9a0a11ac5791297ac83f4bd36ed753afaf46d Mon Sep 17 00:00:00 2001 From: Nogic <24802730+nogic1008@users.noreply.github.com> Date: Mon, 13 Jan 2025 20:51:39 +0900 Subject: [PATCH 3/6] test: add unit test --- __tests__/setup-dotnet.test.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/__tests__/setup-dotnet.test.ts b/__tests__/setup-dotnet.test.ts index 8e60cd1..d10b03c 100644 --- a/__tests__/setup-dotnet.test.ts +++ b/__tests__/setup-dotnet.test.ts @@ -77,6 +77,12 @@ describe('setup-dotnet tests', () => { expect(debugSpy).toHaveBeenCalledWith(expectedDebugMessage); expect(existsSyncSpy).toHaveBeenCalled(); expect(infoSpy).toHaveBeenCalledWith(expectedInfoMessage); + expect(infoSpy).toHaveBeenCalledWith( + expect.stringMatching(/^##\[add-matcher\](.+)csc\.json$/) + ); + expect(infoSpy).toHaveBeenCalledWith( + expect.stringMatching(/^##\[add-matcher\](.+)dotnet-format\.json$/) + ); }); it('should fail the action if quality is supplied but its value is not supported', async () => { From 93a95a226bf576aaee8f2fc99997923229e43f1b Mon Sep 17 00:00:00 2001 From: Nogic <24802730+nogic1008@users.noreply.github.com> Date: Mon, 13 Jan 2025 21:00:38 +0900 Subject: [PATCH 4/6] fix: fix Regex --- .github/dotnet-format.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/dotnet-format.json b/.github/dotnet-format.json index 673d086..c080eda 100644 --- a/.github/dotnet-format.json +++ b/.github/dotnet-format.json @@ -4,7 +4,7 @@ "owner": "dotnet-format", "pattern": [ { - "regexp": "^\\s*(.*)\\((\\d+),(\\d+)\\):\\s+(error|warning|info)\\s+:\\s+(.*)\\s+\\[(.+)\\]$", + "regexp": "^\\s*(.*)\\((\\d+),(\\d+)\\):\\s+(error|warning)\\s+(.+):\\s+(.*)\\s+\\[(.+)\\]$", "file": 1, "line": 2, "column": 3, From e8284b346f329f07cf8b2d4ba862147550b35556 Mon Sep 17 00:00:00 2001 From: Nogic <24802730+nogic1008@users.noreply.github.com> Date: Mon, 13 Jan 2025 23:26:56 +0900 Subject: [PATCH 5/6] test: add unit test for problem matcher --- __tests__/problem-matchers.json.test.ts | 32 +++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 __tests__/problem-matchers.json.test.ts diff --git a/__tests__/problem-matchers.json.test.ts b/__tests__/problem-matchers.json.test.ts new file mode 100644 index 0000000..9ec1a1d --- /dev/null +++ b/__tests__/problem-matchers.json.test.ts @@ -0,0 +1,32 @@ +import dotnetFormat from '../.github/dotnet-format.json'; + +describe('/.github/dotnet-format.json tests', () => { + const problemMatcher = dotnetFormat.problemMatcher[0].pattern[0]; + + it.each([ + [ + "/home/runner/work/repo/Test.cs(18,6): error WHITESPACE: Fix whitespace formatting. Replace 12 characters with '\\n\\s\\s\\s\\s\\s\\s\\s\\s'. [/home/runner/work/repo/Test.csproj]", + '/home/runner/work/repo/Test.cs', + '18', + '6', + 'error', + 'WHITESPACE', + "Fix whitespace formatting. Replace 12 characters with '\\n\\s\\s\\s\\s\\s\\s\\s\\s'.", + '/home/runner/work/repo/Test.csproj' + ] + ])( + '"%s" returns {file: "%s", line: "%s", column: "%s", severity: "%s", code: "%s", message: "%s", fromPath: "%s"}', + (logOutput, file, line, column, severity, code, message, fromPath) => { + const regexp = new RegExp(problemMatcher.regexp); + const res = logOutput.match(regexp); + + expect(res?.[problemMatcher.file]).toBe(file); + expect(res?.[problemMatcher.line]).toBe(line); + expect(res?.[problemMatcher.column]).toBe(column); + expect(res?.[problemMatcher.severity]).toBe(severity); + expect(res?.[problemMatcher.code]).toBe(code); + expect(res?.[problemMatcher.message]).toBe(message); + expect(res?.[problemMatcher.fromPath]).toBe(fromPath); + } + ); +}); From 90a52e1c23eeb84fe7d387857edbcb14808071d5 Mon Sep 17 00:00:00 2001 From: Nogic <24802730+nogic1008@users.noreply.github.com> Date: Tue, 14 Jan 2025 19:25:17 +0900 Subject: [PATCH 6/6] test: move csc.json unit test into problem-matchers tests --- __tests__/csc.test.ts | 45 -------------- __tests__/problem-matchers.json.test.ts | 78 ++++++++++++++++++------- 2 files changed, 58 insertions(+), 65 deletions(-) delete mode 100644 __tests__/csc.test.ts diff --git a/__tests__/csc.test.ts b/__tests__/csc.test.ts deleted file mode 100644 index 8d43b39..0000000 --- a/__tests__/csc.test.ts +++ /dev/null @@ -1,45 +0,0 @@ -import cscFile from '../.github/csc.json'; -describe('csc tests', () => { - test('regular expression in csc.json is valid', async () => { - const regexPattern = cscFile['problemMatcher'][0]['pattern'][0]['regexp']; - const regexResultsMap = cscFile['problemMatcher'][0]['pattern'][0]; - - const regex = new RegExp(regexPattern); - - const stringsToMatch = [ - 'Program.cs(10,79): error CS1002: ; expected [/Users/zacharyeisinger/Documents/repo/setup-dotnet/__tests__/sample-broken-csproj/sample.csproj]', - "S:\\Msbuild\\src\\Build\\Evaluation\\ExpressionShredder.cs(33,7): error CS1003: Syntax error, ',' expected [S:\\msbuild\\src\\Build\\Microsoft.Build.csproj > Properties:prop]" - ]; - // Expected results are calculated according to the csc matcher located in csc.json file - const expectedResults = [ - { - file: 'Program.cs', - line: '10', - severity: 'error', - code: 'CS1002', - message: '; expected', - fromPath: - '/Users/zacharyeisinger/Documents/repo/setup-dotnet/__tests__/sample-broken-csproj/sample.csproj' - }, - { - file: 'S:\\Msbuild\\src\\Build\\Evaluation\\ExpressionShredder.cs', - line: '33', - severity: 'error', - code: 'CS1003', - message: "Syntax error, ',' expected", - fromPath: - 'S:\\msbuild\\src\\Build\\Microsoft.Build.csproj > Properties:prop' - } - ]; - - stringsToMatch.map((string, index) => { - const matchedResultsArray = string.match(regex); - for (const propName in expectedResults[index]) { - const propertyIndex = regexResultsMap[propName]; - const expectedPropValue = expectedResults[index][propName]; - const matchedPropValue = matchedResultsArray![propertyIndex]; - expect(matchedPropValue).toEqual(expectedPropValue); - } - }); - }, 10000); -}); diff --git a/__tests__/problem-matchers.json.test.ts b/__tests__/problem-matchers.json.test.ts index 9ec1a1d..6b1f7c1 100644 --- a/__tests__/problem-matchers.json.test.ts +++ b/__tests__/problem-matchers.json.test.ts @@ -1,32 +1,70 @@ +import csc from '../.github/csc.json'; import dotnetFormat from '../.github/dotnet-format.json'; +// Unit tests for problem matchers +// https://github.com/actions/toolkit/blob/main/docs/problem-matchers.md + +describe('/.github/csc.json tests', () => { + const problemMatcher = csc.problemMatcher[0].pattern[0]; + + it.each([ + [ + 'Program.cs(10,79): error CS1002: ; expected [/Users/zacharyeisinger/Documents/repo/setup-dotnet/__tests__/sample-broken-csproj/sample.csproj]', + { + file: 'Program.cs', + line: '10', + severity: 'error', + code: 'CS1002', + message: '; expected', + fromPath: + '/Users/zacharyeisinger/Documents/repo/setup-dotnet/__tests__/sample-broken-csproj/sample.csproj' + } + ], + [ + "S:\\Msbuild\\src\\Build\\Evaluation\\ExpressionShredder.cs(33,7): error CS1003: Syntax error, ',' expected [S:\\msbuild\\src\\Build\\Microsoft.Build.csproj > Properties:prop]", + { + file: 'S:\\Msbuild\\src\\Build\\Evaluation\\ExpressionShredder.cs', + line: '33', + severity: 'error', + code: 'CS1003', + message: "Syntax error, ',' expected", + fromPath: + 'S:\\msbuild\\src\\Build\\Microsoft.Build.csproj > Properties:prop' + } + ] + ])('log "%s" matches %o', (logOutput, expected) => { + const regexp = new RegExp(problemMatcher.regexp); + const res = logOutput.match(regexp); + + for (const key in expected) { + expect(res?.[problemMatcher[key]]).toBe(expected[key]); + } + }); +}); + describe('/.github/dotnet-format.json tests', () => { const problemMatcher = dotnetFormat.problemMatcher[0].pattern[0]; it.each([ [ "/home/runner/work/repo/Test.cs(18,6): error WHITESPACE: Fix whitespace formatting. Replace 12 characters with '\\n\\s\\s\\s\\s\\s\\s\\s\\s'. [/home/runner/work/repo/Test.csproj]", - '/home/runner/work/repo/Test.cs', - '18', - '6', - 'error', - 'WHITESPACE', - "Fix whitespace formatting. Replace 12 characters with '\\n\\s\\s\\s\\s\\s\\s\\s\\s'.", - '/home/runner/work/repo/Test.csproj' + { + file: '/home/runner/work/repo/Test.cs', + line: '18', + column: '6', + severity: 'error', + code: 'WHITESPACE', + message: + "Fix whitespace formatting. Replace 12 characters with '\\n\\s\\s\\s\\s\\s\\s\\s\\s'.", + fromPath: '/home/runner/work/repo/Test.csproj' + } ] - ])( - '"%s" returns {file: "%s", line: "%s", column: "%s", severity: "%s", code: "%s", message: "%s", fromPath: "%s"}', - (logOutput, file, line, column, severity, code, message, fromPath) => { - const regexp = new RegExp(problemMatcher.regexp); - const res = logOutput.match(regexp); + ])('log "%s" matches %o', (logOutput, expected) => { + const regexp = new RegExp(problemMatcher.regexp); + const res = logOutput.match(regexp); - expect(res?.[problemMatcher.file]).toBe(file); - expect(res?.[problemMatcher.line]).toBe(line); - expect(res?.[problemMatcher.column]).toBe(column); - expect(res?.[problemMatcher.severity]).toBe(severity); - expect(res?.[problemMatcher.code]).toBe(code); - expect(res?.[problemMatcher.message]).toBe(message); - expect(res?.[problemMatcher.fromPath]).toBe(fromPath); + for (const key in expected) { + expect(res?.[problemMatcher[key]]).toBe(expected[key]); } - ); + }); });