|
| 1 | +"""MODULE wrapper to download jmxfetch JAR using variables from release.json. |
| 2 | +
|
| 3 | +This loads 'dependencies' from release.json and uses that to construct the |
| 4 | +appropriate Maven repository URL based on the jmxfetch version type: |
| 5 | +- Release versions (X.Y.Z) use Maven Central repo |
| 6 | +- Snapshot versions (X.Y.Z-identifier-timestamp) use Maven Snapshots repo |
| 7 | +
|
| 8 | +Usage: |
| 9 | + get_jmxfetch_using_release_constants = use_repo_rule(":module_utils.bzl", "get_jmxfetch_using_release_constants") |
| 10 | +
|
| 11 | + get_jmxfetch_using_release_constants( |
| 12 | + name = "jmxfetch", |
| 13 | + ) |
| 14 | +""" |
| 15 | + |
| 16 | +load("@bazel_tools//tools/build_defs/repo:cache.bzl", "DEFAULT_CANONICAL_ID_ENV", "get_default_canonical_id") |
| 17 | +load("@bazel_tools//tools/build_defs/repo:utils.bzl", "get_auth") |
| 18 | + |
| 19 | +get_jmxfetch_using_release_constants_attrs = { |
| 20 | + "executable": attr.bool( |
| 21 | + default = False, |
| 22 | + doc = "If the downloaded file should be made executable.", |
| 23 | + ), |
| 24 | + "target_filename": attr.string( |
| 25 | + default = "jmxfetch.jar", |
| 26 | + doc = "Name assigned to the downloaded file.", |
| 27 | + ), |
| 28 | + "canonical_id": attr.string(), |
| 29 | + "_release_info": attr.label(default = "//:release.json", allow_single_file = True), |
| 30 | +} |
| 31 | + |
| 32 | +def parse_jmxfetch_version(version): |
| 33 | + """Parse jmxfetch version to determine if it's release or snapshot. |
| 34 | +
|
| 35 | + Args: |
| 36 | + version: jmxfetch version |
| 37 | +
|
| 38 | + Returns: |
| 39 | + dict: is_snapshot, url: full download URL |
| 40 | + """ |
| 41 | + parts = version.split(".") |
| 42 | + |
| 43 | + # Release version has exactly 3 parts (X.Y.Z) |
| 44 | + if len(parts) == 3: |
| 45 | + # It's a release version |
| 46 | + url = "https://repo1.maven.org/maven2/com/datadoghq/jmxfetch/{VERSION}/jmxfetch-{VERSION}-jar-with-dependencies.jar".format(VERSION = version) |
| 47 | + return { |
| 48 | + "is_snapshot": False, |
| 49 | + "url": url, |
| 50 | + } |
| 51 | + |
| 52 | + # Otherwise it's a snapshot version like 0.48.0-20230706.234900 |
| 53 | + # Parse using regex to extract components |
| 54 | + for i in range(len(version)): |
| 55 | + if version[i] == "-": |
| 56 | + # Found first dash |
| 57 | + before_dash = version[:i] |
| 58 | + after_dash = version[i + 1:] |
| 59 | + |
| 60 | + # Check if before_dash is X.Y.Z format |
| 61 | + before_parts = before_dash.split(".") |
| 62 | + if len(before_parts) == 3: |
| 63 | + # Found the base version, now parse the rest |
| 64 | + # after_dash should be like "20230706.234900" |
| 65 | + # We need to split this into snapshot_version and timestamp |
| 66 | + after_parts = after_dash.split(".") |
| 67 | + if len(after_parts) >= 2: |
| 68 | + # snapshot_version is base + dash + date part |
| 69 | + snapshot_version = before_dash + "-" + after_parts[0] |
| 70 | + |
| 71 | + # timestamp is everything after the dot |
| 72 | + timestamp = ".".join(after_parts[1:]) |
| 73 | + |
| 74 | + # Reconstruct timestamped_version as base_version-timestamp |
| 75 | + timestamped_version = before_dash + "-" + timestamp |
| 76 | + |
| 77 | + url = "https://central.sonatype.com/repository/maven-snapshots/com/datadoghq/jmxfetch/{SNAPSHOT_VERSION}/jmxfetch-{TIMESTAMPED_VERSION}-jar-with-dependencies.jar".format( |
| 78 | + SNAPSHOT_VERSION = snapshot_version, |
| 79 | + TIMESTAMPED_VERSION = timestamped_version, |
| 80 | + ) |
| 81 | + return { |
| 82 | + "is_snapshot": True, |
| 83 | + "url": url, |
| 84 | + } |
| 85 | + |
| 86 | + # Fallback: treat as snapshot and construct best-effort URL |
| 87 | + url = "https://central.sonatype.com/repository/maven-snapshots/com/datadoghq/jmxfetch/{VERSION}/jmxfetch-{VERSION}-jar-with-dependencies.jar".format(VERSION = version) |
| 88 | + return { |
| 89 | + "is_snapshot": True, |
| 90 | + "url": url, |
| 91 | + } |
| 92 | + |
| 93 | +def _get_jmxfetch_using_release_constants_impl(rctx): |
| 94 | + """Implementation of the get_jmxfetch_using_release_constants rule.""" |
| 95 | + release_info = json.decode(rctx.read(rctx.path(rctx.attr._release_info))) |
| 96 | + vars = release_info["dependencies"] |
| 97 | + |
| 98 | + version = vars["JMXFETCH_VERSION"] |
| 99 | + sha256 = vars["JMXFETCH_HASH"] |
| 100 | + |
| 101 | + # Parse version and get URL |
| 102 | + version_info = parse_jmxfetch_version(version) |
| 103 | + url = version_info["url"] |
| 104 | + is_snapshot = version_info["is_snapshot"] |
| 105 | + |
| 106 | + # Determine license file version: 'master' for snapshots, version for releases |
| 107 | + license_file_version = "master" if is_snapshot else version |
| 108 | + |
| 109 | + repo_root = rctx.path(".") |
| 110 | + forbidden_files = [ |
| 111 | + repo_root, |
| 112 | + rctx.path("MODULE.bazel"), |
| 113 | + rctx.path("BUILD"), |
| 114 | + ] |
| 115 | + target_filename = rctx.attr.target_filename |
| 116 | + download_path = rctx.path("file/" + target_filename) |
| 117 | + |
| 118 | + if download_path in forbidden_files or not str(download_path).startswith(str(repo_root)): |
| 119 | + fail("'%s' cannot be used as target_filename in get_jmxfetch_using_release_constants" % rctx.attr.target_filename) |
| 120 | + |
| 121 | + # Download the JAR file |
| 122 | + rctx.download( |
| 123 | + [url], |
| 124 | + target_filename, |
| 125 | + sha256, |
| 126 | + rctx.attr.executable, |
| 127 | + canonical_id = rctx.attr.canonical_id or get_default_canonical_id(rctx, [url]), |
| 128 | + auth = get_auth(rctx, [url]), |
| 129 | + ) |
| 130 | + |
| 131 | + # Download the LICENSE file |
| 132 | + license_url = "https://raw.githubusercontent.com/DataDog/jmxfetch/{version}/LICENSE".format(version = license_file_version) |
| 133 | + rctx.download( |
| 134 | + [license_url], |
| 135 | + "LICENSE", |
| 136 | + ) |
| 137 | + |
| 138 | + rctx.file("MODULE.bazel", "module(name = \"{name}\")\n".format(name = rctx.name)) |
| 139 | + |
| 140 | + # Use template to generate BUILD file |
| 141 | + rctx.template( |
| 142 | + "BUILD", |
| 143 | + Label("//deps/jmxfetch:jmxfetch.BUILD.bazel"), |
| 144 | + substitutions = { |
| 145 | + "{target_filename}": target_filename, |
| 146 | + }, |
| 147 | + ) |
| 148 | + |
| 149 | + return rctx.repo_metadata(reproducible = True) |
| 150 | + |
| 151 | +get_jmxfetch_using_release_constants = repository_rule( |
| 152 | + implementation = _get_jmxfetch_using_release_constants_impl, |
| 153 | + attrs = get_jmxfetch_using_release_constants_attrs, |
| 154 | + environ = [DEFAULT_CANONICAL_ID_ENV], |
| 155 | +) |
0 commit comments