From acf67244cac181cb6aa4e5861581e37297067520 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 16 Mar 2019 14:01:26 -0400 Subject: [PATCH] Improve doom doctor + Bump Emacs version check to 25.3 + Fix doctor reporting missing packages that are user-disabled + Add Doom core checks for over-sized cache files (a possible cause of freezes/hangs) + Emit a backtrace from module doctor script errors + Fix doom doctor not respecting DEBUG envvar --- bin/doom-doctor | 53 +++++++++++++++++++++++++++++-------------------- core/doctor.el | 29 +++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 22 deletions(-) create mode 100644 core/doctor.el diff --git a/bin/doom-doctor b/bin/doom-doctor index ac162f863..2fe9c2241 100755 --- a/bin/doom-doctor +++ b/bin/doom-doctor @@ -4,17 +4,24 @@ ":"; [[ $VERSION == *\ 2[0-2].[0-1].[0-9] ]] && { echo "You're running $VERSION"; echo "That version is too old to run the doctor. Check your PATH"; echo; exit 2; } ":"; exec emacs --quick --script "$0"; exit 0 -;; Uses a couple simple heuristics to locate issues with your environment that -;; could interfere with running or setting up DOOM Emacs. +;; The Doom doctor is essentially one big, self-contained elisp shell script +;; that uses a series of simple heuristics to diagnose common issues on your +;; system. Issues that could intefere with Doom Emacs. +;; +;; Doom module may optionally have a doctor.el file to run their own heuristics +;; in. Doctor scripts may run in versions of Emacs as old as Emacs 23, so you +;; are limited to very basic standard library calls (e.g. avoid cl, subr-x, and +;; any Doom dependencies). -;; In case it isn't defined (in really old versions of Emacs, like the one that -;; ships with MacOS). +;; In really old versions of Emacs `user-emacs-directory' isn't defined (defvar user-emacs-directory (expand-file-name "../" (file-name-directory load-file-name))) (unless (file-directory-p user-emacs-directory) (error "Couldn't find a Doom config!")) (unless noninteractive (error "This script must not be run from an interactive session.")) +(when (getenv "DEBUG") + (setq debug-on-error t)) (require 'pp) @@ -117,10 +124,10 @@ ;; --- is emacs set up properly? ------------------------------ -(when (version< emacs-version "25.1") +(when (version< emacs-version "25.3") (error! "Important: Emacs %s detected [%s]" emacs-version (executable-find "emacs")) (explain! - "DOOM only supports >= 25.1. Perhaps your PATH wasn't set up properly." + "DOOM only supports >= 25.3. Perhaps your PATH wasn't set up properly." (when (eq system-type 'darwin) (concat "\nMacOS users should use homebrew (https://brew.sh) to install Emacs\n" " brew install emacs --with-modules --with-imagemagick --with-cocoa")))) @@ -166,7 +173,7 @@ font font-dest) (explain! "You can install it by running `M-x all-the-icons-install-fonts' within Emacs.\n\n" "This could also mean you've installed them in non-standard locations, in which " - "case, ignore this warning.")))))) + "case feel free to ignore this warning.")))))) ;; gnutls-cli & openssl (section! "Checking gnutls/openssl...") @@ -289,6 +296,9 @@ (or (cdr-safe ex) (car ex))) (setq doom-modules nil))) +(section! "Checking Doom core for irregularities...") +(load (expand-file-name "doctor.el" doom-core-dir) nil 'nomessage) + (when (bound-and-true-p doom-modules) (section! "Checking your enabled modules...") (let ((indent 4)) @@ -296,22 +306,21 @@ (maphash (lambda (key plist) (let ((prefix (format "%s" (color 1 "(%s %s) " (car key) (cdr key))))) - (condition-case ex + (condition-case-unless-debug ex (let ((doctor-file (doom-module-path (car key) (cdr key) "doctor.el")) - (packages-file (doom-module-path (car key) (cdr key) "packages.el")) - doom-packages) - (when (or (file-exists-p doctor-file) - (file-exists-p packages-file)) - (let ((doom--stage 'packages)) - (when (load packages-file t t) - (cl-loop for (name . plist) in doom-packages - unless (or (doom-package-prop name :disable) - (doom-package-prop name :ignore t) - (package-built-in-p name) - (package-installed-p name)) - do (error! "%s is not installed" name))) - (let ((doom--stage 'doctor)) - (load doctor-file t t))))) + (packages-file (doom-module-path (car key) (cdr key) "packages.el"))) + (cl-loop with doom--stage = 'packages + for name in (let (doom-packages + doom-disabled-packages) + (load packages-file 'noerror 'nomessage) + (mapcar #'car doom-packages)) + unless (or (doom-package-prop name :disable) + (doom-package-prop name :ignore t) + (package-built-in-p name) + (package-installed-p name)) + do (error! "%s is not installed" name)) + (let ((doom--stage 'doctor)) + (load doctor-file 'noerror 'nomessage))) (file-missing (error! "%s" (error-message-string ex))) (error (error! "Syntax error: %s" ex))))) doom-modules))) diff --git a/core/doctor.el b/core/doctor.el new file mode 100644 index 000000000..8487cf324 --- /dev/null +++ b/core/doctor.el @@ -0,0 +1,29 @@ +;;; core/doctor.el -*- lexical-binding: t; -*- + +(defun file-size (file &optional dir) + (setq file (expand-file-name file dir)) + (when (file-exists-p file) + (/ (nth 7 (file-attributes file)) + 1024.0))) + +;; Check for oversized problem files in cache that may cause unusual/tremendous +;; delays or freezing. This shouldn't happen often. +(dolist (file (list "savehist" + "projectile.cache")) + (let* ((path (expand-file-name file doom-core-dir)) + (size (file-size path))) + (when (and (numberp size) (> size 2000)) + (warn! "%s is too large (%.02fmb). This may cause freezes or odd startup delays" + (file-relative-name path doom-core-dir) + (/ size 1024)) + (explain! "Consider deleting it from your system (manually)")))) + +(when! (not (executable-find "fd")) + (warn! "Couldn't find the `fd' binary; project file searches will be slightly slower")) + +(let ((default-directory "~")) + (require 'projectile) + (when! (cl-find-if #'projectile-file-exists-p projectile-project-root-files-bottom-up) + (warn! "Your $HOME is recognized as a project root") + (explain! "Doom will disable bottom-up root search, which may reduce the accuracy of project\n" + "detection.")))