diff --git a/.gitignore b/.gitignore index 4257fef..4338bf7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /evaluator/vendor/ +/evaluator/bangs.go diff --git a/evaluator/evaluator.go b/evaluator/evaluator.go index b9c1ebc..37ca6f7 100644 --- a/evaluator/evaluator.go +++ b/evaluator/evaluator.go @@ -1,17 +1,14 @@ package main import ( - "io/ioutil" "log" "net/http" "net/url" "regexp" "strings" - - "gopkg.in/yaml.v2" ) -var bangs = loadBangs() +//go:generate go run scripts/includebangs.go func main() { http.HandleFunc("/eval", func(w http.ResponseWriter, r *http.Request) { @@ -32,20 +29,6 @@ func main() { log.Fatalf("Failed to start http server: %v", http.ListenAndServe(":8081", nil)) } -func loadBangs() (bangs map[string]string) { - data, err := ioutil.ReadFile("bangs.yml") - if err != nil { - log.Fatalf("Failed to read bangs: %v", err) - } - - err = yaml.Unmarshal(data, &bangs) - if err != nil { - log.Fatalf("Failed to decode bangs: %v", err) - } - - return -} - func buildSearchURL(template string, query string) (searchUrl string) { searchUrl = strings.Replace(template, "%s", url.QueryEscape(query), 1) searchUrl = strings.Replace(searchUrl, "%S", query, 1) @@ -74,7 +57,7 @@ func parseBang(searchQuery string) (bang string, query string) { func evaluateBang(searchQuery string, searchEngine string) (query string, engine string) { bang, query := parseBang(searchQuery) - engine = bangs[bang] + engine = getBang(bang) if bang == "" || engine == "" { return searchQuery, searchEngine diff --git a/evaluator/scripts/includebangs.go b/evaluator/scripts/includebangs.go new file mode 100644 index 0000000..5c00c62 --- /dev/null +++ b/evaluator/scripts/includebangs.go @@ -0,0 +1,51 @@ +package main + +import ( + "fmt" + "io/ioutil" + "os" + "sort" + + "gopkg.in/yaml.v2" +) + +func loadBangs() (bangs map[string]string) { + data, err := ioutil.ReadFile("../bangs.yml") + if err != nil { + panic(fmt.Sprintf("Failed to load bangs.yml: %v", err)) + } + + err = yaml.Unmarshal(data, &bangs) + if err != nil { + panic(fmt.Sprintf("Failed to decode bangs: %v", err)) + } + + return +} + +func main() { + bangs := loadBangs() + + // generating sorted keys to have stable generated code + // this is not optimal, performance-wise but it runs only once at build + // time, so it doesn’t matter that much) + bangNames := []string{} + for bang := range bangs { + bangNames = append(bangNames, bang) + } + sort.Strings(bangNames) + + out, err := os.Create("bangs.go") + if err != nil { + panic(fmt.Sprintf("Failed to create bangs.go: %v", err)) + } + + out.Write([]byte("// Code generated from ../../bangs.yml DO NOT EDIT.\n")) + out.Write([]byte("package main \n\nfunc getBang(name string) string {\n\tswitch name {\n")) + + for _, bangName := range bangNames { + out.Write([]byte("\t\tcase `" + bangName + "`: return `" + bangs[bangName] + "`\n")) + } + out.Write([]byte("\t\tdefault: return \"\"\n")) + out.Write([]byte("\t}\n}\n")) +}