@gatling.io/cli 3.13.103 → 3.13.104-M4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gatling.io/cli",
3
- "version": "3.13.103",
3
+ "version": "3.13.104-M4",
4
4
  "license": "Apache-2.0",
5
5
  "homepage": "https://gatling.io",
6
6
  "repository": "github:gatling/gatling-js",
@@ -25,22 +25,22 @@
25
25
  "dependencies": {
26
26
  "@jspm/core": "2.1.0",
27
27
  "archiver": "7.0.1",
28
- "axios": "1.7.7",
28
+ "node-stream-zip": "1.15.0",
29
29
  "commander": "12.1.0",
30
- "decompress": "4.2.1",
31
30
  "esbuild": "0.24.0",
32
31
  "esbuild-plugin-tsc": "0.4.0",
33
32
  "import-meta-resolve": "4.1.0",
33
+ "make-fetch-happen": "14.0.3",
34
34
  "readline-sync": "1.4.10"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@types/archiver": "6.0.3",
38
- "@types/decompress": "4.2.7",
39
- "@types/node": "18.19.64",
38
+ "@types/make-fetch-happen": "10.0.4",
39
+ "@types/node": "18.19.67",
40
40
  "@types/readline-sync": "1.4.8",
41
- "prettier": "3.3.3",
41
+ "prettier": "3.4.1",
42
42
  "rimraf": "6.0.1",
43
- "typescript": "5.6.3"
43
+ "typescript": "5.7.2"
44
44
  },
