@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.
@@ -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,9 @@
1
+ /**
2
+ * Helper class for building HTTP query parameter strings.
3
+ */
4
+ export default class QueryParameters extends URLSearchParams {
5
+ /**
6
+ * Adds a parameter if the value is defined.
7
+ */
8
+ addIfDefined(key: string, value: string | undefined): void;
9
+ }
@@ -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,5 @@
1
+ import 'dotenv/config';
2
+ /** Class for console logger. Doesn't print all information to ensure better readability. */
3
+ export declare class StdConsoleLogger {
4
+ write(rec: Record<any, any>): void;
5
+ }
@@ -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.5",
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 --forceExit --coverage --silent=true --detectOpenHandles"
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.1",
25
+ "@cqse/commons": "^0.0.1-beta.45",
25
26
  "argparse": "^2.0.1",
26
- "async": "^3.2.0",
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.3",
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/winston": "^2.4.4",
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",