Skip to content

Commit 2f830ed

Browse files
committed
feat: Add ability to use a config file for the CLI tool
1 parent cbd5960 commit 2f830ed

16 files changed

+668
-637
lines changed

js-simulation/package-lock.json

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

js/cli/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"commander": "13.1.0",
3030
"esbuild": "0.25.0",
3131
"esbuild-plugin-tsc": "0.5.0",
32+
"idonttrustlikethat": "2.1.2",
3233
"import-meta-resolve": "4.1.0",
3334
"make-fetch-happen": "14.0.3",
3435
"readline-sync": "1.4.10"

js/cli/src/commands/build.ts

+10-19
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,24 @@
11
import { Command } from "commander";
22

3-
import {
4-
bundleFileOption,
5-
bundleFileOptionValue,
6-
postmanOption,
7-
postmanOptionValueWithDefaults,
8-
sourcesFolderOption,
9-
sourcesFolderOptionValue,
10-
typescriptOption,
11-
typescriptOptionValueWithDefaults
12-
} from "./options";
3+
import { ResolvedOptions } from "./resolveOptions";
134
import { findSimulations } from "../simulations";
145
import { bundle } from "../bundle";
156

16-
export default (program: Command): void => {
7+
export default (opts: ResolvedOptions, program: Command): void => {
178
program
189
.command("build")
1910
.description("Build Gatling simulations")
20-
.addOption(sourcesFolderOption)
21-
.addOption(bundleFileOption)
22-
.addOption(postmanOption)
23-
.addOption(typescriptOption)
11+
.addOption(opts.sourcesFolderOption)
12+
.addOption(opts.bundleFileOption)
13+
.addOption(opts.postmanOption)
14+
.addOption(opts.typescriptOption)
2415
.action(async (options) => {
25-
const sourcesFolder: string = sourcesFolderOptionValue(options);
26-
const bundleFile = bundleFileOptionValue(options);
16+
const sourcesFolder = opts.sourcesFolderOptionValue(options);
17+
const bundleFile = opts.bundleFileOptionValue(options);
2718

2819
const simulations = await findSimulations(sourcesFolder);
29-
const postman = postmanOptionValueWithDefaults(options);
30-
const typescript = typescriptOptionValueWithDefaults(options, simulations);
20+
const postman = opts.postmanOptionValueWithDefaults(options);
21+
const typescript = opts.typescriptOptionValueWithDefaults(options, simulations);
3122

3223
await bundle({ sourcesFolder, bundleFile, postman, typescript, simulations });
3324
});

js/cli/src/commands/configFile.ts

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import fs from "node:fs";
2+
3+
import { dictionary, errorDebugString, number, object, string } from "idonttrustlikethat";
4+
5+
export const readConfigFile = (): ConfigFile => {
6+
const path = ".gatling/cli.json";
7+
const content = fs.existsSync(path) ? fs.readFileSync(path, { encoding: "utf-8" }) : "{}";
8+
const validated = configFileValidation.validate(JSON.parse(content));
9+
if (validated.ok) {
10+
return validated.value;
11+
} else {
12+
throw Error(`Gatling CLI configuration file is not valid.
13+
${errorDebugString(validated.errors)}`);
14+
}
15+
};
16+
17+
export type ConfigFile = typeof configFileValidation.T;
18+
19+
const configFileValidation = object({
20+
// --gatling-home <value>
21+
gatlingHome: string.optional(),
22+
// --sources-folder <value>
23+
sourcesFolder: string.optional(),
24+
// --resources-folder <value>
25+
resourcesFolder: string.optional(),
26+
// --results-folder <value>
27+
resultsFolder: string.optional(),
28+
// --bundle-file <value>
29+
bundleFile: string.optional(),
30+
// --package-file <value>
31+
packageFile: string.optional(),
32+
// --memory <value>
33+
memory: number.optional(),
34+
// args [optionKey=optionValue...]
35+
runParameters: dictionary(string, string).default({}),
36+
// --control-plane-url <value>
37+
controlPlaneUrl: string.optional(),
38+
// --package-descriptor-filename <value>
39+
packageDescriptorFilename: string.optional()
40+
});

js/cli/src/commands/enterpriseDeploy.ts

+34-67
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,55 @@
11
import { Command } from "commander";
22

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-
postmanOption,
19-
postmanOptionValueWithDefaults,
20-
resourcesFolderOption,
21-
resourcesFolderOptionValue,
22-
resultsFolderOption,
23-
resultsFolderOptionValue,
24-
sourcesFolderOption,
25-
sourcesFolderOptionValue,
26-
trustStoreOption,
27-
trustStoreOptionValue,
28-
trustStorePasswordOption,
29-
trustStorePasswordOptionValue,
30-
typescriptOption,
31-
typescriptOptionValueWithDefaults,
32-
apiUrlOption,
33-
apiUrlOptionValue,
34-
webAppUrlOption,
35-
webAppUrlOptionValue
36-
} from "./options";
3+
import { ResolvedOptions } from "./resolveOptions";
374
import { findSimulations } from "../simulations";
385
import { resolveBundle } from "../dependencies";
396
import { bundle } from "../bundle";
407
import { enterpriseDeploy, enterprisePackage } from "../enterprise";
418

42-
export default (program: Command): void => {
9+
export default (opts: ResolvedOptions, program: Command): void => {
4310
program
4411
.command("enterprise-deploy")
4512
.description("Deploy a package and configured simulations")
46-
.addOption(sourcesFolderOption)
47-
.addOption(resourcesFolderOption)
48-
.addOption(bundleFileOption)
49-
.addOption(resultsFolderOption)
50-
.addOption(postmanOption)
51-
.addOption(typescriptOption)
52-
.addOption(gatlingHomeOption)
13+
.addOption(opts.sourcesFolderOption)
14+
.addOption(opts.resourcesFolderOption)
15+
.addOption(opts.bundleFileOption)
16+
.addOption(opts.resultsFolderOption)
17+
.addOption(opts.postmanOption)
18+
.addOption(opts.typescriptOption)
19+
.addOption(opts.gatlingHomeOption)
5320
// Base
54-
.addOption(apiUrlOption)
55-
.addOption(webAppUrlOption)
56-
.addOption(apiTokenOption)
21+
.addOption(opts.apiUrlOption)
22+
.addOption(opts.webAppUrlOption)
23+
.addOption(opts.apiTokenOption)
5724
// Plugin configuration
58-
.addOption(controlPlaneUrlOption)
59-
.addOption(trustStoreOption)
60-
.addOption(trustStorePasswordOption)
61-
.addOption(nonInteractiveOption)
25+
.addOption(opts.controlPlaneUrlOption)
26+
.addOption(opts.trustStoreOption)
27+
.addOption(opts.trustStorePasswordOption)
28+
.addOption(opts.nonInteractiveOption)
6229
// Descriptor file
63-
.addOption(packageDescriptorFilenameOption)
30+
.addOption(opts.packageDescriptorFilenameOption)
6431
// Deployment info
65-
.addOption(packageFileOption)
32+
.addOption(opts.packageFileOption)
6633
.action(async (options) => {
67-
const sourcesFolder: string = sourcesFolderOptionValue(options);
34+
const sourcesFolder: string = opts.sourcesFolderOptionValue(options);
6835

6936
const simulations = await findSimulations(sourcesFolder);
70-
const postman = postmanOptionValueWithDefaults(options);
71-
const typescript = typescriptOptionValueWithDefaults(options, simulations);
37+
const postman = opts.postmanOptionValueWithDefaults(options);
38+
const typescript = opts.typescriptOptionValueWithDefaults(options, simulations);
7239

73-
const resourcesFolder: string = resourcesFolderOptionValue(options);
74-
const bundleFile = bundleFileOptionValue(options);
75-
const resultsFolder: string = resultsFolderOptionValue(options);
76-
const gatlingHome = gatlingHomeOptionValueWithDefaults(options);
77-
const apiUrl = apiUrlOptionValue(options);
78-
const webAppUrl = webAppUrlOptionValue(options);
79-
const apiToken = apiTokenOptionValue(options);
80-
const controlPlaneUrl = controlPlaneUrlOptionValue(options);
81-
const trustStore = trustStoreOptionValue(options);
82-
const trustStorePassword = trustStorePasswordOptionValue(options);
83-
const nonInteractive = nonInteractiveOptionValue(options);
84-
const packageDescriptorFilename = packageDescriptorFilenameOptionValue(options);
85-
const packageFile = packageFileOptionValue(options);
40+
const resourcesFolder = opts.resourcesFolderOptionValue(options);
41+
const bundleFile = opts.bundleFileOptionValue(options);
42+
const resultsFolder = opts.resultsFolderOptionValue(options);
43+
const gatlingHome = opts.gatlingHomeOptionValueWithDefaults(options);
44+
const apiUrl = opts.apiUrlOptionValue(options);
45+
const webAppUrl = opts.webAppUrlOptionValue(options);
46+
const apiToken = opts.apiTokenOptionValue(options);
47+
const controlPlaneUrl = opts.controlPlaneUrlOptionValue(options);
48+
const trustStore = opts.trustStoreOptionValue(options);
49+
const trustStorePassword = opts.trustStorePasswordOptionValue(options);
50+
const nonInteractive = opts.nonInteractiveOptionValue(options);
51+
const packageDescriptorFilename = opts.packageDescriptorFilenameOptionValue(options);
52+
const packageFile = opts.packageFileOptionValue(options);
8653

8754
const { graalvmHome, jvmClasspath } = await resolveBundle({ gatlingHome });
8855
await bundle({ sourcesFolder, bundleFile, postman, typescript, simulations });

js/cli/src/commands/enterprisePackage.ts

+14-27
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,29 @@
11
import { Command } from "commander";
22

3-
import {
4-
bundleFileOption,
5-
bundleFileOptionValue,
6-
packageFileOption,
7-
packageFileOptionValue,
8-
postmanOption,
9-
postmanOptionValueWithDefaults,
10-
resourcesFolderOption,
11-
resourcesFolderOptionValue,
12-
sourcesFolderOption,
13-
sourcesFolderOptionValue,
14-
typescriptOption,
15-
typescriptOptionValueWithDefaults
16-
} from "./options";
3+
import { ResolvedOptions } from "./resolveOptions";
174
import { findSimulations } from "../simulations";
185
import { bundle } from "../bundle";
196
import { enterprisePackage } from "../enterprise";
207

21-
export default (program: Command): void => {
8+
export default (opts: ResolvedOptions, program: Command): void => {
229
program
2310
.command("enterprise-package")
2411
.description("Build Gatling simulations and package them for Gatling Enterprise")
25-
.addOption(sourcesFolderOption)
26-
.addOption(resourcesFolderOption)
27-
.addOption(bundleFileOption)
28-
.addOption(packageFileOption)
29-
.addOption(postmanOption)
30-
.addOption(typescriptOption)
12+
.addOption(opts.sourcesFolderOption)
13+
.addOption(opts.resourcesFolderOption)
14+
.addOption(opts.bundleFileOption)
15+
.addOption(opts.packageFileOption)
16+
.addOption(opts.postmanOption)
17+
.addOption(opts.typescriptOption)
3118
.action(async (options) => {
32-
const sourcesFolder: string = sourcesFolderOptionValue(options);
33-
const resourcesFolder: string = resourcesFolderOptionValue(options);
34-
const bundleFile = bundleFileOptionValue(options);
35-
const packageFile = packageFileOptionValue(options);
19+
const sourcesFolder = opts.sourcesFolderOptionValue(options);
20+
const resourcesFolder = opts.resourcesFolderOptionValue(options);
21+
const bundleFile = opts.bundleFileOptionValue(options);
22+
const packageFile = opts.packageFileOptionValue(options);
3623

3724
const simulations = await findSimulations(sourcesFolder);
38-
const postman = postmanOptionValueWithDefaults(options);
39-
const typescript = typescriptOptionValueWithDefaults(options, simulations);
25+
const postman = opts.postmanOptionValueWithDefaults(options);
26+
const typescript = opts.typescriptOptionValueWithDefaults(options, simulations);
4027

4128
await bundle({ sourcesFolder, bundleFile, postman, typescript, simulations });
4229

0 commit comments

Comments
 (0)