diff --git a/java/kotlin-extractor/BUILD.bazel b/java/kotlin-extractor/BUILD.bazel index b626ea40ac5..188f85b53a0 100644 --- a/java/kotlin-extractor/BUILD.bazel +++ b/java/kotlin-extractor/BUILD.bazel @@ -178,8 +178,18 @@ kt_javac_options( ) for variant in ("standalone", "embeddable") for version in VERSIONS], visibility = ["//visibility:public"], ), - sh_binary( - name = "print-default-version", - srcs = ["//java/kotlin-extractor/defaults:default-version-printer"], + genrule( + name = "versions-list", + outs = ["kotlin-versions.list"], + cmd = "\n".join(["cat > $@ << EOF"] + VERSIONS + ["EOF"]), + ), + # these are packed in the extractor pack for running QL tests + filegroup( + name = "version-picker", + srcs = [ + "pick-kotlin-version.py", + ":versions-list", + ], + visibility = ["//visibility:public"], ), ) if not _for_embeddable else None diff --git a/java/kotlin-extractor/current_kotlin_version.py b/java/kotlin-extractor/current_kotlin_version.py deleted file mode 100755 index 9211042b02a..00000000000 --- a/java/kotlin-extractor/current_kotlin_version.py +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python3 - -import subprocess -import re -import shutil - -kotlinc = shutil.which('kotlinc') -if kotlinc is None: - raise Exception("kotlinc not found") -res = subprocess.run([kotlinc, "-version"], text=True, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE) -if res.returncode != 0: - raise Exception(f"kotlinc -version failed: {res.stderr}") -m = re.match(r'.* kotlinc-jvm ([0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z][a-zA-Z0-9]*)?) .*', res.stderr) -if m is None: - raise Exception(f'Cannot detect version of kotlinc (got {res.stderr})') -print(m[1]) diff --git a/java/kotlin-extractor/defaults/BUILD.bazel b/java/kotlin-extractor/defaults/BUILD.bazel index f68bcb912b6..bd7d502b064 100644 --- a/java/kotlin-extractor/defaults/BUILD.bazel +++ b/java/kotlin-extractor/defaults/BUILD.bazel @@ -28,9 +28,3 @@ alias( kotlin_extractor_defaults.extractor_version, ), ) - -genrule( - name = "default-version-printer", - outs = ["print-default-version.sh"], - cmd = "echo echo %s > $@" % kotlin_extractor_defaults.version, -) diff --git a/java/kotlin-extractor/deps.bzl b/java/kotlin-extractor/deps.bzl index 7ba3ec1f8b7..6e55969f251 100644 --- a/java/kotlin-extractor/deps.bzl +++ b/java/kotlin-extractor/deps.bzl @@ -1,4 +1,4 @@ -load("//java/kotlin-extractor:versions.bzl", "VERSIONS", "version_less") +load("//java/kotlin-extractor:versions.bzl", "VERSIONS") load("//misc/bazel:lfs.bzl", "lfs_smudge") _kotlin_dep_build = """ @@ -69,42 +69,34 @@ def _embeddable_source_impl(repository_ctx): _embeddable_source = repository_rule(implementation = _embeddable_source_impl) -def _get_default_version(repository_ctx): +def _get_version(repository_ctx, available = []): default_version = repository_ctx.getenv("CODEQL_KOTLIN_SINGLE_VERSION") if default_version: return default_version - kotlin_plugin_versions = repository_ctx.path(Label("//java/kotlin-extractor:current_kotlin_version.py")) - python = repository_ctx.which("python3") or repository_ctx.which("python") - env = {} repository_ctx.watch(Label("//java/kotlin-extractor:dev/.kotlinc_version")) - if not repository_ctx.which("kotlinc"): - # take default from the kotlinc wrapper - path = repository_ctx.getenv("PATH") - path_to_add = repository_ctx.path(Label("//java/kotlin-extractor:dev")) - if not path: - path = str(path_to_add) - elif repository_ctx.os.name == "windows": - path = "%s;%s" % (path, path_to_add) - else: - path = "%s:%s" % (path, path_to_add) - env["PATH"] = path - res = repository_ctx.execute([python, kotlin_plugin_versions], environment = env) + version_picker = repository_ctx.path(Label("//java/kotlin-extractor:pick-kotlin-version.py")) + python = repository_ctx.which("python3") or repository_ctx.which("python") + + # use the kotlinc wrapper as fallback + path = repository_ctx.getenv("PATH") + path_to_add = repository_ctx.path(Label("//java/kotlin-extractor:dev")) + if not path: + path = str(path_to_add) + elif repository_ctx.os.name == "windows": + path = "%s;%s" % (path, path_to_add) + else: + path = "%s:%s" % (path, path_to_add) + res = repository_ctx.execute([python, version_picker] + available, environment = {"PATH": path}) if res.return_code != 0: fail(res.stderr) return res.stdout.strip() -def _get_available_version(version): - for available_version in reversed(VERSIONS): - if not version_less(version, available_version): - return available_version - fail("no available version found for version %s among:\n %s" % (version, " ".join(VERSIONS))) - def _defaults_impl(repository_ctx): - default_version = _get_default_version(repository_ctx) + default_version = _get_version(repository_ctx) default_variant = "standalone" if repository_ctx.getenv("CODEQL_KOTLIN_SINGLE_VERSION_EMBEDDABLE") in ("true", "1"): default_variant = "embeddable" - available_version = _get_available_version(default_version) + available_version = _get_version(repository_ctx, VERSIONS) info = struct( version = default_version, variant = default_variant, diff --git a/java/kotlin-extractor/pick-kotlin-version.py b/java/kotlin-extractor/pick-kotlin-version.py new file mode 100755 index 00000000000..d4d85820a8e --- /dev/null +++ b/java/kotlin-extractor/pick-kotlin-version.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +""" +Script to get currently installed kotlinc version. If a list of available versions is provided as input, +the last version of those lower or equal to the kotlinc version is printed. +""" + +import subprocess +import re +import shutil +import argparse +import sys + + +def version_tuple(v): + v, _, _ = v.partition('-') + return tuple(int(x) for x in v.split(".", 2)) + + +p = argparse.ArgumentParser(description=__doc__, fromfile_prefix_chars='@') +p.add_argument("available_versions", nargs="*", metavar="X.Y.Z") +opts = p.parse_args() + +kotlinc = shutil.which('kotlinc') +if kotlinc is None: + raise Exception("kotlinc not found") +res = subprocess.run([kotlinc, "-version"], text=True, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE) +if res.returncode != 0: + raise Exception(f"kotlinc -version failed: {res.stderr}") +m = re.match(r'.* kotlinc-jvm ([0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z][a-zA-Z0-9]*)?) .*', res.stderr) +if m is None: + raise Exception(f'Cannot detect version of kotlinc (got {res.stderr})') +version = m[1] +if opts.available_versions: + vt = version_tuple(version) + available = sorted(opts.available_versions, key=version_tuple, reverse=True) + for v in available: + if version_tuple(v) <= vt: + print(v) + sys.exit(0) + raise Exception(f'Cannot find an available version for {version}') +print(version)