From 00d9bbd85beb5a213176b991164cf188ed828a79 Mon Sep 17 00:00:00 2001 From: Adam Porter Date: Thu, 8 Aug 2019 15:29:53 -0500 Subject: [PATCH] Tests: Add makem.sh, update Makefile --- Makefile | 25 ++- makem.sh | 539 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 561 insertions(+), 3 deletions(-) create mode 100755 makem.sh diff --git a/Makefile b/Makefile index d5edecf..4883294 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,23 @@ -.PHONY: test +# * Verbosity -test: - cask exec buttercup -L . +# Since the "-v" in "make -v" gets intercepted by Make itself, we have +# to use a variable. + +verbose = $(v) + +ifneq (,$(findstring vv,$(verbose))) + VERBOSE = "-vv" +else ifneq (,$(findstring v,$(verbose))) + VERBOSE = "-v" +endif + +# * Rules + +# Unless/until I add Cask support to makem.sh, I'm keeping this, +# because Cask lets me run the tests with a different version of Org +# than I have installed personally. +cask: + @cask exec buttercup -L . + +%: + @./makem.sh $(VERBOSE) $(@) diff --git a/makem.sh b/makem.sh new file mode 100755 index 0000000..909d9eb --- /dev/null +++ b/makem.sh @@ -0,0 +1,539 @@ +#!/bin/bash + +# * makem.sh --- Script to aid building and testing Emacs Lisp packages + +# * Commentary: + + +# * License: + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# * Safety + +# NOTE: These are disabled by default in this template but should be +# enabled when feasible. Documentation is from the Bash man page. + +# ** errexit + +# Exit immediately if a pipeline (which may consist of a single simple +# command), a list, or a compound command (see SHELL GRAMMAR above), +# exits with a non-zero status. The shell does not exit if the +# command that fails is part of the command list immediately following +# a while or until keyword, part of the test following the if or elif +# reserved words, part of any command executed in a && or || list +# except the command follow‐ ing the final && or ||, any command in a +# pipeline but the last, or if the command's return value is being +# inverted with !. If a compound command other than a subshell +# returns a non-zero status because a command failed while -e was +# being ignored, the shell does not exit. A trap on ERR, if set, is +# executed before the shell exits. This option applies to the shell +# environment and each subshell environment separately (see COMMAND +# EXECUTION ENVIRONMENT above), and may cause subshells to exit before +# executing all the commands in the subshell. + +# If a compound command or shell function executes in a context where +# -e is being ignored, none of the commands executed within the +# compound command or function body will be affected by the -e +# setting, even if -e is set and a command returns a failure status. +# If a compound command or shell function sets -e while executing in a +# context where -e is ignored, that setting will not have any effect +# until the compound command or the command containing the function +# call completes. + +# set -o errexit + +# ** nounset + +# Treat unset variables and parameters other than the special +# parameters "@" and "*" as an error when performing parameter +# expansion. If expansion is attempted on an unset variable or +# parameter, the shell prints an error message, and, if not +# interactive, exits with a non-zero status. + +# NOTE: When this is not enabled, individual variables can be required +# to be set by using "${var:?}" parameter expansion syntax. + +# set -o nounset + +# ** pipefail + +# If set, the return value of a pipeline is the value of the last +# (rightmost) command to exit with a non-zero status, or zero if all +# commands in the pipeline exit successfully. This option is disabled +# by default. + +# set -o pipefail + +# * Elisp + +# These functions return a path to an elisp file which can be loaded +# by Emacs on the command line with -l or --load. + +function elisp-buttercup-file { + # The function buttercup-run, which is called by buttercup-run-discover, + # signals an error if it can't find any Buttercup test suites. We don't + # want that to be an error, so we define advice which ignores that error. + local file=$(mktemp) + cat >$file <$file <$file <$output_file + + exit=$? + [[ $exit != 0 ]] && debug "Emacs exited non-zero: $exit" + if [[ $verbose -gt 1 || $exit != 0 ]] + then + cat $output_file + fi + rm -f $output_file + + return $exit +} + +# ** Compilation + +function batch-byte-compile { + debug "batch-byte-compile: ERROR-ON-WARN:$compile_error_on_warn FILES:$@" + + [[ $compile_error_on_warn ]] && local error_on_warn=(--eval "(setq byte-compile-error-on-warn t)") + + run_emacs \ + "${error_on_warn[@]}" \ + --funcall batch-byte-compile \ + "$@" +} + +# ** Files + +function project-elisp-files { + # Echo list of Elisp files in project. + git ls-files 2>/dev/null | egrep "\.el$" | exclude-files +} + +function project-source-files { + # Echo list of Elisp files that are not tests. + project-elisp-files | egrep -v '^tests?/test-?' +} + +function project-test-files { + # Echo list of Elisp test files. + project-elisp-files | egrep '^tests?/test-?' +} + +function exclude-files { + # Filter out paths (STDIN) which should be excluded by default. + egrep -v "(/\.cask/|-autoloads.el)" +} + +function load-files-args { + # For file in $@, echo "--load $file". + for file in "$@" + do + printf -- '--load %q ' "$file" + done +} + +function files_args { + # For file in STDIN, echo "$file". + while read file + do + printf -- '%q ' "$file" + done +} + +# ** Utility + +function cleanup { + # Remove temporary paths (${temp_paths[@]}). + + for path in "${temp_paths[@]}" + do + if [[ $debug ]] + then + debug "Debugging enabled: not deleting temporary path: $path" + elif [[ -r $path ]] + then + rm -rf "$path" + else + debug "Temporary path doesn't exist, not deleting: $path" + fi + done +} + +function echo_color { + # This allows bold, italic, etc. without needing a function for + # each variation. + if [[ $color ]] + then + local color_code="COLOR_$1" + shift + + echo -e "${!color_code}${@}${COLOR_off}" + else + echo "$@" + fi +} +function debug { + if [[ $debug ]] + then + function debug { + echo_color yellow "DEBUG ($(ts)): $@" >&2 + } + debug "$@" + else + function debug { + true + } + fi +} +function error { + echo_color red "ERROR ($(ts)): $@" >&2 + ((errors++)) +} +function die { + error "$@" + exit $errors +} +function log { + echo "LOG ($(ts)): $@" >&2 +} +function log_color { + local color=$1 + shift + echo_color $color "LOG ($(ts)): $@" >&2 +} +function success { + if [[ $verbose -ge 2 ]] + then + log_color green "$@" >&2 + fi +} +function verbose { + # $1 is the verbosity level, rest are echoed when appropriate. + if [[ $verbose -ge $1 ]] + then + [[ $1 -eq 1 ]] && local color=blue + [[ $1 -ge 2 ]] && local color=cyan + + shift + log_color $color "$@" >&2 + fi +} + +function ts { + date "+%Y-%m-%d %H:%M:%S" +} + +function usage { + cat </dev/null | grep "$rule is a function" &>/dev/null + then + $rule + elif [[ $rule = test ]] + then + # Allow the "tests" rule to be called as "test". Since "test" + # is a shell builtin, this workaround is required. + tests + else + error "Invalid rule: $rule" + fi +done + +if [[ $errors -gt 0 ]] +then + log_color red "Finished with $errors errors." +else + success "Finished without errors." +fi + +exit $errors