Skip to content

Commit c8c89be

Browse files
committed
Meta: Update makem.sh, Makefile
1 parent d4f2eb7 commit c8c89be

File tree

2 files changed

+148
-33
lines changed

2 files changed

+148
-33
lines changed

Makefile

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# * makem.sh/Makefile --- Script to aid building and testing Emacs Lisp packages
22

33
# URL: https://github.com/alphapapa/makem.sh
4-
# Version: 0.3
4+
# Version: 0.5
55

66
# * Arguments
77

@@ -38,7 +38,9 @@ endif
3838

3939
verbose = $(v)
4040

41-
ifneq (,$(findstring vv,$(verbose)))
41+
ifneq (,$(findstring vvv,$(verbose)))
42+
VERBOSE = "-vvv"
43+
else ifneq (,$(findstring vv,$(verbose)))
4244
VERBOSE = "-vv"
4345
else ifneq (,$(findstring v,$(verbose)))
4446
VERBOSE = "-v"

makem.sh

+144-31
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
# * makem.sh --- Script to aid building and testing Emacs Lisp packages
44

55
# URL: https://github.com/alphapapa/makem.sh
6-
# Version: 0.3
6+
# Version: 0.6-pre
77

88
# * Commentary:
99

10-
# makem.sh is a script helps to build, lint, and test Emacs Lisp
10+
# makem.sh is a script that helps to build, lint, and test Emacs Lisp
1111
# packages. It aims to make linting and testing as simple as possible
1212
# without requiring per-package configuration.
1313

@@ -79,7 +79,7 @@ Rules:
7979
Options:
8080
-d, --debug Print debug info.
8181
-h, --help I need somebody!
82-
-v, --verbose Increase verbosity, up to -vv.
82+
-v, --verbose Increase verbosity, up to -vvv.
8383
--no-color Disable color output.
8484
8585
--debug-load-path Print load-path from inside Emacs.
@@ -136,6 +136,27 @@ EOF
136136
echo $file
137137
}
138138

