aboutsummaryrefslogtreecommitdiffstats
path: root/elisp/shepherd.el
blob: 3899b92e2100e49b21a15ab92311de625beca2b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
;;; shepherd.el --- Manage shepherd services -*- lexical-binding: t; -*-
;;
;; Copyright (C) 2022 Óscar Nájera
;;
;; Author: Óscar Nájera <hi@oscarnajera.com>
;; Maintainer: Óscar Nájera <hi@oscarnajera.com>
;; Created: April 20, 2022
;; Modified: April 20, 2022
;; Version: 0.0.1
;; Keywords: abbrev bib c calendar comm convenience data docs emulations extensions faces files frames games hardware help hypermedia i18n internal languages lisp local maint mail matching mouse multimedia news outlines processes terminals tex tools unix vc wp
;; Homepage: https://github.com/titan/shepherd
;; Package-Requires: ((emacs "25.1"))
;;
;; This file is not part of GNU Emacs.
;;
;;; Commentary:
;;
;;  Manage shepherd services
;;
;;; Code:

(require 'subr-x)
(require 'helm)

(defun shepherd-command (&rest cmds)
  "Call herd with CMDS."
  (with-temp-buffer
    (apply #'call-process "herd" nil t nil cmds)
    (string-trim (buffer-string))))

(defun shepherd-services ()
  "List all enabled shepherd services."
  (with-temp-buffer
    (insert (shepherd-command "status"))
    (goto-char (point-min))
    (let (matches)
      (while (search-forward-regexp (rx (group (or "+" "-")) space (group (+ any))) nil t)
        (let ((status (if (string= (match-string 1) "+")
                          (propertize "start" 'face 'font-lock-function-name-face)
                        (propertize "stop" 'face 'font-lock-variable-name-face)))
              (service (match-string 2)))
          (push (cons service status) matches)))
      (sort matches (lambda (a b) (string< (car a) (car b)))))))

(defun shepherd-set (service status)
  "Ensure SERVICE is in STATUS."
  (unless (string= status (cdr (assoc service (shepherd-services))))
    (shepherd-command (symbol-name status) service)))

(defun shepherd ()
  "Manage shepherd services."
  (interactive)
  (helm
   :prompt "Shepherd service:"
   :sources (helm-build-sync-source "Services"
              :candidates
              (cl-loop for it in (shepherd-services)
                       collect (cons (format "%s\t%s" (cdr it) (car it))
                                     (car it)))
              :action
              (mapcar (lambda (action)
                        (let ((name (symbol-name action)))
                          `(,name .
                                  (lambda (service)
                                    (message (shepherd-command ,name service))))))
                      '(status start stop restart enable)))))

(provide 'shepherd)
;;; shepherd.el ends here