Package Version in the Device Configuration¶
Since Karabo 2.10, Devices packages are able to set the classVersion
property
in their configuration from helper functions.
The karabo packaging system installs devices from git
repositories. This section
will document the implementation in the various APIs.
The git version will be encoded in the device’s classVersion
property.
Rationale¶
The classVersion
property is set from the framework as a string formatted as
PackageName-git_tag
This implementation allows long-term storage of the installed packages in the archiving system for reproducibility. It also allows to spot if a package is not deployed with a tagged version on a live system.
Known Issues¶
The C++ API and the Python APIs do not use the same path to define the PackageName
string:
- In the case of the C++ API, the
PackageName
is set to the directory name of the root folder of the git repository. - In the case of the Python APIs, the
PackageName
is set to the name of the python module where the device class is defined.
In the case of packages created using the command karabo new
, this distinction does not
have consequences.
The complete code traceability would need to expose the url of the origin repository.
Due to the fact that for the European XFEL scope, the PackageName
and version are sufficient
and that the uri could be easily spoofed by custom network configurations. This feature is not
implemented.
C++ API¶
The karabo
script, currently supports installink c++ dependencies only through a Makefile
.
In the package’s Makefile
, add the following target:
PACKAGE_NAME=$(shell basename -s .git `git remote -v | grep fetch | head -n1 | awk '{ print $$2 }' `)
src/version.hh: .git/HEAD .git/index .git/refs/tags
@echo "// WARNING: This file is auto generated by the Makefile." > $@
@echo "#ifndef PACKAGE_VERSION" >> $@
# Note that --dirty can be fooled: Build once when clean and then change source files - or vice a versa...
@echo "#define PACKAGE_VERSION \"$(PACKAGE_NAME)-$(shell git describe --tags --match "*.*.*" --dirty --always )\"" >> $@
@echo "#endif" >> $@
Make sure to add the src/version.hh
file as a dependency to the library file target.
In case of devices generated from Karabo’s template, this target dependency is sufficient:
.build-pre: src/version.hh
In the file where the device class is defined, include the src/version.hh
file and
pass the PACKAGE_VERSION
define to the KARABO_CLASSINFO
macro.
#include "version.hh" // provides PACKAGE_VERSION
...
KARABO_CLASSINFO(DeviceClassName, "DeviceClassName", PACKAGE_VERSION)
The transient file src/version.hh
should not be included in the git repository and be added to
the .gitignore
file.
Python¶
For Python packages, Karabo uses the setuptools_scm
package to define a path where the version is saved.
In the setup.py
file, the following definition should be added:
ROOT_FOLDER = dirname(realpath(__file__))
VERSION_FILE_PATH = join(ROOT_FOLDER, 'src', 'deviceClassModule', '_version.py')
try:
from karabo.packaging.versioning import device_scm_version
scm_version = device_scm_version(ROOT_FOLDER, VERSION_FILE_PATH)
except ImportError:
# compatibility with karabo versions earlier than 2.10
scm_version = {'write_to': VERSION_FILE_PATH}
This conditional import definition allows compatibility with versions of Karabo earlier than 2.10.
In the setup
function call, one should add the import:
setup(name='DeviceClassName',
use_scm_version=scm_version,
...
Bound API¶
In the file where the device’s class is defined, one should import:
from ._version import version as deviceVersion
and decorate the device class with the decorator
@KARABO_CLASSINFO("DeviceClassName", deviceVersion)
Middlelayer API¶
In the file where the device’s class is defined, one should import:
from ._version import version as deviceVersion
and add the class attribute __version__
to the class:
class DeviceClassName(Device):
# provide version for classVersion property
__version__ = deviceVersion