Add README and export gmconfig() type
This commit is contained in:
parent
eb308e3acd
commit
e553a2c338
80
README.md
Normal file
80
README.md
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
# Gmconfig - A JSON-SCHEMA-based configuration management support library
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
This library offers the basic support functions for the Gajumaru configuration
|
||||||
|
management subsystem. It is based on JSON-Schema, and includes, among other things:
|
||||||
|
|
||||||
|
* A reasonably complete JSON-Schema validator
|
||||||
|
* Validating user configurations against the schema
|
||||||
|
* In-service update of the user config
|
||||||
|
* Caching of the user config (and schema) as persistent terms
|
||||||
|
* Fast config lookups using key paths
|
||||||
|
* Lookups can handle both schema defaults and user-provided defaults
|
||||||
|
|
||||||
|
## JSON-Schema validator
|
||||||
|
|
||||||
|
The main thing the validator currently doesn't support is proper
|
||||||
|
management of complex sets of schemas and subSchemas. There are
|
||||||
|
some preparations made for supporting `"$id"` and uris, but this
|
||||||
|
is still incomplete. `"definitions"` and `"$ref"` properties are recognized.
|
||||||
|
|
||||||
|
As almost anything is theoretically possible with JSON-Schema,
|
||||||
|
there are surely other things that are unsupported.
|
||||||
|
|
||||||
|
### All standard data types
|
||||||
|
|
||||||
|
* `"null"`
|
||||||
|
* `"boolean"`
|
||||||
|
* `"integer"`
|
||||||
|
* `"number"`
|
||||||
|
* `"boolean"`
|
||||||
|
* `"string"`
|
||||||
|
* `"array"`
|
||||||
|
* `"object"`
|
||||||
|
|
||||||
|
### Dynamic properties
|
||||||
|
|
||||||
|
* `"if"`
|
||||||
|
* `"not"`
|
||||||
|
* `"oneOf"`
|
||||||
|
* `"anyOf"`
|
||||||
|
* `"allOf"`
|
||||||
|
|
||||||
|
### Static Properties
|
||||||
|
|
||||||
|
#### Array
|
||||||
|
|
||||||
|
* `"maxItems"`
|
||||||
|
* `"minItems"`
|
||||||
|
* `"uniqueItems"`
|
||||||
|
* `"prefixItems"`
|
||||||
|
* `"contains"` (`"minContains"`, `"maxContains"`)
|
||||||
|
|
||||||
|
#### Object
|
||||||
|
|
||||||
|
* `"properties"` (`"minProperties"`, `"maxProperties"`)
|
||||||
|
* `"patternProperties"`
|
||||||
|
* `"additionalProperties"`
|
||||||
|
* `"required"`
|
||||||
|
|
||||||
|
#### String
|
||||||
|
|
||||||
|
* `"pattern"`
|
||||||
|
* `"minLength"`
|
||||||
|
* `"maxLength"`
|
||||||
|
|
||||||
|
#### Number, Integer
|
||||||
|
|
||||||
|
* `"minimum"`
|
||||||
|
* `"maximum"`
|
||||||
|
* `"exclusiveMinimum"`
|
||||||
|
* `"exclusiveMinimum"`
|
||||||
|
* `"multipleOf"` (only if object is an integer)
|
||||||
|
|
||||||
|
### `"$updateSemantics"`
|
||||||
|
|
||||||
|
* `"replace"` (fully replaces any old data)
|
||||||
|
* `"merge"` (for objects, keeps and/or updates existing values)
|
||||||
|
* `"suggest"` (adds value if not already present)
|
||||||
|
|
@ -10,11 +10,15 @@
|
|||||||
|
|
||||||
-export([get_env/2, get_env/3]).
|
-export([get_env/2, get_env/3]).
|
||||||
|
|
||||||
-export([user_config/0]).
|
-export([user_config/0]). % returns current user config
|
||||||
-export([load_main_config_schema/0, % called from start phase 50
|
-export([load_main_config_schema/0,
|
||||||
load_system_defaults/0]). % called from start phase 60
|
load_system_defaults/0]).
|
||||||
-export([schema/0, schema/1, schema/2]).
|
-export([load_user_config/0,
|
||||||
-export([load_schema/0]).
|
load_user_config/1]).
|
||||||
|
-export([schema/0,
|
||||||
|
schema/1,
|
||||||
|
schema/2]).
|
||||||
|
-export([load_schema/0]). % load_user_config() ensures schema is loaded
|
||||||
-export([schema_default/1, schema_default/2]).
|
-export([schema_default/1, schema_default/2]).
|
||||||
-export([schema_keys/0, schema_keys/1]).
|
-export([schema_keys/0, schema_keys/1]).
|
||||||
-export([config_value/4]).
|
-export([config_value/4]).
|
||||||
@ -23,7 +27,6 @@
|
|||||||
]).
|
]).
|
||||||
-export([merge_config_maps/2]).
|
-export([merge_config_maps/2]).
|
||||||
-export([nested_map_get/2]).
|
-export([nested_map_get/2]).
|
||||||
-export([read_config/0, read_config/1]).
|
|
||||||
-export([load_config_file/1]). % apply system-/network-specific defaults
|
-export([load_config_file/1]). % apply system-/network-specific defaults
|
||||||
-export([search_for_config_file/2]).
|
-export([search_for_config_file/2]).
|
||||||
-export([apply_os_env/0,
|
-export([apply_os_env/0,
|
||||||
@ -75,7 +78,8 @@
|
|||||||
|
|
||||||
-type find_opts() :: [user_config | schema_default | {env, atom(), atom()} | {value, any()}].
|
-type find_opts() :: [user_config | schema_default | {env, atom(), atom()} | {value, any()}].
|
||||||
|
|
||||||
-export_type([ find_opts/0 ]).
|
-export_type([ gmconfig/0
|
||||||
|
, find_opts/0 ]).
|
||||||
|
|
||||||
-ifdef(TEST).
|
-ifdef(TEST).
|
||||||
|
|
||||||
@ -475,17 +479,17 @@ schema_default_(#{default := Def}) ->
|
|||||||
schema_default_(_) ->
|
schema_default_(_) ->
|
||||||
undefined.
|
undefined.
|
||||||
|
|
||||||
read_config() ->
|
load_user_config() ->
|
||||||
read_config(silent).
|
load_user_config(silent).
|
||||||
|
|
||||||
read_config(Mode) when Mode =:= check; Mode =:= silent; Mode =:= report ->
|
load_user_config(Mode) when Mode =:= check; Mode =:= silent; Mode =:= report ->
|
||||||
case config_file() of
|
case config_file() of
|
||||||
undefined ->
|
undefined ->
|
||||||
info_msg(Mode, "No config file specified; using default settings~n", []),
|
info_msg(Mode, "No config file specified; using default settings~n", []),
|
||||||
ok;
|
ok;
|
||||||
F ->
|
F ->
|
||||||
info_msg(Mode, "Reading config file ~s~n", [F]),
|
info_msg(Mode, "Reading config file ~s~n", [F]),
|
||||||
do_read_config(F, store, Mode)
|
do_load_user_config(F, store, Mode)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
load_config_file(File) ->
|
load_config_file(File) ->
|
||||||
@ -494,7 +498,7 @@ load_config_file(File) ->
|
|||||||
load_config_file(File, Mode) when Mode =:= check;
|
load_config_file(File, Mode) when Mode =:= check;
|
||||||
Mode =:= silent;
|
Mode =:= silent;
|
||||||
Mode =:= report ->
|
Mode =:= report ->
|
||||||
do_read_config(File, store, Mode).
|
do_load_user_config(File, store, Mode).
|
||||||
|
|
||||||
apply_os_env() ->
|
apply_os_env() ->
|
||||||
ok = application:ensure_started(gproc),
|
ok = application:ensure_started(gproc),
|
||||||
@ -608,7 +612,7 @@ unhyphenate(Str) ->
|
|||||||
re:replace(Str, <<"\\-">>, <<"_">>, [global, {return, list}]).
|
re:replace(Str, <<"\\-">>, <<"_">>, [global, {return, list}]).
|
||||||
|
|
||||||
check_config(F) ->
|
check_config(F) ->
|
||||||
do_read_config(F, check, check).
|
do_load_user_config(F, check, check).
|
||||||
|
|
||||||
data_dir(Name) when is_atom(Name) ->
|
data_dir(Name) when is_atom(Name) ->
|
||||||
filename:join([setup:data_dir(), Name]).
|
filename:join([setup:data_dir(), Name]).
|
||||||
@ -665,7 +669,7 @@ to_list_string(S) when is_binary(S) ->
|
|||||||
to_list_string(S) when is_list(S) ->
|
to_list_string(S) when is_list(S) ->
|
||||||
binary_to_list(iolist_to_binary(S)).
|
binary_to_list(iolist_to_binary(S)).
|
||||||
|
|
||||||
do_read_config(F, Action, Mode) ->
|
do_load_user_config(F, Action, Mode) ->
|
||||||
case {filename:extension(F), Action} of
|
case {filename:extension(F), Action} of
|
||||||
{".json", store} -> store(read_json(F, Mode), Mode);
|
{".json", store} -> store(read_json(F, Mode), Mode);
|
||||||
{".yaml", store} -> store(read_yaml(F, Mode), Mode);
|
{".yaml", store} -> store(read_yaml(F, Mode), Mode);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user