mirror of
https://gitea.com/gitea/tea.git
synced 2026-10-26 19:11:25 +01:00
- `internal/terminal`: streams and the prompting policy, interactive forms (issue, PR, review, merge, milestone), editor / pager / browser launching, JSON and `--jq` output. - An aligned table renderer and a record renderer for human output; both strip control and escape characters from server-supplied text so titles and bodies cannot inject terminal sequences. Reviewed-on: https://gitea.com/gitea/tea/pulls/1124 Reviewed-by: TheFox0x7 <95654+thefox0x7@noreply.gitea.com>
60 lines
1.7 KiB
Go
60 lines
1.7 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package terminal
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"net/url"
|
|
"os/exec"
|
|
"runtime"
|
|
"strings"
|
|
)
|
|
|
|
// Browser opens an explicitly requested resource using a configured command.
|
|
type Browser interface {
|
|
Open(context.Context, string, string) error
|
|
}
|
|
|
|
// SystemBrowser runs the browser without a shell and routes diagnostics to stderr.
|
|
type SystemBrowser struct{ ErrOut io.Writer }
|
|
|
|
// Open validates the resource and invokes the selected browser directly.
|
|
func (b SystemBrowser) Open(ctx context.Context, resource, command string) error {
|
|
u, err := url.Parse(resource)
|
|
if err != nil || (u.Scheme != "http" && u.Scheme != "https") || u.Host == "" || u.User != nil || strings.ContainsAny(resource, "\x00\r\n") {
|
|
return errors.New("browser requires an HTTP or HTTPS resource URL without credentials")
|
|
}
|
|
var args []string
|
|
if command == "" || command == "auto" {
|
|
switch runtime.GOOS {
|
|
case "darwin":
|
|
args = []string{"open"}
|
|
case "windows":
|
|
args = []string{"rundll32", "url.dll,FileProtocolHandler"}
|
|
default:
|
|
args = []string{"xdg-open"}
|
|
}
|
|
} else {
|
|
if command == "never" {
|
|
return errors.New("browser opening is disabled; configure browser or BROWSER")
|
|
}
|
|
var ok bool
|
|
if args, ok = commandArgs(command); !ok {
|
|
return errors.New("browser command contains malformed quoted arguments")
|
|
}
|
|
}
|
|
process := exec.CommandContext(ctx, args[0], append(args[1:], resource)...)
|
|
process.Stdout, process.Stderr = b.ErrOut, b.ErrOut
|
|
if err := process.Run(); err != nil {
|
|
if ctx.Err() != nil {
|
|
return ctx.Err()
|
|
}
|
|
return fmt.Errorf("browser could not be opened; configure browser or BROWSER: %w", err)
|
|
}
|
|
return nil
|
|
}
|