Skip to content

Commit

Permalink
fix #834: add Go "ParseServeOptions" API
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Feb 19, 2021
1 parent f6dc899 commit a4b1f20
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 21 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,18 @@

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.

* Add the Go-specific `cli.ParseServeOptions()` API ([#834](https://github.com/evanw/esbuild/issues/834))

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:

```go
serveOptions, args, err := cli.ParseServeOptions([]string{
"--serve=8000",
})
buildOptions, err := cli.ParseBuildOptions(args)
result := api.Serve(serveOptions, buildOptions)
```

## 0.8.48

* Fix some parsing edge cases ([#835](https://github.com/evanw/esbuild/issues/835))
Expand Down
19 changes: 19 additions & 0 deletions pkg/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,22 @@ func ParseTransformOptions(osArgs []string) (options api.TransformOptions, err e
err = parseOptionsImpl(osArgs, nil, &options)
return
}

// This parses an array of strings into an options object suitable for passing
// to "api.Serve()". The remaining non-serve arguments are returned in another
// array to then be passed to "api.ParseBuildOptions()". Use this if you need
// to reuse the same argument parsing logic as the esbuild CLI.
//
// Example usage:
//
// serveOptions, args, err := cli.ParseServeOptions([]string{
// "--serve=8000",
// })
//
// buildOptions, err := cli.ParseBuildOptions(args)
//
// result := api.Serve(serveOptions, buildOptions)
//
func ParseServeOptions(osArgs []string) (options api.ServeOptions, remainingArgs []string, err error) {
return parseServeOptionsImpl(osArgs)
}
50 changes: 29 additions & 21 deletions pkg/cli/cli_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ func printSummary(osArgs []string, outputFiles []api.OutputFile, start time.Time
logger.PrintSummary(osArgs, table, start)
}

func serveImpl(osArgs []string) error {
func parseServeOptionsImpl(osArgs []string) (api.ServeOptions, []string, error) {
host := ""
portText := "0"
servedir := ""
Expand All @@ -711,17 +711,30 @@ func serveImpl(osArgs []string) error {
var err error
host, portText, err = net.SplitHostPort(portText)
if err != nil {
return err
return api.ServeOptions{}, nil, err
}
}

// Parse the port
port, err := strconv.ParseInt(portText, 10, 32)
if err != nil {
return err
return api.ServeOptions{}, nil, err
}
if port < 0 || port > 0xFFFF {
return fmt.Errorf("Invalid port number: %s", portText)
return api.ServeOptions{}, nil, fmt.Errorf("Invalid port number: %s", portText)
}

return api.ServeOptions{
Port: uint16(port),
Host: host,
Servedir: servedir,
}, filteredArgs, nil
}

func serveImpl(osArgs []string) error {
serveOptions, filteredArgs, err := parseServeOptionsImpl(osArgs)
if err != nil {
return err
}

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

serveOptions := api.ServeOptions{
Port: uint16(port),
Host: host,
Servedir: servedir,
OnRequest: func(args api.ServeOnRequestArgs) {
logger.PrintText(os.Stderr, logger.LevelInfo, filteredArgs, func(colors logger.Colors) string {
statusColor := colors.Red
if args.Status >= 200 && args.Status <= 299 {
statusColor = colors.Green
} else if args.Status >= 300 && args.Status <= 399 {
statusColor = colors.Yellow
}
return fmt.Sprintf("%s%s - %q %s%d%s [%dms]%s\n",
colors.Dim, args.RemoteAddress, args.Method+" "+args.Path,
statusColor, args.Status, colors.Dim, args.TimeInMS, colors.Default)
})
},
serveOptions.OnRequest = func(args api.ServeOnRequestArgs) {
logger.PrintText(os.Stderr, logger.LevelInfo, filteredArgs, func(colors logger.Colors) string {
statusColor := colors.Red
if args.Status >= 200 && args.Status <= 299 {
statusColor = colors.Green
} else if args.Status >= 300 && args.Status <= 399 {
statusColor = colors.Yellow
}
return fmt.Sprintf("%s%s - %q %s%d%s [%dms]%s\n",
colors.Dim, args.RemoteAddress, args.Method+" "+args.Path,
statusColor, args.Status, colors.Dim, args.TimeInMS, colors.Default)
})
}

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

0 comments on commit a4b1f20

Please sign in to comment.