@sentry/cli 1.74.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/sentry-cli +4 -4
- package/checksums.txt +9 -9
- package/js/helper.js +1 -1
- package/js/releases/index.js +12 -17
- package/package.json +21 -33
- package/scripts/install.js +86 -92
- package/CHANGELOG.md +0 -1093
package/bin/sentry-cli
CHANGED
|
@@ -3,17 +3,17 @@
|
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
5
5
|
const childProcess = require('child_process');
|
|
6
|
-
const
|
|
6
|
+
const SentryCli = require('../js');
|
|
7
7
|
|
|
8
8
|
const child = childProcess
|
|
9
|
-
.spawn(
|
|
9
|
+
.spawn(SentryCli.getPath(), process.argv.slice(2), {
|
|
10
10
|
stdio: 'inherit',
|
|
11
11
|
})
|
|
12
|
-
.on('error', err => {
|
|
12
|
+
.on('error', (err) => {
|
|
13
13
|
console.error(err); // eslint-disable-line no-console
|
|
14
14
|
process.exit(1);
|
|
15
15
|
})
|
|
16
|
-
.on('exit', code => process.exit(code));
|
|
16
|
+
.on('exit', (code) => process.exit(code));
|
|
17
17
|
|
|
18
18
|
process.on('SIGTERM', () => child.kill('SIGTERM'));
|
|
19
19
|
process.on('SIGINT', () => child.kill('SIGINT'));
|
package/checksums.txt
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
sentry-cli-Darwin-arm64=
|
|
2
|
-
sentry-cli-Darwin-universal=
|
|
3
|
-
sentry-cli-Darwin-x86_64=
|
|
4
|
-
sentry-cli-Linux-aarch64=
|
|
5
|
-
sentry-cli-Linux-armv7=
|
|
6
|
-
sentry-cli-Linux-i686=
|
|
7
|
-
sentry-cli-Linux-x86_64=
|
|
8
|
-
sentry-cli-Windows-i686.exe=
|
|
9
|
-
sentry-cli-Windows-x86_64.exe=
|
|
1
|
+
sentry-cli-Darwin-arm64=195df7af336ae6761ac160b57bcd9b43d304d2c48c6835d05d2dd203caf50a14
|
|
2
|
+
sentry-cli-Darwin-universal=edeaf887e46fb7c8702463ab0821502bba2f41c3cb497507fb3bfbe4635727c4
|
|
3
|
+
sentry-cli-Darwin-x86_64=5e5a7d7270ba9486744fc6c1846efba9276fa3a2732ded90daf185bb6ec461f3
|
|
4
|
+
sentry-cli-Linux-aarch64=43d08d15409aec8925c84364a9976ef00ceed7bb78343151a6705c5fd735833f
|
|
5
|
+
sentry-cli-Linux-armv7=850b0d0c0f1995c34fd9721cf83783d29ab7f32d486273c09348af42f66ecf87
|
|
6
|
+
sentry-cli-Linux-i686=a83ce83846d8d7456212e3224b34e0da7213611e49d75e8aa58ccd2f3219220e
|
|
7
|
+
sentry-cli-Linux-x86_64=f1231a5d8d2c0d2a96b61ddf85ad10274731cb904665593bc02427c130728084
|
|
8
|
+
sentry-cli-Windows-i686.exe=7fac8c66defd3aea009a53678c625070557b437c8fb5a95670069bb36e656d2f
|
|
9
|
+
sentry-cli-Windows-x86_64.exe=5c7eb3072edc4901d02095155b0d1b30c003c53b25e4aa0dd21b31e510c1bde2
|
package/js/helper.js
CHANGED
|
@@ -133,7 +133,7 @@ function getPath() {
|
|
|
133
133
|
* @param {Object} [config] More configuration to pass to the CLI
|
|
134
134
|
* @returns {Promise.<string>} A promise that resolves to the standard output.
|
|
135
135
|
*/
|
|
136
|
-
function execute(args, live, silent, configFile, config = {}) {
|
|
136
|
+
async function execute(args, live, silent, configFile, config = {}) {
|
|
137
137
|
const env = { ...process.env };
|
|
138
138
|
if (configFile) {
|
|
139
139
|
env.SENTRY_PROPERTIES = configFile;
|
package/js/releases/index.js
CHANGED
|
@@ -50,7 +50,7 @@ class Releases {
|
|
|
50
50
|
* @returns {Promise} A promise that resolves when the release has been created.
|
|
51
51
|
* @memberof SentryReleases
|
|
52
52
|
*/
|
|
53
|
-
new(release, options) {
|
|
53
|
+
async new(release, options) {
|
|
54
54
|
const args = ['releases', 'new', release].concat(helper.getProjectFlagsFromOptions(options));
|
|
55
55
|
return this.execute(args, null);
|
|
56
56
|
}
|
|
@@ -76,7 +76,7 @@ class Releases {
|
|
|
76
76
|
* @returns {Promise} A promise that resolves when the commits have been associated
|
|
77
77
|
* @memberof SentryReleases
|
|
78
78
|
*/
|
|
79
|
-
setCommits(release, options) {
|
|
79
|
+
async setCommits(release, options) {
|
|
80
80
|
if (!options || (!options.auto && (!options.repo || !options.commit))) {
|
|
81
81
|
throw new Error('options.auto, or options.repo and options.commit must be specified');
|
|
82
82
|
}
|
|
@@ -95,10 +95,6 @@ class Releases {
|
|
|
95
95
|
commitFlags.push('--ignore-missing');
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
if (options.ignoreEmpty) {
|
|
99
|
-
commitFlags.push('--ignore-empty');
|
|
100
|
-
}
|
|
101
|
-
|
|
102
98
|
return this.execute(['releases', 'set-commits', release].concat(commitFlags));
|
|
103
99
|
}
|
|
104
100
|
|
|
@@ -110,7 +106,7 @@ class Releases {
|
|
|
110
106
|
* @returns {Promise} A promise that resolves when the release has been finalized.
|
|
111
107
|
* @memberof SentryReleases
|
|
112
108
|
*/
|
|
113
|
-
finalize(release) {
|
|
109
|
+
async finalize(release) {
|
|
114
110
|
return this.execute(['releases', 'finalize', release], null);
|
|
115
111
|
}
|
|
116
112
|
|
|
@@ -121,10 +117,9 @@ class Releases {
|
|
|
121
117
|
* @returns {Promise.<string>} A promise that resolves to the version string.
|
|
122
118
|
* @memberof SentryReleases
|
|
123
119
|
*/
|
|
124
|
-
proposeVersion() {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
);
|
|
120
|
+
async proposeVersion() {
|
|
121
|
+
const version = await this.execute(['releases', 'propose-version'], null);
|
|
122
|
+
return version.trim();
|
|
128
123
|
}
|
|
129
124
|
|
|
130
125
|
/**
|
|
@@ -159,7 +154,7 @@ class Releases {
|
|
|
159
154
|
* @returns {Promise} A promise that resolves when the upload has completed successfully.
|
|
160
155
|
* @memberof SentryReleases
|
|
161
156
|
*/
|
|
162
|
-
uploadSourceMaps(release, options) {
|
|
157
|
+
async uploadSourceMaps(release, options) {
|
|
163
158
|
if (!options || !options.include || !Array.isArray(options.include)) {
|
|
164
159
|
throw new Error(
|
|
165
160
|
'`options.include` must be a vaild array of paths and/or path descriptor objects.'
|
|
@@ -169,7 +164,7 @@ class Releases {
|
|
|
169
164
|
// Each entry in the `include` array will map to an array of promises, which
|
|
170
165
|
// will in turn contain one promise per literal path value. Thus `uploads`
|
|
171
166
|
// will be an array of Promise arrays, which we'll flatten later.
|
|
172
|
-
const uploads = options.include.map(includeEntry => {
|
|
167
|
+
const uploads = options.include.map((includeEntry) => {
|
|
173
168
|
let pathOptions;
|
|
174
169
|
let uploadPaths;
|
|
175
170
|
|
|
@@ -200,7 +195,7 @@ class Releases {
|
|
|
200
195
|
.concat(helper.getProjectFlagsFromOptions(options))
|
|
201
196
|
.concat(['files', release, 'upload-sourcemaps']);
|
|
202
197
|
|
|
203
|
-
return uploadPaths.map(path =>
|
|
198
|
+
return uploadPaths.map((path) =>
|
|
204
199
|
// `execute()` is async and thus we're returning a promise here
|
|
205
200
|
this.execute(helper.prepareCommand([...args, path], SOURCEMAPS_SCHEMA, newOptions), true)
|
|
206
201
|
);
|
|
@@ -221,7 +216,7 @@ class Releases {
|
|
|
221
216
|
* @returns {Promise} A promise that resolves when the list comes back from the server.
|
|
222
217
|
* @memberof SentryReleases
|
|
223
218
|
*/
|
|
224
|
-
listDeploys(release) {
|
|
219
|
+
async listDeploys(release) {
|
|
225
220
|
return this.execute(['releases', 'deploys', release, 'list'], null);
|
|
226
221
|
}
|
|
227
222
|
|
|
@@ -247,7 +242,7 @@ class Releases {
|
|
|
247
242
|
* @returns {Promise} A promise that resolves when the deploy has been created.
|
|
248
243
|
* @memberof SentryReleases
|
|
249
244
|
*/
|
|
250
|
-
newDeploy(release, options) {
|
|
245
|
+
async newDeploy(release, options) {
|
|
251
246
|
if (!options || !options.env) {
|
|
252
247
|
throw new Error('options.env must be a vaild name');
|
|
253
248
|
}
|
|
@@ -261,7 +256,7 @@ class Releases {
|
|
|
261
256
|
* @param {boolean} live We inherit stdio to display `sentry-cli` output directly.
|
|
262
257
|
* @returns {Promise.<string>} A promise that resolves to the standard output.
|
|
263
258
|
*/
|
|
264
|
-
execute(args, live) {
|
|
259
|
+
async execute(args, live) {
|
|
265
260
|
return helper.execute(args, live, this.options.silent, this.configFile, this.options);
|
|
266
261
|
}
|
|
267
262
|
}
|
package/package.json
CHANGED
|
@@ -1,28 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "A command line utility to work with Sentry. https://docs.sentry.io/hosted/learn/cli/",
|
|
5
|
+
"repository": "git://github.com/getsentry/sentry-cli.git",
|
|
5
6
|
"homepage": "https://docs.sentry.io/hosted/learn/cli/",
|
|
7
|
+
"author": "Sentry",
|
|
6
8
|
"license": "BSD-3-Clause",
|
|
7
|
-
"keywords": [
|
|
8
|
-
"sentry",
|
|
9
|
-
"sentry-cli",
|
|
10
|
-
"cli"
|
|
11
|
-
],
|
|
12
|
-
"repository": {
|
|
13
|
-
"type": "git",
|
|
14
|
-
"url": "https://github.com/getsentry/sentry-cli"
|
|
15
|
-
},
|
|
16
|
-
"bugs": {
|
|
17
|
-
"url": "https://github.com/getsentry/sentry-cli/issues"
|
|
18
|
-
},
|
|
19
9
|
"engines": {
|
|
20
|
-
"node": ">=
|
|
10
|
+
"node": ">= 12"
|
|
21
11
|
},
|
|
22
12
|
"main": "js/index.js",
|
|
13
|
+
"types": "js/index.d.ts",
|
|
23
14
|
"bin": {
|
|
24
15
|
"sentry-cli": "bin/sentry-cli"
|
|
25
16
|
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"https-proxy-agent": "^5.0.0",
|
|
19
|
+
"node-fetch": "^3.2.3",
|
|
20
|
+
"npmlog": "^6.0.1",
|
|
21
|
+
"progress": "^2.0.3",
|
|
22
|
+
"proxy-from-env": "^1.1.0",
|
|
23
|
+
"which": "^2.0.2"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"eslint": "^8.13.0",
|
|
27
|
+
"eslint-config-prettier": "^8.5.0",
|
|
28
|
+
"jest": "^27.5.1",
|
|
29
|
+
"npm-run-all": "^4.1.5",
|
|
30
|
+
"prettier": "^2.6.2"
|
|
31
|
+
},
|
|
26
32
|
"scripts": {
|
|
27
33
|
"install": "node ./scripts/install.js",
|
|
28
34
|
"fix": "npm-run-all fix:eslint fix:prettier",
|
|
@@ -34,29 +40,11 @@
|
|
|
34
40
|
"test:eslint": "eslint bin/* scripts/**/*.js js/**/*.js",
|
|
35
41
|
"test:prettier": "prettier --check bin/* scripts/**/*.js js/**/*.js"
|
|
36
42
|
},
|
|
37
|
-
"dependencies": {
|
|
38
|
-
"https-proxy-agent": "^5.0.0",
|
|
39
|
-
"mkdirp": "^0.5.5",
|
|
40
|
-
"node-fetch": "^2.6.7",
|
|
41
|
-
"npmlog": "^4.1.2",
|
|
42
|
-
"progress": "^2.0.3",
|
|
43
|
-
"proxy-from-env": "^1.1.0",
|
|
44
|
-
"which": "^2.0.2"
|
|
45
|
-
},
|
|
46
|
-
"devDependencies": {
|
|
47
|
-
"eslint": "^6.8.0",
|
|
48
|
-
"eslint-config-airbnb-base": "^14.1.0",
|
|
49
|
-
"eslint-config-prettier": "^6.10.1",
|
|
50
|
-
"eslint-plugin-import": "^2.20.2",
|
|
51
|
-
"jest": "^25.3.0",
|
|
52
|
-
"npm-run-all": "^4.1.5",
|
|
53
|
-
"prettier": "^1.19.1"
|
|
54
|
-
},
|
|
55
43
|
"jest": {
|
|
56
44
|
"collectCoverage": true,
|
|
57
45
|
"testEnvironment": "node",
|
|
58
46
|
"testPathIgnorePatterns": [
|
|
59
|
-
"src
|
|
47
|
+
"<rootDir>/src"
|
|
60
48
|
]
|
|
61
49
|
}
|
|
62
50
|
}
|
package/scripts/install.js
CHANGED
|
@@ -11,12 +11,10 @@ const zlib = require('zlib');
|
|
|
11
11
|
const stream = require('stream');
|
|
12
12
|
const process = require('process');
|
|
13
13
|
|
|
14
|
+
const fetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args));
|
|
14
15
|
const HttpsProxyAgent = require('https-proxy-agent');
|
|
15
|
-
const fetch = require('node-fetch');
|
|
16
16
|
const ProgressBar = require('progress');
|
|
17
17
|
const Proxy = require('proxy-from-env');
|
|
18
|
-
// NOTE: Can be dropped in favor of `fs.mkdirSync(path, { recursive: true })` once we stop supporting Node 8.x
|
|
19
|
-
const mkdirp = require('mkdirp');
|
|
20
18
|
const npmLog = require('npmlog');
|
|
21
19
|
const which = require('which');
|
|
22
20
|
|
|
@@ -46,10 +44,9 @@ function getLogStream(defaultStream) {
|
|
|
46
44
|
}
|
|
47
45
|
|
|
48
46
|
function shouldRenderProgressBar() {
|
|
49
|
-
const silentFlag = process.argv.some(v => v === '--silent');
|
|
47
|
+
const silentFlag = process.argv.some((v) => v === '--silent');
|
|
50
48
|
const silentConfig = process.env.npm_config_loglevel === 'silent';
|
|
51
|
-
|
|
52
|
-
const silentEnv = process.env.SENTRYCLI_NO_PROGRESS_BAR || process.env.SENTRY_NO_PROGRESS_BAR;
|
|
49
|
+
const silentEnv = process.env.SENTRYCLI_NO_PROGRESS_BAR;
|
|
53
50
|
const ciEnv = process.env.CI === 'true';
|
|
54
51
|
// If any of possible options is set, skip rendering of progress bar
|
|
55
52
|
return !(silentFlag || silentConfig || silentEnv || ciEnv);
|
|
@@ -111,7 +108,7 @@ function createProgressBar(name, total) {
|
|
|
111
108
|
let pct = null;
|
|
112
109
|
let current = 0;
|
|
113
110
|
return {
|
|
114
|
-
tick: length => {
|
|
111
|
+
tick: (length) => {
|
|
115
112
|
current += length;
|
|
116
113
|
const next = Math.round((current / total) * 100);
|
|
117
114
|
if (next > pct) {
|
|
@@ -133,11 +130,7 @@ function npmCache() {
|
|
|
133
130
|
}
|
|
134
131
|
|
|
135
132
|
function getCachedPath(url) {
|
|
136
|
-
const digest = crypto
|
|
137
|
-
.createHash('md5')
|
|
138
|
-
.update(url)
|
|
139
|
-
.digest('hex')
|
|
140
|
-
.slice(0, 6);
|
|
133
|
+
const digest = crypto.createHash('md5').update(url).digest('hex').slice(0, 6);
|
|
141
134
|
|
|
142
135
|
return path.join(
|
|
143
136
|
npmCache(),
|
|
@@ -147,9 +140,7 @@ function getCachedPath(url) {
|
|
|
147
140
|
}
|
|
148
141
|
|
|
149
142
|
function getTempFile(cached) {
|
|
150
|
-
return `${cached}.${process.pid}-${Math.random()
|
|
151
|
-
.toString(16)
|
|
152
|
-
.slice(2)}.tmp`;
|
|
143
|
+
return `${cached}.${process.pid}-${Math.random().toString(16).slice(2)}.tmp`;
|
|
153
144
|
}
|
|
154
145
|
|
|
155
146
|
function validateChecksum(tempPath, name) {
|
|
@@ -176,10 +167,7 @@ function validateChecksum(tempPath, name) {
|
|
|
176
167
|
return;
|
|
177
168
|
}
|
|
178
169
|
|
|
179
|
-
const currentHash = crypto
|
|
180
|
-
.createHash('sha256')
|
|
181
|
-
.update(fs.readFileSync(tempPath))
|
|
182
|
-
.digest('hex');
|
|
170
|
+
const currentHash = crypto.createHash('sha256').update(fs.readFileSync(tempPath)).digest('hex');
|
|
183
171
|
|
|
184
172
|
if (storedHash !== currentHash) {
|
|
185
173
|
fs.unlinkSync(tempPath);
|
|
@@ -191,7 +179,7 @@ function validateChecksum(tempPath, name) {
|
|
|
191
179
|
}
|
|
192
180
|
}
|
|
193
181
|
|
|
194
|
-
function downloadBinary() {
|
|
182
|
+
async function downloadBinary() {
|
|
195
183
|
const arch = os.arch();
|
|
196
184
|
const platform = os.platform();
|
|
197
185
|
const outputPath = helper.getPath();
|
|
@@ -212,14 +200,14 @@ function downloadBinary() {
|
|
|
212
200
|
|
|
213
201
|
const downloadUrl = getDownloadUrl(platform, arch);
|
|
214
202
|
if (!downloadUrl) {
|
|
215
|
-
|
|
203
|
+
throw new Error(`Unsupported target ${platform}-${arch}`);
|
|
216
204
|
}
|
|
217
205
|
|
|
218
206
|
const cachedPath = getCachedPath(downloadUrl);
|
|
219
207
|
if (fs.existsSync(cachedPath)) {
|
|
220
208
|
npmLog.info('sentry-cli', `Using cached binary: ${cachedPath}`);
|
|
221
209
|
fs.copyFileSync(cachedPath, outputPath);
|
|
222
|
-
return
|
|
210
|
+
return;
|
|
223
211
|
}
|
|
224
212
|
|
|
225
213
|
const proxyUrl = Proxy.getProxyForUrl(downloadUrl);
|
|
@@ -231,74 +219,77 @@ function downloadBinary() {
|
|
|
231
219
|
npmLog.info('sentry-cli', `Using proxy URL: ${proxyUrl}`);
|
|
232
220
|
}
|
|
233
221
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
if (!response.ok) {
|
|
244
|
-
throw new Error(
|
|
245
|
-
`Unable to download sentry-cli binary from ${downloadUrl}.\nServer returned ${response.status}: ${response.statusText}.`
|
|
246
|
-
);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
const contentEncoding = response.headers.get('content-encoding');
|
|
250
|
-
let decompressor;
|
|
251
|
-
if (/\bgzip\b/.test(contentEncoding)) {
|
|
252
|
-
decompressor = zlib.createGunzip();
|
|
253
|
-
} else if (/\bdeflate\b/.test(contentEncoding)) {
|
|
254
|
-
decompressor = zlib.createInflate();
|
|
255
|
-
} else if (/\bbr\b/.test(contentEncoding)) {
|
|
256
|
-
decompressor = zlib.createBrotliDecompress();
|
|
257
|
-
} else {
|
|
258
|
-
decompressor = new stream.PassThrough();
|
|
259
|
-
}
|
|
260
|
-
const name = downloadUrl.match(/.*\/(.*?)$/)[1];
|
|
261
|
-
const total = parseInt(response.headers.get('content-length'), 10);
|
|
262
|
-
const progressBar = createProgressBar(name, total);
|
|
263
|
-
const tempPath = getTempFile(cachedPath);
|
|
264
|
-
mkdirp.sync(path.dirname(tempPath));
|
|
265
|
-
|
|
266
|
-
return new Promise((resolve, reject) => {
|
|
267
|
-
response.body
|
|
268
|
-
.on('error', e => reject(e))
|
|
269
|
-
.on('data', chunk => progressBar.tick(chunk.length))
|
|
270
|
-
.pipe(decompressor)
|
|
271
|
-
.pipe(fs.createWriteStream(tempPath, { mode: '0755' }))
|
|
272
|
-
.on('error', e => reject(e))
|
|
273
|
-
.on('close', () => resolve());
|
|
274
|
-
}).then(() => {
|
|
275
|
-
if (process.env.SENTRYCLI_SKIP_CHECKSUM_VALIDATION !== '1') {
|
|
276
|
-
validateChecksum(tempPath, name);
|
|
277
|
-
}
|
|
278
|
-
fs.copyFileSync(tempPath, cachedPath);
|
|
279
|
-
fs.copyFileSync(tempPath, outputPath);
|
|
280
|
-
fs.unlinkSync(tempPath);
|
|
281
|
-
});
|
|
282
|
-
})
|
|
283
|
-
.catch(error => {
|
|
284
|
-
if (error instanceof fetch.FetchError) {
|
|
285
|
-
throw new Error(
|
|
286
|
-
`Unable to download sentry-cli binary from ${downloadUrl}.\nError code: ${error.code}`
|
|
287
|
-
);
|
|
288
|
-
} else {
|
|
289
|
-
throw error;
|
|
290
|
-
}
|
|
222
|
+
let response;
|
|
223
|
+
try {
|
|
224
|
+
response = await fetch(downloadUrl, {
|
|
225
|
+
agent,
|
|
226
|
+
compress: false,
|
|
227
|
+
headers: {
|
|
228
|
+
'accept-encoding': 'gzip, deflate, br',
|
|
229
|
+
},
|
|
230
|
+
redirect: 'follow',
|
|
291
231
|
});
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
throw new Error(`Unexpected sentry-cli version "${version}", expected "${expected}"`);
|
|
232
|
+
} catch (error) {
|
|
233
|
+
if (error instanceof fetch.FetchError) {
|
|
234
|
+
throw new Error(
|
|
235
|
+
`Unable to download sentry-cli binary from ${downloadUrl}.\nError code: ${error.code}`
|
|
236
|
+
);
|
|
237
|
+
} else {
|
|
238
|
+
throw error;
|
|
300
239
|
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (!response.ok) {
|
|
243
|
+
throw new Error(
|
|
244
|
+
`Unable to download sentry-cli binary from ${downloadUrl}.\nServer returned ${
|
|
245
|
+
response.status
|
|
246
|
+
}${response.statusText ? `: ${response.statusText}` : ''}.`
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const contentEncoding = response.headers.get('content-encoding');
|
|
251
|
+
let decompressor;
|
|
252
|
+
if (/\bgzip\b/.test(contentEncoding)) {
|
|
253
|
+
decompressor = zlib.createGunzip();
|
|
254
|
+
} else if (/\bdeflate\b/.test(contentEncoding)) {
|
|
255
|
+
decompressor = zlib.createInflate();
|
|
256
|
+
} else if (/\bbr\b/.test(contentEncoding)) {
|
|
257
|
+
decompressor = zlib.createBrotliDecompress();
|
|
258
|
+
} else {
|
|
259
|
+
decompressor = new stream.PassThrough();
|
|
260
|
+
}
|
|
261
|
+
const name = downloadUrl.match(/.*\/(.*?)$/)[1];
|
|
262
|
+
const total = parseInt(response.headers.get('content-length'), 10);
|
|
263
|
+
const progressBar = createProgressBar(name, total);
|
|
264
|
+
const tempPath = getTempFile(cachedPath);
|
|
265
|
+
fs.mkdirSync(path.dirname(tempPath), { recursive: true });
|
|
266
|
+
|
|
267
|
+
await new Promise((resolve, reject) => {
|
|
268
|
+
response.body
|
|
269
|
+
.on('error', (e) => reject(e))
|
|
270
|
+
.on('data', (chunk) => progressBar.tick(chunk.length))
|
|
271
|
+
.pipe(decompressor)
|
|
272
|
+
.pipe(fs.createWriteStream(tempPath, { mode: '0755' }))
|
|
273
|
+
.on('error', (e) => reject(e))
|
|
274
|
+
.on('close', () => resolve());
|
|
301
275
|
});
|
|
276
|
+
|
|
277
|
+
if (process.env.SENTRYCLI_SKIP_CHECKSUM_VALIDATION !== '1') {
|
|
278
|
+
validateChecksum(tempPath, name);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
fs.copyFileSync(tempPath, cachedPath);
|
|
282
|
+
fs.copyFileSync(tempPath, outputPath);
|
|
283
|
+
fs.unlinkSync(tempPath);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
async function checkVersion() {
|
|
287
|
+
const output = await helper.execute(['--version']);
|
|
288
|
+
const version = output.replace('sentry-cli ', '').trim();
|
|
289
|
+
const expected = process.env.SENTRYCLI_LOCAL_CDNURL ? 'DEV' : pkgInfo.version;
|
|
290
|
+
if (version !== expected) {
|
|
291
|
+
throw new Error(`Unexpected sentry-cli version "${version}", expected "${expected}"`);
|
|
292
|
+
}
|
|
302
293
|
}
|
|
303
294
|
|
|
304
295
|
if (process.env.SENTRYCLI_LOCAL_CDNURL) {
|
|
@@ -323,11 +314,14 @@ if (process.env.SENTRYCLI_SKIP_DOWNLOAD === '1') {
|
|
|
323
314
|
process.exit(0);
|
|
324
315
|
}
|
|
325
316
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
317
|
+
(async () => {
|
|
318
|
+
try {
|
|
319
|
+
await downloadBinary();
|
|
320
|
+
await checkVersion();
|
|
321
|
+
process.exit(0);
|
|
322
|
+
} catch (e) {
|
|
330
323
|
// eslint-disable-next-line no-console
|
|
331
324
|
console.error(e.toString());
|
|
332
325
|
process.exit(1);
|
|
333
|
-
}
|
|
326
|
+
}
|
|
327
|
+
})();
|