feat: added the --port flag

This commit is contained in:
Hayden Hargreaves 2026-04-24 22:43:49 -07:00
parent 15c73d7bfe
commit 711508ce58
3 changed files with 75 additions and 19 deletions

View File

@ -14,8 +14,7 @@ import (
"termtap.dev/internal/tui"
)
// This should be configurable at some point, just in case they build on 8080
const proxy_addr = "127.0.0.1:8080"
const defaultProxyPort = 8080
var fatalExit = log.Fatalln
var stdoutWriter io.Writer = stdioRef{isErr: false}
@ -44,13 +43,13 @@ func Run(args []string) {
return
}
cmd, ok := parseCommand(args)
cmd, proxyAddr, ok := parseCommand(args)
if !ok {
displayHelp()
return
}
session, err := startSessionFn(cmd, proxy_addr)
session, err := startSessionFn(cmd, proxyAddr)
if err != nil {
fatalExit(err)
return
@ -67,21 +66,50 @@ func Run(args []string) {
}
}
func parseCommand(args []string) (model.Command, bool) {
func parseCommand(args []string) (model.Command, string, bool) {
if len(args) < 4 {
return model.Command{}, false
return model.Command{}, "", false
}
if args[1] != "run" || args[2] != "--" {
return model.Command{}, false
if args[1] != "run" {
return model.Command{}, "", false
}
args = args[3:]
if len(args) == 1 {
return model.Command{Name: args[0], Args: []string{}}, true
port := defaultProxyPort
idx := 2
for idx < len(args) && args[idx] != "--" {
if args[idx] != "--port" {
return model.Command{}, "", false
}
if idx+1 >= len(args) {
return model.Command{}, "", false
}
p, err := strconv.Atoi(args[idx+1])
if err != nil || p <= 0 || p > 65535 {
return model.Command{}, "", false
}
port = p
idx += 2
}
return model.Command{Name: args[0], Args: args[1:]}, true
if idx >= len(args) || args[idx] != "--" {
return model.Command{}, "", false
}
if idx+1 >= len(args) {
return model.Command{}, "", false
}
cmdArgs := args[idx+1:]
cmd := model.Command{Name: cmdArgs[0], Args: cmdArgs[1:]}
return cmd, proxyAddrForPort(port), true
}
func proxyAddrForPort(port int) string {
return fmt.Sprintf("127.0.0.1:%d", port)
}
func displayHelp() {
@ -89,7 +117,7 @@ func displayHelp() {
usage:
tap demo
tap cert
tap run -- <command> [args...]
tap run [--port <port>] -- <command> [args...]
`
fmt.Fprintln(stderrWriter, helpText)
@ -137,5 +165,5 @@ func runCert() {
fmt.Fprintf(stdoutWriter, " sudo trust anchor %s\n", quotedCertPath)
fmt.Fprintln(stdoutWriter)
fmt.Fprintln(stdoutWriter, "Quick curl test:")
fmt.Fprintf(stdoutWriter, " curl --proxy http://%s --cacert %s https://example.com\n", proxy_addr, quotedCertPath)
fmt.Fprintf(stdoutWriter, " curl --proxy http://%s --cacert %s https://example.com\n", proxyAddrForPort(defaultProxyPort), quotedCertPath)
}

View File

@ -22,18 +22,24 @@ func TestParseCommand(t *testing.T) {
ok bool
nameWant string
argsWant []string
addrWant string
}{
{name: "too few args", args: []string{"tap"}, ok: false},
{name: "missing run token", args: []string{"tap", "oops", "--", "echo"}, ok: false},
{name: "missing separator", args: []string{"tap", "run", "echo"}, ok: false},
{name: "single command", args: []string{"tap", "run", "--", "echo"}, ok: true, nameWant: "echo", argsWant: []string{}},
{name: "command with args", args: []string{"tap", "run", "--", "curl", "-s", "https://example.com"}, ok: true, nameWant: "curl", argsWant: []string{"-s", "https://example.com"}},
{name: "single command", args: []string{"tap", "run", "--", "echo"}, ok: true, nameWant: "echo", argsWant: []string{}, addrWant: "127.0.0.1:8080"},
{name: "command with args", args: []string{"tap", "run", "--", "curl", "-s", "https://example.com"}, ok: true, nameWant: "curl", argsWant: []string{"-s", "https://example.com"}, addrWant: "127.0.0.1:8080"},
{name: "custom port", args: []string{"tap", "run", "--port", "9090", "--", "echo"}, ok: true, nameWant: "echo", argsWant: []string{}, addrWant: "127.0.0.1:9090"},
{name: "port missing value", args: []string{"tap", "run", "--port", "--", "echo"}, ok: false},
{name: "port invalid", args: []string{"tap", "run", "--port", "wat", "--", "echo"}, ok: false},
{name: "port out of range", args: []string{"tap", "run", "--port", "70000", "--", "echo"}, ok: false},
{name: "unknown flag", args: []string{"tap", "run", "--wat", "--", "echo"}, ok: false},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
cmd, ok := parseCommand(tt.args)
cmd, addr, ok := parseCommand(tt.args)
if ok != tt.ok {
t.Fatalf("ok = %v, want %v", ok, tt.ok)
}
@ -46,6 +52,9 @@ func TestParseCommand(t *testing.T) {
if strings.Join(cmd.Args, "|") != strings.Join(tt.argsWant, "|") {
t.Fatalf("cmd.Args = %#v, want %#v", cmd.Args, tt.argsWant)
}
if addr != tt.addrWant {
t.Fatalf("addr = %q, want %q", addr, tt.addrWant)
}
})
}
}
@ -55,7 +64,7 @@ func TestDisplayHelpWritesToStderr(t *testing.T) {
displayHelp()
})
if !strings.Contains(stderr, "tap demo") || !strings.Contains(stderr, "tap cert") || !strings.Contains(stderr, "tap run --") {
if !strings.Contains(stderr, "tap demo") || !strings.Contains(stderr, "tap cert") || !strings.Contains(stderr, "tap run [--port <port>] --") {
t.Fatalf("stderr missing usage text: %q", stderr)
}
}
@ -164,6 +173,25 @@ func TestRun_SuccessPathDoesNotCallFatal(t *testing.T) {
}
}
func TestRun_CustomPortPassedToSession(t *testing.T) {
restore := installRunSeams(t)
defer restore()
var gotAddr string
startSessionFn = func(_ model.Command, addr string) (*app.Session, error) {
gotAddr = addr
return &app.Session{Events: make(chan model.Event)}, nil
}
runTUIFn = func(<-chan model.Event, tui.Controls) error {
return nil
}
Run([]string{"tap", "run", "--port", "9091", "--", "echo"})
if gotAddr != "127.0.0.1:9091" {
t.Fatalf("session addr = %q, want %q", gotAddr, "127.0.0.1:9091")
}
}
func TestRunCert_EnsureCAFailureCallsFatalExit(t *testing.T) {
t.Setenv("XDG_CONFIG_HOME", "")
t.Setenv("HOME", "")

View File

@ -159,7 +159,7 @@ export function DocsPage() {
<div className="space-y-3 text-sm leading-6">
<p className="flex flex-col gap-1 md:flex-row md:gap-8">
<span className="w-28 text-emerald-400">--port</span>
<span className="text-slate-300">Proxy port (default 8888)</span>
<span className="text-slate-300">Proxy port (default 8080)</span>
</p>
</div>
</DocsSection>