[]
type = null
status = implemented
version = 1.0.0
description = This part of the hierarchy specifies the semantics of a
	contract. Each key is a clause of the contract.
	Whenever this file is changed, following files need to be adapted:
	- src/libtools/src/plugin.cpp (validator of this specification)
	- src/libtools/src/plugins.cpp (placements)
	- cmake/Modules/LibAddMacros.cmake (for README.md conversion)
	Use "kdb check" to validate.
	In doubt this specification overrules other specifications.
	It is allowed to export additional keys (below the plugins module
	name). They might, however, someday conflict with the specification
	here. So prefer to prefix plugin specific clauses.

	The presence of the parent key indicates that the module exists.

[exports]
type = null
status = implemented
usedby = plugin
description = Indicate that symbols are exported.


[exports/_]
type = func
status = implemented
usedby = plugin
description = Allows a plugin to export any functions.
	Typical names are get, set, error, open or close.

	A plugin can export symbols for external use. Users of
	the library can look for these symbols and get a pointer to a function.
	Other plugins, however, are not supposed to use these symbols.
	checkfile can be used for resolvers.

	The name of the symbols can be any valid
	C name. It contains a function pointer as value to enable applications to call
	the function. Given the plugin and symbol’s name the function pointer
	can be accessed by a unique locator in the global key database.

	The usage of such functions will couple plugins or applications
	tightly, so avoid them if possible.

[constants]
type = null
status = implemented
usedby = plugin
description = Indicate that constants are available.

[constants/_]
type = string
status = implemented
usedby = plugin
description = Exports constants that might be interesting for users,
	applications or other plugins.
	All plugin specific compilation information (e.g. verbosity, paths)
	should be exported as constants.

[infos]
type = string
status = implemented
usedby = plugin
description = Indicate that info is available.
	These clauses are required so that plugins can be mounted.

[infos/author]
type = string
status = implemented
usedby = plugin spec
description = The name and e-mail address of the author of the plugin.
	It blames the person responsible for the plugin.
	The plugin must behave as described in the contract.

	This clause should contain an e-mail address so that direct contact is possible.
	If you want, you can get an @libelektra.org e-mail address.


[infos/licence]
type = string
status = implemented
example = BSD
usedby = plugin spec
description = The licence relevant for the user of the plugin.
	For plugins published with Elektra it is "BSD".
	Note that it might be illegal to use some combinations of licences,
	so "BSD" is preferred whenever possible.
	If the plugin links against a library, the library’s licence might
	enforce another licence.

	Note that even if the
	plugin’s code is BSD licenced (Berkeley Software Distribution)
	but it links against GPL (GNU General Public
	License) code, the contract needs to say GPL.

	BSD stands for the simplified, three-clause BSD licence that is used by Elektra itself.
	For any plugin which does not declare the licence to be BSD currently,
	a warning will be displayed during the mount process, because the overall
	licence of the installation concerned may change.
	The warning might be wrong, if the licence actually is compatible.

[infos/description]
type = string
status = implemented
usedby = plugin spec
description = The full text describing everything relevant for the
	users, developers or maintainers of this plugin.
	Do not duplicate information from other clauses.

	Explains informally what the plugin does. It
	should be humanly readable and will not be parsed or checked. The person
	reading it should get an idea if, and why, this plugin should be used.
	This clause is the most important, but not used for the
	contract’s validity.

	It should use Markdown syntax.

	It should contain long tutorial-like explanations.
	Use README.md to make the content easily readable and editable.

	The clause should at least contain:
	- Purpose
	- Possible Usage
	- (Current) Limitations, Roadmap or TODOs
	- Dependencies
	- affiliated Projects or Plugins
	- relevant Links for further Information


[infos/provides]
type = enum
	apply
	binary
	check
	code
	conv
	crypto
	error
	filefilter
	logging
	notification
	resolver
	storage
	tracing
