diff --git a/.github/dotnet-format.json b/.github/dotnet-format.json new file mode 100644 index 000000000..c080eda53 --- /dev/null +++ b/.github/dotnet-format.json @@ -0,0 +1,19 @@ +{ + "problemMatcher": [ + { + "owner": "dotnet-format", + "pattern": [ + { + "regexp": "^\\s*(.*)\\((\\d+),(\\d+)\\):\\s+(error|warning)\\s+(.+):\\s+(.*)\\s+\\[(.+)\\]$", + "file": 1, + "line": 2, + "column": 3, + "severity": 4, + "code": 5, + "message": 6, + "fromPath": 7 + } + ] + } + ] +} diff --git a/__tests__/csc.test.ts b/__tests__/csc.test.ts deleted file mode 100644 index 8d43b3925..000000000 --- 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 new file mode 100644 index 000000000..6b1f7c15a --- /dev/null +++ b/__tests__/problem-matchers.json.test.ts @@ -0,0 +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]", + { + 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' + } + ] + ])('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]); + } + }); +}); diff --git a/__tests__/setup-dotnet.test.ts b/__tests__/setup-dotnet.test.ts index 8e60cd1ab..d10b03c71 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 () => { diff --git a/dist/setup/index.js b/dist/setup/index.js index d415cbd8a..8cbadd24a 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 2a628a5ab..dfbabad88 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); }