Skip to content
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
5 changes: 5 additions & 0 deletions src/bmakelib.mk
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
# limitations under the License.
####################################################################################################

ifndef __bmakelib_bmakelib.mk
__bmakelib_bmakelib.mk := 1

####################################################################################################
#>
# # `bmakelib.MIN_MAKE_VERSION`
Expand Down Expand Up @@ -135,3 +138,5 @@ bmakelib.FEATURES := error-if-blank.mk default-if-blank.mk timed.mk logged.mk en
.PHONY : $(bmakelib.FEATURES:%=$(bmakelib.ROOT)%)

include $(bmakelib.FEATURES:%=$(bmakelib.ROOT)%)

endif # __bmakelib_bmakelib.mk
5 changes: 5 additions & 0 deletions src/default-if-blank.mk
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
# limitations under the License.
####################################################################################################

ifndef __bmakelib_default-if-blank.mk
__bmakelib_default-if-blank.mk := 1

####################################################################################################
#>
# # `bmakelib.default-if-blank`
Expand Down Expand Up @@ -93,3 +96,5 @@ bmakelib.default-if-blank(%) :
####################################################################################################

bmakelib.conf.default-if-blank.SILENT ?= $(or $(BMAKELIB_CONF_DEFAULT_IF_BLANK_SILENT),yes)

endif # __bmakelib_default-if-blank.mk
5 changes: 5 additions & 0 deletions src/dict.mk
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
# limitations under the License.
####################################################################################################

ifndef __bmakelib_dict.mk
__bmakelib_dict.mk := 1

####################################################################################################
#>
# # `bmakelib.dict`
Expand Down Expand Up @@ -217,3 +220,5 @@ bmakelib.dict.put(%) :
define bmakelib.dict.get
$(bmakelib.dict.define.__$(1).$(2))
endef

endif # __bmakelib_dict.mk
5 changes: 5 additions & 0 deletions src/enum.mk
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
# limitations under the License.
####################################################################################################

ifndef __bmakelib_enum.mk
__bmakelib_enum.mk := 1

####################################################################################################
#>
# # `bmakelib.enum.define`
Expand Down Expand Up @@ -162,3 +165,5 @@ $(eval \
,\
$(error '$($(2))' is not a member of enum '$(1)')))
endef

endif # __bmakelib_enum.mk
5 changes: 5 additions & 0 deletions src/error-if-blank.mk
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
# limitations under the License.
####################################################################################################

ifndef __bmakelib_error-if-blank.mk
__bmakelib_error-if-blank.mk := 1

####################################################################################################
#>
# # `bmakelib.error-if-blank`
Expand Down Expand Up @@ -42,3 +45,5 @@ bmakelib.error-if-blank(%) :
$(if $($(*)), \
, \
$(error Provide a value for '$(*)'))

endif # __bmakelib_error-if-blank.mk
5 changes: 5 additions & 0 deletions src/help.mk
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
# limitations under the License.
####################################################################################################

ifndef __bmakelib_help.mk
__bmakelib_help.mk := 1

.PHONY : _bmakelib.help.noop

_bmakelib.help.noop :
Expand Down Expand Up @@ -177,3 +180,5 @@ bmakelib.conf.help.tips ?= $(or $(BMAKELIB_CONF_HELP_TIPS),yes)
####################################################################################################

bmakelib.conf.help.show-bmakelib ?= $(or $(BMAKELIB_CONF_HELP_SHOW_BMAKELIB),no)

endif # __bmakelib_help.mk
6 changes: 6 additions & 0 deletions src/logged.mk
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
# limitations under the License.
####################################################################################################

ifndef __bmakelib_logged.mk
__bmakelib_logged.mk := 1

