convert.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package all
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "google.golang.org/protobuf/proto"
  6. "os"
  7. "strings"
  8. "github.com/v2fly/v2ray-core/v4/infra/conf/serial"
  9. "github.com/v2fly/v2ray-core/v4/main/commands/base"
  10. "gopkg.in/yaml.v2"
  11. )
  12. var cmdConvert = &base.Command{
  13. CustomFlags: true,
  14. UsageLine: "{{.Exec}} convert [c1.json] [<url>.json] [dir1] ...",
  15. Short: "Convert config files",
  16. Long: `
  17. Convert config files between different formats. Files are merged
  18. before convert if multiple assigned.
  19. Arguments:
  20. -i, -input
  21. Specify the input format.
  22. Available values: "json", "yaml"
  23. Default: "json"
  24. -o, -output
  25. Specify the output format
  26. Available values: "json", "yaml", "protobuf" / "pb"
  27. Default: "json"
  28. -r
  29. Load confdir recursively.
  30. Examples:
  31. {{.Exec}} {{.LongName}} -output=protobuf config.json (1)
  32. {{.Exec}} {{.LongName}} -output=yaml config.json (2)
  33. {{.Exec}} {{.LongName}} -input=yaml config.yaml (3)
  34. {{.Exec}} {{.LongName}} "path/to/dir" (4)
  35. {{.Exec}} {{.LongName}} -i yaml -o protobuf c1.yaml <url>.yaml (5)
  36. (1) Convert json to protobuf
  37. (2) Convert json to yaml
  38. (3) Convert yaml to json
  39. (4) Merge json files in dir
  40. (5) Merge yaml files and convert to protobuf
  41. Use "{{.Exec}} help config-merge" for more information about merge.
  42. `,
  43. }
  44. func init() {
  45. cmdConvert.Run = executeConvert // break init loop
  46. }
  47. var (
  48. inputFormat string
  49. outputFormat string
  50. confDirRecursively bool
  51. )
  52. var formatExtensions = map[string][]string{
  53. "json": {".json", ".jsonc"},
  54. "yaml": {".yaml", ".yml"},
  55. }
  56. func setConfArgs(cmd *base.Command) {
  57. cmd.Flag.StringVar(&inputFormat, "input", "json", "")
  58. cmd.Flag.StringVar(&inputFormat, "i", "json", "")
  59. cmd.Flag.StringVar(&outputFormat, "output", "json", "")
  60. cmd.Flag.StringVar(&outputFormat, "o", "json", "")
  61. cmd.Flag.BoolVar(&confDirRecursively, "r", true, "")
  62. }
  63. func executeConvert(cmd *base.Command, args []string) {
  64. setConfArgs(cmd)
  65. cmd.Flag.Parse(args)
  66. unnamed := cmd.Flag.Args()
  67. inputFormat = strings.ToLower(inputFormat)
  68. outputFormat = strings.ToLower(outputFormat)
  69. files := resolveFolderToFiles(unnamed, formatExtensions[inputFormat], confDirRecursively)
  70. if len(files) == 0 {
  71. base.Fatalf("empty config list")
  72. }
  73. m := mergeConvertToMap(files, inputFormat)
  74. var (
  75. out []byte
  76. err error
  77. )
  78. switch outputFormat {
  79. case "json":
  80. out, err = json.Marshal(m)
  81. if err != nil {
  82. base.Fatalf("failed to marshal json: %s", err)
  83. }
  84. case "yaml":
  85. out, err = yaml.Marshal(m)
  86. if err != nil {
  87. base.Fatalf("failed to marshal json: %s", err)
  88. }
  89. case "pb", "protobuf":
  90. data, err := json.Marshal(m)
  91. if err != nil {
  92. base.Fatalf("failed to marshal json: %s", err)
  93. }
  94. r := bytes.NewReader(data)
  95. cf, err := serial.DecodeJSONConfig(r)
  96. if err != nil {
  97. base.Fatalf("failed to decode json: %s", err)
  98. }
  99. pbConfig, err := cf.Build()
  100. if err != nil {
  101. base.Fatalf(err.Error())
  102. }
  103. out, err = proto.Marshal(pbConfig)
  104. if err != nil {
  105. base.Fatalf("failed to marshal proto config: %s", err)
  106. }
  107. default:
  108. base.Errorf("invalid output format: %s", outputFormat)
  109. base.Errorf("Run '%s help %s' for details.", base.CommandEnv.Exec, cmd.LongName())
  110. base.Exit()
  111. }
  112. if _, err := os.Stdout.Write(out); err != nil {
  113. base.Fatalf("failed to write proto config: %s", err)
  114. }
  115. }