@sentry/cli 1.74.3 → 2.0.1

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 CHANGED
@@ -3,17 +3,17 @@
3
3
  'use strict';
4
4
 
5
5
  const childProcess = require('child_process');
6
- const cli = require('../js');
6
+ const SentryCli = require('../js');
7
7
 
8
8
  const child = childProcess
9
- .spawn(cli.getPath(), process.argv.slice(2), {
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=da33835c6c68e007747784cc191731fd47b6c1d0984fc5373aad60f3025e5ae9
2
- sentry-cli-Darwin-universal=ec665920219317a728093b30fd9c009dd64a8f49001d1d8434a46aa8ba5d0f12
3
- sentry-cli-Darwin-x86_64=d5f0e2380a79852a1ebaa5abab4c4d0e9681e5cb080d92b5b2801034649b27e5
4
- sentry-cli-Linux-aarch64=5f981d63bf6644973b85cf514381196b7a7089fec07e580be7530522728cf95f
5
- sentry-cli-Linux-armv7=c852fd2e1f402c3db0b269df17da7d14e8098c1c066ee09d342901c39862a36a
6
- sentry-cli-Linux-i686=f1db03614ec2b15e9cafcd7f3f7a9aaee5291f420fe4981ea220dc1bb8ec479e
7
- sentry-cli-Linux-x86_64=2d2b4acc6bb644aef5d07bd8c96ffaa16207719355fbf1578833c6eeee912554
8
- sentry-cli-Windows-i686.exe=8fbef71c26cc3a034043eaa4d2efd9830c17c2500f069411283e2fa3f7a0f9db
9
- sentry-cli-Windows-x86_64.exe=0d2f372d98f53ea4d4df26161f1f821d5322b00a0227ce84ec939bf271c720ad
1
+ sentry-cli-Darwin-arm64=6bf38158c0b3d198802a22ec2d2021d619e5fe1a125f2d21395c6b0b54f5808d
2
+ sentry-cli-Darwin-universal=4ded776b94d1c1e26fbb9e8811fdf003e7f51116bd4720e627a3bc2b9a814e74
3
+ sentry-cli-Darwin-x86_64=a3add22156f70fba60c4f2eb47880362c704bd1fbc6f455f7f9f941a3e269754
4
+ sentry-cli-Linux-aarch64=d05bf0aba980795fb046c62a693bd6c152421de1f85c1c851f94e206cabbe62f
5
+ sentry-cli-Linux-armv7=3e64b3b61dca0cae6c6845dfbfe7ec19a208cc04480ec1dca5a343d2a5a8f3f5
6
+ sentry-cli-Linux-i686=2ac8358c52f5a8936bade1729fb85e3b8be604d60bd195f88609cb44e6fb8f06
7
+ sentry-cli-Linux-x86_64=4f378d823e03a40560cb0438b3eb3ee54ea828aff6087a9ef63dfeb31fb064ab
8
+ sentry-cli-Windows-i686.exe=83965514cc737d6d96cd04d39d0ba91a26fa7881e3bcd325ac89a60d615f4de1
9
+ sentry-cli-Windows-x86_64.exe=00df30fa383c90e27a14f8ddb151f8b29a7edb78507e8832350260bd0e131209
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;
@@ -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
- return this.execute(['releases', 'propose-version'], null).then(
126
- version => version && version.trim()
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": "1.74.3",
3
+ "version": "2.0.1",
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": ">= 8"
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/utils"
47
+ "<rootDir>/src"
60
48
  ]
61
49
  }
62
50
  }
@@ -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
- // Leave `SENTRY_NO_PROGRESS_BAR` for backwards compatibility
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
- return Promise.reject(new Error(`Unsupported target ${platform}-${arch}`));
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 Promise.resolve();
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
- return fetch(downloadUrl, {
235
- agent,
236
- compress: false,
237
- headers: {
238
- 'accept-encoding': 'gzip, deflate, br',
239
- },
240
- redirect: 'follow',
241
- })
242
- .then(response => {
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
- function checkVersion() {
295
- return helper.execute(['--version']).then(output => {
296
- const version = output.replace('sentry-cli ', '').trim();
297
- const expected = process.env.SENTRYCLI_LOCAL_CDNURL ? 'DEV' : pkgInfo.version;
298
- if (version !== expected) {
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
- downloadBinary()
327
- .then(() => checkVersion())
328
- .then(() => process.exit(0))
329
- .catch(e => {
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
+ })();