💥 Add --dry-run and --yes to mutating subcommands

This commit is contained in:
OpenWaygate committed 2026-04-21 21:48:22 +08:00
1 parent 31ad273946
commit b55029cb27
40 files changed
+574 -76

No files matched your search

+11 -1
View File
@@ -1,9 +1,10 @@
load("@rules_go//go:def.bzl", "go_library")
load("@rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "cmd",
srcs = [
"auth.go",
"flags.go",
"mcp.go",
"root.go",
"version.go",
@@ -22,9 +23,18 @@ go_library(
"//pkg",
"//pkg/auth",
"//pkg/common",
"//pkg/utils",
"@com_github_eat_pray_ai_cobra_mcp//:cobra-mcp",
"@com_github_modelcontextprotocol_go_sdk//oauthex",
"@com_github_savioxavier_termlink//:termlink",
"@com_github_spf13_cobra//:cobra",
"@org_golang_x_term//:term",
],
)
go_test(
name = "cmd_test",
srcs = ["flags_test.go"],
embed = [":cmd"],
deps = ["@com_github_spf13_cobra//:cobra"],
)
+9 -2
View File
@@ -5,6 +5,7 @@ package caption
import (
"io"
"strings"
cobramcp "github.com/eat-pray-ai/cobra-mcp"
"github.com/eat-pray-ai/yutu/cmd"
@@ -65,6 +66,7 @@ func init() {
)
_ = deleteCmd.MarkFlagRequired("ids")
cmd.AddMutationFlags(deleteCmd)
}
var deleteCmd = &cobra.Command{
@@ -72,12 +74,17 @@ var deleteCmd = &cobra.Command{
Short: deleteShort,
Long: deleteLong,
Example: deleteExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would delete caption(s): %s", strings.Join(ids, ", "))
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := caption.NewCaption(
caption.WithIds(ids),
caption.WithOnBehalfOf(onBehalfOf),
caption.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
)
utils.HandleCmdError(input.Delete(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Delete(c.OutOrStdout()), c)
},
}
+8 -2
View File
@@ -107,6 +107,7 @@ func init() {
_ = insertCmd.MarkFlagRequired("file")
_ = insertCmd.MarkFlagRequired("videoId")
cmd.AddMutationFlags(insertCmd)
}
var insertCmd = &cobra.Command{
@@ -114,7 +115,12 @@ var insertCmd = &cobra.Command{
Short: insertShort,
Long: insertLong,
Example: insertExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would insert caption")
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := caption.NewCaption(
caption.WithFile(file),
caption.WithAudioTrackType(audioTrackType),
@@ -131,6 +137,6 @@ var insertCmd = &cobra.Command{
caption.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
caption.WithOutput(output),
)
utils.HandleCmdError(input.Insert(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Insert(c.OutOrStdout()), c)
},
}
+8 -2
View File
@@ -105,6 +105,7 @@ func init() {
updateCmd.Flags().StringVarP(&output, "output", "o", "", pkg.SilentUsage)
_ = updateCmd.MarkFlagRequired("videoId")
cmd.AddMutationFlags(updateCmd)
}
var updateCmd = &cobra.Command{
@@ -112,7 +113,12 @@ var updateCmd = &cobra.Command{
Short: updateShort,
Long: updateLong,
Example: updateExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would update caption for video: %s", videoId)
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := caption.NewCaption(
caption.WithFile(file),
caption.WithAudioTrackType(audioTrackType),
@@ -129,6 +135,6 @@ var updateCmd = &cobra.Command{
caption.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
caption.WithOutput(output),
)
utils.HandleCmdError(input.Update(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Update(c.OutOrStdout()), c)
},
}
+9 -2
View File
@@ -6,6 +6,7 @@ package channel
import (
"encoding/json"
"io"
"strings"
cobramcp "github.com/eat-pray-ai/cobra-mcp"
"github.com/eat-pray-ai/yutu/cmd"
@@ -81,6 +82,7 @@ func init() {
updateCmd.Flags().StringVarP(&output, "output", "o", "", pkg.SilentUsage)
_ = updateCmd.MarkFlagRequired("id")
cmd.AddMutationFlags(updateCmd)
}
var updateCmd = &cobra.Command{
@@ -88,7 +90,12 @@ var updateCmd = &cobra.Command{
Short: updateShort,
Long: updateLong,
Example: updateExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would update channel: %s", strings.Join(ids, ", "))
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := channel.NewChannel(
channel.WithIds(ids),
channel.WithCountry(country),
@@ -98,6 +105,6 @@ var updateCmd = &cobra.Command{
channel.WithTitle(title),
channel.WithOutput(output),
)
utils.HandleCmdError(input.Update(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Update(c.OutOrStdout()), c)
},
}
+8 -2
View File
@@ -81,6 +81,7 @@ func init() {
_ = insertCmd.MarkFlagRequired("channelId")
_ = insertCmd.MarkFlagRequired("file")
cmd.AddMutationFlags(insertCmd)
}
var insertCmd = &cobra.Command{
@@ -88,7 +89,12 @@ var insertCmd = &cobra.Command{
Short: insertShort,
Long: insertLong,
Example: insertExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would insert channel banner")
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := channelBanner.NewChannelBanner(
channelBanner.WithChannelId(channelId),
channelBanner.WithFile(file),
@@ -96,6 +102,6 @@ var insertCmd = &cobra.Command{
channelBanner.WithOnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel),
channelBanner.WithOutput(output),
)
utils.HandleCmdError(input.Insert(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Insert(c.OutOrStdout()), c)
},
}
+11 -2
View File
@@ -5,6 +5,7 @@ package channelSection
import (
"io"
"strings"
cobramcp "github.com/eat-pray-ai/cobra-mcp"
"github.com/eat-pray-ai/yutu/cmd"
@@ -64,6 +65,7 @@ func init() {
)
_ = deleteCmd.MarkFlagRequired("ids")
cmd.AddMutationFlags(deleteCmd)
}
var deleteCmd = &cobra.Command{
@@ -71,11 +73,18 @@ var deleteCmd = &cobra.Command{
Short: deleteShort,
Long: deleteLong,
Example: deleteExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(
c, "Would delete channel section(s): %s", strings.Join(ids, ", "),
)
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := channelSection.NewChannelSection(
channelSection.WithIds(ids),
channelSection.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
)
utils.HandleCmdError(input.Delete(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Delete(c.OutOrStdout()), c)
},
}
+9 -2
View File
@@ -5,6 +5,7 @@ package comment
import (
"io"
"strings"
cobramcp "github.com/eat-pray-ai/cobra-mcp"
"github.com/eat-pray-ai/yutu/cmd"
@@ -56,6 +57,7 @@ func init() {
deleteCmd.Flags().StringSliceVarP(&ids, "ids", "i", []string{}, idsUsage)
_ = deleteCmd.MarkFlagRequired("ids")
cmd.AddMutationFlags(deleteCmd)
}
var deleteCmd = &cobra.Command{
@@ -63,8 +65,13 @@ var deleteCmd = &cobra.Command{
Short: deleteShort,
Long: deleteLong,
Example: deleteExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would delete comment(s): %s", strings.Join(ids, ", "))
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := comment.NewComment(comment.WithIds(ids))
utils.HandleCmdError(input.Delete(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Delete(c.OutOrStdout()), c)
},
}
+8 -2
View File
@@ -83,6 +83,7 @@ func init() {
_ = insertCmd.MarkFlagRequired("parentId")
_ = insertCmd.MarkFlagRequired("textOriginal")
cmd.AddMutationFlags(insertCmd)
}
var insertCmd = &cobra.Command{
@@ -90,7 +91,12 @@ var insertCmd = &cobra.Command{
Short: insertShort,
Long: insertLong,
Example: insertExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would insert comment")
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := comment.NewComment(
comment.WithAuthorChannelId(authorChannelId),
comment.WithChannelId(channelId),
@@ -100,6 +106,6 @@ var insertCmd = &cobra.Command{
comment.WithVideoId(videoId),
comment.WithOutput(output),
)
utils.HandleCmdError(input.Insert(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Insert(c.OutOrStdout()), c)
},
}
+9 -2
View File
@@ -6,6 +6,7 @@ package comment
import (
"encoding/json"
"io"
"strings"
cobramcp "github.com/eat-pray-ai/cobra-mcp"
"github.com/eat-pray-ai/yutu/cmd"
@@ -64,6 +65,7 @@ func init() {
markAsSpamCmd.Flags().StringVarP(&output, "output", "o", "", pkg.SilentUsage)
_ = markAsSpamCmd.MarkFlagRequired("ids")
cmd.AddMutationFlags(markAsSpamCmd)
}
var markAsSpamCmd = &cobra.Command{
@@ -71,11 +73,16 @@ var markAsSpamCmd = &cobra.Command{
Short: masShort,
Long: masLong,
Example: masExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would mark comment(s) as spam: %s", strings.Join(ids, ", "))
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := comment.NewComment(
comment.WithIds(ids),
comment.WithOutput(output),
)
utils.HandleCmdError(input.MarkAsSpam(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.MarkAsSpam(c.OutOrStdout()), c)
},
}
+9 -2
View File
@@ -6,6 +6,7 @@ package comment
import (
"encoding/json"
"io"
"strings"
cobramcp "github.com/eat-pray-ai/cobra-mcp"
"github.com/eat-pray-ai/yutu/cmd"
@@ -83,6 +84,7 @@ func init() {
_ = setModerationStatusCmd.MarkFlagRequired("ids")
_ = setModerationStatusCmd.MarkFlagRequired("moderationStatus")
cmd.AddMutationFlags(setModerationStatusCmd)
}
var setModerationStatusCmd = &cobra.Command{
@@ -90,13 +92,18 @@ var setModerationStatusCmd = &cobra.Command{
Short: smsShort,
Long: smsLong,
Example: smsExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would set moderation status of comment(s): %s to %s", strings.Join(ids, ", "), moderationStatus)
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := comment.NewComment(
comment.WithIds(ids),
comment.WithModerationStatus(moderationStatus),
comment.WithBanAuthor(banAuthor),
comment.WithOutput(output),
)
utils.HandleCmdError(input.SetModerationStatus(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.SetModerationStatus(c.OutOrStdout()), c)
},
}
+9 -2
View File
@@ -6,6 +6,7 @@ package comment
import (
"encoding/json"
"io"
"strings"
cobramcp "github.com/eat-pray-ai/cobra-mcp"
"github.com/eat-pray-ai/yutu/cmd"
@@ -80,6 +81,7 @@ func init() {
updateCmd.Flags().StringVarP(&output, "output", "o", "", pkg.SilentUsage)
_ = updateCmd.MarkFlagRequired("id")
cmd.AddMutationFlags(updateCmd)
}
var updateCmd = &cobra.Command{
@@ -87,7 +89,12 @@ var updateCmd = &cobra.Command{
Short: updateShort,
Long: updateLong,
Example: updateExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would update comment: %s", strings.Join(ids, ", "))
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := comment.NewComment(
comment.WithIds(ids),
comment.WithCanRate(canRate),
@@ -95,6 +102,6 @@ var updateCmd = &cobra.Command{
comment.WithViewerRating(viewerRating),
comment.WithOutput(output),
)
utils.HandleCmdError(input.Update(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Update(c.OutOrStdout()), c)
},
}
+8 -2
View File
@@ -74,6 +74,7 @@ func init() {
_ = insertCmd.MarkFlagRequired("channelId")
_ = insertCmd.MarkFlagRequired("textOriginal")
_ = insertCmd.MarkFlagRequired("videoId")
cmd.AddMutationFlags(insertCmd)
}
var insertCmd = &cobra.Command{
@@ -81,7 +82,12 @@ var insertCmd = &cobra.Command{
Short: insertShort,
Long: insertLong,
Example: insertExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would insert comment thread")
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := commentThread.NewCommentThread(
commentThread.WithAuthorChannelId(authorChannelId),
commentThread.WithChannelId(channelId),
@@ -89,6 +95,6 @@ var insertCmd = &cobra.Command{
commentThread.WithVideoId(videoId),
commentThread.WithOutput(output),
)
utils.HandleCmdError(input.Insert(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Insert(c.OutOrStdout()), c)
},
}
+88
View File
@@ -0,0 +1,88 @@
// Copyright 2026 eat-pray-ai & OpenWaygate
// SPDX-License-Identifier: Apache-2.0
package cmd
import (
"bufio"
"errors"
"fmt"
"os"
"strings"
"github.com/eat-pray-ai/yutu/pkg/utils"
"github.com/spf13/cobra"
"golang.org/x/term"
)
// ErrDryRun is returned by Confirm when --dry-run is set.
var ErrDryRun = utils.ErrDryRun
// errAborted is returned by Confirm when the user declines the prompt.
var errAborted = errors.New("aborted")
// AddMutationFlags registers --dry-run and --yes on the given command.
func AddMutationFlags(cmd *cobra.Command) {
cmd.Flags().Bool(
"dry-run", false,
"Print what would happen without calling the API",
)
cmd.Flags().Bool(
"yes", false,
"Skip the confirmation prompt",
)
}
// DryRun returns whether --dry-run was passed.
func DryRun(cmd *cobra.Command) bool {
v, _ := cmd.Flags().GetBool("dry-run")
return v
}
// Confirm checks dry-run and yes flags, then prompts the user for
// confirmation if running in an interactive terminal.
//
// Returns ErrDryRun if --dry-run is set, nil if --yes is set or the user
// confirms, and errAborted if the user declines.
func Confirm(cmd *cobra.Command, format string, args ...any) error {
isTTY := term.IsTerminal(int(os.Stdin.Fd()))
return confirmWithTTYOverride(cmd, isTTY, format, args...)
}
// confirmWithTTYOverride is an internal helper that accepts a pre-computed
// isTTY value so tests can exercise the TTY and non-TTY paths without
// needing a real terminal.
func confirmWithTTYOverride(cmd *cobra.Command, isTTY bool, format string, args ...any) error {
msg := fmt.Sprintf(format, args...)
// 1. --dry-run takes precedence over everything.
if DryRun(cmd) {
fmt.Fprintln(cmd.OutOrStdout(), msg)
return ErrDryRun
}
// 2. --yes skips the prompt entirely.
yes, _ := cmd.Flags().GetBool("yes")
if yes {
return nil
}
// 3. Non-interactive stdin requires --yes.
if !isTTY {
return errors.New("terminal required for confirmation; use --yes to skip")
}
// 4. Interactive prompt.
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "%s [y/N] ", msg)
scanner := bufio.NewScanner(cmd.InOrStdin())
if !scanner.Scan() {
return errAborted
}
answer := strings.TrimSpace(scanner.Text())
if answer == "y" || answer == "Y" {
return nil
}
return errAborted
}
+173
View File
@@ -0,0 +1,173 @@
// Copyright 2026 eat-pray-ai & OpenWaygate
// SPDX-License-Identifier: Apache-2.0
package cmd
import (
"bytes"
"errors"
"strings"
"testing"
"github.com/spf13/cobra"
)
// newTestCmd creates a minimal cobra.Command with mutation flags registered.
func newTestCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "test",
Run: func(cmd *cobra.Command, args []string) {},
}
AddMutationFlags(cmd)
return cmd
}
func TestAddMutationFlags(t *testing.T) {
cmd := newTestCmd()
dr := cmd.Flags().Lookup("dry-run")
if dr == nil {
t.Fatal("expected --dry-run flag to be registered")
}
if dr.DefValue != "false" {
t.Fatalf("expected --dry-run default to be false, got %s", dr.DefValue)
}
yes := cmd.Flags().Lookup("yes")
if yes == nil {
t.Fatal("expected --yes flag to be registered")
}
if yes.DefValue != "false" {
t.Fatalf("expected --yes default to be false, got %s", yes.DefValue)
}
}
func TestDryRun_DefaultFalse(t *testing.T) {
cmd := newTestCmd()
if DryRun(cmd) {
t.Fatal("expected DryRun to be false by default")
}
}
func TestDryRun_SetTrue(t *testing.T) {
cmd := newTestCmd()
if err := cmd.Flags().Set("dry-run", "true"); err != nil {
t.Fatal(err)
}
if !DryRun(cmd) {
t.Fatal("expected DryRun to be true after setting flag")
}
}
func TestConfirm_DryRun(t *testing.T) {
cmd := newTestCmd()
if err := cmd.Flags().Set("dry-run", "true"); err != nil {
t.Fatal(err)
}
var stdout bytes.Buffer
cmd.SetOut(&stdout)
err := Confirm(cmd, "would delete %s", "video123")
if !errors.Is(err, ErrDryRun) {
t.Fatalf("expected ErrDryRun, got %v", err)
}
got := stdout.String()
if !strings.Contains(got, "would delete video123") {
t.Fatalf("expected message in stdout, got %q", got)
}
}
func TestConfirm_Yes(t *testing.T) {
cmd := newTestCmd()
if err := cmd.Flags().Set("yes", "true"); err != nil {
t.Fatal(err)
}
err := Confirm(cmd, "delete video?")
if err != nil {
t.Fatalf("expected nil, got %v", err)
}
}
func TestConfirm_NonTTY(t *testing.T) {
cmd := newTestCmd()
cmd.SetIn(strings.NewReader(""))
// Use the internal helper with isTTY=false to simulate non-TTY stdin.
err := confirmWithTTYOverride(cmd, false, "delete video?")
if err == nil {
t.Fatal("expected error for non-TTY stdin")
}
if !strings.Contains(
err.Error(), "terminal required for confirmation; use --yes to skip",
) {
t.Fatalf("unexpected error message: %v", err)
}
}
func TestConfirm_TTY_Yes(t *testing.T) {
cmd := newTestCmd()
cmd.SetIn(strings.NewReader("y\n"))
var stderr bytes.Buffer
cmd.SetErr(&stderr)
err := confirmWithTTYOverride(cmd, true, "delete %s?", "video123")
if err != nil {
t.Fatalf("expected nil, got %v", err)
}
prompt := stderr.String()
if !strings.Contains(prompt, "delete video123?") {
t.Fatalf("expected prompt on stderr, got %q", prompt)
}
if !strings.Contains(prompt, "[y/N]") {
t.Fatalf("expected [y/N] in prompt, got %q", prompt)
}
}
func TestConfirm_TTY_No(t *testing.T) {
cmd := newTestCmd()
cmd.SetIn(strings.NewReader("n\n"))
var stderr bytes.Buffer
cmd.SetErr(&stderr)
err := confirmWithTTYOverride(cmd, true, "delete video?")
if !errors.Is(err, errAborted) {
t.Fatalf("expected errAborted, got %v", err)
}
}
func TestConfirm_TTY_Default(t *testing.T) {
cmd := newTestCmd()
cmd.SetIn(strings.NewReader("\n"))
var stderr bytes.Buffer
cmd.SetErr(&stderr)
err := confirmWithTTYOverride(cmd, true, "delete video?")
if !errors.Is(err, errAborted) {
t.Fatalf("expected errAborted for empty input (default N), got %v", err)
}
}
func TestConfirm_DryRunTakesPrecedence(t *testing.T) {
cmd := newTestCmd()
if err := cmd.Flags().Set("dry-run", "true"); err != nil {
t.Fatal(err)
}
if err := cmd.Flags().Set("yes", "true"); err != nil {
t.Fatal(err)
}
var stdout bytes.Buffer
cmd.SetOut(&stdout)
err := Confirm(cmd, "would delete video")
if !errors.Is(err, ErrDryRun) {
t.Fatalf("expected ErrDryRun even with --yes, got %v", err)
}
}
+9 -2
View File
@@ -5,6 +5,7 @@ package playlist
import (
"io"
"strings"
cobramcp "github.com/eat-pray-ai/cobra-mcp"
"github.com/eat-pray-ai/yutu/cmd"
@@ -63,6 +64,7 @@ func init() {
)
_ = deleteCmd.MarkFlagRequired("ids")
cmd.AddMutationFlags(deleteCmd)
}
var deleteCmd = &cobra.Command{
@@ -70,11 +72,16 @@ var deleteCmd = &cobra.Command{
Short: deleteShort,
Long: deleteLong,
Example: deleteExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would delete playlist(s): %s", strings.Join(ids, ", "))
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := playlist.NewPlaylist(
playlist.WithIds(ids),
playlist.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
)
utils.HandleCmdError(input.Delete(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Delete(c.OutOrStdout()), c)
},
}
+8 -2
View File
@@ -82,6 +82,7 @@ func init() {
_ = insertCmd.MarkFlagRequired("title")
_ = insertCmd.MarkFlagRequired("channelId")
_ = insertCmd.MarkFlagRequired("privacy")
cmd.AddMutationFlags(insertCmd)
}
var insertCmd = &cobra.Command{
@@ -89,7 +90,12 @@ var insertCmd = &cobra.Command{
Short: insertShort,
Long: insertLong,
Example: insertExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would insert playlist")
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := playlist.NewPlaylist(
playlist.WithTitle(title),
playlist.WithDescription(description),
@@ -99,6 +105,6 @@ var insertCmd = &cobra.Command{
playlist.WithPrivacy(privacy),
playlist.WithOutput(output),
)
utils.HandleCmdError(input.Insert(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Insert(c.OutOrStdout()), c)
},
}
+10 -3
View File
@@ -6,6 +6,7 @@ package playlist
import (
"encoding/json"
"io"
"strings"
cobramcp "github.com/eat-pray-ai/cobra-mcp"
"github.com/eat-pray-ai/yutu/cmd"
@@ -85,6 +86,7 @@ func init() {
updateCmd.Flags().StringVarP(&output, "output", "o", "", pkg.SilentUsage)
_ = updateCmd.MarkFlagRequired("id")
cmd.AddMutationFlags(updateCmd)
}
var updateCmd = &cobra.Command{
@@ -92,7 +94,12 @@ var updateCmd = &cobra.Command{
Short: updateShort,
Long: updateLong,
Example: updateExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
confirmErr := cmd.Confirm(c, "Would update playlist: %s", strings.Join(ids, ", "))
if confirmErr != nil {
utils.HandleCmdError(confirmErr, c)
return
}
p := playlist.NewPlaylist(
playlist.WithIds(ids),
playlist.WithTitle(title),
@@ -102,7 +109,7 @@ var updateCmd = &cobra.Command{
playlist.WithPrivacy(privacy),
playlist.WithOutput(output),
)
err := p.Update(cmd.OutOrStdout())
utils.HandleCmdError(err, cmd)
err := p.Update(c.OutOrStdout())
utils.HandleCmdError(err, c)
},
}
+11 -2
View File
@@ -5,6 +5,7 @@ package playlistImage
import (
"io"
"strings"
cobramcp "github.com/eat-pray-ai/cobra-mcp"
"github.com/eat-pray-ai/yutu/cmd"
@@ -63,6 +64,7 @@ func init() {
)
_ = deleteCmd.MarkFlagRequired("ids")
cmd.AddMutationFlags(deleteCmd)
}
var deleteCmd = &cobra.Command{
@@ -70,11 +72,18 @@ var deleteCmd = &cobra.Command{
Short: deleteShort,
Long: deleteLong,
Example: deleteExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(
c, "Would delete playlist image(s): %s", strings.Join(ids, ", "),
)
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := playlistImage.NewPlaylistImage(
playlistImage.WithIds(ids),
playlistImage.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
)
utils.HandleCmdError(input.Delete(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Delete(c.OutOrStdout()), c)
},
}
+9 -3
View File
@@ -94,6 +94,7 @@ func init() {
_ = insertCmd.MarkFlagRequired("file")
_ = insertCmd.MarkFlagRequired("playlistId")
cmd.AddMutationFlags(insertCmd)
}
var insertCmd = &cobra.Command{
@@ -101,7 +102,12 @@ var insertCmd = &cobra.Command{
Short: insertShort,
Long: insertLong,
Example: insertExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
confirmErr := cmd.Confirm(c, "Would insert playlist image")
if confirmErr != nil {
utils.HandleCmdError(confirmErr, c)
return
}
pi := playlistImage.NewPlaylistImage(
playlistImage.WithFile(file),
playlistImage.WithPlaylistId(playlistId),
@@ -112,7 +118,7 @@ var insertCmd = &cobra.Command{
playlistImage.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
playlistImage.WithOnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel),
)
err := pi.Insert(cmd.OutOrStdout())
utils.HandleCmdError(err, cmd)
err := pi.Insert(c.OutOrStdout())
utils.HandleCmdError(err, c)
},
}
+10 -2
View File
@@ -87,6 +87,7 @@ func init() {
)
_ = updateCmd.MarkFlagRequired("playlistId")
cmd.AddMutationFlags(updateCmd)
}
var updateCmd = &cobra.Command{
@@ -94,7 +95,14 @@ var updateCmd = &cobra.Command{
Short: updateShort,
Long: updateLong,
Example: updateExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(
c, "Would update playlist image for playlist: %s", playlistId,
)
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := playlistImage.NewPlaylistImage(
playlistImage.WithPlaylistId(playlistId),
playlistImage.WithType(type_),
@@ -105,6 +113,6 @@ var updateCmd = &cobra.Command{
playlistImage.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
playlistImage.WithOnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel),
)
utils.HandleCmdError(input.Update(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Update(c.OutOrStdout()), c)
},
}
+11 -2
View File
@@ -5,6 +5,7 @@ package playlistItem
import (
"io"
"strings"
cobramcp "github.com/eat-pray-ai/cobra-mcp"
"github.com/eat-pray-ai/yutu/cmd"
@@ -63,6 +64,7 @@ func init() {
)
_ = deleteCmd.MarkFlagRequired("ids")
cmd.AddMutationFlags(deleteCmd)
}
var deleteCmd = &cobra.Command{
@@ -70,11 +72,18 @@ var deleteCmd = &cobra.Command{
Short: deleteShort,
Long: deleteLong,
Example: deleteExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(
c, "Would delete playlist item(s): %s", strings.Join(ids, ", "),
)
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := playlistItem.NewPlaylistItem(
playlistItem.WithIds(ids),
playlistItem.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
)
utils.HandleCmdError(input.Delete(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Delete(c.OutOrStdout()), c)
},
}
+8 -2
View File
@@ -92,6 +92,7 @@ func init() {
_ = insertCmd.MarkFlagRequired("kind")
_ = insertCmd.MarkFlagRequired("playlistId")
_ = insertCmd.MarkFlagRequired("channelId")
cmd.AddMutationFlags(insertCmd)
}
var insertCmd = &cobra.Command{
@@ -99,7 +100,12 @@ var insertCmd = &cobra.Command{
Short: insertShort,
Long: insertLong,
Example: insertExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would insert playlist item")
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := playlistItem.NewPlaylistItem(
playlistItem.WithTitle(title),
playlistItem.WithDescription(description),
@@ -113,6 +119,6 @@ var insertCmd = &cobra.Command{
playlistItem.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
playlistItem.WithOutput(output),
)
utils.HandleCmdError(input.Insert(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Insert(c.OutOrStdout()), c)
},
}
+11 -2
View File
@@ -6,6 +6,7 @@ package playlistItem
import (
"encoding/json"
"io"
"strings"
cobramcp "github.com/eat-pray-ai/cobra-mcp"
"github.com/eat-pray-ai/yutu/cmd"
@@ -80,6 +81,7 @@ func init() {
updateCmd.Flags().StringVarP(&output, "output", "o", "", pkg.SilentUsage)
_ = updateCmd.MarkFlagRequired("id")
cmd.AddMutationFlags(updateCmd)
}
var updateCmd = &cobra.Command{
@@ -87,7 +89,14 @@ var updateCmd = &cobra.Command{
Short: updateShort,
Long: updateLong,
Example: updateExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(
c, "Would update playlist item: %s", strings.Join(ids, ", "),
)
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := playlistItem.NewPlaylistItem(
playlistItem.WithIds(ids),
playlistItem.WithTitle(title),
@@ -96,6 +105,6 @@ var updateCmd = &cobra.Command{
playlistItem.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
playlistItem.WithOutput(output),
)
utils.HandleCmdError(input.Update(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Update(c.OutOrStdout()), c)
},
}
+9 -2
View File
@@ -5,6 +5,7 @@ package subscription
import (
"io"
"strings"
cobramcp "github.com/eat-pray-ai/cobra-mcp"
"github.com/eat-pray-ai/yutu/cmd"
@@ -57,6 +58,7 @@ func init() {
deleteCmd.Flags().StringSliceVarP(&ids, "ids", "i", []string{}, deleteIdsUsage)
_ = deleteCmd.MarkFlagRequired("ids")
cmd.AddMutationFlags(deleteCmd)
}
var deleteCmd = &cobra.Command{
@@ -64,10 +66,15 @@ var deleteCmd = &cobra.Command{
Short: deleteShort,
Long: deleteLong,
Example: deleteExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would delete subscription(s): %s", strings.Join(ids, ", "))
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := subscription.NewSubscription(
subscription.WithIds(ids),
)
utils.HandleCmdError(input.Delete(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Delete(c.OutOrStdout()), c)
},
}
+8 -2
View File
@@ -71,6 +71,7 @@ func init() {
_ = insertCmd.MarkFlagRequired("subscriberChannelId")
_ = insertCmd.MarkFlagRequired("channelId")
cmd.AddMutationFlags(insertCmd)
}
var insertCmd = &cobra.Command{
@@ -78,7 +79,12 @@ var insertCmd = &cobra.Command{
Short: insertShort,
Long: insertLong,
Example: insertExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would insert subscription")
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := subscription.NewSubscription(
subscription.WithSubscriberChannelId(subscriberChannelId),
subscription.WithDescription(description),
@@ -86,6 +92,6 @@ var insertCmd = &cobra.Command{
subscription.WithTitle(title),
subscription.WithOutput(output),
)
utils.HandleCmdError(input.Insert(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Insert(c.OutOrStdout()), c)
},
}
+8 -2
View File
@@ -64,6 +64,7 @@ func init() {
_ = setCmd.MarkFlagRequired("file")
_ = setCmd.MarkFlagRequired("videoId")
cmd.AddMutationFlags(setCmd)
}
var setCmd = &cobra.Command{
@@ -71,12 +72,17 @@ var setCmd = &cobra.Command{
Short: setShort,
Long: setLong,
Example: setExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would set thumbnail for video: %s", videoId)
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := thumbnail.NewThumbnail(
thumbnail.WithFile(file),
thumbnail.WithVideoId(videoId),
thumbnail.WithOutput(output),
)
utils.HandleCmdError(input.Set(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Set(c.OutOrStdout()), c)
},
}
+9 -2
View File
@@ -5,6 +5,7 @@ package video
import (
"io"
"strings"
cobramcp "github.com/eat-pray-ai/cobra-mcp"
"github.com/eat-pray-ai/yutu/cmd"
@@ -57,6 +58,7 @@ func init() {
deleteCmd.Flags().StringSliceVarP(&ids, "ids", "i", []string{}, deleteIdsUsage)
_ = deleteCmd.MarkFlagRequired("ids")
cmd.AddMutationFlags(deleteCmd)
}
var deleteCmd = &cobra.Command{
@@ -64,8 +66,13 @@ var deleteCmd = &cobra.Command{
Short: deleteShort,
Long: deleteLong,
Example: deleteExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would delete video(s): %s", strings.Join(ids, ", "))
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := video.NewVideo(video.WithIds(ids))
utils.HandleCmdError(input.Delete(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Delete(c.OutOrStdout()), c)
},
}
+8 -2
View File
@@ -139,6 +139,7 @@ func init() {
_ = insertCmd.MarkFlagRequired("file")
_ = insertCmd.MarkFlagRequired("categoryId")
_ = insertCmd.MarkFlagRequired("privacy")
cmd.AddMutationFlags(insertCmd)
}
var insertCmd = &cobra.Command{
@@ -146,7 +147,12 @@ var insertCmd = &cobra.Command{
Short: insertShort,
Long: insertLong,
Example: insertExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would insert video")
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := video.NewVideo(
video.WithAutoLevels(autoLevels),
video.WithFile(file),
@@ -172,6 +178,6 @@ var insertCmd = &cobra.Command{
video.WithOnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel),
video.WithOutput(output),
)
utils.HandleCmdError(input.Insert(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Insert(c.OutOrStdout()), c)
},
}
+9 -2
View File
@@ -5,6 +5,7 @@ package video
import (
"io"
"strings"
cobramcp "github.com/eat-pray-ai/cobra-mcp"
"github.com/eat-pray-ai/yutu/cmd"
@@ -67,6 +68,7 @@ func init() {
_ = rateCmd.MarkFlagRequired("ids")
_ = rateCmd.MarkFlagRequired("rating")
cmd.AddMutationFlags(rateCmd)
}
var rateCmd = &cobra.Command{
@@ -74,11 +76,16 @@ var rateCmd = &cobra.Command{
Short: rateShort,
Long: rateLong,
Example: rateExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would rate video(s): %s as %s", strings.Join(ids, ", "), rating)
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := video.NewVideo(
video.WithIds(ids),
video.WithRating(rating),
)
utils.HandleCmdError(input.Rate(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Rate(c.OutOrStdout()), c)
},
}
+9 -2
View File
@@ -5,6 +5,7 @@ package video
import (
"io"
"strings"
cobramcp "github.com/eat-pray-ai/cobra-mcp"
"github.com/eat-pray-ai/yutu/cmd"
@@ -82,6 +83,7 @@ func init() {
_ = reportAbuseCmd.MarkFlagRequired("ids")
_ = reportAbuseCmd.MarkFlagRequired("reasonId")
cmd.AddMutationFlags(reportAbuseCmd)
}
var reportAbuseCmd = &cobra.Command{
@@ -89,7 +91,12 @@ var reportAbuseCmd = &cobra.Command{
Short: reportAbuseShort,
Long: reportAbuseLong,
Example: reportAbuseExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would report abuse on video(s): %s", strings.Join(ids, ", "))
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := video.NewVideo(
video.WithIds(ids),
video.WithReasonId(reasonId),
@@ -98,6 +105,6 @@ var reportAbuseCmd = &cobra.Command{
video.WithLanguage(language),
video.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
)
utils.HandleCmdError(input.ReportAbuse(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.ReportAbuse(c.OutOrStdout()), c)
},
}
+9 -2
View File
@@ -6,6 +6,7 @@ package video
import (
"encoding/json"
"io"
"strings"
cobramcp "github.com/eat-pray-ai/cobra-mcp"
"github.com/eat-pray-ai/yutu/cmd"
@@ -106,6 +107,7 @@ func init() {
updateCmd.Flags().StringVarP(&output, "output", "o", "", pkg.SilentUsage)
_ = updateCmd.MarkFlagRequired("id")
cmd.AddMutationFlags(updateCmd)
}
var updateCmd = &cobra.Command{
@@ -113,7 +115,12 @@ var updateCmd = &cobra.Command{
Short: updateShort,
Long: updateLong,
Example: updateExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would update video: %s", strings.Join(ids, ", "))
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := video.NewVideo(
video.WithIds(ids),
video.WithTitle(title),
@@ -131,6 +138,6 @@ var updateCmd = &cobra.Command{
video.WithMaxResults(1),
video.WithOutput(output),
)
utils.HandleCmdError(input.Update(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Update(c.OutOrStdout()), c)
},
}
+8 -2
View File
@@ -80,6 +80,7 @@ func init() {
_ = setCmd.MarkFlagRequired("channelId")
_ = setCmd.MarkFlagRequired("file")
cmd.AddMutationFlags(setCmd)
}
var setCmd = &cobra.Command{
@@ -87,7 +88,12 @@ var setCmd = &cobra.Command{
Short: setShort,
Long: setLong,
Example: setExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would set watermark for channel: %s", channelId)
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := watermark.NewWatermark(
watermark.WithChannelId(channelId),
watermark.WithFile(file),
@@ -97,6 +103,6 @@ var setCmd = &cobra.Command{
watermark.WithOffsetType(offsetType),
watermark.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
)
utils.HandleCmdError(input.Set(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Set(c.OutOrStdout()), c)
},
}
+8 -2
View File
@@ -51,6 +51,7 @@ func init() {
unsetCmd.Flags().StringVarP(&channelId, "channelId", "c", "", cidUsage)
_ = unsetCmd.MarkFlagRequired("channelId")
cmd.AddMutationFlags(unsetCmd)
}
var unsetCmd = &cobra.Command{
@@ -58,8 +59,13 @@ var unsetCmd = &cobra.Command{
Short: unsetShort,
Long: unsetLong,
Example: unsetExample,
Run: func(cmd *cobra.Command, args []string) {
Run: func(c *cobra.Command, args []string) {
err := cmd.Confirm(c, "Would unset watermark for channel: %s", channelId)
if err != nil {
utils.HandleCmdError(err, c)
return
}
input := watermark.NewWatermark(watermark.WithChannelId(channelId))
utils.HandleCmdError(input.Unset(cmd.OutOrStdout()), cmd)
utils.HandleCmdError(input.Unset(c.OutOrStdout()), c)
},
}
+1 -3
View File
@@ -20,7 +20,6 @@ require (
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
@@ -35,7 +34,6 @@ require (
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect
github.com/mattn/go-runewidth v0.0.23 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/segmentio/asm v1.2.1 // indirect
github.com/segmentio/encoding v0.5.4 // indirect
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
@@ -52,10 +50,10 @@ require (
go.opentelemetry.io/otel/sdk/log v0.19.0 // indirect
go.opentelemetry.io/otel/trace v1.43.0 // indirect
go.opentelemetry.io/proto/otlp v1.10.0 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/crypto v0.49.0 // indirect
golang.org/x/net v0.52.0 // indirect
golang.org/x/sync v0.20.0 // indirect
golang.org/x/term v0.42.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260406210006-6f92a3bedf2d // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d // indirect
google.golang.org/grpc v1.80.0 // indirect
+2 -4
View File
@@ -19,8 +19,6 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk=
github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo=
github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/eat-pray-ai/cobra-mcp v0.1.0 h1:szHIgFhCH0HqWSRRlyVVWzrB+3c9SMNfQCxlKA4lNLo=
@@ -74,7 +72,6 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/savioxavier/termlink v1.4.3 h1:Gh6vrG7jSn21cRiYdQqFXYcdXfM+Fg14aG487JTfKpA=
github.com/savioxavier/termlink v1.4.3/go.mod h1:5T5ePUlWbxCHIwyF8/Ez1qufOoGM89RCg9NvG+3G3gc=
@@ -123,7 +120,6 @@ go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpu
go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=
golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA=
@@ -135,6 +131,8 @@ golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY=
golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
+1 -1
View File
@@ -7,8 +7,8 @@ go_library(
visibility = ["//visibility:private"],
deps = [
"//cmd",
"//cmd/agent",
"//cmd/activity",
"//cmd/agent",
"//cmd/caption",
"//cmd/channel",
"//cmd/channelBanner",
+3
View File
@@ -1,3 +1,6 @@
// Copyright 2026 eat-pray-ai & OpenWaygate
// SPDX-License-Identifier: Apache-2.0
package auth
import (
+8 -3
View File
@@ -7,6 +7,7 @@ import (
"crypto/rand"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io"
"os/exec"
@@ -99,9 +100,13 @@ func ExtractHl(uri string) string {
return ""
}
// ErrDryRun is returned when --dry-run is set; HandleCmdError silently ignores it.
var ErrDryRun = errors.New("dry run")
func HandleCmdError(err error, cmd *cobra.Command) {
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
if err == nil || errors.Is(err, ErrDryRun) {
return
}
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
+10
View File
@@ -331,6 +331,16 @@ func TestRandomStage(t *testing.T) {
}
}
func TestHandleCmdError_DryRun(t *testing.T) {
c := &cobra.Command{Use: "test"}
var stderr bytes.Buffer
c.SetErr(&stderr)
HandleCmdError(ErrDryRun, c)
if stderr.Len() != 0 {
t.Errorf("expected no error output for ErrDryRun, got %q", stderr.String())
}
}
func TestHandleCmdError(t *testing.T) {
tests := []struct {
name string