Skip to content

Commit

Permalink
refactor: improve the lock copy.sh script
Browse files Browse the repository at this point in the history
* separate the script into a template file so it's easier to shellcheck
  and syntax highlight in editors.

* shellcheck the script and remove all SC2086 warnings
  ("Double quote to prevent globbing and word splitting")

* improve the buildozer help messages in the copy.sh script:
  * reduce duplication of buildozer command
  * add a more clear autofix bazel run command that can be easily
    copy-pasted

* change some of the variable names in the copy.sh template for longer,
  easier to understand names (repo_name >> name, lock_label >> label)

* move repo_name and workspace_relative_path into variables to reduce
  line length and improve readability
  • Loading branch information
jjmaestro committed Sep 22, 2024
1 parent c038d26 commit 0afb5dc
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 49 deletions.
1 change: 1 addition & 0 deletions apt/private/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
exports_files([
"dpkg_statusd.sh",
"dpkg_status.sh",
"copy.sh.tmpl",
"package.BUILD.tmpl",
])

Expand Down
51 changes: 51 additions & 0 deletions apt/private/copy.sh.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/usr/bin/env bash

set -o pipefail -o errexit -o nounset

lock=$(realpath "$1")
autofix=${{2:-}}

cd "$BUILD_WORKING_DIRECTORY"

echo
echo "Writing lockfile to {workspace_relative_path}"
cp "$lock" "{workspace_relative_path}"

# Detect which file we wish the user to edit
if [ -e "$BUILD_WORKSPACE_DIRECTORY/WORKSPACE" ]; then
wksp_file="WORKSPACE"
elif [ -e "$BUILD_WORKSPACE_DIRECTORY/WORKSPACE.bazel" ]; then
wksp_file="WORKSPACE.bazel"
elif [ -e "$BUILD_WORKSPACE_DIRECTORY/MODULE.bazel" ]; then
wksp_file="MODULE.bazel"
else
echo>&2 "Error: no MODULE.bazel or WORKSPACE file was found"
exit 1
fi

# Detect a vendored buildozer binary in canonical location (tools/buildozer)
if [ -e "$BUILD_WORKSPACE_DIRECTORY/tools/buildozer" ]; then
buildozer="tools/buildozer"
else
# Assume it's on the $PATH
buildozer="buildozer"
fi

echo

cmd="$buildozer 'set lock \"{lock_label}\"' $wksp_file:{repo_name}"

if [[ "$autofix" == "--autofix" ]]; then
eval "$cmd"
else
cat <<EOF
Run the following command to add the 'lock' attribute
to the "{repo_name}" repo in $wksp_file:
$cmd
or run the following command to do it automatically:
bazel run @{repo_name}//:lock -- --autofix
EOF
fi
60 changes: 11 additions & 49 deletions apt/private/resolve.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -83,50 +83,6 @@ def internal_resolve(rctx, yq_toolchain_prefix, manifest, include_transitive):
lockf.add_package_dependency(package, dep, arch)
return lockf

_COPY_SH_TMPL = """\
#!/usr/bin/env bash
set -o pipefail -o errexit -o nounset
lock=$(realpath $1)
cd $BUILD_WORKING_DIRECTORY
echo ''
echo 'Writing lockfile to {workspace_relative_path}'
cp $lock {workspace_relative_path}
# Detect which file we wish the user to edit
if [ -e $BUILD_WORKSPACE_DIRECTORY/WORKSPACE ]; then
wksp_file="WORKSPACE"
elif [ -e $BUILD_WORKSPACE_DIRECTORY/WORKSPACE.bazel ]; then
wksp_file="WORKSPACE.bazel"
elif [ -e $BUILD_WORKSPACE_DIRECTORY/MODULE.bazel ]; then
wksp_file="MODULE.bazel"
else
echo>&2 "Error: no MODULE.bazel or WORKSPACE file was found"
exit 1
fi
# Detect a vendored buildozer binary in canonical location (tools/buildozer)
if [ -e $BUILD_WORKSPACE_DIRECTORY/tools/buildozer ]; then
buildozer="tools/buildozer"
else
# Assume it's on the $PATH
buildozer="buildozer"
fi
if [[ "${{2:-}}" == "--autofix" ]]; then
echo ''
${{buildozer}} 'set lock \"{label}\"' ${{wksp_file}}:{name}
else
cat <<EOF
Run the following command to add the lockfile or pass --autofix flag to do it automatically.
${{buildozer}} 'set lock \"{label}\"' ${{wksp_file}}:{name}
EOF
fi
"""

_BUILD_TMPL = """
filegroup(
name = "lockfile",
Expand All @@ -149,16 +105,22 @@ def _deb_resolve_impl(rctx):
lockf = internal_resolve(rctx, rctx.attr.yq_toolchain_prefix, rctx.attr.manifest, rctx.attr.resolve_transitive)
lockf.write("lock.json")

locklabel = rctx.attr.manifest.relative(rctx.attr.manifest.name.replace(".yaml", ".lock.json"))
lock_filename = rctx.attr.manifest.name.replace(".yaml", ".lock.json")
lock_label = rctx.attr.manifest.relative(lock_filename)
workspace_relative_path = "{}{}".format(
("%s/" % lock_label.package) if lock_label.package else "",
lock_label.name,
)

rctx.file(
"copy.sh",
_COPY_SH_TMPL.format(
rctx.read(Label("//apt/private:copy.sh.tmpl")).format(
# NOTE: the split("~") is needed when we run bazel from another
# directory, e.g. when running e2e tests we change dir to e2e/smoke
# and then rctx.name is 'rules_distroless~~apt~bullseye'
name = rctx.name.split("~")[-1].replace("_resolve", ""),
label = locklabel,
workspace_relative_path = (("%s/" % locklabel.package) if locklabel.package else "") + locklabel.name,
repo_name = rctx.name.split("~")[-1].replace("_resolve", ""),
lock_label = lock_label,
workspace_relative_path = workspace_relative_path,
),
executable = True,
)
Expand Down

0 comments on commit 0afb5dc

Please sign in to comment.