// Copyright 2016 Frank Schroeder. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Package properties provides functions for reading and writing // ISO-8859-1 and UTF-8 encoded .properties files and has // support for recursive property expansion. // // Java properties files are ISO-8859-1 encoded and use Unicode // literals for characters outside the ISO character set. Unicode // literals can be used in UTF-8 encoded properties files but // aren't necessary. // // To load a single properties file use MustLoadFile(): // // p := properties.MustLoadFile(filename, properties.UTF8) // // To load multiple properties files use MustLoadFiles() // which loads the files in the given order and merges the // result. Missing properties files can be ignored if the // 'ignoreMissing' flag is set to true. // // Filenames can contain environment variables which are expanded // before loading. // // f1 := "/etc/myapp/myapp.conf" // f2 := "/home/${USER}/myapp.conf" // p := MustLoadFiles([]string{f1, f2}, properties.UTF8, true) // // All of the different key/value delimiters ' ', ':' and '=' are // supported as well as the comment characters '!' and '#' and // multi-line values. // // ! this is a comment // # and so is this // // # the following expressions are equal // key value // key=value // key:value // key = value // key : value // key = val\ // ue // // Properties stores all comments preceding a key and provides // GetComments() and SetComments() methods to retrieve and // update them. The convenience functions GetComment() and // SetComment() allow access to the last comment. The // WriteComment() method writes properties files including // the comments and with the keys in the original order. // This can be used for sanitizing properties files. // // Property expansion is recursive and circular references // and malformed expressions are not allowed and cause an // error. Expansion of environment variables is supported. // // # standard property // key = value // // # property expansion: key2 = value // key2 = ${key} // // # recursive expansion: key3 = value // key3 = ${key2} // // # circular reference (error) // key = ${key} // // # malformed expression (error) // key = ${ke // // # refers to the users' home dir // home = ${HOME} // // # local key takes precendence over env var: u = foo // USER = foo // u = ${USER} // // The default property expansion format is ${key} but can be // changed by setting different pre- and postfix values on the // Properties object. // // p := properties.NewProperties() // p.Prefix = "#[" // p.Postfix = "]#" // // Properties provides convenience functions for getting typed // values with default values if the key does not exist or the // type conversion failed. // // # Returns true if the value is either "1", "on", "yes" or "true" // # Returns false for every other value and the default value if // # the key does not exist. // v = p.GetBool("key", false) // // # Returns the value if the key exists and the format conversion // # was successful. Otherwise, the default value is returned. // v = p.GetInt64("key", 999) // v = p.GetUint64("key", 999) // v = p.GetFloat64("key", 123.0) // v = p.GetString("key", "def") // v = p.GetDuration("key", 999) // // As an alterantive properties may be applied with the standard // library's flag implementation at any time. // // # Standard configuration // v = flag.Int("key", 999, "help message") // flag.Parse() // // # Merge p into the flag set // p.MustFlag(flag.CommandLine) // // Properties provides several MustXXX() convenience functions // which will terminate the app if an error occurs. The behavior // of the failure is configurable and the default is to call // log.Fatal(err). To have the MustXXX() functions panic instead // of logging the error set a different ErrorHandler before // you use the Properties package. // // properties.ErrorHandler = properties.PanicHandler // // # Will panic instead of logging an error // p := properties.MustLoadFile("config.properties") // // You can also provide your own ErrorHandler function. The only requirement // is that the error handler function must exit after handling the error. // // properties.ErrorHandler = func(err error) { // fmt.Println(err) // os.Exit(1) // } // // # Will write to stdout and then exit // p := properties.MustLoadFile("config.properties") // // Properties can also be loaded into a struct via the `Decode` // method, e.g. // // type S struct { // A string `properties:"a,default=foo"` // D time.Duration `properties:"timeout,default=5s"` // E time.Time `properties:"expires,layout=2006-01-02,default=2015-01-01"` // } // // See `Decode()` method for the full documentation. // // The following documents provide a description of the properties // file format. // // http://en.wikipedia.org/wiki/.properties // // http://docs.oracle.com/javase/7/docs/api/java/util/Properties.html#load%28java.io.Reader%29 // package properties