Meta: Update makem.sh, Makefile
This commit is contained in:
parent
d4f2eb760e
commit
c8c89be7bc
2 changed files with 148 additions and 33 deletions
175
makem.sh
175
makem.sh
|
|
@ -3,11 +3,11 @@
|
|||
# * makem.sh --- Script to aid building and testing Emacs Lisp packages
|
||||
|
||||
# URL: https://github.com/alphapapa/makem.sh
|
||||
# Version: 0.3
|
||||
# Version: 0.6-pre
|
||||
|
||||
# * 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
|
||||
# without requiring per-package configuration.
|
||||
|
||||
|
|
@ -79,7 +79,7 @@ Rules:
|
|||
Options:
|
||||
-d, --debug Print debug info.
|
||||
-h, --help I need somebody!
|
||||
-v, --verbose Increase verbosity, up to -vv.
|
||||
-v, --verbose Increase verbosity, up to -vvv.
|
||||
--no-color Disable color output.
|
||||
|
||||
--debug-load-path Print load-path from inside Emacs.
|
||||
|
|
@ -136,6 +136,27 @@ EOF
|
|||
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 {
|
||||
# Since checkdoc doesn't have a batch function that exits non-zero
|
||||
# when errors are found, we make one.
|
||||
|
|
@ -154,7 +175,8 @@ function elisp-checkdoc-file {
|
|||
": " text)))
|
||||
(message msg)
|
||||
(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)
|
||||
(when makem-checkdoc-errors-p
|
||||
(kill-emacs 1))))
|
||||
|
|
@ -165,6 +187,51 @@ EOF
|
|||
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 {
|
||||
# Since check-declare doesn't have a batch function that exits
|
||||
# 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))
|
||||
(cl-labels ((lint-file (file)
|
||||
(find-file file)
|
||||
(let ((tick (buffer-modified-tick)))
|
||||
(let ((inhibit-message t))
|
||||
(indent-region (point-min) (point-max)))
|
||||
(when (/= tick (buffer-modified-tick))
|
||||
;; Indentation changed: warn for each line.
|
||||
(dolist (line (undo-lines buffer-undo-list))
|
||||
(message "%s:%s: Indentation mismatch" (buffer-name) line))
|
||||
(setf errors-p t))))
|
||||
(let ((inhibit-message t))
|
||||
(indent-region (point-min) (point-max)))
|
||||
(when buffer-undo-list
|
||||
;; Indentation changed: warn for each line.
|
||||
(dolist (line (undo-lines buffer-undo-list))
|
||||
(message "%s:%s: Indentation mismatch" (buffer-name) line))
|
||||
(setf errors-p t)))
|
||||
(undo-pos (entry)
|
||||
(cl-typecase (car entry)
|
||||
(number (car entry))
|
||||
(string (abs (cdr entry)))))
|
||||
(undo-lines (undo-list)
|
||||
;; Return list of lines changed in UNDO-LIST.
|
||||
(nreverse (cl-loop for elt in undo-list
|
||||
when (and (consp elt)
|
||||
(numberp (car elt)))
|
||||
collect (line-number-at-pos (car elt))))))
|
||||
for pos = (undo-pos elt)
|
||||
when pos
|
||||
collect (line-number-at-pos pos)))))
|
||||
(mapc #'lint-file (mapcar #'expand-file-name command-line-args-left))
|
||||
(when errors-p
|
||||
(kill-emacs 1)))))
|
||||
|
|
@ -232,7 +302,6 @@ function elisp-package-initialize-file {
|
|||
(cons "melpa-stable" "https://stable.melpa.org/packages/")))
|
||||
$elisp_org_package_archive
|
||||
(package-initialize)
|
||||
(setq load-prefer-newer t)
|
||||
EOF
|
||||
echo $file
|
||||
}
|
||||
|
|
@ -245,6 +314,7 @@ function run_emacs {
|
|||
local emacs_command=(
|
||||
"${emacs_command[@]}"
|
||||
-Q
|
||||
--eval "(setq load-prefer-newer t)"
|
||||
"${args_debug[@]}"
|
||||
"${args_sandbox[@]}"
|
||||
-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)")
|
||||
|
||||
run_emacs \
|
||||
--load "$(elisp-byte-compile-file)" \
|
||||
"${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)")
|
||||
|
||||
# FIXME: Why is the line starting with "&& verbose 3" not indented properly? Emacs insists on indenting it back a level.
|
||||
run_emacs \
|
||||
--load "$(elisp-byte-compile-file)" \
|
||||
"${error_on_warn[@]}" \
|
||||
--eval "(byte-compile-file \"$file\")" \
|
||||
|| error "Compiling file failed: $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)))" \
|
||||
&& verbose 3 "Compiling $file finished without errors." \
|
||||
|| { verbose 3 "Compiling file failed: $file"; return 1; }
|
||||
}
|
||||
|
||||
# ** Files
|
||||
|
|
@ -376,7 +450,8 @@ function args-load-files {
|
|||
# For file in $@, echo "--load $file".
|
||||
for file in "$@"
|
||||
do
|
||||
printf -- '--load %q ' "$file"
|
||||
sans_extension=${file%%.el}
|
||||
printf -- '--load %q ' "$sans_extension"
|
||||
done
|
||||
}
|
||||
|
||||
|
|
@ -413,8 +488,7 @@ function ert-tests-p {
|
|||
}
|
||||
|
||||
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)
|
||||
|
||||
if [[ $file_pkg ]]
|
||||
|
|
@ -496,6 +570,8 @@ function sandbox {
|
|||
args_sandbox=(
|
||||
--title "makem.sh: $(basename $(pwd)) (sandbox: $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\"))"
|
||||
)
|
||||
|
||||
|
|
@ -658,7 +734,8 @@ function verbose {
|
|||
if [[ $verbose -ge $1 ]]
|
||||
then
|
||||
[[ $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
|
||||
log_color $color_name "$@" >&2
|
||||
|
|
@ -706,9 +783,7 @@ function compile-batch {
|
|||
verbose 2 "Batch-compiling files..."
|
||||
debug "Byte-compile files: ${files_project_byte_compile[@]}"
|
||||
|
||||
batch-byte-compile "${files_project_byte_compile[@]}" \
|
||||
&& success "Compiling finished without errors." \
|
||||
|| error "Compilation failed."
|
||||
batch-byte-compile "${files_project_byte_compile[@]}"
|
||||
}
|
||||
|
||||
function compile-each {
|
||||
|
|
@ -726,9 +801,7 @@ function compile-each {
|
|||
|| compile_errors=t
|
||||
done
|
||||
|
||||
! [[ $compile_errors ]] \
|
||||
&& success "Compiling finished without errors." \
|
||||
|| error "Compilation failed."
|
||||
[[ ! $compile_errors ]]
|
||||
}
|
||||
|
||||
function compile {
|
||||
|
|
@ -738,6 +811,18 @@ function compile {
|
|||
else
|
||||
compile-each "$@"
|
||||
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 {
|
||||
|
|
@ -752,12 +837,15 @@ function batch {
|
|||
|
||||
function interactive {
|
||||
# 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 2 "Loading files:" "${files_project_feature[@]}" "${files_project_test[@]}"
|
||||
verbose 2 "Loading files: ${load_file_args//--load /}"
|
||||
|
||||
[[ $compile ]] && compile
|
||||
|
||||
unset arg_batch
|
||||
run_emacs \
|
||||
$(args-load-files "${files_project_feature[@]}" "${files_project_test[@]}") \
|
||||
$load_file_args \
|
||||
--eval "(load user-init-file)" \
|
||||
"${args_batch_interactive[@]}"
|
||||
arg_batch="--batch"
|
||||
|
|
@ -769,6 +857,9 @@ function lint {
|
|||
lint-checkdoc
|
||||
lint-compile
|
||||
lint-declare
|
||||
# NOTE: Elint doesn't seem very useful at the moment. See comment
|
||||
# in lint-elint function.
|
||||
# lint-elint
|
||||
lint-indent
|
||||
lint-package
|
||||
lint-regexps
|
||||
|
|
@ -825,6 +916,28 @@ function lint-elsa {
|
|||
|| 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 {
|
||||
verbose 1 "Linting indentation..."
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue