Skip to content

Commit a4b1f20

Browse files
committed
fix evanw#834: add Go "ParseServeOptions" API
1 parent f6dc899 commit a4b1f20

File tree

3 files changed

+60
-21
lines changed

3 files changed

+60
-21
lines changed

CHANGELOG.md

+12
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,18 @@
5555

5656
Restrictions on array and object destructuring patterns in the previous release introduced a regression where arrays or objects in TypeScript code could fail to parse if they were wrapped in a double layer of parentheses. This was due to the speculative parsing of arrow function arguments. The regression has been fixed.
5757

58+
* Add the Go-specific `cli.ParseServeOptions()` API ([#834](https://github.com/evanw/esbuild/issues/834))
59+
60+
This API is specifically for people trying to emulate esbuild's CLI in Go. It lets you share esbuild's logic of parsing the `--serve=` and `--servedir=` flags. Use it like this:
61+
62+
```go
63+
serveOptions, args, err := cli.ParseServeOptions([]string{
64+
"--serve=8000",
65+
})
66+
buildOptions, err := cli.ParseBuildOptions(args)
67+
result := api.Serve(serveOptions, buildOptions)
68+
```
69+
5870
## 0.8.48
5971

6072
* Fix some parsing edge cases ([#835](https://github.com/evanw/esbuild/issues/835))

pkg/cli/cli.go

+19
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,22 @@ func ParseTransformOptions(osArgs []string) (options api.TransformOptions, err e
6969
err = parseOptionsImpl(osArgs, nil, &options)
7070
return
7171
}
72+
73+
// This parses an array of strings into an options object suitable for passing
74+
// to "api.Serve()". The remaining non-serve arguments are returned in another
75+
// array to then be passed to "api.ParseBuildOptions()". Use this if you need
76+
// to reuse the same argument parsing logic as the esbuild CLI.
77+
//
78+
// Example usage:
79+
//
80+
// serveOptions, args, err := cli.ParseServeOptions([]string{
81+
// "--serve=8000",
82+
// })
83+
//
84+
// buildOptions, err := cli.ParseBuildOptions(args)
85+
//
86+
// result := api.Serve(serveOptions, buildOptions)
87+
//
88+
func ParseServeOptions(osArgs []string) (options api.ServeOptions, remainingArgs []string, err error) {
89+
return parseServeOptionsImpl(osArgs)
90+
}

pkg/cli/cli_impl.go

+29-21
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,7 @@ func printSummary(osArgs []string, outputFiles []api.OutputFile, start time.Time
687687
logger.PrintSummary(osArgs, table, start)
688688
}
689689

690-
func serveImpl(osArgs []string) error {
690+
func parseServeOptionsImpl(osArgs []string) (api.ServeOptions, []string, error) {
691691
host := ""
692692
portText := "0"
693693
servedir := ""
@@ -711,17 +711,30 @@ func serveImpl(osArgs []string) error {
711711
var err error
712712
host, portText, err = net.SplitHostPort(portText)
713713
if err != nil {
714-
return err
714+
return api.ServeOptions{}, nil, err
715715
}
716716
}
717717

718718
// Parse the port
719719
port, err := strconv.ParseInt(portText, 10, 32)
720720
if err != nil {
721-
return err
721+
return api.ServeOptions{}, nil, err
722722
}
723723
if port < 0 || port > 0xFFFF {
724-
return fmt.Errorf("Invalid port number: %s", portText)
724+
return api.ServeOptions{}, nil, fmt.Errorf("Invalid port number: %s", portText)
725+
}
726+
727+
return api.ServeOptions{
728+
Port: uint16(port),
729+
Host: host,
730+
Servedir: servedir,
731+
}, filteredArgs, nil
732+
}
733+
734+
func serveImpl(osArgs []string) error {
735+
serveOptions, filteredArgs, err := parseServeOptionsImpl(osArgs)
736+
if err != nil {
737+
return err
725738
}
726739

727740
options := newBuildOptions()
@@ -735,23 +748,18 @@ func serveImpl(osArgs []string) error {
735748
return err
736749
}
737750

738-
serveOptions := api.ServeOptions{
739-
Port: uint16(port),
740-
Host: host,
741-
Servedir: servedir,
742-
OnRequest: func(args api.ServeOnRequestArgs) {
743-
logger.PrintText(os.Stderr, logger.LevelInfo, filteredArgs, func(colors logger.Colors) string {
744-
statusColor := colors.Red
745-
if args.Status >= 200 && args.Status <= 299 {
746-
statusColor = colors.Green
747-
} else if args.Status >= 300 && args.Status <= 399 {
748-
statusColor = colors.Yellow
749-
}
750-
return fmt.Sprintf("%s%s - %q %s%d%s [%dms]%s\n",
751-
colors.Dim, args.RemoteAddress, args.Method+" "+args.Path,
752-
statusColor, args.Status, colors.Dim, args.TimeInMS, colors.Default)
753-
})
754-
},
751+
serveOptions.OnRequest = func(args api.ServeOnRequestArgs) {
752+
logger.PrintText(os.Stderr, logger.LevelInfo, filteredArgs, func(colors logger.Colors) string {
753+
statusColor := colors.Red
754+
if args.Status >= 200 && args.Status <= 299 {
755+
statusColor = colors.Green
756+
} else if args.Status >= 300 && args.Status <= 399 {
757+
statusColor = colors.Yellow
758+
}
759+
return fmt.Sprintf("%s%s - %q %s%d%s [%dms]%s\n",
760+
colors.Dim, args.RemoteAddress, args.Method+" "+args.Path,
761+
statusColor, args.Status, colors.Dim, args.TimeInMS, colors.Default)
762+
})
755763
}
756764

757765
result, err := api.Serve(serveOptions, options)

0 commit comments

Comments
 (0)