139+
function elisp-elint-file {
140+
local file=$(mktemp)
141+
cat >$file <<EOF
142+
(require 'cl-lib)
143+
(require 'elint)
144+
(defun makem-elint-file (file)
145+
(let ((errors 0))
146+
(cl-letf (((symbol-function 'orig-message) (symbol-function 'message))
147+
((symbol-function 'message) (symbol-function 'ignore))
148+
((symbol-function 'elint-output)
149+
(lambda (string)
150+
(cl-incf errors)
151+
(orig-message "%s" string))))
152+
(elint-file file)
153+
;; NOTE: \`errors' is not actually the number of errors, because
154+
;; it's incremented for non-error header strings as well.
155+
(kill-emacs errors))))
156+
EOF
157+
echo "$file"
158+
}
159+
139160
function elisp-checkdoc-file {
140161
# Since checkdoc doesn't have a batch function that exits non-zero
141162
# when errors are found, we make one.
@@ -154,7 +175,8 @@ function elisp-checkdoc-file {
154175
": " text)))
155176
(message msg)
156177
(setq makem-checkdoc-errors-p t)
157-
(list text start end unfixable)))))
178+
;; Return nil because we *are* generating a buffered list of errors.
179+
nil))))
158180
(mapcar #'checkdoc-file files)
159181
(when makem-checkdoc-errors-p
160182
(kill-emacs 1))))
@@ -165,6 +187,51 @@ EOF
165187
echo $file
166188
}
167189

190+
function elisp-byte-compile-file {
191+
# This seems to be the only way to make byte-compilation signal
192+
# errors for warnings AND display all warnings rather than only
193+
# the first one.
194+
local file=$(mktemp)
195+
# TODO: Add file to $paths_temp in other elisp- functions.
196+
paths_temp+=("$file")
197+
198+
cat >"$file" <<EOF
199+
(defun makem-batch-byte-compile (&rest args)
200+
""
201+
(let ((num-errors 0)
202+
(num-warnings 0))
203+
;; NOTE: Only accepts files as args, not directories.
204+
(dolist (file command-line-args-left)
205+
(pcase-let ((\`(,errors ,warnings) (makem-byte-compile-file file)))
206+
(cl-incf num-errors errors)
207+
(cl-incf num-warnings warnings)))
208+
(zerop num-errors)))
209+
210+
(defun makem-byte-compile-file (filename &optional load)
211+
"Call \`byte-compile-warn', returning the number of errors and the number of warnings."
212+
(let ((num-warnings 0)
213+
(num-errors 0))
214+
(cl-letf (((symbol-function 'byte-compile-warn)
215+
(lambda (format &rest args)
216+
;; Copied from \`byte-compile-warn'.
217+
(cl-incf num-warnings)
218+
(setq format (apply #'format-message format args))
219+
(byte-compile-log-warning format t :warning)))
220+
((symbol-function 'byte-compile-report-error)
221+
(lambda (error-info &optional fill &rest args)
222+
(cl-incf num-errors)
223+
;; Copied from \`byte-compile-report-error'.
224+
(setq byte-compiler-error-flag t)
225+
(byte-compile-log-warning
226+
(if (stringp error-info) error-info
227+
(error-message-string error-info))
228+
fill :error))))
229+
(byte-compile-file filename load))
230+
(list num-errors num-warnings)))
231+
EOF
232+
echo "$file"
233+
}
234+
168235
function elisp-check-declare-file {
169236
# Since check-declare doesn't have a batch function that exits
170237
# 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
200267
(let ((errors-p))
201268
(cl-labels ((lint-file (file)
202269
(find-file file)
203-
(let ((tick (buffer-modified-tick)))
204-
(let ((inhibit-message t))
205-
(indent-region (point-min) (point-max)))
206-
(when (/= tick (buffer-modified-tick))
207-
;; Indentation changed: warn for each line.
208-
(dolist (line (undo-lines buffer-undo-list))
209-
(message "%s:%s: Indentation mismatch" (buffer-name) line))
210-
(setf errors-p t))))
270+
(let ((inhibit-message t))
271+
(indent-region (point-min) (point-max)))
272+
(when buffer-undo-list
273+
;; Indentation changed: warn for each line.
274+
(dolist (line (undo-lines buffer-undo-list))
275+
(message "%s:%s: Indentation mismatch" (buffer-name) line))
276+
(setf errors-p t)))
277+
(undo-pos (entry)
278+
(cl-typecase (car entry)
279+
(number (car entry))
280+
(string (abs (cdr entry)))))
211281
(undo-lines (undo-list)
212282
;; Return list of lines changed in UNDO-LIST.
213283
(nreverse (cl-loop for elt in undo-list
214-
when (and (consp elt)
215-
(numberp (car elt)))
216-
collect (line-number-at-pos (car elt))))))
284+
for pos = (undo-pos elt)
285+
when pos
286+
collect (line-number-at-pos pos)))))
217287
(mapc #'lint-file (mapcar #'expand-file-name command-line-args-left))
218288
(when errors-p
219289
(kill-emacs 1)))))
@@ -232,7 +302,6 @@ function elisp-package-initialize-file {
232302
(cons "melpa-stable" "https://stable.melpa.org/packages/")))
233303
$elisp_org_package_archive
234304
(package-initialize)
235-
(setq load-prefer-newer t)
236305
EOF
237306
echo $file
238307
}
@@ -245,6 +314,7 @@ function run_emacs {
245314
local emacs_command=(
246315
"${emacs_command[@]}"
247316
-Q
317+
--eval "(setq load-prefer-newer t)"
248318
"${args_debug[@]}"
249319
"${args_sandbox[@]}"
250320
-l $package_initialize_file
@@ -286,8 +356,9 @@ function batch-byte-compile {
286356
[[ $compile_error_on_warn ]] && local error_on_warn=(--eval "(setq byte-compile-error-on-warn t)")
287357

288358
run_emacs \
359+
--load "$(elisp-byte-compile-file)" \
289360
"${error_on_warn[@]}" \
290-
--funcall batch-byte-compile \
361+
--eval "(unless (makem-batch-byte-compile) (kill-emacs 1))" \
291362
"$@"
292363
}
293364

@@ -297,10 +368,13 @@ function byte-compile-file {
297368

298369
[[ $compile_error_on_warn ]] && local error_on_warn=(--eval "(setq byte-compile-error-on-warn t)")
299370

371+
# FIXME: Why is the line starting with "&& verbose 3" not indented properly? Emacs insists on indenting it back a level.
300372
run_emacs \
373+
--load "$(elisp-byte-compile-file)" \
301374
"${error_on_warn[@]}" \
302-
--eval "(byte-compile-file \"$file\")" \
303-
|| error "Compiling file failed: $file"
375+
--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)))" \
376+
&& verbose 3 "Compiling $file finished without errors." \
377+
|| { verbose 3 "Compiling file failed: $file"; return 1; }
304378
}
305379

306380
# ** Files
@@ -376,7 +450,8 @@ function args-load-files {
376450
# For file in $@, echo "--load $file".
377451
for file in "$@"
378452
do
379-
printf -- '--load %q ' "$file"
453+
sans_extension=${file%%.el}
454+
printf -- '--load %q ' "$sans_extension"
380455
done
381456
}
382457

@@ -413,8 +488,7 @@ function ert-tests-p {
413488
}
414489

415490
function package-main-file {
416-
# Echo the package's main file. Helpful for setting package-lint-main-file.
417-
491+
# Echo the package's main file.
418492
file_pkg=$(git ls-files ./*-pkg.el 2>/dev/null)
419493

420494
if [[ $file_pkg ]]
@@ -496,6 +570,8 @@ function sandbox {
496570
args_sandbox=(
497571
--title "makem.sh: $(basename $(pwd)) (sandbox: $sandbox_dir)"
498572
--eval "(setq user-emacs-directory (file-truename \"$sandbox_dir\"))"
573+
--load package
574+
--eval "(setq package-user-dir (expand-file-name \"elpa\" user-emacs-directory))"
499575
--eval "(setq user-init-file (file-truename \"$init_file\"))"
500576
)
501577

@@ -658,7 +734,8 @@ function verbose {
658734
if [[ $verbose -ge $1 ]]
659735
then
660736
[[ $1 -eq 1 ]] && local color_name=blue
661-
[[ $1 -ge 2 ]] && local color_name=cyan
737+
[[ $1 -eq 2 ]] && local color_name=cyan
738+
[[ $1 -ge 3 ]] && local color_name=white
662739

663740
shift
664741
log_color $color_name "$@" >&2
@@ -706,9 +783,7 @@ function compile-batch {
706783
verbose 2 "Batch-compiling files..."
707784
debug "Byte-compile files: ${files_project_byte_compile[@]}"
708785

709-
batch-byte-compile "${files_project_byte_compile[@]}" \
710-
&& success "Compiling finished without errors." \
711-
|| error "Compilation failed."
786+
batch-byte-compile "${files_project_byte_compile[@]}"
712787
}
713788

714789
function compile-each {
@@ -726,9 +801,7 @@ function compile-each {
726801
|| compile_errors=t
727802
done
728803

729-
! [[ $compile_errors ]] \
730-
&& success "Compiling finished without errors." \
731-
|| error "Compilation failed."
804+
[[ ! $compile_errors ]]
732805
}
733806

734807
function compile {
@@ -738,6 +811,18 @@ function compile {
738811
else
739812
compile-each "$@"
740813
fi
814+
local status=$?
815+
816+
if [[ $compile_error_on_warn ]]
817+
then
818+
# Linting: just return status code, because lint rule will print messages.
819+
[[ $status = 0 ]]
820+
else
821+
# Not linting: print messages here.
822+
[[ $status = 0 ]] \
823+
&& success "Compiling finished without errors." \
824+
|| error "Compiling failed."
825+
fi
741826
}
742827

743828
function batch {
@@ -752,12 +837,15 @@ function batch {
752837

753838
function interactive {
754839
# Run Emacs interactively. Most useful with --sandbox and --install-deps.
840+
local load_file_args=$(args-load-files "${files_project_feature[@]}" "${files_project_test[@]}")
755841
verbose 1 "Running Emacs interactively..."
756-
verbose 2 "Loading files:" "${files_project_feature[@]}" "${files_project_test[@]}"
842+
verbose 2 "Loading files: ${load_file_args//--load /}"
843+
844+
[[ $compile ]] && compile
757845

758846
unset arg_batch
759847
run_emacs \
760-
$(args-load-files "${files_project_feature[@]}" "${files_project_test[@]}") \
848+
$load_file_args \
761849
--eval "(load user-init-file)" \
762850
"${args_batch_interactive[@]}"
763851
arg_batch="--batch"
@@ -769,6 +857,9 @@ function lint {
769857
lint-checkdoc
770858
lint-compile
771859
lint-declare
860+
# NOTE: Elint doesn't seem very useful at the moment. See comment
861+
# in lint-elint function.
862+
# lint-elint
772863
lint-indent
773864
lint-package
774865
lint-regexps
@@ -825,6 +916,28 @@ function lint-elsa {
825916
|| error "Linting with Elsa failed."
826917
}
827918

919+
function lint-elint {
920+
# NOTE: Elint gives a lot of spurious warnings, apparently because it doesn't load files
921+
# that are `require'd, so its output isn't very useful. But in case it's improved in
922+
# the future, and since this wrapper code already works, we might as well leave it in.
923+
verbose 1 "Linting with Elint..."
924+
925+
local errors=0
926+
for file in "${files_project_feature[@]}"
927+
do
928+
verbose 2 "Linting with Elint: $file..."
929+
run_emacs \
930+
--load "$(elisp-elint-file)" \
931+
--eval "(makem-elint-file \"$file\")" \
932+
&& verbose 3 "Linting with Elint found no errors." \
933+
|| { error "Linting with Elint failed: $file"; ((errors++)) ; }
934+
done
935+
936+
[[ $errors = 0 ]] \
937+
&& success "Linting with Elint finished without errors." \
938+
|| error "Linting with Elint failed."
939+
}
940+
828941
function lint-indent {
829942
verbose 1 "Linting indentation..."
830943

0 commit comments

Comments
 (0)