mega-linter-runner 9.4.0 → 9.6.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/lib/options.js CHANGED
@@ -14,11 +14,42 @@ import { DEFAULT_RELEASE } from "./config.js";
14
14
  // Initialization and Public Interface
15
15
  //------------------------------------------------------------------------------
16
16
 
17
+ export const KNOWN_FLAVORS = [
18
+ "all",
19
+ "c_cpp",
20
+ "ci_light",
21
+ "cupcake",
22
+ "documentation",
23
+ "dotnet",
24
+ "dotnetweb",
25
+ "formatters",
26
+ "go",
27
+ "java",
28
+ "javascript",
29
+ "php",
30
+ "python",
31
+ "ruby",
32
+ "rust",
33
+ "salesforce",
34
+ "security",
35
+ "swift",
36
+ "terraform",
37
+ ];
38
+
39
+ export const KNOWN_CONTAINER_ENGINES = ["docker", "podman"];
40
+
41
+ export const KNOWN_PLATFORMS = ["linux/amd64", "linux/arm64"];
42
+
17
43
  // exports "parse(args)", "generateHelp()", and "generateHelpForOption(optionName)"
18
44
  export const optionsDefinition = optionator.default({
19
- prepend: "mega-linter [options]",
45
+ prepend: "mega-linter [options] [FILES...]",
46
+ append:
47
+ "Tips:\n" +
48
+ " - Pass MegaLinter env variables with -e KEY=VALUE (repeat or use commas: -e KEY1=val1,KEY2=val2).\n" +
49
+ " - List all 2300+ MegaLinter env variables with `mega-linter-runner --list-vars [pattern]`.\n" +
50
+ " - Online reference: https://megalinter.io/latest/config-variables/",
20
51
  defaults: {
21
- concatRepeatedArrays: true,
52
+ concatRepeatedArrays: [true, { oneValuePerFlag: true }],
22
53
  mergeRepeatedObjects: true,
23
54
  },
24
55
  options: [
@@ -27,22 +58,26 @@ export const optionsDefinition = optionator.default({
27
58
  alias: "r",
28
59
  type: "String",
29
60
  default: DEFAULT_RELEASE,
30
- description: "MegaLinter version",
31
- example: ["stable", "latest", `${DEFAULT_RELEASE}.1.2`],
61
+ description:
62
+ "MegaLinter version tag pulled from ghcr.io/oxsecurity/megalinter. Accepts a release tag (`v9.1.2`), a moving tag (`stable`, `latest`, `beta`, `alpha`), or a major-version tag (`v9`).",
63
+ example: ["stable", "latest", "beta", `${DEFAULT_RELEASE}.1.2`],
32
64
  },
33
65
  {
34
66
  option: "flavor",
35
67
  alias: "f",
36
68
  type: "String",
37
69
  default: "all",
38
- description: "MegaLinter flavor",
39
- example: ["dotnet", "javascript", "java", "php", "python"],
70
+ description:
71
+ "Specialized MegaLinter image to pull. Smaller flavors start faster and avoid pulling tools you do not need.\n" +
72
+ `Allowed values: ${KNOWN_FLAVORS.join(", ")}.`,
73
+ example: KNOWN_FLAVORS,
40
74
  },
41
75
  {
42
76
  option: "image",
43
77
  alias: "d",
44
78
  type: "String",
45
- description: "MegaLinter docker image",
79
+ description:
80
+ "Full docker image reference to run instead of resolving from --flavor/--release. Mutually exclusive with --flavor.",
46
81
  example: [
47
82
  "ghcr.io/oxsecurity/megalinter:latest",
48
83
  `ghcr.io/oxsecurity/megalinter:${DEFAULT_RELEASE}`,
@@ -55,40 +90,47 @@ export const optionsDefinition = optionator.default({
55
90
  type: "path::String",
56
91
  default: ".",
57
92
  description:
58
- "Directory containing the files to lint (default: current directory)",
59
- example: ["./path/to/my/files"],
93
+ "Directory containing the files to lint (default: current working directory). Mounted into the container at /tmp/lint.",
94
+ example: ["./path/to/my/files", "/abs/path/to/repo"],
60
95
  },
61
96
  {
62
97
  option: "env",
63
98
  alias: "e",
64
99
  type: "[String]",
65
- description: "Environment variable (multiple)",
100
+ description:
101
+ "MegaLinter environment variable in KEY=VALUE form. Repeat the flag for multiple variables, or pass several with a single flag using commas (KEY1=val1,KEY2=val2). Commas inside a single value (e.g. ENABLE_LINTERS=A,B) are preserved as-is, quoted or not. Run `mega-linter-runner --list-vars [pattern]` to discover supported variables.",
66
102
  example: [
67
- "-e 'ENABLE=JAVASCRIPT' -e 'SHOW_ELAPSED_TIME=true'",
68
- "-e 'ENABLE=JAVASCRIPT,YAML' -e 'DISABLE_LINTERS=MARKDOWN_MARKDOWN_LINK_CHECK'",
103
+ "-e ENABLE=JAVASCRIPT -e SHOW_ELAPSED_TIME=true",
104
+ "-e ENABLE_LINTERS=YAML_PRETTIER,YAML_YAMLLINT",
105
+ "-e APPLY_FIXES=all,LOG_LEVEL=DEBUG",
106
+ "--env=DISABLE_LINTERS=MARKDOWN_MARKDOWN_LINK_CHECK",
69
107
  ],
70
108
  },
71
109
  {
72
110
  option: "fix",
73
111
  type: "Boolean",
74
- description: "Apply formatters and fixes in linted sources",
112
+ description:
113
+ "Apply formatters and auto-fixes (equivalent to -e APPLY_FIXES=all).",
75
114
  },
76
115
  {
77
116
  option: "filesonly",
78
117
  type: "Boolean",
79
- description: "Do not run linters with project as CLI lint mode",
118
+ description:
119
+ "Do not run linters in `project` CLI lint mode (equivalent to -e SKIP_CLI_LINT_MODES=project).",
80
120
  },
81
121
  {
82
122
  option: "json",
83
123
  alias: "j",
84
124
  type: "Boolean",
85
- description: "Outputs results as JSON string",
125
+ description:
126
+ "Output the run summary as a JSON object on stdout (equivalent to -e JSON_REPORTER=true).",
86
127
  },
87
128
  {
88
129
  option: "nodockerpull",
89
130
  alias: "n",
90
131
  type: "Boolean",
91
- description: "Do not pull docker image before running it",
132
+ description:
133
+ "Skip `docker pull` before running. Useful for offline / cached / locally built images.",
92
134
  },
93
135
  {
94
136
  option: "platform",
@@ -96,86 +138,127 @@ export const optionsDefinition = optionator.default({
96
138
  type: "String",
97
139
  default: "linux/amd64",
98
140
  description:
99
- "Force a docker image platform (currently, only linux/amd64 works)",
141
+ "Container image platform forwarded to `docker --platform`.\n" +
142
+ `Allowed values: ${KNOWN_PLATFORMS.join(", ")} (linux/arm64 support is partial — see docs).`,
143
+ example: KNOWN_PLATFORMS,
100
144
  },
101
145
  {
102
146
  option: "debug",
103
147
  type: "Boolean",
104
- description: "See debug logs",
148
+ description:
149
+ "Enable verbose logs (equivalent to -e LOG_LEVEL=DEBUG).",
105
150
  },
106
151
  {
107
152
  option: "help",
108
153
  alias: "h",
109
154
  type: "Boolean",
110
155
  description:
111
- "Show help (mega-linter --help OPTIONNAME to see option detail)",
156
+ "Show help. Pass an option name as positional arg to see details: `mega-linter-runner --help env`.",
112
157
  },
113
158
  {
114
159
  option: "version",
115
160
  alias: "v",
116
161
  type: "Boolean",
117
- description: "Show version",
162
+ description: "Print the mega-linter-runner version and exit.",
118
163
  },
119
164
  {
120
165
  option: "install",
121
166
  alias: "i",
122
167
  type: "Boolean",
123
- description: "Generate MegaLinter configuration in your project",
168
+ description:
169
+ "Interactive generator that scaffolds .mega-linter.yml and CI workflow files in the current project.",
124
170
  },
125
171
  {
126
172
  option: "custom-flavor-setup",
127
173
  alias: "cfs",
128
174
  type: "Boolean",
129
- description: "Generate files to create a custom flavor",
175
+ description: "Generate scaffolding files to build a custom MegaLinter flavor.",
130
176
  },
131
177
  {
132
178
  option: "custom-flavor-linters",
133
179
  type: "String",
134
- description: "comma-separated list of linters to include in custom flavor",
180
+ description:
181
+ "Comma-separated list of MegaLinter linter keys to include in the custom flavor (e.g. YAML_PRETTIER,YAML_YAMLLINT).",
182
+ example: ["YAML_PRETTIER,YAML_YAMLLINT", "PYTHON_RUFF,PYTHON_BLACK"],
135
183
  },
136
184
  {
137
185
  option: "upgrade",
138
186
  alias: "u",
139
187
  type: "Boolean",
140
- description: "Upgrade local repository MegaLinter configuration",
188
+ description:
189
+ "Upgrade the local MegaLinter configuration (.mega-linter.yml and related CI files) to the current major version.",
190
+ },
191
+ {
192
+ option: "prompt",
193
+ type: "Boolean",
194
+ description:
195
+ "Enable interactive prompts. Use --no-prompt to run non-interactively. For `--upgrade`, that proceeds with the upgrade and skips optional follow-up prompts.",
141
196
  },
142
197
  {
143
198
  option: "container-name",
144
199
  alias: "containername",
145
200
  type: "String",
146
- description: "Specify MegaLinter container name",
201
+ description:
202
+ "Override the container name passed to `docker run --name`.",
203
+ example: ["my-megalinter-run"],
147
204
  },
148
205
  {
149
206
  option: "container-engine",
150
207
  alias: "",
151
208
  type: "String",
152
209
  default: "docker",
153
- description: "Use docker or podman as container engine",
154
- },
210
+ description:
211
+ "Container engine binary to invoke.\n" +
212
+ `Allowed values: ${KNOWN_CONTAINER_ENGINES.join(", ")}.`,
213
+ example: KNOWN_CONTAINER_ENGINES,
214
+ },
155
215
  {
156
216
  option: "remove-container",
157
217
  type: "Boolean",
158
- description: "Remove MegaLinter Docker container when done (default: true since v7.8.0)",
218
+ description:
219
+ "Remove the MegaLinter container when done. This is the default since v7.8.0; use --no-remove-container to keep it.",
159
220
  },
160
221
  {
161
222
  option: "no-remove-container",
162
223
  type: "Boolean",
163
- description: "Do not remove MegaLinter Docker container when done",
224
+ description:
225
+ "Keep the MegaLinter container after the run. Useful for `docker logs <container>` post-mortem.",
226
+ },
227
+ {
228
+ option: "user-map",
229
+ type: "Boolean",
230
+ description:
231
+ "Run the container as a non-root user. On POSIX systems this uses your user. On other hosts it uses 1000:1000.",
232
+ },
233
+ {
234
+ option: "no-user-map",
235
+ type: "Boolean",
236
+ description:
237
+ "Run the container as root.",
164
238
  },
165
239
  {
166
240
  option: "codetotal",
167
241
  type: "Boolean",
168
- description: "Run CodeTotal locally",
242
+ description:
243
+ "[NOT ACTIVELY MAINTAINED] Launch CodeTotal locally (companion UI for MegaLinter results). The CodeTotal project is no longer actively maintained; use at your own risk.",
169
244
  },
170
245
  {
171
246
  option: "codetotal-url",
172
247
  type: "String",
173
248
  default: "http://localhost:8081/",
174
- description: "URL Hosting CodeTotal once launched",
249
+ description:
250
+ "[NOT ACTIVELY MAINTAINED] URL where the local CodeTotal instance will be served. The CodeTotal project is no longer actively maintained.",
251
+ example: ["http://localhost:8081/"],
252
+ },
253
+ {
254
+ option: "list-vars",
255
+ type: "Boolean",
256
+ description:
257
+ "List MegaLinter environment variables that can be passed via -e. Add a positional substring to filter (case-insensitive), e.g. `mega-linter-runner --list-vars PYTHON_RUFF`. Add --json for machine-readable output.",
175
258
  },
176
259
  ],
177
260
  mutuallyExclusive: [
178
- ["help", "version", "install"],
261
+ ["help", "version", "install", "list-vars"],
179
262
  ["image", "flavor"],
180
263
  ],
181
264
  });
package/lib/runner.js CHANGED
@@ -1,4 +1,6 @@
1
- import { optionsDefinition } from "./options.js"
1
+ import { optionsDefinition, KNOWN_CONTAINER_ENGINES } from "./options.js"
2
+ import { expandEnvEntries } from "./env-parser.js";
3
+ import { listVars } from "./list-vars.js";
2
4
  import { spawnSync } from "child_process";
3
5
  import { default as c } from 'chalk';
4
6
  import * as path from 'path';
@@ -28,6 +30,14 @@ export class MegaLinterRunner {
28
30
  return { status: 0, stdout: outputString };
29
31
  }
30
32
 
33
+ // List MegaLinter env variables (optionally filtered)
34
+ if (options.listVars) {
35
+ const pattern = options._ && options._.length ? options._[0] : null;
36
+ const { stdout } = listVars({ pattern, asJson: options.json === true });
37
+ console.log(stdout);
38
+ return { status: 0, stdout };
39
+ }
40
+
31
41
  // Show version
32
42
  if (options.version) {
33
43
  let v = process.env.npm_package_version;
@@ -73,12 +83,19 @@ export class MegaLinterRunner {
73
83
 
74
84
  // Run upgrader from v4 to v5
75
85
  if (options.upgrade) {
76
- const megaLinterUpgrader = new MegaLinterUpgrader();
86
+ const megaLinterUpgrader = new MegaLinterUpgrader({
87
+ noPrompt: options.prompt === false,
88
+ });
77
89
  await megaLinterUpgrader.run();
78
90
  return { status: 0 };
79
91
  }
80
92
 
81
93
  if (options.codetotal) {
94
+ console.warn(
95
+ c.yellow(
96
+ "[WARNING] CodeTotal is not actively maintained. The --codetotal integration is kept for legacy users and may be removed in a future major release.",
97
+ ),
98
+ );
82
99
  const codeTotalRunner = new CodeTotalRunner(options);
83
100
  await codeTotalRunner.run();
84
101
  return { status: 0 }
@@ -86,8 +103,10 @@ export class MegaLinterRunner {
86
103
 
87
104
  // Build MegaLinter docker image name with flavor and release version
88
105
  this.containerEngine = options.containerEngine || "docker";
89
- if (this.containerEngine !== "docker" && this.containerEngine !== "podman") {
90
- throw new Error(`Invalid container engine: ${this.containerEngine}. Supported engines are 'docker' and 'podman'.`);
106
+ if (!KNOWN_CONTAINER_ENGINES.includes(this.containerEngine)) {
107
+ throw new Error(
108
+ `Invalid container engine: ${this.containerEngine}. Supported engines are ${KNOWN_CONTAINER_ENGINES.join(", ")}.`,
109
+ );
91
110
  }
92
111
  const release = options.release in ["stable"] ? DEFAULT_RELEASE : options.release;
93
112
  const dockerImageName =
@@ -199,8 +218,16 @@ export class MegaLinterRunner {
199
218
  if (options["containerName"]) {
200
219
  commandArgs.push(...["--name", options["containerName"]]);
201
220
  }
202
- commandArgs.push(...["-v", "/var/run/docker.sock:/var/run/docker.sock:rw"]);
203
221
  commandArgs.push(...["-v", `${lintPath}:/tmp/lint:rw`]);
222
+ if (options["userMap"] === true) {
223
+ const runtimeUid =
224
+ typeof process.getuid === "function" ? process.getuid() : 1000;
225
+ const runtimeGid =
226
+ typeof process.getgid === "function" ? process.getgid() : 1000;
227
+ commandArgs.push(...["-e", `MEGALINTER_UID=${runtimeUid}`]);
228
+ commandArgs.push(...["-e", `MEGALINTER_GID=${runtimeGid}`]);
229
+ commandArgs.push(...["-e", "HOME=/home/megalinter"]);
230
+ }
204
231
  if (emptyEnvFile) {
205
232
  commandArgs.push(...["-v", `${emptyEnvFile}:/tmp/lint/.env:ro`]);
206
233
  }
@@ -219,7 +246,7 @@ export class MegaLinterRunner {
219
246
  }
220
247
  }
221
248
  if (options.env) {
222
- for (const envVarEqualsValue of options.env) {
249
+ for (const envVarEqualsValue of expandEnvEntries(options.env)) {
223
250
  commandArgs.push(...["-e", envVarEqualsValue]);
224
251
  }
225
252
  }
package/lib/upgrade.js CHANGED
@@ -8,7 +8,8 @@ import { asciiArt } from "./ascii.js";
8
8
  import { DEFAULT_RELEASE, GLOB_IGNORE_PATTERNS } from "./config.js";
9
9
 
10
10
  export class MegaLinterUpgrader {
11
- constructor() {
11
+ constructor({ noPrompt = false } = {}) {
12
+ this.noPrompt = noPrompt;
12
13
  this.replacements = [
13
14
  // Documentation base URL
14
15
  {
@@ -462,10 +463,10 @@ jobs:
462
463
  },
463
464
  // Create pull request action
464
465
  {
465
- regex: /peter-evans\/create-pull-request@v(3|4|5|6)/gm,
466
- replacement: `peter-evans/create-pull-request@v7`,
467
- test: "peter-evans/create-pull-request@v6",
468
- testRes: `peter-evans/create-pull-request@v7`,
466
+ regex: /peter-evans\/create-pull-request@v(3|4|5|6|7)/gm,
467
+ replacement: `peter-evans/create-pull-request@v8`,
468
+ test: "peter-evans/create-pull-request@v7",
469
+ testRes: `peter-evans/create-pull-request@v8`,
469
470
  },
470
471
  // Auto-commit action
471
472
  {
@@ -553,15 +554,19 @@ jobs:
553
554
 
554
555
  async run() {
555
556
  console.log(asciiArt());
556
- const promptsUpgradeRes = await prompts({
557
- name: "upgrade",
558
- message: c.blueBright(
559
- `This assistant will automatically upgrade your local files so you use MegaLinter ${DEFAULT_RELEASE}\nPlease confirm to proceed :)`
560
- ),
561
- type: "confirm",
562
- initial: true,
563
- });
564
- if (promptsUpgradeRes.upgrade === false) {
557
+ const confirmedUpgrade = this.noPrompt
558
+ ? true
559
+ : (
560
+ await prompts({
561
+ name: "upgrade",
562
+ message: c.blueBright(
563
+ `This assistant will automatically upgrade your local files so you use MegaLinter ${DEFAULT_RELEASE}\nPlease confirm to proceed :)`
564
+ ),
565
+ type: "confirm",
566
+ initial: true,
567
+ })
568
+ ).upgrade;
569
+ if (confirmedUpgrade === false) {
565
570
  console.log(
566
571
  `You should upgrade to ${DEFAULT_RELEASE} to benefit from latest versions of linters, and more features :)`
567
572
  );
@@ -580,6 +585,9 @@ jobs:
580
585
  )
581
586
  );
582
587
  console.log("");
588
+ if (this.noPrompt) {
589
+ return;
590
+ }
583
591
  // Propose to try ox service
584
592
  const promptsOXRes = await prompts({
585
593
  name: "ox",
@@ -662,4 +670,3 @@ jobs:
662
670
  }
663
671
  }
664
672
  }
665
-
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mega-linter-runner",
3
- "version": "9.4.0",
3
+ "version": "9.6.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/oxsecurity/megalinter.git"
@@ -92,10 +92,10 @@
92
92
  "optionator": "^0.9.3",
93
93
  "prompts": "^2.4.2",
94
94
  "simple-git": "^3.28.0",
95
- "uuid": "^13.0.0",
96
- "which": "^6.0.0",
97
- "yeoman-environment": "^5.0.0",
98
- "yeoman-generator": "^7.1.0"
95
+ "uuid": "^14.0.0",
96
+ "which": "^7.0.0",
97
+ "yeoman-environment": "^6.0.0",
98
+ "yeoman-generator": "^8.0.0"
99
99
  },
100
100
  "devDependencies": {
101
101
  "assert": "^2.1.0",
@@ -103,7 +103,10 @@
103
103
  "mocha": "^11.0.0"
104
104
  },
105
105
  "resolutions": {
106
- "semver": "7.7.4",
107
- "tmp": "0.2.5"
106
+ "diff": "^9.0.0",
107
+ "ip-address": "^10.1.1",
108
+ "serialize-javascript": "^7.0.5",
109
+ "semver": "7.8.5",
110
+ "tmp": "0.2.7"
108
111
  }
109
112
  }