45
45
  "scripts": {
46
46
  "clean": "rimraf target",
@@ -31,7 +31,7 @@ import {
31
31
  webAppUrlOptionValue
32
32
  } from "./options";
33
33
  import { findSimulations } from "../simulations";
34
- import { installGatlingJs } from "../dependencies";
34
+ import { resolveBundle } from "../dependencies";
35
35
  import { bundle } from "../bundle";
36
36
  import { enterpriseDeploy, enterprisePackage } from "../enterprise";
37
37
 
@@ -76,7 +76,7 @@ export default (program: Command): void => {
76
76
  const packageDescriptorFilename = packageDescriptorFilenameOptionValue(options);
77
77
  const packageFile = packageFileOptionValue(options);
78
78
 
79
- const { graalvmHome, jvmClasspath } = await installGatlingJs({ gatlingHome });
79
+ const { graalvmHome, jvmClasspath } = await resolveBundle({ gatlingHome });
80
80
  await bundle({ sourcesFolder, bundleFile, postman, typescript, simulations });
81
81
  await enterprisePackage({ bundleFile, resourcesFolder, packageFile, simulations });
82
82
  await enterpriseDeploy({
@@ -39,7 +39,7 @@ import {
39
39
  waitForRunEndOptionValue
40
40
  } from "./options";
41
41
  import { findSimulations } from "../simulations";
42
- import { installGatlingJs } from "../dependencies";
42
+ import { resolveBundle } from "../dependencies";
43
43
  import { bundle } from "../bundle";
44
44
  import { enterprisePackage, enterpriseStart } from "../enterprise";
45
45
 
@@ -97,7 +97,7 @@ export default (program: Command): void => {
97
97
  throw new Error(`No simulation specified when using non-interactive mode`);
98
98
  }
99
99
 
100
- const { graalvmHome, jvmClasspath } = await installGatlingJs({ gatlingHome });
100
+ const { graalvmHome, jvmClasspath } = await resolveBundle({ gatlingHome });
101
101
  await bundle({ sourcesFolder, bundleFile, postman, typescript, simulations });
102
102
  await enterprisePackage({ bundleFile, resourcesFolder, packageFile, simulations });
103
103
  await enterpriseStart({
@@ -1,7 +1,7 @@
1
1
  import { Command } from "commander";
2
2
 
3
- import { gatlingHomeOption, gatlingHomeOptionValueWithDefaults } from "./options";
4
- import { installGatlingJs } from "../dependencies";
3
+ import { bundleFileArgument, gatlingHomeOption, gatlingHomeOptionValueWithDefaults } from "./options";
4
+ import { installBundleFile, resolveBundle } from "../dependencies";
5
5
  import { logger } from "../log";
6
6
 
7
7
  export default (program: Command): void => {
@@ -9,11 +9,14 @@ export default (program: Command): void => {
9
9
  .command("install")
10
10
  .description("Install all required components and dependencies for Gatling")
11
11
  .addOption(gatlingHomeOption)
12
- .action(async (options) => {
12
+ .addArgument(bundleFileArgument)
13
+ .action(async (bundleFilePath: string | undefined, options) => {
13
14
  const gatlingHome = gatlingHomeOptionValueWithDefaults(options);
14
- const { graalvmHome, coursierBinary, jvmClasspath } = await installGatlingJs({ gatlingHome });
15
+ const { graalvmHome, jvmClasspath } =
16
+ bundleFilePath !== undefined
17
+ ? await installBundleFile({ gatlingHome, bundleFilePath })
18
+ : await resolveBundle({ gatlingHome });
15
19
  logger.info(`graalvmHome=${graalvmHome}`);
16
- logger.info(`coursierBinary=${coursierBinary}`);
17
20
  logger.info(`jvmClasspath=${jvmClasspath}`);
18
21
  });
19
22
  };
@@ -6,6 +6,7 @@ import path from "path";
6
6
  import { SimulationFile } from "../simulations";
7
7
  import { keyInSelectPaginated } from "../readline";
8
8
  import { logger } from "../log";
9
+ import stream from "stream";
9
10
 
10
11
  const getStringValueOptional =
11
12
  (option: Option) =>
@@ -70,7 +71,7 @@ const getNumberValueOptional =
70
71
 
71
72
  export const gatlingHomeOption = new Option(
72
73
  "--gatling-home <value>",
73
- 'The folder used to download and install Gatling components (default: "~/.gatling")'
74
+ 'The folder used to download and install Gatling components (default: "<user home>/.gatling")'
74
75
  );
75
76
  export const gatlingHomeOptionValueWithDefaults = (options: any): string =>
76
77
  getStringValueOptional(gatlingHomeOption)(options) || `${os.homedir()}/.gatling`;
@@ -252,6 +253,11 @@ export const parseRunParametersArgument = (args: string[]): Record<string, strin
252
253
  return parsedParameters;
253
254
  };
254
255
 
256
+ export const bundleFileArgument = new Argument(
257
+ "[bundleFile]",
258
+ "Specify the path to a Gatling JS bundle file to install; if not specified, bundle will be downloaded automatically"
259
+ );
260
+
255
261
  export const apiUrlOption = new Option("--apiUrl <value>", "URL of the Gatling Enterprise API")
256
262
  .default("https://api.gatling.io")
257
263
  .hideHelp();
@@ -11,7 +11,7 @@ import {
11
11
  typescriptOptionValueWithDefaults
12
12
  } from "./options";
13
13
  import { findSimulations } from "../simulations";
14
- import { installRecorder } from "../dependencies";
14
+ import { resolveBundle } from "../dependencies";
15
15
  import { logger } from "../log";
16
16
  import { runRecorder } from "../run";
17
17
 
@@ -31,9 +31,8 @@ export default (program: Command): void => {
31
31
  const simulations = await findSimulations(sourcesFolder);
32
32
  const typescript = typescriptOptionValueWithDefaults(options, simulations);
33
33
 
34
- const { graalvmHome, coursierBinary, jvmClasspath } = await installRecorder({ gatlingHome });
34
+ const { graalvmHome, jvmClasspath } = await resolveBundle({ gatlingHome });
35
35
  logger.debug(`graalvmHome=${graalvmHome}`);
36
- logger.debug(`coursierBinary=${coursierBinary}`);
37
36
  logger.debug(`jvmClasspath=${jvmClasspath}`);
38
37
 
39
38
  await runRecorder({ graalvmHome, jvmClasspath, sourcesFolder, typescript, resourcesFolder });
@@ -24,7 +24,7 @@ import {
24
24
  typescriptOptionValueWithDefaults
25
25
  } from "./options";
26
26
  import { findSimulations } from "../simulations";
27
- import { installGatlingJs } from "../dependencies";
27
+ import { resolveBundle } from "../dependencies";
28
28
  import { logger } from "../log";
29
29
  import { bundle } from "../bundle";
30
30
  import { runSimulation } from "../run";
@@ -61,9 +61,8 @@ export default (program: Command): void => {
61
61
  const typescript = typescriptOptionValueWithDefaults(options, simulations);
62
62
  const simulation = simulationOptionValueWithDefaults(options, simulations, !nonInteractive);
63
63
 
64
- const { graalvmHome, coursierBinary, jvmClasspath } = await installGatlingJs({ gatlingHome, postman });
64
+ const { graalvmHome, jvmClasspath } = await resolveBundle({ gatlingHome });
65
65
  logger.debug(`graalvmHome=${graalvmHome}`);
66
- logger.debug(`coursierBinary=${coursierBinary}`);
67
66
  logger.debug(`jvmClasspath=${jvmClasspath}`);
68
67
 
69
68
  await bundle({ sourcesFolder, bundleFile, postman, typescript, simulations });
@@ -1,11 +1,29 @@
1
- import axios from "axios";
1
+ import fetch, { MakeFetchHappenOptions, TlsOptions } from "make-fetch-happen";
2
2
  import fs from "fs";
3
- import stream from "stream";
4
3
  import util from "util";
4
+ import stream from "stream";
5
5
 
6
6
  const pipeline = util.promisify(stream.pipeline);
7
7
 
8
+ const NPM_CONFIG_PROXY_KEY = "npm_config_proxy";
9
+ const NPM_CONFIG_HTTPS_PROXY_KEY = "npm_config_https_proxy";
10
+ const NPM_CONFIG_NOPROXY_KEY = "npm_config_noproxy";
11
+
12
+ const fetchOptionsFromNpmConfiguration = (): MakeFetchHappenOptions & TlsOptions => {
13
+ const proxy = process.env[NPM_CONFIG_HTTPS_PROXY_KEY] || process.env[NPM_CONFIG_PROXY_KEY] || undefined;
14
+ const noProxy = process.env[NPM_CONFIG_NOPROXY_KEY] || undefined;
15
+ return {
16
+ proxy,
17
+ noProxy
18
+ };
19
+ };
20
+
8
21
  export const downloadFile = async (url: string, targetFile: string): Promise<void> => {
9
- const request = await axios.get(url, { responseType: "stream" });
10
- await pipeline(request.data, fs.createWriteStream(targetFile));
22
+ const options = fetchOptionsFromNpmConfiguration();
23
+ const response = await fetch(url, options);
24
+ if (!response.ok) {
25
+ throw new Error(`Failed to fetch: ${response.status} ${response.statusText}`);
26
+ }
27
+
28
+ await pipeline(response.body, fs.createWriteStream(targetFile));
11
29
  };
@@ -1,45 +1,130 @@
1
- import fs from "fs/promises";
1
+ import * as fsSync from "node:fs";
2
+ import fs from "node:fs/promises";
3
+ import path from "node:path";
2
4
 
3
- import { installCoursier, resolveGatlingJsDependencies, resolveRecorderDependencies } from "./coursier";
4
- import { installGraalVm } from "./graalVm";
5
+ import StreamZip from "node-stream-zip";
6
+
7
+ import { downloadFile } from "./download";
8
+ import { logger } from "../log";
9
+ import { osArch, osType } from "./os";
10
+ import { versions } from "./versions";
5
11
 
6
12
  export { versions } from "./versions";
7
13
 
8
- export interface DependenciesOptions {
14
+ export interface BundleOptions {
9
15
  gatlingHome: string;
10
- postman?: string;
11
16
  }
12
17
 
13
- export interface ResolvedDependencies {
18
+ export interface BundleInstallOptions extends BundleOptions {
19
+ bundleFilePath: string;
20
+ }
21
+
22
+ export interface ResolvedBundle {
14
23
  graalvmHome: string;
15
- coursierBinary: string;
16
24
  jvmClasspath: string;
17
25
  }
18
26
 
19
- export const installGatlingJs = async (options: DependenciesOptions): Promise<ResolvedDependencies> => {
20
- const downloadDir = `${options.gatlingHome}/tmp/download`;
21
- await fs.mkdir(downloadDir, { recursive: true });
22
-
23
- const graalvmHomePath = await installGraalVm(options.gatlingHome, downloadDir);
24
- const coursierPath = await installCoursier(options.gatlingHome, downloadDir);
25
- const classpath = await resolveGatlingJsDependencies(coursierPath, graalvmHomePath, options.postman);
26
- return {
27
- graalvmHome: graalvmHomePath,
28
- coursierBinary: coursierPath,
29
- jvmClasspath: classpath.trim()
30
- };
27
+ export const installBundleFile = async (options: BundleInstallOptions): Promise<ResolvedBundle> => {
28
+ logger.info(`bundleFilePath: ${options.bundleFilePath}`);
29
+ const zip = new StreamZip.async({ file: options.bundleFilePath });
30
+ const metadata = await zip.entryData(metadataFileName);
31
+ const { version } = JSON.parse(metadata.toString("utf-8"));
32
+ if (version === versions.gatling.jsAdapter) {
33
+ logger.info(`Installing dependencies bundle for Gatling JS ${version}, which is the current version`);
34
+ } else {
35
+ logger.info(
36
+ `Installing dependencies bundle for Gatling JS ${version}, which is not the current version (${versions.gatling.jsAdapter})`
37
+ );
38
+ }
39
+
40
+ const bundlePath = getBundlePath(options, version);
41
+ if (await canReadPath(bundlePath)) {
42
+ throw Error(`Directory ${bundlePath} already exists`);
43
+ }
44
+ await fs.mkdir(bundlePath, { recursive: true });
45
+ await zip.extract(null, bundlePath);
46
+ if (osType !== "Windows_NT") {
47
+ const graalVmBinDir = path.join(bundlePath, "graalvm", "bin");
48
+ const binFiles = await fs.readdir(graalVmBinDir);
49
+ for (const binFile of binFiles) {
50
+ await fs.chmod(path.join(graalVmBinDir, binFile), 0o744); // chmod +x
51
+ }
52
+ }
53
+ logger.info(`Gatling JS dependencies bundle installed in ${bundlePath}`);
54
+
55
+ return getResolvedBundle(bundlePath);
31
56
  };
32
57
 
33
- export const installRecorder = async (options: DependenciesOptions): Promise<ResolvedDependencies> => {
34
- const downloadDir = `${options.gatlingHome}/tmp/download`;
35
- await fs.mkdir(downloadDir, { recursive: true });
36
-
37
- const graalvmHomePath = await installGraalVm(options.gatlingHome, downloadDir);
38
- const coursierPath = await installCoursier(options.gatlingHome, downloadDir);
39
- const classpath = await resolveRecorderDependencies(coursierPath, graalvmHomePath);
40
- return {
41
- graalvmHome: graalvmHomePath,
42
- coursierBinary: coursierPath,
43
- jvmClasspath: classpath.trim()
44
- };
58
+ export const resolveBundle = async (options: BundleOptions): Promise<ResolvedBundle> => {
59
+ const bundlePath = getBundlePath(options, versions.gatling.jsAdapter);
60
+ if (await canReadPath(bundlePath)) {
61
+ // Basic check of the installed bundle we found
62
+ const bundleMetadataPath = path.join(bundlePath, metadataFileName);
63
+ let version = "";
64
+ try {
65
+ const f = await fs.readFile(bundleMetadataPath, { encoding: "utf-8" });
66
+ const metadata = JSON.parse(f);
67
+ version = metadata.version;
68
+ } catch {}
69
+ if (version !== versions.gatling.jsAdapter) {
70
+ throw Error(`Inconsistent bundle content found at ${bundlePath}`);
71
+ }
72
+ return getResolvedBundle(bundlePath);
73
+ } else {
74
+ return await downloadAndInstallBundle(options);
75
+ }
76
+ };
77
+
78
+ const getBundlePath = (options: BundleOptions, version: string) =>
79
+ path.join(options.gatlingHome, "gatling-js-bundle", version);
80
+
81
+ const metadataFileName = "gatling-bundle.json";
82
+
83
+ const canReadPath = async (path: string) => {
84
+ try {
85
+ await fs.access(path, fs.constants.R_OK);
86
+ return true;
87
+ } catch (e) {
88
+ if ((e as any).code === "ENOENT") {
89
+ return false;
90
+ } else {
91
+ throw e;
92
+ }
93
+ }
94
+ };
95
+
96
+ const getResolvedBundle = (bundlePath: string): ResolvedBundle => ({
97
+ graalvmHome: path.join(bundlePath, "graalvm"),
98
+ jvmClasspath: path.join(bundlePath, "lib", "java", "*")
99
+ });
100
+
101
+ const downloadAndInstallBundle = async (options: BundleOptions) => {
102
+ const tmpFolder = path.join(options.gatlingHome, "tmp");
103
+ if (!fsSync.existsSync(tmpFolder)) {
104
+ await fs.mkdir(tmpFolder);
105
+ }
106
+
107
+ const tmpFile = path.join(tmpFolder, "bundle-download.zip");
108
+ if (fsSync.existsSync(tmpFile)) {
109
+ await fs.rm(tmpFile);
110
+ }
111
+
112
+ const version = versions.gatling.jsAdapter;
113
+ const url = `https://github.com/gatling/gatling-js/releases/download/v${version}/gatling-js-bundle-${version}-${osType}-${osArch}.zip`;
114
+ try {
115
+ logger.info(`Downloading bundle file from ${url} to temporary file ${tmpFile}`);
116
+ await downloadFile(url, tmpFile);
117
+
118
+ const resolvedBundle = await installBundleFile({ ...options, bundleFilePath: tmpFile });
119
+
120
+ logger.info(`Deleting temporary file ${tmpFile}`);
121
+ await fs.rm(tmpFile);
122
+
123
+ return resolvedBundle;
124
+ } catch (e) {
125
+ logger.error(`Failed to automatically download and install the Gatling dependency bundle. You can try to:
126
+ 1. Make sure you have access to https://github.com/gatling/gatling-js/releases/; and if you connect to the Internet through a proxy, make sure it is configured in your NPM configuration file (.npmrc).
127
+ 2. Alternatively, you can try manually downloading the file from ${url}, and install it with the command 'npx gatling install <path-to-downloaded-file.zip>'.`);
128
+ throw e;
129
+ }
45
130
  };
@@ -1,15 +1,14 @@
1
1
  export const versions = {
2
2
  graalvm: {
3
- jdk: "23.0.0",
3
+ jdk: "23.0.1",
4
4
  js: "24.1.1"
5
5
  },
6
6
  java: {
7
7
  compilerRelease: "21"
8
8
  },
9
- coursier: "2.1.12",
10
9
  gatling: {
11
10
  core: "3.13.1",
12
- enterprisePluginCommons: "1.9.8",
13
- jsAdapter: "3.13.103"
11
+ enterprisePluginCommons: "1.11.0",
12
+ jsAdapter: "3.13.104-M4"
14
13
  }
15
14
  };
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
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
- };
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
25
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
37
  };
@@ -43,7 +43,7 @@ exports.default = (program) => {
43
43
  const nonInteractive = (0, options_1.nonInteractiveOptionValue)(options);
44
44
  const packageDescriptorFilename = (0, options_1.packageDescriptorFilenameOptionValue)(options);
45
45
  const packageFile = (0, options_1.packageFileOptionValue)(options);
46
- const { graalvmHome, jvmClasspath } = await (0, dependencies_1.installGatlingJs)({ gatlingHome });
46
+ const { graalvmHome, jvmClasspath } = await (0, dependencies_1.resolveBundle)({ gatlingHome });
47
47
  await (0, bundle_1.bundle)({ sourcesFolder, bundleFile, postman, typescript, simulations });
48
48
  await (0, enterprise_1.enterprisePackage)({ bundleFile, resourcesFolder, packageFile, simulations });
49
49
  await (0, enterprise_1.enterpriseDeploy)({
@@ -55,7 +55,7 @@ exports.default = (program) => {
55
55
  if ((0, options_1.nonInteractiveOptionValue)(options) && enterpriseSimulation === undefined) {
56
56
  throw new Error(`No simulation specified when using non-interactive mode`);
57
57
  }
58
- const { graalvmHome, jvmClasspath } = await (0, dependencies_1.installGatlingJs)({ gatlingHome });
58
+ const { graalvmHome, jvmClasspath } = await (0, dependencies_1.resolveBundle)({ gatlingHome });
59
59
  await (0, bundle_1.bundle)({ sourcesFolder, bundleFile, postman, typescript, simulations });
60
60
  await (0, enterprise_1.enterprisePackage)({ bundleFile, resourcesFolder, packageFile, simulations });
61
61
  await (0, enterprise_1.enterpriseStart)({
@@ -8,11 +8,13 @@ exports.default = (program) => {
8
8
  .command("install")
9
9
  .description("Install all required components and dependencies for Gatling")
10
10
  .addOption(options_1.gatlingHomeOption)
11
- .action(async (options) => {
11
+ .addArgument(options_1.bundleFileArgument)
12
+ .action(async (bundleFilePath, options) => {
12
13
  const gatlingHome = (0, options_1.gatlingHomeOptionValueWithDefaults)(options);
13
- const { graalvmHome, coursierBinary, jvmClasspath } = await (0, dependencies_1.installGatlingJs)({ gatlingHome });
14
+ const { graalvmHome, jvmClasspath } = bundleFilePath !== undefined
15
+ ? await (0, dependencies_1.installBundleFile)({ gatlingHome, bundleFilePath })
16
+ : await (0, dependencies_1.resolveBundle)({ gatlingHome });
14
17
  log_1.logger.info(`graalvmHome=${graalvmHome}`);
15
- log_1.logger.info(`coursierBinary=${coursierBinary}`);
16
18
  log_1.logger.info(`jvmClasspath=${jvmClasspath}`);
17
19
  });
18
20
  };
@@ -30,6 +30,7 @@ export declare const postmanOption: Option;
30
30
  export declare const postmanOptionValueWithDefaults: (options: any) => string | undefined;
31
31
  export declare const runParametersArgument: Argument;
32
32
  export declare const parseRunParametersArgument: (args: string[]) => Record<string, string>;
33
+ export declare const bundleFileArgument: Argument;
33
34
  export declare const apiUrlOption: Option;
34
35
  export declare const apiUrlOptionValue: (options: any) => string;
35
36
  export declare const webAppUrlOption: Option;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.waitForRunEndOptionValue = exports.waitForRunEndOption = exports.runDescriptionOptionValue = exports.runDescriptionOption = exports.runTitleOptionValue = exports.runTitleOption = exports.enterpriseSimulationOptionValue = exports.enterpriseSimulationOption = exports.packageDescriptorFilenameOptionValue = exports.packageDescriptorFilenameOption = exports.controlPlaneUrlOptionValue = exports.controlPlaneUrlOption = exports.apiTokenOptionValue = exports.apiTokenOption = exports.webAppUrlOptionValue = exports.webAppUrlOption = exports.apiUrlOptionValue = exports.apiUrlOption = exports.parseRunParametersArgument = exports.runParametersArgument = exports.postmanOptionValueWithDefaults = exports.postmanOption = exports.nonInteractiveOptionValue = exports.nonInteractiveOption = exports.memoryOptionValue = exports.memoryOption = exports.jvmClasspathMandatoryOptionValue = exports.jvmClasspathMandatoryOption = exports.graalvmHomeMandatoryOptionValue = exports.graalvmHomeMandatoryOption = exports.typescriptOptionValueWithDefaults = exports.typescriptOption = exports.resultsFolderOptionValue = exports.resultsFolderOption = exports.resourcesFolderOptionValue = exports.resourcesFolderOption = exports.packageFileOptionValue = exports.packageFileOption = exports.bundleFileOptionValue = exports.bundleFileOption = exports.simulationMandatoryOptionValue = exports.simulationMandatoryOption = exports.simulationOptionValueWithDefaults = exports.simulationOption = exports.sourcesFolderOptionValue = exports.sourcesFolderOption = exports.gatlingHomeOptionValueWithDefaults = exports.gatlingHomeOption = void 0;
6
+ exports.waitForRunEndOptionValue = exports.waitForRunEndOption = exports.runDescriptionOptionValue = exports.runDescriptionOption = exports.runTitleOptionValue = exports.runTitleOption = exports.enterpriseSimulationOptionValue = exports.enterpriseSimulationOption = exports.packageDescriptorFilenameOptionValue = exports.packageDescriptorFilenameOption = exports.controlPlaneUrlOptionValue = exports.controlPlaneUrlOption = exports.apiTokenOptionValue = exports.apiTokenOption = exports.webAppUrlOptionValue = exports.webAppUrlOption = exports.apiUrlOptionValue = exports.apiUrlOption = exports.bundleFileArgument = exports.parseRunParametersArgument = exports.runParametersArgument = exports.postmanOptionValueWithDefaults = exports.postmanOption = exports.nonInteractiveOptionValue = exports.nonInteractiveOption = exports.memoryOptionValue = exports.memoryOption = exports.jvmClasspathMandatoryOptionValue = exports.jvmClasspathMandatoryOption = exports.graalvmHomeMandatoryOptionValue = exports.graalvmHomeMandatoryOption = exports.typescriptOptionValueWithDefaults = exports.typescriptOption = exports.resultsFolderOptionValue = exports.resultsFolderOption = exports.resourcesFolderOptionValue = exports.resourcesFolderOption = exports.packageFileOptionValue = exports.packageFileOption = exports.bundleFileOptionValue = exports.bundleFileOption = exports.simulationMandatoryOptionValue = exports.simulationMandatoryOption = exports.simulationOptionValueWithDefaults = exports.simulationOption = exports.sourcesFolderOptionValue = exports.sourcesFolderOption = exports.gatlingHomeOptionValueWithDefaults = exports.gatlingHomeOption = void 0;
7
7
  const commander_1 = require("commander");
8
8
  const fs_1 = __importDefault(require("fs"));
9
9
  const os_1 = __importDefault(require("os"));
@@ -55,7 +55,7 @@ const getNumberValueOptional = (option) => (options) => {
55
55
  throw Error(`Expected type number|undefined for attribute ${option.attributeName()}, got ${typeof value} - please report this as a bug.`);
56
56
  }
57
57
  };
58
- exports.gatlingHomeOption = new commander_1.Option("--gatling-home <value>", 'The folder used to download and install Gatling components (default: "~/.gatling")');
58
+ exports.gatlingHomeOption = new commander_1.Option("--gatling-home <value>", 'The folder used to download and install Gatling components (default: "<user home>/.gatling")');
59
59
  const gatlingHomeOptionValueWithDefaults = (options) => getStringValueOptional(exports.gatlingHomeOption)(options) || `${os_1.default.homedir()}/.gatling`;
60
60
  exports.gatlingHomeOptionValueWithDefaults = gatlingHomeOptionValueWithDefaults;
61
61
  exports.sourcesFolderOption = new commander_1.Option("--sources-folder <value>", "The sources folder path").default("src");
@@ -187,6 +187,7 @@ const parseRunParametersArgument = (args) => {
187
187
  return parsedParameters;
188
188
  };
189
189
  exports.parseRunParametersArgument = parseRunParametersArgument;
190
+ exports.bundleFileArgument = new commander_1.Argument("[bundleFile]", "Specify the path to a Gatling JS bundle file to install; if not specified, bundle will be downloaded automatically");
190
191
  exports.apiUrlOption = new commander_1.Option("--apiUrl <value>", "URL of the Gatling Enterprise API")
191
192
  .default("https://api.gatling.io")
192
193
  .hideHelp();
@@ -19,9 +19,8 @@ exports.default = (program) => {
19
19
  const resourcesFolder = (0, options_1.resourcesFolderOptionValue)(options);
20
20
  const simulations = await (0, simulations_1.findSimulations)(sourcesFolder);
21
21
  const typescript = (0, options_1.typescriptOptionValueWithDefaults)(options, simulations);
22
- const { graalvmHome, coursierBinary, jvmClasspath } = await (0, dependencies_1.installRecorder)({ gatlingHome });
22
+ const { graalvmHome, jvmClasspath } = await (0, dependencies_1.resolveBundle)({ gatlingHome });
23
23
  log_1.logger.debug(`graalvmHome=${graalvmHome}`);
24
- log_1.logger.debug(`coursierBinary=${coursierBinary}`);
25
24
  log_1.logger.debug(`jvmClasspath=${jvmClasspath}`);
26
25
  await (0, run_1.runRecorder)({ graalvmHome, jvmClasspath, sourcesFolder, typescript, resourcesFolder });
27
26
  });
@@ -34,9 +34,8 @@ exports.default = (program) => {
34
34
  const simulations = await (0, simulations_1.findSimulations)(sourcesFolder);
35
35
  const typescript = (0, options_1.typescriptOptionValueWithDefaults)(options, simulations);
36
36
  const simulation = (0, options_1.simulationOptionValueWithDefaults)(options, simulations, !nonInteractive);
37
- const { graalvmHome, coursierBinary, jvmClasspath } = await (0, dependencies_1.installGatlingJs)({ gatlingHome, postman });
37
+ const { graalvmHome, jvmClasspath } = await (0, dependencies_1.resolveBundle)({ gatlingHome });
38
38
  log_1.logger.debug(`graalvmHome=${graalvmHome}`);
39
- log_1.logger.debug(`coursierBinary=${coursierBinary}`);
40
39
  log_1.logger.debug(`jvmClasspath=${jvmClasspath}`);
41
40
  await (0, bundle_1.bundle)({ sourcesFolder, bundleFile, postman, typescript, simulations });
42
41
  await (0, run_1.runSimulation)({
@@ -4,13 +4,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.downloadFile = void 0;
7
- const axios_1 = __importDefault(require("axios"));
7
+ const make_fetch_happen_1 = __importDefault(require("make-fetch-happen"));
8
8
  const fs_1 = __importDefault(require("fs"));
9
- const stream_1 = __importDefault(require("stream"));
10
9
  const util_1 = __importDefault(require("util"));
10
+ const stream_1 = __importDefault(require("stream"));
11
11
  const pipeline = util_1.default.promisify(stream_1.default.pipeline);
12
+ const NPM_CONFIG_PROXY_KEY = "npm_config_proxy";
13
+ const NPM_CONFIG_HTTPS_PROXY_KEY = "npm_config_https_proxy";
14
+ const NPM_CONFIG_NOPROXY_KEY = "npm_config_noproxy";
15
+ const fetchOptionsFromNpmConfiguration = () => {
16
+ const proxy = process.env[NPM_CONFIG_HTTPS_PROXY_KEY] || process.env[NPM_CONFIG_PROXY_KEY] || undefined;
17
+ const noProxy = process.env[NPM_CONFIG_NOPROXY_KEY] || undefined;
18
+ return {
19
+ proxy,
20
+ noProxy
21
+ };
22
+ };
12
23
  const downloadFile = async (url, targetFile) => {
13
- const request = await axios_1.default.get(url, { responseType: "stream" });
14
- await pipeline(request.data, fs_1.default.createWriteStream(targetFile));
24
+ const options = fetchOptionsFromNpmConfiguration();
25
+ const response = await (0, make_fetch_happen_1.default)(url, options);
26
+ if (!response.ok) {
27
+ throw new Error(`Failed to fetch: ${response.status} ${response.statusText}`);
28
+ }
29
+ await pipeline(response.body, fs_1.default.createWriteStream(targetFile));
15
30
  };
16
31
  exports.downloadFile = downloadFile;
@@ -1,12 +1,13 @@
1
1
  export { versions } from "./versions";
2
- export interface DependenciesOptions {
2
+ export interface BundleOptions {
3
3
  gatlingHome: string;
4
- postman?: string;
5
4
  }
6
- export interface ResolvedDependencies {
5
+ export interface BundleInstallOptions extends BundleOptions {
6
+ bundleFilePath: string;
7
+ }
8
+ export interface ResolvedBundle {
7
9
  graalvmHome: string;
8
- coursierBinary: string;
9
10
  jvmClasspath: string;
10
11
  }
11
- export declare const installGatlingJs: (options: DependenciesOptions) => Promise<ResolvedDependencies>;
12
- export declare const installRecorder: (options: DependenciesOptions) => Promise<ResolvedDependencies>;
12
+ export declare const installBundleFile: (options: BundleInstallOptions) => Promise<ResolvedBundle>;
13
+ export declare const resolveBundle: (options: BundleOptions) => Promise<ResolvedBundle>;
@@ -1,37 +1,145 @@
1
1
  "use strict";
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 () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
37
  };
5
38
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.installRecorder = exports.installGatlingJs = exports.versions = void 0;
7
- const promises_1 = __importDefault(require("fs/promises"));
8
- const coursier_1 = require("./coursier");
9
- const graalVm_1 = require("./graalVm");
10
- var versions_1 = require("./versions");
11
- Object.defineProperty(exports, "versions", { enumerable: true, get: function () { return versions_1.versions; } });
12
- const installGatlingJs = async (options) => {
13
- const downloadDir = `${options.gatlingHome}/tmp/download`;
14
- await promises_1.default.mkdir(downloadDir, { recursive: true });
15
- const graalvmHomePath = await (0, graalVm_1.installGraalVm)(options.gatlingHome, downloadDir);
16
- const coursierPath = await (0, coursier_1.installCoursier)(options.gatlingHome, downloadDir);
17
- const classpath = await (0, coursier_1.resolveGatlingJsDependencies)(coursierPath, graalvmHomePath, options.postman);
18
- return {
19
- graalvmHome: graalvmHomePath,
20
- coursierBinary: coursierPath,
21
- jvmClasspath: classpath.trim()
22
- };
39
+ exports.resolveBundle = exports.installBundleFile = exports.versions = void 0;
40
+ const fsSync = __importStar(require("node:fs"));
41
+ const promises_1 = __importDefault(require("node:fs/promises"));
42
+ const node_path_1 = __importDefault(require("node:path"));
43
+ const node_stream_zip_1 = __importDefault(require("node-stream-zip"));
44
+ const download_1 = require("./download");
45
+ const log_1 = require("../log");
46
+ const os_1 = require("./os");
47
+ const versions_1 = require("./versions");
48
+ var versions_2 = require("./versions");
49
+ Object.defineProperty(exports, "versions", { enumerable: true, get: function () { return versions_2.versions; } });
50
+ const installBundleFile = async (options) => {
51
+ log_1.logger.info(`bundleFilePath: ${options.bundleFilePath}`);
52
+ const zip = new node_stream_zip_1.default.async({ file: options.bundleFilePath });
53
+ const metadata = await zip.entryData(metadataFileName);
54
+ const { version } = JSON.parse(metadata.toString("utf-8"));
55
+ if (version === versions_1.versions.gatling.jsAdapter) {
56
+ log_1.logger.info(`Installing dependencies bundle for Gatling JS ${version}, which is the current version`);
57
+ }
58
+ else {
59
+ log_1.logger.info(`Installing dependencies bundle for Gatling JS ${version}, which is not the current version (${versions_1.versions.gatling.jsAdapter})`);
60
+ }
61
+ const bundlePath = getBundlePath(options, version);
62
+ if (await canReadPath(bundlePath)) {
63
+ throw Error(`Directory ${bundlePath} already exists`);
64
+ }
65
+ await promises_1.default.mkdir(bundlePath, { recursive: true });
66
+ await zip.extract(null, bundlePath);
67
+ if (os_1.osType !== "Windows_NT") {
68
+ const graalVmBinDir = node_path_1.default.join(bundlePath, "graalvm", "bin");
69
+ const binFiles = await promises_1.default.readdir(graalVmBinDir);
70
+ for (const binFile of binFiles) {
71
+ await promises_1.default.chmod(node_path_1.default.join(graalVmBinDir, binFile), 0o744); // chmod +x
72
+ }
73
+ }
74
+ log_1.logger.info(`Gatling JS dependencies bundle installed in ${bundlePath}`);
75
+ return getResolvedBundle(bundlePath);
23
76
  };
24
- exports.installGatlingJs = installGatlingJs;
25
- const installRecorder = async (options) => {
26
- const downloadDir = `${options.gatlingHome}/tmp/download`;
27
- await promises_1.default.mkdir(downloadDir, { recursive: true });
28
- const graalvmHomePath = await (0, graalVm_1.installGraalVm)(options.gatlingHome, downloadDir);
29
- const coursierPath = await (0, coursier_1.installCoursier)(options.gatlingHome, downloadDir);
30
- const classpath = await (0, coursier_1.resolveRecorderDependencies)(coursierPath, graalvmHomePath);
31
- return {
32
- graalvmHome: graalvmHomePath,
33
- coursierBinary: coursierPath,
34
- jvmClasspath: classpath.trim()
35
- };
77
+ exports.installBundleFile = installBundleFile;
78
+ const resolveBundle = async (options) => {
79
+ const bundlePath = getBundlePath(options, versions_1.versions.gatling.jsAdapter);
80
+ if (await canReadPath(bundlePath)) {
81
+ // Basic check of the installed bundle we found
82
+ const bundleMetadataPath = node_path_1.default.join(bundlePath, metadataFileName);
83
+ let version = "";
84
+ try {
85
+ const f = await promises_1.default.readFile(bundleMetadataPath, { encoding: "utf-8" });
86
+ const metadata = JSON.parse(f);
87
+ version = metadata.version;
88
+ }
89
+ catch { }
90
+ if (version !== versions_1.versions.gatling.jsAdapter) {
91
+ throw Error(`Inconsistent bundle content found at ${bundlePath}`);
92
+ }
93
+ return getResolvedBundle(bundlePath);
94
+ }
95
+ else {
96
+ return await downloadAndInstallBundle(options);
97
+ }
98
+ };
99
+ exports.resolveBundle = resolveBundle;
100
+ const getBundlePath = (options, version) => node_path_1.default.join(options.gatlingHome, "gatling-js-bundle", version);
101
+ const metadataFileName = "gatling-bundle.json";
102
+ const canReadPath = async (path) => {
103
+ try {
104
+ await promises_1.default.access(path, promises_1.default.constants.R_OK);
105
+ return true;
106
+ }
107
+ catch (e) {
108
+ if (e.code === "ENOENT") {
109
+ return false;
110
+ }
111
+ else {
112
+ throw e;
113
+ }
114
+ }
115
+ };
116
+ const getResolvedBundle = (bundlePath) => ({
117
+ graalvmHome: node_path_1.default.join(bundlePath, "graalvm"),
118
+ jvmClasspath: node_path_1.default.join(bundlePath, "lib", "java", "*")
119
+ });
120
+ const downloadAndInstallBundle = async (options) => {
121
+ const tmpFolder = node_path_1.default.join(options.gatlingHome, "tmp");
122
+ if (!fsSync.existsSync(tmpFolder)) {
123
+ await promises_1.default.mkdir(tmpFolder);
124
+ }
125
+ const tmpFile = node_path_1.default.join(tmpFolder, "bundle-download.zip");
126
+ if (fsSync.existsSync(tmpFile)) {
127
+ await promises_1.default.rm(tmpFile);
128
+ }
129
+ const version = versions_1.versions.gatling.jsAdapter;
130
+ const url = `https://github.com/gatling/gatling-js/releases/download/v${version}/gatling-js-bundle-${version}-${os_1.osType}-${os_1.osArch}.zip`;
131
+ try {
132
+ log_1.logger.info(`Downloading bundle file from ${url} to temporary file ${tmpFile}`);
133
+ await (0, download_1.downloadFile)(url, tmpFile);
134
+ const resolvedBundle = await (0, exports.installBundleFile)({ ...options, bundleFilePath: tmpFile });
135
+ log_1.logger.info(`Deleting temporary file ${tmpFile}`);
136
+ await promises_1.default.rm(tmpFile);
137
+ return resolvedBundle;
138
+ }
139
+ catch (e) {
140
+ log_1.logger.error(`Failed to automatically download and install the Gatling dependency bundle. You can try to:
141
+ 1. Make sure you have access to https://github.com/gatling/gatling-js/releases/; and if you connect to the Internet through a proxy, make sure it is configured in your NPM configuration file (.npmrc).
142
+ 2. Alternatively, you can try manually downloading the file from ${url}, and install it with the command 'npx gatling install <path-to-downloaded-file.zip>'.`);
143
+ throw e;
144
+ }
36
145
  };
37
- exports.installRecorder = installRecorder;
@@ -6,7 +6,6 @@ export declare const versions: {
6
6
  java: {
7
7
  compilerRelease: string;
8
8
  };
9
- coursier: string;
10
9
  gatling: {
11
10
  core: string;
12
11
  enterprisePluginCommons: string;
@@ -3,16 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.versions = void 0;
4
4
  exports.versions = {
5
5
  graalvm: {
6
- jdk: "23.0.0",
6
+ jdk: "23.0.1",
7
7
  js: "24.1.1"
8
8
  },
9
9
  java: {
10
10
  compilerRelease: "21"
11
11
  },
12
- coursier: "2.1.12",
13
12
  gatling: {
14
13
  core: "3.13.1",
15
- enterprisePluginCommons: "1.9.8",
16
- jsAdapter: "3.13.103"
14
+ enterprisePluginCommons: "1.11.0",
15
+ jsAdapter: "3.13.104-M4"
17
16
  }
18
17
  };
@@ -1,84 +0,0 @@
1
- import { existsSync } from "fs";
2
- import fs from "fs/promises";
3
-
4
- import { downloadFile } from "./download";
5
- import { logger } from "../log";
6
- import { versions } from "./versions";
7
- import { promisify } from "util";
8
- import { exec } from "child_process";
9
- import { osType } from "./os";
10
-
11
- export const installCoursier = async (gatlingHomeDir: string, downloadDir: string): Promise<string> => {
12
- const coursierRootPath = `${gatlingHomeDir}/coursier/${versions.coursier}`;
13
- const coursierPath = `${coursierRootPath}/cs`;
14
-
15
- if (!existsSync(coursierPath)) {
16
- const jarUrl = `https://github.com/coursier/coursier/releases/download/v${versions.coursier}/coursier`;
17
- const windowsBatUrl = `https://github.com/coursier/launchers/raw/master/coursier.bat`;
18
- const downloadPath = `${downloadDir}/cs`;
19
-
20
- if (existsSync(coursierRootPath)) {
21
- await fs.rm(coursierRootPath, { recursive: true });
22
- }
23
- if (existsSync(downloadPath)) {
24
- await fs.rm(downloadPath);
25
- }
26
- await fs.mkdir(coursierRootPath, { recursive: true });
27
-
28
- logger.info(`Downloading Coursier ${versions.coursier} to ${downloadPath}`);
29
- await downloadFile(jarUrl, downloadPath);
30
- if (osType === "Windows_NT") {
31
- await downloadFile(windowsBatUrl, `${downloadPath}.bat`);
32
- } else {
33
- await fs.chmod(downloadPath, 0o744);
34
- }
35
-
36
- logger.info(`Installing Coursier to ${coursierPath}`);
37
- await fs.rename(downloadPath, coursierPath);
38
- if (osType === "Windows_NT") {
39
- await fs.rename(`${downloadPath}.bat`, `${coursierPath}.bat`);
40
- }
41
- } else {
42
- logger.info(`Coursier ${versions.coursier} already installed at ${coursierPath}`);
43
- }
44
-
45
- return coursierPath;
46
- };
47
-
48
- export const resolveGatlingJsDependencies = async (
49
- coursierPath: string,
50
- javaHome: string,
51
- postmanVersion?: string
52
- ): Promise<string> => {
53
- const dependencies = [
54
- `"io.gatling.highcharts:gatling-charts-highcharts:${versions.gatling.core}"`,
55
- `"io.gatling:gatling-jvm-to-js-adapter:${versions.gatling.jsAdapter}"`,
56
- `"io.gatling:gatling-enterprise-plugin-commons:${versions.gatling.enterprisePluginCommons}"`,
57
- `"org.graalvm.polyglot:js-community:${versions.graalvm.js}"`
58
- ];
59
- if (postmanVersion !== undefined) {
60
- dependencies.push(`"io.gatling:gatling-postman-jvm-to-js-adapter:${postmanVersion}"`);
61
- }
62
-
63
- return await resolveDependencies(coursierPath, javaHome, ...dependencies);
64
- };
65
-
66
- export const resolveRecorderDependencies = async (coursierPath: string, javaHome: string): Promise<string> => {
67
- const recorderDep = `io.gatling:gatling-recorder:${versions.gatling.core}`;
68
- return await resolveDependencies(coursierPath, javaHome, recorderDep);
69
- };
70
-
71
- const resolveDependencies = async (
72
- coursierPath: string,
73
- javaHome: string,
74
- ...dependencies: string[]
75
- ): Promise<string> => {
76
- const command = `"${coursierPath}" fetch --classpath ${dependencies.join(" ")}`;
77
-
78
- // TODO could add a timeout
79
- logger.info(`Resolving dependencies with Coursier`);
80
- const { stdout } = await execAsync(command, { env: { ...process.env, JAVA_HOME: javaHome } });
81
- return stdout;
82
- };
83
-
84
- const execAsync = promisify(exec);
@@ -1,74 +0,0 @@
1
- import { existsSync } from "fs";
2
- import fs from "fs/promises";
3
- import decompress from "decompress";
4
-
5
- import { downloadFile } from "./download";
6
- import { logger } from "../log";
7
- import { osType, osArch } from "./os";
8
- import { versions } from "./versions";
9
-
10
- export const installGraalVm = async (gatlingHomeDir: string, downloadDir: string): Promise<string> => {
11
- const { os, arch, extension, homePath, binPath } = graalVmPlatformParams();
12
- const graalvmRootPath = `${gatlingHomeDir}/graalvm/${versions.graalvm.jdk}`;
13
- const graalvmHomePath = `${graalvmRootPath}${homePath}`;
14
- const graalvmJavaPath = `${graalvmHomePath}${binPath}`;
15
-
16
- if (!existsSync(graalvmJavaPath)) {
17
- const url = `https://github.com/graalvm/graalvm-ce-builds/releases/download/jdk-${versions.graalvm.jdk}/graalvm-community-jdk-${versions.graalvm.jdk}_${os}-${arch}_bin.${extension}`;
18
- const downloadPath = `${downloadDir}/graalvm.${extension}`;
19
-
20
- if (existsSync(graalvmRootPath)) {
21
- await fs.rm(graalvmRootPath, { recursive: true });
22
- }
23
- if (existsSync(downloadPath)) {
24
- await fs.rm(downloadPath);
25
- }
26
- await fs.mkdir(graalvmRootPath, { recursive: true });
27
-
28
- logger.info(`Downloading GraalVM Community Edition ${versions.graalvm.jdk} to ${downloadPath}`);
29
- await downloadFile(url, downloadPath);
30
-
31
- logger.info(`Unpacking GraalVM to ${graalvmRootPath}`);
32
- await decompress(downloadPath, graalvmRootPath, {
33
- map: (file) => {
34
- // Remove first level of file name, because it already contains a root directory
35
- file.path = file.path.split("/").slice(1).join("/");
36
- return file;
37
- }
38
- });
39
-
40
- await fs.rm(downloadPath);
41
- } else {
42
- logger.info(`GraalVM Community Edition ${versions.graalvm.jdk} already installed at ${graalvmRootPath}`);
43
- }
44
-
45
- return graalvmHomePath;
46
- };
47
-
48
- const graalVmPlatformParams = () => {
49
- if (osType === "Linux") {
50
- const os = "linux";
51
- const extension = "tar.gz";
52
- const homePath = "";
53
- const binPath = "/bin/java";
54
- if (osArch === "x64") {
55
- return { os, arch: "x64", extension, homePath, binPath };
56
- } else if (osArch === "arm64") {
57
- return { os, arch: "aarch64", extension, homePath, binPath };
58
- }
59
- } else if (osType === "Darwin") {
60
- const os = "macos";
61
- const extension = "tar.gz";
62
- const homePath = "/Contents/Home";
63
- const binPath = "/bin/java";
64
- if (osArch === "x64") {
65
- return { os, arch: "x64", extension, homePath, binPath };
66
- } else if (osArch === "arm64") {
67
- return { os, arch: "aarch64", extension, homePath, binPath };
68
- }
69
- } else if (osType === "Windows_NT" && osArch === "x64") {
70
- return { os: "windows", arch: "x64", extension: "zip", homePath: "", binPath: "/bin/java.exe" };
71
- }
72
-
73
- throw Error(`Operating system type '${osType}' with architecture '${osArch}' is not currently supported.`);
74
- };
@@ -1,3 +0,0 @@
1
- export declare const installCoursier: (gatlingHomeDir: string, downloadDir: string) => Promise<string>;
2
- export declare const resolveGatlingJsDependencies: (coursierPath: string, javaHome: string, postmanVersion?: string) => Promise<string>;
3
- export declare const resolveRecorderDependencies: (coursierPath: string, javaHome: string) => Promise<string>;
@@ -1,74 +0,0 @@
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.resolveRecorderDependencies = exports.resolveGatlingJsDependencies = exports.installCoursier = void 0;
7
- const fs_1 = require("fs");
8
- const promises_1 = __importDefault(require("fs/promises"));
9
- const download_1 = require("./download");
10
- const log_1 = require("../log");
11
- const versions_1 = require("./versions");
12
- const util_1 = require("util");
13
- const child_process_1 = require("child_process");
14
- const os_1 = require("./os");
15
- const installCoursier = async (gatlingHomeDir, downloadDir) => {
16
- const coursierRootPath = `${gatlingHomeDir}/coursier/${versions_1.versions.coursier}`;
17
- const coursierPath = `${coursierRootPath}/cs`;
18
- if (!(0, fs_1.existsSync)(coursierPath)) {
19
- const jarUrl = `https://github.com/coursier/coursier/releases/download/v${versions_1.versions.coursier}/coursier`;
20
- const windowsBatUrl = `https://github.com/coursier/launchers/raw/master/coursier.bat`;
21
- const downloadPath = `${downloadDir}/cs`;
22
- if ((0, fs_1.existsSync)(coursierRootPath)) {
23
- await promises_1.default.rm(coursierRootPath, { recursive: true });
24
- }
25
- if ((0, fs_1.existsSync)(downloadPath)) {
26
- await promises_1.default.rm(downloadPath);
27
- }
28
- await promises_1.default.mkdir(coursierRootPath, { recursive: true });
29
- log_1.logger.info(`Downloading Coursier ${versions_1.versions.coursier} to ${downloadPath}`);
30
- await (0, download_1.downloadFile)(jarUrl, downloadPath);
31
- if (os_1.osType === "Windows_NT") {
32
- await (0, download_1.downloadFile)(windowsBatUrl, `${downloadPath}.bat`);
33
- }
34
- else {
35
- await promises_1.default.chmod(downloadPath, 0o744);
36
- }
37
- log_1.logger.info(`Installing Coursier to ${coursierPath}`);
38
- await promises_1.default.rename(downloadPath, coursierPath);
39
- if (os_1.osType === "Windows_NT") {
40
- await promises_1.default.rename(`${downloadPath}.bat`, `${coursierPath}.bat`);
41
- }
42
- }
43
- else {
44
- log_1.logger.info(`Coursier ${versions_1.versions.coursier} already installed at ${coursierPath}`);
45
- }
46
- return coursierPath;
47
- };
48
- exports.installCoursier = installCoursier;
49
- const resolveGatlingJsDependencies = async (coursierPath, javaHome, postmanVersion) => {
50
- const dependencies = [
51
- `"io.gatling.highcharts:gatling-charts-highcharts:${versions_1.versions.gatling.core}"`,
52
- `"io.gatling:gatling-jvm-to-js-adapter:${versions_1.versions.gatling.jsAdapter}"`,
53
- `"io.gatling:gatling-enterprise-plugin-commons:${versions_1.versions.gatling.enterprisePluginCommons}"`,
54
- `"org.graalvm.polyglot:js-community:${versions_1.versions.graalvm.js}"`
55
- ];
56
- if (postmanVersion !== undefined) {
57
- dependencies.push(`"io.gatling:gatling-postman-jvm-to-js-adapter:${postmanVersion}"`);
58
- }
59
- return await resolveDependencies(coursierPath, javaHome, ...dependencies);
60
- };
61
- exports.resolveGatlingJsDependencies = resolveGatlingJsDependencies;
62
- const resolveRecorderDependencies = async (coursierPath, javaHome) => {
63
- const recorderDep = `io.gatling:gatling-recorder:${versions_1.versions.gatling.core}`;
64
- return await resolveDependencies(coursierPath, javaHome, recorderDep);
65
- };
66
- exports.resolveRecorderDependencies = resolveRecorderDependencies;
67
- const resolveDependencies = async (coursierPath, javaHome, ...dependencies) => {
68
- const command = `"${coursierPath}" fetch --classpath ${dependencies.join(" ")}`;
69
- // TODO could add a timeout
70
- log_1.logger.info(`Resolving dependencies with Coursier`);
71
- const { stdout } = await execAsync(command, { env: { ...process.env, JAVA_HOME: javaHome } });
72
- return stdout;
73
- };
74
- const execAsync = (0, util_1.promisify)(child_process_1.exec);
@@ -1 +0,0 @@
1
- export declare const installGraalVm: (gatlingHomeDir: string, downloadDir: string) => Promise<string>;
@@ -1,76 +0,0 @@
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.installGraalVm = void 0;
7
- const fs_1 = require("fs");
8
- const promises_1 = __importDefault(require("fs/promises"));
9
- const decompress_1 = __importDefault(require("decompress"));
10
- const download_1 = require("./download");
11
- const log_1 = require("../log");
12
- const os_1 = require("./os");
13
- const versions_1 = require("./versions");
14
- const installGraalVm = async (gatlingHomeDir, downloadDir) => {
15
- const { os, arch, extension, homePath, binPath } = graalVmPlatformParams();
16
- const graalvmRootPath = `${gatlingHomeDir}/graalvm/${versions_1.versions.graalvm.jdk}`;
17
- const graalvmHomePath = `${graalvmRootPath}${homePath}`;
18
- const graalvmJavaPath = `${graalvmHomePath}${binPath}`;
19
- if (!(0, fs_1.existsSync)(graalvmJavaPath)) {
20
- const url = `https://github.com/graalvm/graalvm-ce-builds/releases/download/jdk-${versions_1.versions.graalvm.jdk}/graalvm-community-jdk-${versions_1.versions.graalvm.jdk}_${os}-${arch}_bin.${extension}`;
21
- const downloadPath = `${downloadDir}/graalvm.${extension}`;
22
- if ((0, fs_1.existsSync)(graalvmRootPath)) {
23
- await promises_1.default.rm(graalvmRootPath, { recursive: true });
24
- }
25
- if ((0, fs_1.existsSync)(downloadPath)) {
26
- await promises_1.default.rm(downloadPath);
27
- }
28
- await promises_1.default.mkdir(graalvmRootPath, { recursive: true });
29
- log_1.logger.info(`Downloading GraalVM Community Edition ${versions_1.versions.graalvm.jdk} to ${downloadPath}`);
30
- await (0, download_1.downloadFile)(url, downloadPath);
31
- log_1.logger.info(`Unpacking GraalVM to ${graalvmRootPath}`);
32
- await (0, decompress_1.default)(downloadPath, graalvmRootPath, {
33
- map: (file) => {
34
- // Remove first level of file name, because it already contains a root directory
35
- file.path = file.path.split("/").slice(1).join("/");
36
- return file;
37
- }
38
- });
39
- await promises_1.default.rm(downloadPath);
40
- }
41
- else {
42
- log_1.logger.info(`GraalVM Community Edition ${versions_1.versions.graalvm.jdk} already installed at ${graalvmRootPath}`);
43
- }
44
- return graalvmHomePath;
45
- };
46
- exports.installGraalVm = installGraalVm;
47
- const graalVmPlatformParams = () => {
48
- if (os_1.osType === "Linux") {
49
- const os = "linux";
50
- const extension = "tar.gz";
51
- const homePath = "";
52
- const binPath = "/bin/java";
53
- if (os_1.osArch === "x64") {
54
- return { os, arch: "x64", extension, homePath, binPath };
55
- }
56
- else if (os_1.osArch === "arm64") {
57
- return { os, arch: "aarch64", extension, homePath, binPath };
58
- }
59
- }
60
- else if (os_1.osType === "Darwin") {
61
- const os = "macos";
62
- const extension = "tar.gz";
63
- const homePath = "/Contents/Home";
64
- const binPath = "/bin/java";
65
- if (os_1.osArch === "x64") {
66
- return { os, arch: "x64", extension, homePath, binPath };
67
- }
68
- else if (os_1.osArch === "arm64") {
69
- return { os, arch: "aarch64", extension, homePath, binPath };
70
- }
71
- }
72
- else if (os_1.osType === "Windows_NT" && os_1.osArch === "x64") {
73
- return { os: "windows", arch: "x64", extension: "zip", homePath: "", binPath: "/bin/java.exe" };
74
- }
75
- throw Error(`Operating system type '${os_1.osType}' with architecture '${os_1.osArch}' is not currently supported.`);
76
- };