Skip to content

Commit

Permalink
Make datamodel version a command line argument to the generator
Browse files Browse the repository at this point in the history
  • Loading branch information
tmadlener committed Aug 28, 2024
1 parent 40d42b0 commit f49fa45
Show file tree
Hide file tree
Showing 11 changed files with 60 additions and 68 deletions.
10 changes: 8 additions & 2 deletions cmake/podioMacros.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,14 @@ set_property(CACHE PODIO_USE_CLANG_FORMAT PROPERTY STRINGS AUTO ON OFF)
# LANG OPTIONAL: The programming language choice
# Default is cpp
# DEPENDS OPTIONAL: List of files to be added as configure dependencies of the datamodel
# VERSION OPTIONAL: The version of the datamodel (which does not have to be the schema version!)
# )
#
# Note that the create_${datamodel} target will always be called, but if the YAML_FILE has not changed
# this is essentially a no-op, and should not cause re-compilation.
#---------------------------------------------------------------------------------------------------
function(PODIO_GENERATE_DATAMODEL datamodel YAML_FILE RETURN_HEADERS RETURN_SOURCES)
CMAKE_PARSE_ARGUMENTS(ARG "" "OLD_DESCRIPTION;OUTPUT_FOLDER;UPSTREAM_EDM;SCHEMA_EVOLUTION" "IO_BACKEND_HANDLERS;LANG;DEPENDS" ${ARGN})
CMAKE_PARSE_ARGUMENTS(ARG "" "OLD_DESCRIPTION;OUTPUT_FOLDER;UPSTREAM_EDM;SCHEMA_EVOLUTION" "IO_BACKEND_HANDLERS;LANG;DEPENDS;VERSION" ${ARGN})
IF(NOT ARG_OUTPUT_FOLDER)
SET(ARG_OUTPUT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR})
ENDIF()
Expand Down Expand Up @@ -196,6 +197,11 @@ function(PODIO_GENERATE_DATAMODEL datamodel YAML_FILE RETURN_HEADERS RETURN_SOUR
endif()
endif()

set(VERSION_ARG "")
if (ARG_VERSION)
set(VERSION_ARG "--datamodel-version=${ARG_VERSION}")
endif()

# Make sure that we re run the generation process every time either the
# templates or the yaml file changes.
include(${podio_PYTHON_DIR}/templates/CMakeLists.txt)
Expand All @@ -215,7 +221,7 @@ function(PODIO_GENERATE_DATAMODEL datamodel YAML_FILE RETURN_HEADERS RETURN_SOUR
message(STATUS "Creating '${datamodel}' datamodel")
# we need to bootstrap the data model, so this has to be executed in the cmake run
execute_process(
COMMAND ${Python_EXECUTABLE} ${podio_PYTHON_DIR}/podio_class_generator.py ${CLANG_FORMAT_ARG} ${OLD_DESCRIPTION_ARG} ${SCHEMA_EVOLUTION_ARG} ${UPSTREAM_EDM_ARG} ${YAML_FILE} ${ARG_OUTPUT_FOLDER} ${datamodel} ${ARG_IO_BACKEND_HANDLERS} ${LANGUAGE_ARG}
COMMAND ${Python_EXECUTABLE} ${podio_PYTHON_DIR}/podio_class_generator.py ${CLANG_FORMAT_ARG} ${OLD_DESCRIPTION_ARG} ${SCHEMA_EVOLUTION_ARG} ${UPSTREAM_EDM_ARG} ${YAML_FILE} ${ARG_OUTPUT_FOLDER} ${datamodel} ${ARG_IO_BACKEND_HANDLERS} ${LANGUAGE_ARG} ${VERSION_ARG}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE podio_generate_command_retval
)
Expand Down
23 changes: 22 additions & 1 deletion python/podio_class_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import os
import subprocess

import re

from podio_gen.podio_config_reader import PodioConfigReader
from podio_gen.generator_utils import DefinitionError
Expand Down Expand Up @@ -72,6 +72,20 @@ def read_upstream_edm(name_path):
) from err


def parse_version(version_str):
"""Parse the version into a tuple of (major, minor, patch) from the passed
version string.
"""
if version_str is None:
return None

if re.match(r"v?(\d+)(\.|-)(\d+)((\.|-)(\d+))?$", version_str):
ver = version_str.replace("-", ".").replace("v", "").split(".")
return tuple(int(v) for v in ver)

raise argparse.ArgumentTypeError(f"{version_str} cannot be parsed as a valid version")


if __name__ == "__main__":
import argparse

Expand Down Expand Up @@ -147,6 +161,12 @@ def read_upstream_edm(name_path):
default=None,
action="store",
)
parser.add_argument(
"--datamodel-version",
help="The version string of the generated datamodel",
default=None,
type=parse_version,
)

