@sonar/scan
Version:
SonarQube/SonarCloud Scanner for the JavaScript world
129 lines (128 loc) • 5.85 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getCacheFileLocation = getCacheFileLocation;
exports.extractArchive = extractArchive;
exports.validateChecksum = validateChecksum;
exports.getCacheDirectories = getCacheDirectories;
/*
* sonar-scanner-npm
* Copyright (C) 2022-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
const adm_zip_1 = __importDefault(require("adm-zip"));
const crypto_1 = __importDefault(require("crypto"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const path_1 = __importDefault(require("path"));
const tar_stream_1 = __importDefault(require("tar-stream"));
const zlib_1 = __importDefault(require("zlib"));
const constants_1 = require("./constants");
const logging_1 = require("./logging");
const types_1 = require("./types");
async function getCacheFileLocation(properties, { checksum, filename, alias }) {
const filePath = path_1.default.join(getParentCacheDirectory(properties), checksum, filename);
if (fs_extra_1.default.existsSync(filePath)) {
(0, logging_1.log)(logging_1.LogLevel.DEBUG, alias, 'version found in cache:', filename);
// validate cache
try {
await validateChecksum(filePath, checksum);
}
catch (error) {
await fs_extra_1.default.remove(filePath);
throw error;
}
return filePath;
}
else {
(0, logging_1.log)(logging_1.LogLevel.INFO, `No Cache found for ${alias}`);
return null;
}
}
async function extractArchive(fromPath, toPath) {
(0, logging_1.log)(logging_1.LogLevel.DEBUG, `Extracting ${fromPath} to ${toPath}`);
if (fromPath.endsWith('.tar.gz')) {
const tarFilePath = fromPath;
const extract = tar_stream_1.default.extract();
const extractionPromise = new Promise((resolve, reject) => {
extract.on('entry', async (header, stream, next) => {
// Create the full path for the file
const filePath = path_1.default.join(toPath, header.name);
// Ensure the parent directory exists
await fs_extra_1.default.ensureDir(path_1.default.dirname(filePath));
stream.pipe(fs_extra_1.default.createWriteStream(filePath, { mode: header.mode }));
stream.on('end', next); // End of file, move onto next file
stream.resume(); // Auto drain the stream
});
extract.on('finish', () => {
resolve(null);
});
extract.on('error', err => {
(0, logging_1.log)(logging_1.LogLevel.ERROR, 'Error extracting tar.gz', err);
reject(err);
});
});
const readStream = fs_extra_1.default.createReadStream(tarFilePath);
const gunzip = zlib_1.default.createGunzip();
const nextStep = readStream.pipe(gunzip);
nextStep.pipe(extract);
await extractionPromise;
}
else {
const zip = new adm_zip_1.default(fromPath);
zip.extractAllTo(toPath, true, true);
}
}
async function generateChecksum(filepath) {
return new Promise((resolve, reject) => {
fs_extra_1.default.readFile(filepath, (err, data) => {
if (err) {
reject(err);
return;
}
resolve(crypto_1.default.createHash('sha256').update(data).digest('hex'));
});
});
}
async function validateChecksum(filePath, expectedChecksum) {
if (expectedChecksum) {
(0, logging_1.log)(logging_1.LogLevel.DEBUG, `Verifying checksum ${expectedChecksum}`);
const checksum = await generateChecksum(filePath);
(0, logging_1.log)(logging_1.LogLevel.DEBUG, `Checksum Value: ${checksum}`);
if (checksum !== expectedChecksum) {
throw new Error(`Checksum verification failed for ${filePath}. Expected checksum ${expectedChecksum} but got ${checksum}`);
}
}
else {
throw new Error('Checksum not provided');
}
}
async function getCacheDirectories(properties, { checksum, filename }) {
const archivePath = path_1.default.join(getParentCacheDirectory(properties), checksum, filename);
const unarchivePath = path_1.default.join(getParentCacheDirectory(properties), checksum, filename + constants_1.UNARCHIVE_SUFFIX);
// Create destination directory if it doesn't exist
const parentCacheDirectory = path_1.default.dirname(unarchivePath);
if (!fs_extra_1.default.existsSync(parentCacheDirectory)) {
(0, logging_1.log)(logging_1.LogLevel.DEBUG, `Creating Cache directory as it doesn't exist: ${parentCacheDirectory}`);
fs_extra_1.default.mkdirSync(parentCacheDirectory, { recursive: true });
}
return { archivePath, unarchivePath };
}
function getParentCacheDirectory(properties) {
return path_1.default.join(properties[types_1.ScannerProperty.SonarUserHome], constants_1.SONAR_CACHE_DIR);
}