cmd/tailscale: print a helpful error for Taildrive CLI on macOS GUI

Rather than printing `unknown subcommand: drive` for any Taildrive
commands run in the macOS GUI, print an error message directing the user
to the GUI client and the docs page.

Updates #17210
Fixes #18823

Change-Id: I6435007b5911baee79274b56e3ee101e6bb6d809
Signed-off-by: Alex Chan <alexc@tailscale.com>
This commit is contained in:
Alex Chan
2026-03-17 09:55:24 +00:00
committed by Alex Chan
parent 931fe56586
commit 34267d5afa
2 changed files with 99 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
//go:build !ts_omit_drive && ts_mac_gui
package cli
import (
"context"
"errors"
"github.com/peterbourgon/ff/v3/ffcli"
)
func init() {
maybeDriveCmd = driveCmdStub
}
func driveCmdStub() *ffcli.Command {
return &ffcli.Command{
Name: "drive",
ShortHelp: "Share a directory with your tailnet",
ShortUsage: "tailscale drive [...any]",
LongHelp: hidden + "Taildrive allows you to share directories with other machines on your tailnet.",
Exec: func(_ context.Context, args []string) error {
return errors.New(
"Taildrive CLI commands are not supported when using the macOS GUI app. " +
"Please use the Tailscale menu bar icon to configure Taildrive in Settings.\n\n" +
"See https://tailscale.com/docs/features/taildrive",
)
},
}
}

View File

@@ -0,0 +1,66 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
//go:build !ts_omit_drive && ts_mac_gui
package cli
import (
"bytes"
"context"
"flag"
"strings"
"testing"
"github.com/peterbourgon/ff/v3/ffcli"
)
// In macOS GUI builds, the `drive` command should not appear in
// the help text generated by ffcli.
func TestDriveCommandHiddenInHelpText(t *testing.T) {
root := newRootCmd()
var buf bytes.Buffer
root.FlagSet = flag.NewFlagSet("tailscale", flag.ContinueOnError)
root.FlagSet.SetOutput(&buf)
ffcli.DefaultUsageFunc(root)
output := buf.String()
if strings.Contains(output, "drive") {
t.Errorf("found hidden command 'drive' in help output:\n%q", output)
}
}
// Running the drive command always prints an error pointing you to
// the GUI app, regardless of input.
func TestDriveCommandPrintsError(t *testing.T) {
commands := [][]string{
{"drive"},
{"drive", "share", "myfile.txt", "/path/to/myfile.txt"},
{"drive", "rename", "oldname.txt", "newname.txt"},
{"drive", "unshare", "myfile.txt"},
{"drive", "list"},
}
for _, args := range commands {
root := newRootCmd()
if err := root.Parse(args); err != nil {
t.Errorf("unable to parse args %q, got err %v", args, err)
continue
}
t.Logf("running `tailscale drive %q`", strings.Join(args, " "))
err := root.Run(context.Background())
if err == nil {
t.Error("expected error, but got nil", args)
}
expectedText := "Taildrive CLI commands are not supported when using the macOS GUI app."
if !strings.Contains(err.Error(), expectedText) {
t.Errorf("error was not expected: want %q, got %q", expectedText, err.Error())
}
}
}