-
Notifications
You must be signed in to change notification settings - Fork 17
feat: add utilities to generate rv_checksums and excluded_gems #283
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
97c51a7
cd24460
0cc523f
372421f
2324a06
933618b
3437d70
e7ba0a0
2aba6f9
5817670
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,14 +12,16 @@ module( | |
| # the versions resolved in users repositories. | ||
| bazel_dep(name = "bazel_features", version = "1.9.0") | ||
| bazel_dep(name = "bazel_skylib", version = "1.3.0") | ||
| bazel_dep(name = "cgrindel_bazel_starlib", version = "0.27.0") | ||
| bazel_dep(name = "platforms", version = "0.0.5") | ||
| bazel_dep(name = "rules_cc", version = "0.0.9") | ||
| bazel_dep(name = "rules_java", version = "7.2.0") | ||
| bazel_dep(name = "rules_shell", version = "0.4.1") | ||
| bazel_dep(name = "buildifier_prebuilt", version = "8.2.1.1") | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it have to be a runtime dependency?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunatley, yes. The tools use buildozer to update the
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it, thanks for explanation. |
||
|
|
||
| # Ruleset development dependencies. | ||
| bazel_dep(name = "aspect_bazel_lib", version = "2.22.0", dev_dependency = True) | ||
| bazel_dep(name = "bazel_skylib_gazelle_plugin", version = "1.9.0", dev_dependency = True) | ||
| bazel_dep(name = "buildifier_prebuilt", version = "8.2.1.1", dev_dependency = True) | ||
| bazel_dep(name = "gazelle", version = "0.47.0", dev_dependency = True) | ||
| bazel_dep(name = "rules_go", version = "0.59.0", dev_dependency = True) | ||
| bazel_dep(name = "stardoc", version = "0.8.0", dev_dependency = True) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| load("@rules_shell//shell:sh_binary.bzl", "sh_binary") | ||
| load("@rules_shell//shell:sh_test.bzl", "sh_test") | ||
|
|
||
| sh_binary( | ||
| name = "generate_excluded_gems", | ||
| srcs = ["generate_excluded_gems.sh"], | ||
| data = [ | ||
| "@buildifier_prebuilt//buildozer", | ||
| ], | ||
| visibility = ["//visibility:public"], | ||
| deps = [ | ||
| "@cgrindel_bazel_starlib//shlib/lib:fail", | ||
| "@rules_shell//shell/runfiles", | ||
| ], | ||
| ) | ||
|
|
||
| sh_test( | ||
| name = "generate_excluded_gems_test", | ||
| srcs = ["generate_excluded_gems_test.sh"], | ||
| data = [ | ||
| "testdata/default_gems.json", | ||
| "testdata/expected_excluded_gems_output.txt", | ||
| ":generate_excluded_gems", | ||
| ], | ||
| deps = [ | ||
| "@cgrindel_bazel_starlib//shlib/lib:assertions", | ||
| "@rules_shell//shell/runfiles", | ||
| ], | ||
| ) | ||
|
|
||
| sh_test( | ||
| name = "generate_excluded_gems_integration_test", | ||
| srcs = ["generate_excluded_gems_integration_test.sh"], | ||
| data = [ | ||
| "testdata/default_gems.json", | ||
| ":generate_excluded_gems", | ||
| ], | ||
| deps = [ | ||
| "@cgrindel_bazel_starlib//shlib/lib:assertions", | ||
| "@rules_shell//shell/runfiles", | ||
| ], | ||
| ) | ||
|
|
||
| filegroup( | ||
| name = "all_files", | ||
| srcs = glob(["**/*"]), | ||
| visibility = ["//:__subpackages__"], | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,171 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| # Generates excluded_gems for ruby.bundle_fetch() and updates MODULE.bazel. | ||
|
|
||
| # --- begin runfiles.bash initialization v3 --- | ||
| # Copy-pasted from the Bazel Bash runfiles library v3. | ||
| set -uo pipefail | ||
| set +e | ||
| f=bazel_tools/tools/bash/runfiles/runfiles.bash | ||
| # shellcheck disable=SC1090 | ||
| source "${RUNFILES_DIR:-/dev/null}/${f}" 2>/dev/null \ | ||
| || source "$(grep -sm1 "^${f} " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null \ | ||
| || source "$0.runfiles/${f}" 2>/dev/null \ | ||
| || source "$(grep -sm1 "^${f} " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null \ | ||
| || source "$(grep -sm1 "^${f} " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null \ | ||
| || { | ||
| echo >&2 "ERROR: ${BASH_SOURCE[0]} cannot find ${f}" | ||
| exit 1 | ||
| } | ||
| f= | ||
| set -e | ||
| # --- end runfiles.bash initialization v3 --- | ||
|
|
||
| # MARK - Dependencies | ||
|
|
||
| fail_sh_location=cgrindel_bazel_starlib/shlib/lib/fail.sh | ||
| fail_sh="$(rlocation "${fail_sh_location}")" \ | ||
| || (echo >&2 "Failed to locate ${fail_sh_location}" && exit 1) | ||
| # shellcheck disable=SC1090 | ||
| source "${fail_sh}" | ||
|
|
||
| # Locate buildozer via runfiles | ||
| buildozer_location=buildifier_prebuilt/buildozer/buildozer | ||
| buildozer="$(rlocation "${buildozer_location}")" \ | ||
| || (echo >&2 "Failed to locate ${buildozer_location}" && exit 1) | ||
|
|
||
| # MARK - Default Values | ||
|
|
||
| # Default values | ||
| dry_run=false | ||
| name="bundle" | ||
| module_bazel="${BUILD_WORKSPACE_DIRECTORY:-.}/MODULE.bazel" | ||
| ruby_version="" | ||
|
|
||
| # MARK - Functions | ||
|
|
||
| # Read .ruby-version file | ||
| read_ruby_version() { | ||
| local version_file="${BUILD_WORKSPACE_DIRECTORY}/.ruby-version" | ||
| if [[ ! -f ${version_file} ]]; then | ||
| fail "Error: .ruby-version not found and --ruby-version not specified" | ||
| fi | ||
| tr -d '[:space:]' <"${version_file}" | ||
| } | ||
|
|
||
| # Extract minor version from a Ruby version string (e.g., 3.4.8 -> 3.4) | ||
| # Ruby uses MAJOR.MINOR.PATCH versioning, and stdgems data is organized by | ||
| # minor version since default gems are typically consistent within a minor | ||
| # release series. | ||
| get_minor_version() { | ||
| local version="$1" | ||
| echo "${version}" | cut -d. -f1,2 | ||
| } | ||
|
|
||
| # MARK - Argument Handling | ||
|
|
||
| # Parse arguments | ||
| while (("$#")); do | ||
| case "${1}" in | ||
| --dry-run) | ||
| dry_run=true | ||
| shift | ||
| ;; | ||
| --ruby-version) | ||
| ruby_version="${2}" | ||
| shift 2 | ||
| ;; | ||
| --name) | ||
| name="${2}" | ||
| shift 2 | ||
| ;; | ||
| --module-bazel) | ||
| module_bazel="${2}" | ||
| shift 2 | ||
| ;; | ||
| -*) | ||
| fail "Error: Unknown option: ${1}" | ||
| ;; | ||
| *) | ||
| fail "Error: Unexpected argument: ${1}" | ||
| ;; | ||
| esac | ||
| done | ||
|
|
||
| # Get Ruby version | ||
| if [[ -z ${ruby_version} ]]; then | ||
| ruby_version="$(read_ruby_version)" | ||
| fi | ||
|
|
||
| # Get minor version | ||
| minor_version=$(get_minor_version "${ruby_version}") | ||
|
|
||
| # MARK - Retrieve stdgems data | ||
|
|
||
| # Fetch stdgems data | ||
| stdgems_url="${STDGEMS_URL:-https://raw.githubusercontent.com/janlelis/stdgems/main/default_gems.json}" | ||
| response=$(curl -sL --max-time 30 "${stdgems_url}") | ||
|
|
||
| # Filter for native gems that exist for this Ruby version | ||
| # The jq query: | ||
| # 1. Select gems where native == true | ||
| # 2. Select gems where versions contains the minor version key | ||
| # 3. Extract the gem name | ||
| # 4. Sort | ||
| excluded_gems=$(echo "${response}" | jq -r --arg version "${minor_version}" \ | ||
| '.gems[] | select(.native == true) | select(.versions | has($version)) | .gem' \ | ||
| | sort) | ||
|
|
||
| # Check if we found any gems | ||
| if [[ -z ${excluded_gems} ]]; then | ||
| fail <<-EOT | ||
| Error: No native gems found for Ruby ${ruby_version} (${minor_version}) | ||
| This Ruby version may not be supported in stdgems data | ||
| EOT | ||
| fi | ||
|
|
||
| # MARK - Update MODULE.bazel | ||
|
|
||
| # Generate output for dry-run or display | ||
| output="excluded_gems = [\n" | ||
| while IFS= read -r gem; do | ||
| output+=" \"${gem}\",\n" | ||
| done <<<"${excluded_gems}" | ||
| output+="]," | ||
|
|
||
| if [[ ${dry_run} == "true" ]]; then | ||
| # Dry-run: just output the excluded gems | ||
| echo -e "${output}" | ||
| exit 0 | ||
| fi | ||
|
|
||
| # Construct list of gems for buildozer 'add' command | ||
| # Convert newline-separated list to space-separated | ||
| gem_list="" | ||
| while IFS= read -r gem; do | ||
| gem_list+=" ${gem}" | ||
| done <<<"${excluded_gems}" | ||
|
|
||
| # Update MODULE.bazel using buildozer | ||
| buildozer_cmd=( | ||
| "${buildozer}" | ||
| -types ruby.bundle_fetch | ||
| "remove excluded_gems" | ||
| "add excluded_gems${gem_list}" | ||
| "${module_bazel}:${name}" | ||
| ) | ||
| if ! "${buildozer_cmd[@]}" 2>/dev/null; then | ||
| fail <<-EOT | ||
| Failed to update ${module_bazel} | ||
|
|
||
| Buildozer command failed. This could mean: | ||
| - The file doesn't exist at ${module_bazel} | ||
| - No ruby.bundle_fetch() call was found with name="${name}" | ||
| - The file has syntax errors | ||
|
|
||
| You can use --dry-run to see what would be updated: | ||
| $(echo -e "${output}") | ||
| EOT | ||
| fi | ||
|
|
||
| echo "Successfully updated excluded_gems in ${module_bazel}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it have to be a runtime dependency?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used some shell libraries from my repo in the tools. We can copy those utilities somewhere, but then you would need to maintain them here, as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's fine to use the dependency then.