Skip to content

Instantly share code, notes, and snippets.

@plathrop
Created July 29, 2011 16:48
Show Gist options
  • Save plathrop/1114207 to your computer and use it in GitHub Desktop.
Save plathrop/1114207 to your computer and use it in GitHub Desktop.
Minor mode for validating puppet manifests.
;;; -*- coding: utf-8 -*-
;;;
;;; puppet-validate.el --- minor mode for validating puppet manifest
;;; syntax.
;;;
;;; © 2011 Paul Lathrop <paul@tertiusfamily.net>
;;;
;;; Keywords: languages puppet
;;;
;;; puppet-validate.el is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by the Free
;;; Software Foundation; either version 2, or (at your option) any later
;;; version.
;;;
;;; It is distributed in the hope that it will be useful, but WITHOUT ANY
;;; WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
;;; FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
;;; details.
;;;
;;; You should have received a copy of the GNU General Public License along
;;; with your copy of Emacs; see the file COPYING. If not, write to the Free
;;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
;;; 02111-1307, USA.
;;;
;;; Commentary:
;;;
;;; This code is thanks to Ian Eure and python-pep8.el.
;;; https://gist.github.com/302847
;;;
;;; Basic setup:
;;;
;;; (autoload 'puppet-validate "puppet-validate")
;;;
;;; Automatically syntax check .pp files on save:
;;;
;;; (add-hook 'puppet-mode-hook
;;; (lambda ()
;;; (add-hook (make-local-variable 'after-save-hook)
;;; 'puppet-validate))))
;;;
;;; Code:
(require 'compile)
(defgroup puppet-validate nil
"Minor mode for validating puppet manifests."
:prefix "puppet-validate-"
:group 'tools)
(defvar puppet-validate-last-buffer nil
"The most recent puppet-validate buffer.
A puppet-validate buffer becomes most recent when you select
puppet-validate mode in it. Notice that using \\[next-error] or
\\[compile-goto-error] modifies `compilation-last-buffer` rather
than `puppet-validate-last-buffer`.")
(defcustom puppet-validate-command "puppet parser validate"
"Base command to run to validate puppet manifests."
:type '(file)
:group 'puppet-validate)
(defcustom puppet-validate-options '()
"Additional options to pass to the validation command."
:type '(repeat string)
:group 'puppet-validate)
(defcustom puppet-validate-ask-about-save nil
"Non-nil means \\[puppet-validate] asks which buffers to save
before compiling. Otherwise it saves all modified buffers
without asking."
:type 'boolean
:group 'puppet-validate)
(defconst puppet-validate-regexp-alist
'(("^err: \\(.*\\): Syntax error at \\(.*\\) at \\([a-zA-Z0-9_/-]+\\.pp\\):\\([0-9]+\\)" 3 4))
"Regexp used to match puppet-validate hits. See `compilation-error-regexp-alist'.")
(define-compilation-mode puppet-validate-mode "puppet-validate"
(setq puppet-validate-last-buffer (current-buffer))
(set (make-local-variable 'compilation-error-regexp-alist)
puppet-validate-regexp-alist)
(set (make-local-variable 'compilation-disable-input) t))
(defvar puppet-validate-mode-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map compilation-minor-mode-map)
(define-key map " " 'scroll-up)
(define-key map "\^?" 'scroll-down)
(define-key map "\C-c\C-f" 'next-error-follow-minor-mode)
(define-key map "\r" 'compile-goto-error) ;; ?
(define-key map "n" 'next-error-no-select)
(define-key map "p" 'previous-error-no-select)
(define-key map "{" 'compilation-previous-file)
(define-key map "}" 'compilation-next-file)
(define-key map "\t" 'compilation-next-error)
(define-key map [backtab] 'compilation-previous-error)
map)
"Keymap for puppet-validate
buffers. `compilation-minor-mode-map` is a cdr of this.")
;;;###autoload
(defun puppet-validate ()
"Run puppet's parser to validate manifests and collect output in a buffer.
While puppet runs asynchronously, you can use \\[next-error] (M-x
next-error), or \\<puppet-validate-mode-map>\\[compile-goto-error] in
the grep \ output buffer, to go to the lines where puppet found
matches."
(interactive)
(save-some-buffers (not puppet-validate-ask-about-save) nil)
(let* ((tramp (tramp-tramp-file-p (buffer-file-name)))
(file (or (and tramp
(aref (tramp-dissect-file-name (buffer-file-name)) 3))
(buffer-file-name)))
(modulepath (concat (locate-dominating-file file "modules") "modules"))
(command (mapconcat
'identity
(list puppet-validate-command
"--color=false"
(mapconcat 'identity (list "--modulepath" modulepath) " ")
(mapconcat 'identity puppet-validate-options " ")
(comint-quote-filename file)) " ")))
(compilation-start command 'puppet-validate-mode)))
(provide 'puppet-validate)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment