diff --git a/cmd/genautocomplete/genautocomplete_bash.go b/cmd/genautocomplete/genautocomplete_bash.go index 63660e283..f371d690c 100644 --- a/cmd/genautocomplete/genautocomplete_bash.go +++ b/cmd/genautocomplete/genautocomplete_bash.go @@ -2,6 +2,7 @@ package genautocomplete import ( "log" + "os" "github.com/rclone/rclone/cmd" "github.com/spf13/cobra" @@ -29,11 +30,20 @@ them directly If you supply a command line argument the script will be written there. + +If output_file is "-", then the output will be written to stdout. `, Run: func(command *cobra.Command, args []string) { cmd.CheckArgs(0, 1, command, args) out := "/etc/bash_completion.d/rclone" if len(args) > 0 { + if args[0] == "-" { + err := cmd.Root.GenBashCompletion(os.Stdout) + if err != nil { + log.Fatal(err) + } + return + } out = args[0] } err := cmd.Root.GenBashCompletionFile(out) diff --git a/cmd/genautocomplete/genautocomplete_fish.go b/cmd/genautocomplete/genautocomplete_fish.go index edb327b8b..a60230c40 100644 --- a/cmd/genautocomplete/genautocomplete_fish.go +++ b/cmd/genautocomplete/genautocomplete_fish.go @@ -2,6 +2,7 @@ package genautocomplete import ( "log" + "os" "github.com/rclone/rclone/cmd" "github.com/spf13/cobra" @@ -29,11 +30,20 @@ them directly If you supply a command line argument the script will be written there. + +If output_file is "-", then the output will be written to stdout. `, Run: func(command *cobra.Command, args []string) { cmd.CheckArgs(0, 1, command, args) out := "/etc/fish/completions/rclone.fish" if len(args) > 0 { + if args[0] == "-" { + err := cmd.Root.GenFishCompletion(os.Stdout, true) + if err != nil { + log.Fatal(err) + } + return + } out = args[0] } err := cmd.Root.GenFishCompletionFile(out, true) diff --git a/cmd/genautocomplete/genautocomplete_test.go b/cmd/genautocomplete/genautocomplete_test.go index e97ad1169..ce766c6fd 100644 --- a/cmd/genautocomplete/genautocomplete_test.go +++ b/cmd/genautocomplete/genautocomplete_test.go @@ -11,8 +11,10 @@ import ( func TestCompletionBash(t *testing.T) { tempFile, err := ioutil.TempFile("", "completion_bash") assert.NoError(t, err) - defer func() { _ = tempFile.Close() }() - defer func() { _ = os.Remove(tempFile.Name()) }() + defer func() { + _ = tempFile.Close() + _ = os.Remove(tempFile.Name()) + }() bashCommandDefinition.Run(bashCommandDefinition, []string{tempFile.Name()}) @@ -21,11 +23,32 @@ func TestCompletionBash(t *testing.T) { assert.NotEmpty(t, string(bs)) } +func TestCompletionBashStdout(t *testing.T) { + originalStdout := os.Stdout + tempFile, err := ioutil.TempFile("", "completion_zsh") + assert.NoError(t, err) + defer func() { + _ = tempFile.Close() + _ = os.Remove(tempFile.Name()) + }() + + os.Stdout = tempFile + defer func() { os.Stdout = originalStdout }() + + bashCommandDefinition.Run(bashCommandDefinition, []string{"-"}) + + output, err := ioutil.ReadFile(tempFile.Name()) + assert.NoError(t, err) + assert.NotEmpty(t, string(output)) +} + func TestCompletionZsh(t *testing.T) { tempFile, err := ioutil.TempFile("", "completion_zsh") assert.NoError(t, err) - defer func() { _ = tempFile.Close() }() - defer func() { _ = os.Remove(tempFile.Name()) }() + defer func() { + _ = tempFile.Close() + _ = os.Remove(tempFile.Name()) + }() zshCommandDefinition.Run(zshCommandDefinition, []string{tempFile.Name()}) @@ -34,11 +57,31 @@ func TestCompletionZsh(t *testing.T) { assert.NotEmpty(t, string(bs)) } +func TestCompletionZshStdout(t *testing.T) { + originalStdout := os.Stdout + tempFile, err := ioutil.TempFile("", "completion_zsh") + assert.NoError(t, err) + defer func() { + _ = tempFile.Close() + _ = os.Remove(tempFile.Name()) + }() + + os.Stdout = tempFile + defer func() { os.Stdout = originalStdout }() + + zshCommandDefinition.Run(zshCommandDefinition, []string{"-"}) + output, err := ioutil.ReadFile(tempFile.Name()) + assert.NoError(t, err) + assert.NotEmpty(t, string(output)) +} + func TestCompletionFish(t *testing.T) { tempFile, err := ioutil.TempFile("", "completion_fish") assert.NoError(t, err) - defer func() { _ = tempFile.Close() }() - defer func() { _ = os.Remove(tempFile.Name()) }() + defer func() { + _ = tempFile.Close() + _ = os.Remove(tempFile.Name()) + }() fishCommandDefinition.Run(fishCommandDefinition, []string{tempFile.Name()}) @@ -46,3 +89,22 @@ func TestCompletionFish(t *testing.T) { assert.NoError(t, err) assert.NotEmpty(t, string(bs)) } + +func TestCompletionFishStdout(t *testing.T) { + originalStdout := os.Stdout + tempFile, err := ioutil.TempFile("", "completion_zsh") + assert.NoError(t, err) + defer func() { + _ = tempFile.Close() + _ = os.Remove(tempFile.Name()) + }() + + os.Stdout = tempFile + defer func() { os.Stdout = originalStdout }() + + fishCommandDefinition.Run(fishCommandDefinition, []string{"-"}) + + output, err := ioutil.ReadFile(tempFile.Name()) + assert.NoError(t, err) + assert.NotEmpty(t, string(output)) +} diff --git a/cmd/genautocomplete/genautocomplete_zsh.go b/cmd/genautocomplete/genautocomplete_zsh.go index 0d635506d..6a2c1c4a0 100644 --- a/cmd/genautocomplete/genautocomplete_zsh.go +++ b/cmd/genautocomplete/genautocomplete_zsh.go @@ -30,11 +30,20 @@ them directly If you supply a command line argument the script will be written there. + +If output_file is "-", then the output will be written to stdout. `, Run: func(command *cobra.Command, args []string) { cmd.CheckArgs(0, 1, command, args) out := "/usr/share/zsh/vendor-completions/_rclone" if len(args) > 0 { + if args[0] == "-" { + err := cmd.Root.GenZshCompletion(os.Stdout) + if err != nil { + log.Fatal(err) + } + return + } out = args[0] } outFile, err := os.Create(out) diff --git a/docs/content/commands/rclone_genautocomplete_bash.md b/docs/content/commands/rclone_genautocomplete_bash.md index 72dc7cc21..27928c680 100644 --- a/docs/content/commands/rclone_genautocomplete_bash.md +++ b/docs/content/commands/rclone_genautocomplete_bash.md @@ -27,6 +27,7 @@ them directly If you supply a command line argument the script will be written there. +If output_file is `-`, then the output will be written to stdout. ``` rclone genautocomplete bash [output_file] [flags] diff --git a/docs/content/commands/rclone_genautocomplete_fish.md b/docs/content/commands/rclone_genautocomplete_fish.md index 8d9a122ed..d9ba9706c 100644 --- a/docs/content/commands/rclone_genautocomplete_fish.md +++ b/docs/content/commands/rclone_genautocomplete_fish.md @@ -27,6 +27,7 @@ them directly If you supply a command line argument the script will be written there. +If output_file is `-`, then the output will be written to stdout. ``` rclone genautocomplete fish [output_file] [flags] diff --git a/docs/content/commands/rclone_genautocomplete_zsh.md b/docs/content/commands/rclone_genautocomplete_zsh.md index 6816f7dde..e31df0726 100644 --- a/docs/content/commands/rclone_genautocomplete_zsh.md +++ b/docs/content/commands/rclone_genautocomplete_zsh.md @@ -27,6 +27,7 @@ them directly If you supply a command line argument the script will be written there. +If output_file is `-`, then the output will be written to stdout. ``` rclone genautocomplete zsh [output_file] [flags] diff --git a/go.sum b/go.sum index 4b5ec2d63..e5abaa4a5 100644 --- a/go.sum +++ b/go.sum @@ -400,6 +400,7 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=