mirror of
https://github.com/alibaba/open-code-review.git
synced 2026-10-21 05:29:48 +00:00
* feat(viewer): open URL in default browser * chore: write tests (AI) * fix: TCP listener created by net.Listen is not explicitly closed via defer Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * fix: no interactive prompt in non-interactives * fixes qwq * fix: no new line * refactor * chore: write test (AI) * apply suggestions & new example * docs: update (AI) * fix(viewer): address review feedback on browser auto-open - displayURL takes the host from the requested addr and only the port from the listener. net.Listen resolves a hostname to an IP literal while hostGuard's allowlist is built from the requested addr, so `--addr box.local:5483` auto-opened a URL its own host guard answered with 403 forbidden host. Taking only the port keeps `--addr :0` reporting the port the kernel assigned. - runBrowserCmd reads cmd.Wait() within a bounded window instead of trusting Start(). xdg-open exits non-zero when no handler is registered and open exits non-zero when no application claims the scheme, both after a successful fork/exec, so those failures left the user with neither a browser nor a warning. An opener that outlives the window is treated as success because it became the browser, but a later failure still warns. The child's stderr is folded into the error, and every candidate's failure is reported rather than only the first. - --open=auto|always|never replaces --no-open, matching the existing --color. The boolean could only suppress opening, never force it, leaving no way out when the heuristic declines wrongly. The auto-mode suppression reason is appended to the ready line so it cannot be mistaken for a broken open, $BROWSER is honored on Unix, and SSH is judged together with the display variables so `ssh -X` opens without an override. - ASSURANCE_CASE.md no longer claims every exec.Command call runs git. It already had four kinds of exception before this one. Browser handling moves to internal/viewer/browser.go, covered through a helper-process test that exercises the exec paths without launching a real browser. Docs updated across en/ja/ko/ru/zh. * fix(viewer): correct $BROWSER attribution and harden open-mode test browserCandidates credited the colon-separated list and %s placeholder to the Go toolchain, but cmd/internal/browser treats $BROWSER as a single executable path with neither. Attribute the parsing to the freedesktop convention as Python's webbrowser implements it, and note the divergence so the richer parsing reads as this package's choice rather than something inherited. Move the Go reference to browserWaitWindow, which is what is actually borrowed from it (appearsSuccessful, also 3s). TestViewerCmd_RejectsInvalidOpenMode called RunE directly. Dropping the ValidateOpenMode guard does not make RunE return an error there: it falls through to StartServer, which serves until the listener fails and so never returns, turning the regression into a suite-wide timeout panic that blames whichever test the runner happened to be on. Run RunE under a deadline and bind port 0 so a regression reports the actual cause instead of hanging, and restore addr alongside open. Confirmed by deleting the guard: the test now fails in 5s with "--open is not validated before StartServer binds". --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: kite <lizhengfeng.lzf@alibaba-inc.com>
41 lines
1.3 KiB
Go
41 lines
1.3 KiB
Go
// SPDX-License-Identifier: Apache-2.0
|
|
// Copyright 2026 alibaba/open-code-review Contributors
|
|
|
|
package main
|
|
|
|
import (
|
|
"github.com/alibaba/open-code-review/internal/viewer"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
type viewerOptions struct {
|
|
addr string
|
|
open string
|
|
}
|
|
|
|
var viewerOpts viewerOptions
|
|
|
|
var viewerCmd = &cobra.Command{
|
|
Use: "viewer [flags]",
|
|
Aliases: []string{"v"},
|
|
Short: "Start the WebUI session viewer",
|
|
Long: "Session history WebUI viewer.",
|
|
Args: cobra.NoArgs,
|
|
Example: ` ocr viewer # start and open the browser
|
|
ocr viewer --addr :3000 # bind to all interfaces on port 3000
|
|
ocr viewer --open=never # just print the URL
|
|
ocr viewer --open=always # force it when auto declines (piped output, WSL)`,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
if err := viewer.ValidateOpenMode(viewerOpts.open); err != nil {
|
|
return err
|
|
}
|
|
return viewer.StartServer(viewerOpts.addr, viewerOpts.open)
|
|
},
|
|
}
|
|
|
|
func init() {
|
|
viewerCmd.Flags().StringVar(&viewerOpts.addr, "addr", "localhost:5483", "listen address")
|
|
viewerCmd.Flags().StringVar(&viewerOpts.open, "open", viewer.OpenAuto,
|
|
"when to open the browser: auto (only on a local terminal with a display), always, or never")
|
|
viewerCmd.RegisterFlagCompletionFunc("open", completeEnum(viewer.OpenAuto, viewer.OpenAlways, viewer.OpenNever))
|
|
}
|