From 63d1b25e974e149ae85c4e6b10d3004b7b17a2d8 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 29 Sep 2025 12:50:55 +0100 Subject: [PATCH] Use `getGroupedSarifFilePaths` for `upload-sarif` Action --- lib/upload-sarif-action.js | 261 ++++++++++++++++++++----------------- src/upload-sarif.test.ts | 75 +---------- src/upload-sarif.ts | 102 +++------------ 3 files changed, 155 insertions(+), 283 deletions(-) diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index e9c9af1e0..9bf6647ec 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -185,7 +185,7 @@ var require_file_command = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.prepareKeyValueMessage = exports2.issueFileCommand = void 0; var crypto = __importStar4(require("crypto")); - var fs16 = __importStar4(require("fs")); + var fs15 = __importStar4(require("fs")); var os3 = __importStar4(require("os")); var utils_1 = require_utils(); function issueFileCommand(command, message) { @@ -193,10 +193,10 @@ var require_file_command = __commonJS({ if (!filePath) { throw new Error(`Unable to find environment variable for file command ${command}`); } - if (!fs16.existsSync(filePath)) { + if (!fs15.existsSync(filePath)) { throw new Error(`Missing file at path: ${filePath}`); } - fs16.appendFileSync(filePath, `${(0, utils_1.toCommandValue)(message)}${os3.EOL}`, { + fs15.appendFileSync(filePath, `${(0, utils_1.toCommandValue)(message)}${os3.EOL}`, { encoding: "utf8" }); } @@ -18513,12 +18513,12 @@ var require_io_util = __commonJS({ var _a; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.getCmdPath = exports2.tryGetExecutablePath = exports2.isRooted = exports2.isDirectory = exports2.exists = exports2.READONLY = exports2.UV_FS_O_EXLOCK = exports2.IS_WINDOWS = exports2.unlink = exports2.symlink = exports2.stat = exports2.rmdir = exports2.rm = exports2.rename = exports2.readlink = exports2.readdir = exports2.open = exports2.mkdir = exports2.lstat = exports2.copyFile = exports2.chmod = void 0; - var fs16 = __importStar4(require("fs")); + var fs15 = __importStar4(require("fs")); var path16 = __importStar4(require("path")); - _a = fs16.promises, exports2.chmod = _a.chmod, exports2.copyFile = _a.copyFile, exports2.lstat = _a.lstat, exports2.mkdir = _a.mkdir, exports2.open = _a.open, exports2.readdir = _a.readdir, exports2.readlink = _a.readlink, exports2.rename = _a.rename, exports2.rm = _a.rm, exports2.rmdir = _a.rmdir, exports2.stat = _a.stat, exports2.symlink = _a.symlink, exports2.unlink = _a.unlink; + _a = fs15.promises, exports2.chmod = _a.chmod, exports2.copyFile = _a.copyFile, exports2.lstat = _a.lstat, exports2.mkdir = _a.mkdir, exports2.open = _a.open, exports2.readdir = _a.readdir, exports2.readlink = _a.readlink, exports2.rename = _a.rename, exports2.rm = _a.rm, exports2.rmdir = _a.rmdir, exports2.stat = _a.stat, exports2.symlink = _a.symlink, exports2.unlink = _a.unlink; exports2.IS_WINDOWS = process.platform === "win32"; exports2.UV_FS_O_EXLOCK = 268435456; - exports2.READONLY = fs16.constants.O_RDONLY; + exports2.READONLY = fs15.constants.O_RDONLY; function exists(fsPath) { return __awaiter4(this, void 0, void 0, function* () { try { @@ -27907,8 +27907,8 @@ var require_utils7 = __commonJS({ exports2.array = array; var errno = require_errno(); exports2.errno = errno; - var fs16 = require_fs(); - exports2.fs = fs16; + var fs15 = require_fs(); + exports2.fs = fs15; var path16 = require_path(); exports2.path = path16; var pattern = require_pattern(); @@ -28092,12 +28092,12 @@ var require_fs2 = __commonJS({ "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.createFileSystemAdapter = exports2.FILE_SYSTEM_ADAPTER = void 0; - var fs16 = require("fs"); + var fs15 = require("fs"); exports2.FILE_SYSTEM_ADAPTER = { - lstat: fs16.lstat, - stat: fs16.stat, - lstatSync: fs16.lstatSync, - statSync: fs16.statSync + lstat: fs15.lstat, + stat: fs15.stat, + lstatSync: fs15.lstatSync, + statSync: fs15.statSync }; function createFileSystemAdapter(fsMethods) { if (fsMethods === void 0) { @@ -28114,12 +28114,12 @@ var require_settings = __commonJS({ "node_modules/@nodelib/fs.stat/out/settings.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - var fs16 = require_fs2(); + var fs15 = require_fs2(); var Settings = class { constructor(_options = {}) { this._options = _options; this.followSymbolicLink = this._getValue(this._options.followSymbolicLink, true); - this.fs = fs16.createFileSystemAdapter(this._options.fs); + this.fs = fs15.createFileSystemAdapter(this._options.fs); this.markSymbolicLink = this._getValue(this._options.markSymbolicLink, false); this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); } @@ -28274,8 +28274,8 @@ var require_utils8 = __commonJS({ "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.fs = void 0; - var fs16 = require_fs3(); - exports2.fs = fs16; + var fs15 = require_fs3(); + exports2.fs = fs15; } }); @@ -28470,14 +28470,14 @@ var require_fs4 = __commonJS({ "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.createFileSystemAdapter = exports2.FILE_SYSTEM_ADAPTER = void 0; - var fs16 = require("fs"); + var fs15 = require("fs"); exports2.FILE_SYSTEM_ADAPTER = { - lstat: fs16.lstat, - stat: fs16.stat, - lstatSync: fs16.lstatSync, - statSync: fs16.statSync, - readdir: fs16.readdir, - readdirSync: fs16.readdirSync + lstat: fs15.lstat, + stat: fs15.stat, + lstatSync: fs15.lstatSync, + statSync: fs15.statSync, + readdir: fs15.readdir, + readdirSync: fs15.readdirSync }; function createFileSystemAdapter(fsMethods) { if (fsMethods === void 0) { @@ -28496,12 +28496,12 @@ var require_settings2 = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); var path16 = require("path"); var fsStat = require_out(); - var fs16 = require_fs4(); + var fs15 = require_fs4(); var Settings = class { constructor(_options = {}) { this._options = _options; this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, false); - this.fs = fs16.createFileSystemAdapter(this._options.fs); + this.fs = fs15.createFileSystemAdapter(this._options.fs); this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path16.sep); this.stats = this._getValue(this._options.stats, false); this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); @@ -29762,16 +29762,16 @@ var require_settings4 = __commonJS({ "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DEFAULT_FILE_SYSTEM_ADAPTER = void 0; - var fs16 = require("fs"); + var fs15 = require("fs"); var os3 = require("os"); var CPU_COUNT = Math.max(os3.cpus().length, 1); exports2.DEFAULT_FILE_SYSTEM_ADAPTER = { - lstat: fs16.lstat, - lstatSync: fs16.lstatSync, - stat: fs16.stat, - statSync: fs16.statSync, - readdir: fs16.readdir, - readdirSync: fs16.readdirSync + lstat: fs15.lstat, + lstatSync: fs15.lstatSync, + stat: fs15.stat, + statSync: fs15.statSync, + readdir: fs15.readdir, + readdirSync: fs15.readdirSync }; var Settings = class { constructor(_options = {}) { @@ -35465,7 +35465,7 @@ var require_internal_globber = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DefaultGlobber = void 0; var core14 = __importStar4(require_core()); - var fs16 = __importStar4(require("fs")); + var fs15 = __importStar4(require("fs")); var globOptionsHelper = __importStar4(require_internal_glob_options_helper()); var path16 = __importStar4(require("path")); var patternHelper = __importStar4(require_internal_pattern_helper()); @@ -35517,7 +35517,7 @@ var require_internal_globber = __commonJS({ for (const searchPath of patternHelper.getSearchPaths(patterns)) { core14.debug(`Search path '${searchPath}'`); try { - yield __await4(fs16.promises.lstat(searchPath)); + yield __await4(fs15.promises.lstat(searchPath)); } catch (err) { if (err.code === "ENOENT") { continue; @@ -35548,7 +35548,7 @@ var require_internal_globber = __commonJS({ continue; } const childLevel = item.level + 1; - const childItems = (yield __await4(fs16.promises.readdir(item.path))).map((x) => new internal_search_state_1.SearchState(path16.join(item.path, x), childLevel)); + const childItems = (yield __await4(fs15.promises.readdir(item.path))).map((x) => new internal_search_state_1.SearchState(path16.join(item.path, x), childLevel)); stack.push(...childItems.reverse()); } else if (match & internal_match_kind_1.MatchKind.File) { yield yield __await4(item.path); @@ -35583,7 +35583,7 @@ var require_internal_globber = __commonJS({ let stats; if (options.followSymbolicLinks) { try { - stats = yield fs16.promises.stat(item.path); + stats = yield fs15.promises.stat(item.path); } catch (err) { if (err.code === "ENOENT") { if (options.omitBrokenSymbolicLinks) { @@ -35595,10 +35595,10 @@ var require_internal_globber = __commonJS({ throw err; } } else { - stats = yield fs16.promises.lstat(item.path); + stats = yield fs15.promises.lstat(item.path); } if (stats.isDirectory() && options.followSymbolicLinks) { - const realPath = yield fs16.promises.realpath(item.path); + const realPath = yield fs15.promises.realpath(item.path); while (traversalChain.length >= item.level) { traversalChain.pop(); } @@ -36932,7 +36932,7 @@ var require_cacheUtils = __commonJS({ var glob = __importStar4(require_glob()); var io6 = __importStar4(require_io()); var crypto = __importStar4(require("crypto")); - var fs16 = __importStar4(require("fs")); + var fs15 = __importStar4(require("fs")); var path16 = __importStar4(require("path")); var semver8 = __importStar4(require_semver3()); var util = __importStar4(require("util")); @@ -36962,7 +36962,7 @@ var require_cacheUtils = __commonJS({ } exports2.createTempDirectory = createTempDirectory; function getArchiveFileSizeInBytes(filePath) { - return fs16.statSync(filePath).size; + return fs15.statSync(filePath).size; } exports2.getArchiveFileSizeInBytes = getArchiveFileSizeInBytes; function resolvePaths(patterns) { @@ -37002,7 +37002,7 @@ var require_cacheUtils = __commonJS({ exports2.resolvePaths = resolvePaths; function unlinkFile(filePath) { return __awaiter4(this, void 0, void 0, function* () { - return util.promisify(fs16.unlink)(filePath); + return util.promisify(fs15.unlink)(filePath); }); } exports2.unlinkFile = unlinkFile; @@ -37047,7 +37047,7 @@ var require_cacheUtils = __commonJS({ exports2.getCacheFileName = getCacheFileName; function getGnuTarPathOnWindows() { return __awaiter4(this, void 0, void 0, function* () { - if (fs16.existsSync(constants_1.GnuTarPathOnWindows)) { + if (fs15.existsSync(constants_1.GnuTarPathOnWindows)) { return constants_1.GnuTarPathOnWindows; } const versionOutput = yield getVersion("tar"); @@ -48820,7 +48820,7 @@ var require_dist7 = __commonJS({ var stream2 = require("stream"); var coreLro = require_dist6(); var events = require("events"); - var fs16 = require("fs"); + var fs15 = require("fs"); var util = require("util"); var buffer = require("buffer"); function _interopNamespaceDefault(e) { @@ -48843,7 +48843,7 @@ var require_dist7 = __commonJS({ } var coreHttpCompat__namespace = /* @__PURE__ */ _interopNamespaceDefault(coreHttpCompat); var coreClient__namespace = /* @__PURE__ */ _interopNamespaceDefault(coreClient); - var fs__namespace = /* @__PURE__ */ _interopNamespaceDefault(fs16); + var fs__namespace = /* @__PURE__ */ _interopNamespaceDefault(fs15); var util__namespace = /* @__PURE__ */ _interopNamespaceDefault(util); var logger = logger$1.createClientLogger("storage-blob"); var BaseRequestPolicy = class { @@ -72691,7 +72691,7 @@ var require_downloadUtils = __commonJS({ var http_client_1 = require_lib(); var storage_blob_1 = require_dist7(); var buffer = __importStar4(require("buffer")); - var fs16 = __importStar4(require("fs")); + var fs15 = __importStar4(require("fs")); var stream2 = __importStar4(require("stream")); var util = __importStar4(require("util")); var utils = __importStar4(require_cacheUtils()); @@ -72802,7 +72802,7 @@ var require_downloadUtils = __commonJS({ exports2.DownloadProgress = DownloadProgress; function downloadCacheHttpClient(archiveLocation, archivePath) { return __awaiter4(this, void 0, void 0, function* () { - const writeStream = fs16.createWriteStream(archivePath); + const writeStream = fs15.createWriteStream(archivePath); const httpClient = new http_client_1.HttpClient("actions/cache"); const downloadResponse = yield (0, requestUtils_1.retryHttpClientResponse)("downloadCache", () => __awaiter4(this, void 0, void 0, function* () { return httpClient.get(archiveLocation); @@ -72828,7 +72828,7 @@ var require_downloadUtils = __commonJS({ function downloadCacheHttpClientConcurrent(archiveLocation, archivePath, options) { var _a; return __awaiter4(this, void 0, void 0, function* () { - const archiveDescriptor = yield fs16.promises.open(archivePath, "w"); + const archiveDescriptor = yield fs15.promises.open(archivePath, "w"); const httpClient = new http_client_1.HttpClient("actions/cache", void 0, { socketTimeout: options.timeoutInMs, keepAlive: true @@ -72945,7 +72945,7 @@ var require_downloadUtils = __commonJS({ } else { const maxSegmentSize = Math.min(134217728, buffer.constants.MAX_LENGTH); const downloadProgress = new DownloadProgress(contentLength); - const fd = fs16.openSync(archivePath, "w"); + const fd = fs15.openSync(archivePath, "w"); try { downloadProgress.startDisplayTimer(); const controller = new abort_controller_1.AbortController(); @@ -72963,12 +72963,12 @@ var require_downloadUtils = __commonJS({ controller.abort(); throw new Error("Aborting cache download as the download time exceeded the timeout."); } else if (Buffer.isBuffer(result)) { - fs16.writeFileSync(fd, result); + fs15.writeFileSync(fd, result); } } } finally { downloadProgress.stopDisplayTimer(); - fs16.closeSync(fd); + fs15.closeSync(fd); } } }); @@ -73267,7 +73267,7 @@ var require_cacheHttpClient = __commonJS({ var core14 = __importStar4(require_core()); var http_client_1 = require_lib(); var auth_1 = require_auth(); - var fs16 = __importStar4(require("fs")); + var fs15 = __importStar4(require("fs")); var url_1 = require("url"); var utils = __importStar4(require_cacheUtils()); var uploadUtils_1 = require_uploadUtils(); @@ -73405,7 +73405,7 @@ Other caches with similar key:`); return __awaiter4(this, void 0, void 0, function* () { const fileSize = utils.getArchiveFileSizeInBytes(archivePath); const resourceUrl = getCacheApiUrl(`caches/${cacheId.toString()}`); - const fd = fs16.openSync(archivePath, "r"); + const fd = fs15.openSync(archivePath, "r"); const uploadOptions = (0, options_1.getUploadOptions)(options); const concurrency = utils.assertDefined("uploadConcurrency", uploadOptions.uploadConcurrency); const maxChunkSize = utils.assertDefined("uploadChunkSize", uploadOptions.uploadChunkSize); @@ -73419,7 +73419,7 @@ Other caches with similar key:`); const start = offset; const end = offset + chunkSize - 1; offset += maxChunkSize; - yield uploadChunk(httpClient, resourceUrl, () => fs16.createReadStream(archivePath, { + yield uploadChunk(httpClient, resourceUrl, () => fs15.createReadStream(archivePath, { fd, start, end, @@ -73430,7 +73430,7 @@ Other caches with similar key:`); } }))); } finally { - fs16.closeSync(fd); + fs15.closeSync(fd); } return; }); @@ -80643,7 +80643,7 @@ var require_manifest = __commonJS({ var core_1 = require_core(); var os3 = require("os"); var cp = require("child_process"); - var fs16 = require("fs"); + var fs15 = require("fs"); function _findMatch(versionSpec, stable, candidates, archFilter) { return __awaiter4(this, void 0, void 0, function* () { const platFilter = os3.platform(); @@ -80707,10 +80707,10 @@ var require_manifest = __commonJS({ const lsbReleaseFile = "/etc/lsb-release"; const osReleaseFile = "/etc/os-release"; let contents = ""; - if (fs16.existsSync(lsbReleaseFile)) { - contents = fs16.readFileSync(lsbReleaseFile).toString(); - } else if (fs16.existsSync(osReleaseFile)) { - contents = fs16.readFileSync(osReleaseFile).toString(); + if (fs15.existsSync(lsbReleaseFile)) { + contents = fs15.readFileSync(lsbReleaseFile).toString(); + } else if (fs15.existsSync(osReleaseFile)) { + contents = fs15.readFileSync(osReleaseFile).toString(); } return contents; } @@ -80887,7 +80887,7 @@ var require_tool_cache = __commonJS({ var core14 = __importStar4(require_core()); var io6 = __importStar4(require_io()); var crypto = __importStar4(require("crypto")); - var fs16 = __importStar4(require("fs")); + var fs15 = __importStar4(require("fs")); var mm = __importStar4(require_manifest()); var os3 = __importStar4(require("os")); var path16 = __importStar4(require("path")); @@ -80934,7 +80934,7 @@ var require_tool_cache = __commonJS({ exports2.downloadTool = downloadTool2; function downloadToolAttempt(url2, dest, auth, headers) { return __awaiter4(this, void 0, void 0, function* () { - if (fs16.existsSync(dest)) { + if (fs15.existsSync(dest)) { throw new Error(`Destination file path ${dest} already exists`); } const http = new httpm.HttpClient(userAgent, [], { @@ -80958,7 +80958,7 @@ var require_tool_cache = __commonJS({ const readStream = responseMessageFactory(); let succeeded = false; try { - yield pipeline(readStream, fs16.createWriteStream(dest)); + yield pipeline(readStream, fs15.createWriteStream(dest)); core14.debug("download complete"); succeeded = true; return dest; @@ -81170,11 +81170,11 @@ var require_tool_cache = __commonJS({ arch2 = arch2 || os3.arch(); core14.debug(`Caching tool ${tool} ${version} ${arch2}`); core14.debug(`source dir: ${sourceDir}`); - if (!fs16.statSync(sourceDir).isDirectory()) { + if (!fs15.statSync(sourceDir).isDirectory()) { throw new Error("sourceDir is not a directory"); } const destPath = yield _createToolPath(tool, version, arch2); - for (const itemName of fs16.readdirSync(sourceDir)) { + for (const itemName of fs15.readdirSync(sourceDir)) { const s = path16.join(sourceDir, itemName); yield io6.cp(s, destPath, { recursive: true }); } @@ -81189,7 +81189,7 @@ var require_tool_cache = __commonJS({ arch2 = arch2 || os3.arch(); core14.debug(`Caching tool ${tool} ${version} ${arch2}`); core14.debug(`source file: ${sourceFile}`); - if (!fs16.statSync(sourceFile).isFile()) { + if (!fs15.statSync(sourceFile).isFile()) { throw new Error("sourceFile is not a file"); } const destFolder = yield _createToolPath(tool, version, arch2); @@ -81219,7 +81219,7 @@ var require_tool_cache = __commonJS({ versionSpec = semver8.clean(versionSpec) || ""; const cachePath = path16.join(_getCacheDirectory(), toolName, versionSpec, arch2); core14.debug(`checking cache: ${cachePath}`); - if (fs16.existsSync(cachePath) && fs16.existsSync(`${cachePath}.complete`)) { + if (fs15.existsSync(cachePath) && fs15.existsSync(`${cachePath}.complete`)) { core14.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch2}`); toolPath = cachePath; } else { @@ -81233,12 +81233,12 @@ var require_tool_cache = __commonJS({ const versions = []; arch2 = arch2 || os3.arch(); const toolPath = path16.join(_getCacheDirectory(), toolName); - if (fs16.existsSync(toolPath)) { - const children = fs16.readdirSync(toolPath); + if (fs15.existsSync(toolPath)) { + const children = fs15.readdirSync(toolPath); for (const child of children) { if (isExplicitVersion(child)) { const fullPath = path16.join(toolPath, child, arch2 || ""); - if (fs16.existsSync(fullPath) && fs16.existsSync(`${fullPath}.complete`)) { + if (fs15.existsSync(fullPath) && fs15.existsSync(`${fullPath}.complete`)) { versions.push(child); } } @@ -81312,7 +81312,7 @@ var require_tool_cache = __commonJS({ function _completeToolPath(tool, version, arch2) { const folderPath = path16.join(_getCacheDirectory(), tool, semver8.clean(version) || version, arch2 || ""); const markerPath = `${folderPath}.complete`; - fs16.writeFileSync(markerPath, ""); + fs15.writeFileSync(markerPath, ""); core14.debug("finished caching tool"); } function isExplicitVersion(versionSpec) { @@ -85706,21 +85706,21 @@ async function getFolderSize(itemPath, options) { getFolderSize.loose = async (itemPath, options) => await core(itemPath, options); getFolderSize.strict = async (itemPath, options) => await core(itemPath, options, { strict: true }); async function core(rootItemPath, options = {}, returnType = {}) { - const fs16 = options.fs || await import("node:fs/promises"); + const fs15 = options.fs || await import("node:fs/promises"); let folderSize = 0n; const foundInos = /* @__PURE__ */ new Set(); const errors = []; await processItem(rootItemPath); async function processItem(itemPath) { if (options.ignore?.test(itemPath)) return; - const stats = returnType.strict ? await fs16.lstat(itemPath, { bigint: true }) : await fs16.lstat(itemPath, { bigint: true }).catch((error2) => errors.push(error2)); + const stats = returnType.strict ? await fs15.lstat(itemPath, { bigint: true }) : await fs15.lstat(itemPath, { bigint: true }).catch((error2) => errors.push(error2)); if (typeof stats !== "object") return; if (!foundInos.has(stats.ino)) { foundInos.add(stats.ino); folderSize += stats.size; } if (stats.isDirectory()) { - const directoryItems = returnType.strict ? await fs16.readdir(itemPath) : await fs16.readdir(itemPath).catch((error2) => errors.push(error2)); + const directoryItems = returnType.strict ? await fs15.readdir(itemPath) : await fs15.readdir(itemPath).catch((error2) => errors.push(error2)); if (typeof directoryItems !== "object") return; await Promise.all( directoryItems.map( @@ -88590,6 +88590,9 @@ async function asyncSome(array, predicate) { const results = await Promise.all(array.map(predicate)); return results.some((result) => result); } +function entriesTyped(object) { + return Object.entries(object); +} // src/actions-util.ts var pkg = require_package(); @@ -88782,6 +88785,15 @@ var CodeQuality = { fixCategory: fixCodeQualityCategory, sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" }; +function getAnalysisConfig(kind) { + switch (kind) { + case "code-scanning" /* CodeScanning */: + return CodeScanning; + case "code-quality" /* CodeQuality */: + return CodeQuality; + } +} +var SarifScanOrder = [CodeQuality, CodeScanning]; // src/api-client.ts var core5 = __toESM(require_core()); @@ -93076,6 +93088,47 @@ function findSarifFilesInDir(sarifPath, isSarif) { walkSarifFiles(sarifPath); return sarifFiles; } +async function getGroupedSarifFilePaths(logger, sarifPath) { + const stats = fs14.statSync(sarifPath, { throwIfNoEntry: false }); + if (stats === void 0) { + throw new ConfigurationError(`Path does not exist: ${sarifPath}`); + } + const results = {}; + if (stats.isDirectory()) { + let sarifFiles = findSarifFilesInDir( + sarifPath, + (name) => name.endsWith(".sarif") + ); + logger.debug( + `Found the following .sarif files in ${sarifPath}: ${sarifFiles.join(", ")}` + ); + for (const analysisConfig of SarifScanOrder) { + const files = sarifFiles.filter(analysisConfig.sarifPredicate); + if (files.length > 0) { + logger.debug( + `The following SARIF files are for ${analysisConfig.name}: ${files.join(", ")}` + ); + sarifFiles = sarifFiles.filter( + (name) => !analysisConfig.sarifPredicate(name) + ); + results[analysisConfig.kind] = files; + } else { + logger.debug(`Found no SARIF files for ${analysisConfig.name}`); + } + } + } else { + for (const analysisConfig of SarifScanOrder) { + if (analysisConfig.kind === "code-scanning" /* CodeScanning */ || analysisConfig.sarifPredicate(sarifPath)) { + logger.debug( + `Using '${sarifPath}' as a SARIF file for ${analysisConfig.name}.` + ); + results[analysisConfig.kind] = [sarifPath]; + break; + } + } + } + return results; +} function countResultsInSarif(sarif) { let numResults = 0; const parsedSarif = JSON.parse(sarif); @@ -93418,61 +93471,23 @@ function filterAlertsByDiffRange(logger, sarif) { } // src/upload-sarif.ts -var fs15 = __toESM(require("fs")); -async function findAndUpload(logger, features, sarifPath, pathStats, checkoutPath, analysis, category) { - let sarifFiles; - if (pathStats.isDirectory()) { - sarifFiles = findSarifFilesInDir( - sarifPath, - analysis.sarifPredicate - ); - } else if (pathStats.isFile() && (analysis.sarifPredicate(sarifPath) || analysis.kind === "code-scanning" /* CodeScanning */ && !CodeQuality.sarifPredicate(sarifPath))) { - sarifFiles = [sarifPath]; - } else { - return void 0; - } - if (sarifFiles.length !== 0) { - return await uploadSpecifiedFiles( +async function uploadSarif(logger, features, checkoutPath, sarifPath, category) { + const sarifGroups = await getGroupedSarifFilePaths( + logger, + sarifPath + ); + const uploadResults = {}; + for (const [analysisKind, sarifFiles] of entriesTyped(sarifGroups)) { + const analysisConfig = getAnalysisConfig(analysisKind); + uploadResults[analysisKind] = await uploadSpecifiedFiles( sarifFiles, checkoutPath, - category, + analysisConfig.fixCategory(logger, category), features, logger, - analysis + analysisConfig ); } - return void 0; -} -async function uploadSarif(logger, features, checkoutPath, sarifPath, category) { - const pathStats = fs15.lstatSync(sarifPath, { throwIfNoEntry: false }); - if (pathStats === void 0) { - throw new ConfigurationError(`Path does not exist: ${sarifPath}.`); - } - const uploadResults = {}; - const uploadResult = await findAndUpload( - logger, - features, - sarifPath, - pathStats, - checkoutPath, - CodeScanning, - category - ); - if (uploadResult !== void 0) { - uploadResults["code-scanning" /* CodeScanning */] = uploadResult; - } - const qualityUploadResult = await findAndUpload( - logger, - features, - sarifPath, - pathStats, - checkoutPath, - CodeQuality, - CodeQuality.fixCategory(logger, category) - ); - if (qualityUploadResult !== void 0) { - uploadResults["code-quality" /* CodeQuality */] = qualityUploadResult; - } return uploadResults; } diff --git a/src/upload-sarif.test.ts b/src/upload-sarif.test.ts index b0a288ec5..893330eda 100644 --- a/src/upload-sarif.test.ts +++ b/src/upload-sarif.test.ts @@ -4,87 +4,16 @@ import * as path from "path"; import test, { ExecutionContext } from "ava"; import * as sinon from "sinon"; -import { - AnalysisConfig, - AnalysisKind, - CodeScanning, - getAnalysisConfig, -} from "./analyses"; +import { AnalysisKind, getAnalysisConfig } from "./analyses"; import { getRunnerLogger } from "./logging"; import { createFeatures, setupTests } from "./testing-utils"; import { UploadResult } from "./upload-lib"; import * as uploadLib from "./upload-lib"; -import { findAndUpload, uploadSarif } from "./upload-sarif"; +import { uploadSarif } from "./upload-sarif"; import * as util from "./util"; setupTests(test); -const findAndUploadMacro = test.macro({ - exec: async ( - t: ExecutionContext, - sarifFiles: string[], - analysis: AnalysisConfig, - sarifPath: (tempDir: string) => string = (tempDir) => tempDir, - expectedResult: UploadResult | undefined, - ) => { - await util.withTmpDir(async (tempDir) => { - sinon.stub(uploadLib, "uploadSpecifiedFiles").resolves(expectedResult); - const logger = getRunnerLogger(true); - const features = createFeatures([]); - - for (const sarifFile of sarifFiles) { - fs.writeFileSync(path.join(tempDir, sarifFile), ""); - } - - const stats = fs.statSync(sarifPath(tempDir)); - const actual = await findAndUpload( - logger, - features, - sarifPath(tempDir), - stats, - "", - analysis, - ); - - t.deepEqual(actual, expectedResult); - }); - }, - title: (providedTitle = "") => `findAndUpload - ${providedTitle}`, -}); - -test( - "no matching files", - findAndUploadMacro, - ["test.json"], - CodeScanning, - undefined, - undefined, -); - -test( - "matching files for Code Scanning with directory path", - findAndUploadMacro, - ["test.sarif"], - CodeScanning, - undefined, - { - statusReport: {}, - sarifID: "some-id", - }, -); - -test( - "matching files for Code Scanning with file path", - findAndUploadMacro, - ["test.sarif"], - CodeScanning, - (tempDir) => path.join(tempDir, "test.sarif"), - { - statusReport: {}, - sarifID: "some-id", - }, -); - interface UploadSarifExpectedResult { uploadResult?: UploadResult; expectedFiles?: string[]; diff --git a/src/upload-sarif.ts b/src/upload-sarif.ts index 436bb9ed8..ee685f31a 100644 --- a/src/upload-sarif.ts +++ b/src/upload-sarif.ts @@ -1,64 +1,8 @@ -import * as fs from "fs"; - import * as analyses from "./analyses"; import { FeatureEnablement } from "./feature-flags"; import { Logger } from "./logging"; import * as upload_lib from "./upload-lib"; -import { ConfigurationError } from "./util"; - -/** - * Searches for SARIF files for the given `analysis` in the given `sarifPath`. - * If any are found, then they are uploaded to the appropriate endpoint for the given `analysis`. - * - * @param logger The logger to use. - * @param features Information about FFs. - * @param sarifPath The path to a SARIF file or directory containing SARIF files. - * @param pathStats Information about `sarifPath`. - * @param checkoutPath The checkout path. - * @param analysis The configuration of the analysis we should upload SARIF files for. - * @param category The SARIF category to use for the upload. - * @returns The result of uploading the SARIF file(s) or `undefined` if there are none. - */ -export async function findAndUpload( - logger: Logger, - features: FeatureEnablement, - sarifPath: string, - pathStats: fs.Stats, - checkoutPath: string, - analysis: analyses.AnalysisConfig, - category?: string, -): Promise { - let sarifFiles: string[] | undefined; - - if (pathStats.isDirectory()) { - sarifFiles = upload_lib.findSarifFilesInDir( - sarifPath, - analysis.sarifPredicate, - ); - } else if ( - pathStats.isFile() && - (analysis.sarifPredicate(sarifPath) || - (analysis.kind === analyses.AnalysisKind.CodeScanning && - !analyses.CodeQuality.sarifPredicate(sarifPath))) - ) { - sarifFiles = [sarifPath]; - } else { - return undefined; - } - - if (sarifFiles.length !== 0) { - return await upload_lib.uploadSpecifiedFiles( - sarifFiles, - checkoutPath, - category, - features, - logger, - analysis, - ); - } - - return undefined; -} +import { entriesTyped } from "./util"; // Maps analysis kinds to SARIF IDs. export type UploadSarifResults = Partial< @@ -83,38 +27,22 @@ export async function uploadSarif( sarifPath: string, category?: string, ): Promise { - const pathStats = fs.lstatSync(sarifPath, { throwIfNoEntry: false }); - - if (pathStats === undefined) { - throw new ConfigurationError(`Path does not exist: ${sarifPath}.`); - } + const sarifGroups = await upload_lib.getGroupedSarifFilePaths( + logger, + sarifPath, + ); const uploadResults: UploadSarifResults = {}; - const uploadResult = await findAndUpload( - logger, - features, - sarifPath, - pathStats, - checkoutPath, - analyses.CodeScanning, - category, - ); - if (uploadResult !== undefined) { - uploadResults[analyses.AnalysisKind.CodeScanning] = uploadResult; - } - - // If there are `.quality.sarif` files in `sarifPath`, then upload those to the code quality service. - const qualityUploadResult = await findAndUpload( - logger, - features, - sarifPath, - pathStats, - checkoutPath, - analyses.CodeQuality, - analyses.CodeQuality.fixCategory(logger, category), - ); - if (qualityUploadResult !== undefined) { - uploadResults[analyses.AnalysisKind.CodeQuality] = qualityUploadResult; + for (const [analysisKind, sarifFiles] of entriesTyped(sarifGroups)) { + const analysisConfig = analyses.getAnalysisConfig(analysisKind); + uploadResults[analysisKind] = await upload_lib.uploadSpecifiedFiles( + sarifFiles, + checkoutPath, + analysisConfig.fixCategory(logger, category), + features, + logger, + analysisConfig, + ); } return uploadResults;