@appland/scanner 1.76.1 → 1.76.2
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/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
# [@appland/scanner-v1.76.2](https://github.com/getappmap/appmap-js/compare/@appland/scanner-v1.76.1...@appland/scanner-v1.76.2) (2023-02-22)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* Include contributor counts in `scan` ([1c5de40](https://github.com/getappmap/appmap-js/commit/1c5de40410ae2e1794509fb29e9ba128eaac18c0))
|
|
7
|
+
* Report git state ([a5d3797](https://github.com/getappmap/appmap-js/commit/a5d3797815b283ed114a57351067ed911ca36fa2))
|
|
8
|
+
|
|
1
9
|
# [@appland/scanner-v1.76.1](https://github.com/getappmap/appmap-js/compare/@appland/scanner-v1.76.0...@appland/scanner-v1.76.1) (2023-02-16)
|
|
2
10
|
|
|
3
11
|
|
|
@@ -76,7 +76,7 @@ class Watcher {
|
|
|
76
76
|
// do not remove callbackify, apparently on windows
|
|
77
77
|
// passing plain async function doesn't work (?)
|
|
78
78
|
this.queue = (0, async_1.queue)((0, node_util_1.callbackify)(this.scan.bind(this)), 2);
|
|
79
|
-
watchScanTelemetry_1.WatchScanTelemetry.watch(this.scanEventEmitter);
|
|
79
|
+
watchScanTelemetry_1.WatchScanTelemetry.watch(this.scanEventEmitter, options.appmapDir);
|
|
80
80
|
this.queue.error((error, task) => console.warn(`Problem processing ${task}:\n`, error));
|
|
81
81
|
}
|
|
82
82
|
watch() {
|
|
@@ -7,7 +7,8 @@ exports.WatchScanTelemetry = void 0;
|
|
|
7
7
|
const eventAggregator_1 = __importDefault(require("../../util/eventAggregator"));
|
|
8
8
|
const scanResults_1 = require("../../report/scanResults");
|
|
9
9
|
class WatchScanTelemetry {
|
|
10
|
-
constructor(scanEvents) {
|
|
10
|
+
constructor(scanEvents, appmapDir) {
|
|
11
|
+
this.appmapDir = appmapDir;
|
|
11
12
|
this.cancelFn = new eventAggregator_1.default((events) => {
|
|
12
13
|
const scanEvents = events.map((e) => e.arg);
|
|
13
14
|
this.sendTelemetry(scanEvents);
|
|
@@ -18,8 +19,8 @@ class WatchScanTelemetry {
|
|
|
18
19
|
this.cancelFn();
|
|
19
20
|
this.cancelFn = undefined;
|
|
20
21
|
}
|
|
21
|
-
static watch(scanEvents) {
|
|
22
|
-
const telemetry = new WatchScanTelemetry(scanEvents);
|
|
22
|
+
static watch(scanEvents, appmapDir) {
|
|
23
|
+
const telemetry = new WatchScanTelemetry(scanEvents, appmapDir);
|
|
23
24
|
return () => telemetry.cancel();
|
|
24
25
|
}
|
|
25
26
|
sendTelemetry(scanEvents) {
|
|
@@ -36,6 +37,7 @@ class WatchScanTelemetry {
|
|
|
36
37
|
numAppMaps: telemetryScanResults.summary.numAppMaps,
|
|
37
38
|
numFindings: telemetryScanResults.summary.numFindings,
|
|
38
39
|
elapsedMs: elapsed,
|
|
40
|
+
appmapDir: this.appmapDir,
|
|
39
41
|
});
|
|
40
42
|
}
|
|
41
43
|
}
|
|
@@ -1,10 +1,39 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
4
33
|
};
|
|
5
34
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
35
|
exports.sendScanResultsTelemetry = exports.ScanResults = void 0;
|
|
7
|
-
const telemetry_1 =
|
|
36
|
+
const telemetry_1 = __importStar(require("../telemetry"));
|
|
8
37
|
class DistinctItems {
|
|
9
38
|
constructor() {
|
|
10
39
|
this.members = {};
|
|
@@ -90,18 +119,23 @@ class ScanResults {
|
|
|
90
119
|
}
|
|
91
120
|
exports.ScanResults = ScanResults;
|
|
92
121
|
function sendScanResultsTelemetry(telemetry) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
122
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
123
|
+
const gitState = telemetry_1.GitState[yield telemetry_1.Git.state(telemetry.appmapDir)];
|
|
124
|
+
const contributors = (yield telemetry_1.Git.contributors(60, telemetry.appmapDir)).length;
|
|
125
|
+
telemetry_1.default.sendEvent({
|
|
126
|
+
name: 'scan:completed',
|
|
127
|
+
properties: {
|
|
128
|
+
rules: telemetry.ruleIds.sort().join(', '),
|
|
129
|
+
git_state: gitState,
|
|
130
|
+
},
|
|
131
|
+
metrics: {
|
|
132
|
+
duration: telemetry.elapsedMs / 1000,
|
|
133
|
+
numRules: telemetry.ruleIds.length,
|
|
134
|
+
numAppMaps: telemetry.numAppMaps,
|
|
135
|
+
numFindings: telemetry.numFindings,
|
|
136
|
+
contributors: contributors,
|
|
137
|
+
},
|
|
138
|
+
}, { includeEnvironment: true });
|
|
139
|
+
});
|
|
106
140
|
}
|
|
107
141
|
exports.sendScanResultsTelemetry = sendScanResultsTelemetry;
|
package/built/telemetry.js
CHANGED
|
@@ -22,16 +22,29 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
25
34
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
35
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
36
|
};
|
|
28
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
exports.Git = exports.GitState = void 0;
|
|
29
39
|
const os_1 = require("os");
|
|
30
40
|
const crypto_1 = require("crypto");
|
|
31
41
|
const os = __importStar(require("os"));
|
|
32
42
|
const read_pkg_up_1 = require("read-pkg-up");
|
|
33
43
|
const applicationinsights_1 = require("applicationinsights");
|
|
34
44
|
const conf_1 = __importDefault(require("conf"));
|
|
45
|
+
const child_process_1 = require("child_process");
|
|
46
|
+
const util_1 = require("util");
|
|
47
|
+
const exec = (0, util_1.promisify)(child_process_1.exec);
|
|
35
48
|
const { name, version } = (() => {
|
|
36
49
|
var _a;
|
|
37
50
|
const result = (_a = (0, read_pkg_up_1.sync)({ cwd: __dirname })) === null || _a === void 0 ? void 0 : _a.packageJson;
|
|
@@ -215,3 +228,93 @@ class Telemetry {
|
|
|
215
228
|
exports.default = Telemetry;
|
|
216
229
|
Telemetry.debug = process.env.APPMAP_TELEMETRY_DEBUG !== undefined;
|
|
217
230
|
Telemetry.machineId = getMachineId();
|
|
231
|
+
var GitState;
|
|
232
|
+
(function (GitState) {
|
|
233
|
+
GitState[GitState["NotInstalled"] = 0] = "NotInstalled";
|
|
234
|
+
GitState[GitState["NoRepository"] = 1] = "NoRepository";
|
|
235
|
+
GitState[GitState["Ok"] = 2] = "Ok";
|
|
236
|
+
})(GitState = exports.GitState || (exports.GitState = {}));
|
|
237
|
+
class GitProperties {
|
|
238
|
+
static contributors(sinceDaysAgo, cwd) {
|
|
239
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
240
|
+
const unixTimeNow = Math.floor(Number(new Date()) / 1000);
|
|
241
|
+
const unixTimeAgo = unixTimeNow - sinceDaysAgo * 24 * 60 * 60;
|
|
242
|
+
try {
|
|
243
|
+
const { stdout } = yield exec([
|
|
244
|
+
'git',
|
|
245
|
+
cwd && `-C ${cwd.toString()}`,
|
|
246
|
+
'--no-pager',
|
|
247
|
+
'log',
|
|
248
|
+
`--since=${unixTimeAgo}`,
|
|
249
|
+
'--format="%ae"',
|
|
250
|
+
].join(' '));
|
|
251
|
+
return [
|
|
252
|
+
...stdout
|
|
253
|
+
.trim()
|
|
254
|
+
.split('\n')
|
|
255
|
+
.reduce((acc, email) => {
|
|
256
|
+
acc.add(email);
|
|
257
|
+
return acc;
|
|
258
|
+
}, new Set()),
|
|
259
|
+
];
|
|
260
|
+
}
|
|
261
|
+
catch (_a) {
|
|
262
|
+
return [];
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
static state(cwd) {
|
|
267
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
268
|
+
return new Promise((resolve) => {
|
|
269
|
+
try {
|
|
270
|
+
const commandProcess = (0, child_process_1.spawn)('git', ['status'], {
|
|
271
|
+
shell: true,
|
|
272
|
+
cwd: cwd === null || cwd === void 0 ? void 0 : cwd.toString(),
|
|
273
|
+
});
|
|
274
|
+
commandProcess.on('close', (code) => {
|
|
275
|
+
switch (code) {
|
|
276
|
+
case 127:
|
|
277
|
+
return resolve(GitState.NotInstalled);
|
|
278
|
+
case 128:
|
|
279
|
+
return resolve(GitState.NoRepository);
|
|
280
|
+
default:
|
|
281
|
+
return resolve(GitState.Ok);
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
commandProcess.on('error', () => GitState.NotInstalled);
|
|
285
|
+
}
|
|
286
|
+
catch (_a) {
|
|
287
|
+
resolve(GitState.NotInstalled);
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
const gitCache = new Map();
|
|
294
|
+
// GitProperties is available externally as Git.
|
|
295
|
+
// This export provides a simple caching layer around GitProperties to avoid
|
|
296
|
+
// excessive shelling out to git.
|
|
297
|
+
exports.Git = new Proxy(GitProperties, {
|
|
298
|
+
get(target, prop) {
|
|
299
|
+
if (typeof target[prop] === 'function') {
|
|
300
|
+
return new Proxy(target[prop], {
|
|
301
|
+
apply(target, thisArg, argArray) {
|
|
302
|
+
const cacheKey = `${prop.toString()}(${JSON.stringify(argArray)})`;
|
|
303
|
+
if (gitCache.has(cacheKey)) {
|
|
304
|
+
return gitCache.get(cacheKey);
|
|
305
|
+
}
|
|
306
|
+
/* eslint-disable-next-line @typescript-eslint/ban-types */
|
|
307
|
+
const result = Reflect.apply(target, thisArg, argArray);
|
|
308
|
+
if (result instanceof Promise) {
|
|
309
|
+
return result.then((r) => {
|
|
310
|
+
gitCache.set(cacheKey, r);
|
|
311
|
+
return r;
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
return result;
|
|
315
|
+
},
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
return Reflect.get(target, prop);
|
|
319
|
+
},
|
|
320
|
+
});
|