scikit-build/scikit-build-core

Executing Python commands from pyproject.toml

ahnaf-tahmid-chowdhury opened this issue · 5 comments

Description

I'm working on a project that maintains its version in CMakeLists.txt. The version string follows the format x.x.x or x.x.x-pre. To extract this version number and ensure its validity, I've added some configuration to pyproject.toml and created a Python script for validation.

The configuration in pyproject.toml looks like this:

# Get version from CMakeLists
[tool.scikit-build.metadata.version]
provider = "scikit_build_core.metadata.regex"
input = "CMakeLists.txt"
regex = 'SET\(PACKAGE_VERSION "(?P<value>[0-9.]+(-[a-z]+)?)"\)'

# Add the version to the package
[[tool.scikit-build.generate]]
path = "pymoab/_version.py"
template = '''
version = "${version}"
'''

And here's the Python script for validation (validate_version.py):

import re
import sys

def validate_version(version):
    pattern = re.compile(r'^[0-9]+\.[0-9]+\.[0-9]+(-[a-z]+)?$')
    if not pattern.match(version):
        raise ValueError(f"Invalid version string: {version}")

if __name__ == "__main__":
    validate_version(sys.argv[1])

Question

I'm unsure how to call the validate_version.py script from pyproject.toml. While I know I could use setup.py or add a command in CMakeLists.txt to run the Python script, I'm wondering if there's a way to execute Python commands directly from pyproject.toml.

You can't run arbitrary Python during the build, at least not yet. The general idea is users should use CMake if they want custom code. And you can't use setup.py, as we are not setuptools. :) Couldn't you just make sure the regex doesn't match if it's not of the pattern you want, though? Other ideas include a custom plugin, or a "validator" field could be added to the regex plugin.

After some investigation, it seems that Regix has its own built-in validators, which is nice. However, I noticed that whenever I set any string after a value, it always results in x.x.xrc0. Here is my configuration.

# CmakeLists.txt
SET(PACKAGE_VERSION "5.5.1-preview")
SET(PACKAGE_VERSION "5.5.1-pre")
SET(PACKAGE_VERSION "5.5.1-anything")

# pyproject.toml
# Get version from CMakeLists
[tool.scikit-build.metadata.version]
provider = "scikit_build_core.metadata.regex"
input = "CMakeLists.txt"
regex = 'SET\(PACKAGE_VERSION "(?P<value>[0-9.]+(?:-[a-z]+)?)"\)'

# Output
5.5.1rc0

If there is inbuilt support to understanding the semantic versioning specs, it would be great. For example, supporting pre-release tags would help this approach. Returning rc0 for all pre-release tags could be quite confusing.