From 19fa779d551960ef690e467e006c834e7aefe217 Mon Sep 17 00:00:00 2001 From: Alex Miller Date: Wed, 11 Sep 2024 13:04:01 +1200 Subject: [PATCH] Fix lint findings --- __tests__/filter.test.ts | 4 ++-- __tests__/git.test.ts | 4 ++-- src/exec.ts | 6 +++--- src/filter.ts | 17 +++++++---------- src/git.ts | 7 ++++--- src/main.ts | 24 ++++++++++++++++-------- 6 files changed, 34 insertions(+), 28 deletions(-) diff --git a/__tests__/filter.test.ts b/__tests__/filter.test.ts index b1b5d58..8e96d71 100644 --- a/__tests__/filter.test.ts +++ b/__tests__/filter.test.ts @@ -1,7 +1,7 @@ import {describe, expect, test} from 'vitest' -import {Filter} from '../src/filter' import {File, ChangeStatus} from '../src/file' +import {Filter} from '../src/filter' describe('yaml filter parsing tests', () => { test('throws if yaml is not a dictionary', () => { @@ -26,7 +26,7 @@ describe('matching tests', () => { const yaml = ` src: "src/**/*.js" ` - let filter = new Filter(yaml) + const filter = new Filter(yaml) const files = modified(['src/app/module/file.js']) const match = filter.match(files) expect(match.src).toEqual(files) diff --git a/__tests__/git.test.ts b/__tests__/git.test.ts index 38c418e..c1aa8ed 100644 --- a/__tests__/git.test.ts +++ b/__tests__/git.test.ts @@ -1,10 +1,10 @@ import {describe, expect, test} from 'vitest' -import * as git from '../src/git' import {ChangeStatus} from '../src/file' +import * as git from '../src/git' describe('parsing output of the git diff command', () => { - test('parseGitDiffOutput returns files with correct change status', async () => { + test('parseGitDiffOutput returns files with correct change status', () => { const files = git.parseGitDiffOutput( 'A\u0000LICENSE\u0000' + 'M\u0000src/index.ts\u0000' + 'D\u0000src/main.ts\u0000' ) diff --git a/src/exec.ts b/src/exec.ts index d0abd03..4fa88f5 100644 --- a/src/exec.ts +++ b/src/exec.ts @@ -3,12 +3,12 @@ import {exec as execImpl, ExecOptions} from '@actions/exec' // Wraps original exec() function // Returns exit code and whole stdout/stderr export default async function exec(commandLine: string, args?: string[], options?: ExecOptions): Promise { - options = options || {} + options = options ?? {} let stdout = '' let stderr = '' options.listeners = { - stdout: (data: Buffer) => (stdout += data.toString()), - stderr: (data: Buffer) => (stderr += data.toString()) + stdout: (data: Buffer): string => (stdout += data.toString()), + stderr: (data: Buffer): string => (stderr += data.toString()) } const code = await execImpl(commandLine, args, options) return {code, stdout, stderr} diff --git a/src/filter.ts b/src/filter.ts index 29ca0e1..8949e24 100644 --- a/src/filter.ts +++ b/src/filter.ts @@ -1,11 +1,10 @@ import * as jsyaml from 'js-yaml' import micromatch from 'micromatch' + import {File} from './file' // Type definition of object we expect to load from YAML -interface FilterYaml { - [name: string]: FilterItemYaml -} +type FilterYaml = Record type FilterItemYaml = | string // Filename pattern, e.g. "path/to/*.js" | FilterItemYaml[] // Supports referencing another rule via YAML anchor @@ -15,12 +14,10 @@ const MatchOptions: micromatch.Options = { dot: true } -export interface FilterResults { - [key: string]: File[] -} +export type FilterResults = Partial> export class Filter { - rules: {[key: string]: string[]} = {} + rules: Record = {} // Creates instance of Filter and load rules from YAML if it's provided constructor(yaml?: string) { @@ -47,9 +44,9 @@ export class Filter { match(files: File[]): FilterResults { const result: FilterResults = {} - const filesMap = files.reduce((result, x) => { - result.set(x.filename, x) - return result + const filesMap = files.reduce((fileResult, x) => { + fileResult.set(x.filename, x) + return fileResult }, new Map()) for (const [key, patterns] of Object.entries(this.rules)) { diff --git a/src/git.ts b/src/git.ts index 3d6d3be..5f96890 100644 --- a/src/git.ts +++ b/src/git.ts @@ -1,5 +1,6 @@ -import exec from './exec' import * as core from '@actions/core' + +import exec from './exec' import {File, ChangeStatus} from './file' export const NULL_SHA = '0000000000000000000000000000000000000000' @@ -215,7 +216,7 @@ async function getLocalRef(shortName: string): Promise { const output = (await exec('git', ['show-ref', shortName], {ignoreReturnCode: true})).stdout const refs = output .split(/\r?\n/g) - .map(l => l.match(/refs\/(?:(?:heads)|(?:tags)|(?:remotes\/origin))\/(.*)$/)) + .map(l => /refs\/(?:(?:heads)|(?:tags)|(?:remotes\/origin))\/(.*)$/.exec(l)) .filter(match => match !== null && match[1] === shortName) .map(match => match?.[0] ?? '') // match can't be null here but compiler doesn't understand that @@ -260,7 +261,7 @@ function fixStdOutNullTermination(): void { core.info('') } -const statusMap: {[char: string]: ChangeStatus} = { +const statusMap: Record = { A: ChangeStatus.Added, C: ChangeStatus.Copied, D: ChangeStatus.Deleted, diff --git a/src/main.ts b/src/main.ts index d99581d..51dcc72 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,13 +1,14 @@ -import * as fs from 'fs' +import * as fs from 'node:fs' + import * as core from '@actions/core' import * as github from '@actions/github' import {PullRequest, PushEvent} from '@octokit/webhooks-types' -import {Filter, FilterResults} from './filter' import {File, ChangeStatus} from './file' +import {Filter, FilterResults} from './filter' import * as git from './git' -import {backslashEscape, shellEscape} from './list-format/shell-escape' import {csvEscape} from './list-format/csv-escape' +import {backslashEscape, shellEscape} from './list-format/shell-escape' type ExportFormat = 'none' | 'csv' | 'json' | 'shell' | 'escape' @@ -95,7 +96,10 @@ async function getChangedFiles(token: string, base: string, ref: string, initial } async function getChangedFilesFromGit(base: string, head: string, initialFetchDepth: number): Promise { - const defaultBranch = github.context.payload.repository?.default_branch + const defaultBranch = + typeof github.context.payload.repository?.default_branch === 'string' + ? github.context.payload.repository.default_branch + : '' const beforeSha = github.context.eventName === 'push' ? (github.context.payload as PushEvent).before : null @@ -174,6 +178,7 @@ async function getChangedFilesFromApi(token: string, prNumber: PullRequest): Pro page }) + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (response.status !== 200) { throw new Error(`Fetching list of changed files from GitHub API failed with error code ${response.status}`) } @@ -195,8 +200,9 @@ async function getChangedFilesFromApi(token: string, prNumber: PullRequest): Pro status: ChangeStatus.Added }) files.push({ - // 'previous_filename' for some unknown reason isn't in the type definition or documentation - filename: (row).previous_filename as string, + // Existing behaviour, possibly a bug + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + filename: row.previous_filename!, status: ChangeStatus.Deleted }) } else { @@ -220,6 +226,8 @@ function exportResults(results: FilterResults, format: ExportFormat): void { core.info('Results:') const changes = [] for (const [key, files] of Object.entries(results)) { + if (!files) continue + const value = files.length > 0 core.startGroup(`Filter ${key} = ${value}`) if (files.length > 0) { @@ -241,7 +249,7 @@ function exportResults(results: FilterResults, format: ExportFormat): void { core.endGroup() } - if (results['changes'] === undefined) { + if (results.changes === undefined) { const changesJson = JSON.stringify(changes) core.info(`Changes output set to ${changesJson}`) core.setOutput('changes', changesJson) @@ -270,4 +278,4 @@ function isExportFormat(value: string): value is ExportFormat { return ['none', 'csv', 'shell', 'json', 'escape'].includes(value) } -run() +;((): Promise => run())()