@teamscale/coverage-collector 0.0.1-beta.5 → 0.0.1-beta.50
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/README.md +1 -6
- package/dist/package.json +19 -7
- package/dist/src/App.d.ts +39 -0
- package/dist/src/App.js +244 -0
- package/dist/src/main.d.ts +1 -30
- package/dist/src/main.js +2 -115
- package/dist/src/receiver/CollectingServer.d.ts +5 -3
- package/dist/src/receiver/CollectingServer.js +31 -14
- package/dist/src/receiver/Session.d.ts +23 -5
- package/dist/src/receiver/Session.js +79 -15
- package/dist/src/storage/DataStorage.d.ts +39 -8
- package/dist/src/storage/DataStorage.js +68 -23
- package/dist/src/upload/ArtifactoryUpload.d.ts +6 -0
- package/dist/src/upload/ArtifactoryUpload.js +66 -0
- package/dist/src/upload/CommonUpload.d.ts +16 -0
- package/dist/src/upload/CommonUpload.js +55 -0
- package/dist/src/upload/ProxyUpload.d.ts +6 -0
- package/dist/src/upload/ProxyUpload.js +30 -0
- package/dist/src/upload/TeamscaleUpload.d.ts +6 -0
- package/dist/src/upload/TeamscaleUpload.js +54 -0
- package/dist/src/utils/ConfigParameters.d.ts +36 -0
- package/dist/src/utils/ConfigParameters.js +107 -0
- package/dist/src/utils/PrettyFileLogger.d.ts +13 -0
- package/dist/src/utils/PrettyFileLogger.js +24 -0
- package/dist/src/utils/QueryParameters.d.ts +9 -0
- package/dist/src/utils/QueryParameters.js +19 -0
- package/dist/src/utils/StdConsoleLogger.d.ts +5 -0
- package/dist/src/utils/StdConsoleLogger.js +15 -0
- package/package.json +19 -7
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.uploadToTeamscale = void 0;
|
|
7
|
+
const QueryParameters_1 = __importDefault(require("../utils/QueryParameters"));
|
|
8
|
+
const CommonUpload_1 = require("./CommonUpload");
|
|
9
|
+
const axios_1 = __importDefault(require("axios"));
|
|
10
|
+
const ProxyUpload_1 = require("./ProxyUpload");
|
|
11
|
+
/**
|
|
12
|
+
* Uploads a coverage file to Teamscale with the provided configuration.
|
|
13
|
+
*/
|
|
14
|
+
async function uploadToTeamscale(config, logger, coverageFile, lines) {
|
|
15
|
+
if (!(config.teamscale_access_token && config.teamscale_user && config.teamscale_server_url)) {
|
|
16
|
+
throw new CommonUpload_1.UploadError('API key and user name must be configured!');
|
|
17
|
+
}
|
|
18
|
+
if (lines === 0) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
logger.info('Preparing upload to Teamscale');
|
|
22
|
+
const form = (0, CommonUpload_1.prepareFormData)(coverageFile);
|
|
23
|
+
const queryParameters = prepareQueryParameters(config);
|
|
24
|
+
await performTeamscaleUpload(config, queryParameters, form, logger);
|
|
25
|
+
}
|
|
26
|
+
exports.uploadToTeamscale = uploadToTeamscale;
|
|
27
|
+
async function performTeamscaleUpload(config, parameters, form, logger) {
|
|
28
|
+
var _a;
|
|
29
|
+
await (0, CommonUpload_1.performUpload)(`${(_a = config.teamscale_server_url) === null || _a === void 0 ? void 0 : _a.replace(/\/$/, '')}/api/projects/${config.teamscale_project}/external-analysis/session/auto-create/report?${parameters.toString()}`, form, prepareTeamscaleConfig(config, form), axios_1.default.post, logger);
|
|
30
|
+
}
|
|
31
|
+
function prepareQueryParameters(config) {
|
|
32
|
+
const parameters = new QueryParameters_1.default();
|
|
33
|
+
parameters.addIfDefined('format', 'SIMPLE');
|
|
34
|
+
parameters.addIfDefined('message', config.teamscale_message);
|
|
35
|
+
parameters.addIfDefined('repository', config.teamscale_repository);
|
|
36
|
+
parameters.addIfDefined('t', config.teamscale_commit);
|
|
37
|
+
parameters.addIfDefined('revision', config.teamscale_revision);
|
|
38
|
+
parameters.addIfDefined('partition', config.teamscale_partition);
|
|
39
|
+
return parameters;
|
|
40
|
+
}
|
|
41
|
+
function prepareTeamscaleConfig(config, form) {
|
|
42
|
+
var _a, _b;
|
|
43
|
+
return {
|
|
44
|
+
auth: {
|
|
45
|
+
username: (_a = config.teamscale_user) !== null && _a !== void 0 ? _a : 'no username provided',
|
|
46
|
+
password: (_b = config.teamscale_access_token) !== null && _b !== void 0 ? _b : 'no password provided'
|
|
47
|
+
},
|
|
48
|
+
headers: {
|
|
49
|
+
Accept: '*/*',
|
|
50
|
+
'Content-Type': `multipart/form-data; boundary=${form.getBoundary()}`
|
|
51
|
+
},
|
|
52
|
+
proxy: (0, ProxyUpload_1.extractProxyOptions)(config)
|
|
53
|
+
};
|
|
54
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ArgumentParser } from 'argparse';
|
|
2
|
+
/**
|
|
3
|
+
* The command line parameters the profiler can be configured with.
|
|
4
|
+
*
|
|
5
|
+
* ATTENTION: We use snake_case here because ArgParse creates
|
|
6
|
+
* the parameters that way---as in Python from which ArgParse stems.
|
|
7
|
+
*/
|
|
8
|
+
export declare type ConfigParameters = {
|
|
9
|
+
dump_to_folder: string;
|
|
10
|
+
log_to_file: string;
|
|
11
|
+
keep_coverage_files: boolean;
|
|
12
|
+
log_level: string;
|
|
13
|
+
dump_after_mins: number;
|
|
14
|
+
port: number;
|
|
15
|
+
json_log: boolean;
|
|
16
|
+
teamscale_server_url?: string;
|
|
17
|
+
teamscale_access_token?: string;
|
|
18
|
+
teamscale_project?: string;
|
|
19
|
+
teamscale_user?: string;
|
|
20
|
+
teamscale_partition?: string;
|
|
21
|
+
teamscale_revision?: string;
|
|
22
|
+
teamscale_commit?: string;
|
|
23
|
+
teamscale_repository?: string;
|
|
24
|
+
teamscale_message?: string;
|
|
25
|
+
artifactory_server_url?: string;
|
|
26
|
+
artifactory_user?: string;
|
|
27
|
+
artifactory_password?: string;
|
|
28
|
+
artifactory_access_token?: string;
|
|
29
|
+
artifactory_path_suffix?: string;
|
|
30
|
+
enable_control_port?: number;
|
|
31
|
+
http_proxy?: string;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Construct the object for parsing the command line arguments.
|
|
35
|
+
*/
|
|
36
|
+
export declare function buildParameterParser(): ArgumentParser;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildParameterParser = void 0;
|
|
4
|
+
const argparse_1 = require("argparse");
|
|
5
|
+
const package_json_1 = require("../../package.json");
|
|
6
|
+
/**
|
|
7
|
+
* Construct the object for parsing the command line arguments.
|
|
8
|
+
*/
|
|
9
|
+
function buildParameterParser() {
|
|
10
|
+
var _a;
|
|
11
|
+
const parser = new argparse_1.ArgumentParser({
|
|
12
|
+
description: 'Collector of the Teamscale JavaScript Profiler. Collects coverage information from a' +
|
|
13
|
+
'(headless) Web browser that executes code instrumented with our instrumenter.'
|
|
14
|
+
});
|
|
15
|
+
parser.add_argument('-v', '--version', { action: 'version', version: package_json_1.version });
|
|
16
|
+
parser.add_argument('-p', '--port', { help: 'The port to receive coverage information on.', default: 54678 });
|
|
17
|
+
parser.add_argument('-f', '--dump-to-folder', {
|
|
18
|
+
help: 'Target folder for coverage files.',
|
|
19
|
+
default: 'coverage'
|
|
20
|
+
});
|
|
21
|
+
parser.add_argument('-k', '--keep-coverage-files', {
|
|
22
|
+
help: 'Whether to keep the coverage files on disk after a successful upload to Teamsacle',
|
|
23
|
+
action: 'store_true',
|
|
24
|
+
default: false
|
|
25
|
+
});
|
|
26
|
+
parser.add_argument('-l', '--log-to-file', { help: 'Log file', default: 'logs/collector-combined.log' });
|
|
27
|
+
parser.add_argument('-e', '--log-level', { help: 'Log level', default: 'info' });
|
|
28
|
+
parser.add_argument('-c', '--enable-control-port', {
|
|
29
|
+
help: 'Enables the remote control API on the specified port (<=0 means "disabled").',
|
|
30
|
+
default: 0
|
|
31
|
+
});
|
|
32
|
+
parser.add_argument('-t', '--dump-after-mins', {
|
|
33
|
+
help: 'Dump the coverage information to the target file every N minutes.',
|
|
34
|
+
default: 360
|
|
35
|
+
});
|
|
36
|
+
parser.add_argument('-d', '--debug', {
|
|
37
|
+
help: 'Print received coverage information to the terminal?',
|
|
38
|
+
default: false
|
|
39
|
+
});
|
|
40
|
+
parser.add_argument('-j', '--json-log', {
|
|
41
|
+
help: 'Additional JSON-like log file format.',
|
|
42
|
+
action: 'store_true'
|
|
43
|
+
});
|
|
44
|
+
// Parameters for the upload to Teamscale
|
|
45
|
+
parser.add_argument('-u', '--teamscale-server-url', {
|
|
46
|
+
help: 'Upload the coverage to the given Teamscale server URL, for example, https://teamscale.dev.example.com:8080/production.',
|
|
47
|
+
default: process.env.TEAMSCALE_SERVER_URL
|
|
48
|
+
});
|
|
49
|
+
parser.add_argument('--teamscale-access-token', {
|
|
50
|
+
help: 'The API key to use for uploading to Teamscale.',
|
|
51
|
+
default: process.env.TEAMSCALE_ACCESS_TOKEN
|
|
52
|
+
});
|
|
53
|
+
parser.add_argument('--teamscale-project', {
|
|
54
|
+
help: 'The project ID to upload coverage to.',
|
|
55
|
+
default: process.env.TEAMSCALE_PROJECT
|
|
56
|
+
});
|
|
57
|
+
parser.add_argument('--teamscale-user', {
|
|
58
|
+
help: 'The user for uploading coverage to Teamscale.',
|
|
59
|
+
default: process.env.TEAMSCALE_USER
|
|
60
|
+
});
|
|
61
|
+
parser.add_argument('--teamscale-partition', {
|
|
62
|
+
help: 'The partition to upload coverage to.',
|
|
63
|
+
default: process.env.TEAMSCALE_PARTITION
|
|
64
|
+
});
|
|
65
|
+
parser.add_argument('--teamscale-revision', {
|
|
66
|
+
help: 'The revision (commit hash, version id) to upload coverage for.',
|
|
67
|
+
default: process.env.TEAMSCALE_REVISION
|
|
68
|
+
});
|
|
69
|
+
parser.add_argument('--teamscale-commit', {
|
|
70
|
+
help: 'The branch and timestamp to upload coverage for, separated by colon.',
|
|
71
|
+
default: process.env.TEAMSCALE_COMMIT
|
|
72
|
+
});
|
|
73
|
+
parser.add_argument('--teamscale-repository', {
|
|
74
|
+
help: 'The repository to upload coverage for. Optional: Only needed when uploading via revision to a project that has more than one connector.',
|
|
75
|
+
default: process.env.TEAMSCALE_REPOSITORY
|
|
76
|
+
});
|
|
77
|
+
parser.add_argument('--teamscale-message', {
|
|
78
|
+
help: 'The commit message shown within Teamscale for the coverage upload. Default is "JavaScript coverage upload".',
|
|
79
|
+
default: (_a = process.env.TEAMSCALE_MESSAGE) !== null && _a !== void 0 ? _a : 'JavaScript coverage upload'
|
|
80
|
+
});
|
|
81
|
+
parser.add_argument('--artifactory-server-url', {
|
|
82
|
+
help: 'Upload the coverage to the given Artifactory server URL. The URL may include a subpath on the artifactory server, e.g. https://artifactory.acme.com/my-repo/my/subpath',
|
|
83
|
+
default: process.env.ARTIFACTORY_SERVER_URL
|
|
84
|
+
});
|
|
85
|
+
parser.add_argument('--artifactory-user', {
|
|
86
|
+
help: 'The user for uploading coverage to Artifactory. Only needed when not using the --artifactory-access-token option',
|
|
87
|
+
default: process.env.ARTIFACTORY_USER
|
|
88
|
+
});
|
|
89
|
+
parser.add_argument('--artifactory-password', {
|
|
90
|
+
help: 'The password for uploading coverage to Artifactory. Only needed when not using the --artifactory-access-token option',
|
|
91
|
+
default: process.env.ARTIFACTORY_PASSWORD
|
|
92
|
+
});
|
|
93
|
+
parser.add_argument('--artifactory-access-token', {
|
|
94
|
+
help: 'The access_token for uploading coverage to Artifactory.',
|
|
95
|
+
default: process.env.ARTIFACTORY_ACCESS_TOKEN
|
|
96
|
+
});
|
|
97
|
+
parser.add_argument('--artifactory-path-suffix', {
|
|
98
|
+
help: '(optional): The path within the storage location between the default path and the uploaded artifact.',
|
|
99
|
+
default: process.env.ARTIFACTORY_PATH_SUFFIX
|
|
100
|
+
});
|
|
101
|
+
parser.add_argument('--http-proxy', {
|
|
102
|
+
help: '(optional): The HTTP/HTTPS proxy address that should be used in the format: http://host:port/ or http://username:password@host:port/.',
|
|
103
|
+
default: process.env.HTTP_PROXY
|
|
104
|
+
});
|
|
105
|
+
return parser;
|
|
106
|
+
}
|
|
107
|
+
exports.buildParameterParser = buildParameterParser;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import 'dotenv/config';
|
|
3
|
+
import { WriteStream } from 'fs';
|
|
4
|
+
/**
|
|
5
|
+
* Class for log4j-like logger. Stream output shows less information than the
|
|
6
|
+
* standard JSON format of the bunyan logger and therefore has better readability.
|
|
7
|
+
*/
|
|
8
|
+
export declare class PrettyFileLogger {
|
|
9
|
+
outputStream: WriteStream;
|
|
10
|
+
constructor(outputStream: WriteStream);
|
|
11
|
+
write(rec: Record<any, any>): void;
|
|
12
|
+
end(): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.PrettyFileLogger = void 0;
|
|
7
|
+
const bunyan_1 = __importDefault(require("bunyan"));
|
|
8
|
+
require("dotenv/config");
|
|
9
|
+
/**
|
|
10
|
+
* Class for log4j-like logger. Stream output shows less information than the
|
|
11
|
+
* standard JSON format of the bunyan logger and therefore has better readability.
|
|
12
|
+
*/
|
|
13
|
+
class PrettyFileLogger {
|
|
14
|
+
constructor(outputStream) {
|
|
15
|
+
this.outputStream = outputStream;
|
|
16
|
+
}
|
|
17
|
+
write(rec) {
|
|
18
|
+
this.outputStream.write(`[${rec.time.toISOString()}] ${bunyan_1.default.nameFromLevel[rec.level].toUpperCase()}: ${rec.msg}\n`);
|
|
19
|
+
}
|
|
20
|
+
end() {
|
|
21
|
+
this.outputStream.close();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.PrettyFileLogger = PrettyFileLogger;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* Helper class for building HTTP query parameter strings.
|
|
5
|
+
*/
|
|
6
|
+
class QueryParameters extends URLSearchParams {
|
|
7
|
+
/**
|
|
8
|
+
* Adds a parameter if the value is defined.
|
|
9
|
+
*/
|
|
10
|
+
addIfDefined(key, value) {
|
|
11
|
+
if (value) {
|
|
12
|
+
this.append(key, value);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
this.delete(key);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.default = QueryParameters;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.StdConsoleLogger = void 0;
|
|
7
|
+
const bunyan_1 = __importDefault(require("bunyan"));
|
|
8
|
+
require("dotenv/config");
|
|
9
|
+
/** Class for console logger. Doesn't print all information to ensure better readability. */
|
|
10
|
+
class StdConsoleLogger {
|
|
11
|
+
write(rec) {
|
|
12
|
+
console.log(`[${rec.time.toISOString()}] ${bunyan_1.default.nameFromLevel[rec.level].toUpperCase()}: ${rec.msg}`);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.StdConsoleLogger = StdConsoleLogger;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teamscale/coverage-collector",
|
|
3
|
-
"version": "0.0.1-beta.
|
|
3
|
+
"version": "0.0.1-beta.50",
|
|
4
4
|
"description": "Collector for JavaScript code coverage information",
|
|
5
5
|
"main": "dist/src/main.js",
|
|
6
6
|
"bin": "dist/src/main.js",
|
|
@@ -12,22 +12,30 @@
|
|
|
12
12
|
"url": "https://github.com/cqse/teamscale-javascript-profiler.git"
|
|
13
13
|
},
|
|
14
14
|
"scripts": {
|
|
15
|
+
"prepublishOnly": "yarn clean && yarn build",
|
|
15
16
|
"clean": "rimraf dist tsconfig.tsbuildinfo",
|
|
16
17
|
"build": "tsc",
|
|
17
18
|
"collector": "node dist/src/main.js",
|
|
18
|
-
"test": "yarn build && NODE_OPTIONS='--experimental-vm-modules' jest --
|
|
19
|
+
"test": "yarn build && NODE_OPTIONS='--experimental-vm-modules' jest --coverage --silent=true"
|
|
19
20
|
},
|
|
20
21
|
"files": [
|
|
21
22
|
"dist/**/*"
|
|
22
23
|
],
|
|
23
24
|
"dependencies": {
|
|
24
|
-
"@cqse/commons": "^0.0.1-beta.
|
|
25
|
+
"@cqse/commons": "^0.0.1-beta.45",
|
|
25
26
|
"argparse": "^2.0.1",
|
|
26
|
-
"async": "^3.2.
|
|
27
|
+
"async": "^3.2.4",
|
|
28
|
+
"axios": "^0.24.0",
|
|
29
|
+
"bunyan": "^1.8.15",
|
|
30
|
+
"date-and-time": "^2.3.1",
|
|
31
|
+
"dotenv": "^14.1.0",
|
|
32
|
+
"express": "^4.18.1",
|
|
33
|
+
"form-data": "^4.0.0",
|
|
34
|
+
"mkdirp": "^1.0.4",
|
|
27
35
|
"rxjs": "^7.1.0",
|
|
28
|
-
"source-map": "^0.7.
|
|
36
|
+
"source-map": "^0.7.4",
|
|
37
|
+
"tmp": "^0.2.1",
|
|
29
38
|
"typescript-optional": "^2.0.1",
|
|
30
|
-
"winston": "^3.3.3",
|
|
31
39
|
"ws": "^7.4.5"
|
|
32
40
|
},
|
|
33
41
|
"devDependencies": {
|
|
@@ -35,14 +43,18 @@
|
|
|
35
43
|
"@babel/preset-env": "^7.14.1",
|
|
36
44
|
"@types/argparse": "^2.0.5",
|
|
37
45
|
"@types/async": "^3.2.6",
|
|
46
|
+
"@types/bunyan": "^1.8.8",
|
|
47
|
+
"@types/express": "^4.17.13",
|
|
38
48
|
"@types/jest": "^27.0.1",
|
|
49
|
+
"@types/mkdirp": "^1.0.2",
|
|
39
50
|
"@types/node": "^15.0.1",
|
|
40
51
|
"@types/source-map": "^0.5.7",
|
|
41
|
-
"@types/
|
|
52
|
+
"@types/tmp": "^0.2.3",
|
|
42
53
|
"@types/ws": "^7.4.2",
|
|
43
54
|
"babel-jest": "^27.2.0",
|
|
44
55
|
"esbuild": "^0.13.4",
|
|
45
56
|
"jest": "^27.2.0",
|
|
57
|
+
"mockttp": "^3.4.0",
|
|
46
58
|
"rimraf": "^3.0.2",
|
|
47
59
|
"ts-jest": "^27.0.5",
|
|
48
60
|
"ts-node": "^10.2.1",
|