@gatling.io/cli 3.11.6 → 3.12.0
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 +5 -5
- package/src/bundle.ts +36 -0
- package/src/commands/build.ts +30 -0
- package/src/commands/enterpriseDeploy.ts +88 -0
- package/src/commands/enterprisePackage.ts +41 -0
- package/src/commands/enterpriseStart.ts +113 -0
- package/src/commands/index.ts +25 -0
- package/src/commands/install.ts +19 -0
- package/src/commands/options.ts +263 -0
- package/src/commands/recorder.ts +41 -0
- package/src/commands/run.ts +78 -0
- package/src/commands/runOnly.ts +56 -0
- package/src/dependencies/coursier.ts +82 -0
- package/src/dependencies/download.ts +11 -0
- package/src/dependencies/graalVm.ts +74 -0
- package/src/dependencies/index.ts +44 -0
- package/src/dependencies/os.ts +24 -0
- package/src/dependencies/versions.ts +12 -0
- package/src/enterprise.ts +225 -0
- package/src/index.ts +5 -0
- package/src/java.ts +48 -0
- package/src/log.ts +19 -0
- package/src/readline.ts +39 -0
- package/src/run.ts +67 -0
- package/src/simulations.ts +29 -0
- package/target/commands/build.d.ts +3 -0
- package/target/commands/build.js +20 -0
- package/target/commands/enterpriseDeploy.d.ts +3 -0
- package/target/commands/enterpriseDeploy.js +59 -0
- package/target/commands/enterprisePackage.d.ts +3 -0
- package/target/commands/enterprisePackage.js +26 -0
- package/target/commands/enterpriseStart.d.ts +3 -0
- package/target/commands/enterpriseStart.js +75 -0
- package/target/commands/index.d.ts +2 -0
- package/target/commands/index.js +28 -0
- package/target/commands/install.d.ts +3 -0
- package/target/commands/install.js +18 -0
- package/target/commands/options.d.ts +46 -0
- package/target/commands/options.js +169 -0
- package/target/commands/recorder.d.ts +3 -0
- package/target/commands/recorder.js +28 -0
- package/target/commands/run.d.ts +3 -0
- package/target/commands/run.js +51 -0
- package/target/commands/runOnly.d.ts +3 -0
- package/target/commands/runOnly.js +37 -0
- package/target/dependencies/index.d.ts +1 -0
- package/target/dependencies/index.js +3 -1
- package/target/dependencies/versions.js +2 -2
- package/target/enterprise.js +5 -5
- package/target/index.js +2 -337
- package/target/run.d.ts +1 -1
- package/target/run.js +5 -3
- package/tsconfig.json +18 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gatling.io/cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.12.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"bin": {
|
|
6
6
|
"gatling": "target/index.js"
|
|
@@ -9,21 +9,21 @@
|
|
|
9
9
|
"types": "target/index.d.ts",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"archiver": "7.0.1",
|
|
12
|
-
"axios": "1.7.
|
|
12
|
+
"axios": "1.7.7",
|
|
13
13
|
"commander": "12.1.0",
|
|
14
14
|
"decompress": "4.2.1",
|
|
15
|
-
"esbuild": "0.23.
|
|
15
|
+
"esbuild": "0.23.1",
|
|
16
16
|
"esbuild-plugin-tsc": "0.4.0",
|
|
17
17
|
"readline-sync": "1.4.10"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
20
|
"@types/archiver": "6.0.2",
|
|
21
21
|
"@types/decompress": "4.2.7",
|
|
22
|
-
"@types/node": "
|
|
22
|
+
"@types/node": "18.19.50",
|
|
23
23
|
"@types/readline-sync": "1.4.8",
|
|
24
24
|
"prettier": "3.3.3",
|
|
25
25
|
"rimraf": "6.0.1",
|
|
26
|
-
"typescript": "5.5.
|
|
26
|
+
"typescript": "5.5.4"
|
|
27
27
|
},
|
|
28
28
|
"scripts": {
|
|
29
29
|
"clean": "rimraf target",
|
package/src/bundle.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as esbuild from "esbuild";
|
|
2
|
+
import esbuildPluginTsc from "esbuild-plugin-tsc";
|
|
3
|
+
|
|
4
|
+
import { SimulationFile } from "./simulations";
|
|
5
|
+
import { logger } from "./log";
|
|
6
|
+
|
|
7
|
+
export interface BundleOptions {
|
|
8
|
+
sourcesFolder: string;
|
|
9
|
+
bundleFile: string;
|
|
10
|
+
typescript: boolean;
|
|
11
|
+
simulations: SimulationFile[];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const bundle = async (options: BundleOptions): Promise<void> => {
|
|
15
|
+
logger.info(`Bundling a Gatling simulation with options:
|
|
16
|
+
- sourcesFolder: ${options.sourcesFolder}
|
|
17
|
+
- bundleFile: ${options.bundleFile}
|
|
18
|
+
- typescript: ${options.typescript}`);
|
|
19
|
+
|
|
20
|
+
const contents = options.simulations.map((s) => `export { default as "${s.name}" } from "./${s.path}";`).join("\n");
|
|
21
|
+
|
|
22
|
+
const plugins = options.typescript ? [esbuildPluginTsc({ force: true })] : [];
|
|
23
|
+
await esbuild.build({
|
|
24
|
+
stdin: {
|
|
25
|
+
contents,
|
|
26
|
+
resolveDir: options.sourcesFolder
|
|
27
|
+
},
|
|
28
|
+
outfile: options.bundleFile,
|
|
29
|
+
bundle: true,
|
|
30
|
+
minify: false,
|
|
31
|
+
sourcemap: true,
|
|
32
|
+
format: "iife",
|
|
33
|
+
globalName: "gatling",
|
|
34
|
+
plugins
|
|
35
|
+
});
|
|
36
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
bundleFileOption,
|
|
5
|
+
bundleFileOptionValue,
|
|
6
|
+
sourcesFolderOption,
|
|
7
|
+
sourcesFolderOptionValue,
|
|
8
|
+
typescriptOption,
|
|
9
|
+
typescriptOptionValueWithDefaults
|
|
10
|
+
} from "./options";
|
|
11
|
+
import { findSimulations } from "../simulations";
|
|
12
|
+
import { bundle } from "../bundle";
|
|
13
|
+
|
|
14
|
+
export default (program: Command): void => {
|
|
15
|
+
program
|
|
16
|
+
.command("build")
|
|
17
|
+
.description("Build Gatling simulations")
|
|
18
|
+
.addOption(sourcesFolderOption)
|
|
19
|
+
.addOption(bundleFileOption)
|
|
20
|
+
.addOption(typescriptOption)
|
|
21
|
+
.action(async (options) => {
|
|
22
|
+
const sourcesFolder: string = sourcesFolderOptionValue(options);
|
|
23
|
+
const bundleFile = bundleFileOptionValue(options);
|
|
24
|
+
|
|
25
|
+
const simulations = await findSimulations(sourcesFolder);
|
|
26
|
+
const typescript = typescriptOptionValueWithDefaults(options, simulations);
|
|
27
|
+
|
|
28
|
+
await bundle({ sourcesFolder, bundleFile, typescript, simulations });
|
|
29
|
+
});
|
|
30
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
apiTokenOption,
|
|
5
|
+
apiTokenOptionValue,
|
|
6
|
+
bundleFileOption,
|
|
7
|
+
bundleFileOptionValue,
|
|
8
|
+
controlPlaneUrlOption,
|
|
9
|
+
controlPlaneUrlOptionValue,
|
|
10
|
+
gatlingHomeOption,
|
|
11
|
+
gatlingHomeOptionValueWithDefaults,
|
|
12
|
+
nonInteractiveOption,
|
|
13
|
+
nonInteractiveOptionValue,
|
|
14
|
+
packageDescriptorFilenameOption,
|
|
15
|
+
packageDescriptorFilenameOptionValue,
|
|
16
|
+
packageFileOption,
|
|
17
|
+
packageFileOptionValue,
|
|
18
|
+
resourcesFolderOption,
|
|
19
|
+
resourcesFolderOptionValue,
|
|
20
|
+
resultsFolderOption,
|
|
21
|
+
resultsFolderOptionValue,
|
|
22
|
+
sourcesFolderOption,
|
|
23
|
+
sourcesFolderOptionValue,
|
|
24
|
+
typescriptOption,
|
|
25
|
+
typescriptOptionValueWithDefaults,
|
|
26
|
+
urlOption,
|
|
27
|
+
urlOptionValue
|
|
28
|
+
} from "./options";
|
|
29
|
+
import { findSimulations } from "../simulations";
|
|
30
|
+
import { installGatlingJs } from "../dependencies";
|
|
31
|
+
import { bundle } from "../bundle";
|
|
32
|
+
import { enterpriseDeploy, enterprisePackage } from "../enterprise";
|
|
33
|
+
|
|
34
|
+
export default (program: Command): void => {
|
|
35
|
+
program
|
|
36
|
+
.command("enterprise-deploy")
|
|
37
|
+
.description("Deploy a package and configured simulations")
|
|
38
|
+
.addOption(sourcesFolderOption)
|
|
39
|
+
.addOption(resourcesFolderOption)
|
|
40
|
+
.addOption(bundleFileOption)
|
|
41
|
+
.addOption(resultsFolderOption)
|
|
42
|
+
.addOption(typescriptOption)
|
|
43
|
+
.addOption(gatlingHomeOption)
|
|
44
|
+
// Base
|
|
45
|
+
.addOption(urlOption)
|
|
46
|
+
.addOption(apiTokenOption)
|
|
47
|
+
// Plugin configuration
|
|
48
|
+
.addOption(controlPlaneUrlOption)
|
|
49
|
+
.addOption(nonInteractiveOption)
|
|
50
|
+
// Descriptor file
|
|
51
|
+
.addOption(packageDescriptorFilenameOption)
|
|
52
|
+
// Deployment info
|
|
53
|
+
.addOption(packageFileOption)
|
|
54
|
+
.action(async (options) => {
|
|
55
|
+
const sourcesFolder: string = sourcesFolderOptionValue(options);
|
|
56
|
+
|
|
57
|
+
const simulations = await findSimulations(sourcesFolder);
|
|
58
|
+
const typescript = typescriptOptionValueWithDefaults(options, simulations);
|
|
59
|
+
|
|
60
|
+
const resourcesFolder: string = resourcesFolderOptionValue(options);
|
|
61
|
+
const bundleFile = bundleFileOptionValue(options);
|
|
62
|
+
const resultsFolder: string = resultsFolderOptionValue(options);
|
|
63
|
+
const gatlingHome = gatlingHomeOptionValueWithDefaults(options);
|
|
64
|
+
const url = urlOptionValue(options);
|
|
65
|
+
const apiToken = apiTokenOptionValue(options);
|
|
66
|
+
const controlPlaneUrl = controlPlaneUrlOptionValue(options);
|
|
67
|
+
const nonInteractive = nonInteractiveOptionValue(options);
|
|
68
|
+
const packageDescriptorFilename = packageDescriptorFilenameOptionValue(options);
|
|
69
|
+
const packageFile = packageFileOptionValue(options);
|
|
70
|
+
|
|
71
|
+
const { graalvmHome, jvmClasspath } = await installGatlingJs({ gatlingHome });
|
|
72
|
+
await bundle({ sourcesFolder, bundleFile, typescript, simulations });
|
|
73
|
+
await enterprisePackage({ bundleFile, resourcesFolder, packageFile, simulations });
|
|
74
|
+
await enterpriseDeploy({
|
|
75
|
+
graalvmHome,
|
|
76
|
+
jvmClasspath,
|
|
77
|
+
bundleFile,
|
|
78
|
+
resourcesFolder,
|
|
79
|
+
resultsFolder,
|
|
80
|
+
url,
|
|
81
|
+
apiToken,
|
|
82
|
+
controlPlaneUrl,
|
|
83
|
+
nonInteractive,
|
|
84
|
+
packageDescriptorFilename,
|
|
85
|
+
packageFile
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
bundleFileOption,
|
|
5
|
+
bundleFileOptionValue,
|
|
6
|
+
packageFileOption,
|
|
7
|
+
packageFileOptionValue,
|
|
8
|
+
resourcesFolderOption,
|
|
9
|
+
resourcesFolderOptionValue,
|
|
10
|
+
sourcesFolderOption,
|
|
11
|
+
sourcesFolderOptionValue,
|
|
12
|
+
typescriptOption,
|
|
13
|
+
typescriptOptionValueWithDefaults
|
|
14
|
+
} from "./options";
|
|
15
|
+
import { findSimulations } from "../simulations";
|
|
16
|
+
import { bundle } from "../bundle";
|
|
17
|
+
import { enterprisePackage } from "../enterprise";
|
|
18
|
+
|
|
19
|
+
export default (program: Command): void => {
|
|
20
|
+
program
|
|
21
|
+
.command("enterprise-package")
|
|
22
|
+
.description("Build Gatling simulations and package them for Gatling Enterprise")
|
|
23
|
+
.addOption(sourcesFolderOption)
|
|
24
|
+
.addOption(resourcesFolderOption)
|
|
25
|
+
.addOption(bundleFileOption)
|
|
26
|
+
.addOption(packageFileOption)
|
|
27
|
+
.addOption(typescriptOption)
|
|
28
|
+
.action(async (options) => {
|
|
29
|
+
const sourcesFolder: string = sourcesFolderOptionValue(options);
|
|
30
|
+
const resourcesFolder: string = resourcesFolderOptionValue(options);
|
|
31
|
+
const bundleFile = bundleFileOptionValue(options);
|
|
32
|
+
const packageFile = packageFileOptionValue(options);
|
|
33
|
+
|
|
34
|
+
const simulations = await findSimulations(sourcesFolder);
|
|
35
|
+
const typescript = typescriptOptionValueWithDefaults(options, simulations);
|
|
36
|
+
|
|
37
|
+
await bundle({ sourcesFolder, bundleFile, typescript, simulations });
|
|
38
|
+
|
|
39
|
+
await enterprisePackage({ bundleFile, resourcesFolder, packageFile, simulations });
|
|
40
|
+
});
|
|
41
|
+
};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
apiTokenOption,
|
|
5
|
+
apiTokenOptionValue,
|
|
6
|
+
bundleFileOption,
|
|
7
|
+
bundleFileOptionValue,
|
|
8
|
+
controlPlaneUrlOption,
|
|
9
|
+
controlPlaneUrlOptionValue,
|
|
10
|
+
enterpriseSimulationOption,
|
|
11
|
+
enterpriseSimulationOptionValue,
|
|
12
|
+
gatlingHomeOption,
|
|
13
|
+
gatlingHomeOptionValueWithDefaults,
|
|
14
|
+
nonInteractiveOption,
|
|
15
|
+
nonInteractiveOptionValue,
|
|
16
|
+
packageDescriptorFilenameOption,
|
|
17
|
+
packageDescriptorFilenameOptionValue,
|
|
18
|
+
packageFileOption,
|
|
19
|
+
packageFileOptionValue,
|
|
20
|
+
resourcesFolderOption,
|
|
21
|
+
resourcesFolderOptionValue,
|
|
22
|
+
resultsFolderOption,
|
|
23
|
+
resultsFolderOptionValue,
|
|
24
|
+
runDescriptionOption,
|
|
25
|
+
runDescriptionOptionValue,
|
|
26
|
+
runTitleOption,
|
|
27
|
+
runTitleOptionValue,
|
|
28
|
+
sourcesFolderOption,
|
|
29
|
+
sourcesFolderOptionValue,
|
|
30
|
+
typescriptOption,
|
|
31
|
+
typescriptOptionValueWithDefaults,
|
|
32
|
+
urlOption,
|
|
33
|
+
urlOptionValue,
|
|
34
|
+
waitForRunEndOption,
|
|
35
|
+
waitForRunEndOptionValue
|
|
36
|
+
} from "./options";
|
|
37
|
+
import { findSimulations } from "../simulations";
|
|
38
|
+
import { installGatlingJs } from "../dependencies";
|
|
39
|
+
import { bundle } from "../bundle";
|
|
40
|
+
import { enterprisePackage, enterpriseStart } from "../enterprise";
|
|
41
|
+
|
|
42
|
+
export default (program: Command): void => {
|
|
43
|
+
program
|
|
44
|
+
.command("enterprise-start")
|
|
45
|
+
.description("Start a simulation deployed with `enterprise-deploy`")
|
|
46
|
+
.addOption(sourcesFolderOption)
|
|
47
|
+
.addOption(resourcesFolderOption)
|
|
48
|
+
.addOption(bundleFileOption)
|
|
49
|
+
.addOption(resultsFolderOption)
|
|
50
|
+
.addOption(typescriptOption)
|
|
51
|
+
.addOption(gatlingHomeOption)
|
|
52
|
+
// Base
|
|
53
|
+
.addOption(urlOption)
|
|
54
|
+
.addOption(apiTokenOption)
|
|
55
|
+
// Plugin configuration
|
|
56
|
+
.addOption(controlPlaneUrlOption)
|
|
57
|
+
.addOption(nonInteractiveOption)
|
|
58
|
+
// Descriptor file
|
|
59
|
+
.addOption(packageDescriptorFilenameOption)
|
|
60
|
+
// Deployment info
|
|
61
|
+
.addOption(packageFileOption)
|
|
62
|
+
// Start
|
|
63
|
+
.addOption(enterpriseSimulationOption)
|
|
64
|
+
.addOption(runTitleOption)
|
|
65
|
+
.addOption(runDescriptionOption)
|
|
66
|
+
.addOption(waitForRunEndOption)
|
|
67
|
+
.action(async (options) => {
|
|
68
|
+
const sourcesFolder: string = sourcesFolderOptionValue(options);
|
|
69
|
+
|
|
70
|
+
const simulations = await findSimulations(sourcesFolder);
|
|
71
|
+
const typescript = typescriptOptionValueWithDefaults(options, simulations);
|
|
72
|
+
|
|
73
|
+
const resourcesFolder: string = resourcesFolderOptionValue(options);
|
|
74
|
+
const bundleFile = bundleFileOptionValue(options);
|
|
75
|
+
const resultsFolder: string = resultsFolderOptionValue(options);
|
|
76
|
+
const gatlingHome = gatlingHomeOptionValueWithDefaults(options);
|
|
77
|
+
const url = urlOptionValue(options);
|
|
78
|
+
const apiToken = apiTokenOptionValue(options);
|
|
79
|
+
const controlPlaneUrl = controlPlaneUrlOptionValue(options);
|
|
80
|
+
const nonInteractive = nonInteractiveOptionValue(options);
|
|
81
|
+
const packageDescriptorFilename = packageDescriptorFilenameOptionValue(options);
|
|
82
|
+
const packageFile = packageFileOptionValue(options);
|
|
83
|
+
const enterpriseSimulation = enterpriseSimulationOptionValue(options);
|
|
84
|
+
const runTitle = runTitleOptionValue(options);
|
|
85
|
+
const runDescription = runDescriptionOptionValue(options);
|
|
86
|
+
const waitForRunEnd = waitForRunEndOptionValue(options);
|
|
87
|
+
|
|
88
|
+
if (nonInteractiveOptionValue(options) && enterpriseSimulation === undefined) {
|
|
89
|
+
throw new Error(`No simulation specified when using non-interactive mode`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const { graalvmHome, jvmClasspath } = await installGatlingJs({ gatlingHome });
|
|
93
|
+
await bundle({ sourcesFolder, bundleFile, typescript, simulations });
|
|
94
|
+
await enterprisePackage({ bundleFile, resourcesFolder, packageFile, simulations });
|
|
95
|
+
await enterpriseStart({
|
|
96
|
+
graalvmHome,
|
|
97
|
+
jvmClasspath,
|
|
98
|
+
bundleFile,
|
|
99
|
+
resourcesFolder,
|
|
100
|
+
resultsFolder,
|
|
101
|
+
url,
|
|
102
|
+
apiToken,
|
|
103
|
+
controlPlaneUrl,
|
|
104
|
+
nonInteractive,
|
|
105
|
+
packageDescriptorFilename,
|
|
106
|
+
packageFile,
|
|
107
|
+
enterpriseSimulation,
|
|
108
|
+
runTitle,
|
|
109
|
+
runDescription,
|
|
110
|
+
waitForRunEnd
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
|
|
3
|
+
import registerInstallCommand from "./install";
|
|
4
|
+
import registerBuildCommand from "./build";
|
|
5
|
+
import registerRunOnlyCommand from "./runOnly";
|
|
6
|
+
import registerRunCommand from "./run";
|
|
7
|
+
import registerRecorderCommand from "./recorder";
|
|
8
|
+
import registerEnterprisePackageCommand from "./enterprisePackage";
|
|
9
|
+
import registerEnterpriseDeployCommand from "./enterpriseDeploy";
|
|
10
|
+
import registerEnterpriseStartCommand from "./enterpriseStart";
|
|
11
|
+
import { versions } from "../dependencies";
|
|
12
|
+
|
|
13
|
+
export const program: Command = new Command()
|
|
14
|
+
.name("gatling-js-cli")
|
|
15
|
+
.version(versions.gatling.jsAdapter)
|
|
16
|
+
.description("The Gatling Javascript run & packaging tool");
|
|
17
|
+
|
|
18
|
+
registerInstallCommand(program);
|
|
19
|
+
registerBuildCommand(program);
|
|
20
|
+
registerRunOnlyCommand(program);
|
|
21
|
+
registerRunCommand(program);
|
|
22
|
+
registerRecorderCommand(program);
|
|
23
|
+
registerEnterprisePackageCommand(program);
|
|
24
|
+
registerEnterpriseDeployCommand(program);
|
|
25
|
+
registerEnterpriseStartCommand(program);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
|
|
3
|
+
import { gatlingHomeOption, gatlingHomeOptionValueWithDefaults } from "./options";
|
|
4
|
+
import { installGatlingJs } from "../dependencies";
|
|
5
|
+
import { logger } from "../log";
|
|
6
|
+
|
|
7
|
+
export default (program: Command): void => {
|
|
8
|
+
program
|
|
9
|
+
.command("install")
|
|
10
|
+
.description("Install all required components and dependencies for Gatling")
|
|
11
|
+
.addOption(gatlingHomeOption)
|
|
12
|
+
.action(async (options) => {
|
|
13
|
+
const gatlingHome = gatlingHomeOptionValueWithDefaults(options);
|
|
14
|
+
const { graalvmHome, coursierBinary, jvmClasspath } = await installGatlingJs({ gatlingHome });
|
|
15
|
+
logger.info(`graalvmHome=${graalvmHome}`);
|
|
16
|
+
logger.info(`coursierBinary=${coursierBinary}`);
|
|
17
|
+
logger.info(`jvmClasspath=${jvmClasspath}`);
|
|
18
|
+
});
|
|
19
|
+
};
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { Option, Argument } from "commander";
|
|
2
|
+
import os from "os";
|
|
3
|
+
|
|
4
|
+
import { SimulationFile } from "../simulations";
|
|
5
|
+
import { keyInSelectPaginated } from "../readline";
|
|
6
|
+
import { logger } from "../log";
|
|
7
|
+
|
|
8
|
+
const getStringValueOptional =
|
|
9
|
+
(option: Option) =>
|
|
10
|
+
(options: any): string | undefined => {
|
|
11
|
+
const value = options[option.attributeName()];
|
|
12
|
+
if (typeof value === "string" || typeof value === "undefined") {
|
|
13
|
+
return value;
|
|
14
|
+
} else {
|
|
15
|
+
throw Error(
|
|
16
|
+
`Expected type string|undefined for attribute ${option.attributeName()}, got ${typeof value} - please report this as a bug.`
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
const getStringValueMandatory =
|
|
21
|
+
(option: Option) =>
|
|
22
|
+
(options: any): string => {
|
|
23
|
+
const value = options[option.attributeName()];
|
|
24
|
+
if (typeof value === "string") {
|
|
25
|
+
return value;
|
|
26
|
+
} else {
|
|
27
|
+
throw Error(
|
|
28
|
+
`Expected type string for attribute ${option.attributeName()}, got ${typeof value} - please report this as a bug.`
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const getBooleanValueOptional =
|
|
33
|
+
(option: Option) =>
|
|
34
|
+
(options: any): boolean | undefined => {
|
|
35
|
+
const value = options[option.attributeName()];
|
|
36
|
+
if (typeof value === "boolean" || typeof value === "undefined") {
|
|
37
|
+
return value;
|
|
38
|
+
} else {
|
|
39
|
+
throw Error(
|
|
40
|
+
`Expected type boolean|undefined for attribute ${option.attributeName()}, got ${typeof value} - please report this as a bug.`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
const getBooleanValueMandatory =
|
|
45
|
+
(option: Option) =>
|
|
46
|
+
(options: any): boolean => {
|
|
47
|
+
const value = options[option.attributeName()];
|
|
48
|
+
if (typeof value === "boolean") {
|
|
49
|
+
return value;
|
|
50
|
+
} else {
|
|
51
|
+
throw Error(
|
|
52
|
+
`Expected type boolean for attribute ${option.attributeName()}, got ${typeof value} - please report this as a bug.`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
const getNumberValueOptional =
|
|
57
|
+
(option: Option) =>
|
|
58
|
+
(options: any): number | undefined => {
|
|
59
|
+
const value = options[option.attributeName()];
|
|
60
|
+
if (typeof value === "number" || typeof value === "undefined") {
|
|
61
|
+
return value;
|
|
62
|
+
} else {
|
|
63
|
+
throw Error(
|
|
64
|
+
`Expected type number|undefined for attribute ${option.attributeName()}, got ${typeof value} - please report this as a bug.`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const gatlingHomeOption = new Option(
|
|
70
|
+
"--gatling-home <value>",
|
|
71
|
+
'The folder used to download and install Gatling components (default: "~/.gatling")'
|
|
72
|
+
);
|
|
73
|
+
export const gatlingHomeOptionValueWithDefaults = (options: any): string =>
|
|
74
|
+
getStringValueOptional(gatlingHomeOption)(options) || `${os.homedir()}/.gatling`;
|
|
75
|
+
|
|
76
|
+
export const sourcesFolderOption = new Option("--sources-folder <value>", "The sources folder path").default("src");
|
|
77
|
+
export const sourcesFolderOptionValue = getStringValueMandatory(sourcesFolderOption);
|
|
78
|
+
|
|
79
|
+
export const simulationOption = new Option(
|
|
80
|
+
"--simulation <value>",
|
|
81
|
+
"The simulation entry point function name (default: if only one *.gatling.js or *.gatling.ts file is found, will execute that simulation)"
|
|
82
|
+
);
|
|
83
|
+
export const simulationOptionValueWithDefaults = (
|
|
84
|
+
options: any,
|
|
85
|
+
simulationsFound: SimulationFile[],
|
|
86
|
+
interactive: boolean
|
|
87
|
+
): string => {
|
|
88
|
+
const declaredSimulation = getStringValueOptional(simulationOption)(options);
|
|
89
|
+
if (declaredSimulation !== undefined) {
|
|
90
|
+
return declaredSimulation;
|
|
91
|
+
} else if (simulationsFound.length === 1) {
|
|
92
|
+
return simulationsFound[0].name;
|
|
93
|
+
} else if (simulationsFound.length === 0) {
|
|
94
|
+
throw new Error(
|
|
95
|
+
"No simulation found, simulations must be defined in a <simulation name>.gatling.js or <simulation name>.gatling.ts file)"
|
|
96
|
+
);
|
|
97
|
+
} else if (interactive) {
|
|
98
|
+
const idx = keyInSelectPaginated(
|
|
99
|
+
simulationsFound.map((s) => s.name).sort((a, b) => a.localeCompare(b)),
|
|
100
|
+
"Choose a simulation to run"
|
|
101
|
+
);
|
|
102
|
+
if (idx >= 0) {
|
|
103
|
+
const simulation = simulationsFound[idx].name;
|
|
104
|
+
logger.info(`Simulation '${simulation}' was chosen.`);
|
|
105
|
+
return simulation;
|
|
106
|
+
} else {
|
|
107
|
+
throw new Error("Simulation choice was cancelled.");
|
|
108
|
+
}
|
|
109
|
+
} else {
|
|
110
|
+
throw new Error(
|
|
111
|
+
`Several simulations found, specify one using the --simulation option (available simulations: ${simulationsFound.map((s) => s.name)})`
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
export const simulationMandatoryOption = new Option(
|
|
117
|
+
"--simulation <value>",
|
|
118
|
+
"The simulation entry point function name"
|
|
119
|
+
).makeOptionMandatory(true);
|
|
120
|
+
export const simulationMandatoryOptionValue = getStringValueMandatory(simulationMandatoryOption);
|
|
121
|
+
|
|
122
|
+
export const bundleFileOption = new Option(
|
|
123
|
+
"--bundle-file <value>",
|
|
124
|
+
"The target bundle file path when building simulations (must have a .js extension)"
|
|
125
|
+
)
|
|
126
|
+
.default("target/bundle.js")
|
|
127
|
+
.argParser((value) => {
|
|
128
|
+
if (!value.endsWith(".js")) {
|
|
129
|
+
throw Error(`'${value}' is not a valid bundle file path: should have a .js extension`);
|
|
130
|
+
}
|
|
131
|
+
return value;
|
|
132
|
+
});
|
|
133
|
+
export const bundleFileOptionValue = getStringValueMandatory(bundleFileOption);
|
|
134
|
+
|
|
135
|
+
export const packageFileOption = new Option(
|
|
136
|
+
"--package-file <value>",
|
|
137
|
+
"The target package file path when packaging simulations for Gatling Enterprise (must have a .zip extension)"
|
|
138
|
+
)
|
|
139
|
+
.default("target/package.zip")
|
|
140
|
+
.argParser((value) => {
|
|
141
|
+
if (!value.endsWith(".zip")) {
|
|
142
|
+
throw Error(`'${value}' is not a valid package file path: should have a .zip extension`);
|
|
143
|
+
}
|
|
144
|
+
return value;
|
|
145
|
+
});
|
|
146
|
+
export const packageFileOptionValue = getStringValueMandatory(packageFileOption);
|
|
147
|
+
|
|
148
|
+
export const resourcesFolderOption = new Option("--resources-folder <value>", "The resources folder path").default(
|
|
149
|
+
"resources"
|
|
150
|
+
);
|
|
151
|
+
export const resourcesFolderOptionValue = getStringValueMandatory(resourcesFolderOption);
|
|
152
|
+
|
|
153
|
+
export const resultsFolderOption = new Option("--results-folder <value>", "The results folder path").default(
|
|
154
|
+
"target/gatling"
|
|
155
|
+
);
|
|
156
|
+
export const resultsFolderOptionValue = getStringValueMandatory(resultsFolderOption);
|
|
157
|
+
|
|
158
|
+
export const typescriptOption = new Option(
|
|
159
|
+
"--typescript",
|
|
160
|
+
"Use the typescript compiler to compile your code (default: true if the sourcesFolder contains any *.gatling.ts file, false otherwise)"
|
|
161
|
+
);
|
|
162
|
+
export const typescriptOptionValueWithDefaults = (options: any, simulationsFound: SimulationFile[]): boolean => {
|
|
163
|
+
const value = getBooleanValueOptional(typescriptOption)(options);
|
|
164
|
+
return value !== undefined ? value : simulationsFound.findIndex((s) => s.type === "typescript") >= 0;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
export const graalvmHomeMandatoryOption = new Option(
|
|
168
|
+
"--graalvm-home <value>",
|
|
169
|
+
"Path to the GraalVM home"
|
|
170
|
+
).makeOptionMandatory(true);
|
|
171
|
+
export const graalvmHomeMandatoryOptionValue = getStringValueMandatory(graalvmHomeMandatoryOption);
|
|
172
|
+
|
|
173
|
+
export const jvmClasspathMandatoryOption = new Option(
|
|
174
|
+
"--jvm-classpath <value>",
|
|
175
|
+
"The classpath containing all Gatling JVM components"
|
|
176
|
+
).makeOptionMandatory(true);
|
|
177
|
+
export const jvmClasspathMandatoryOptionValue = getStringValueMandatory(jvmClasspathMandatoryOption);
|
|
178
|
+
|
|
179
|
+
export const memoryOption = new Option(
|
|
180
|
+
"--memory <value>",
|
|
181
|
+
"Heap space memory size in MiB for Gatling. Half the total available memory is usually a good default, as the Gatling process will use more memory than just the heap space."
|
|
182
|
+
).argParser((value) => {
|
|
183
|
+
const parsedValue = parseInt(value, 10);
|
|
184
|
+
if (isNaN(parsedValue)) {
|
|
185
|
+
throw new Error(`${value} is not a valid memory size, must be an integer number`);
|
|
186
|
+
}
|
|
187
|
+
return parsedValue;
|
|
188
|
+
});
|
|
189
|
+
export const memoryOptionValue = getNumberValueOptional(memoryOption);
|
|
190
|
+
|
|
191
|
+
export const nonInteractiveOption = new Option(
|
|
192
|
+
"--non-interactive",
|
|
193
|
+
"Switch to non-interactive mode and fail if no simulation is explicitly specified"
|
|
194
|
+
).default(false);
|
|
195
|
+
export const nonInteractiveOptionValue = getBooleanValueMandatory(nonInteractiveOption);
|
|
196
|
+
|
|
197
|
+
export const runParametersArgument = new Argument(
|
|
198
|
+
"[optionKey=optionValue...]",
|
|
199
|
+
"Specify one or more parameter which can be read in the simulation script with the getParameter() function; format must be key=value"
|
|
200
|
+
);
|
|
201
|
+
export const parseRunParametersArgument = (args: string[]): Record<string, string> => {
|
|
202
|
+
const parsedParameters: Record<string, string> = {};
|
|
203
|
+
for (const arg of args) {
|
|
204
|
+
const i = arg.indexOf("=");
|
|
205
|
+
if (i < 0) {
|
|
206
|
+
throw Error(`Parameter '${arg}' is not valid: format should be key=value`);
|
|
207
|
+
} else {
|
|
208
|
+
const key = arg.slice(0, i).trim();
|
|
209
|
+
parsedParameters[key] = arg.slice(i + 1);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return parsedParameters;
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
export const urlOption = new Option("--url <value>", "URL of Gatling Enterprise")
|
|
216
|
+
.default("https://cloud.gatling.io")
|
|
217
|
+
.hideHelp();
|
|
218
|
+
export const urlOptionValue = getStringValueMandatory(urlOption);
|
|
219
|
+
|
|
220
|
+
export const apiTokenOption = new Option(
|
|
221
|
+
"--api-token <value>",
|
|
222
|
+
"API Token on Gatling Enterprise. Prefer configuration using `GATLING_ENTERPRISE_API_TOKEN` environment variable."
|
|
223
|
+
);
|
|
224
|
+
export const apiTokenOptionValue = getStringValueOptional(apiTokenOption);
|
|
225
|
+
|
|
226
|
+
// Plugin configuration
|
|
227
|
+
|
|
228
|
+
export const controlPlaneUrlOption = new Option(
|
|
229
|
+
"--control-plane-url <value>",
|
|
230
|
+
"URL of a control plane for Gatling Enterprise providing a private repository. If this parameter is provided, packages will be registered as private packages and uploaded through this private control plane."
|
|
231
|
+
);
|
|
232
|
+
export const controlPlaneUrlOptionValue = getStringValueOptional(controlPlaneUrlOption);
|
|
233
|
+
|
|
234
|
+
// Descriptor file
|
|
235
|
+
|
|
236
|
+
export const packageDescriptorFilenameOption = new Option(
|
|
237
|
+
"--package-descriptor-filename <value>",
|
|
238
|
+
"Path to a package descriptor inside the .gatling folder"
|
|
239
|
+
).default("package.conf");
|
|
240
|
+
export const packageDescriptorFilenameOptionValue = getStringValueMandatory(packageDescriptorFilenameOption);
|
|
241
|
+
|
|
242
|
+
// Deployment info
|
|
243
|
+
|
|
244
|
+
export const enterpriseSimulationOption = new Option(
|
|
245
|
+
"--enterprise-simulation <value>",
|
|
246
|
+
"Specify the simulation name directly to bypass the prompt using the following command."
|
|
247
|
+
);
|
|
248
|
+
export const enterpriseSimulationOptionValue = getStringValueOptional(enterpriseSimulationOption);
|
|
249
|
+
|
|
250
|
+
export const runTitleOption = new Option("--run-title <value>", "Allows setting a title for your run reports.");
|
|
251
|
+
export const runTitleOptionValue = getStringValueOptional(runTitleOption);
|
|
252
|
+
|
|
253
|
+
export const runDescriptionOption = new Option(
|
|
254
|
+
"--run-description <value>",
|
|
255
|
+
"Allows setting a description for your run reports summary."
|
|
256
|
+
);
|
|
257
|
+
export const runDescriptionOptionValue = getStringValueOptional(runDescriptionOption);
|
|
258
|
+
|
|
259
|
+
export const waitForRunEndOption = new Option(
|
|
260
|
+
"--wait-for-run-end",
|
|
261
|
+
"Wait for the result after starting the simulation on Gatling Enterprise, and complete with an error if the simulation ends with any error status"
|
|
262
|
+
).default(false);
|
|
263
|
+
export const waitForRunEndOptionValue = getBooleanValueMandatory(waitForRunEndOption);
|