diff --git a/scripts/extract_version.py b/scripts/extract_version.py index 84f2461..4f8ceff 100644 --- a/scripts/extract_version.py +++ b/scripts/extract_version.py @@ -173,7 +173,14 @@ def increment_dev_version_number(base_version): return new_version -ENGINE_JAR_PATTERN = re.compile(r"^arcadedb-engine-(.+)\.jar$") +# The version is read by its shape (26.11.1, 26.11.1-SNAPSHOT, 26.11.1-RC1, +# 26.11.1-RC1-SNAPSHOT); anything after it is a Maven classifier +# (arcadedb-engine--tests.jar, -sources, -shaded, ...). A classifier jar counts +# under its own version: one of another version is a second engine, and it would +# ship on the classpath, so it must fail the check, not be skipped (#8). +ENGINE_JAR_PATTERN = re.compile( + r"^arcadedb-engine-(\d+(?:\.\d+)*(?:-RC\d+)?(?:-SNAPSHOT)?)(-[A-Za-z][A-Za-z0-9-]*)?\.jar$" +) def default_jars_dir(): @@ -191,14 +198,14 @@ def extract_raw_version_from_jars(jars_dir): if not jars_dir.is_dir(): raise FileNotFoundError(f"Jars directory not found: {jars_dir}") - versions = sorted( - { - match.group(1) - for match in (ENGINE_JAR_PATTERN.match(p.name) for p in jars_dir.iterdir()) - if match - } - ) - if not versions: + matches = [ + match + for match in (ENGINE_JAR_PATTERN.match(p.name) for p in jars_dir.iterdir()) + if match + ] + versions = sorted({match.group(1) for match in matches}) + # A classifier jar alone (-sources, -javadoc) is no engine to version from + if not any(match.group(2) is None for match in matches): raise ValueError(f"No arcadedb-engine-.jar found in {jars_dir}") if len(versions) > 1: raise ValueError( diff --git a/tests/test_extract_version_classifiers.py b/tests/test_extract_version_classifiers.py new file mode 100644 index 0000000..5a6738b --- /dev/null +++ b/tests/test_extract_version_classifiers.py @@ -0,0 +1,82 @@ +"""A classifier jar beside the engine jar is not a second engine version. + +``arcadedb-engine-(.+)\\.jar`` also matched ``arcadedb-engine-26.11.1-SNAPSHOT-tests.jar``, +read ``26.11.1-SNAPSHOT-tests`` as a version, and failed the build with "engine +jars of more than one version" on a valid jar set (#8). The upstream image +already ships classifier jars for other modules (``arcadedb-bolt--shaded.jar``). +""" + +from __future__ import annotations + +import importlib.util +from pathlib import Path + +import pytest + +SCRIPT_PATH = Path(__file__).resolve().parents[1] / "scripts" / "extract_version.py" + + +def _load(): + spec = importlib.util.spec_from_file_location("extract_version", SCRIPT_PATH) + module = importlib.util.module_from_spec(spec) + assert spec.loader is not None + spec.loader.exec_module(module) + return module + + +mod = _load() + + +@pytest.mark.parametrize("classifier", ["tests", "sources", "javadoc", "shaded", "all"]) +@pytest.mark.parametrize("version", ["26.11.1-SNAPSHOT", "26.10.2", "26.11.1-RC1"]) +def test_classifier_jar_is_not_a_version(tmp_path, version, classifier): + for name in ( + f"arcadedb-engine-{version}.jar", + f"arcadedb-engine-{version}-{classifier}.jar", + ): + (tmp_path / name).touch() + assert mod.extract_raw_version_from_jars(tmp_path) == version + + +def test_classifier_jar_alone_is_no_engine_jar(tmp_path): + (tmp_path / "arcadedb-engine-26.11.1-SNAPSHOT-sources.jar").touch() + with pytest.raises(ValueError, match="arcadedb-engine"): + mod.extract_raw_version_from_jars(tmp_path) + + +def test_two_real_versions_still_raise(tmp_path): + for name in ( + "arcadedb-engine-26.11.1-SNAPSHOT.jar", + "arcadedb-engine-26.11.1-SNAPSHOT-tests.jar", + "arcadedb-engine-26.10.2.jar", + ): + (tmp_path / name).touch() + with pytest.raises(ValueError, match="more than one version"): + mod.extract_raw_version_from_jars(tmp_path) + + +@pytest.mark.parametrize( + "classifier", ["all", "shaded", "jar-with-dependencies", "native"] +) +def test_classifier_jar_of_another_version_still_raises(tmp_path, classifier): + # A classifier jar carries the engine too, and ships on the classpath: one of + # another version is a second engine, not something to skip. + for name in ( + "arcadedb-engine-26.11.1-SNAPSHOT.jar", + f"arcadedb-engine-26.10.2-{classifier}.jar", + ): + (tmp_path / name).touch() + with pytest.raises(ValueError, match="26.10.2.*26.11.1-SNAPSHOT"): + mod.extract_raw_version_from_jars(tmp_path) + + +@pytest.mark.parametrize( + "classifier", ["jar-with-dependencies", "native", "test-sources"] +) +def test_any_classifier_is_read_under_its_version(tmp_path, classifier): + for name in ( + "arcadedb-engine-26.11.1-RC1.jar", + f"arcadedb-engine-26.11.1-RC1-{classifier}.jar", + ): + (tmp_path / name).touch() + assert mod.extract_raw_version_from_jars(tmp_path) == "26.11.1-RC1"