args = parser.parse_args()

Expand Down Expand Up @@ -176,6 +196,7 @@ def read_upstream_edm(name_path):
verbose=args.verbose,
dryrun=args.dryrun,
upstream_edm=args.upstream_edm,
datamodel_version=args.datamodel_version,
old_description=args.old_description,
evolution_file=args.evolution_file,
)
Expand Down
14 changes: 12 additions & 2 deletions python/podio_gen/cpp_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,17 @@ def __init__(
upstream_edm,
old_description,
evolution_file,
datamodel_version=None,
):
super().__init__(yamlfile, install_dir, package_name, verbose, dryrun, upstream_edm)
super().__init__(
yamlfile,
install_dir,
package_name,
verbose,
dryrun,
upstream_edm,
datamodel_version=datamodel_version,
)
self.io_handlers = io_handlers

# schema evolution specific code
Expand Down Expand Up @@ -505,13 +514,14 @@ def _write_all_collections_header(self):
def _write_edm_def_file(self):
"""Write the edm definition to a compile time string"""
model_encoder = DataModelJSONEncoder()
print(f"{self.datamodel_version=}")
data = {
"package_name": self.package_name,
"edm_definition": model_encoder.encode(self.datamodel),
"incfolder": self.incfolder,
"schema_version": self.datamodel.schema_version,
"datatypes": self.datamodel.datatypes,
"version_info": self.datamodel.version_info,
"datamodel_version": self.datamodel_version,
}

def quoted_sv(string):
Expand Down
12 changes: 11 additions & 1 deletion python/podio_gen/generator_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,23 @@ class ClassGeneratorBaseMixin:
"""

def __init__(self, yamlfile, install_dir, package_name, verbose, dryrun, upstream_edm):
def __init__(
self,
yamlfile,
install_dir,
package_name,
verbose,
dryrun,
upstream_edm,
datamodel_version=None,
):
self.yamlfile = yamlfile
self.install_dir = install_dir
self.package_name = package_name
self.verbose = verbose
self.dryrun = dryrun
self.upstream_edm = upstream_edm
self.datamodel_version = datamodel_version

try:
self.datamodel = PodioConfigReader.read(yamlfile, package_name, upstream_edm)
Expand Down
8 changes: 1 addition & 7 deletions python/podio_gen/generator_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,6 @@ def __init__(
interfaces=None,
options=None,
schema_version=None,
version_info=None,
):
self.options = options or {
# should getters / setters be prefixed with get / set?
Expand All @@ -317,19 +316,14 @@ def __init__(
"includeSubfolder": False,
}
self.schema_version = schema_version
self.version_info = version_info
self.components = components or {}
self.datatypes = datatypes or {}
self.interfaces = interfaces or {}

def _to_json(self):
"""Return the dictionary, so that we can easily hook this into the pythons
JSON ecosystem"""
definition = deepcopy(self.__dict__)
# Only dump the version information if it's populated
if definition["version_info"] is None:
del definition["version_info"]
return definition
return self.__dict__


class DataModelJSONEncoder(json.JSONEncoder):
Expand Down
21 changes: 1 addition & 20 deletions python/podio_gen/podio_config_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,23 +531,6 @@ def parse_model(cls, model_dict, package_name, upstream_edm=None, parent_path=No
f"schema_version has to be convertible to int (is {model_dict['schema_version']})"
)

try:
version_info = model_dict["version_info"]
try:
for key in ("variable", "header"):
if not isinstance(version_info[key], str):
raise DefinitionError(
f"'version_info:{key} needs to be a single string, but is {version_info[key]}"
)
except KeyError:
raise DefinitionError(
"'version_info' needs to define a 'header' and a 'variable' to be valid"
f" but it defines {model_dict['version_info']}"
)
except KeyError:
version_info = None
pass

components = {}
if "components" in model_dict:
for klassname, value in model_dict["components"].items():
Expand Down Expand Up @@ -576,9 +559,7 @@ def parse_model(cls, model_dict, package_name, upstream_edm=None, parent_path=No

# If this doesn't raise an exception everything should in principle work out
validator = ClassDefinitionValidator()
datamodel = DataModel(
datatypes, components, interfaces, options, schema_version, version_info
)
datamodel = DataModel(datatypes, components, interfaces, options, schema_version)
validator.validate(datamodel, upstream_edm)
return datamodel

Expand Down
8 changes: 2 additions & 6 deletions python/templates/DatamodelDefinition.h.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@
#include "podio/DatamodelRegistry.h"
#include "podio/SchemaEvolution.h"

{% if version_info %}
#include "{{ version_info.header }}"
{% endif %}

namespace {{ package_name }}::meta {
/**
* The complete definition of the datamodel at generation time in JSON format.
Expand Down Expand Up @@ -50,8 +46,8 @@ public:
"{{ package_name }}",
{{ package_name }}__JSONDefinition,
relationNames
{% if version_info %}
, podio::version::Version({{ version_info.variable }})
{% if datamodel_version %}
, podio::version::Version{ {{ datamodel_version | join(", ") }} }
{% endif %}
));
return index.m_value;
Expand Down
2 changes: 1 addition & 1 deletion tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ set(extra_code extra_code/component_declarations.cc
)

PODIO_GENERATE_DATAMODEL(datamodel datalayout.yaml headers sources
IO_BACKEND_HANDLERS ${PODIO_IO_HANDLERS} DEPENDS ${extra_code}
IO_BACKEND_HANDLERS ${PODIO_IO_HANDLERS} DEPENDS ${extra_code} VERSION ${${PROJECT_NAME}_VERSION}
)

# Use the cmake building blocks to add the different parts (conditionally)
Expand Down
4 changes: 0 additions & 4 deletions tests/datalayout.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
---
schema_version : 2

version_info:
header: "datamodel/version.h"
variable: "datamodel::ver::version"

options :
# should getters / setters be prefixed with get / set?
getSyntax: False
Expand Down
20 changes: 0 additions & 20 deletions tests/datamodel/version.h

This file was deleted.

6 changes: 2 additions & 4 deletions tests/read_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

#include "datamodel/ExampleWithInterfaceRelationCollection.h"
#include "datamodel/ExampleWithVectorMemberCollection.h"
#include "datamodel/version.h"
#include "read_test.h"

#include "extension_model/ContainedTypeCollection.h"
Expand Down Expand Up @@ -118,10 +117,9 @@ int read_frames(const std::string& filename, bool assertBuildVersion = true) {
}

const auto datamodelVersion = reader.currentFileVersion("datamodel").value_or(podio::version::Version{});
if (assertBuildVersion && datamodelVersion != podio::version::Version(datamodel::ver::version)) {
if (assertBuildVersion && datamodelVersion != podio::version::build_version) {
std::cerr << "The (build) version of the datamodel could not be read back correctly. "
<< "(expected: " << podio::version::Version(datamodel::ver::version) << ", actual: " << datamodelVersion
<< ")" << std::endl;
<< "(expected: " << podio::version::build_version << ", actual: " << datamodelVersion << ")" << std::endl;
return 1;
}

Expand Down

0 comments on commit f49fa45

Please sign in to comment.