Skip to content
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

Import from Bazel #3

Merged
merged 1 commit into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions .bazelci/presubmit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
buildifier: latest

matrix:
platform:
- ubuntu2004
- macos
# TODO: Enable Windows once the private API it allowlists rules_shell.
# - windows

tasks:
test_module_bzlmod:
name: "Test module (Bazel 7.3.2, Bzlmod)"
working_directory: "tests/bcr"
bazel: 7.3.2
platform: ${{ platform }}
build_flags:
- "--enable_bzlmod"
- "--noenable_workspace"
build_targets:
- "//..."
test_flags:
- "--enable_bzlmod"
- "--noenable_workspace"
test_targets:
- "//..."
test_module_workspace:
name: "Test module (Bazel 7.3.2, WORKSPACE)"
working_directory: "tests/bcr"
bazel: 7.3.2
platform: ${{ platform }}
build_flags:
- "--noenable_bzlmod"
- "--enable_workspace"
build_targets:
- "//..."
test_flags:
- "--noenable_bzlmod"
- "--enable_workspace"
test_targets:
- "//..."
test_module_head:
name: "Test module (Bazel@HEAD, Bzlmod)"
working_directory: "tests/bcr"
bazel: last_green
platform: ${{ platform }}
build_flags:
- "--enable_bzlmod"
- "--noenable_workspace"
build_targets:
- "//..."
test_flags:
- "--enable_bzlmod"
- "--noenable_workspace"
test_targets:
- "//..."
1 change: 1 addition & 0 deletions .bazelignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tests/bcr
20 changes: 20 additions & 0 deletions .bcr/metadata.template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"homepage": "https://github.com/bazelbuild/rules_shell",
"maintainers": [
{
"email": "[email protected]",
"github": "meteorcloudy",
"name": "Yun Peng"
},
{
"email": "[email protected]",
"github": "fmeum",
"name": "Fabian Meumertzheim"
}
],
"repository": [
"github:bazelbuild/rules_shell"
],
"versions": [],
"yanked_versions": {}
}
17 changes: 17 additions & 0 deletions .bcr/presubmit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
bcr_test_module:
module_path: tests/bcr
matrix:
platform:
- centos7
- debian10
- ubuntu2004
- macos
- windows
bazel: [6.x, 7.x]
tasks:
run_test_module:
name: Run test module
platform: ${{ platform }}
bazel: ${{ bazel }}
test_targets:
- "//..."
5 changes: 5 additions & 0 deletions .bcr/source.template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"integrity": "**leave this alone**",
"strip_prefix": "{REPO}-{VERSION}",
"url": "https://github.com/{OWNER}/{REPO}/releases/download/{TAG}/{REPO}-{TAG}.tar.gz"
}
18 changes: 18 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Cut a release whenever a new tag is pushed to the repo.
# You should use an annotated tag, like `git tag -a v1.2.3`
# and put the release notes into the commit message for the tag.
name: Release

on:
push:
tags:
- "v*.*.*"

permissions:
contents: write

jobs:
release:
uses: bazel-contrib/.github/.github/workflows/release_ruleset.yaml@v6
with:
release_files: rules_shell-*.tar.gz
45 changes: 45 additions & 0 deletions .github/workflows/release_prep.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env bash

set -o errexit -o nounset -o pipefail

# Set by GH actions, see
# https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables
TAG=${GITHUB_REF_NAME}
# The prefix is chosen to match what GitHub generates for source archives
# This guarantees that users can easily switch from a released artifact to a source archive
# with minimal differences in their code (e.g. strip_prefix remains the same)
PREFIX="rules_shell-${TAG:1}"
ARCHIVE="rules_shell-$TAG.tar.gz"

# NB: configuration for 'git archive' is in /.gitattributes
git archive --format=tar --prefix="${PREFIX}/" "${TAG}" | gzip > "$ARCHIVE"
SHA=$(shasum -a 256 "$ARCHIVE" | awk '{print $1}')

cat << EOF
## Using Bzlmod with Bazel 6 or greater