status = implemented
usedby = plugin
description = Introduces a more abstract name (=provider) for the type
	of problem the plugin solves.

	A plugin indicates that it
	is a provider for all activities necessary to fulfil
	a specific mission. The name already provides users with an
	understanding what this assignment is. Together with an informal text
	(`infos/description`) it exactly describes the responsibilities.
	Other plugins can utilise this service.

	The above enum lists (in type) the current known providers, even though any other
	name can be used, too.
	Note, that similar to adding new clauses, usages of prefixes is
	highly recommended to avoid name conflicts with future providers added
	here.


[infos/placements]
type = enum
	prerollback
	rollback
	postrollback
	getresolver
	pregetstorage
	getstorage
	postgetstorage
	setresolver
	presetstorage
	setstorage
	precommit
	commit
	postcommit
status = implemented
usedby = plugin
description = gives a list of places in which the plugin must appear.
	During mounting, the algorithm checks if a free slot is available in
	the requested position. Because of this clause the placement works
	automatically.

	The type enumerates the only supported placements for mountpoints.
	For global plugins, for every placement additional placement information
	can be given separated by slash (ignored by regular mountpoints).

	The places refer to names given
	in [elektra-ordering(7)](/doc/help/elektra-ordering.md).
	During mounting, the algorithm checks if
	a free slot is available in the requested position. Because of this
	clause the placement works automatically.


[infos/ordering]
type = string
status = implemented
usedby = plugin
description = requests that a list of plugins or provided names is not
	present at the time of insertion. If such a plugin is already there,
	the order constraint is violated. Note, that the relation to the
	storage and resolver plugins is already determined using the clause
	placement.

	So it is a simple way to ensure that your plugin will be added before
	the one given with this contract clause.

[infos/stacking]
type = string
status = implemented
usedby = plugin
description = any non-empty string disables the stacking of plugins.
	By default, plugins in
	postgetstorage are ordered in reverse order than in presetstorage.
	This is called stacking. The stacking reintroduces the feature which
	would automatically be available when only one array of plugins is
	processed bidirectionally.

[infos/needs]
type = list <string>
status = implemented
usedby = plugin spec
example = null code
description = Lists the requirements of the plugin.
	This can be a name of a plugin, but you should always prefer
	the name of providers.
	Then, any plugin providing the functionality can be used and the
	coupling is reduced.

	infos/needs is the counterpart of provides. Using it, plugins
	delegate some work to other plugins. They need a provider of a specific
	service to work properly. The clause describes that the plugin can
	only fulfil its work if a specific service is present in the backend.
	It does not state when the work has to be done. The clause only declares
	that such a provider must be present anywhere in the backend. The name
	can also directly refer to another plugin’s name.

[infos/recommends]
type = string
status = implemented
usedby = plugin spec
description = Recommendations are similar to needs, but the backend
	also validates if they are not included.

[infos/metadata]
type = null
status = implemented
usedby = spec
example = check/validation check/validation/message
description = a space separated list of metanames a plugin will take care of.
	(implements the semantics for)

	Which metadata exists is defined in doc/METADATA.ini.

	Note that if you need other plugins to work properly
	(e.g. that consume metadata that your plugin writes or
	that create the metadata that your plugin consumes)
	use infos/needs and infos/ordering instead!

	Note that this is also documentation for the supported
	metadata. The metadata itself, however should be
	described in doc/METADATA.ini.

[infos/plugins]
type = string
status = implemented
usedby = plugin spec
description = Load plugins as given (with arguments as in "kdb mount").

	Note that, if plugin is already loaded somewhere else, the plugin
	will be loaded twice. Additionally, they will not be loaded recursively,
	but only by those plugins that were given explicitly.
	So you should prefer providers and needs to declare dependencies.

	It is only useful as an "alias" for a group of plugins.


[infos/status]
type = vector<int enum>
	{"default",      64000}, ; will be added by the build system for KDB_DEFAULT_STORAGE and KDB_DEFAULT_RESOLVER
	{"recommended",  32000}, ; in case of doubt, use this plugin
	{"productive",    8000}, ; actively used in productive environments, not only by maintainer
	{"maintained",    4000}, ; actively used and fixed by maintainer (infos/author)
	{"reviewed",      4000}, ; actively reviewed on every change and not by maintainer
	{"conformant",    2000}, ; to indicate that e.g. a storage plugin fulfils all requirements of a storage plugin
	{"compatible",    2000}, ; to indicate it will be compatible with its later versions
	{"coverage",      2000}, ; unittests have full code coverage
	{"specific",      1000}, ; means that the plugin is non-portable in order to gain some specific advantages for the user
	                         ; (i.e. in a positive sense specific/non-portable)
	{"unittest",      1000}, ; substantial plugin unittests (testmod)
	{"shelltest",     1000}, ; substantial unittests with shell
	{"tested",         500}, ; extensively manually tested on every change
	{"nodep",          250}, ; no external library dependencies, except the languages core deps, e.g. libstdc++ and other plugins in `needs`
	{"libc",           250}, ; uses libc only, no deps of other language’s run-times, e.g., libstdc++
	{"configurable",    50}, ; options available to modify behavior
	{"final",           50}, ; no further extensions, configure options or features are desirable
	{"global",           1}, ; suitable as global plugin
	{"readonly",         0}, ; can only read data from files (only kdbGet implemented)
	{"writeonly",        0}, ; can only write data to files (only kdbSet implemented)
	{"preview",        -50}, ; plugin in technical preview state
	{"memleak",       -250}, ; memleak in plugin or one of the libraries the plugin uses
	{"experimental",  -500}, ; not much tested, plugin is in early stage
	{"difficult",     -500}, ; the plugin is (unnecessarily) difficult to use
	{"limited",       -750}, ; cannot represent arbitrary data (i.e. very specific format)
	{"unfinished",   -1000}, ; important functionality still missing
	{"old",          -1000}, ; code base is old and should be refactored/improved
	{"nodoc",        -1000}, ; documentation is minimal
	{"concept",      -2000}, ; the plugin only exists to demonstrate something
	{"orphan",       -4000}, ; author does not respond and also otherwise not much knowledge about plugin is present
	{"obsolete",     -4000}, ; another plugin fulfils a similar functionality in a better way
	{"discouraged", -32000}, ; only use the plugin if you really know what you are doing
status = implemented
usedby = plugin spec binding
description = Tags about how well-established and well-working a plugin is.

	Different status can be combined.

	Numerical values are allowed, too. Please argue in the infos/description why
	numerical values are used.

	When changing some value in the type, you need to copy the information to
	src/libs/tools/src/plugindatabase.cpp
	src/plugins/template/README.md


[infos/version]
type = string
status = implemented
usedby = plugin spec
example = 1
description = Exports the plugin version this plugin was compiled
	against. Use the macro PLUGINVERSION in kdbplugin.h for its value.
	The current version is the major version as indicated in this file.

	The version implies how the plugin interface must look like.

[config/needs]
type = null
status = implemented
usedby = plugin spec
description = Exports a plugin configuration needed by another plugin. All keys
	below `config/needs` will be propagated to the backend configuration.
	Usually a provider in infos/needs then will use this configuration.
	Alternatively, it can be provided if it avoids conflicts with some
	other plugins.

	It presents the plugin configuration needed so that
	the plugin works properly. Typically the configuration is not for the
	plugin itself, but for other needed plugins (in infos/needs).


[infos/environment]
type = string
status = PROPOSED
usedby = plugin kdb-info
example = HOME USER
description = List all environment variables the plugin
	may access.

	Note: Not listed environment variables do not mean that there
	are none (the clause is only proposed, not yet implemented).
	Grep for `getenv` to list all environment variables.


[infos/dependencies/_]
type = string
status = PROPOSED
usedby = plugin kdb-info
example = libyajl-dev
description = The list of dependencies a plugin has for
	a specific package management system (like deb, rpm,
	arch, homebrew, ...).

	Note: Not listed dependencies do not mean that there
	are none (the clause is only proposed, not yet implemented).
	See `infos/status` with `nodep` for up-to-date information.
