├── LICENSE ├── README.md └── jsonconfig.go /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Kailash Nadh 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Go jsconfig 2 | 3 | Kailash Nadh, January 2015 4 | 5 | MIT License 6 | 7 | ## What? 8 | jsconfig is a tiny JSON configuration file parser for Go with support for comments. Really, JSON spec doesn't include comments, but a configuration file without helpful comments is a pain to deal with. 9 | 10 | Moreover, JSON for configuration files is powerful when combined with structs, enabling effortless loading of complex, nested data structures with Go's native JSON Unmarshaling. 11 | 12 | ## Installation (go 1.1+) 13 | `go get github.com/knadh/jsonconfig` 14 | 15 | ## Usage 16 | ### Sample file: config.json 17 | Notice the comments 18 |
19 | { 20 | // url to the site 21 | "url": "http://google.com", 22 | 23 | "methods": ["GET", "POST"], // supported methods 24 | 25 | "always_load": true, 26 | 27 | // nested structure with different types 28 | "module": { 29 | "name": "Welcome", 30 | "route": "/", 31 | "port": 8080 32 | } 33 | } 34 |35 | 36 | ### Loading the configuration 37 | ```go 38 | package main 39 | 40 | import ( 41 | "github.com/knadh/jsonconfig" 42 | ) 43 | 44 | func main() { 45 | // setup the structure 46 | config := struct { 47 | Url string `json:"url"` 48 | 49 | Methods []string `json:"methods"` 50 | 51 | AlwaysLoad bool `json:"always_load"` 52 | 53 | Module struct{ 54 | Name string `json:"name"` 55 | Route string `json:"route"` 56 | Port int `json:"port"` 57 | } `json:"module"` 58 | }{} 59 | 60 | // parse and load json config 61 | err := jsonconfig.Load("config.json", &config) 62 | 63 | if err == nil { 64 | println("The url is", config.Url) 65 | println("Supported methods are", config.Methods[0], config.Methods[1]) 66 | 67 | println("The module is", config.Module.Name, "on route", config.Module.Route) 68 | } 69 | } 70 | ``` -------------------------------------------------------------------------------- /jsonconfig.go: -------------------------------------------------------------------------------- 1 | // Package jsonconfig is a super tiny (pseudo) JSON configuration parser for Go with support for comments. 2 | 3 | // Kailash Nadh, http://nadh.in/code/jsonconfig 4 | // Jan 2015 5 | // MIT License 6 | 7 | package jsonconfig 8 | 9 | import ( 10 | "encoding/json" 11 | "errors" 12 | "io/ioutil" 13 | "regexp" 14 | ) 15 | 16 | func Load(filename string, config interface{}) error { 17 | // Read the config file. 18 | data, err := ioutil.ReadFile(filename) 19 | if err != nil { 20 | return errors.New("Error reading file") 21 | } 22 | 23 | // Regex monstrosity because of the lack of lookbehinds/aheads. 24 | 25 | // Standalone comments. 26 | r1, _ := regexp.Compile(`(?m)^(\s+)?//(.*)$`) 27 | 28 | // Numbers and boolean. 29 | r2, _ := regexp.Compile(`(?m)"(.+?)":(\s+)?([0-9\.\-]+|true|false|null)(\s+)?,(\s+)?//(.*)$`) 30 | 31 | // Strings. 32 | r3, _ := regexp.Compile(`(?m)"(.+?)":(\s+)?"(.+?)"(\s+)?,(\s+)?//(.*)$`) 33 | 34 | // Arrays and objects. 35 | r4, _ := regexp.Compile(`(?m)"(.+?)":(\s+)?([\{\[])(.+?)([\}\]])(\s+)?,(\s+)?//(.*)$`) 36 | 37 | res := r1.ReplaceAllString(string(data), "") 38 | res = r2.ReplaceAllString(res, `"$1": $3,`) 39 | res = r3.ReplaceAllString(res, `"$1": "$3",`) 40 | res = r4.ReplaceAllString(res, `"$1": $3$4$5,`) 41 | 42 | // Decode json. 43 | if err := json.Unmarshal([]byte(res), &config); err != nil { 44 | return err 45 | } 46 | 47 | return nil 48 | } 49 | --------------------------------------------------------------------------------