github.com/sagernet/sing-box@v1.9.0-rc.20/cmd/sing-box/cmd_rule_set_compile.go (about) 1 package main 2 3 import ( 4 "io" 5 "os" 6 "strings" 7 8 "github.com/sagernet/sing-box/common/srs" 9 "github.com/sagernet/sing-box/log" 10 "github.com/sagernet/sing-box/option" 11 "github.com/sagernet/sing/common/json" 12 13 "github.com/spf13/cobra" 14 ) 15 16 var flagRuleSetCompileOutput string 17 18 const flagRuleSetCompileDefaultOutput = "<file_name>.srs" 19 20 var commandRuleSetCompile = &cobra.Command{ 21 Use: "compile [source-path]", 22 Short: "Compile rule-set json to binary", 23 Args: cobra.ExactArgs(1), 24 Run: func(cmd *cobra.Command, args []string) { 25 err := compileRuleSet(args[0]) 26 if err != nil { 27 log.Fatal(err) 28 } 29 }, 30 } 31 32 func init() { 33 commandRuleSet.AddCommand(commandRuleSetCompile) 34 commandRuleSetCompile.Flags().StringVarP(&flagRuleSetCompileOutput, "output", "o", flagRuleSetCompileDefaultOutput, "Output file") 35 } 36 37 func compileRuleSet(sourcePath string) error { 38 var ( 39 reader io.Reader 40 err error 41 ) 42 if sourcePath == "stdin" { 43 reader = os.Stdin 44 } else { 45 reader, err = os.Open(sourcePath) 46 if err != nil { 47 return err 48 } 49 } 50 content, err := io.ReadAll(reader) 51 if err != nil { 52 return err 53 } 54 plainRuleSet, err := json.UnmarshalExtended[option.PlainRuleSetCompat](content) 55 if err != nil { 56 return err 57 } 58 if err != nil { 59 return err 60 } 61 ruleSet := plainRuleSet.Upgrade() 62 var outputPath string 63 if flagRuleSetCompileOutput == flagRuleSetCompileDefaultOutput { 64 if strings.HasSuffix(sourcePath, ".json") { 65 outputPath = sourcePath[:len(sourcePath)-5] + ".srs" 66 } else { 67 outputPath = sourcePath + ".srs" 68 } 69 } else { 70 outputPath = flagRuleSetCompileOutput 71 } 72 outputFile, err := os.Create(outputPath) 73 if err != nil { 74 return err 75 } 76 err = srs.Write(outputFile, ruleSet) 77 if err != nil { 78 outputFile.Close() 79 os.Remove(outputPath) 80 return err 81 } 82 outputFile.Close() 83 return nil 84 }