1. (Bazel 6 only) Enable with \`common --enable_bzlmod\` in \`.bazelrc\`.
2. Add to your \`MODULE.bazel\` file:

\`\`\`starlark
bazel_dep(name = "rules_shell", version = "${TAG:1}")
\`\`\`

## Using WORKSPACE

Paste this snippet into your \`WORKSPACE.bazel\` file:

\`\`\`starlark
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "rules_shell",
sha256 = "${SHA}",
strip_prefix = "${PREFIX}",
url = "https://github.com/bazelbuild/rules_shell/releases/download/${TAG}/${ARCHIVE}",
)

load("@rules_shell//shell:repositories.bzl", "rules_shell_dependencies", "rules_shell_toolchains")
rules_shell_dependencies()
rules_shell_toolchains()
\`\`\`
EOF
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
bazel-*

MODULE.bazel.lock
11 changes: 11 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module(
name = "rules_shell",
version = "0.0.0",
)

bazel_dep(name = "platforms", version = "0.0.10")

sh_configure = use_extension("//shell/private/extensions:sh_configure.bzl", "sh_configure")
use_repo(sh_configure, "local_config_shell")

register_toolchains("@local_config_shell//:all")
Empty file added WORKSPACE
Empty file.
15 changes: 15 additions & 0 deletions shell/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# A runtime toolchain for shell scripts.
#
# Use `sh_toolchain` to register a toolchain for this type.
#
# Every toolchain registered for this type has the following attributes:
# - `path`: The path to the shell interpreter for the target platform.
#
# Other attribute may be present but are considered implementation details of
# Bazel's sh_* rules.
#
# Toolchains registered for this type should have target constraints.
toolchain_type(
name = "toolchain_type",
visibility = ["//visibility:public"],
)
Empty file added shell/private/BUILD
Empty file.
Empty file added shell/private/extensions/BUILD
Empty file.
23 changes: 23 additions & 0 deletions shell/private/extensions/sh_configure.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2018 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""The sh_configure module extension."""

load("//shell/private/repositories:sh_config.bzl", "sh_config")

def _sh_configure_impl(module_ctx):
sh_config(name = "local_config_shell")
return module_ctx.extension_metadata(reproducible = True)

sh_configure = module_extension(implementation = _sh_configure_impl)
Empty file.
140 changes: 140 additions & 0 deletions shell/private/repositories/sh_config.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# Copyright 2018 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Configure sh_toolchains based on the local machine."""

visibility(["//shell", "//shell/private/extensions"])

_DEFAULT_SHELL_PATHS = {
"windows": "c:/msys64/usr/bin/bash.exe",
"linux": "/bin/bash",
"osx": "/bin/bash",
"freebsd": "/usr/local/bin/bash",
"openbsd": "/usr/local/bin/bash",
}

_UNIX_SH_TOOLCHAIN_TEMPLATE = """
sh_toolchain(
name = "{os}_sh",
path = {sh_path},
)
"""

_WINDOWS_SH_TOOLCHAIN_TEMPLATE = """
sh_toolchain(
name = "{os}_sh",
path = {sh_path},
launcher = "@bazel_tools//tools/launcher",
launcher_maker = "@bazel_tools//tools/launcher:launcher_maker",
)
"""

_TOOLCHAIN_TEMPLATE = """
toolchain(
name = "{os}_sh_toolchain",
toolchain = ":{os}_sh",
toolchain_type = "@rules_shell//shell:toolchain_type",
target_compatible_with = [
"@platforms//os:{os}",
],
)
"""

def _sh_config_impl(repository_ctx):
"""sh_config rule implementation.

Creates sh_toolchains for commonly supported target platforms.
For the target platform matching the local machine, it detects the path of
the shell interpreter instead of using the default path.

Args:
repository_ctx: the repository rule context object
"""
toolchains = []
for os, default_shell_path in _DEFAULT_SHELL_PATHS.items():
is_host = repository_ctx.os.name.startswith(os)
if is_host:
# This toolchain was first added before optional toolchains were
# available, so instead of not registering a toolchain if we
# couldn't find the shell, we register a toolchain with an empty
# path.
sh_path = _detect_local_shell_path(repository_ctx) or ""
else:
sh_path = default_shell_path

sh_toolchain_template = _WINDOWS_SH_TOOLCHAIN_TEMPLATE if os == "windows" else _UNIX_SH_TOOLCHAIN_TEMPLATE
toolchains.append(sh_toolchain_template.format(
os = os,
sh_path = repr(sh_path),
))
toolchains.append(_TOOLCHAIN_TEMPLATE.format(
os = os,
))

repository_ctx.file("BUILD", """
load("@rules_shell//shell/toolchains:sh_toolchain.bzl", "sh_toolchain")
""" + "\n".join(toolchains))

sh_config = repository_rule(
environ = [
"WINDIR",
"PATH",
],
# TODO: Replace this with configure = True and add BAZEL_SH to the
# environ list above for consistency with CC and other repo rules.
# This would make discovery differ from --shell_executable.
local = True,
implementation = _sh_config_impl,
)

def _detect_local_shell_path(repository_ctx):
if repository_ctx.os.name.startswith("windows"):
return _detect_local_shell_path_windows(repository_ctx)
else:
return _detect_local_shell_path_unix(repository_ctx)

def _detect_local_shell_path_windows(repository_ctx):
sh_path = repository_ctx.os.environ.get("BAZEL_SH")
if sh_path:
return sh_path.replace("\\", "/")

sh_path_obj = repository_ctx.which("bash.exe")
if sh_path_obj:
# repository_ctx.which returns a path object, convert that to
# string so we can call string.startswith on it.
sh_path = str(sh_path_obj)

# When the Windows Subsystem for Linux is installed there's a
# bash.exe under %WINDIR%\system32\bash.exe that launches Ubuntu
# Bash which cannot run native Windows programs so it's not what
# we want.
windir = repository_ctx.os.environ.get("WINDIR")
if not windir or not sh_path.startswith(windir):
return sh_path.replace("\\", "/")

return None

def _detect_local_shell_path_unix(repository_ctx):
sh_path = repository_ctx.os.environ.get("BAZEL_SH")
if sh_path:
return sh_path

sh_path_obj = repository_ctx.which("bash")
if sh_path_obj:
return str(sh_path_obj)

sh_path_obj = repository_ctx.which("sh")
if sh_path_obj:
return str(sh_path_obj)

return None
Loading