diff --git a/CHANGELOG.md b/CHANGELOG.md index e00b23047..f6c5e01fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). +## [1.1.89](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.89) - 2026-04-30 + +### Fixed +- `socket scan create` now matches manifest filenames case-insensitively, so capitalized files such as `Pipfile` and `Pipfile.lock` are no longer silently dropped from the scan. + ## [1.1.88](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.88) - 2026-04-29 ### Changed diff --git a/package.json b/package.json index 84a7c7825..a6a80bff9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "socket", - "version": "1.1.88", + "version": "1.1.89", "description": "CLI for Socket.dev", "homepage": "https://github.com/SocketDev/socket-cli", "license": "MIT AND OFL-1.1", diff --git a/src/commands/scan/handle-create-new-scan.mts b/src/commands/scan/handle-create-new-scan.mts index 7a0e63e0c..800d37323 100644 --- a/src/commands/scan/handle-create-new-scan.mts +++ b/src/commands/scan/handle-create-new-scan.mts @@ -57,7 +57,7 @@ function filterToCdxSpdxAndFactsFiles( return true } // Include CDX and SPDX files. - return micromatch.some(filepath, patterns) + return micromatch.some(filepath, patterns, { nocase: true }) }) } diff --git a/src/utils/glob.mts b/src/utils/glob.mts index 7fa86042f..8dbff543d 100644 --- a/src/utils/glob.mts +++ b/src/utils/glob.mts @@ -161,7 +161,9 @@ export function filterBySupportedScanFiles( supportedFiles: SocketSdkSuccessResult<'getReportSupportedFiles'>['data'], ): string[] { const patterns = getSupportedFilePatterns(supportedFiles) - return filepaths.filter(p => micromatch.some(p, patterns, { dot: true })) + return filepaths.filter(p => + micromatch.some(p, patterns, { dot: true, nocase: true }), + ) } export function createSupportedFilesFilter( @@ -169,7 +171,7 @@ export function createSupportedFilesFilter( ): (filepath: string) => boolean { const patterns = getSupportedFilePatterns(supportedFiles) return (filepath: string) => - micromatch.some(filepath, patterns, { dot: true }) + micromatch.some(filepath, patterns, { dot: true, nocase: true }) } export function getSupportedFilePatterns( @@ -311,7 +313,7 @@ export function isReportSupportedFile( supportedFiles: SocketSdkSuccessResult<'getReportSupportedFiles'>['data'], ) { const patterns = getSupportedFilePatterns(supportedFiles) - return micromatch.some(filepath, patterns, { dot: true }) + return micromatch.some(filepath, patterns, { dot: true, nocase: true }) } export function pathsToGlobPatterns( diff --git a/src/utils/path-resolve.test.mts b/src/utils/path-resolve.test.mts index 001902251..242c696ad 100644 --- a/src/utils/path-resolve.test.mts +++ b/src/utils/path-resolve.test.mts @@ -358,5 +358,64 @@ describe('Path Resolve', () => { `${mockFixturePath}/package.json`, ]) }) + + // The supported-file patterns from the SDK are lowercase (e.g. 'pipfile'), + // but real Python projects often use capitalized filenames such as + // `Pipfile` and `Pipfile.lock`. Pattern matching must be case-insensitive + // so those files are not silently dropped from the scan. + describe('case-insensitive manifest matching', () => { + const pythonPatterns = { + npm: { + packagejson: { pattern: PACKAGE_JSON }, + }, + pypi: { + pipfile: { pattern: 'pipfile' }, + pipfilelock: { pattern: 'pipfile.lock' }, + pyproject: { pattern: 'pyproject.toml' }, + requirements: { + pattern: + '{*requirements.txt,requirements/*.txt,requirements-*.txt,requirements.frozen}', + }, + setuppy: { pattern: 'setup.py' }, + uvlock: { pattern: 'uv.lock' }, + }, + } + + const sortedGetPythonFiles = sortedPromise(getPackageFilesForScan) + + it('picks up canonical Pipfile and Pipfile.lock (uppercase P)', async () => { + mockTestFs({ + [`${mockFixturePath}/project-pipfile/Pipfile`]: '', + [`${mockFixturePath}/project-pipfilelock/Pipfile.lock`]: '{}', + }) + + const actual = await sortedGetPythonFiles(['**/*'], pythonPatterns, { + cwd: mockFixturePath, + }) + expect(actual.map(normalizePath)).toEqual([ + `${mockFixturePath}/project-pipfile/Pipfile`, + `${mockFixturePath}/project-pipfilelock/Pipfile.lock`, + ]) + }) + + it('picks up every Python sibling project in a mixed-format root', async () => { + mockTestFs({ + [`${mockFixturePath}/project-a/pyproject.toml`]: '', + [`${mockFixturePath}/project-a/uv.lock`]: '', + [`${mockFixturePath}/project-a/src/main.py`]: '', + [`${mockFixturePath}/project-b/requirements.txt`]: '', + [`${mockFixturePath}/project-b/src/main.py`]: '', + }) + + const actual = await sortedGetPythonFiles(['**/*'], pythonPatterns, { + cwd: mockFixturePath, + }) + expect(actual.map(normalizePath)).toEqual([ + `${mockFixturePath}/project-a/pyproject.toml`, + `${mockFixturePath}/project-a/uv.lock`, + `${mockFixturePath}/project-b/requirements.txt`, + ]) + }) + }) }) })