|
1 // Copyright 2018 Frank Schroeder. All rights reserved. |
|
2 // Use of this source code is governed by a BSD-style |
|
3 // license that can be found in the LICENSE file. |
|
4 |
|
5 // Package properties provides functions for reading and writing |
|
6 // ISO-8859-1 and UTF-8 encoded .properties files and has |
|
7 // support for recursive property expansion. |
|
8 // |
|
9 // Java properties files are ISO-8859-1 encoded and use Unicode |
|
10 // literals for characters outside the ISO character set. Unicode |
|
11 // literals can be used in UTF-8 encoded properties files but |
|
12 // aren't necessary. |
|
13 // |
|
14 // To load a single properties file use MustLoadFile(): |
|
15 // |
|
16 // p := properties.MustLoadFile(filename, properties.UTF8) |
|
17 // |
|
18 // To load multiple properties files use MustLoadFiles() |
|
19 // which loads the files in the given order and merges the |
|
20 // result. Missing properties files can be ignored if the |
|
21 // 'ignoreMissing' flag is set to true. |
|
22 // |
|
23 // Filenames can contain environment variables which are expanded |
|
24 // before loading. |
|
25 // |
|
26 // f1 := "/etc/myapp/myapp.conf" |
|
27 // f2 := "/home/${USER}/myapp.conf" |
|
28 // p := MustLoadFiles([]string{f1, f2}, properties.UTF8, true) |
|
29 // |
|
30 // All of the different key/value delimiters ' ', ':' and '=' are |
|
31 // supported as well as the comment characters '!' and '#' and |
|
32 // multi-line values. |
|
33 // |
|
34 // ! this is a comment |
|
35 // # and so is this |
|
36 // |
|
37 // # the following expressions are equal |
|
38 // key value |
|
39 // key=value |
|
40 // key:value |
|
41 // key = value |
|
42 // key : value |
|
43 // key = val\ |
|
44 // ue |
|
45 // |
|
46 // Properties stores all comments preceding a key and provides |
|
47 // GetComments() and SetComments() methods to retrieve and |
|
48 // update them. The convenience functions GetComment() and |
|
49 // SetComment() allow access to the last comment. The |
|
50 // WriteComment() method writes properties files including |
|
51 // the comments and with the keys in the original order. |
|
52 // This can be used for sanitizing properties files. |
|
53 // |
|
54 // Property expansion is recursive and circular references |
|
55 // and malformed expressions are not allowed and cause an |
|
56 // error. Expansion of environment variables is supported. |
|
57 // |
|
58 // # standard property |
|
59 // key = value |
|
60 // |
|
61 // # property expansion: key2 = value |
|
62 // key2 = ${key} |
|
63 // |
|
64 // # recursive expansion: key3 = value |
|
65 // key3 = ${key2} |
|
66 // |
|
67 // # circular reference (error) |
|
68 // key = ${key} |
|
69 // |
|
70 // # malformed expression (error) |
|
71 // key = ${ke |
|
72 // |
|
73 // # refers to the users' home dir |
|
74 // home = ${HOME} |
|
75 // |
|
76 // # local key takes precedence over env var: u = foo |
|
77 // USER = foo |
|
78 // u = ${USER} |
|
79 // |
|
80 // The default property expansion format is ${key} but can be |
|
81 // changed by setting different pre- and postfix values on the |
|
82 // Properties object. |
|
83 // |
|
84 // p := properties.NewProperties() |
|
85 // p.Prefix = "#[" |
|
86 // p.Postfix = "]#" |
|
87 // |
|
88 // Properties provides convenience functions for getting typed |
|
89 // values with default values if the key does not exist or the |
|
90 // type conversion failed. |
|
91 // |
|
92 // # Returns true if the value is either "1", "on", "yes" or "true" |
|
93 // # Returns false for every other value and the default value if |
|
94 // # the key does not exist. |
|
95 // v = p.GetBool("key", false) |
|
96 // |
|
97 // # Returns the value if the key exists and the format conversion |
|
98 // # was successful. Otherwise, the default value is returned. |
|
99 // v = p.GetInt64("key", 999) |
|
100 // v = p.GetUint64("key", 999) |
|
101 // v = p.GetFloat64("key", 123.0) |
|
102 // v = p.GetString("key", "def") |
|
103 // v = p.GetDuration("key", 999) |
|
104 // |
|
105 // As an alternative properties may be applied with the standard |
|
106 // library's flag implementation at any time. |
|
107 // |
|
108 // # Standard configuration |
|
109 // v = flag.Int("key", 999, "help message") |
|
110 // flag.Parse() |
|
111 // |
|
112 // # Merge p into the flag set |
|
113 // p.MustFlag(flag.CommandLine) |
|
114 // |
|
115 // Properties provides several MustXXX() convenience functions |
|
116 // which will terminate the app if an error occurs. The behavior |
|
117 // of the failure is configurable and the default is to call |
|
118 // log.Fatal(err). To have the MustXXX() functions panic instead |
|
119 // of logging the error set a different ErrorHandler before |
|
120 // you use the Properties package. |
|
121 // |
|
122 // properties.ErrorHandler = properties.PanicHandler |
|
123 // |
|
124 // # Will panic instead of logging an error |
|
125 // p := properties.MustLoadFile("config.properties") |
|
126 // |
|
127 // You can also provide your own ErrorHandler function. The only requirement |
|
128 // is that the error handler function must exit after handling the error. |
|
129 // |
|
130 // properties.ErrorHandler = func(err error) { |
|
131 // fmt.Println(err) |
|
132 // os.Exit(1) |
|
133 // } |
|
134 // |
|
135 // # Will write to stdout and then exit |
|
136 // p := properties.MustLoadFile("config.properties") |
|
137 // |
|
138 // Properties can also be loaded into a struct via the `Decode` |
|
139 // method, e.g. |
|
140 // |
|
141 // type S struct { |
|
142 // A string `properties:"a,default=foo"` |
|
143 // D time.Duration `properties:"timeout,default=5s"` |
|
144 // E time.Time `properties:"expires,layout=2006-01-02,default=2015-01-01"` |
|
145 // } |
|
146 // |
|
147 // See `Decode()` method for the full documentation. |
|
148 // |
|
149 // The following documents provide a description of the properties |
|
150 // file format. |
|
151 // |
|
152 // http://en.wikipedia.org/wiki/.properties |
|
153 // |
|
154 // http://docs.oracle.com/javase/7/docs/api/java/util/Properties.html#load%28java.io.Reader%29 |
|
155 // |
|
156 package properties |