Skip to content

Commit

Permalink
Create common build settings (#154)
Browse files Browse the repository at this point in the history
Create common simple build settings for people to use so they don't recreate these rules over and over again. 

This fulfills part of the SBC design doc: https://docs.google.com/document/d/1vc8v-kXjvgZOdQdnxPTaV0rrLxtP2XwnD2tAZlYJOqw/edit#bookmark=id.iiumwic0jphr
  • Loading branch information
ngiloq6 authored and c-parsons committed Jun 14, 2019
1 parent 6539483 commit 89df357
Show file tree
Hide file tree
Showing 3 changed files with 274 additions and 0 deletions.
94 changes: 94 additions & 0 deletions rules/common_settings.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Copyright 2019 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.

"""Common build setting rules
These rules return a BuildSettingInfo with the value of the build setting.
For label-typed settings, use the native label_flag and label_setting rules.
More documentation on how to use build settings at
https://docs.bazel.build/versions/master/skylark/config.html#user-defined-build-settings
"""

BuildSettingInfo = provider(
doc = "A singleton provider that contains the raw value of a build setting",
fields = ["value"]
)

def _impl(ctx):
return BuildSettingInfo(value = ctx.build_setting_value)

int_flag = rule(
implementation = _impl,
build_setting = config.int(flag = True),
doc = "An int-typed build setting that can be set on the command line",
)

int_setting = rule(
implementation = _impl,
build_setting = config.int(),
doc = "An int-typed build setting that cannot be set on the command line",
)

bool_flag = rule(
implementation = _impl,
build_setting = config.bool(flag = True),
doc = "A bool-typed build setting that can be set on the command line",
)

bool_setting = rule(
implementation = _impl,
build_setting = config.bool(),
doc = "A bool-typed build setting that cannot be set on the command line",
)

string_list_flag = rule(
implementation = _impl,
build_setting = config.string_list(flag = True),
doc = "A string list-typed build setting that can be set on the command line",
)

string_list_setting = rule(
implementation = _impl,
build_setting = config.string_list(),
doc = "A string list-typed build setting that cannot be set on the command line",
)

def _string_impl(ctx):
allowed_values = ctx.attr.values
value = ctx.build_setting_value
if len(allowed_values) == 0 or value in ctx.attr.values:
return BuildSettingInfo(value = value)
else:
fail("Error setting "+ str(ctx.label) + ": invalid value '" + value + "'. Allowed values are " + str(allowed_values))

string_flag = rule(
implementation = _string_impl,
build_setting = config.string(flag = True),
attrs = {
"values" : attr.string_list(
doc = "The list of allowed values for this setting. An error is raised if any other value is given."
)},
doc = "A string-typed build setting that can be set on the command line",
)

string_setting = rule(
implementation = _string_impl,
build_setting = config.string(),
attrs = {
"values" : attr.string_list(
doc = "The list of allowed values for this setting. An error is raised if any other value is given."
)},
doc = "A string-typed build setting that cannot be set on the command line",
)
11 changes: 11 additions & 0 deletions tests/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,17 @@ sh_test(
tags = ["local"],
)

sh_test(
name = "common_settings_e2e_test",
srcs = ["common_settings_test.sh"],
data = [
":unittest.bash",
"//rules:common_settings.bzl",
"@bazel_tools//tools/bash/runfiles",
],
tags = ["local"],
)

shell_args_test_gen(
name = "shell_spawn_e2e_test_src",
)
Expand Down
169 changes: 169 additions & 0 deletions tests/common_settings_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
#!/bin/bash

# Copyright 2019 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.
#
# End to end tests for common_settings.bzl

# --- begin runfiles.bash initialization ---
set -euo pipefail
if [[ ! -d "${RUNFILES_DIR:-/dev/null}" && ! -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
if [[ -f "$0.runfiles_manifest" ]]; then
export RUNFILES_MANIFEST_FILE="$0.runfiles_manifest"
elif [[ -f "$0.runfiles/MANIFEST" ]]; then
export RUNFILES_MANIFEST_FILE="$0.runfiles/MANIFEST"
elif [[ -f "$0.runfiles/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
export RUNFILES_DIR="$0.runfiles"
fi
fi
if [[ -f "${RUNFILES_DIR:-/dev/null}/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
source "${RUNFILES_DIR}/bazel_tools/tools/bash/runfiles/runfiles.bash"
elif [[ -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
source "$(grep -m1 "^bazel_tools/tools/bash/runfiles/runfiles.bash " \
"$RUNFILES_MANIFEST_FILE" | cut -d ' ' -f 2-)"
else
echo >&2 "ERROR: cannot find @bazel_tools//tools/bash/runfiles:runfiles.bash"
exit 1
fi
# --- end runfiles.bash initialization ---

source "$(rlocation bazel_skylib/tests/unittest.bash)" \
|| { echo "Could not source bazel_skylib/tests/unittest.bash" >&2; exit 1; }

function create_volcano_pkg() {
local -r pkg="$1"
mkdir -p "$pkg"
cd "$pkg"

cat > WORKSPACE <<EOF
workspace(name = 'bazel_skylib')
EOF

mkdir -p rules
cat > rules/BUILD <<EOF
exports_files(["*.bzl"])
EOF

ln -sf "$(rlocation bazel_skylib/rules/common_settings.bzl)" rules/common_settings.bzl

mkdir -p volcano
cat > volcano/rules.bzl <<EOF
load("//rules:common_settings.bzl", "BuildSettingInfo")
def _volcano_impl(ctx):
description = struct(
height = ctx.attr.height[BuildSettingInfo].value,
active = ctx.attr.active[BuildSettingInfo].value,
namer = ctx.attr.namer[BuildSettingInfo].value,
nicknames = ctx.attr.nicknames[BuildSettingInfo].value
)
print(description)
volcano = rule(
implementation = _volcano_impl,
attrs = {
"height" : attr.label(),
"active" : attr.label(),
"namer": attr.label(),
"nicknames": attr.label(),
}
)
EOF

cat > volcano/BUILD <<EOF
load(
"//rules:common_settings.bzl",
"int_flag",
"int_setting",
"bool_flag",
"string_flag",
"string_list_flag",
)
load("//volcano:rules.bzl", "volcano")
int_flag(
name = "height-flag",
build_setting_default = 9677 # pre-1980 explosion
)
bool_flag(
name = "active-flag",
build_setting_default = True
)
string_flag(
name = "namer-flag",
build_setting_default = "cpt-george-vancouver",
values = ["cpt-george-vancouver", "puyallup-tribe"]
)
string_list_flag(
name = "nicknames-flag",
build_setting_default = ["loowit", "loowitiatkla", "lavelatla"]
)
int_setting(
name = "height-setting",
build_setting_default = 9677
)
volcano(
name = "mt-st-helens",
height = ":height-flag",
active = ":active-flag",
namer = ":namer-flag",
nicknames = ":nicknames-flag",
)
EOF

}

function test_can_set_flags() {
local -r pkg="${FUNCNAME[0]}"
create_volcano_pkg "$pkg"

bazel build volcano:mt-st-helens --experimental_build_setting_api --//volcano:height-flag=8366 \
--//volcano:active-flag=False --//volcano:namer-flag=puyallup-tribe \
--//volcano:nicknames-flag=volcano-mc-volcanoface \
>"$TEST_log" 2>&1 || fail "Expected test to pass"

expect_log "active = False"
expect_log "height = 8366"
expect_log "namer = \"puyallup-tribe\""
expect_log "nicknames = \[\"volcano-mc-volcanoface\"\]"
}

function test_cannot_set_settings() {
local -r pkg="${FUNCNAME[0]}"
create_volcano_pkg "$pkg"

bazel build volcano:mt-st-helens --experimental_build_setting_api --//volcano:height-setting=8366 \
>"$TEST_log" 2>&1 && fail "Expected test to fail" || true

expect_log "Unrecognized option: //volcano:height-setting"
}

function test_not_allowed_value() {
local -r pkg="${FUNCNAME[0]}"
create_volcano_pkg "$pkg"

bazel build volcano:mt-st-helens --experimental_build_setting_api --//volcano:namer-flag=me \
>"$TEST_log" 2>&1 && fail "Expected test to fail" || true

expect_log "Error setting //volcano:namer-flag: invalid value 'me'. Allowed values are"
}


cd "$TEST_TMPDIR"
run_suite "common_settings test suite"

0 comments on commit 89df357

Please sign in to comment.