mirror of
				https://github.com/TomWright/dasel.git
				synced 2022-05-22 02:32:45 +03:00 
			
		
		
		
	Merge pull request #168 from TomWright/json-escape
Add --escape-html flag
This commit is contained in:
		| @@ -7,7 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | ||||
|  | ||||
| ## [Unreleased] | ||||
|  | ||||
| - Nothing yet. | ||||
| ### Added | ||||
| - `--escape-html` flag. | ||||
|  | ||||
| ### Fixed | ||||
| - `put document` and `put object` are now aware of the `--merge-input-documents` flag. | ||||
|  | ||||
| ## [v1.20.1] - 2021-08-28 | ||||
|  | ||||
|   | ||||
| @@ -20,6 +20,7 @@ type deleteOptions struct { | ||||
| 	Compact             bool | ||||
| 	MergeInputDocuments bool | ||||
| 	Out                 string | ||||
| 	EscapeHTML          bool | ||||
| } | ||||
|  | ||||
| func runDeleteMultiCommand(cmd *cobra.Command, rootNode *dasel.Node, opts deleteOptions, writeParser storage.WriteParser, writeOptions []storage.ReadWriteOption) error { | ||||
| @@ -78,7 +79,9 @@ func runDeleteCommand(opts deleteOptions, cmd *cobra.Command) error { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	writeOptions := make([]storage.ReadWriteOption, 0) | ||||
| 	writeOptions := []storage.ReadWriteOption{ | ||||
| 		storage.EscapeHTMLOption(opts.EscapeHTML), | ||||
| 	} | ||||
|  | ||||
| 	if opts.Compact { | ||||
| 		writeOptions = append(writeOptions, storage.PrettyPrintOption(false)) | ||||
| @@ -121,7 +124,7 @@ func runDeleteCommand(opts deleteOptions, cmd *cobra.Command) error { | ||||
|  | ||||
| func deleteCommand() *cobra.Command { | ||||
| 	var fileFlag, selectorFlag, parserFlag, readParserFlag, writeParserFlag, outFlag string | ||||
| 	var plainFlag, multiFlag, compactFlag, mergeInputDocumentsFlag bool | ||||
| 	var plainFlag, multiFlag, compactFlag, mergeInputDocumentsFlag, escapeHTMLFlag bool | ||||
|  | ||||
| 	cmd := &cobra.Command{ | ||||
| 		Use:   "delete -f <file> -p <json,yaml> -s <selector>", | ||||
| @@ -144,6 +147,7 @@ func deleteCommand() *cobra.Command { | ||||
| 				Compact:             compactFlag, | ||||
| 				MergeInputDocuments: mergeInputDocumentsFlag, | ||||
| 				Out:                 outFlag, | ||||
| 				EscapeHTML:          escapeHTMLFlag, | ||||
| 			}, cmd) | ||||
| 		}, | ||||
| 	} | ||||
| @@ -157,6 +161,7 @@ func deleteCommand() *cobra.Command { | ||||
| 	cmd.Flags().BoolVarP(&multiFlag, "multiple", "m", false, "Delete multiple results.") | ||||
| 	cmd.Flags().BoolVar(&mergeInputDocumentsFlag, "merge-input-documents", false, "Merge multiple input documents into an array.") | ||||
| 	cmd.Flags().BoolVarP(&compactFlag, "compact", "c", false, "Compact the output by removing all pretty-printing where possible.") | ||||
| 	cmd.Flags().BoolVar(&escapeHTMLFlag, "escape-html", true, "Escape HTML tags when writing output.") | ||||
| 	cmd.Flags().StringVarP(&outFlag, "out", "o", "", "Output destination.") | ||||
|  | ||||
| 	_ = cmd.MarkFlagFilename("file") | ||||
|   | ||||
| @@ -291,7 +291,7 @@ func getOutputWriter(cmd *cobra.Command, in io.Writer, file string, out string) | ||||
|  | ||||
| func putCommand() *cobra.Command { | ||||
| 	var fileFlag, selectorFlag, parserFlag, readParserFlag, writeParserFlag, outFlag, valueFlag string | ||||
| 	var multiFlag, compactFlag, mergeInputDocumentsFlag bool | ||||
| 	var multiFlag, compactFlag, mergeInputDocumentsFlag, escapeHTMLFlag bool | ||||
|  | ||||
| 	cmd := &cobra.Command{ | ||||
| 		Use:   "put -f <file> -s <selector>", | ||||
| @@ -316,6 +316,7 @@ func putCommand() *cobra.Command { | ||||
| 	cmd.PersistentFlags().BoolVarP(&compactFlag, "compact", "c", false, "Compact the output by removing all pretty-printing where possible.") | ||||
| 	cmd.PersistentFlags().BoolVar(&mergeInputDocumentsFlag, "merge-input-documents", false, "Merge multiple input documents into an array.") | ||||
| 	cmd.PersistentFlags().StringVarP(&valueFlag, "value", "v", "", "Value to put.") | ||||
| 	cmd.PersistentFlags().BoolVar(&escapeHTMLFlag, "escape-html", true, "Escape HTML tags when writing output.") | ||||
|  | ||||
| 	_ = cmd.MarkPersistentFlagFilename("file") | ||||
|  | ||||
| @@ -337,6 +338,7 @@ type genericPutOptions struct { | ||||
| 	Multi               bool | ||||
| 	Compact             bool | ||||
| 	MergeInputDocuments bool | ||||
| 	EscapeHTML          bool | ||||
| } | ||||
|  | ||||
| func getGenericInit(cmd *cobra.Command, args []string) func(options genericPutOptions) genericPutOptions { | ||||
| @@ -351,6 +353,7 @@ func getGenericInit(cmd *cobra.Command, args []string) func(options genericPutOp | ||||
| 		opts.Compact, _ = cmd.Flags().GetBool("compact") | ||||
| 		opts.MergeInputDocuments, _ = cmd.Flags().GetBool("merge-input-documents") | ||||
| 		opts.Value, _ = cmd.Flags().GetString("value") | ||||
| 		opts.EscapeHTML, _ = cmd.Flags().GetBool("escape-html") | ||||
|  | ||||
| 		if opts.Selector == "" && len(args) > 0 { | ||||
| 			opts.Selector = args[0] | ||||
| @@ -404,7 +407,9 @@ func runGenericPutCommand(opts genericPutOptions, cmd *cobra.Command) error { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	writeOptions := make([]storage.ReadWriteOption, 0) | ||||
| 	writeOptions := []storage.ReadWriteOption{ | ||||
| 		storage.EscapeHTMLOption(opts.EscapeHTML), | ||||
| 	} | ||||
|  | ||||
| 	if opts.Compact { | ||||
| 		writeOptions = append(writeOptions, storage.PrettyPrintOption(false)) | ||||
|   | ||||
| @@ -21,6 +21,7 @@ type putDocumentOpts struct { | ||||
| 	Multi               bool | ||||
| 	Compact             bool | ||||
| 	MergeInputDocuments bool | ||||
| 	EscapeHTML          bool | ||||
| } | ||||
|  | ||||
| func runPutDocumentCommand(opts putDocumentOpts, cmd *cobra.Command) error { | ||||
| @@ -63,7 +64,9 @@ func runPutDocumentCommand(opts putDocumentOpts, cmd *cobra.Command) error { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	writeOptions := make([]storage.ReadWriteOption, 0) | ||||
| 	writeOptions := []storage.ReadWriteOption{ | ||||
| 		storage.EscapeHTMLOption(opts.EscapeHTML), | ||||
| 	} | ||||
|  | ||||
| 	if opts.Compact { | ||||
| 		writeOptions = append(writeOptions, storage.PrettyPrintOption(false)) | ||||
| @@ -102,6 +105,8 @@ func putDocumentCommand() *cobra.Command { | ||||
| 			opts.Multi, _ = cmd.Flags().GetBool("multiple") | ||||
| 			opts.Compact, _ = cmd.Flags().GetBool("compact") | ||||
| 			opts.DocumentString, _ = cmd.Flags().GetString("value") | ||||
| 			opts.MergeInputDocuments, _ = cmd.Flags().GetBool("merge-input-documents") | ||||
| 			opts.EscapeHTML, _ = cmd.Flags().GetBool("escape-html") | ||||
|  | ||||
| 			if opts.Selector == "" && len(args) > 0 { | ||||
| 				opts.Selector = args[0] | ||||
|   | ||||
| @@ -23,6 +23,7 @@ type putObjectOpts struct { | ||||
| 	Multi               bool | ||||
| 	Compact             bool | ||||
| 	MergeInputDocuments bool | ||||
| 	EscapeHTML          bool | ||||
| } | ||||
|  | ||||
| func getMapFromTypesValues(inputTypes []string, inputValues []string) (map[string]interface{}, error) { | ||||
| @@ -81,7 +82,9 @@ func runPutObjectCommand(opts putObjectOpts, cmd *cobra.Command) error { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	writeOptions := make([]storage.ReadWriteOption, 0) | ||||
| 	writeOptions := []storage.ReadWriteOption{ | ||||
| 		storage.EscapeHTMLOption(opts.EscapeHTML), | ||||
| 	} | ||||
|  | ||||
| 	if opts.Compact { | ||||
| 		writeOptions = append(writeOptions, storage.PrettyPrintOption(false)) | ||||
| @@ -120,6 +123,8 @@ func putObjectCommand() *cobra.Command { | ||||
| 			} | ||||
| 			opts.Multi, _ = cmd.Flags().GetBool("multiple") | ||||
| 			opts.Compact, _ = cmd.Flags().GetBool("compact") | ||||
| 			opts.MergeInputDocuments, _ = cmd.Flags().GetBool("merge-input-documents") | ||||
| 			opts.EscapeHTML, _ = cmd.Flags().GetBool("escape-html") | ||||
|  | ||||
| 			if opts.Selector == "" && len(opts.InputValues) > 0 { | ||||
| 				opts.Selector = opts.InputValues[0] | ||||
|   | ||||
| @@ -163,4 +163,21 @@ func TestRootCmd_Delete_JSON(t *testing.T) { | ||||
| 	t.Run("RootArray", deleteTest(`[1, 2, 3]`, "json", ".", newline(`[]`), nil)) | ||||
| 	t.Run("RootArrayMulti", deleteTest(`[1, 2, 3]`, "json", ".", newline(`[]`), nil, "-m")) | ||||
|  | ||||
| 	t.Run("DeleteStringEscapeHTMLOn", deleteTest(`{ | ||||
|   "name": "Tom", | ||||
|   "user": "Tom <contact@tomwright.me>" | ||||
| } | ||||
| `, "json", `.name`, `{ | ||||
|   "user": "Tom \u003ccontact@tomwright.me\u003e" | ||||
| } | ||||
| `, nil, "--escape-html=true")) | ||||
|  | ||||
| 	t.Run("DeleteStringEscapeHTMLOff", deleteTest(`{ | ||||
|   "name": "Tom", | ||||
|   "user": "Tom <contact@tomwright.me>" | ||||
| } | ||||
| `, "json", `.name`, `{ | ||||
|   "user": "Tom <contact@tomwright.me>" | ||||
| } | ||||
| `, nil, "--escape-html=false")) | ||||
| } | ||||
|   | ||||
| @@ -688,6 +688,54 @@ foo: true | ||||
|   "id": -1 | ||||
| } | ||||
| `, nil, "put", "int", "-p", "json", "-v", "-1", "-s", ".id")) | ||||
|  | ||||
| 	t.Run("PutStringEscapeHTMLOn", putStringTest(`{ | ||||
|   "user": "Old" | ||||
| } | ||||
| `, "json", `.user`, `Tom <contact@tomwright.me>`, `{ | ||||
|   "user": "Tom \u003ccontact@tomwright.me\u003e" | ||||
| } | ||||
| `, nil, "--escape-html=true")) | ||||
|  | ||||
| 	t.Run("PutStringEscapeHTMLOff", putStringTest(`{ | ||||
|   "user": "Tom <contact@tomwright.me>" | ||||
| } | ||||
| `, "json", `.user`, `Tom <contact@tomwright.me>`, `{ | ||||
|   "user": "Tom <contact@tomwright.me>" | ||||
| } | ||||
| `, nil, "--escape-html=false")) | ||||
|  | ||||
| 	t.Run("PutObjectEscapeHTMLOn", putObjectTest(`{ | ||||
|   "user": "Old" | ||||
| } | ||||
| `, "json", `.`, []string{`user=Tom <contact@tomwright.me>`}, []string{"string"}, `{ | ||||
|   "user": "Tom \u003ccontact@tomwright.me\u003e" | ||||
| } | ||||
| `, nil, "--escape-html=true")) | ||||
|  | ||||
| 	t.Run("PutObjectEscapeHTMLOff", putObjectTest(`{ | ||||
|   "user": "Old" | ||||
| } | ||||
| `, "json", `.`, []string{`user=Tom <contact@tomwright.me>`}, []string{"string"}, `{ | ||||
|   "user": "Tom <contact@tomwright.me>" | ||||
| } | ||||
| `, nil, "--escape-html=false")) | ||||
|  | ||||
| 	t.Run("PutDocumentEscapeHTMLOn", putDocumentTest(`{ | ||||
|   "user": "Old" | ||||
| } | ||||
| `, "json", `.`, `{"user": "Tom <contact@tomwright.me>"}`, `{ | ||||
|   "user": "Tom \u003ccontact@tomwright.me\u003e" | ||||
| } | ||||
| `, nil, "--escape-html=true")) | ||||
|  | ||||
| 	t.Run("PutDocumentEscapeHTMLOff", putDocumentTest(`{ | ||||
|   "user": "Tom <contact@tomwright.me>" | ||||
| } | ||||
| `, "json", `.`, `{"user": "Tom <contact@tomwright.me>"}`, `{ | ||||
|   "user": "Tom <contact@tomwright.me>" | ||||
| } | ||||
| `, nil, "--escape-html=false")) | ||||
| } | ||||
|  | ||||
| func TestRootCMD_Put_YAML(t *testing.T) { | ||||
|   | ||||
| @@ -477,6 +477,22 @@ func TestRootCmd_Select_JSON(t *testing.T) { | ||||
| ] | ||||
| `, nil, "--merge-input-documents")) | ||||
|  | ||||
| 	t.Run("EscapeHTMLOn", selectTest(`{ | ||||
|   "user": "Tom <contact@tomwright.me>" | ||||
| } | ||||
| `, "json", `.`, `{ | ||||
|   "user": "Tom \u003ccontact@tomwright.me\u003e" | ||||
| } | ||||
| `, nil, "--escape-html=true")) | ||||
|  | ||||
| 	t.Run("EscapeHTMLOff", selectTest(`{ | ||||
|   "user": "Tom <contact@tomwright.me>" | ||||
| } | ||||
| `, "json", `.`, `{ | ||||
|   "user": "Tom <contact@tomwright.me>" | ||||
| } | ||||
| `, nil, "--escape-html=false")) | ||||
|  | ||||
| } | ||||
|  | ||||
| func TestRootCmd_Select_YAML(t *testing.T) { | ||||
|   | ||||
| @@ -24,6 +24,7 @@ type selectOptions struct { | ||||
| 	MergeInputDocuments bool | ||||
| 	FormatTemplate      string | ||||
| 	Colourise           bool | ||||
| 	EscapeHTML          bool | ||||
| } | ||||
|  | ||||
| func outputNodeLength(writer io.Writer, nodes ...*dasel.Node) error { | ||||
| @@ -114,7 +115,9 @@ func runSelectCommand(opts selectOptions, cmd *cobra.Command) error { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	writeOptions := make([]storage.ReadWriteOption, 0) | ||||
| 	writeOptions := []storage.ReadWriteOption{ | ||||
| 		storage.EscapeHTMLOption(opts.EscapeHTML), | ||||
| 	} | ||||
|  | ||||
| 	if opts.Compact { | ||||
| 		writeOptions = append(writeOptions, storage.PrettyPrintOption(false)) | ||||
| @@ -170,7 +173,8 @@ func runSelectCommand(opts selectOptions, cmd *cobra.Command) error { | ||||
|  | ||||
| func selectCommand() *cobra.Command { | ||||
| 	var fileFlag, selectorFlag, parserFlag, readParserFlag, writeParserFlag, formatTemplateFlag string | ||||
| 	var plainFlag, multiFlag, nullValueNotFoundFlag, compactFlag, lengthFlag, mergeInputDocumentsFlag, colourFlag, colorFlag bool | ||||
| 	var plainFlag, multiFlag, nullValueNotFoundFlag, compactFlag, lengthFlag, mergeInputDocumentsFlag, | ||||
| 		colourFlag, colorFlag, escapeHTMLFlag bool | ||||
|  | ||||
| 	cmd := &cobra.Command{ | ||||
| 		Use:   "select -f <file> -p <json,yaml> -s <selector>", | ||||
| @@ -196,6 +200,7 @@ func selectCommand() *cobra.Command { | ||||
| 				MergeInputDocuments: mergeInputDocumentsFlag, | ||||
| 				FormatTemplate:      formatTemplateFlag, | ||||
| 				Colourise:           colourFlag || colorFlag, | ||||
| 				EscapeHTML:          escapeHTMLFlag, | ||||
| 			}, cmd) | ||||
| 		}, | ||||
| 	} | ||||
| @@ -214,6 +219,7 @@ func selectCommand() *cobra.Command { | ||||
| 	cmd.Flags().StringVar(&formatTemplateFlag, "format", "", "Formatting template to use when writing results.") | ||||
| 	cmd.Flags().BoolVar(&colourFlag, "colour", false, "Print colourised output.") | ||||
| 	cmd.Flags().BoolVar(&colorFlag, "color", false, "Alias of --colour.") | ||||
| 	cmd.Flags().BoolVar(&escapeHTMLFlag, "escape-html", true, "Escape HTML tags when writing output.") | ||||
|  | ||||
| 	_ = cmd.MarkFlagFilename("file") | ||||
|  | ||||
|   | ||||
| @@ -66,6 +66,10 @@ func (p *JSONParser) ToBytes(value interface{}, options ...ReadWriteOption) ([]b | ||||
| 			if value, ok := o.Value.(bool); ok { | ||||
| 				colourise = value | ||||
| 			} | ||||
| 		case OptionEscapeHTML: | ||||
| 			if value, ok := o.Value.(bool); ok { | ||||
| 				encoder.SetEscapeHTML(value) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -24,6 +24,14 @@ func ColouriseOption(enabled bool) ReadWriteOption { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // EscapeHTMLOption returns an option that enables or disables HTML escaping. | ||||
| func EscapeHTMLOption(enabled bool) ReadWriteOption { | ||||
| 	return ReadWriteOption{ | ||||
| 		Key:   OptionEscapeHTML, | ||||
| 		Value: enabled, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // OptionKey is a defined type for keys within a ReadWriteOption. | ||||
| type OptionKey string | ||||
|  | ||||
| @@ -34,6 +42,8 @@ const ( | ||||
| 	OptionPrettyPrint OptionKey = "prettyPrint" | ||||
| 	// OptionColourise is the key used with ColouriseOption. | ||||
| 	OptionColourise OptionKey = "colourise" | ||||
| 	// OptionEscapeHTML is the key used with EscapeHTMLOption. | ||||
| 	OptionEscapeHTML OptionKey = "escapeHtml" | ||||
| ) | ||||
|  | ||||
| // ReadWriteOption is an option to be used when writing. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Tom Wright
					Tom Wright