Skip to content

Commit 892d2a7

Browse files
committed
fix #3834: cli sometimes panics with --analyze
1 parent 360d472 commit 892d2a7

File tree

3 files changed

+50
-15
lines changed

3 files changed

+50
-15
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
fs.open;
2121
```
2222

23+
* Fix a panic when using the CLI with invalid build flags if `--analyze` is present ([#3834](https://github.com/evanw/esbuild/issues/3834))
24+
25+
Previously esbuild's CLI could crash if it was invoked with flags that aren't valid for a "build" API call and the `--analyze` flag is present. This was caused by esbuild's internals attempting to add a Go plugin (which is how `--analyze` is implemented) to a null build object. The panic has been fixed in this release.
26+
2327
## 0.23.0
2428
2529
**_This release deliberately contains backwards-incompatible changes._** To avoid automatically picking up releases like this, you should either be pinning the exact version of `esbuild` in your `package.json` file (recommended) or be using a version range syntax that only accepts patch upgrades such as `^0.22.0` or `~0.22.0`. See npm's documentation about [semver](https://docs.npmjs.com/cli/v6/using-npm/semver/) for more information.

pkg/cli/cli_impl.go

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,11 +1023,15 @@ outer:
10231023
return
10241024
}
10251025

1026+
func isArgForBuild(arg string) bool {
1027+
return !strings.HasPrefix(arg, "-") || arg == "--bundle"
1028+
}
1029+
10261030
// This returns either BuildOptions, TransformOptions, or an error
10271031
func parseOptionsForRun(osArgs []string) (*api.BuildOptions, *api.TransformOptions, parseOptionsExtras, *cli_helpers.ErrorWithNote) {
10281032
// If there's an entry point or we're bundling, then we're building
10291033
for _, arg := range osArgs {
1030-
if !strings.HasPrefix(arg, "-") || arg == "--bundle" {
1034+
if isArgForBuild(arg) {
10311035
options := newBuildOptions()
10321036

10331037
// Apply defaults appropriate for the CLI
@@ -1091,20 +1095,25 @@ const (
10911095
)
10921096

10931097
func filterAnalyzeFlags(osArgs []string) ([]string, analyzeMode) {
1094-
analyze := analyzeDisabled
1095-
end := 0
10961098
for _, arg := range osArgs {
1097-
switch arg {
1098-
case "--analyze":
1099-
analyze = analyzeEnabled
1100-
case "--analyze=verbose":
1101-
analyze = analyzeVerbose
1102-
default:
1103-
osArgs[end] = arg
1104-
end++
1099+
if isArgForBuild(arg) {
1100+
analyze := analyzeDisabled
1101+
end := 0
1102+
for _, arg := range osArgs {
1103+
switch arg {
1104+
case "--analyze":
1105+
analyze = analyzeEnabled
1106+
case "--analyze=verbose":
1107+
analyze = analyzeVerbose
1108+
default:
1109+
osArgs[end] = arg
1110+
end++
1111+
}
1112+
}
1113+
return osArgs[:end], analyze
11051114
}
11061115
}
1107-
return osArgs[:end], analyze
1116+
return osArgs, analyzeDisabled
11081117
}
11091118

11101119
// Print metafile analysis after the build if it's enabled
@@ -1150,10 +1159,11 @@ func runImpl(osArgs []string, plugins []api.Plugin) int {
11501159
// Add any plugins from the caller after parsing the build options
11511160
if buildOptions != nil {
11521161
buildOptions.Plugins = append(buildOptions.Plugins, plugins...)
1153-
}
11541162

1155-
if analyze != analyzeDisabled {
1156-
addAnalyzePlugin(buildOptions, analyze, osArgs)
1163+
// The "--analyze" flag is implemented as a plugin
1164+
if analyze != analyzeDisabled {
1165+
addAnalyzePlugin(buildOptions, analyze, osArgs)
1166+
}
11571167
}
11581168

11591169
switch {

scripts/end-to-end-tests.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8446,6 +8446,27 @@ tests.push(
84468446
}),
84478447
)
84488448

8449+
// Tests for analyze
8450+
tests.push(
8451+
test(['in.js', '--analyze', '--outfile=node.js'], {
8452+
'in.js': `let x = 1 + 2`,
8453+
}, {
8454+
expectedStderr: `
8455+
node.js 15b 100.0%
8456+
└ in.js 15b 100.0%
8457+
8458+
`,
8459+
}),
8460+
test(['in.js', '--invalid-flag', '--analyze'], {
8461+
'in.js': `let x = 1 + 2`,
8462+
}, {
8463+
expectedStderr: `${errorIcon} [ERROR] Invalid build flag: "--invalid-flag"\n\n`,
8464+
}),
8465+
test(['--analyze'], {}, {
8466+
expectedStderr: `${errorIcon} [ERROR] Invalid transform flag: "--analyze"\n\n`,
8467+
}),
8468+
)
8469+
84498470
// Test writing to stdout
84508471
tests.push(
84518472
// These should succeed

0 commit comments

Comments
 (0)