Meta: Update makem.sh, Makefile
This commit is contained in:
parent
d4f2eb760e
commit
c8c89be7bc
2 changed files with 148 additions and 33 deletions
6
Makefile
6
Makefile
|
|
@ -1,7 +1,7 @@
|
||||||
# * makem.sh/Makefile --- Script to aid building and testing Emacs Lisp packages
|
# * makem.sh/Makefile --- Script to aid building and testing Emacs Lisp packages
|
||||||
|
|
||||||
# URL: https://github.com/alphapapa/makem.sh
|
# URL: https://github.com/alphapapa/makem.sh
|
||||||
# Version: 0.3
|
# Version: 0.5
|
||||||
|
|
||||||
# * Arguments
|
# * Arguments
|
||||||
|
|
||||||
|
|
@ -38,7 +38,9 @@ endif
|
||||||
|
|
||||||
verbose = $(v)
|
verbose = $(v)
|
||||||
|
|
||||||
ifneq (,$(findstring vv,$(verbose)))
|
ifneq (,$(findstring vvv,$(verbose)))
|
||||||
|
VERBOSE = "-vvv"
|
||||||
|
else ifneq (,$(findstring vv,$(verbose)))
|
||||||
VERBOSE = "-vv"
|
VERBOSE = "-vv"
|
||||||
else ifneq (,$(findstring v,$(verbose)))
|
else ifneq (,$(findstring v,$(verbose)))
|
||||||
VERBOSE = "-v"
|
VERBOSE = "-v"
|
||||||
|
|
|
||||||
165
makem.sh
165
makem.sh
|
|
@ -3,11 +3,11 @@
|
||||||
# * makem.sh --- Script to aid building and testing Emacs Lisp packages
|
# * makem.sh --- Script to aid building and testing Emacs Lisp packages
|
||||||
|
|
||||||
# URL: https://github.com/alphapapa/makem.sh
|
# URL: https://github.com/alphapapa/makem.sh
|
||||||
# Version: 0.3
|
# Version: 0.6-pre
|
||||||
|
|
||||||
# * Commentary:
|
# * Commentary:
|
||||||
|
|
||||||
# makem.sh is a script helps to build, lint, and test Emacs Lisp
|
# makem.sh is a script that helps to build, lint, and test Emacs Lisp
|
||||||
# packages. It aims to make linting and testing as simple as possible
|
# packages. It aims to make linting and testing as simple as possible
|
||||||
# without requiring per-package configuration.
|
# without requiring per-package configuration.
|
||||||
|
|
||||||
|
|
@ -79,7 +79,7 @@ Rules:
|
||||||
Options:
|
Options:
|
||||||
-d, --debug Print debug info.
|
-d, --debug Print debug info.
|
||||||
-h, --help I need somebody!
|
-h, --help I need somebody!
|
||||||
-v, --verbose Increase verbosity, up to -vv.
|
-v, --verbose Increase verbosity, up to -vvv.
|
||||||
--no-color Disable color output.
|
--no-color Disable color output.
|
||||||
|
|
||||||
--debug-load-path Print load-path from inside Emacs.
|
--debug-load-path Print load-path from inside Emacs.
|
||||||
|
|
@ -136,6 +136,27 @@ EOF
|
||||||
echo $file
|
echo $file
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function elisp-elint-file {
|
||||||
|
local file=$(mktemp)
|
||||||
|
cat >$file <<EOF
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'elint)
|
||||||
|
(defun makem-elint-file (file)
|
||||||
|
(let ((errors 0))
|
||||||
|
(cl-letf (((symbol-function 'orig-message) (symbol-function 'message))
|
||||||
|
((symbol-function 'message) (symbol-function 'ignore))
|
||||||
|
((symbol-function 'elint-output)
|
||||||
|
(lambda (string)
|
||||||
|
(cl-incf errors)
|
||||||
|
(orig-message "%s" string))))
|
||||||
|
(elint-file file)
|
||||||
|
;; NOTE: \`errors' is not actually the number of errors, because
|
||||||
|
;; it's incremented for non-error header strings as well.
|
||||||
|
(kill-emacs errors))))
|
||||||
|
EOF
|
||||||
|
echo "$file"
|
||||||
|
}
|
||||||
|
|
||||||
function elisp-checkdoc-file {
|
function elisp-checkdoc-file {
|
||||||
# Since checkdoc doesn't have a batch function that exits non-zero
|
# Since checkdoc doesn't have a batch function that exits non-zero
|
||||||
# when errors are found, we make one.
|
# when errors are found, we make one.
|
||||||
|
|
@ -154,7 +175,8 @@ function elisp-checkdoc-file {
|
||||||
": " text)))
|
": " text)))
|
||||||
(message msg)
|
(message msg)
|
||||||
(setq makem-checkdoc-errors-p t)
|
(setq makem-checkdoc-errors-p t)
|
||||||
(list text start end unfixable)))))
|
;; Return nil because we *are* generating a buffered list of errors.
|
||||||
|
nil))))
|
||||||
(mapcar #'checkdoc-file files)
|
(mapcar #'checkdoc-file files)
|
||||||
(when makem-checkdoc-errors-p
|
(when makem-checkdoc-errors-p
|
||||||
(kill-emacs 1))))
|
(kill-emacs 1))))
|
||||||
|
|
@ -165,6 +187,51 @@ EOF
|
||||||
echo $file
|
echo $file
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function elisp-byte-compile-file {
|
||||||
|
# This seems to be the only way to make byte-compilation signal
|
||||||
|
# errors for warnings AND display all warnings rather than only
|
||||||
|
# the first one.
|
||||||
|
local file=$(mktemp)
|
||||||
|
# TODO: Add file to $paths_temp in other elisp- functions.
|
||||||
|
paths_temp+=("$file")
|
||||||
|
|
||||||
|
cat >"$file" <<EOF
|
||||||
|
(defun makem-batch-byte-compile (&rest args)
|
||||||
|
""
|
||||||
|
(let ((num-errors 0)
|
||||||
|
(num-warnings 0))
|
||||||
|
;; NOTE: Only accepts files as args, not directories.
|
||||||
|
(dolist (file command-line-args-left)
|
||||||
|
(pcase-let ((\`(,errors ,warnings) (makem-byte-compile-file file)))
|
||||||
|
(cl-incf num-errors errors)
|
||||||
|
(cl-incf num-warnings warnings)))
|
||||||
|
(zerop num-errors)))
|
||||||
|
|
||||||
|
(defun makem-byte-compile-file (filename &optional load)
|
||||||
|
"Call \`byte-compile-warn', returning the number of errors and the number of warnings."
|
||||||
|
(let ((num-warnings 0)
|
||||||
|
(num-errors 0))
|
||||||
|
(cl-letf (((symbol-function 'byte-compile-warn)
|
||||||
|
(lambda (format &rest args)
|
||||||
|
;; Copied from \`byte-compile-warn'.
|
||||||
|
(cl-incf num-warnings)
|
||||||
|
(setq format (apply #'format-message format args))
|
||||||
|
(byte-compile-log-warning format t :warning)))
|
||||||
|
((symbol-function 'byte-compile-report-error)
|
||||||
|
(lambda (error-info &optional fill &rest args)
|
||||||
|
(cl-incf num-errors)
|
||||||
|
;; Copied from \`byte-compile-report-error'.
|
||||||
|
(setq byte-compiler-error-flag t)
|
||||||
|
(byte-compile-log-warning
|
||||||
|
(if (stringp error-info) error-info
|
||||||
|
(error-message-string error-info))
|
||||||
|
fill :error))))
|
||||||
|
(byte-compile-file filename load))
|
||||||
|
(list num-errors num-warnings)))
|
||||||
|
EOF
|
||||||
|
echo "$file"
|
||||||
|
}
|
||||||
|
|
||||||
function elisp-check-declare-file {
|
function elisp-check-declare-file {
|
||||||
# Since check-declare doesn't have a batch function that exits
|
# Since check-declare doesn't have a batch function that exits
|
||||||
# non-zero when errors are found, we make one.
|
# non-zero when errors are found, we make one.
|
||||||
|
|
@ -200,20 +267,23 @@ Exits non-zero if mis-indented lines are found. Checks files in
|
||||||
(let ((errors-p))
|
(let ((errors-p))
|
||||||
(cl-labels ((lint-file (file)
|
(cl-labels ((lint-file (file)
|
||||||
(find-file file)
|
(find-file file)
|
||||||
(let ((tick (buffer-modified-tick)))
|
|
||||||
(let ((inhibit-message t))
|
(let ((inhibit-message t))
|
||||||
(indent-region (point-min) (point-max)))
|
(indent-region (point-min) (point-max)))
|
||||||
(when (/= tick (buffer-modified-tick))
|
(when buffer-undo-list
|
||||||
;; Indentation changed: warn for each line.
|
;; Indentation changed: warn for each line.
|
||||||
(dolist (line (undo-lines buffer-undo-list))
|
(dolist (line (undo-lines buffer-undo-list))
|
||||||
(message "%s:%s: Indentation mismatch" (buffer-name) line))
|
(message "%s:%s: Indentation mismatch" (buffer-name) line))
|
||||||
(setf errors-p t))))
|
(setf errors-p t)))
|
||||||
|
(undo-pos (entry)
|
||||||
|
(cl-typecase (car entry)
|
||||||
|
(number (car entry))
|
||||||
|
(string (abs (cdr entry)))))
|
||||||
(undo-lines (undo-list)
|
(undo-lines (undo-list)
|
||||||
;; Return list of lines changed in UNDO-LIST.
|
;; Return list of lines changed in UNDO-LIST.
|
||||||
(nreverse (cl-loop for elt in undo-list
|
(nreverse (cl-loop for elt in undo-list
|
||||||
when (and (consp elt)
|
for pos = (undo-pos elt)
|
||||||
(numberp (car elt)))
|
when pos
|
||||||
collect (line-number-at-pos (car elt))))))
|
collect (line-number-at-pos pos)))))
|
||||||
(mapc #'lint-file (mapcar #'expand-file-name command-line-args-left))
|
(mapc #'lint-file (mapcar #'expand-file-name command-line-args-left))
|
||||||
(when errors-p
|
(when errors-p
|
||||||
(kill-emacs 1)))))
|
(kill-emacs 1)))))
|
||||||
|
|
@ -232,7 +302,6 @@ function elisp-package-initialize-file {
|
||||||
(cons "melpa-stable" "https://stable.melpa.org/packages/")))
|
(cons "melpa-stable" "https://stable.melpa.org/packages/")))
|
||||||
$elisp_org_package_archive
|
$elisp_org_package_archive
|
||||||
(package-initialize)
|
(package-initialize)
|
||||||
(setq load-prefer-newer t)
|
|
||||||
EOF
|
EOF
|
||||||
echo $file
|
echo $file
|
||||||
}
|
}
|
||||||
|
|
@ -245,6 +314,7 @@ function run_emacs {
|
||||||
local emacs_command=(
|
local emacs_command=(
|
||||||
"${emacs_command[@]}"
|
"${emacs_command[@]}"
|
||||||
-Q
|
-Q
|
||||||
|
--eval "(setq load-prefer-newer t)"
|
||||||
"${args_debug[@]}"
|
"${args_debug[@]}"
|
||||||
"${args_sandbox[@]}"
|
"${args_sandbox[@]}"
|
||||||
-l $package_initialize_file
|
-l $package_initialize_file
|
||||||
|
|
@ -286,8 +356,9 @@ function batch-byte-compile {
|
||||||
[[ $compile_error_on_warn ]] && local error_on_warn=(--eval "(setq byte-compile-error-on-warn t)")
|
[[ $compile_error_on_warn ]] && local error_on_warn=(--eval "(setq byte-compile-error-on-warn t)")
|
||||||
|
|
||||||
run_emacs \
|
run_emacs \
|
||||||
|
--load "$(elisp-byte-compile-file)" \
|
||||||
"${error_on_warn[@]}" \
|
"${error_on_warn[@]}" \
|
||||||
--funcall batch-byte-compile \
|
--eval "(unless (makem-batch-byte-compile) (kill-emacs 1))" \
|
||||||
"$@"
|
"$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -297,10 +368,13 @@ function byte-compile-file {
|
||||||
|
|
||||||
[[ $compile_error_on_warn ]] && local error_on_warn=(--eval "(setq byte-compile-error-on-warn t)")
|
[[ $compile_error_on_warn ]] && local error_on_warn=(--eval "(setq byte-compile-error-on-warn t)")
|
||||||
|
|
||||||
|
# FIXME: Why is the line starting with "&& verbose 3" not indented properly? Emacs insists on indenting it back a level.
|
||||||
run_emacs \
|
run_emacs \
|
||||||
|
--load "$(elisp-byte-compile-file)" \
|
||||||
"${error_on_warn[@]}" \
|
"${error_on_warn[@]}" \
|
||||||
--eval "(byte-compile-file \"$file\")" \
|
--eval "(pcase-let ((\`(,num-errors ,num-warnings) (makem-byte-compile-file \"$file\"))) (when (or (and byte-compile-error-on-warn (not (zerop num-warnings))) (not (zerop num-errors))) (kill-emacs 1)))" \
|
||||||
|| error "Compiling file failed: $file"
|
&& verbose 3 "Compiling $file finished without errors." \
|
||||||
|
|| { verbose 3 "Compiling file failed: $file"; return 1; }
|
||||||
}
|
}
|
||||||
|
|
||||||
# ** Files
|
# ** Files
|
||||||
|
|
@ -376,7 +450,8 @@ function args-load-files {
|
||||||
# For file in $@, echo "--load $file".
|
# For file in $@, echo "--load $file".
|
||||||
for file in "$@"
|
for file in "$@"
|
||||||
do
|
do
|
||||||
printf -- '--load %q ' "$file"
|
sans_extension=${file%%.el}
|
||||||
|
printf -- '--load %q ' "$sans_extension"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -413,8 +488,7 @@ function ert-tests-p {
|
||||||
}
|
}
|
||||||
|
|
||||||
function package-main-file {
|
function package-main-file {
|
||||||
# Echo the package's main file. Helpful for setting package-lint-main-file.
|
# Echo the package's main file.
|
||||||
|
|
||||||
file_pkg=$(git ls-files ./*-pkg.el 2>/dev/null)
|
file_pkg=$(git ls-files ./*-pkg.el 2>/dev/null)
|
||||||
|
|
||||||
if [[ $file_pkg ]]
|
if [[ $file_pkg ]]
|
||||||
|
|
@ -496,6 +570,8 @@ function sandbox {
|
||||||
args_sandbox=(
|
args_sandbox=(
|
||||||
--title "makem.sh: $(basename $(pwd)) (sandbox: $sandbox_dir)"
|
--title "makem.sh: $(basename $(pwd)) (sandbox: $sandbox_dir)"
|
||||||
--eval "(setq user-emacs-directory (file-truename \"$sandbox_dir\"))"
|
--eval "(setq user-emacs-directory (file-truename \"$sandbox_dir\"))"
|
||||||
|
--load package
|
||||||
|
--eval "(setq package-user-dir (expand-file-name \"elpa\" user-emacs-directory))"
|
||||||
--eval "(setq user-init-file (file-truename \"$init_file\"))"
|
--eval "(setq user-init-file (file-truename \"$init_file\"))"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -658,7 +734,8 @@ function verbose {
|
||||||
if [[ $verbose -ge $1 ]]
|
if [[ $verbose -ge $1 ]]
|
||||||
then
|
then
|
||||||
[[ $1 -eq 1 ]] && local color_name=blue
|
[[ $1 -eq 1 ]] && local color_name=blue
|
||||||
[[ $1 -ge 2 ]] && local color_name=cyan
|
[[ $1 -eq 2 ]] && local color_name=cyan
|
||||||
|
[[ $1 -ge 3 ]] && local color_name=white
|
||||||
|
|
||||||
shift
|
shift
|
||||||
log_color $color_name "$@" >&2
|
log_color $color_name "$@" >&2
|
||||||
|
|
@ -706,9 +783,7 @@ function compile-batch {
|
||||||
verbose 2 "Batch-compiling files..."
|
verbose 2 "Batch-compiling files..."
|
||||||
debug "Byte-compile files: ${files_project_byte_compile[@]}"
|
debug "Byte-compile files: ${files_project_byte_compile[@]}"
|
||||||
|
|
||||||
batch-byte-compile "${files_project_byte_compile[@]}" \
|
batch-byte-compile "${files_project_byte_compile[@]}"
|
||||||
&& success "Compiling finished without errors." \
|
|
||||||
|| error "Compilation failed."
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function compile-each {
|
function compile-each {
|
||||||
|
|
@ -726,9 +801,7 @@ function compile-each {
|
||||||
|| compile_errors=t
|
|| compile_errors=t
|
||||||
done
|
done
|
||||||
|
|
||||||
! [[ $compile_errors ]] \
|
[[ ! $compile_errors ]]
|
||||||
&& success "Compiling finished without errors." \
|
|
||||||
|| error "Compilation failed."
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function compile {
|
function compile {
|
||||||
|
|
@ -738,6 +811,18 @@ function compile {
|
||||||
else
|
else
|
||||||
compile-each "$@"
|
compile-each "$@"
|
||||||
fi
|
fi
|
||||||
|
local status=$?
|
||||||
|
|
||||||
|
if [[ $compile_error_on_warn ]]
|
||||||
|
then
|
||||||
|
# Linting: just return status code, because lint rule will print messages.
|
||||||
|
[[ $status = 0 ]]
|
||||||
|
else
|
||||||
|
# Not linting: print messages here.
|
||||||
|
[[ $status = 0 ]] \
|
||||||
|
&& success "Compiling finished without errors." \
|
||||||
|
|| error "Compiling failed."
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function batch {
|
function batch {
|
||||||
|
|
@ -752,12 +837,15 @@ function batch {
|
||||||
|
|
||||||
function interactive {
|
function interactive {
|
||||||
# Run Emacs interactively. Most useful with --sandbox and --install-deps.
|
# Run Emacs interactively. Most useful with --sandbox and --install-deps.
|
||||||
|
local load_file_args=$(args-load-files "${files_project_feature[@]}" "${files_project_test[@]}")
|
||||||
verbose 1 "Running Emacs interactively..."
|
verbose 1 "Running Emacs interactively..."
|
||||||
verbose 2 "Loading files:" "${files_project_feature[@]}" "${files_project_test[@]}"
|
verbose 2 "Loading files: ${load_file_args//--load /}"
|
||||||
|
|
||||||
|
[[ $compile ]] && compile
|
||||||
|
|
||||||
unset arg_batch
|
unset arg_batch
|
||||||
run_emacs \
|
run_emacs \
|
||||||
$(args-load-files "${files_project_feature[@]}" "${files_project_test[@]}") \
|
$load_file_args \
|
||||||
--eval "(load user-init-file)" \
|
--eval "(load user-init-file)" \
|
||||||
"${args_batch_interactive[@]}"
|
"${args_batch_interactive[@]}"
|
||||||
arg_batch="--batch"
|
arg_batch="--batch"
|
||||||
|
|
@ -769,6 +857,9 @@ function lint {
|
||||||
lint-checkdoc
|
lint-checkdoc
|
||||||
lint-compile
|
lint-compile
|
||||||
lint-declare
|
lint-declare
|
||||||
|
# NOTE: Elint doesn't seem very useful at the moment. See comment
|
||||||
|
# in lint-elint function.
|
||||||
|
# lint-elint
|
||||||
lint-indent
|
lint-indent
|
||||||
lint-package
|
lint-package
|
||||||
lint-regexps
|
lint-regexps
|
||||||
|
|
@ -825,6 +916,28 @@ function lint-elsa {
|
||||||
|| error "Linting with Elsa failed."
|
|| error "Linting with Elsa failed."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function lint-elint {
|
||||||
|
# NOTE: Elint gives a lot of spurious warnings, apparently because it doesn't load files
|
||||||
|
# that are `require'd, so its output isn't very useful. But in case it's improved in
|
||||||
|
# the future, and since this wrapper code already works, we might as well leave it in.
|
||||||
|
verbose 1 "Linting with Elint..."
|
||||||
|
|
||||||
|
local errors=0
|
||||||
|
for file in "${files_project_feature[@]}"
|
||||||
|
do
|
||||||
|
verbose 2 "Linting with Elint: $file..."
|
||||||
|
run_emacs \
|
||||||
|
--load "$(elisp-elint-file)" \
|
||||||
|
--eval "(makem-elint-file \"$file\")" \
|
||||||
|
&& verbose 3 "Linting with Elint found no errors." \
|
||||||
|
|| { error "Linting with Elint failed: $file"; ((errors++)) ; }
|
||||||
|
done
|
||||||
|
|
||||||
|
[[ $errors = 0 ]] \
|
||||||
|
&& success "Linting with Elint finished without errors." \
|
||||||
|
|| error "Linting with Elint failed."
|
||||||
|
}
|
||||||
|
|
||||||
function lint-indent {
|
function lint-indent {
|
||||||
verbose 1 "Linting indentation..."
|
verbose 1 "Linting indentation..."
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue