Skip to content

Commit

Permalink
Merge pull request #3319 from ElektraInitiative/versioning
Browse files Browse the repository at this point in the history
Versioning
  • Loading branch information
mpranj committed Dec 4, 2019
2 parents 485be13 + d138602 commit ad0ac3d
Show file tree
Hide file tree
Showing 27 changed files with 142 additions and 77 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Expand Up @@ -5,8 +5,8 @@ set (CMAKE_USER_MAKE_RULES_OVERRIDE "${CMAKE_SOURCE_DIR}/scripts/cmake/Platform.

set (KDB_VERSION_MAJOR 0)
set (KDB_VERSION_MINOR 9)
set (KDB_VERSION_MICRO 1)
set (KDB_VERSION "${KDB_VERSION_MAJOR}.${KDB_VERSION_MINOR}.${KDB_VERSION_MICRO}")
set (KDB_VERSION_PATCH 1)
set (KDB_VERSION "${KDB_VERSION_MAJOR}.${KDB_VERSION_MINOR}.${KDB_VERSION_PATCH}")

set (ELEKTRA_DESCRIPTION
"Elektra serves as a universal and secure framework to access configuration settings in a global, hierarchical key database.")
Expand Down
144 changes: 102 additions & 42 deletions doc/VERSION.md
Expand Up @@ -2,47 +2,85 @@

The version of Elektra is handled with the kdb.h macros
`KDB_VERSION` which is a string and `KDB_VERSION_MAJOR`,
`KDB_VERSION_MINOR` and `KDB_VERSION_MICRO` which are
numbers. They represent the public announced version
information.
`KDB_VERSION_MINOR` and `KDB_VERSION_PATCH` which are
numbers for the publicly announced versions.

The same information can be retrieved at run-time using
The version can also be retrieved at run-time from KDB:

```
system/elektra/version/constants/KDB_VERSION
system/elektra/version/constants/KDB_VERSION_MAJOR
system/elektra/version/constants/KDB_VERSION_MICRO
system/elektra/version/constants/KDB_VERSION_MINOR
system/elektra/version/constants/KDB_VERSION_PATCH
```

This is the API to programs using Elektra. Its interface
is defined in [src/include/kdb.h](/src/include/kdb.h.in).
Both applications and plugins use this API.

Additionally there is also a very small API
to plugins. It consists of only 5 functions
and is described in [src/plugins/doc/doc.c](/src/plugins/doc/doc.c).
## Scope

The version applies to following parts of Elektra:

- the API for programs using Elektra. Its interface
is declared in [src/include/kdb.h](/src/include/kdb.h.in).
Both applications and plugins use this API.
- the high-level API as declared in
[src/include/elektra.h](/src/include/elektra.h).
- the API to plugins as declared in
[src/plugins/doc/doc.h](/src/plugins/doc/doc.h).
- the API to [libease](/src/include/kdbease.h)
- the API to [libmeta](/src/include/kdbmeta.h)
- the API to [libmerge](/src/include/kdbmerge.h)
- the API to [module loading](/src/include/kdbmodule.h)
- the API to [libnotification](/src/include/kdbnotification.h)
- the API to [libopts](/src/include/kdbopts.h)
- plugins that have `infos/status` of `compatible`.
- the CLI tool `kdb` with its command-line
arguments, KDB access and its return values.

## Behavior

The following order defines the behavior of Elektra:

1. [ABI](/tests/abi) test cases
2. Non-ABI test cases (including Shell Recorder)
3. The [API documentation](https://doc.libelektra.org/api/latest/html/)
4. The [man pages](/doc/help)
5. Tutorials (excluding Shell Recorder)
6. Examples

Any inconsistency within this artifacts within each other
or with the implementation constitutes a bug.

## Compatibility

This section describes under which circumstances API
and ABI incompatibilities may occur. As developer from
Elektra your mission is to avoid that.
The tool icheck against the interfaces mentioned
above may help you too.

In `0.8.*` the API and ABI must be always forward-compatible,
and ABI incompatibilities may occur. As Elektra developer
your mission is to avoid any unwanted incompatibilities.
The tool icheck which checks the interfaces mentioned
in the Scope may help you.

Elektra uses a stricter version of
[Semantic Versioning 2.0.0](https://semver.org/),
with the extensions explained here.

In `1.0.*` the API and ABI must be always forward-compatible
and backwards-compatible.
That means that Elektra's libraries may be upgraded and downgraded
without any effect on applications, only bug or docu fixes
are allowed.

In minor or patch version updates the API and ABI must be always forward-compatible,
but not backwards-compatible.
That means that a program written and compiled against 0.8.0
compiles and links against 0.8.1. But because it is
That means that a program written and compiled against 1.0.0
compiles and links against 1.1.0. But because it is
not necessarily backwards-compatible a program written
for 0.8.1 may not link or compile against elektra 0.8.0
(but it may do when you use the compatible subset, maybe
with #ifdefs).
for 1.1.0 may not link or compile against Elektra 1.0.0
(but it compiles if you use the compatible subset, maybe
by using #ifdefs).
Also here applications must continue to work as originally
intended.

Following points are allowed:
When you add a new function you break ABI and API backward-
compatibility, but not forward, so you are allowed to do so.
compatibility (but not forward). You are only allowed to
do so in a `1.*` change.

In the signature you are only allowed to add const to
any parameter. You are _not_ allowed to use subtypes to
Expand All @@ -59,24 +97,46 @@ a complex topic, so better don't underestimate it, but
generally said the methods should behave on the same data
the same way.

As we use [symbol versioning](dev/symbol-versioning.md), the SO_VERSION
of Elektra always remains the same, even if the major version changes.
That means, if we rename or remove a function in the `2.0` release,
applications that linked against Elektra `1.0` can still link against
Elektra `2.0` but they do not necessarily compile with Elektra `2.0`
anymore. Once the code is adapted to use `2.0`, it cannot link against
`1.0` anymore. Note that this feature is only available on platforms
that support symbol versioning. For other platforms, all applications
need to be recompiled for every major version.

In major upgrades, changes of behavior is possible even if it might
break some use cases of some applications. Furthermore, symbols
that already have been deprecated before, might be removed.
For example, in `1.0` there is a deprecated method `ksNext` (not
available in `kdb.h`). Thus in `2.0` it is subject to be removed.

References:
http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html
http://packages.debian.org/de/sid/icheck

## Increment

This section describes how to increment the `KDB_VERSION`.
It consists of a triplet integer `current:revision:age`.

`revision` is something which will always incremented when there
is a new bug fix release.

`current` and `age` will be incremented by one when you release
a compatible but changed API. The revision is set back to zero then.

Note: All 3 versioning infos are handled separately!

http://www.gnu.org/software/libtool/manual/libtool.html#Versioning
http://semver.org/

> TODO write about SO_VERSION and rest version
## Bindings

Bindings are in general tied to Elektra's version number except
for the patch level. So bindings can only add or change
functionality when Elektra's core does.
This is a quite severe restriction but makes the version
much easier to understand for users. It serves the goal
that Elektra does not prefer any programming languages,
instead people expect from Elektra version `x.y.*`
identical functionality.

The patch level can be chosen by bindings as wanted.
Using the binding `x.y.z` does not mean that
Elektra `x.y.z` will be used on the target system.
Please read the changelog of the binding maintainers to
know about which bug fixes are included.

The patch level might also be used to fix bugs within bindings.
This means that applications can only introspect the patch
level of Elektra by getting `system/elektra/version/constants/KDB_VERSION_PATCH`
but not by static patch levels the binding might provide.
This should be no problem, as the patch level is supposed
to not change the behavior.
2 changes: 1 addition & 1 deletion doc/api_blueprints/elektrad.apib
Expand Up @@ -22,7 +22,7 @@ for further information and explanation see [doc/VERSION.md](https://github.com/
+ version: 0.8.23 (string) - The currently used version in its complete format
+ major: 0 (number) - The currently used major version
+ minor: 8 (number) - The currently used minor version
+ micro: 23 (number) - The currently used micro version
+ patch: 23 (number) - The currently used patch version


## elektra key database [/kdb/{+path}]
Expand Down
2 changes: 1 addition & 1 deletion doc/api_blueprints/snippet-sharing.apib
Expand Up @@ -32,7 +32,7 @@ Returns the current version of the API and Elektra. The API version is increased
+ version: `0.8.18` (string) - The currently used version in its complete format
+ major: `0` (number) - The currently used major version
+ minor: `8` (number) - The currently used minor version
+ micro: `18` (number) - The currently used micro version
+ patch: `18` (number) - The currently used patch version
+ api: `1` (number) - The version of the API itself


Expand Down
4 changes: 2 additions & 2 deletions doc/api_blueprints/webd.apib
Expand Up @@ -25,7 +25,7 @@ for further information and explanation see [doc/VERSION.md](https://github.com/
+ version: 0.8.23 (string) - The currently used version in its complete format
+ major: 0 (number) - The currently used major version
+ minor: 8 (number) - The currently used minor version
+ micro: 23 (number) - The currently used micro version
+ patch: 23 (number) - The currently used patch version



Expand Down Expand Up @@ -269,7 +269,7 @@ copy a key (and all its subkeys) to a new path - works like `kdb cp -r`
+ version (string) - The currently used version in its complete format
+ major (number) - The currently used major version
+ minor (number) - The currently used minor version
+ micro (number) - The currently used micro version
+ patch (number) - The currently used patch version

## Instance (object)
+ id: `46a288ae-7475-4cdd-a04c-3826c9a4b5f5` (string, required)
Expand Down
4 changes: 4 additions & 0 deletions doc/news/_preparation_next_release.md
Expand Up @@ -71,6 +71,10 @@ The text below summarizes updates to the [C (and C++)-based libraries](https://w

### Compatibility

- We clarified compatibility requirements for Elektra and its plugins and bindings.
Furthermore, we renamed `system/elektra/version/constants/KDB_VERSION_MICRO`
to `system/elektra/version/constants/KDB_VERSION_PATCH` to be compatible
with [Semantic Versioning 2.0.0](https://semver.org/). _(Markus Raab)_
- <<TODO>>
- <<TODO>>
- <<TODO>>
Expand Down
3 changes: 2 additions & 1 deletion scripts/build/run_icheck
Expand Up @@ -11,7 +11,8 @@ BUILD_DIR="$BASE_DIR/build"
ICHECK_DIR="$BASE_DIR/icheck"

CMPVERSION="0.9.1"
FILES="src/include/kdbmeta.h src/include/kdbease.h src/include/kdbplugin.h src/include/kdbproposal.h"
# XXX: updates here require update in doc/VERSION.md
FILES="src/include/kdbmeta.h src/include/kdbease.h src/include/kdbmerge.h src/include/kdbmodule.h src/include/kdbnotification.h src/include/kdbplugin.h src/plugins/doc/doc.h src/include/kdbopts.h"

# =============
# = Functions =
Expand Down
2 changes: 1 addition & 1 deletion scripts/cmake/ElektraConfig.cmake.in
Expand Up @@ -39,7 +39,7 @@ set (ELEKTRA_TEMPLATES ${Elektra_TEMPLATES_DIR})
set (ELEKTRA_VERSION ${Elektra_VERSION})
set (ELEKTRA_VERSION_MAJOR ${Elektra_VERSION_MAJOR})
set (ELEKTRA_VERSION_MINOR ${Elektra_VERSION_MINOR})
set (ELEKTRA_VERSION_MICRO ${Elektra_VERSION_MICRO})
set (ELEKTRA_VERSION_PATCH ${Elektra_VERSION_PATCH})

# Set build type of Elektra
set (Elektra_BUILD_TYPE @Elektra_BUILD_TYPE@)
Expand Down
8 changes: 4 additions & 4 deletions scripts/cmake/Modules/FindGLib.cmake
Expand Up @@ -50,12 +50,12 @@ if (GLib_LIBRARY AND NOT GLib_FOUND)
string (REGEX REPLACE "^#define GLIB_MAJOR_VERSION ([0-9]+)$" "\\1" GLib_MAJOR_VERSION "${GLib_MAJOR_VERSION}")
file (STRINGS "${GLib_CONFIG_INCLUDE_DIR}/glibconfig.h" GLib_MINOR_VERSION REGEX "^#define GLIB_MINOR_VERSION +([0-9]+)")
string (REGEX REPLACE "^#define GLIB_MINOR_VERSION ([0-9]+)$" "\\1" GLib_MINOR_VERSION "${GLib_MINOR_VERSION}")
file (STRINGS "${GLib_CONFIG_INCLUDE_DIR}/glibconfig.h" GLib_MICRO_VERSION REGEX "^#define GLIB_MICRO_VERSION +([0-9]+)")
string (REGEX REPLACE "^#define GLIB_MICRO_VERSION ([0-9]+)$" "\\1" GLib_MICRO_VERSION "${GLib_MICRO_VERSION}")
set (GLib_VERSION "${GLib_MAJOR_VERSION}.${GLib_MINOR_VERSION}.${GLib_MICRO_VERSION}")
file (STRINGS "${GLib_CONFIG_INCLUDE_DIR}/glibconfig.h" GLib_PATCH_VERSION REGEX "^#define GLIB_PATCH_VERSION +([0-9]+)")
string (REGEX REPLACE "^#define GLIB_PATCH_VERSION ([0-9]+)$" "\\1" GLib_PATCH_VERSION "${GLib_PATCH_VERSION}")
set (GLib_VERSION "${GLib_MAJOR_VERSION}.${GLib_MINOR_VERSION}.${GLib_PATCH_VERSION}")
unset (GLib_MAJOR_VERSION)
unset (GLib_MINOR_VERSION)
unset (GLib_MICRO_VERSION)
unset (GLib_PATCH_VERSION)

list (APPEND GLib_INCLUDE_DIRS ${GLib_CONFIG_INCLUDE_DIR})
set_property (TARGET ${GLib} PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${GLib_INCLUDE_DIRS}")
Expand Down
2 changes: 1 addition & 1 deletion src/bindings/glib/gelektra-constants.h.in
Expand Up @@ -14,6 +14,6 @@
#define GELEKTRA_VERSION "@KDB_VERSION@"
#define GELEKTRA_VERSION_MAJOR @KDB_VERSION_MAJOR@
#define GELEKTRA_VERSION_MINOR @KDB_VERSION_MINOR@
#define GELEKTRA_VERSION_MICRO @KDB_VERSION_MICRO@
#define GELEKTRA_VERSION_PATCH @KDB_VERSION_PATCH@

#endif
2 changes: 1 addition & 1 deletion src/bindings/glib/gelektra-kdb.h
Expand Up @@ -37,7 +37,7 @@ typedef enum {
#define GELEKTRA_VERSION KDB_VERSION
#define GELEKTRA_VERSION_MAJOR KDB_VERSION_MAJOR
#define GELEKTRA_VERSION_MINOR KDB_VERSION_MINOR
#define GELEKTRA_VERSION_MICRO KDB_VERSION_MICRO
#define GELEKTRA_VERSION_PATCH KDB_VERSION_PATCH
#endif

struct _GElektraKdb
Expand Down
2 changes: 1 addition & 1 deletion src/bindings/swig/common.i
Expand Up @@ -43,7 +43,7 @@
%constant const char *VERSION = KDB_VERSION;
%constant const short VERSION_MAJOR = KDB_VERSION_MAJOR;
%constant const short VERSION_MINOR = KDB_VERSION_MINOR;
%constant const short VERSION_MICRO = KDB_VERSION_MICRO;
%constant const short VERSION_PATCH = KDB_VERSION_PATCH;
// we only care about the enums. ignore the c functions
%ignore ckdb;
%include "kdb.h"
Expand Down
2 changes: 1 addition & 1 deletion src/bindings/swig/lua/tests/test_kdb.lua
Expand Up @@ -12,7 +12,7 @@ assert(type(kdb.DEBUG) == "number")
assert(type(kdb.VERSION) == "string")
assert(type(kdb.VERSION_MAJOR) == "number")
assert(type(kdb.VERSION_MINOR) == "number")
assert(type(kdb.VERSION_MICRO) == "number")
assert(type(kdb.VERSION_PATCH) == "number")
assert(kdb.KS_END == nil)

-- ctor
Expand Down
2 changes: 1 addition & 1 deletion src/bindings/swig/python/tests/test_kdb.py
Expand Up @@ -16,7 +16,7 @@ def test_kdb_h(self):
self.assertIsInstance(kdb.VERSION, str)
self.assertIsInstance(kdb.VERSION_MAJOR, int)
self.assertIsInstance(kdb.VERSION_MINOR, int)
self.assertIsInstance(kdb.VERSION_MICRO, int)
self.assertIsInstance(kdb.VERSION_PATCH, int)
self.assertIsNone(kdb.KS_END)

class KDB(unittest.TestCase):
Expand Down
2 changes: 1 addition & 1 deletion src/bindings/swig/ruby/kdb.i
Expand Up @@ -70,7 +70,7 @@ namespace std {
%constant const char *VERSION = KDB_VERSION;
%constant const short VERSION_MAJOR = KDB_VERSION_MAJOR;
%constant const short VERSION_MINOR = KDB_VERSION_MINOR;
%constant const short VERSION_MICRO = KDB_VERSION_MICRO;
%constant const short VERSION_PATCH = KDB_VERSION_PATCH;
/* we only care about the enums. ignore the c functions */
%ignore ckdb;
%include "kdb.h"
Expand Down
2 changes: 1 addition & 1 deletion src/include/kdb.h.in
Expand Up @@ -24,7 +24,7 @@
#define KDB_VERSION "@KDB_VERSION@"
#define KDB_VERSION_MAJOR @KDB_VERSION_MAJOR@
#define KDB_VERSION_MINOR @KDB_VERSION_MINOR@
#define KDB_VERSION_MICRO @KDB_VERSION_MICRO@
#define KDB_VERSION_PATCH @KDB_VERSION_PATCH@

/* ENABLE_OPTIMIZATIONS */
#cmakedefine ELEKTRA_ENABLE_OPTIMIZATIONS
Expand Down
2 changes: 1 addition & 1 deletion src/include/kdbinternal.h
Expand Up @@ -26,7 +26,7 @@ namespace ckdb
extern "C" {
#endif

// can be made simply without elektra's internals, so better keep it as
// can be made simply without Elektra's internals, so better keep it as
// extension.
ssize_t keySetStringF (Key * key, const char * format, ...);

Expand Down
4 changes: 2 additions & 2 deletions src/include/kdbversion.h.in
Expand Up @@ -30,8 +30,8 @@ static inline KeySet *elektraVersionKeySet (void)
KEY_VALUE, "@KDB_VERSION_MAJOR@", KEY_END),
keyNew ("system/elektra/version/constants/KDB_VERSION_MINOR",
KEY_VALUE, "@KDB_VERSION_MINOR@", KEY_END),
keyNew ("system/elektra/version/constants/KDB_VERSION_MICRO",
KEY_VALUE, "@KDB_VERSION_MICRO@", KEY_END),
keyNew ("system/elektra/version/constants/KDB_VERSION_PATCH",
KEY_VALUE, "@KDB_VERSION_PATCH@", KEY_END),
keyNew ("system/elektra/version/constants/SO_VERSION",
KEY_VALUE, "@SO_VERSION@", KEY_END),
keyNew ("system/elektra/version/infos",
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/constants/README.md
Expand Up @@ -88,8 +88,8 @@ kdb ls user/tests/constants
#> user/tests/constants/package/tool_execdir
#> user/tests/constants/version
#> user/tests/constants/version/KDB_VERSION_MAJOR
#> user/tests/constants/version/KDB_VERSION_MICRO
#> user/tests/constants/version/KDB_VERSION_MINOR
#> user/tests/constants/version/KDB_VERSION_PATCH
#> user/tests/constants/version/SO_VERSION
#> user/tests/constants/version/SO_VERSION_GETENV
#> user/tests/constants/version/SO_VERSION_TOOLS
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/constants/constants.c.in
Expand Up @@ -55,8 +55,8 @@ static void elektraAddConstants (KeySet * ks, Key * parentKey)


key = keyDup (parentKey);
keyAddName (key, "version/KDB_VERSION_MICRO");
keySetString (key, "@KDB_VERSION_MICRO@");
keyAddName (key, "version/KDB_VERSION_PATCH");
keySetString (key, "@KDB_VERSION_PATCH@");
ksAppendKey (ks, key);


Expand Down
4 changes: 2 additions & 2 deletions src/tools/web/elektrad/src/index.js
Expand Up @@ -29,8 +29,8 @@ getVersions()
error(`are you sure you have libelektra and kdb installed?`);
process.exit(1);
} else {
const { major, minor, micro } = versions.elektra;
const versionSupported = major >= 0 && minor >= 8 && micro >= 23;
const { major, minor, patch } = versions.elektra;
const versionSupported = major >= 0 && minor >= 8 && patch >= 23;
if (!versionSupported) {
error(
`you are running an old libelektra version, which is not supported`
Expand Down
2 changes: 1 addition & 1 deletion src/tools/web/elektrad/src/versions.js
Expand Up @@ -4,7 +4,7 @@
* @brief exports a function to get the API and elektra versions
*
* e.g.
* { api: 1, elektra: { version: '0.8.19', major: 0, minor: 8, micro: 19 } }
* { api: 1, elektra: { version: '0.8.19', major: 0, minor: 8, patch: 19 } }
*
* @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
*/
Expand Down

0 comments on commit ad0ac3d

Please sign in to comment.