github.com/sagernet/sing-box@v1.2.7/cmd/sing-box/cmd_format.go (about) 1 package main 2 3 import ( 4 "bytes" 5 "os" 6 "path/filepath" 7 8 "github.com/sagernet/sing-box/common/json" 9 "github.com/sagernet/sing-box/log" 10 "github.com/sagernet/sing-box/option" 11 E "github.com/sagernet/sing/common/exceptions" 12 13 "github.com/spf13/cobra" 14 ) 15 16 var commandFormatFlagWrite bool 17 18 var commandFormat = &cobra.Command{ 19 Use: "format", 20 Short: "Format configuration", 21 Run: func(cmd *cobra.Command, args []string) { 22 err := format() 23 if err != nil { 24 log.Fatal(err) 25 } 26 }, 27 Args: cobra.NoArgs, 28 } 29 30 func init() { 31 commandFormat.Flags().BoolVarP(&commandFormatFlagWrite, "write", "w", false, "write result to (source) file instead of stdout") 32 mainCommand.AddCommand(commandFormat) 33 } 34 35 func format() error { 36 optionsList, err := readConfig() 37 if err != nil { 38 return err 39 } 40 for _, optionsEntry := range optionsList { 41 buffer := new(bytes.Buffer) 42 encoder := json.NewEncoder(buffer) 43 encoder.SetIndent("", " ") 44 err = encoder.Encode(optionsEntry.options) 45 if err != nil { 46 return E.Cause(err, "encode config") 47 } 48 outputPath, _ := filepath.Abs(optionsEntry.path) 49 if !commandFormatFlagWrite { 50 if len(optionsList) > 1 { 51 os.Stdout.WriteString(outputPath + "\n") 52 } 53 os.Stdout.WriteString(buffer.String() + "\n") 54 continue 55 } 56 if bytes.Equal(optionsEntry.content, buffer.Bytes()) { 57 continue 58 } 59 output, err := os.Create(optionsEntry.path) 60 if err != nil { 61 return E.Cause(err, "open output") 62 } 63 _, err = output.Write(buffer.Bytes()) 64 output.Close() 65 if err != nil { 66 return E.Cause(err, "write output") 67 } 68 os.Stderr.WriteString(outputPath + "\n") 69 } 70 return nil 71 } 72 73 func formatOne(configPath string) error { 74 configContent, err := os.ReadFile(configPath) 75 if err != nil { 76 return E.Cause(err, "read config") 77 } 78 var options option.Options 79 err = options.UnmarshalJSON(configContent) 80 if err != nil { 81 return E.Cause(err, "decode config") 82 } 83 buffer := new(bytes.Buffer) 84 encoder := json.NewEncoder(buffer) 85 encoder.SetIndent("", " ") 86 err = encoder.Encode(options) 87 if err != nil { 88 return E.Cause(err, "encode config") 89 } 90 if !commandFormatFlagWrite { 91 os.Stdout.WriteString(buffer.String() + "\n") 92 return nil 93 } 94 if bytes.Equal(configContent, buffer.Bytes()) { 95 return nil 96 } 97 output, err := os.Create(configPath) 98 if err != nil { 99 return E.Cause(err, "open output") 100 } 101 _, err = output.Write(buffer.Bytes()) 102 output.Close() 103 if err != nil { 104 return E.Cause(err, "write output") 105 } 106 outputPath, _ := filepath.Abs(configPath) 107 os.Stderr.WriteString(outputPath + "\n") 108 return nil 109 }