mirror of
https://github.com/mikefarah/yq.git
synced 2024-12-19 20:19:04 +00:00
Adds @uri/@urid #1529
This commit is contained in:
parent
dd6cf3df14
commit
6d7d76a3f1
@ -15,6 +15,7 @@ const (
|
|||||||
JsonInputFormat
|
JsonInputFormat
|
||||||
CSVObjectInputFormat
|
CSVObjectInputFormat
|
||||||
TSVObjectInputFormat
|
TSVObjectInputFormat
|
||||||
|
UriInputFormat
|
||||||
)
|
)
|
||||||
|
|
||||||
type Decoder interface {
|
type Decoder interface {
|
||||||
|
60
pkg/yqlib/decoder_uri.go
Normal file
60
pkg/yqlib/decoder_uri.go
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
package yqlib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
yaml "gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
type uriDecoder struct {
|
||||||
|
reader io.Reader
|
||||||
|
finished bool
|
||||||
|
readAnything bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUriDecoder() Decoder {
|
||||||
|
return &uriDecoder{finished: false}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dec *uriDecoder) Init(reader io.Reader) error {
|
||||||
|
dec.reader = reader
|
||||||
|
dec.readAnything = false
|
||||||
|
dec.finished = false
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dec *uriDecoder) Decode() (*CandidateNode, error) {
|
||||||
|
if dec.finished {
|
||||||
|
return nil, io.EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
|
||||||
|
if _, err := buf.ReadFrom(dec.reader); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if buf.Len() == 0 {
|
||||||
|
dec.finished = true
|
||||||
|
|
||||||
|
// if we've read _only_ an empty string, lets return that
|
||||||
|
// otherwise if we've already read some bytes, and now we get
|
||||||
|
// an empty string, then we are done.
|
||||||
|
if dec.readAnything {
|
||||||
|
return nil, io.EOF
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newValue, err := url.QueryUnescape(buf.String())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dec.readAnything = true
|
||||||
|
return &CandidateNode{
|
||||||
|
Node: &yaml.Node{
|
||||||
|
Kind: yaml.ScalarNode,
|
||||||
|
Tag: "!!str",
|
||||||
|
Value: newValue,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
@ -16,6 +16,7 @@ These operators are useful to process yaml documents that have stringified embed
|
|||||||
| TSV | from_tsv/@tsvd | to_tsv/@tsv |
|
| TSV | from_tsv/@tsvd | to_tsv/@tsv |
|
||||||
| XML | from_xml/@xmld | to_xml(i)/@xml |
|
| XML | from_xml/@xmld | to_xml(i)/@xml |
|
||||||
| Base64 | @base64d | @base64 |
|
| Base64 | @base64d | @base64 |
|
||||||
|
| URI | @urid | @uri |
|
||||||
|
|
||||||
|
|
||||||
See CSV and TSV [documentation](https://mikefarah.gitbook.io/yq/usage/csv-tsv) for accepted formats.
|
See CSV and TSV [documentation](https://mikefarah.gitbook.io/yq/usage/csv-tsv) for accepted formats.
|
||||||
@ -435,6 +436,34 @@ will output
|
|||||||
YTogYXBwbGUK
|
YTogYXBwbGUK
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Encode a string to uri
|
||||||
|
Given a sample.yml file of:
|
||||||
|
```yaml
|
||||||
|
coolData: this has & special () characters *
|
||||||
|
```
|
||||||
|
then
|
||||||
|
```bash
|
||||||
|
yq '.coolData | @uri' sample.yml
|
||||||
|
```
|
||||||
|
will output
|
||||||
|
```yaml
|
||||||
|
this+has+%26+special+%28%29+characters+%2A
|
||||||
|
```
|
||||||
|
|
||||||
|
## Decode a URI to a string
|
||||||
|
Given a sample.yml file of:
|
||||||
|
```yaml
|
||||||
|
this+has+%26+special+%28%29+characters+%2A
|
||||||
|
```
|
||||||
|
then
|
||||||
|
```bash
|
||||||
|
yq '@urid' sample.yml
|
||||||
|
```
|
||||||
|
will output
|
||||||
|
```yaml
|
||||||
|
this has & special () characters *
|
||||||
|
```
|
||||||
|
|
||||||
## Decode a base64 encoded string
|
## Decode a base64 encoded string
|
||||||
Decoded data is assumed to be a string.
|
Decoded data is assumed to be a string.
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ These operators are useful to process yaml documents that have stringified embed
|
|||||||
| TSV | from_tsv/@tsvd | to_tsv/@tsv |
|
| TSV | from_tsv/@tsvd | to_tsv/@tsv |
|
||||||
| XML | from_xml/@xmld | to_xml(i)/@xml |
|
| XML | from_xml/@xmld | to_xml(i)/@xml |
|
||||||
| Base64 | @base64d | @base64 |
|
| Base64 | @base64d | @base64 |
|
||||||
|
| URI | @urid | @uri |
|
||||||
|
|
||||||
|
|
||||||
See CSV and TSV [documentation](https://mikefarah.gitbook.io/yq/usage/csv-tsv) for accepted formats.
|
See CSV and TSV [documentation](https://mikefarah.gitbook.io/yq/usage/csv-tsv) for accepted formats.
|
||||||
|
37
pkg/yqlib/encoder_uri.go
Normal file
37
pkg/yqlib/encoder_uri.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package yqlib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
yaml "gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
type uriEncoder struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUriEncoder() Encoder {
|
||||||
|
return &uriEncoder{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *uriEncoder) CanHandleAliases() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *uriEncoder) PrintDocumentSeparator(writer io.Writer) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *uriEncoder) PrintLeadingContent(writer io.Writer, content string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *uriEncoder) Encode(writer io.Writer, originalNode *yaml.Node) error {
|
||||||
|
node := unwrapDoc(originalNode)
|
||||||
|
if guessTagFromCustomType(node) != "!!str" {
|
||||||
|
return fmt.Errorf("cannot encode %v as url, can only operate on strings. Please first pipe through another encoding operator to convert the value to a string", node.Tag)
|
||||||
|
}
|
||||||
|
_, err := writer.Write([]byte(url.QueryEscape(originalNode.Value)))
|
||||||
|
return err
|
||||||
|
}
|
@ -78,6 +78,9 @@ var participleYqRules = []*participleYqRule{
|
|||||||
{"Base64d", `@base64d`, decodeOp(Base64InputFormat), 0},
|
{"Base64d", `@base64d`, decodeOp(Base64InputFormat), 0},
|
||||||
{"Base64", `@base64`, encodeWithIndent(Base64OutputFormat, 0), 0},
|
{"Base64", `@base64`, encodeWithIndent(Base64OutputFormat, 0), 0},
|
||||||
|
|
||||||
|
{"Urld", `@urid`, decodeOp(UriInputFormat), 0},
|
||||||
|
{"Url", `@uri`, encodeWithIndent(UriOutputFormat, 0), 0},
|
||||||
|
|
||||||
{"LoadXML", `load_?xml|xml_?load`, loadOp(NewXMLDecoder(ConfiguredXMLPreferences), false), 0},
|
{"LoadXML", `load_?xml|xml_?load`, loadOp(NewXMLDecoder(ConfiguredXMLPreferences), false), 0},
|
||||||
|
|
||||||
{"LoadBase64", `load_?base64`, loadOp(NewBase64Decoder(), false), 0},
|
{"LoadBase64", `load_?base64`, loadOp(NewBase64Decoder(), false), 0},
|
||||||
|
@ -26,6 +26,8 @@ func configureEncoder(format PrinterOutputFormat, indent int) Encoder {
|
|||||||
return NewXMLEncoder(indent, ConfiguredXMLPreferences)
|
return NewXMLEncoder(indent, ConfiguredXMLPreferences)
|
||||||
case Base64OutputFormat:
|
case Base64OutputFormat:
|
||||||
return NewBase64Encoder()
|
return NewBase64Encoder()
|
||||||
|
case UriOutputFormat:
|
||||||
|
return NewUriEncoder()
|
||||||
}
|
}
|
||||||
panic("invalid encoder")
|
panic("invalid encoder")
|
||||||
}
|
}
|
||||||
@ -113,6 +115,8 @@ func decodeOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
|
|||||||
decoder = NewCSVObjectDecoder(',')
|
decoder = NewCSVObjectDecoder(',')
|
||||||
case TSVObjectInputFormat:
|
case TSVObjectInputFormat:
|
||||||
decoder = NewCSVObjectDecoder('\t')
|
decoder = NewCSVObjectDecoder('\t')
|
||||||
|
case UriInputFormat:
|
||||||
|
decoder = NewUriDecoder()
|
||||||
}
|
}
|
||||||
|
|
||||||
var results = list.New()
|
var results = list.New()
|
||||||
|
@ -241,6 +241,22 @@ var encoderDecoderOperatorScenarios = []expressionScenario{
|
|||||||
"D0, P[], (!!str)::YTogYXBwbGUK\n",
|
"D0, P[], (!!str)::YTogYXBwbGUK\n",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
description: "Encode a string to uri",
|
||||||
|
document: "coolData: this has & special () characters *",
|
||||||
|
expression: ".coolData | @uri",
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[coolData], (!!str)::this+has+%26+special+%28%29+characters+%2A\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Decode a URI to a string",
|
||||||
|
document: "this+has+%26+special+%28%29+characters+%2A",
|
||||||
|
expression: "@urid",
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[], (!!str)::this has & special () characters *\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
description: "Decode a base64 encoded string",
|
description: "Decode a base64 encoded string",
|
||||||
subdescription: "Decoded data is assumed to be a string.",
|
subdescription: "Decoded data is assumed to be a string.",
|
||||||
|
@ -27,6 +27,7 @@ const (
|
|||||||
TSVOutputFormat
|
TSVOutputFormat
|
||||||
XMLOutputFormat
|
XMLOutputFormat
|
||||||
Base64OutputFormat
|
Base64OutputFormat
|
||||||
|
UriOutputFormat
|
||||||
)
|
)
|
||||||
|
|
||||||
func OutputFormatFromString(format string) (PrinterOutputFormat, error) {
|
func OutputFormatFromString(format string) (PrinterOutputFormat, error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user