####################################################################################################
#>
# # `!!bmakelib.logged`
Expand Down Expand Up @@ -223,3 +226,6 @@ $(if $(filter yes,$(bmakelib.conf.logged.ECHO_COMMAND)),,@)exec 3>&1 4>&2 $(bmak
&& $(1)

endef

endif # __bmakelib_logged.mk

5 changes: 5 additions & 0 deletions src/shell.mk
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
# limitations under the License.
####################################################################################################

ifndef __bmakelib_shell.mk
__bmakelib_shell.mk := 1

####################################################################################################
#>
# # `bmakelib.shell.error-if-nonzero`
Expand Down Expand Up @@ -123,3 +126,5 @@ endef
####################################################################################################

bmakelib.conf.shell.error-if-nonzero.SILENT ?= $(or $(BMAKELIB_CONF_SHELL_ERROR_IF_NONZERO_SILENT),yes)

endif # __bmakelib_shell.mk
5 changes: 5 additions & 0 deletions src/timed.mk
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
# limitations under the License.
####################################################################################################

ifndef __bmakelib_timed.mk
__bmakelib_timed.mk := 1

####################################################################################################
#>
# # `!bmakelib.timed`
Expand Down Expand Up @@ -161,3 +164,5 @@ bmakelib._%!timed-post :
bmakelib._%!timed : bmakelib._%!timed-pre .WAIT % .WAIT bmakelib._%!timed-post
$(eval bmakelib.vars.timed.duration.$(*) := \
$(shell perl -E 'printf("%.0f", ($(bmakelib.vars.timed.end-ts.$(*)) - $(bmakelib.vars.timed.begin-ts.$(*))) / 1_000_000)'))

endif # __bmakelib_timed.mk
207 changes: 207 additions & 0 deletions tests/test_include-guard
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
#!/usr/bin/env bash
####################################################################################################
# Copyright © Bahman Movaqar
#
# 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.
####################################################################################################

set -o pipefail

test_suite_name=$(basename $BASH_SOURCE)
source ${root_dir}tests/lib.sh

####################################################################################################
# when bmakelib.mk is included multiple times, no warnings or errors should be emitted
####################################################################################################

function bmakelib_multiple_includes_no_warnings {
local test_case_name=${FUNCNAME[0]}
local actual_value_filename=${test_case_name}.actual.log
bmakelib.test.cat <<EOF > Makefile
SHELL := /usr/bin/env bash
include \$(bmakelib.ROOT)/bmakelib.mk
include \$(bmakelib.ROOT)/bmakelib.mk
include \$(bmakelib.ROOT)/bmakelib.mk

.PHONY : test-target

test-target :
@echo "success"
EOF

make test-target > $actual_value_filename 2>&1

local expected_pattern_filename=${test_case_name}.expected.pattern
bmakelib.test.cat <<EOF > $expected_pattern_filename
make.+Entering.+
success
make.+Leaving.+
EOF

bmakelib.test.assert_matches $test_case_name $actual_value_filename $expected_pattern_filename \
|| return 1
}

####################################################################################################
# when help.mk is included multiple times, no recipe overwrite warnings should occur
####################################################################################################

function help_mk_multiple_includes_no_warnings {
local test_case_name=${FUNCNAME[0]}
local actual_value_filename=${test_case_name}.actual.log
bmakelib.test.cat <<EOF > Makefile
SHELL := /usr/bin/env bash
include \$(bmakelib.ROOT)/help.mk
include \$(bmakelib.ROOT)/help.mk

.PHONY : dummy

dummy :
@echo "help included cleanly"
EOF

make dummy > $actual_value_filename 2>&1

local expected_pattern_filename=${test_case_name}.expected.pattern
bmakelib.test.cat <<EOF > $expected_pattern_filename
make.+Entering.+
help included cleanly
make.+Leaving.+
EOF

bmakelib.test.assert_matches $test_case_name $actual_value_filename $expected_pattern_filename \
|| return 1
}

####################################################################################################
# when each module is included multiple times, execution should remain idempotent
####################################################################################################

function all_individual_modules_multiple_includes {
local test_case_name=${FUNCNAME[0]}
local actual_value_filename=${test_case_name}.actual.log
bmakelib.test.cat <<EOF > Makefile
SHELL := /usr/bin/env bash
include \$(bmakelib.ROOT)/error-if-blank.mk
include \$(bmakelib.ROOT)/error-if-blank.mk
include \$(bmakelib.ROOT)/default-if-blank.mk
include \$(bmakelib.ROOT)/default-if-blank.mk
include \$(bmakelib.ROOT)/dict.mk
include \$(bmakelib.ROOT)/dict.mk
include \$(bmakelib.ROOT)/enum.mk
include \$(bmakelib.ROOT)/enum.mk
include \$(bmakelib.ROOT)/logged.mk
include \$(bmakelib.ROOT)/logged.mk
include \$(bmakelib.ROOT)/shell.mk
include \$(bmakelib.ROOT)/shell.mk
include \$(bmakelib.ROOT)/timed.mk
include \$(bmakelib.ROOT)/timed.mk

.PHONY : check-all

check-all :
@echo "all modules included idempotently"
EOF

make check-all > $actual_value_filename 2>&1

local expected_pattern_filename=${test_case_name}.expected.pattern
bmakelib.test.cat <<EOF > $expected_pattern_filename
make.+Entering.+
all modules included idempotently
make.+Leaving.+
EOF

bmakelib.test.assert_matches $test_case_name $actual_value_filename $expected_pattern_filename \
|| return 1
}

####################################################################################################
# guard variables must be defined and set to 1
####################################################################################################

function guard_variables_defined {
local test_case_name=${FUNCNAME[0]}
local actual_value_filename=${test_case_name}.actual.log
bmakelib.test.cat <<EOF > Makefile
SHELL := /usr/bin/env bash
include \$(bmakelib.ROOT)/bmakelib.mk

.PHONY : check-guards

check-guards :
@echo "bmakelib: \$(__bmakelib_bmakelib.mk)"
@echo "error-if-blank: \$(__bmakelib_error-if-blank.mk)"
@echo "default-if-blank: \$(__bmakelib_default-if-blank.mk)"
@echo "dict: \$(__bmakelib_dict.mk)"
@echo "enum: \$(__bmakelib_enum.mk)"
@echo "help: \$(__bmakelib_help.mk)"
@echo "logged: \$(__bmakelib_logged.mk)"
@echo "shell: \$(__bmakelib_shell.mk)"
@echo "timed: \$(__bmakelib_timed.mk)"
EOF

make check-guards > $actual_value_filename 2>&1

local expected_pattern_filename=${test_case_name}.expected.pattern
bmakelib.test.cat <<EOF > $expected_pattern_filename
make.+Entering.+
bmakelib: 1
error-if-blank: 1
default-if-blank: 1
dict: 1
enum: 1
help: 1
logged: 1
shell: 1
timed: 1
make.+Leaving.+
EOF

bmakelib.test.assert_matches $test_case_name $actual_value_filename $expected_pattern_filename \
|| return 1
}

####################################################################################################
# guard variables must not be exposed in make help output
####################################################################################################

function guard_variables_not_in_help {
local test_case_name=${FUNCNAME[0]}
local actual_value_filename=${test_case_name}.actual.log
bmakelib.test.cat <<EOF > Makefile
SHELL := /usr/bin/env bash
include \$(bmakelib.ROOT)/bmakelib.mk

## Sample target
sample-target :
@echo "sample"
EOF

make help bmakelib.conf.help.show-bmakelib=yes > $actual_value_filename 2>&1

if grep -E '__bmakelib_' $actual_value_filename > /dev/null; then
bmakelib.test.echo.error "${test_case_name}: guard variables found in help output"
return 1
fi

return 0
}

####################################################################################################

bmakelib.test.run_test_case bmakelib_multiple_includes_no_warnings
bmakelib.test.run_test_case help_mk_multiple_includes_no_warnings
bmakelib.test.run_test_case all_individual_modules_multiple_includes
bmakelib.test.run_test_case guard_variables_defined
bmakelib.test.run_test_case guard_variables_not_in_help