diff --git a/action-src/fixtures/cspell.json b/action-src/fixtures/cspell.json index ff5e9c284..593c3b095 100644 --- a/action-src/fixtures/cspell.json +++ b/action-src/fixtures/cspell.json @@ -1,5 +1,5 @@ { - "version": "0.1", + "version": "0.2", "words": ["camelcase", "octokit", "pollyjs", "repos", "shrinkwrap", "streetsidesoftware"], "ignorePaths": ["node_modules", "action/", "cspell.json", "__recordings__", "**/*.json"], "overrides": [ diff --git a/action-src/fixtures/sampleCode/ts/cspell.config.yaml b/action-src/fixtures/sampleCode/ts/cspell.config.yaml new file mode 100644 index 000000000..4712614cf --- /dev/null +++ b/action-src/fixtures/sampleCode/ts/cspell.config.yaml @@ -0,0 +1,4 @@ +import: + - "../../cspell.json" +files: + - "*.ts" diff --git a/action-src/src/action.test.ts b/action-src/src/action.test.ts index 773057a45..1a8bfe283 100644 --- a/action-src/src/action.test.ts +++ b/action-src/src/action.test.ts @@ -3,7 +3,7 @@ import * as path from 'path'; import { Context } from '@actions/github/lib/context.js'; import { action } from './action.js'; import { AppError } from './error.js'; -import { fetchGithubActionFixture, root } from './test/helper.js'; +import { fetchGithubActionFixture, root, sourceDir } from './test/helper.js'; import { beforeEach, describe, expect, test, vi } from 'vitest'; const configFile = path.resolve(root, 'cspell.json'); @@ -97,8 +97,8 @@ describe('Validate Action', () => { INPUT_FILES: files, INPUT_INCREMENTAL_FILES_ONLY: incremental ? 'true' : 'false', INPUT_CHECK_DOT_FILES: dot, - INPUT_ROOT: path.resolve(root, 'fixtures'), - INPUT_CONFIG: path.resolve(root, 'fixtures/cspell.json'), + INPUT_ROOT: path.resolve(sourceDir, 'fixtures'), + INPUT_CONFIG: path.resolve(sourceDir, 'fixtures/cspell.json'), }; const context = createContextFromFile(contextFile, params); await expect(action(context)).resolves.toBe(expected); diff --git a/action-src/src/action.ts b/action-src/src/action.ts index 6d006bf40..1a2e5237b 100644 --- a/action-src/src/action.ts +++ b/action-src/src/action.ts @@ -3,19 +3,18 @@ import { debug, info, error, warning, setFailed, setOutput } from '@actions/core import type { Context as GitHubContext } from '@actions/github/lib/context.js'; import type { RunResult } from 'cspell'; import * as glob from 'cspell-glob'; -import { ActionParams, validateActionParams } from './ActionParams.js'; +import { validateActionParams } from './ActionParams.js'; import { getActionParams } from './getActionParams.js'; -import { CSpellReporterForGithubAction } from './reporter.js'; -import { lint, LintOptions } from './spell.js'; import { gitListFilesForPullRequest, gitListFilesForPush, gitRoot } from './git.js'; - import type { PushEvent, PullRequestEvent } from '@octokit/webhooks-types'; +import { checkDotMap } from './checkDotMap.js'; +import { checkSpellingForContext } from './checkSpellingForContext.js'; const core = { debug, error, info, warning }; const defaultGlob = '**'; -interface Context { +export interface Context { githubContext: GitHubContext; files: string; useEventFiles: boolean; @@ -25,38 +24,6 @@ interface Context { type EventNames = 'push' | 'pull_request'; const supportedIncrementalEvents = new Set(['push', 'pull_request']); -const checkDotMap = { - true: true, - false: false, - explicit: undefined, -} as const; - -async function checkSpelling( - params: ActionParams, - globs: string[], - files: string[] | undefined, -): Promise { - const options: LintOptions = { - root: params.root || process.cwd(), - config: params.config || undefined, - checkDotFiles: checkDotMap[params.check_dot_files], - files, - }; - - if (!globs.length && !files?.length) { - return true; - } - - const reporterOptions = { - verbose: params.verbose === 'true', - }; - - const collector = new CSpellReporterForGithubAction(params.inline, reporterOptions, core); - await lint(globs, options, collector.reporter); - - return collector.result; -} - function friendlyEventName(eventName: EventNames | string): string { switch (eventName) { case 'push': @@ -72,7 +39,7 @@ function isSupportedEvent(eventName: EventNames | string): eventName is EventNam return supportedIncrementalEvents.has(eventName); } -async function gatherGitCommitFilesFromContext(context: Context): Promise { +export async function gatherGitCommitFilesFromContext(context: Context): Promise { if (context.useEventFiles) { const eventFiles = await gatherFiles(context); if (!eventFiles) return undefined; @@ -82,7 +49,7 @@ async function gatherGitCommitFilesFromContext(context: Context): Promise> { +export async function gatherFileGlobsFromContext(context: Context): Promise> { const files = new Set( context.files .split('\n') @@ -155,9 +122,7 @@ export async function action(githubContext: GitHubContext): Promise { }; core.info(friendlyEventName(eventName)); - const fileList = await gatherGitCommitFilesFromContext(context); - const files = await gatherFileGlobsFromContext(context); - const result = await checkSpelling(params, fileList ? [] : [...files], fileList); + const result = await checkSpellingForContext(params, context); if (result === true) { return true; } diff --git a/action-src/src/checkDotMap.ts b/action-src/src/checkDotMap.ts new file mode 100644 index 000000000..64d219cbd --- /dev/null +++ b/action-src/src/checkDotMap.ts @@ -0,0 +1,5 @@ +export const checkDotMap = { + true: true, + false: false, + explicit: undefined, +} as const; diff --git a/action-src/src/checkSpelling.ts b/action-src/src/checkSpelling.ts new file mode 100644 index 000000000..a8ce4c31b --- /dev/null +++ b/action-src/src/checkSpelling.ts @@ -0,0 +1,30 @@ +import { debug, info, error, warning } from '@actions/core'; +import type { RunResult } from 'cspell'; +import { ActionParams } from './ActionParams.js'; +import { CSpellReporterForGithubAction } from './reporter.js'; +import { lint, LintOptions } from './spell.js'; +import { checkDotMap } from './checkDotMap.js'; + +const core = { debug, error, info, warning }; + +export async function checkSpelling( + params: ActionParams, + globs: string[], + files: string[] | undefined, +): Promise { + const options: LintOptions = { + root: params.root || process.cwd(), + config: params.config || undefined, + checkDotFiles: checkDotMap[params.check_dot_files], + files, + }; + + const reporterOptions = { + verbose: params.verbose === 'true', + }; + + const collector = new CSpellReporterForGithubAction(params.inline, reporterOptions, core); + await lint(globs, options, collector.reporter); + + return collector.result; +} diff --git a/action-src/src/checkSpellingForContext.ts b/action-src/src/checkSpellingForContext.ts new file mode 100644 index 000000000..0d51fcda2 --- /dev/null +++ b/action-src/src/checkSpellingForContext.ts @@ -0,0 +1,11 @@ +import type { RunResult } from 'cspell'; +import { ActionParams } from './ActionParams.js'; +import { checkSpelling } from './checkSpelling.js'; +import { Context, gatherGitCommitFilesFromContext, gatherFileGlobsFromContext } from './action.js'; + +export async function checkSpellingForContext(params: ActionParams, context: Context): Promise { + const fileList = await gatherGitCommitFilesFromContext(context); + const files = await gatherFileGlobsFromContext(context); + const result = await checkSpelling(params, fileList ? [] : [...files], fileList); + return result; +} diff --git a/action-src/src/git.test.ts b/action-src/src/git.test.ts index 103f055ef..b1f5ee880 100644 --- a/action-src/src/git.test.ts +++ b/action-src/src/git.test.ts @@ -31,7 +31,7 @@ describe('git', () => { test.each` contextFile | expected ${'./pull_request_2_context.json'} | ${ac(['README.md'])} - ${'./pr_1594_context.json'} | ${ac(['action-src/build.mjs', 'package.json'])} + ${'./pr_1594_context.json'} | ${ac(['action-src/build.mjs', 'package.json', 'action-src/package.json', 'action.yaml'])} `('gitListFilesForContext $contextFile', async ({ contextFile, expected }) => { const context = await readFixtureFileJSON(contextFile); const files = await gitListFilesForContext(context); diff --git a/action-src/src/spell.test.ts b/action-src/src/spell.test.ts index 5478d8d7b..a4d594fd0 100644 --- a/action-src/src/spell.test.ts +++ b/action-src/src/spell.test.ts @@ -1,5 +1,5 @@ import * as spell from './spell.js'; -import { root } from './test/helper.js'; +import { root, sourceDir, resolveFiles, resolveFile } from './test/helper.js'; import { CSpellReporterForGithubAction, Logger } from './reporter.js'; import { describe, expect, test, vi } from 'vitest'; @@ -79,4 +79,43 @@ describe('Validate Spell Checking', () => { await spell.lint([glob], options, reporter.reporter); expect(info.sort()).toEqual(expected); }); + + const defaultResult = { + cachedFiles: 0, + errors: 0, + files: 0, + filesWithIssues: new Set(), + issues: 0, + }; + + const sampleConfig = resolveFile('fixtures/cspell.json', sourceDir); + const sampleConfigTs = resolveFile('fixtures/sampleCode/ts/cspell.config.yaml', sourceDir); + + test.only.each` + globs | files | options | expected + ${[]} | ${['fixtures/sampleCode/ts/sample.ts']} | ${{}} | ${{ files: 1 }} + ${[]} | ${['fixtures/sampleCode/ts/missing.ts']} | ${{}} | ${{ files: 0 }} + ${[]} | ${['fixtures/sampleCode/ts/cspell.config.yaml']} | ${{ config: sampleConfig }} | ${{ files: 1 }} + ${[]} | ${['fixtures/sampleCode/ts/cspell.config.yaml']} | ${{ config: sampleConfigTs }} | ${{ files: 0 }} + ${['**/*.ts']} | ${['fixtures/sampleCode/ts/cspell.config.yaml']} | ${{ config: sampleConfig }} | ${{ files: 1 }} + ${['**/ts/missing.ts']} | ${undefined} | ${{}} | ${{ files: 0 }} + `('Linting $globs $files $options', async ({ globs, files, options, expected }) => { + const opts: spell.LintOptions = { + root, + checkDotFiles: undefined, + files: resolveFiles(files, sourceDir), + ...options, + }; + const info: string[] = []; + const f = () => {}; + const logger: Logger = { + error: vi.fn(f), + debug: vi.fn(f), + info: vi.fn((msg) => info.push(msg)), + warning: vi.fn(f), + }; + const reporter = new CSpellReporterForGithubAction('none', { verbose: false }, logger); + await spell.lint(globs, opts, reporter.reporter); + expect(reporter.result).toEqual({ ...defaultResult, ...expected }); + }); }); diff --git a/action-src/src/spell.ts b/action-src/src/spell.ts index c22861f1b..41474051d 100644 --- a/action-src/src/spell.ts +++ b/action-src/src/spell.ts @@ -27,12 +27,20 @@ export async function lint(globs: string[], lintOptions: LintOptions, reporter: (globs.length && !files) || (files && !globs.length), 'Either globs or files must be specified, but not both.', ); - // console.warn('lint: %o', { globs, lintOptions }); - const options: CSpellApplicationOptions = { root, config, files, filterFiles: !files }; + // It is expected that `files` in the configuration will be used to filter the files. + const mustFindFiles = !files; + const options: CSpellApplicationOptions = { + root, + config, + files, + // filterFiles: files ? false : undefined, + mustFindFiles, + }; if (checkDotFiles) { options.dot = true; } else if (checkDotFiles === false) { options.dot = false; } + console.warn('lint: %o', { globs, lintOptions, options }); await cspellAppLint(globs, options, reporter); } diff --git a/action-src/src/test/helper.ts b/action-src/src/test/helper.ts index 6bbf4bdee..cf8c0e7e8 100644 --- a/action-src/src/test/helper.ts +++ b/action-src/src/test/helper.ts @@ -34,3 +34,12 @@ export function fetchGithubActionFixture(filename: string): Record resolveFile(file, rootDir)); +}