From 22bab036929b8b4b2c79f4b456f8c1e82eba1e50 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 21 May 2017 20:25:30 +0200 Subject: [PATCH] Improve bin/doctor's portability + revise feedback --- bin/doctor | 131 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 88 insertions(+), 43 deletions(-) diff --git a/bin/doctor b/bin/doctor index 73f0a05fb..d1fbfdad9 100755 --- a/bin/doctor +++ b/bin/doctor @@ -1,13 +1,13 @@ -#!/bin/sh -":"; exec emacs --no-site-file --script "$0" -- "$@" # -*-emacs-lisp-*- +#!/usr/bin/env bash +":"; command -v emacs >/dev/null || { >&2 echo "Emacs isn't installed"; exit 1; } +":"; [[ $(emacs --version | head -n1) == *\ 2[0-2].[0-1].[0-9] ]] && echo 'Emacs version is too old, check your PATH' || exec emacs --no-site-file --batch -l "$0" # -*-emacs-lisp-*- ;; Uses a couple simple heuristics to locate issues with your environment that ;; could interfere with running or setting up DOOM Emacs. -(defconst IS-MAC (eq system-type 'darwin)) - -(require 'package) -(load "~/.emacs.d/core/autoload/message" nil t) +;; In case it isn't defined (in really old versions of Emacs, like the one that +;; ships with MacOS). +(defvar user-emacs-directory (expand-file-name "~/.emacs.d/")) (unless (equal (expand-file-name user-emacs-directory) (expand-file-name "~/.emacs.d/")) @@ -54,18 +54,31 @@ "\n"))) (buffer-string))) -(defmacro error! (&rest args) `(message! (bold (red ,@args)))) -(defmacro warn! (&rest args) `(message! (bold (yellow ,@args)))) -(defmacro success! (&rest args) `(message! (bold (green ,@args)))) -(defmacro explain! (&rest args) `(message! (indented 2 (autofill ,@args)))) +(defun color (code msg &rest args) + (format "\e[%dm%s\e[%dm" code (apply #'format msg args) 0)) -;; -(message! "%s\nRunning Emacs v%s" - (bold "DOOM Doctor") - (bold emacs-version)) -(message! "Compiled with:\n%s" (indented 2 (autofill system-configuration-features))) -(message! "uname -a:\n%s" (indented 2 (autofill (shell-command-to-string "uname -a")))) -(message "----\n") +(defalias 'msg! #'message) +(defmacro error! (&rest args) `(message (color 1 (color 31 ,@args)))) +(defmacro warn! (&rest args) `(message (color 1 (color 33 ,@args)))) +(defmacro success! (&rest args) `(message (color 1 (color 32 ,@args)))) +(defmacro explain! (&rest args) `(message (indented 2 (autofill ,@args)))) + +;;; Polyfills +;; early versions of emacs won't have this +(unless (fboundp 'string-match-p) + (defun string-match-p (regexp string &optional start) + (save-match-data + (string-match regexp string &optional start)))) + + +;; --- start a'doctorin' -------------------------------------- + +(msg! "%s\nRunning Emacs v%s" + (color 1 "DOOM Doctor") + (color 1 emacs-version)) +(msg! "Compiled with:\n%s" (indented 2 (autofill system-configuration-features))) +(msg! "uname -a:\n%s" (indented 2 (autofill (shell-command-to-string "uname -a")))) +(msg! "----\n") ;; --- is emacs set up properly? ------------------------------ @@ -74,20 +87,59 @@ (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." - (when IS-MAC + (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")))) ;; --- is the environment set up properly? -------------------- -(check! (not (executable-find "git")) - (error! "Important: Couldn't find git")) +;; gnutls-cli & openssl +(unless (not (executable-find "gnutls-cli")) + (cond ((executable-find "openssl") + (let* ((output (shell-command-to-string "openssl ciphers -v")) + (protocols + (let (protos) + (mapcar (lambda (row) + (add-to-list 'protos (cadr (split-string row " " t)))) + (split-string (shell-command-to-string "openssl ciphers -v") "\n")) + (delq nil protos)))) + (check! (not (or (member "TLSv1.1" protocols) + (member "TLSv1.2" protocols))) + (let ((version (cadr (split-string (shell-command-to-string "openssl version") " " t)))) + (warn! "Warning: couldn't find gnutls-cli, and OpenSSL is out-of-date (v%s)" version) + (explain! + "This may not affect your Emacs experience, but there are security " + "vulnerabilities in the SSL2/3 & TLS1.0 protocols. You should use " + "TLS 1.1+, which wasn't introduced until OpenSSL v1.0.1.\n\n" + "Please considering updating (or installing gnutls-cli, which is preferred)."))))) + (t + (check! t + (error! "Important: couldn't find either gnutls-cli or openssl") + (explain! + "You won't be able to install/update packages because Emacs won't be able to " + "verify HTTPS ELPA sources. Install gnutls-cli or openssl v1.0.0+. If for some " + "reason you can't, you can bypass this verification with the INSECURE flag:\n\n" + + " INSECURE=1 make install\n\n" + + "Or change `package-archives' to use non-https sources.\n\n" + + "But remember that you're leaving your security in the hands of your " + "network, provider, government, neckbearded mother-in-laws, geeky roommates, " + "or just about anyone who knows more about computers than you do!"))))) + +;; git +(check! (not (executable-find "git")) + (error! "Important: couldn't find git")) + +;; windows? windows (check! (memq system-type '(windows-nt ms-dos cygwin)) (warn! "Warning: Windows detected") (explain! "DOOM was designed for MacOS and Linux. Expect a bumpy ride!")) +;; bsd vs gnu tar (if (executable-find "tar") (check! (not (string-match-p "(GNU tar)" (shell-command-to-string "tar --version"))) (warn! "Warning: BSD tar detected") @@ -95,24 +147,18 @@ "QUELPA (through package-build) uses the system tar to build plugins." "BSD tar *could* cause errors during package installation or updating from" "non-ELPA sources." - (when IS-MAC + (when (eq system-type 'darwin) (concat "\nMacOS users can install gnu-tar via homebrew:\n" " brew install gnu-tar")))) - (check! nil (error! "Important: Couldn't find tar"))) ; very unlikely - -(check! (not (executable-find "gnutls-cli")) - (cond ((executable-find "openssl") - (warn! "Warning: couldn't find gnutls-cli") - (explain! "...but found openssl (which is possibly less secure)")) - (t - (error! "Warning: neither gnutls-cli or openssl were found") - (explain! "You will be unable to install/update packages through secure sources (HTTPS)")))) + (check! t ; very unlikely + (error! "Important: Couldn't find tar") + (explain! "This is required by package.el and QUELPA to build packages."))) ;; --- report! ------------------------------------------------ (when (getenv "DEBUG") - (message! "\n====\nHave some debug information:\n") + (msg! "\n====\nHave some debug information:\n") (let (doom-core-packages doom-debug-mode) (condition-case ex @@ -122,24 +168,23 @@ (doom-initialize-packages) (success! " + Attempt to load DOOM: success! Loaded v%s" doom-version) (when (executable-find "git") - (message! " Revision %s" + (msg! " Revision %s" (or (ignore-errors (let ((default-directory user-emacs-directory)) (shell-command-to-string "git rev-parse HEAD"))) "\n")))) ('error (warn! " + Attempt to load DOOM: failed\n %s\n" (or (cdr-safe ex) (car ex)))))) - (message! " + Emacs directory: %s\n" user-emacs-directory) - (when (bound-and-true-p doom-modules) - (message! " + enabled modules:\n%s" + (msg! " + enabled modules:\n%s" (indented 4 (columns 3 23 (mapcar (lambda (x) (format "+%s" x)) (mapcar #'cdr (doom--module-pairs))))))) - (when (bound-and-true-p doom-packages) - (message! " + enabled packages:\n%s" + (when (and (bound-and-true-p doom-packages) + (require 'package nil t)) + (msg! " + enabled packages:\n%s" (indented 4 (columns 2 35 (mapcar (lambda (pkg) @@ -148,7 +193,7 @@ (package-desc-full-name desc)))) (sort (mapcar #'car doom-packages) #'string-lessp)))))) - (message! " + byte-compiled files:\n%s" + (msg! " + byte-compiled files:\n%s" (indented 4 (columns 2 39 (let ((files (append (directory-files-recursively doom-core-dir ".elc$") @@ -157,11 +202,11 @@ (nreverse files))) (list "n/a")))))) - (message! " + exec-path:\n%s" + (msg! " + exec-path:\n%s" (indented 4 (columns 1 79 exec-path))) - (message! " + PATH:\n%s" + (msg! " + PATH:\n%s" (indented 4 (columns 1 79 (split-string (getenv "PATH") ":"))))) @@ -171,6 +216,6 @@ (message "\n----") (warn! "There were issues!") (unless (getenv "DEBUG") - (message! "\nHopefully these can help you find problems. If not, run this doctor again with DEBUG=1:") - (message! "\n DEBUG=1 make doctor\n") - (message! "And file a bug report with its output at https://github.com/hlissner/.emacs.d/issues"))) + (msg! "\nHopefully these can help you find problems. If not, run this doctor again with DEBUG=1:") + (msg! "\n DEBUG=1 make doctor\n") + (msg! "And file a bug report with its output at https://github.com/hlissner/.emacs.d/issues")))