diff --git a/cmd/config.go b/cmd/config.go index b88ab687b..79b3a38df 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -178,7 +178,7 @@ func setPhotoPath(req *core.ProfileRequests, proppath, filepath string) error { func init() { configGetCommand.Flags().Bool("with-private-keys", false, "include private keys in export") configGetCommand.Flags().BoolP("concise", "c", false, "print output without indentation, only applies to json format") - configGetCommand.Flags().StringP("format", "f", "json", "data format to export. either json or yaml") + configGetCommand.Flags().StringP("format", "f", "yaml", "data format to export. either json or yaml") configGetCommand.Flags().StringP("output", "o", "", "path to export to") configCmd.AddCommand(configGetCommand) diff --git a/cmd/export.go b/cmd/export.go index bf0d368f7..88effc5e0 100644 --- a/cmd/export.go +++ b/cmd/export.go @@ -7,7 +7,9 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" + "github.com/ghodss/yaml" "github.com/qri-io/dataset" "github.com/qri-io/dataset/dsfs" "github.com/qri-io/dataset/dsutil" @@ -46,6 +48,7 @@ To export everything about a dataset, use the --dataset flag.`, Run: func(cmd *cobra.Command, args []string) { requireNotRPC(cmd.Name()) path := cmd.Flag("output").Value.String() + format := cmd.Flag("format").Value.String() if blank, err := cmd.Flags().GetBool("blank"); err == nil && blank { if path == "" { @@ -157,18 +160,38 @@ To export everything about a dataset, use the --dataset flag.`, } metaPath := filepath.Join(path, dsfs.PackageFileMeta.Filename()) - mdBytes, err := json.MarshalIndent(md, "", " ") + mdBytes := []byte{} + + switch format { + case "json": + mdBytes, err = json.MarshalIndent(md, "", " ") + ExitIfErr(err) + default: + mdBytes, err = yaml.Marshal(md) + ExitIfErr(err) + metaPath = FilenameToYAML(metaPath) + } err = ioutil.WriteFile(metaPath, mdBytes, os.ModePerm) ExitIfErr(err) printSuccess("exported metadata file to: %s", metaPath) } if exportCmdStructure { - stpath := filepath.Join(path, dsfs.PackageFileStructure.Filename()) - stbytes, err := json.MarshalIndent(ds.Structure, "", " ") - err = ioutil.WriteFile(stpath, stbytes, os.ModePerm) + stPath := filepath.Join(path, dsfs.PackageFileStructure.Filename()) + stBytes := []byte{} + + switch format { + case "json": + stBytes, err = json.MarshalIndent(ds.Structure, "", " ") + ExitIfErr(err) + default: + stBytes, err = yaml.Marshal(ds.Structure) + ExitIfErr(err) + stPath = FilenameToYAML(stPath) + } + err = ioutil.WriteFile(stPath, stBytes, os.ModePerm) ExitIfErr(err) - printSuccess("exported structure file to: %s", stpath) + printSuccess("exported structure file to: %s", stPath) } if exportCmdData { @@ -189,9 +212,18 @@ To export everything about a dataset, use the --dataset flag.`, if exportCmdDataset { dsPath := filepath.Join(path, dsfs.PackageFileDataset.String()) - dsbytes, err := json.MarshalIndent(ds, "", " ") - ExitIfErr(err) - err = ioutil.WriteFile(dsPath, dsbytes, os.ModePerm) + dsBytes := []byte{} + + switch format { + case "json": + dsBytes, err = json.MarshalIndent(ds, "", " ") + ExitIfErr(err) + default: + dsBytes, err = yaml.Marshal(ds) + ExitIfErr(err) + dsPath = FilenameToYAML(dsPath) + } + err = ioutil.WriteFile(dsPath, dsBytes, os.ModePerm) ExitIfErr(err) printSuccess("exported dataset.json to: %s", dsPath) @@ -206,6 +238,7 @@ func init() { RootCmd.AddCommand(exportCmd) exportCmd.Flags().BoolP("blank", "", false, "export a blank dataset YAML file, overrides all other flags except output") exportCmd.Flags().StringP("output", "o", "", "path to write to, default is current directory") + exportCmd.Flags().StringP("format", "f", "yaml", "format for all exported files, except for data. yaml is the default format. options: yaml, json") exportCmd.Flags().BoolVarP(&exportCmdZipped, "zip", "z", false, "compress export as zip archive") exportCmd.Flags().BoolVarP(&exportCmdAll, "all", "a", false, "export full dataset package") exportCmd.Flags().BoolVarP(&exportCmdAll, "namespaced", "n", false, "export to a peer name namespaced directory") @@ -217,7 +250,7 @@ func init() { // exportCmd.Flags().BoolVarP(&exportCmdVis, "vis-conf", "c", false, "export viz config file") // TODO - get format conversion up & running - // exportCmd.Flags().StringP("format", "f", "csv", "set output format [csv,json,cbor]") + // exportCmd.Flags().StringP("data-format", "", "csv", "set output format [csv,json,cbor]") } const blankYamlDataset = `# This file defines a qri dataset. Change this file, save it, then from a terminal run: @@ -270,3 +303,18 @@ structure: # or a URL that leads to the raw data # dataPath: ` + +// FilenameToYAML takes a filename, removes any format ending (if there is one), and replaces it with yaml +// should probably be generalized to +// FilenameFormatChange(filename string, newEnding string) string +func FilenameToYAML(filename string) string { + if len(filename) == 0 { + return "" + } + index := strings.LastIndex(filename, ".") + if index == -1 { + index = len(filename) + filename += "." + } + return filename[:index+1] + "yaml" +} diff --git a/cmd/export_test.go b/cmd/export_test.go new file mode 100644 index 000000000..f605cd64a --- /dev/null +++ b/cmd/export_test.go @@ -0,0 +1,25 @@ +package cmd + +import ( + "testing" +) + +func TestFilenameToYAML(t *testing.T) { + cases := []struct { + filename, expected string + }{ + {"", ""}, + {"filename", "filename.yaml"}, + {"filename.json", "filename.yaml"}, + {"filename.", "filename.yaml"}, + {"file.name.json", "file.name.yaml"}, + } + + for i, c := range cases { + got := FilenameToYAML(c.filename) + if got != c.expected { + t.Errorf("case %d (expected != got): '%s' != '%s'", i, c.expected, got) + continue + } + } +}