From 7fa208a356eba601017025db33a4465c649e2309 Mon Sep 17 00:00:00 2001 From: USAMI Kenta Date: Fri, 17 Jul 2026 22:46:12 +0900 Subject: [PATCH 1/6] Require Emacs 27.1 everywhere The declared floor was inconsistent -- 25.1 in phpstan.el and flycheck-phpstan.el, 26.1 in flymake-phpstan.el and phpstan-hover.el, "Emacs 26+" in the README, and 24.3 in Eask -- and none of it was true. CI has not covered anything below 27.2 for a while, and `php-mode' and `flycheck' both require Emacs 27.1 themselves, so a 26.x user could never have resolved the dependencies in the first place. Say 27.1 in every place. --- CHANGELOG.md | 4 ++++ README.org | 2 +- flycheck-phpstan.el | 2 +- flymake-phpstan.el | 2 +- phpstan-hover.el | 2 +- phpstan.el | 2 +- 6 files changed, 9 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f29d5b..9f40d40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,10 @@ All notable changes of the `phpstan.el` are documented in this file using the [K * Fix editor mode detection asking the wrong program for its version. Only the first element of the command line was probed, which is the container runtime for `(phpstan-executable . docker)` / `container` and `php` for a PHAR without the executable bit — so `docker --version` and `php --version` were parsed as PHPStan versions (`d1c06ef`, `Technologies`) and editor mode was silently disabled for every setup except a directly executable `phpstan`. * `phpstan-version` and `phpstan-editor-mode-available-p` now take the whole command line, as returned by `phpstan-get-executable-and-args`. A bare string is still accepted. `phpstan-version` no longer merges STDERR into the version string, which a container runtime pollutes with its progress report. +### Removed + +* Drop support for Emacs 26 and earlier. All files now require Emacs 27.1, which is also the floor of `php-mode` and `flycheck` themselves, so anything older could not have resolved its dependencies anyway. + ## [0.9.0] ### Added diff --git a/README.org b/README.org index ed8ef86..543e14b 100644 --- a/README.org +++ b/README.org @@ -5,7 +5,7 @@ #+END_HTML Emacs interface to [[https://github.com/phpstan/phpstan][PHPStan]], includes checker for [[http://www.flycheck.org/en/latest/][Flycheck]]. ** Support version -- Emacs 26+ +- Emacs 27.1+ - PHPStan latest/dev-master (NOT support 0.9 seriese) - PHP 7.1+ or Docker runtime diff --git a/flycheck-phpstan.el b/flycheck-phpstan.el index c8af850..ee8094b 100644 --- a/flycheck-phpstan.el +++ b/flycheck-phpstan.el @@ -7,7 +7,7 @@ ;; Version: 0.9.0 ;; Keywords: tools, php ;; Homepage: https://github.com/emacs-php/phpstan.el -;; Package-Requires: ((emacs "25.1") (flycheck "26") (phpstan "0.9.0")) +;; Package-Requires: ((emacs "27.1") (flycheck "26") (phpstan "0.9.0")) ;; License: GPL-3.0-or-later ;; This program is free software; you can redistribute it and/or modify diff --git a/flymake-phpstan.el b/flymake-phpstan.el index ec93028..80bc794 100644 --- a/flymake-phpstan.el +++ b/flymake-phpstan.el @@ -7,7 +7,7 @@ ;; Version: 0.9.0 ;; Keywords: tools, php ;; Homepage: https://github.com/emacs-php/phpstan.el -;; Package-Requires: ((emacs "26.1") (phpstan "0.9.0")) +;; Package-Requires: ((emacs "27.1") (phpstan "0.9.0")) ;; License: GPL-3.0-or-later ;; This program is free software; you can redistribute it and/or modify diff --git a/phpstan-hover.el b/phpstan-hover.el index 09f1ebd..b5ef1d9 100644 --- a/phpstan-hover.el +++ b/phpstan-hover.el @@ -6,7 +6,7 @@ ;; Created: 16 Feb 2026 ;; Keywords: tools, php ;; Homepage: https://github.com/emacs-php/phpstan.el -;; Package-Requires: ((emacs "26.1") (phpstan "0.9.0")) +;; Package-Requires: ((emacs "27.1") (phpstan "0.9.0")) ;; License: GPL-3.0-or-later ;;; Commentary: diff --git a/phpstan.el b/phpstan.el index 8269675..336b8d4 100644 --- a/phpstan.el +++ b/phpstan.el @@ -7,7 +7,7 @@ ;; Version: 0.9.0 ;; Keywords: tools, php ;; Homepage: https://github.com/emacs-php/phpstan.el -;; Package-Requires: ((emacs "25.1") (compat "30") (php-mode "1.22.3") (php-runtime "0.2")) +;; Package-Requires: ((emacs "27.1") (compat "30") (php-mode "1.22.3") (php-runtime "0.2")) ;; License: GPL-3.0-or-later ;; This program is free software; you can redistribute it and/or modify From 1f92f054aec52119345b82a2dc7a671f28f8362c Mon Sep 17 00:00:00 2001 From: USAMI Kenta Date: Fri, 17 Jul 2026 22:46:24 +0900 Subject: [PATCH 2/6] Require Emacs 27.1 in Eask Eask still declared 24.3, out of step with the 27.1 the package headers now ask for. Align it. The package archive is left as MELPA: pinning to MELPA Stable belongs in the local 27.x check, not in CI, where the stable php-mode release lags behind Emacs master and breaks the snapshot job. See the Eask.27 file. --- Eask | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Eask b/Eask index dfec247..6182245 100644 --- a/Eask +++ b/Eask @@ -15,7 +15,7 @@ (source 'gnu) (source 'melpa) -(depends-on "emacs" "24.3") +(depends-on "emacs" "27.1") (depends-on "compat") (depends-on "php-mode") (depends-on "php-runtime") From d9a28dff628c22210fcd67b5e02b74432f70eed2 Mon Sep 17 00:00:00 2001 From: USAMI Kenta Date: Sat, 18 Jul 2026 00:01:03 +0900 Subject: [PATCH 3/6] Fix declare-function forms for tramp Both `declare-function' calls quoted the function name and the argument list, which is wrong -- the symbol and the arglist are passed unquoted -- so neither declaration registered, and the byte compiler warned: the function `tramp-dissect-file-name' might not be defined at runtime One of them also named the file "tamp" instead of "tramp". Found while compiling under Emacs 27.2; the warning was present on every version. --- CHANGELOG.md | 1 + phpstan.el | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f40d40..e6244e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,7 @@ All notable changes of the `phpstan.el` are documented in this file using the [K * Fix `flycheck-phpstan` silently discarding the fallback warning when PHPStan produced no JSON report, hiding failures such as a broken configuration file behind a clean buffer. * Fix editor mode detection asking the wrong program for its version. Only the first element of the command line was probed, which is the container runtime for `(phpstan-executable . docker)` / `container` and `php` for a PHAR without the executable bit — so `docker --version` and `php --version` were parsed as PHPStan versions (`d1c06ef`, `Technologies`) and editor mode was silently disabled for every setup except a directly executable `phpstan`. * `phpstan-version` and `phpstan-editor-mode-available-p` now take the whole command line, as returned by `phpstan-get-executable-and-args`. A bare string is still accepted. `phpstan-version` no longer merges STDERR into the version string, which a container runtime pollutes with its progress report. +* Fix `declare-function` forms for `tramp` that quoted the function name and argument list (and misspelled `tramp` as `tamp`), so the byte compiler warned that `tramp-dissect-file-name` might not be defined at runtime. ### Removed diff --git a/phpstan.el b/phpstan.el index 336b8d4..b0b5ddb 100644 --- a/phpstan.el +++ b/phpstan.el @@ -63,8 +63,8 @@ (require 'php) (require 'json) (require 'tramp) - (declare-function 'tramp-dissect-file-name "tramp" '(name &optional nodefault)) - (declare-function 'tramp-file-name-localname "tamp" '(cl-x))) + (declare-function tramp-dissect-file-name "tramp" (name &optional nodefault)) + (declare-function tramp-file-name-localname "tramp" (cl-x))) ;; Variables: (defgroup phpstan nil From 133321c628aa1db6807f3be37f34e42618f84bc0 Mon Sep 17 00:00:00 2001 From: USAMI Kenta Date: Sat, 18 Jul 2026 00:01:03 +0900 Subject: [PATCH 4/6] Add a script to test under Emacs 27.2 via nix-emacs-ci CI does not cover Emacs 27, but Package-Requires now declares it as the floor, so there has to be a way to check it by hand. nix-emacs-ci does not expose Emacs 27 on aarch64-darwin (it fails to build old Emacs on that platform), only on x86_64-darwin, so on Apple Silicon this goes through Rosetta -- which needs `extra-platforms = x86_64-darwin` in nix.conf. The prebuilt binaries are also not cached for x86_64-darwin, so the first run builds Emacs from source; the nix-emacs-ci revision is pinned so that later runs reuse it instead of rebuilding. --- .github/run-emacs-27-2.sh | 55 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100755 .github/run-emacs-27-2.sh diff --git a/.github/run-emacs-27-2.sh b/.github/run-emacs-27-2.sh new file mode 100755 index 0000000..c9c1e49 --- /dev/null +++ b/.github/run-emacs-27-2.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +# Build this package with Emacs 27.2 from nix-emacs-ci. +# +# CI does not cover Emacs 27 (see .github/workflows/test.yml), so this is the +# way to check the floor declared in Package-Requires by hand. +# +# nix-emacs-ci does not expose Emacs 27 on aarch64-darwin, only on +# x86_64-darwin, so on Apple Silicon this runs through Rosetta. That needs +# `extra-platforms = x86_64-darwin` in /etc/nix/nix.conf. Reaching the +# prebuilt binaries also needs your user in `trusted-users` there, otherwise +# the daemon silently ignores the substituter below and builds from source. +set -euo pipefail + +# Pinned rather than master, so that the Emacs you get today is the Emacs you +# got last time. nix-emacs-ci pins nixpkgs in its own flake.lock, so following +# master would change the derivation -- and on a platform without prebuilt +# binaries (see below) that means rebuilding Emacs from source. +NIX_EMACS_CI_REV=${NIX_EMACS_CI_REV:-ca88f42462347e8e17859645aa59b156617e98fb} +NIX_EMACS_CI=${NIX_EMACS_CI:-https://github.com/purcell/nix-emacs-ci/archive/${NIX_EMACS_CI_REV}.tar.gz} +EMACS_ATTR=${EMACS_ATTR:-emacs-27-2} + +case "$(uname -s)/$(uname -m)" in + Darwin/arm64) SYSTEM=x86_64-darwin ;; + Darwin/*) SYSTEM=x86_64-darwin ;; + Linux/x86_64) SYSTEM=x86_64-linux ;; + Linux/aarch64) SYSTEM=aarch64-linux ;; + *) echo "unsupported host: $(uname -s)/$(uname -m)" >&2; exit 1 ;; +esac + +cd "$(dirname "$0")/.." + +echo "==> Fetching ${EMACS_ATTR} for ${SYSTEM}" +emacs_path=$(nix-build --no-out-link \ + --option system "${SYSTEM}" \ + --option extra-substituters https://emacs-ci.cachix.org \ + --option extra-trusted-public-keys emacs-ci.cachix.org-1:B5FVOrxhXXrOL0S+tQ7USrhjMT5iOPH+QN9q0NItom4= \ + -A "${EMACS_ATTR}" \ + -E "import (fetchTarball \"${NIX_EMACS_CI}\")") + +export PATH="${emacs_path}/bin:${PATH}" +export EMACS="${emacs_path}/bin/emacs" + +echo "==> $("${EMACS}" --version | head -1)" + +# Stale .elc files silently win over newer .el, which would hide a failure. +find . -maxdepth 1 -name '*.elc' -delete +rm -rf .eask + +echo "==> eask install-deps" +eask install-deps + +echo "==> eask compile" +eask compile + +echo "==> OK" From 77907da61c1c50656b96228f121bd6a88a4a9521 Mon Sep 17 00:00:00 2001 From: USAMI Kenta Date: Sat, 18 Jul 2026 00:24:19 +0900 Subject: [PATCH 5/6] Add Eask.27 to pull dependencies from MELPA Stable on Emacs 27 MELPA's php-mode and flycheck track Emacs master -- flycheck HEAD requires Emacs 28.1 and will not install on 27 -- which is why the 27.2 CI job was failing and got dropped. MELPA Stable's releases still support 27 (flycheck 36.0, php-mode 1.27.0). Eask reads `Eask.' in preference to `Eask' on a matching Emacs, so `Eask.27' redirects only Emacs 27 to MELPA Stable while every other version keeps using MELPA through the main `Eask'. This lets the 27 check run in CI (next commit) and locally (.github/run-emacs-27-2.sh) without a per-job archive override. It is a copy of `Eask' differing only in the `source' line; its header says so, since the two have to stay in sync. --- Eask.27 | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 Eask.27 diff --git a/Eask.27 b/Eask.27 new file mode 100644 index 0000000..5535597 --- /dev/null +++ b/Eask.27 @@ -0,0 +1,35 @@ +;; -*- mode: eask; lexical-binding: t -*- + +;; Emacs 27-only variant of `Eask'. Eask reads `Eask.27' in preference to +;; `Eask' on Emacs 27, so this redirects only that version to MELPA Stable. +;; +;; MELPA's php-mode and flycheck track Emacs master: flycheck HEAD requires +;; Emacs 28.1 and will not install on 27. MELPA Stable's releases still +;; support 27 (flycheck 36.0, php-mode 1.27.0), so the 27 CI job and the local +;; .github/run-emacs-27-2.sh check both use them. +;; +;; This is a copy of `Eask' with one line changed -- the `source'. Keep the +;; rest in sync with `Eask', which is the source of truth. + +(package "phpstan" + "0.9.0" + "Interface to PHPStan (PHP static analyzer)") + +(website-url "https://github.com/emacs-php/phpstan.el") +(keywords "tools" "php") + +(package-file "phpstan.el") +(files "*.el") + +(script "test" "echo \"Error: no test specified\" && exit 1") + +(source 'gnu) +(source 'melpa-stable) + +(depends-on "emacs" "27.1") +(depends-on "compat") +(depends-on "php-mode") +(depends-on "php-runtime") +(depends-on "flycheck") + +(setq network-security-level 'low) ; see https://github.com/jcs090218/setup-emacs-windows/issues/156#issuecomment-932956432 From 44f8306100c48eb13b5d97ac74fbf2542e6aabe7 Mon Sep 17 00:00:00 2001 From: USAMI Kenta Date: Sat, 18 Jul 2026 00:24:57 +0900 Subject: [PATCH 6/6] Test Emacs 27.2 on Ubuntu in CI 27.1 is the declared floor, so cover it in CI again. It was dropped because MELPA's flycheck HEAD requires Emacs 28.1 and would not install on 27; the previous commit's Eask.27 pulls 27's dependencies from MELPA Stable instead, which supports it. Ubuntu only: one platform is enough to catch a 27-specific break, and it keeps the matrix small. --- .github/workflows/test.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1d77a33..6cfecb3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -24,6 +24,12 @@ jobs: - 30.1 experimental: [false] include: + # Emacs 27.1 is the declared floor. Run it on Ubuntu only: its + # dependencies come from MELPA Stable via Eask.27 (MELPA's HEAD needs + # Emacs 28.1), and one platform is enough to catch a 27-specific break. + - os: ubuntu-latest + emacs-version: "27.2" + experimental: false - os: ubuntu-latest emacs-version: snapshot experimental: true