-
Notifications
You must be signed in to change notification settings - Fork 533
/
analytics-sources.ts
159 lines (135 loc) · 4.89 KB
/
analytics-sources.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*
We are collecting Snyk CLI usage in our official integrations
We distinguish them by either:
- Setting SNYK_INTEGRATION_NAME or SNYK_INTEGRATION_VERSION in environment when CLI is run
- passing an --integration-name or --integration-version flags on CLI invocation
Integration name is validated with a list
*/
const debug = require('debug')('snyk');
import * as fs from 'fs';
import { ArgsOptions } from '../cli/args';
import { join } from 'path';
export const INTEGRATION_NAME_ENVVAR = 'SNYK_INTEGRATION_NAME';
export const INTEGRATION_VERSION_ENVVAR = 'SNYK_INTEGRATION_VERSION';
export const INTEGRATION_ENVIRONMENT_ENVVAR = 'SNYK_INTEGRATION_ENVIRONMENT';
export const INTEGRATION_ENVIRONMENT_VERSION_ENVVAR =
'SNYK_INTEGRATION_ENVIRONMENT_VERSION';
enum TrackedIntegration {
// Distribution builds/packages
NPM = 'NPM', // registry - how can we detect this one? Not standalone?
STANDALONE = 'STANDALONE', // Tracked by detecting "isStandalone" flag
// tracked by passing envvar on CLI invocation
HOMEBREW = 'HOMEBREW',
SCOOP = 'SCOOP',
// Our Docker images - tracked by passing envvar on CLI invocation
DOCKER_SNYK_CLI = 'DOCKER_SNYK_CLI', // docker snyk/snyk-cli
DOCKER_SNYK = 'DOCKER_SNYK', // docker snyk/snyk
// IDE plugins - tracked by passing flag or envvar on CLI invocation
JETBRAINS_IDE = 'JETBRAINS_IDE',
ECLIPSE = 'ECLIPSE',
VS_CODE_VULN_COST = 'VS_CODE_VULN_COST',
// CI - tracked by passing flag or envvar on CLI invocation
JENKINS = 'JENKINS',
TEAMCITY = 'TEAMCITY',
BITBUCKET_PIPELINES = 'BITBUCKET_PIPELINES',
AZURE_PIPELINES = 'AZURE_PIPELINES',
CIRCLECI_ORB = 'CIRCLECI_ORB',
GITHUB_ACTIONS = 'GITHUB_ACTIONS',
// Partner integrations - tracked by passing envvar on CLI invocation
DOCKER_DESKTOP = 'DOCKER_DESKTOP',
// DevRel integrations and plugins
// Netlify plugin: https://github.com/snyk-labs/netlify-plugin-snyk
NETLIFY_PLUGIN = 'NETLIFY_PLUGIN',
}
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_ENVVAR] ||
maybeHomebrew ||
maybeScoop ||
'',
).toUpperCase();
if (integrationName in TrackedIntegration) {
return integrationName;
}
return '';
};
export const getIntegrationVersion = (args: ArgsOptions[]): string => {
// Integration details passed through CLI flag
const integrationVersion = String(
args[0]?.integrationVersion ||
process.env[INTEGRATION_VERSION_ENVVAR] ||
'',
);
return integrationVersion;
};
export const getIntegrationEnvironment = (args: ArgsOptions[]): string | void =>
(args[0]?.integrationEnvironment as string) ||
process.env[INTEGRATION_ENVIRONMENT_ENVVAR] ||
undefined;
export const getIntegrationEnvironmentVersion = (
args: ArgsOptions[],
): string | void =>
(args[0]?.integrationEnvironmentVersion as string) ||
process.env[INTEGRATION_ENVIRONMENT_VERSION_ENVVAR] ||
undefined;
export function isScoop(): boolean {
const currentProcessPath = process.execPath;
const looksLikeScoop =
currentProcessPath.includes('snyk-win.exe') &&
currentProcessPath.includes('scoop');
if (looksLikeScoop) {
return validateScoopManifestFile(currentProcessPath);
} else {
return false;
}
}
export function validateScoopManifestFile(snykExecutablePath: string): boolean {
// If this really is installed with scoop, there should be a `manifest.json` file adjacent to the running CLI executable (`snyk-win.exe`) which
// we can look at for further validation that this really is from scoop.
try {
const snykScoopManifiestPath = snykExecutablePath.replace(
'snyk-win.exe',
'manifest.json',
);
if (fs.existsSync(snykScoopManifiestPath)) {
const manifestJson = JSON.parse(
fs.readFileSync(snykScoopManifiestPath, 'utf8'),
);
const url = manifestJson.url;
if (
url.startsWith('https://github.com/snyk/snyk') &&
url.endsWith('snyk-win.exe')
) {
return true;
}
}
} catch (error) {
debug('Error validating scoop manifest file', error);
}
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;
}