UNPKG

5.09 kBJavaScriptView Raw
1"use strict";
2/* eslint-disable no-magic-numbers */
3var __importDefault = (this && this.__importDefault) || function (mod) {
4 return (mod && mod.__esModule) ? mod : { "default": mod };
5};
6Object.defineProperty(exports, "__esModule", { value: true });
7const fs_1 = __importDefault(require("fs"));
8const os_1 = __importDefault(require("os"));
9const execa_1 = __importDefault(require("execa"));
10const constants_1 = require("./constants");
11function run(command, args) {
12 return String(execa_1.default.sync(command, args, { preferLocal: true }).stdout);
13}
14function resolveHome(path) {
15 return path.replace(process.env.HOME, '~');
16}
17function extractVersion(value) {
18 const match = value.match(/\d+\.\d+\.\d+([.-a-z0-9])?/u);
19 return match ? match[0] : '';
20}
21class CrashReporter {
22 constructor() {
23 Object.defineProperty(this, "contents", {
24 enumerable: true,
25 configurable: true,
26 writable: true,
27 value: ''
28 });
29 }
30 /**
31 * Add a label with a value, or multiple values, to the last added section.
32 */
33 add(label, ...messages) {
34 this.contents += `${label}:\n`;
35 this.contents += ` ${messages.map(String).join(' - ')}\n`;
36 return this;
37 }
38 /**
39 * Start a new section with a title.
40 */
41 addSection(title) {
42 this.contents += `\n${title.toUpperCase()}\n`;
43 this.contents += `${'='.repeat(title.length)}\n\n`;
44 constants_1.debug('Reporting crash with %s', title);
45 return this;
46 }
47 /**
48 * Report Node.js related binary versions and paths.
49 */
50 reportBinaries() {
51 this.addSection('Binaries');
52 const bins = {
53 node: 'Node',
54 npm: 'NPM',
55 yarn: 'Yarn',
56 };
57 Object.keys(bins).forEach(bin => {
58 try {
59 this.add(bins[bin], extractVersion(run(bin, ['--version'])), resolveHome(run('which', [bin])));
60 }
61 catch (_a) {
62 // Ignore
63 }
64 });
65 return this;
66 }
67 /**
68 * Report all environment variables.
69 */
70 reportEnvVars() {
71 this.addSection('Environment');
72 const keys = Object.keys(process.env).sort();
73 keys.forEach(key => {
74 this.add(key, process.env[key]);
75 });
76 return this;
77 }
78 /**
79 * Report common programming language versions and paths
80 */
81 reportLanguages() {
82 this.addSection('Languages');
83 const languages = {
84 bash: 'Bash',
85 go: 'Go',
86 javac: 'Java',
87 perl: 'Perl',
88 php: 'PHP',
89 python: 'Python',
90 ruby: 'Ruby',
91 rustup: 'Rust',
92 };
93 // When running on OSX and Java is not installed,
94 // OSX will interrupt the process with a prompt to install Java.
95 // This is super annoying, so let's not disrupt consumers.
96 // istanbul ignore next
97 if (os_1.default.platform() === 'darwin') {
98 delete languages.javac;
99 }
100 Object.keys(languages).forEach(bin => {
101 let version;
102 try {
103 version = extractVersion(run(bin, ['--version']));
104 if (!version) {
105 version = extractVersion(run(bin, ['version']));
106 }
107 }
108 catch (_a) {
109 // Ignore
110 }
111 if (version) {
112 this.add(languages[bin], version, resolveHome(run('which', [bin])));
113 }
114 });
115 return this;
116 }
117 /**
118 * Report information about the current `process`.
119 */
120 reportProcess() {
121 this.addSection('Process');
122 this.add('ID', process.pid);
123 this.add('Title', process.title);
124 this.add('Timestamp', new Date().toISOString());
125 this.add('CWD', process.cwd());
126 this.add('ARGV', process.argv.map(v => `- ${v}`).join('\n '));
127 return this;
128 }
129 /**
130 * Report the stack trace for a defined `Error`.
131 */
132 reportStackTrace(error) {
133 this.addSection('Stack Trace');
134 this.contents += error.stack;
135 return this;
136 }
137 /**
138 * Report information about the platform and operating system.
139 */
140 reportSystem() {
141 this.addSection('System');
142 this.add('OS', os_1.default.platform());
143 this.add('Architecture', os_1.default.arch());
144 this.add('CPUs', os_1.default.cpus().length);
145 this.add('Uptime (sec)', os_1.default.uptime());
146 this.add('Memory usage', `${Math.round((process.memoryUsage().heapUsed / 1024 / 1024) * 100) / 100} MB`);
147 if (process.platform !== 'win32') {
148 this.add('Group ID', process.getgid());
149 this.add('User ID', process.getuid());
150 }
151 return this;
152 }
153 /**
154 * Write the reported content to the defined file path.
155 */
156 write(filePath) {
157 fs_1.default.writeFileSync(String(filePath), this.contents.trim(), 'utf8');
158 return this;
159 }
160}
161exports.default = CrashReporter;