Skip to content

Commit

Permalink
Extend Sprintf to allow formatting a slice
Browse files Browse the repository at this point in the history
  • Loading branch information
keegancsmith committed Feb 8, 2016
1 parent 1d6f3a2 commit ccb53e0
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 0 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,15 @@ fmt.Println(remoteCmd)
// Output: ssh ubuntu@foo.com 'find . -iname '\''*.go'\'' | wc -l'
```

Also slightly extends `Sprintf` syntax to allow easily passing in slices. This
is a common use case when interacting with commands that take in a list of
arguments:

```go
// Support for passing in a slice of arguments
gitcmd := shell.Sprintf("git add %S", []string{"foo.go", "bar.go", "test data"})
fmt.Println(gitcmd)
// Output: git add foo.go bar.go 'test data'
```

See https://godoc.org/github.com/keegancsmith/shell for more information.
17 changes: 17 additions & 0 deletions command.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import (
"fmt"
"io"
"os/exec"
"reflect"
"strings"
"unicode"
)

// Commandf runs a shell command based on the format string
Expand Down Expand Up @@ -38,6 +41,20 @@ func (e escapable) Format(f fmt.State, c rune) {
if p, ok := f.Precision(); ok {
s += fmt.Sprintf(".%d", p)
}
// If we have an uppercase format char and a slice, format each slice
// element
if unicode.IsUpper(c) && reflect.TypeOf(e.x).Kind() == reflect.Slice {
s += strings.ToLower(string(c))
v := reflect.ValueOf(e.x)
for i := 0; i < v.Len(); i++ {
formatted := fmt.Sprintf(s, v.Index(i))
io.WriteString(f, ReadableEscapeArg(formatted))
if i+1 != v.Len() {
io.WriteString(f, " ")
}
}
return
}
s += string(c)
formatted := fmt.Sprintf(s, e.x)
io.WriteString(f, ReadableEscapeArg(formatted))
Expand Down
7 changes: 7 additions & 0 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ func ExampleSprintf() {
// Output: ssh ubuntu@foo.com 'find . -iname '\''*.go'\'' | wc -l'
}

func ExampleSprintf_StringSlice() {
// Support for passing in a slice of arguments
gitcmd := shell.Sprintf("git add %S", []string{"foo.go", "bar.go", "test data"})
fmt.Println(gitcmd)
// Output: git add foo.go bar.go 'test data'
}

func ExampleCommandf() {
out, err := shell.Commandf("echo %s", "hello world").Output()
if err != nil {
Expand Down

0 comments on commit ccb53e0

Please sign in to comment.