Skip to content

Commit

Permalink
SCANNPM-52 Fix scanner archive directory when having an architecture
Browse files Browse the repository at this point in the history
  • Loading branch information
henryju committed Oct 14, 2024
1 parent 3a9122f commit 2db974b
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 24 deletions.
5 changes: 3 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "sonarqube-scanner",
"description": "SonarQube/SonarCloud Scanner for the JavaScript world",
"version": "4.2.4",
"version": "4.2.5",
"homepage": "https://github.com/SonarSource/sonar-scanner-npm",
"author": {
"name": "Fabrice Bellingard",
Expand Down
28 changes: 15 additions & 13 deletions src/scanner-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,31 +52,33 @@ export function normalizePlatformName(): 'windows' | 'linux' | 'macosx' {
/**
* Where to download the SonarScanner CLI
*/
function getScannerCliUrl(properties: ScannerProperties, versionStr: string): URL {
function getScannerCliUrl(
properties: ScannerProperties,
versionStr: string,
archStr?: string,
): URL {
// Get location to download scanner-cli from

// Not in default to avoid populating it for non scanner-cli users
const scannerCliMirror = properties[ScannerProperty.SonarScannerCliMirror] ?? SCANNER_CLI_MIRROR;
const version = semver.coerce(versionStr);
if (!version) {
throw new Error(`Version "${versionStr}" does not have a correct format."`);
}
const arch = version.compare('6.1.0') >= 0 ? '-x64' : '';

const scannerCliFileName =
'sonar-scanner-cli-' + versionStr + '-' + normalizePlatformName() + arch + '.zip';
let archSuffix = archStr ? `-${archStr}` : '';
const scannerCliFileName = `sonar-scanner-cli-${versionStr}-${normalizePlatformName()}${archSuffix}.zip`;
return new URL(scannerCliFileName, scannerCliMirror);
}

export async function downloadScannerCli(properties: ScannerProperties): Promise<string> {
const version = properties[ScannerProperty.SonarScannerCliVersion] ?? SCANNER_CLI_VERSION;
if (!/^[\d.]+$/.test(version)) {
throw new Error(`Version "${version}" does not have a correct format."`);
const versionStr = properties[ScannerProperty.SonarScannerCliVersion] ?? SCANNER_CLI_VERSION;
const version = semver.coerce(versionStr);
if (!version) {
throw new Error(`Version "${versionStr}" does not have a correct format."`);
}
const archStr = version.compare('6.1.0') >= 0 ? 'x64' : undefined;
let archSuffix = archStr ? `-${archStr}` : '';

// Build paths
const binExt = normalizePlatformName() === 'windows' ? '.bat' : '';
const dirName = `sonar-scanner-${version}-${normalizePlatformName()}`;
const dirName = `sonar-scanner-${versionStr}-${normalizePlatformName()}${archSuffix}`;
const installDir = path.join(properties[ScannerProperty.SonarUserHome], SCANNER_CLI_INSTALL_PATH);
const archivePath = path.join(installDir, `${dirName}.zip`);
const binPath = path.join(installDir, dirName, 'bin', `sonar-scanner${binExt}`);
Expand All @@ -89,7 +91,7 @@ export async function downloadScannerCli(properties: ScannerProperties): Promise
await fsExtra.ensureDir(installDir);

// Add basic auth credentials when used in the UR
const scannerCliUrl = getScannerCliUrl(properties, version);
const scannerCliUrl = getScannerCliUrl(properties, versionStr, archStr);
let overrides: AxiosRequestConfig | undefined;
if (scannerCliUrl.username && scannerCliUrl.password) {
overrides = {
Expand Down
73 changes: 65 additions & 8 deletions test/unit/scanner-cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ const MOCK_PROPERTIES = {
[ScannerProperty.SonarScannerCliVersion]: SCANNER_CLI_VERSION,
};

const SCANNER_CLI_VERSION_NO_ARCH = '6.0.0';
const MOCK_PROPERTIES_NO_ARCH = {
[ScannerProperty.SonarToken]: 'token',
[ScannerProperty.SonarHostUrl]: 'http://localhost:9000',
[ScannerProperty.SonarUserHome]: 'path/to/user/home',
[ScannerProperty.SonarScannerCliVersion]: SCANNER_CLI_VERSION_NO_ARCH,
};

beforeEach(() => {
childProcessHandler.reset();
});
Expand All @@ -65,7 +73,7 @@ describe('scanner-cli', () => {
const scannerBinPath = path.join(
MOCK_PROPERTIES[ScannerProperty.SonarUserHome],
SCANNER_CLI_INSTALL_PATH,
`sonar-scanner-${SCANNER_CLI_VERSION}-linux/bin/sonar-scanner`,
`sonar-scanner-${SCANNER_CLI_VERSION}-linux-x64/bin/sonar-scanner`,
);
const stub = sinon.stub(process, 'platform').value('linux');
jest.spyOn(fsExtra, 'exists').mockImplementation(_path => Promise.resolve(true));
Expand All @@ -76,6 +84,21 @@ describe('scanner-cli', () => {
stub.restore();
});

it('should use already downloaded version without arch', async () => {
const scannerBinPath = path.join(
MOCK_PROPERTIES_NO_ARCH[ScannerProperty.SonarUserHome],
SCANNER_CLI_INSTALL_PATH,
`sonar-scanner-${SCANNER_CLI_VERSION_NO_ARCH}-linux/bin/sonar-scanner`,
);
const stub = sinon.stub(process, 'platform').value('linux');
jest.spyOn(fsExtra, 'exists').mockImplementation(_path => Promise.resolve(true));

expect(await downloadScannerCli(MOCK_PROPERTIES_NO_ARCH)).toBe(scannerBinPath);
expect(download).not.toHaveBeenCalled();

stub.restore();
});

it('should download SonarScanner CLI if it does not exist on Unix', async () => {
jest.spyOn(fsExtra, 'exists').mockImplementation(_path => Promise.resolve(false));
const stub = sinon.stub(process, 'platform').value('linux');
Expand All @@ -86,23 +109,57 @@ describe('scanner-cli', () => {
path.join(
MOCK_PROPERTIES[ScannerProperty.SonarUserHome],
SCANNER_CLI_INSTALL_PATH,
`sonar-scanner-${SCANNER_CLI_VERSION}-linux/bin/sonar-scanner`,
`sonar-scanner-${SCANNER_CLI_VERSION}-linux-x64/bin/sonar-scanner`,
),
);
expect(download).toHaveBeenLastCalledWith(
`https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SCANNER_CLI_VERSION}-linux-x64.zip`,
path.join(
MOCK_PROPERTIES[ScannerProperty.SonarUserHome],
SCANNER_CLI_INSTALL_PATH,
`sonar-scanner-${SCANNER_CLI_VERSION}-linux.zip`,
`sonar-scanner-${SCANNER_CLI_VERSION}-linux-x64.zip`,
),
undefined,
);
expect(extractArchive).toHaveBeenLastCalledWith(
path.join(
MOCK_PROPERTIES[ScannerProperty.SonarUserHome],
SCANNER_CLI_INSTALL_PATH,
`sonar-scanner-${SCANNER_CLI_VERSION}-linux.zip`,
`sonar-scanner-${SCANNER_CLI_VERSION}-linux-x64.zip`,
),
path.join(MOCK_PROPERTIES[ScannerProperty.SonarUserHome], SCANNER_CLI_INSTALL_PATH),
);

stub.restore();
});

it('should download SonarScanner CLI if it does not exist on Unix without arch', async () => {
jest.spyOn(fsExtra, 'exists').mockImplementation(_path => Promise.resolve(false));
const stub = sinon.stub(process, 'platform').value('linux');

const binPath = await downloadScannerCli(MOCK_PROPERTIES_NO_ARCH);

expect(binPath).toBe(
path.join(
MOCK_PROPERTIES_NO_ARCH[ScannerProperty.SonarUserHome],
SCANNER_CLI_INSTALL_PATH,
`sonar-scanner-${SCANNER_CLI_VERSION_NO_ARCH}-linux/bin/sonar-scanner`,
),
);
expect(download).toHaveBeenLastCalledWith(
`https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SCANNER_CLI_VERSION_NO_ARCH}-linux.zip`,
path.join(
MOCK_PROPERTIES_NO_ARCH[ScannerProperty.SonarUserHome],
SCANNER_CLI_INSTALL_PATH,
`sonar-scanner-${SCANNER_CLI_VERSION_NO_ARCH}-linux.zip`,
),
undefined,
);
expect(extractArchive).toHaveBeenLastCalledWith(
path.join(
MOCK_PROPERTIES_NO_ARCH[ScannerProperty.SonarUserHome],
SCANNER_CLI_INSTALL_PATH,
`sonar-scanner-${SCANNER_CLI_VERSION_NO_ARCH}-linux.zip`,
),
path.join(MOCK_PROPERTIES[ScannerProperty.SonarUserHome], SCANNER_CLI_INSTALL_PATH),
);
Expand All @@ -121,23 +178,23 @@ describe('scanner-cli', () => {
path.join(
MOCK_PROPERTIES[ScannerProperty.SonarUserHome],
SCANNER_CLI_INSTALL_PATH,
`sonar-scanner-${SCANNER_CLI_VERSION}-windows.zip`,
`sonar-scanner-${SCANNER_CLI_VERSION}-windows-x64.zip`,
),
undefined,
);
expect(extractArchive).toHaveBeenLastCalledWith(
path.join(
MOCK_PROPERTIES[ScannerProperty.SonarUserHome],
SCANNER_CLI_INSTALL_PATH,
`sonar-scanner-${SCANNER_CLI_VERSION}-windows.zip`,
`sonar-scanner-${SCANNER_CLI_VERSION}-windows-x64.zip`,
),
path.join(MOCK_PROPERTIES[ScannerProperty.SonarUserHome], SCANNER_CLI_INSTALL_PATH),
);
expect(binPath).toBe(
path.join(
MOCK_PROPERTIES[ScannerProperty.SonarUserHome],
SCANNER_CLI_INSTALL_PATH,
`sonar-scanner-${SCANNER_CLI_VERSION}-windows/bin/sonar-scanner.bat`,
`sonar-scanner-${SCANNER_CLI_VERSION}-windows-x64/bin/sonar-scanner.bat`,
),
);

Expand All @@ -157,7 +214,7 @@ describe('scanner-cli', () => {
path.join(
MOCK_PROPERTIES[ScannerProperty.SonarUserHome],
SCANNER_CLI_INSTALL_PATH,
`sonar-scanner-${SCANNER_CLI_VERSION}-windows.zip`,
`sonar-scanner-${SCANNER_CLI_VERSION}-windows-x64.zip`,
),
{ headers: { Authorization: 'Basic bXlVc2VyOm15UGFzc3dvcmQ=' } },
);
Expand Down

0 comments on commit 2db974b

Please sign in to comment.