From c3716cb90452da3795586f4b87fd0cb22918081d Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 09:23:53 -0700 Subject: [PATCH 01/24] Reorder scripts in npm run all --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7620f76..3016186 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "test": "jest", "lint": "eslint . --ext .ts,.tsx --ignore-pattern node_modules/", "pack": "ncc build", - "all": "npm run build && npm run lint && npm run pack && npm test" + "all": "npm run lint && npm run build && npm test && npm run pack" }, "repository": { "type": "git", From 6f9f67b7e7be000fb6d2f31c8d3fe84e5ceb0be4 Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 10:23:45 -0700 Subject: [PATCH 02/24] Added default value for pathFilter and optional contentFilter to comment --- __tests__/configReader.test.ts | 28 ++++++++++++++--- ...ing-nitpicks.yml => blocking_nitpicks.yml} | 2 +- __tests__/data/default_content_filter.yml | 9 ++++++ __tests__/data/default_path_filter.yml | 8 +++++ ...alid-nitpicks.yml => invalid_nitpicks.yml} | 0 __tests__/data/valid-nitpicks.yml | 21 ------------- __tests__/data/valid_nitpicks.yml | 30 +++++++++++++++++++ src/constants.ts | 1 + src/models/comment.ts | 1 + src/services/configReader.ts | 5 ++-- 10 files changed, 77 insertions(+), 28 deletions(-) rename __tests__/data/{blocking-nitpicks.yml => blocking_nitpicks.yml} (81%) create mode 100644 __tests__/data/default_content_filter.yml create mode 100644 __tests__/data/default_path_filter.yml rename __tests__/data/{invalid-nitpicks.yml => invalid_nitpicks.yml} (100%) delete mode 100644 __tests__/data/valid-nitpicks.yml create mode 100644 __tests__/data/valid_nitpicks.yml diff --git a/__tests__/configReader.test.ts b/__tests__/configReader.test.ts index bd93484..1845fc6 100644 --- a/__tests__/configReader.test.ts +++ b/__tests__/configReader.test.ts @@ -3,16 +3,36 @@ import { getConfiguredComments } from '../src/services'; import { Constants } from '../src/constants'; test('read valid config file', () => { - const configFile = './data/valid-nitpicks.yml'; + const configFile = './data/valid_nitpicks.yml'; const inputPath = path.join(__dirname, configFile); const comments = getConfiguredComments(inputPath); - expect(comments.length).toEqual(3); + expect(comments.length).toEqual(5); +}); + +test("pathFilter defaults to '*'", () => { + const configFile = './data/default_path_filter.yml'; + const inputPath = path.join(__dirname, configFile); + + const comments = getConfiguredComments(inputPath); + + expect( + comments.every(c => c.pathFilter.every(p => p === '**/*')) + ).toBeTruthy(); +}); + +test('contentFilter defaults to undefined', () => { + const configFile = './data/default_content_filter.yml'; + const inputPath = path.join(__dirname, configFile); + + const comments = getConfiguredComments(inputPath); + + expect(comments.every(c => !c.contentFilter)).toBeTruthy(); }); test('read invalid config file', () => { - const configFile = './data/invalid-nitpicks.yml'; + const configFile = './data/invalid_nitpicks.yml'; const inputPath = path.join(__dirname, configFile); const comments = getConfiguredComments(inputPath); @@ -21,7 +41,7 @@ test('read invalid config file', () => { }); test('blocking comment text', () => { - const configFile = './data/blocking-nitpicks.yml'; + const configFile = './data/blocking_nitpicks.yml'; const inputPath = path.join(__dirname, configFile); const comments = getConfiguredComments(inputPath); diff --git a/__tests__/data/blocking-nitpicks.yml b/__tests__/data/blocking_nitpicks.yml similarity index 81% rename from __tests__/data/blocking-nitpicks.yml rename to __tests__/data/blocking_nitpicks.yml index b395135..8a43bc3 100644 --- a/__tests__/data/blocking-nitpicks.yml +++ b/__tests__/data/blocking_nitpicks.yml @@ -1,5 +1,5 @@ - markdown: | - This is a blcoking comment + This is a blocking comment blocking: true pathFilter: - '**/*.dll' diff --git a/__tests__/data/default_content_filter.yml b/__tests__/data/default_content_filter.yml new file mode 100644 index 0000000..0a73f71 --- /dev/null +++ b/__tests__/data/default_content_filter.yml @@ -0,0 +1,9 @@ +- markdown: | + ## Notice + Thanks for this contribution. We _really_ appreciate your help! + +- markdown: | + ## Blocking issue + blocking: true + pathFilter: + - '**/*.dll' diff --git a/__tests__/data/default_path_filter.yml b/__tests__/data/default_path_filter.yml new file mode 100644 index 0000000..99bf454 --- /dev/null +++ b/__tests__/data/default_path_filter.yml @@ -0,0 +1,8 @@ +- markdown: | + ## Notice + Thanks for this contribution. We _really_ appreciate your help! + +- markdown: | + Don't add email addresses! + contentFilter: + - '[\w-]+@([\w-]+\.)+[\w-]+' diff --git a/__tests__/data/invalid-nitpicks.yml b/__tests__/data/invalid_nitpicks.yml similarity index 100% rename from __tests__/data/invalid-nitpicks.yml rename to __tests__/data/invalid_nitpicks.yml diff --git a/__tests__/data/valid-nitpicks.yml b/__tests__/data/valid-nitpicks.yml deleted file mode 100644 index f35675e..0000000 --- a/__tests__/data/valid-nitpicks.yml +++ /dev/null @@ -1,21 +0,0 @@ -- markdown: | - ## Notice - Thanks for this contribution. We _really_ appreciate your help! - pathFilter: - - '**' -- markdown: | - ## Blocking issue - We no longer check in binaries to this repo - our new convention is to use NuGet packages. - - Read more about this change [here](https://www.nuget.org/). - blocking: true - pathFilter: - - '**/*.dll' -- markdown: | - ## Information - You modified a file that controls the payment processing for the company. Please ensure that you have completed all of the following: - - [ ] Added unit tests to verify changes - - [ ] Tested change in multiple web browsers (Chrome, Firefox, Safari, and Edge) - - [ ] Updated documentation with any API changes - pathFilter: - - 'payments/**' diff --git a/__tests__/data/valid_nitpicks.yml b/__tests__/data/valid_nitpicks.yml new file mode 100644 index 0000000..feb4861 --- /dev/null +++ b/__tests__/data/valid_nitpicks.yml @@ -0,0 +1,30 @@ +# Test that pathFilter alone works +- markdown: | + ## Notice + Thanks for this contribution. We _really_ appreciate your help! + pathFilter: + - '**' +# blocking is a valid option +- markdown: | + ## Blocking issue + We no longer check in binaries to this repo - our new convention is to use NuGet packages. + + Read more about this change [here](https://www.nuget.org/). + blocking: true + pathFilter: + - '**/*.dll' +# Path filter should default to * +- markdown: | + Apply to everything +# Test that contentFilter is a valid option +- markdown: | + Don't add email addresses! + contentFilter: + - '[\w-]+@([\w-]+\.)+[\w-]+' +# Kitchen sink +- markdown: | + Oops - looks like you added a `puts` statement + pathFilter: + - app/**/*.rb + contentFilter: + - '(puts\W+)' diff --git a/src/constants.ts b/src/constants.ts index d1b9e1e..42b3329 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -4,4 +4,5 @@ export module Constants { '\n__Note__: this is a [blocking](https://github.com/ethanis/nitpicker#blocking-comments) comment.\n'; export const CannedTextSeparator: string = '\n--------------\n_Caused by:_\n'; export const ResolvedText: string = '\n--------------\n_Resolved_\n'; + export const DefaultPathFilter: string[] = ['**/*']; } diff --git a/src/models/comment.ts b/src/models/comment.ts index f1142b1..10aa1f0 100644 --- a/src/models/comment.ts +++ b/src/models/comment.ts @@ -1,5 +1,6 @@ export interface Comment { pathFilter: string[]; + contentFilter: string[]; markdown: string; blocking: boolean; } diff --git a/src/services/configReader.ts b/src/services/configReader.ts index c600ac2..eff6360 100644 --- a/src/services/configReader.ts +++ b/src/services/configReader.ts @@ -8,10 +8,11 @@ export function getConfiguredComments(filePath: string): Comment[] { const yaml: Comment[] = safeLoad(contents); const comments: Comment[] = yaml - .filter(y => y.markdown && y.pathFilter?.length > 0) + .filter(y => y.markdown) .map(c => ({ ...c, - markdown: `${c.markdown}${c.blocking ? Constants.BlockingText : ''}` + markdown: `${c.markdown}${c.blocking ? Constants.BlockingText : ''}`, + pathFilter: c.pathFilter ?? Constants.DefaultPathFilter // Default to match everything })); return comments; From b8c9df516c482a9e5114a2976ea5113144f1fada Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 10:32:55 -0700 Subject: [PATCH 03/24] Throw actionable error if nitpicks file does not exist --- __tests__/configReader.test.ts | 9 +++++++++ src/services/configReader.ts | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/__tests__/configReader.test.ts b/__tests__/configReader.test.ts index 1845fc6..7eaf4a9 100644 --- a/__tests__/configReader.test.ts +++ b/__tests__/configReader.test.ts @@ -53,3 +53,12 @@ test('blocking comment text', () => { } } }); + +test('file doesnt exist', () => { + const configFile = './data/foo_bar.yml'; + const inputPath = path.join(__dirname, configFile); + + expect(() => getConfiguredComments(inputPath)).toThrowError( + 'Nitpicks file does not exist: ' + ); +}); diff --git a/src/services/configReader.ts b/src/services/configReader.ts index eff6360..faf6416 100644 --- a/src/services/configReader.ts +++ b/src/services/configReader.ts @@ -4,6 +4,10 @@ import { safeLoad } from 'js-yaml'; import { Constants } from '../constants'; export function getConfiguredComments(filePath: string): Comment[] { + if (!fs.existsSync(filePath)) { + throw Error(`Nitpicks file does not exist: ${filePath}`); + } + const contents = fs.readFileSync(filePath, 'utf8'); const yaml: Comment[] = safeLoad(contents); From a66a074553608740d0ea6925639cab1e0336d59d Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 10:54:21 -0700 Subject: [PATCH 04/24] Retrieve diffs from changed files --- src/main.ts | 3 --- src/services/changes.ts | 9 ++++++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main.ts b/src/main.ts index 7582cda..5886d44 100644 --- a/src/main.ts +++ b/src/main.ts @@ -37,11 +37,8 @@ async function run() { } const octokit = new github.GitHub(token); - const eventName = process.env.GITHUB_EVENT_NAME; - console.log('starting check'); - const changes: Change[] = await getChangedFiles(octokit, eventName); const targetState = await getTargetState(octokit, comments, changes); diff --git a/src/services/changes.ts b/src/services/changes.ts index bc4c0a1..49380b7 100644 --- a/src/services/changes.ts +++ b/src/services/changes.ts @@ -28,14 +28,17 @@ async function getChangesFromSha(octokit: github.GitHub): Promise { return []; } - const listFilesResponse = await octokit.repos.compareCommits({ + const changedFiles = await octokit.repos.compareCommits({ owner: owner, repo: repo, base: beforeSha, - head: afterSha + head: afterSha, + mediaType: { format: 'diff' } }); - const changes = listFilesResponse.data.files.map(f => ({ + console.log(changedFiles.data); + + const changes = changedFiles.data.files.map(f => ({ file: f.filename, changeType: parseStatus(f.status) })); From fb42ec533a72315b12b6e4e241d463eb37730ad7 Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 11:04:07 -0700 Subject: [PATCH 05/24] Make comment.contentFilter optional --- __tests__/configReader.test.ts | 4 +--- src/constants.ts | 2 +- src/models/comment.ts | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/__tests__/configReader.test.ts b/__tests__/configReader.test.ts index 7eaf4a9..7c25f38 100644 --- a/__tests__/configReader.test.ts +++ b/__tests__/configReader.test.ts @@ -17,9 +17,7 @@ test("pathFilter defaults to '*'", () => { const comments = getConfiguredComments(inputPath); - expect( - comments.every(c => c.pathFilter.every(p => p === '**/*')) - ).toBeTruthy(); + expect(comments.every(c => c.pathFilter.every(p => p === '*'))).toBeTruthy(); }); test('contentFilter defaults to undefined', () => { diff --git a/src/constants.ts b/src/constants.ts index 42b3329..04f2d9a 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -4,5 +4,5 @@ export module Constants { '\n__Note__: this is a [blocking](https://github.com/ethanis/nitpicker#blocking-comments) comment.\n'; export const CannedTextSeparator: string = '\n--------------\n_Caused by:_\n'; export const ResolvedText: string = '\n--------------\n_Resolved_\n'; - export const DefaultPathFilter: string[] = ['**/*']; + export const DefaultPathFilter: string[] = ['*']; } diff --git a/src/models/comment.ts b/src/models/comment.ts index 10aa1f0..5c2d6f6 100644 --- a/src/models/comment.ts +++ b/src/models/comment.ts @@ -1,6 +1,6 @@ export interface Comment { pathFilter: string[]; - contentFilter: string[]; + contentFilter?: string[]; markdown: string; blocking: boolean; } From 70d6955e575c18bd51829a0b3589ac3e642d046b Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 11:06:29 -0700 Subject: [PATCH 06/24] Use snazzy defaults for thank you comment --- .github/nitpicks.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/nitpicks.yml b/.github/nitpicks.yml index b9deea9..efa3fbc 100644 --- a/.github/nitpicks.yml +++ b/.github/nitpicks.yml @@ -1,8 +1,6 @@ - markdown: | ## Rockstar alert Thanks for this contribution, we _really_ appreciate your help :heart:! - pathFilter: - - '*' - markdown: | Please proofread any changes to documentation. pathFilter: From 93b8770fa5b40ab72e44fdbf916be14c78e9860e Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 11:08:14 -0700 Subject: [PATCH 07/24] Moar debug output --- src/services/changes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/changes.ts b/src/services/changes.ts index 49380b7..3d5e65c 100644 --- a/src/services/changes.ts +++ b/src/services/changes.ts @@ -36,7 +36,7 @@ async function getChangesFromSha(octokit: github.GitHub): Promise { mediaType: { format: 'diff' } }); - console.log(changedFiles.data); + core.debug(JSON.stringify(changedFiles)); const changes = changedFiles.data.files.map(f => ({ file: f.filename, From 93c9c6cbf57e9a8927680a96df3edc48fa40a97d Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 11:21:09 -0700 Subject: [PATCH 08/24] Retrieve patch for changed files --- __tests__/services/state.test.ts | 33 +++++++++++++++++++++----------- src/models/changes.ts | 1 + src/services/changes.ts | 12 ++++++------ 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/__tests__/services/state.test.ts b/__tests__/services/state.test.ts index dafa2cf..9d19504 100644 --- a/__tests__/services/state.test.ts +++ b/__tests__/services/state.test.ts @@ -11,7 +11,8 @@ test('* matches everything', () => { const changes: Change[] = [ { file: 'app/models/foo.rb', - changeType: ChangeType.edit + changeType: ChangeType.edit, + patch: '' } ]; @@ -30,7 +31,8 @@ test('match recursively', () => { const changes: Change[] = [ { file: 'app/models/foo.rb', - changeType: ChangeType.edit + changeType: ChangeType.edit, + patch: '' } ]; @@ -49,7 +51,8 @@ test('ignore case', () => { const changes: Change[] = [ { file: 'APP/MODELS/FOO.rb', - changeType: ChangeType.edit + changeType: ChangeType.edit, + patch: '' } ]; @@ -68,7 +71,8 @@ test('remove exclusion patterns', () => { const changes: Change[] = [ { file: 'app/models/main.h', - changeType: ChangeType.edit + changeType: ChangeType.edit, + patch: '' } ]; @@ -87,11 +91,13 @@ test('match new files only', () => { const changes: Change[] = [ { file: 'app/models/old.rb', - changeType: ChangeType.edit + changeType: ChangeType.edit, + patch: '' }, { file: 'app/models/new.rb', - changeType: ChangeType.add + changeType: ChangeType.add, + patch: '' } ]; @@ -110,11 +116,13 @@ test('match deleted files only', () => { const changes: Change[] = [ { file: 'app/models/old.rb', - changeType: ChangeType.edit + changeType: ChangeType.edit, + patch: '' }, { file: 'app/models/deleted.rb', - changeType: ChangeType.delete + changeType: ChangeType.delete, + patch: '' } ]; @@ -133,11 +141,13 @@ test('match edited files only', () => { const changes: Change[] = [ { file: 'app/models/old.rb', - changeType: ChangeType.edit + changeType: ChangeType.edit, + patch: '' }, { file: 'app/models/deleted.rb', - changeType: ChangeType.delete + changeType: ChangeType.delete, + patch: '' } ]; @@ -156,7 +166,8 @@ test('disallow multiple modifiers', () => { const changes: Change[] = [ { file: 'app/models/old.rb', - changeType: ChangeType.edit + changeType: ChangeType.edit, + patch: '' } ]; diff --git a/src/models/changes.ts b/src/models/changes.ts index 077b04f..3301d6d 100644 --- a/src/models/changes.ts +++ b/src/models/changes.ts @@ -8,4 +8,5 @@ export enum ChangeType { export interface Change { file: string; changeType: ChangeType; + patch: string; } diff --git a/src/services/changes.ts b/src/services/changes.ts index 3d5e65c..bb49cf4 100644 --- a/src/services/changes.ts +++ b/src/services/changes.ts @@ -33,14 +33,13 @@ async function getChangesFromSha(octokit: github.GitHub): Promise { repo: repo, base: beforeSha, head: afterSha, - mediaType: { format: 'diff' } + mediaType: { format: 'sha' } }); - core.debug(JSON.stringify(changedFiles)); - - const changes = changedFiles.data.files.map(f => ({ + const changes: Change[] = changedFiles.data.files.map(f => ({ file: f.filename, - changeType: parseStatus(f.status) + changeType: parseStatus(f.status), + patch: f.patch })); core.debug('found changed files:'); @@ -65,7 +64,8 @@ async function getChangesFromPR(octokit: github.GitHub): Promise { const changes = listFilesResponse.data.map(f => ({ file: f.filename, - changeType: parseStatus(f.status) + changeType: parseStatus(f.status), + patch: f.patch })); core.debug('found changed files:'); From 0893a8d1d524c49b6bd51db1357089d64e88dc23 Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 11:32:49 -0700 Subject: [PATCH 09/24] Return full change data from getMatchingFilePaths --- __tests__/services/state.test.ts | 32 +++++++++++++++++--------------- src/services/state.ts | 25 ++++++++++++++++++++----- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/__tests__/services/state.test.ts b/__tests__/services/state.test.ts index 9d19504..c400048 100644 --- a/__tests__/services/state.test.ts +++ b/__tests__/services/state.test.ts @@ -1,7 +1,7 @@ import { getMatchingFilePaths } from '../../src/services'; import { Comment, Change, ChangeType } from '../../src/models'; -test('* matches everything', () => { +test('pathFilter * matches everything', () => { const comment: Comment = { pathFilter: ['*'], markdown: 'Woohoo!', @@ -18,10 +18,10 @@ test('* matches everything', () => { const result = getMatchingFilePaths(comment, changes); - expect(result).toEqual(changes.map(c => c.file)); + expect(result).toEqual(changes); }); -test('match recursively', () => { +test('pathFilter matches recursively', () => { const comment: Comment = { pathFilter: ['app/**'], markdown: 'Woohoo!', @@ -38,10 +38,10 @@ test('match recursively', () => { const result = getMatchingFilePaths(comment, changes); - expect(result).toEqual(changes.map(c => c.file)); + expect(result).toEqual(changes); }); -test('ignore case', () => { +test('pathFilter ignores case', () => { const comment: Comment = { pathFilter: ['app/**'], markdown: 'Woohoo!', @@ -58,10 +58,10 @@ test('ignore case', () => { const result = getMatchingFilePaths(comment, changes); - expect(result).toEqual(changes.map(c => c.file)); + expect(result).toEqual(changes); }); -test('remove exclusion patterns', () => { +test('pathFilter removes exclusion patterns', () => { const comment: Comment = { pathFilter: ['app/**', '!app/models/*.h'], markdown: 'Everything except headers', @@ -78,10 +78,10 @@ test('remove exclusion patterns', () => { const result = getMatchingFilePaths(comment, changes); - expect(result).toEqual([]); + expect(result).toHaveLength(0); }); -test('match new files only', () => { +test('pathFilter can match new files only', () => { const comment: Comment = { pathFilter: ['+app/**'], markdown: 'Only new files', @@ -103,10 +103,10 @@ test('match new files only', () => { const result = getMatchingFilePaths(comment, changes); - expect(result).toEqual(['app/models/new.rb']); + expect(result).toEqual(changes.filter(c => c.changeType === ChangeType.add)); }); -test('match deleted files only', () => { +test('pathFilter can match deleted files only', () => { const comment: Comment = { pathFilter: ['-app/**'], markdown: 'Only deleted files', @@ -128,10 +128,12 @@ test('match deleted files only', () => { const result = getMatchingFilePaths(comment, changes); - expect(result).toEqual(['app/models/deleted.rb']); + expect(result).toEqual( + changes.filter(c => c.changeType === ChangeType.delete) + ); }); -test('match edited files only', () => { +test('pathFilter can match edited files only', () => { const comment: Comment = { pathFilter: ['~app/**'], markdown: 'Only deleted files', @@ -153,10 +155,10 @@ test('match edited files only', () => { const result = getMatchingFilePaths(comment, changes); - expect(result).toEqual(['app/models/old.rb']); + expect(result).toEqual(changes.filter(c => c.changeType === ChangeType.edit)); }); -test('disallow multiple modifiers', () => { +test('pathFilter disallows multiple modifiers', () => { const comment: Comment = { pathFilter: ['!~app/**'], markdown: 'Not edited files', diff --git a/src/services/state.ts b/src/services/state.ts index 1fddc95..d5d976f 100644 --- a/src/services/state.ts +++ b/src/services/state.ts @@ -9,7 +9,7 @@ import { Comment } from '../models'; import { getExistingComments } from '.'; -import { IOptions, Minimatch } from 'minimatch'; +import { IOptions, Minimatch, match } from 'minimatch'; import { Constants } from '../constants'; const pathModifiers = ['!', '+', '-', '~']; @@ -35,7 +35,10 @@ export async function getTargetState( ); for (const comment of allComments) { - const matches = getMatchingFilePaths(comment, changes); + const matchedFiles = getMatchingFilePaths(comment, changes); + const matchedContent = getMatchingContentChanges(comment, matchedFiles); + const matches = matchedContent.map(m => m.file); + const isApplicable = matches.length > 0; const commentMatchText = `${comment.markdown}${Constants.CannedTextSeparator}`; @@ -80,8 +83,8 @@ export async function getTargetState( export function getMatchingFilePaths( comment: Comment, changes: Change[] -): string[] { - const results: string[] = []; +): Change[] { + const results: Change[] = []; const options: IOptions = { dot: true, nocase: true }; const inclusions: string[] = []; @@ -175,9 +178,21 @@ export function getMatchingFilePaths( // If we've made it this far, comment is good to go if (isMatch) { - results.push(change.file); + results.push(change); } } return results; } + +export function getMatchingContentChanges( + comment: Comment, + changes: Change[] +): Change[] { + // if contentFilter isn't defined, return everything + if (!comment.contentFilter) { + return changes; + } + + return []; +} From 15b48c20ff4c83ad259225720d0127a628b895af Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 12:04:00 -0700 Subject: [PATCH 10/24] Match comments based on regexpr --- __tests__/services/state.test.ts | 131 ++++++++++++++++++++++++++++--- src/services/state.ts | 18 ++++- 2 files changed, 139 insertions(+), 10 deletions(-) diff --git a/__tests__/services/state.test.ts b/__tests__/services/state.test.ts index c400048..ef0c488 100644 --- a/__tests__/services/state.test.ts +++ b/__tests__/services/state.test.ts @@ -1,7 +1,10 @@ -import { getMatchingFilePaths } from '../../src/services'; +import { + getMatchingFilePaths, + getMatchingContentChanges +} from '../../src/services'; import { Comment, Change, ChangeType } from '../../src/models'; -test('pathFilter * matches everything', () => { +test('getMatchingFilePaths * matches everything', () => { const comment: Comment = { pathFilter: ['*'], markdown: 'Woohoo!', @@ -21,7 +24,7 @@ test('pathFilter * matches everything', () => { expect(result).toEqual(changes); }); -test('pathFilter matches recursively', () => { +test('getMatchingFilePaths matches recursively', () => { const comment: Comment = { pathFilter: ['app/**'], markdown: 'Woohoo!', @@ -41,7 +44,7 @@ test('pathFilter matches recursively', () => { expect(result).toEqual(changes); }); -test('pathFilter ignores case', () => { +test('getMatchingFilePaths ignores case', () => { const comment: Comment = { pathFilter: ['app/**'], markdown: 'Woohoo!', @@ -61,7 +64,7 @@ test('pathFilter ignores case', () => { expect(result).toEqual(changes); }); -test('pathFilter removes exclusion patterns', () => { +test('getMatchingFilePaths removes exclusion patterns', () => { const comment: Comment = { pathFilter: ['app/**', '!app/models/*.h'], markdown: 'Everything except headers', @@ -81,7 +84,7 @@ test('pathFilter removes exclusion patterns', () => { expect(result).toHaveLength(0); }); -test('pathFilter can match new files only', () => { +test('getMatchingFilePaths can match new files only', () => { const comment: Comment = { pathFilter: ['+app/**'], markdown: 'Only new files', @@ -106,7 +109,7 @@ test('pathFilter can match new files only', () => { expect(result).toEqual(changes.filter(c => c.changeType === ChangeType.add)); }); -test('pathFilter can match deleted files only', () => { +test('getMatchingFilePaths can match deleted files only', () => { const comment: Comment = { pathFilter: ['-app/**'], markdown: 'Only deleted files', @@ -133,7 +136,7 @@ test('pathFilter can match deleted files only', () => { ); }); -test('pathFilter can match edited files only', () => { +test('getMatchingFilePaths can match edited files only', () => { const comment: Comment = { pathFilter: ['~app/**'], markdown: 'Only deleted files', @@ -158,7 +161,7 @@ test('pathFilter can match edited files only', () => { expect(result).toEqual(changes.filter(c => c.changeType === ChangeType.edit)); }); -test('pathFilter disallows multiple modifiers', () => { +test('getMatchingFilePaths disallows multiple modifiers', () => { const comment: Comment = { pathFilter: ['!~app/**'], markdown: 'Not edited files', @@ -177,3 +180,113 @@ test('pathFilter disallows multiple modifiers', () => { 'Multiple path modifiers are not supported' ); }); + +test('getMatchingContentChanges returns all changes if contentFilter not defined', () => { + const comment: Comment = { + pathFilter: ['*'], + markdown: 'Everything', + blocking: false + }; + + const changes: Change[] = [ + { + file: 'app/models/old.rb', + changeType: ChangeType.edit, + patch: '' + }, + { + file: 'app/models/new.rb', + changeType: ChangeType.add, + patch: '' + } + ]; + + const result = getMatchingContentChanges(comment, changes); + + expect(result).toEqual(changes); +}); + +test('getMatchingContentChanges returns changes with matching regex', () => { + const comment: Comment = { + pathFilter: ['*'], + markdown: 'Everything', + blocking: false, + contentFilter: [`(\\+\\s*console.log\\(.*\\))`] + }; + + const changes: Change[] = [ + { + file: 'src/services/configReader.ts', + changeType: ChangeType.edit, + patch: + "@@ -4,14 +4,19 @@ import { safeLoad } from 'js-yaml';\n" + + " import { Constants } from '../constants';\n" + + ' \n' + + ' export function getConfiguredComments(filePath: string): Comment[] {\n' + + '+ if (!fs.existsSync(filePath)) {\n' + + '+ throw Error(`Nitpicks file does not exist: ${filePath}`);\n' + + '+ }\n' + + '+\n' + + " const contents = fs.readFileSync(filePath, 'utf8');\n" + + ' const yaml: Comment[] = safeLoad(contents);\n' + + ' \n' + + '+ console.log("this shouldnt have been committed!")\n' + + ' \n' + + ' const comments: Comment[] = yaml\n' + + '- .filter(y => y.markdown && y.pathFilter?.length > 0)\n' + + '+ .filter(y => y.markdown)\n' + + ' .map(c => ({\n' + + ' ...c,\n' + + "- markdown: `${c.markdown}${c.blocking ? Constants.BlockingText : ''}`\n" + + "+ markdown: `${c.markdown}${c.blocking ? Constants.BlockingText : ''}`,\n" + + '+ pathFilter: c.pathFilter ?? Constants.DefaultPathFilter // Default to match everything\n' + + ' }));\n' + + ' \n' + + ' return comments;' + }, + { + file: 'src/models/comment.ts', + changeType: ChangeType.edit, + patch: + '@@ -1,5 +1,6 @@\n' + + ' export interface Comment {\n' + + ' pathFilter: string[];\n' + + '+ contentFilter?: string[];\n' + + ' markdown: string;\n' + + ' blocking: boolean;\n' + + ' }' + } + ]; + + const result = getMatchingContentChanges(comment, changes); + + expect(result).toEqual(changes.slice(0, 1)); +}); + +test('getMatchingContentChanges throws error if unable to parse regexpr', () => { + const comment: Comment = { + pathFilter: ['*'], + markdown: 'Everything', + blocking: false, + contentFilter: [`(\+\s*console.log\(.*\))`] + }; + + const changes: Change[] = [ + { + file: 'src/models/comment.ts', + changeType: ChangeType.edit, + patch: + '@@ -1,5 +1,6 @@\n' + + ' export interface Comment {\n' + + ' pathFilter: string[];\n' + + '+ contentFilter?: string[];\n' + + ' markdown: string;\n' + + ' blocking: boolean;\n' + + ' }' + } + ]; + + expect(() => getMatchingContentChanges(comment, changes)).toThrowError( + 'Unable to parse regex expression' + ); +}); diff --git a/src/services/state.ts b/src/services/state.ts index d5d976f..7e0324f 100644 --- a/src/services/state.ts +++ b/src/services/state.ts @@ -194,5 +194,21 @@ export function getMatchingContentChanges( return changes; } - return []; + const matches: Change[] = []; + + for (const change of changes) { + for (const contentFilter of comment.contentFilter) { + try { + const regex = new RegExp(contentFilter); + if (regex.test(change.patch)) { + matches.push(change); + break; + } + } catch (SyntaxError) { + throw Error(`Unable to parse regex expression: ${contentFilter}`); + } + } + } + + return matches; } From 7b705a1810c0a569635eac9c77ea817895a67260 Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 12:13:10 -0700 Subject: [PATCH 11/24] Additional test cases for matching file contents --- __tests__/services/state.test.ts | 46 ++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/__tests__/services/state.test.ts b/__tests__/services/state.test.ts index ef0c488..81cd82e 100644 --- a/__tests__/services/state.test.ts +++ b/__tests__/services/state.test.ts @@ -263,6 +263,52 @@ test('getMatchingContentChanges returns changes with matching regex', () => { expect(result).toEqual(changes.slice(0, 1)); }); +test('getMatchingContentChanges returns single changes with multiple matching contentFilters', () => { + const comment: Comment = { + pathFilter: ['*'], + markdown: 'Everything', + blocking: false, + contentFilter: [`(\\+\\s*debugger)`, `(\\+\\s*console.log\\(.*\\))`] + }; + + const changes: Change[] = [ + { + file: 'src/services/configReader.ts', + changeType: ChangeType.edit, + patch: + "@@ -4,14 +4,19 @@ import { safeLoad } from 'js-yaml';\n" + + " import { Constants } from '../constants';\n" + + ' \n' + + ' export function getConfiguredComments(filePath: string): Comment[] {\n' + + '+ if (!fs.existsSync(filePath)) {\n' + + '+ throw Error(`Nitpicks file does not exist: ${filePath}`);\n' + + '+ }\n' + + '+\n' + + " const contents = fs.readFileSync(filePath, 'utf8');\n" + + ' const yaml: Comment[] = safeLoad(contents);\n' + + ' \n' + + '+ debugger\n' + + '+ console.log("this shouldnt have been committed!")\n' + + ' \n' + + ' const comments: Comment[] = yaml\n' + + '- .filter(y => y.markdown && y.pathFilter?.length > 0)\n' + + '+ .filter(y => y.markdown)\n' + + ' .map(c => ({\n' + + ' ...c,\n' + + "- markdown: `${c.markdown}${c.blocking ? Constants.BlockingText : ''}`\n" + + "+ markdown: `${c.markdown}${c.blocking ? Constants.BlockingText : ''}`,\n" + + '+ pathFilter: c.pathFilter ?? Constants.DefaultPathFilter // Default to match everything\n' + + ' }));\n' + + ' \n' + + ' return comments;' + } + ]; + + const result = getMatchingContentChanges(comment, changes); + + expect(result).toHaveLength(1); +}); + test('getMatchingContentChanges throws error if unable to parse regexpr', () => { const comment: Comment = { pathFilter: ['*'], From 05376a1a632aaf38abe50b90e041a3310a3363fc Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 12:13:28 -0700 Subject: [PATCH 12/24] Add nitpick rule for ts debugging --- .github/nitpicks.yml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/nitpicks.yml b/.github/nitpicks.yml index efa3fbc..786d503 100644 --- a/.github/nitpicks.yml +++ b/.github/nitpicks.yml @@ -1,13 +1,22 @@ - markdown: | ## Rockstar alert Thanks for this contribution, we _really_ appreciate your help :heart:! + +- markdown: | + Are you _sure_ you want to be console logging or debuggering here?? :trollface: + pathFilter: 'src/**' + contentFilter: + - '(\\+\\s*console.log\\(.*\\))' + - '(\\+\\s*debugger)' + - markdown: | Please proofread any changes to documentation. pathFilter: - '**/*.md' -- markdown: | + + - markdown: | ## Uh oh - Don't check in binaries...we use GitHub package registry for that! + Uhh... don't check in binaries here - we use GitHub package registry for that! blocking: true pathFilter: - '+**/*.dll' From 50fae5337adf3f73907901ffdc3ceaf63bc2f2ee Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 12:15:39 -0700 Subject: [PATCH 13/24] Format yaml correctly --- .github/nitpicks.yml | 5 ++--- src/services/state.ts | 2 ++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/nitpicks.yml b/.github/nitpicks.yml index 786d503..5ca3f71 100644 --- a/.github/nitpicks.yml +++ b/.github/nitpicks.yml @@ -5,7 +5,7 @@ - markdown: | Are you _sure_ you want to be console logging or debuggering here?? :trollface: pathFilter: 'src/**' - contentFilter: + contentFilter: - '(\\+\\s*console.log\\(.*\\))' - '(\\+\\s*debugger)' @@ -14,8 +14,7 @@ pathFilter: - '**/*.md' - - markdown: | - ## Uh oh +- markdown: | Uhh... don't check in binaries here - we use GitHub package registry for that! blocking: true pathFilter: diff --git a/src/services/state.ts b/src/services/state.ts index 7e0324f..292f4c9 100644 --- a/src/services/state.ts +++ b/src/services/state.ts @@ -196,6 +196,8 @@ export function getMatchingContentChanges( const matches: Change[] = []; + console.log('you found me!'); + for (const change of changes) { for (const contentFilter of comment.contentFilter) { try { From 8fe424ed1d0f16cef05460b0d15c0f1f061c7730 Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 12:22:09 -0700 Subject: [PATCH 14/24] Remove path filter from debuggering nitpick --- .github/nitpicks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/nitpicks.yml b/.github/nitpicks.yml index 5ca3f71..5a500eb 100644 --- a/.github/nitpicks.yml +++ b/.github/nitpicks.yml @@ -4,7 +4,7 @@ - markdown: | Are you _sure_ you want to be console logging or debuggering here?? :trollface: - pathFilter: 'src/**' + # pathFilter: 'src/**' contentFilter: - '(\\+\\s*console.log\\(.*\\))' - '(\\+\\s*debugger)' From ff05aef2080390feb982cd549ce8a50ac0d5e22f Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 12:23:18 -0700 Subject: [PATCH 15/24] Revert "Remove path filter from debuggering nitpick" This reverts commit 8fe424ed1d0f16cef05460b0d15c0f1f061c7730. --- .github/nitpicks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/nitpicks.yml b/.github/nitpicks.yml index 5a500eb..5ca3f71 100644 --- a/.github/nitpicks.yml +++ b/.github/nitpicks.yml @@ -4,7 +4,7 @@ - markdown: | Are you _sure_ you want to be console logging or debuggering here?? :trollface: - # pathFilter: 'src/**' + pathFilter: 'src/**' contentFilter: - '(\\+\\s*console.log\\(.*\\))' - '(\\+\\s*debugger)' From 6b84a4e203131bdbba71c8e63217e6ea6c56acd5 Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 12:24:00 -0700 Subject: [PATCH 16/24] Sanity check --- .github/nitpicks.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/nitpicks.yml b/.github/nitpicks.yml index 5ca3f71..f95931f 100644 --- a/.github/nitpicks.yml +++ b/.github/nitpicks.yml @@ -5,10 +5,10 @@ - markdown: | Are you _sure_ you want to be console logging or debuggering here?? :trollface: pathFilter: 'src/**' - contentFilter: - - '(\\+\\s*console.log\\(.*\\))' - - '(\\+\\s*debugger)' + # contentFilter: + # - '(\\+\\s*console.log\\(.*\\))' + # - '(\\+\\s*debugger)' - markdown: | Please proofread any changes to documentation. pathFilter: From 931c5b3b1e983e62f0eea8c31a22cccb6ce82659 Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 12:27:28 -0700 Subject: [PATCH 17/24] Informational logging in matching content filter --- .github/nitpicks.yml | 6 +++--- src/services/state.ts | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/nitpicks.yml b/.github/nitpicks.yml index f95931f..5ca3f71 100644 --- a/.github/nitpicks.yml +++ b/.github/nitpicks.yml @@ -5,10 +5,10 @@ - markdown: | Are you _sure_ you want to be console logging or debuggering here?? :trollface: pathFilter: 'src/**' + contentFilter: + - '(\\+\\s*console.log\\(.*\\))' + - '(\\+\\s*debugger)' - # contentFilter: - # - '(\\+\\s*console.log\\(.*\\))' - # - '(\\+\\s*debugger)' - markdown: | Please proofread any changes to documentation. pathFilter: diff --git a/src/services/state.ts b/src/services/state.ts index 292f4c9..f02b06e 100644 --- a/src/services/state.ts +++ b/src/services/state.ts @@ -199,7 +199,11 @@ export function getMatchingContentChanges( console.log('you found me!'); for (const change of changes) { + core.debug(` checking file contents ${change.file}`); + for (const contentFilter of comment.contentFilter) { + core.debug(` - ${contentFilter}`); + try { const regex = new RegExp(contentFilter); if (regex.test(change.patch)) { From d93286cb1cddd26c1320b45624f7e4fceaca8ddb Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 12:30:06 -0700 Subject: [PATCH 18/24] More (hopefully) useful logging --- src/services/state.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/services/state.ts b/src/services/state.ts index f02b06e..e91366a 100644 --- a/src/services/state.ts +++ b/src/services/state.ts @@ -207,6 +207,7 @@ export function getMatchingContentChanges( try { const regex = new RegExp(contentFilter); if (regex.test(change.patch)) { + core.debug(` matched contentFilter!`); matches.push(change); break; } From ac9aa58d5909dd9d402648da90f580f74f074131 Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 12:36:54 -0700 Subject: [PATCH 19/24] Correct valid-albeit wrong-yaml --- .github/nitpicks.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/nitpicks.yml b/.github/nitpicks.yml index 5ca3f71..649ff2a 100644 --- a/.github/nitpicks.yml +++ b/.github/nitpicks.yml @@ -4,7 +4,8 @@ - markdown: | Are you _sure_ you want to be console logging or debuggering here?? :trollface: - pathFilter: 'src/**' + pathFilter: + - 'src/**' contentFilter: - '(\\+\\s*console.log\\(.*\\))' - '(\\+\\s*debugger)' From 699410fc5d32f909d3d4c5fd0b1b5ca95fc4b022 Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 13:04:18 -0700 Subject: [PATCH 20/24] More debugging --- src/services/state.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/services/state.ts b/src/services/state.ts index e91366a..05d4cad 100644 --- a/src/services/state.ts +++ b/src/services/state.ts @@ -206,6 +206,7 @@ export function getMatchingContentChanges( try { const regex = new RegExp(contentFilter); + core.debug('patch' + change.patch); if (regex.test(change.patch)) { core.debug(` matched contentFilter!`); matches.push(change); From 23416b1925416c3563ef73e7ff3772d9d7c738c1 Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 13:10:54 -0700 Subject: [PATCH 21/24] Apparently yaml dont care about escapism --- .github/nitpicks.yml | 4 ++-- __tests__/data/default_path_filter.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/nitpicks.yml b/.github/nitpicks.yml index 649ff2a..99dadfc 100644 --- a/.github/nitpicks.yml +++ b/.github/nitpicks.yml @@ -7,8 +7,8 @@ pathFilter: - 'src/**' contentFilter: - - '(\\+\\s*console.log\\(.*\\))' - - '(\\+\\s*debugger)' + - '(\+\s*console.log\(.*\))' + - '(\+\s*debugger)' - markdown: | Please proofread any changes to documentation. diff --git a/__tests__/data/default_path_filter.yml b/__tests__/data/default_path_filter.yml index 99bf454..fc6f337 100644 --- a/__tests__/data/default_path_filter.yml +++ b/__tests__/data/default_path_filter.yml @@ -3,6 +3,6 @@ Thanks for this contribution. We _really_ appreciate your help! - markdown: | - Don't add email addresses! + Properly escaped regexp contentFilter: - - '[\w-]+@([\w-]+\.)+[\w-]+' + - '(\+\s*console.log\(.*\))' From f83062787d43fc6b4fda3dfeb5e45993bccdc8ee Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 13:12:36 -0700 Subject: [PATCH 22/24] Remove unnecessary logging --- src/services/state.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/services/state.ts b/src/services/state.ts index 05d4cad..3bcdd18 100644 --- a/src/services/state.ts +++ b/src/services/state.ts @@ -196,8 +196,6 @@ export function getMatchingContentChanges( const matches: Change[] = []; - console.log('you found me!'); - for (const change of changes) { core.debug(` checking file contents ${change.file}`); @@ -206,7 +204,6 @@ export function getMatchingContentChanges( try { const regex = new RegExp(contentFilter); - core.debug('patch' + change.patch); if (regex.test(change.patch)) { core.debug(` matched contentFilter!`); matches.push(change); From f2805c29e0977ed9749a44198b3f7b49b1b4ce0b Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 13:22:04 -0700 Subject: [PATCH 23/24] Readme updates for content filters --- README.md | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ba0a114..cc4cd8d 100644 --- a/README.md +++ b/README.md @@ -10,14 +10,21 @@ Add a new YAML file that specifies the comments to be evaluated during PRs. We r - markdown: | ## Rockstar alert Thanks for this contribution, we _really_ appreciate your help :heart:! - pathFilter: - - '*' + - markdown: | ## Uh oh Don't check in binaries...we use GitHub Packages for those! blocking: true pathFilter: - '+**/*.dll' + +- markdown: | + Are you _sure_ you want to be console logging or debuggering here?? :trollface: + pathFilter: + - 'src/**' + contentFilter: + - '(\+\s*console.log\(.*\))' + - '(\+\s*debugger)' ``` Add the Nitpicker action to your workflow and allow access to the `secrets.GITHUB_TOKEN` variable. @@ -69,6 +76,8 @@ In order for this PR to be completed, the author of the PR should address any co Path filters define which comments to add to a PR based on the set of files changed. These can either be explicit file paths or a file path pattern. If you want to add multiple path filters to a comment, they must be separated with a `,` or `;`. Comments will only be added to a PR if it changes files that match the path filter. +If no value for `pathFilter` is specified, `*`, is used. This effectively means any file path will match the comment. + Paths prefixed with `!` are excluded. For example, `!tests/**` will exclude files changed within the `tests/` directory. Paths prefixed with `+` indicate only _new_ files will match. For example, `+depot/*.dll` will match when a file with the file extension `.dll` is added to the `depot/` directory but would not match when an existing `.dll` is edited or deleted in the `depot/` directory. @@ -77,6 +86,23 @@ Paths prefixed with `-` indicate only _removed_ files will match. For example, ` Paths prefixed with `~` indicate only _edited_ files will match. For example, `~sources/*.nupkg` will match when an existing file with the file extension `.nupkg` is edited in the `sources/` directory, but would not match when a `.nugpkg` file is added or deleted in the `sources/` directory. +## Content filters + +Content filters define which comments to add based on the `patch` of the files changed. + +A comment's `contentFilter` parameter accepts an array of regular expressions that are used to match comments based on the changes to a file in a PR. These can be used in combination with path filters to create complex comment rules. For example, this rule will match any typescript file in the `src` directory, except `src/models/debug.ts`, that add a `console.log` or `debugger` statement. + +```yaml +- markdown: | + Did you _really_ mean to commit this debug statement?? + pathFilter: + - 'src/**/*.ts' + - '!src/models/debug.ts' + contentFilter: + - '(\+\s*console.log\(.*\))' + - '(\+\s*debugger)' +``` + ## Development Install the dependencies From 9197b4b7f472e0b98f53821e496c2478d731cffc Mon Sep 17 00:00:00 2001 From: Ethan Dennis Date: Fri, 26 Jun 2020 13:23:32 -0700 Subject: [PATCH 24/24] Remove unused import --- src/services/state.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/state.ts b/src/services/state.ts index 3bcdd18..59bd671 100644 --- a/src/services/state.ts +++ b/src/services/state.ts @@ -9,7 +9,7 @@ import { Comment } from '../models'; import { getExistingComments } from '.'; -import { IOptions, Minimatch, match } from 'minimatch'; +import { IOptions, Minimatch } from 'minimatch'; import { Constants } from '../constants'; const pathModifiers = ['!', '+', '-', '~'];