Skip to content

Commit

Permalink
implement format string sh (ref: #2)
Browse files Browse the repository at this point in the history
  • Loading branch information
itchyny committed Jan 5, 2020
1 parent d664364 commit f9c09ad
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 0 deletions.
16 changes: 16 additions & 0 deletions cli/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3294,6 +3294,22 @@
error: |
invalid tsv row: array (["foo"])
- name: format strings @sh
args:
- '@sh'
input: |
[1, "f'o'o", null, false]
expected: |
"1 'f'\\''o'\\''o' null false"
- name: format strings @sh error
args:
- '@sh'
input: |
[{}]
error: |
cannot escape for shell: object ({})
- name: format strings @base64
args:
- '@base64'
Expand Down
2 changes: 2 additions & 0 deletions compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,8 @@ func formatToFunc(fmt string) *Func {
return &Func{Name: "_tocsv"}
case "@tsv":
return &Func{Name: "_totsv"}
case "@sh":
return &Func{Name: "_tosh"}
case "@base64":
return &Func{Name: "_tobase64"}
case "@base64d":
Expand Down
8 changes: 8 additions & 0 deletions error.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,14 @@ func (err *formatCsvTsvRowError) Error() string {
return fmt.Sprintf("invalid %s row: %s", err.typ, typeErrorPreview(err.v))
}

type formatShError struct {
v interface{}
}

func (err *formatShError) Error() string {
return fmt.Sprintf("cannot escape for shell: %s", typeErrorPreview(err.v))
}

var errTooManyVariables = errors.New("too many variables provided")

type expectedVariableError struct {
Expand Down
30 changes: 30 additions & 0 deletions func.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ func init() {
"_touri": argFunc0(funcToURI),
"_tocsv": argFunc0(funcToCSV),
"_totsv": argFunc0(funcToTSV),
"_tosh": argFunc0(funcToSh),
"_tobase64": argFunc0(funcToBase64),
"_tobase64d": argFunc0(funcToBase64d),
"_index": argFunc2(funcIndex),
Expand Down Expand Up @@ -521,6 +522,35 @@ func funcToTSV(v interface{}) interface{} {
})
}

func funcToSh(v interface{}) interface{} {
var xs []interface{}
if w, ok := v.([]interface{}); ok {
xs = w
} else {
xs = []interface{}{v}
}
var s strings.Builder
for i, x := range xs {
if i > 0 {
s.WriteByte(' ')
}
switch x := x.(type) {
case map[string]interface{}, []interface{}:
return &formatShError{x}
case string:
s.WriteString("'" + strings.ReplaceAll(x, "'", `'\''`) + "'")
default:
switch v := funcToJSON(x).(type) {
case error:
return v
case string:
s.WriteString(v)
}
}
}
return s.String()
}

func funcToCSVTSV(typ string, v interface{}, sep string, escape func(string) string) interface{} {
switch xs := v.(type) {
case []interface{}:
Expand Down

0 comments on commit f9c09ad

Please sign in to comment.