Skip to content

Commit

Permalink
chore: set integration name for Homebrew installs
Browse files Browse the repository at this point in the history
  • Loading branch information
maxjeffos committed Oct 15, 2020
1 parent 028d178 commit 68bffc6
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 16 deletions.
28 changes: 28 additions & 0 deletions src/lib/analytics-sources.ts
Expand Up @@ -11,6 +11,7 @@
const debug = require('debug')('snyk');
import * as fs from 'fs';
import { ArgsOptions } from '../cli/args';
import { join } from 'path';

export const INTEGRATION_NAME_HEADER = 'SNYK_INTEGRATION_NAME';
export const INTEGRATION_VERSION_HEADER = 'SNYK_INTEGRATION_VERSION';
Expand Down Expand Up @@ -50,10 +51,13 @@ enum TrackedIntegration {
}

export const getIntegrationName = (args: ArgsOptions[]): string => {
const maybeHomebrew = isHomebrew() ? 'HOMEBREW' : '';
const maybeScoop = isScoop() ? 'SCOOP' : '';

const integrationName = String(
args[0]?.integrationName || // Integration details passed through CLI flag
process.env[INTEGRATION_NAME_HEADER] ||
maybeHomebrew ||
maybeScoop ||
'',
).toUpperCase();
Expand Down Expand Up @@ -114,3 +118,27 @@ export function validateScoopManifestFile(snykExecutablePath: string): boolean {
}
return false;
}

export function isHomebrew(): boolean {
const currentProcessPath = process.execPath;
const isHomebrewPath = currentProcessPath.includes('/Cellar/snyk/');
if (isHomebrewPath) {
return validateHomebrew(currentProcessPath);
} else {
return false;
}
}

export function validateHomebrew(snykExecutablePath: string): boolean {
try {
const expectedFormulaFilePath = join(
snykExecutablePath,
'../../.brew/snyk.rb',
);
const formulaFileExists = fs.existsSync(expectedFormulaFilePath);
return formulaFileExists;
} catch (error) {
debug('Error checking for Homebrew Formula file', error);
}
return false;
}
83 changes: 67 additions & 16 deletions test/analytics-sources.spec.ts
Expand Up @@ -4,9 +4,13 @@ import {
INTEGRATION_NAME_HEADER,
INTEGRATION_VERSION_HEADER,
isScoop,
isHomebrew,
validateHomebrew,
validateScoopManifestFile,
} from '../src/lib/analytics-sources';

import * as fs from 'fs';

const emptyArgs = [];
const defaultArgsParams = {
_: [],
Expand All @@ -21,16 +25,13 @@ beforeEach(() => {
describe('analytics-sources - scoop detection', () => {
it('detects if snyk is installed via scoop', () => {
const originalExecPath = process.execPath;
try {
process.execPath =
process.cwd() + '/test/fixtures/scoop/good-manifest/snyk-win.exe';
expect(isScoop()).toBe(true);
process.execPath =
process.cwd() + '/test/fixtures/scoop/good-manifest/snyk-win.exe';
expect(isScoop()).toBe(true);

process.execPath = '/test/fixtures/scoop/bad-manifest/snyk-win.exe';
expect(isScoop()).toBe(false);
} finally {
process.execPath = originalExecPath;
}
process.execPath = '/test/fixtures/scoop/bad-manifest/snyk-win.exe';
expect(isScoop()).toBe(false);
process.execPath = originalExecPath;
});

it('validates scoop manifest file', () => {
Expand All @@ -47,6 +48,51 @@ describe('analytics-sources - scoop detection', () => {
});
});

describe('analytics-sources - Homebrew detection', () => {
afterEach(() => {
jest.restoreAllMocks();
});

it('detects if snyk is installed via Homebrew', () => {
const originalExecPath = process.execPath;
process.execPath = process.cwd() + '/usr/local/Cellar/snyk/v1.413.2/bin';
const fileExistsSpy = jest.spyOn(fs, 'existsSync').mockReturnValue(true);
expect(isHomebrew()).toBe(true);
expect(fileExistsSpy).toHaveBeenCalledTimes(1);
process.execPath = originalExecPath;
});

it('returns false if formula not in Homebrew path', () => {
const originalExecPath = process.execPath;
process.execPath =
process.cwd() + '/usr/local/some-other-location/snyk/v1.413.2/bin';
const fileExistsSpy = jest.spyOn(fs, 'existsSync');
expect(isHomebrew()).toBe(false);
expect(fileExistsSpy).not.toHaveBeenCalled();
process.execPath = originalExecPath;
});

it('returns false if formula files does not exist', () => {
const originalExecPath = process.execPath;
process.execPath = process.cwd() + '/usr/local/Cellar/snyk/v1.413.2/bin';
const fileExistsSpy = jest.spyOn(fs, 'existsSync').mockReturnValue(false);
expect(isHomebrew()).toBe(false);
expect(fileExistsSpy).toHaveBeenCalledTimes(1);
process.execPath = originalExecPath;
});

it('validates Homebrew formula file exists', () => {
let snykExecPath =
process.cwd() + '/test/fixtures/homebrew/Cellar/snyk/vX/bin/snyk'; // relies on fixture at /test/fixtures/homebrew/Cellar/vX/.brew/snyk.rb
expect(validateHomebrew(snykExecPath)).toBe(true);

snykExecPath =
process.cwd() +
'/test/fixtures/homebrew/no-exist/Cellar/snyk/vX/bin/snyk';
expect(validateHomebrew(snykExecPath)).toBe(false);
});
});

describe('analytics-sources - getIntegrationName', () => {
it('integration name is empty by default', () => {
expect(getIntegrationName(emptyArgs)).toBe('');
Expand Down Expand Up @@ -83,13 +129,18 @@ describe('analytics-sources - getIntegrationName', () => {

it('integration name SCOOP when snyk is installed with scoop', () => {
const originalExecPath = process.execPath;
try {
process.execPath =
process.cwd() + '/test/fixtures/scoop/good-manifest/snyk-win.exe';
expect(getIntegrationName(emptyArgs)).toBe('SCOOP');
} finally {
process.execPath = originalExecPath;
}
process.execPath =
process.cwd() + '/test/fixtures/scoop/good-manifest/snyk-win.exe';
expect(getIntegrationName(emptyArgs)).toBe('SCOOP');
process.execPath = originalExecPath;
});

it('integration name HOMEBREW when snyk is installed with Homebrew', () => {
const originalExecPath = process.execPath;
process.execPath =
process.cwd() + '/test/fixtures/homebrew/Cellar/snyk/vX/bin/snyk'; // relies on fixture at /test/fixtures/homebrew/Cellar/vX/.brew/snyk.rb
expect(getIntegrationName(emptyArgs)).toBe('HOMEBREW');
process.execPath = originalExecPath;
});
});

Expand Down
1 change: 1 addition & 0 deletions test/fixtures/homebrew/Cellar/snyk/vX/.brew/snyk.rb
@@ -0,0 +1 @@
# fake Formula file

0 comments on commit 68bffc6

Please sign in to comment.