From 15f51d4bf04b1ed6b5e76a6c5d434fdf53098e17 Mon Sep 17 00:00:00 2001 From: mfarah Date: Thu, 8 Oct 2015 10:31:31 +1100 Subject: [PATCH] Can update a yaml file from an instruction yaml file --- README.md | 28 ++++++++++++++++++++++++++++ instruction_sample.yaml | 2 ++ yaml.go | 32 ++++++++++++++++++++------------ yaml_test.go | 8 ++++---- 4 files changed, 54 insertions(+), 16 deletions(-) create mode 100644 instruction_sample.yaml diff --git a/README.md b/README.md index a3f820ae..bed4681c 100644 --- a/README.md +++ b/README.md @@ -132,3 +132,31 @@ then yaml w -i sample.yaml b.c cat ``` will update the sample.yaml file so that the value of 'c' is cat. + + +### Updating multiple values with a script +Given a sample.yaml file of: +```yaml +b: + c: 2 + e: + - name: Billy Bob +``` +and a script update_instructions.yaml of: +```yaml +b.c: 3 +b.e[0].name: Howdy Partner +``` +then + +```bash +yaml -w -s update_instructions.yaml sample.yaml +``` +will output: +```yaml +b: + c: 3 + e: + - name: Howdy Partner +``` + diff --git a/instruction_sample.yaml b/instruction_sample.yaml new file mode 100644 index 00000000..1250a747 --- /dev/null +++ b/instruction_sample.yaml @@ -0,0 +1,2 @@ +b.c: cat +b.e[0].name: Mike Farah diff --git a/yaml.go b/yaml.go index 4438f8dd..a9ac6d31 100644 --- a/yaml.go +++ b/yaml.go @@ -12,6 +12,7 @@ import ( var trimOutput = true var writeInplace = false +var writeScript = "" func main() { var cmdRead = &cobra.Command{ @@ -43,6 +44,7 @@ Outputs to STDOUT unless the inplace flag is used, in which case the file is upd Run: writeProperty, } cmdWrite.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the yaml file inplace") + cmdWrite.PersistentFlags().StringVarP(&writeScript, "script", "s", "", "yaml script for updating yaml") var rootCmd = &cobra.Command{Use: "yaml"} rootCmd.PersistentFlags().BoolVarP(&trimOutput, "trim", "t", true, "trim yaml output") @@ -53,7 +55,7 @@ Outputs to STDOUT unless the inplace flag is used, in which case the file is upd func readProperty(cmd *cobra.Command, args []string) { var parsedData map[interface{}]interface{} - readYaml(args, &parsedData) + readYaml(args[0], &parsedData) if len(args) == 1 { printYaml(parsedData) @@ -66,16 +68,22 @@ func readProperty(cmd *cobra.Command, args []string) { } func writeProperty(cmd *cobra.Command, args []string) { - if len(args) < 3 { + var writeCommands map[string]interface{} + if writeScript != "" { + readYaml(writeScript, &writeCommands) + } else if len(args) < 3 { die("Must provide ") + } else { + writeCommands[args[1]] = parseValue(args[2]) } var parsedData map[interface{}]interface{} - readYaml(args, &parsedData) + readYaml(args[0], &parsedData) - var paths = parsePath(args[1]) - - write(parsedData, paths[0], paths[1:len(paths)], getValue(args[2])) + for path, value := range writeCommands { + var paths = parsePath(path) + write(parsedData, paths[0], paths[1:len(paths)], value) + } if writeInplace { ioutil.WriteFile(args[0], []byte(yamlToString(parsedData)), 0644) @@ -83,7 +91,7 @@ func writeProperty(cmd *cobra.Command, args []string) { printYaml(parsedData) } } -func getValue(argument string) interface{} { +func parseValue(argument string) interface{} { var value, err interface{} var inQuotes = argument[0] == '"' if !inQuotes { @@ -118,19 +126,19 @@ func yamlToString(context interface{}) string { return outStr } -func readYaml(args []string, parsedData *map[interface{}]interface{}) { - if len(args) == 0 { +func readYaml(filename string, parsedData interface{}) { + if filename == "" { die("Must provide filename") } var rawData []byte - if args[0] == "-" { + if filename == "-" { rawData = readStdin() } else { - rawData = readFile(args[0]) + rawData = readFile(filename) } - err := yaml.Unmarshal([]byte(rawData), &parsedData) + err := yaml.Unmarshal([]byte(rawData), parsedData) if err != nil { die("error: %v", err) } diff --git a/yaml_test.go b/yaml_test.go index 65e2b890..105f1656 100644 --- a/yaml_test.go +++ b/yaml_test.go @@ -4,7 +4,7 @@ import ( "testing" ) -var getValueTests = []struct { +var parseValueTests = []struct { argument string expectedResult interface{} testDescription string @@ -15,8 +15,8 @@ var getValueTests = []struct { {"\"3.4\"", "3.4", "number as string"}, } -func TestGetValue(t *testing.T) { - for _, tt := range getValueTests { - assertResultWithContext(t, tt.expectedResult, getValue(tt.argument), tt.testDescription) +func TestParseValue(t *testing.T) { + for _, tt := range parseValueTests { + assertResultWithContext(t, tt.expectedResult, parseValue(tt.argument), tt.testDescription) } }