Skip to content

Commit e1456cb

Browse files
committed
feat(serve): open the browser once the server answers, --no-open opts out
scry demo forwards the flag; the e2e fixture passes it so test runs never spawn browser windows.
1 parent 6b80713 commit e1456cb

3 files changed

Lines changed: 51 additions & 7 deletions

File tree

cmd/scry/agent.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,15 @@ func cmdOpen(args []string) error {
486486
return errors.New("no Jira site configured — run `scry init` first")
487487
}
488488
u := strings.TrimRight(cfg.Site, "/") + "/browse/" + url.PathEscape(normalizeKey(args[0]))
489+
if err := openBrowser(u); err != nil {
490+
return fmt.Errorf("could not open a browser (%v) — the URL is %s", err, u)
491+
}
492+
fmt.Println(u)
493+
return nil
494+
}
495+
496+
// openBrowser starts the platform's URL opener and does not wait for it.
497+
func openBrowser(u string) error {
489498
var cmd *exec.Cmd
490499
switch runtime.GOOS {
491500
case "darwin":
@@ -495,9 +504,5 @@ func cmdOpen(args []string) error {
495504
default:
496505
cmd = exec.Command("xdg-open", u)
497506
}
498-
if err := cmd.Start(); err != nil {
499-
return fmt.Errorf("could not open a browser (%v) — the URL is %s", err, u)
500-
}
501-
fmt.Println(u)
502-
return nil
507+
return cmd.Start()
503508
}

cmd/scry/main.go

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ func cmdServe(args []string) error {
9292
withSync := fs.Bool("sync", false, "run the incremental sync loop inside the server")
9393
importAttachments := fs.String("import-attachments", "",
9494
"seed the attachment cache from a directory holding manifest.json (see examples/attachments)")
95+
noOpen := fs.Bool("no-open", false, "do not open the browser after the server starts")
9596
if err := fs.Parse(args); err != nil {
9697
return err
9798
}
@@ -207,6 +208,9 @@ func cmdServe(args []string) error {
207208
if len(cfg.Projects) == 0 {
208209
log.Printf("no projects configured — run `scry init`")
209210
}
211+
if !*noOpen {
212+
go openOnceUp(browseAddr(*addr))
213+
}
210214
err = srv.ListenAndServe()
211215
if err == http.ErrServerClosed {
212216
return nil
@@ -574,6 +578,7 @@ func cmdDemo(args []string) error {
574578
addr := fs.String("addr", "127.0.0.1:7878", "listen address")
575579
static := fs.String("static", "dist/app", "directory holding the built web UI")
576580
dbPath := fs.String("db", "examples/demo.db", "snapshot to serve")
581+
noOpen := fs.Bool("no-open", false, "do not open the browser after the server starts")
577582
if err := fs.Parse(args); err != nil {
578583
return err
579584
}
@@ -608,7 +613,41 @@ func cmdDemo(args []string) error {
608613
}
609614
log.Printf("demo mirror in %s (deleted on exit)", home)
610615
defer os.RemoveAll(home)
611-
return cmdServe([]string{"--addr", *addr, "--static", *static})
616+
serveArgs := []string{"--addr", *addr, "--static", *static}
617+
if *noOpen {
618+
serveArgs = append(serveArgs, "--no-open")
619+
}
620+
return cmdServe(serveArgs)
621+
}
622+
623+
// browseAddr turns a listen address into the URL a person should visit:
624+
// a blank or wildcard host becomes localhost.
625+
func browseAddr(addr string) string {
626+
host, port, err := net.SplitHostPort(addr)
627+
if err != nil {
628+
return "http://" + addr
629+
}
630+
if host == "" || host == "0.0.0.0" || host == "::" {
631+
host = "localhost"
632+
}
633+
return "http://" + net.JoinHostPort(host, port)
634+
}
635+
636+
// openOnceUp opens the browser as soon as the server answers /healthz, so the
637+
// tab never lands on a connection error. Gives up quietly after ~5s — a browser
638+
// failing to open must never take the server down with it.
639+
func openOnceUp(u string) {
640+
for i := 0; i < 50; i++ {
641+
res, err := http.Get(u + "/healthz")
642+
if err == nil {
643+
res.Body.Close()
644+
if err := openBrowser(u); err != nil {
645+
log.Printf("could not open a browser: %v — visit %s", err, u)
646+
}
647+
return
648+
}
649+
time.Sleep(100 * time.Millisecond)
650+
}
612651
}
613652

614653
func cmdProfiles() error {

e2e/serve.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,5 +90,5 @@ echo "[e2e] serving on 127.0.0.1:7877 (SCRY_HOME=$SCRY_HOME)…"
9090
# The snapshot references attachments whose bytes cannot be proxied (the fixture
9191
# credential is fake), so seed the cache from the committed images. Without this
9292
# the browser logs 502s and the console-hygiene spec fails.
93-
exec "$BIN" serve --addr 127.0.0.1:7877 --static dist/app \
93+
exec "$BIN" serve --addr 127.0.0.1:7877 --static dist/app --no-open \
9494
--import-attachments "$ROOT/examples/attachments"

0 commit comments

Comments
 (0)