yaml2mts.go 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // Copyright 2023 prestidigitator (as registered on forum.minetest.net)
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package mts
  15. import (
  16. "bytes"
  17. "io"
  18. "os"
  19. "github.com/spf13/cobra"
  20. "notabug.org/prestidigitator-mt/minetest-goutils/schematic"
  21. )
  22. var YAML2MTS = &cobra.Command{
  23. Use: "yaml2mts [inFile|-] [outFile|-]",
  24. Aliases: []string{"json2mts"},
  25. Short: "Convert YAML to binary MTS schematic file.",
  26. Long: "Write a binary mintest MTS schematic file given a YAML or JSON input "+
  27. "definition.",
  28. Args: cobra.MaximumNArgs(2),
  29. ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) (
  30. []string, cobra.ShellCompDirective,
  31. ) {
  32. switch len(args) {
  33. case 0:
  34. return []string{"yaml", "json"}, cobra.ShellCompDirectiveFilterFileExt
  35. case 1:
  36. return []string{"mts"}, cobra.ShellCompDirectiveFilterFileExt
  37. default:
  38. return nil, cobra.ShellCompDirectiveNoFileComp
  39. }
  40. },
  41. RunE: func(cmd *cobra.Command, args []string) error {
  42. // Don't confuse the user: from this point on, errors are runtime errors.
  43. cmd.SilenceUsage = true
  44. var ins io.Reader = os.Stdin
  45. if len(args) > 0 && args[0] != "-" {
  46. file, err := os.Open(args[0])
  47. if err != nil { return err }
  48. defer file.Close()
  49. ins = file
  50. }
  51. // Eventually it might make sense to either have some predictive logic that can
  52. // determine the input type based on content (and/or file extension when
  53. // applicable), or still allow streaming when the input is a file rather than
  54. // stdin. But for now just gobble up the whole input and try to parse it
  55. // multiple times.
  56. inb, err := io.ReadAll(ins)
  57. if err != nil { return err }
  58. var outs io.Writer = os.Stdout
  59. if len(args) > 1 && args[1] != "-" {
  60. file, err := os.Create(args[1])
  61. if err != nil { return err }
  62. defer file.Close()
  63. outs = file
  64. }
  65. s, err := schematic.FromJSONStream(bytes.NewReader(inb))
  66. if err != nil {
  67. s, err = schematic.FromYAMLStream(bytes.NewReader(inb))
  68. if err != nil { return err }
  69. }
  70. return s.WriteMTS(outs)
  71. },
  72. }