From 23bb79978fcd42387dac099e442749b133ad3305 Mon Sep 17 00:00:00 2001 From: Ram Bhardwaj Date: Sun, 17 May 2026 19:46:48 +0530 Subject: [PATCH] fix(replication): support positional log arguments Signed-off-by: Ram Bhardwaj --- cmd/harbor/root/replication/logs.go | 40 +++++++- cmd/harbor/root/replication/logs_test.go | 107 +++++++++++++++++++++ doc/cli-docs/harbor-replication-log.md | 5 +- doc/man-docs/man1/harbor-replication-log.1 | 5 +- 4 files changed, 149 insertions(+), 8 deletions(-) create mode 100644 cmd/harbor/root/replication/logs_test.go diff --git a/cmd/harbor/root/replication/logs.go b/cmd/harbor/root/replication/logs.go index 1d8442a4e..7e4987ca7 100644 --- a/cmd/harbor/root/replication/logs.go +++ b/cmd/harbor/root/replication/logs.go @@ -15,6 +15,7 @@ package replication import ( "fmt" + "strconv" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -31,12 +32,17 @@ func LogsCommand() *cobra.Command { Use: "log [EXECUTION_ID] [TASK_ID]", Short: "get replication execution logs by execution and task id", Long: `Get the logs of a specific replication execution and task by their IDs. If no IDs are provided, it will prompt the user to select them interactively.`, - Example: ` harbor replication log -e 12345 -t 67890 - harbor replication log --execution-id 12345 --task-id 67890 - harbor replication log --execution-id 12345 + Example: ` harbor replication log 12345 67890 + harbor replication log -e 12345 -t 67890 + harbor replication log --execution-id 12345 --task-id 67890 + harbor replication log --execution-id 12345 harbor replication log`, - Args: cobra.MaximumNArgs(0), + Args: cobra.MaximumNArgs(2), RunE: func(cmd *cobra.Command, args []string) error { + if err := applyLogArgs(args, &execID, &taskID); err != nil { + return err + } + if execID != 0 && taskID == 0 { taskID = prompt.GetReplicationTaskIDFromUser(execID) } else if execID == 0 && taskID == 0 { @@ -73,3 +79,29 @@ func LogsCommand() *cobra.Command { return cmd } + +func applyLogArgs(args []string, execID, taskID *int64) error { + var err error + + if len(args) > 0 { + if *execID != 0 { + return fmt.Errorf("execution ID cannot be provided both as a flag and an argument") + } + *execID, err = strconv.ParseInt(args[0], 10, 64) + if err != nil { + return fmt.Errorf("invalid replication execution ID %q: %w", args[0], err) + } + } + + if len(args) > 1 { + if *taskID != 0 { + return fmt.Errorf("task ID cannot be provided both as a flag and an argument") + } + *taskID, err = strconv.ParseInt(args[1], 10, 64) + if err != nil { + return fmt.Errorf("invalid replication task ID %q: %w", args[1], err) + } + } + + return nil +} diff --git a/cmd/harbor/root/replication/logs_test.go b/cmd/harbor/root/replication/logs_test.go new file mode 100644 index 000000000..79b370d86 --- /dev/null +++ b/cmd/harbor/root/replication/logs_test.go @@ -0,0 +1,107 @@ +// Copyright Project Harbor Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package replication + +import ( + "strings" + "testing" +) + +func TestLogsCommandAcceptsAdvertisedPositionalArgs(t *testing.T) { + cmd := LogsCommand() + + if err := cmd.Args(cmd, []string{"123", "456"}); err != nil { + t.Fatalf("expected two positional args to be accepted, got %v", err) + } + + if err := cmd.Args(cmd, []string{"123", "456", "789"}); err == nil { + t.Fatal("expected more than two positional args to be rejected") + } +} + +func TestApplyLogArgs(t *testing.T) { + tests := []struct { + name string + args []string + execID int64 + taskID int64 + wantExec int64 + wantTask int64 + wantError string + }{ + { + name: "execution and task IDs", + args: []string{"123", "456"}, + wantExec: 123, + wantTask: 456, + }, + { + name: "execution ID only", + args: []string{"123"}, + wantExec: 123, + }, + { + name: "invalid execution ID", + args: []string{"abc"}, + wantError: "invalid replication execution ID", + }, + { + name: "invalid task ID", + args: []string{"123", "abc"}, + wantError: "invalid replication task ID", + }, + { + name: "execution ID flag and argument conflict", + args: []string{"123"}, + execID: 99, + wantExec: 99, + wantError: "execution ID cannot be provided both as a flag and an argument", + }, + { + name: "task ID flag and argument conflict", + args: []string{"123", "456"}, + taskID: 99, + wantExec: 123, + wantTask: 99, + wantError: "task ID cannot be provided both as a flag and an argument", + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + execID := tc.execID + taskID := tc.taskID + + err := applyLogArgs(tc.args, &execID, &taskID) + if tc.wantError != "" { + if err == nil { + t.Fatalf("expected error containing %q", tc.wantError) + } + if !strings.Contains(err.Error(), tc.wantError) { + t.Fatalf("expected error containing %q, got %v", tc.wantError, err) + } + return + } + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + if execID != tc.wantExec { + t.Fatalf("expected execution ID %d, got %d", tc.wantExec, execID) + } + if taskID != tc.wantTask { + t.Fatalf("expected task ID %d, got %d", tc.wantTask, taskID) + } + }) + } +} diff --git a/doc/cli-docs/harbor-replication-log.md b/doc/cli-docs/harbor-replication-log.md index 683e1a85e..60687e452 100644 --- a/doc/cli-docs/harbor-replication-log.md +++ b/doc/cli-docs/harbor-replication-log.md @@ -19,9 +19,10 @@ harbor replication log [EXECUTION_ID] [TASK_ID] [flags] ### Examples ```sh + harbor replication log 12345 67890 harbor replication log -e 12345 -t 67890 - harbor replication log --execution-id 12345 --task-id 67890 - harbor replication log --execution-id 12345 + harbor replication log --execution-id 12345 --task-id 67890 + harbor replication log --execution-id 12345 harbor replication log ``` diff --git a/doc/man-docs/man1/harbor-replication-log.1 b/doc/man-docs/man1/harbor-replication-log.1 index 3c207c42a..887bfa117 100644 --- a/doc/man-docs/man1/harbor-replication-log.1 +++ b/doc/man-docs/man1/harbor-replication-log.1 @@ -41,9 +41,10 @@ Get the logs of a specific replication execution and task by their IDs. If no ID .SH EXAMPLE .EX + harbor replication log 12345 67890 harbor replication log -e 12345 -t 67890 - harbor replication log --execution-id 12345 --task-id 67890 - harbor replication log --execution-id 12345 + harbor replication log --execution-id 12345 --task-id 67890 + harbor replication log --execution-id 12345 harbor replication log .EE