Given a key, find the value. Viper will check to see if an alias exists first. Viper will then check in the following order: flag, env, config file, key/value store. Lastly, if no value was found and flagDefault is true, and if the key corresponds to a flag, the flag's default value is returned. N
(lcaseKey string, flagDefault bool)
| 1147 | // |
| 1148 | // Note: this assumes a lower-cased key given. |
| 1149 | func (v *Viper) find(lcaseKey string, flagDefault bool) any { |
| 1150 | var ( |
| 1151 | val any |
| 1152 | exists bool |
| 1153 | path = strings.Split(lcaseKey, v.keyDelim) |
| 1154 | nested = len(path) > 1 |
| 1155 | ) |
| 1156 | |
| 1157 | // compute the path through the nested maps to the nested value |
| 1158 | if nested && v.isPathShadowedInDeepMap(path, castMapStringToMapInterface(v.aliases)) != "" { |
| 1159 | return nil |
| 1160 | } |
| 1161 | |
| 1162 | // if the requested key is an alias, then return the proper key |
| 1163 | lcaseKey = v.realKey(lcaseKey) |
| 1164 | path = strings.Split(lcaseKey, v.keyDelim) |
| 1165 | nested = len(path) > 1 |
| 1166 | |
| 1167 | // Set() override first |
| 1168 | val = v.searchMap(v.override, path) |
| 1169 | if val != nil { |
| 1170 | return val |
| 1171 | } |
| 1172 | if nested && v.isPathShadowedInDeepMap(path, v.override) != "" { |
| 1173 | return nil |
| 1174 | } |
| 1175 | |
| 1176 | // PFlag override next |
| 1177 | flag, exists := v.pflags[lcaseKey] |
| 1178 | if exists && flag.HasChanged() { |
| 1179 | switch flag.ValueType() { |
| 1180 | case "int", "int8", "int16", "int32", "int64": |
| 1181 | return cast.ToInt(flag.ValueString()) |
| 1182 | case "bool": |
| 1183 | return cast.ToBool(flag.ValueString()) |
| 1184 | case "stringSlice", "stringArray": |
| 1185 | s := strings.TrimPrefix(flag.ValueString(), "[") |
| 1186 | s = strings.TrimSuffix(s, "]") |
| 1187 | res, _ := readAsCSV(s) |
| 1188 | return res |
| 1189 | case "boolSlice": |
| 1190 | s := strings.TrimPrefix(flag.ValueString(), "[") |
| 1191 | s = strings.TrimSuffix(s, "]") |
| 1192 | res, _ := readAsCSV(s) |
| 1193 | return cast.ToBoolSlice(res) |
| 1194 | case "intSlice": |
| 1195 | s := strings.TrimPrefix(flag.ValueString(), "[") |
| 1196 | s = strings.TrimSuffix(s, "]") |
| 1197 | res, _ := readAsCSV(s) |
| 1198 | return cast.ToIntSlice(res) |
| 1199 | case "uintSlice": |
| 1200 | s := strings.TrimPrefix(flag.ValueString(), "[") |
| 1201 | s = strings.TrimSuffix(s, "]") |
| 1202 | res, _ := readAsCSV(s) |
| 1203 | return cast.ToUintSlice(res) |
| 1204 | case "float64Slice": |
| 1205 | s := strings.TrimPrefix(flag.ValueString(), "[") |
| 1206 | s = strings.TrimSuffix(s, "]") |
no test coverage detected