From 0f5ad092d9e3b0956872ef7130b1d49a270f0694 Mon Sep 17 00:00:00 2001 From: Michael Herstine Date: Thu, 29 Aug 2024 18:04:31 -0700 Subject: [PATCH] Add two new functions: `elmpd-conn-status' and `elmpd-conn-failed-p'. This patch adds two new utility functions for checking the status of an elmpd connection. In addition it tidies up several docstrings, and adds some utility scripts (under 'admin') for validating commits. --- .gitignore | 1 + admin/configure-to-distcheck | 15 ++++++++++++ admin/run-linters | 44 ++++++++++++++++++++++++++++++++++++ admin/run-melpazoid | 13 +++++++++++ admin/signoff | 33 +++++++++++++++++++++++++++ elmpd.el | 27 +++++++++++++++------- 6 files changed, 125 insertions(+), 8 deletions(-) create mode 100755 admin/configure-to-distcheck create mode 100755 admin/run-linters create mode 100755 admin/run-melpazoid create mode 100755 admin/signoff diff --git a/.gitignore b/.gitignore index bfc92e5..207b49e 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ env.sh *.bz2 *.gz *.xz +*.zst diff --git a/admin/configure-to-distcheck b/admin/configure-to-distcheck new file mode 100755 index 0000000..80f88b6 --- /dev/null +++ b/admin/configure-to-distcheck @@ -0,0 +1,15 @@ +#!/bin/bash + +set -x + +# Configure the source tree, build it, test it, and test the distribution tarballs +make distclean + +./bootstrap || exit 1 +./configure || exit 1 +make all || exit 1 +if ! make check; then + test -f test/test-suite.log && cat test/test-suite.log + exit 1 +fi +make distcheck diff --git a/admin/run-linters b/admin/run-linters new file mode 100755 index 0000000..1e17eaa --- /dev/null +++ b/admin/run-linters @@ -0,0 +1,44 @@ +#!/bin/bash + +# Run a few linters. This script is designed to be run either locally by the +# developer, or as part of a Github action. + +EMACS=${EMACS:=emacs} +PKGS="package-lint" +LISP="elmpd.el" + +set -x + +# Shamelessly stolen from https://github.com/purcell/package-lint/blob/master/run-tests.sh: +INIT_PACKAGE_EL="(progn \ + (require 'package) \ + (push '(\"melpa\" . \"https://melpa.org/packages/\") package-archives) \ + (setq package-check-signature nil) \ + (package-initialize) \ + (package-refresh-contents) \ + (dolist (pkg '(${PKGS})) \ + (unless (package-installed-p pkg) \ + (package-install pkg))))" + +"$EMACS" -Q -batch --eval "$INIT_PACKAGE_EL" + +# Check that there are no TODOs left laying around in the code +find . -iname '*.el' -print0|xargs -0 -e grep -E 'TODO|TOOD|LATER|DEBUG|IN-PROGRESS|\\todo' && exit 1 + +set -e + +# This is a bit lame, since it will abort on the first error found for each +# file, but checkdoc is not easy to run in batch mode. +COLLECT_EL="(setq \ + checkdoc-create-error-function \ + (lambda (text start _end &optional _unfixable) \ + (checkdoc-error start text) \ + (kill-emacs 1)))" + +# run checkdoc +for x in $LISP; do + ${EMACS} -Q -batch --eval "$INIT_PACKAGE_EL" --eval "$COLLECT_EL" --eval "(checkdoc-file \"$x\")" +done + +# package-lint clean +${EMACS} -Q -batch --eval "$INIT_PACKAGE_EL" --eval "(package-lint-batch-and-exit)" diff --git a/admin/run-melpazoid b/admin/run-melpazoid new file mode 100755 index 0000000..14f870a --- /dev/null +++ b/admin/run-melpazoid @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +# Run melpazoid against elmpd. This script is designed to be run exclusively +# locally. + +set -ex + +cd ${HOME}/code/projects/melpazoid +git pull +PATH=/opt/emacsen/current/bin:$PATH \ +RECIPE='(elmpd :repo "sp1ff/elmpd" :fetcher github :files ("*.el" (:exclude "elmpd-pkg.el" ".dir-locals.el" "*-tests.el")))' \ +LOCAL_REPO="${HOME}/code/projects/elmpd" \ +python3 melpazoid/melpazoid.py diff --git a/admin/signoff b/admin/signoff new file mode 100755 index 0000000..295a949 --- /dev/null +++ b/admin/signoff @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +# Validate that this source tree is ready to push. This script is designed to +# be run exclusively locally. + +# Shamelessly stolen from: +set -e +SECONDS=0 +SHA=$(git rev-parse HEAD) + +GREEN=32; RED=31; BLUE=34 +announce() { echo -e "\033[0;$2m$1\033[0m"; } +run() { + local SPLIT=$SECONDS + announce "\nRun $1" $BLUE + eval "$1" + local INTERVAL=$((SECONDS-SPLIT)) + announce "Completed $1 in $INTERVAL seconds" $GREEN +} + +if [ -n "$(git status --porcelain)" ]; then + echo "Can't sign-off on a dirty repository:" >&2 + git status + exit 1 +fi + +announce "Attempting sign-off on elmpd $SHA." $GREEN + +run "admin/run-linters" +run "admin/run-melpazoid" +run "admin/configure-to-distcheck" + +announce "Signed off on elmpd $SHA in $SECONDS seconds 🍻" $GREEN diff --git a/elmpd.el b/elmpd.el index a0d1c81..5b9398b 100644 --- a/elmpd.el +++ b/elmpd.el @@ -355,7 +355,9 @@ an optional callback. The (optional) third is the callback style; one of (defun elmpd--process-sentinel (process event) "Callback invoked when PROCESS experiences EVENT." - (elmpd--log 'info "Process: %s saw the event '%s'." (process-name process) (substring event 0 -1))) + (let* ((msg (substring event 0 -1)) + (level (if (string-prefix-p "failed" msg) 'error 'info))) + (elmpd--log level "Process: %s saw the event '%s'." (process-name process) msg))) (defun elmpd--kick-queue (conn) "Move CONN's queue forward. @@ -781,7 +783,7 @@ as soon as possible." ;; socket. We prefer the Unix socket. (fd (if (and local (file-exists-p local)) - (make-network-process :name name :remote local :nowait t) + (make-network-process :name name :remote local :nowait t :service t) (make-network-process :name name :host host @@ -792,7 +794,8 @@ as soon as possible." (lambda () (elmpd--log 'info "Finalizing `%s'" fd) (delete-process fd)))) - (conn (elmpd--make-connection :fd fd :inbuf "" :finalize dtor :idle (plist-get args :subsystems)))) + (conn (elmpd--make-connection :fd fd :inbuf "" :finalize dtor + :idle (plist-get args :subsystems)))) (set-process-coding-system fd 'utf-8-unix 'utf-8-unix) (set-process-query-on-exit-flag fd nil) (set-process-sentinel fd 'elmpd--process-sentinel) @@ -885,8 +888,8 @@ depend on the responses to prior commands, consider ;; ;; 1. `q' is empty & we're not expecting any MPD output ;; - ;; 2. `q' is non-empty & we're waiting for the result - ;; of the command at its head + ;; 2. `q' is non-empty & we're waiting for the result + ;; of the command at its head (unless q ;; We're idling-- kick off this command. (elmpd--kick-queue conn)))))) @@ -895,17 +898,25 @@ depend on the responses to prior commands, consider "Return the present length of CONN's queue." (length (elmpd-connection--q conn))) +(defun elmpd-conn-status (conn) + "Return the process status for CONN." + (process-status (elmpd-connection--fd conn))) + +(defun elmpd-conn-failed-p (conn) + "Return t if CONN failed to connect, nil else." + (eq 'failed (elmpd-conn-status conn))) + (defmacro elmpd-chain (conn &rest chain) "Chain multiple MPD commands on CONN conveniently. See below for CHAIN. Sending multiple, un-connected commands to MPD is simple: use a command list: - (elmpd-send conn '(\"foo\" \"bar\" \"splat\")...) + (elmpd-send conn \='(\"foo\" \"bar\" \"splat\")...) But what if you need to send a command, process the response, and send another command whose contents depends upon the response to -the first? Then you're reduced to writing things like: +the first? Then you\='re reduced to writing things like: (elmpd-send conn @@ -936,7 +947,7 @@ CMD may be any of: 3. a list with three elements (`cmd' `cb' `style') In any case, `cmd' may be either a string or a list of strings. -In case 3, if `cmd' is a string, then `style' must be 'default. +In case 3, if `cmd' is a string, then `style' must be \='default. Note that the callback will be invoked with just two arguments (the connection and the response), since it will only be invoked on success (you can place failure logic in an :or-else