aboutsummaryrefslogtreecommitdiffstats
path: root/src/option.lisp
blob: 4d1ce19ad7d3cd767b5dd7c650ea22701b4bcbb4 (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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
(in-package :wajir)

(opts:define-opts
  (:name :login
   :description "Jira login email address"
   :long "login"
   :arg-parser #'identity
   :meta-var "<login>")
  (:name :token
   :description "Jira API token"
   :long "token"
   :arg-parser #'identity
   :meta-var "<token>")
  (:name :endpoint
   :description "Jira site URL host (e.g. example.atlassian.net)"
   :long "endpoint"
   :meta-var "<endpoint>")

  (:name :sendmail
   :description "send email command"
   :long "sendmail"
   :meta-var "<command>")
  (:name :email-to
   :description "recipient email address"
   :long "email-to"
   :meta-var "<address>")

  (:name :verbose
   :description "print verbose output"
   :short #\v
   :long "verbose")

  (:name :help
   :description "print this help menu"
   :short #\h
   :long "help")
  (:name :version
   :description "show the program version"
   :short #\V
   :long "version"))

(defmacro when-option ((options option) &body body)
  "When `option` is present in `options`, run `body`."
  `(let ((value (getf ,options ,option)))
     (when value
       ,@body)))

(defun exit-with-error (condition exit-code)
  "Print the error associated with `condition` on standard error, then exit
with code `exit-code`."
  (format *error-output* "error: ~a~%" condition)

  (opts:exit exit-code))

(defun handle-option-error (condition)
  "Handle errors related to command line options. Prints the error specified by
`condition` and exits with EX_USAGE."
  (exit-with-error condition sysexits:+usage+))

(defun parse-options ()
  "Parse command line options."
  (multiple-value-bind (options free-args)
    (handler-bind
      ((opts:unknown-option #'handle-option-error)
       (opts:missing-arg #'handle-option-error)
       (opts:arg-parser-failed #'handle-option-error)
       (opts:missing-required-option #'handle-option-error))

      (opts:get-opts))

    ;; Help
    (when-option (options :help)
      (opts:describe
        :usage-of "wajir"
        :args "<JQL>")

      (opts:exit sysexits:+usage+))

    ;; Version
    (when-option (options :version)
      (format t "~a~%" (asdf:component-version (asdf:find-system :extreload)))

      (opts:exit sysexits:+ok+))

    ;; If `sendmail` is given, `email-to` must be defined.
    (when (not (null (getf options :sendmail)))
      (when (null (getf options  :email-to))
        (format *error-output* "error: `--sendmail' requires `--email-to'")
        (opts:exit sysexits:+usage+)))

    ;; Error if JQL is empty
    (when (null free-args)
      (format *error-output* "error: missing JQL")

      (opts:exit sysexits:+usage+))

    (make-instance 'config
                   :login (getf options :login)
                   :token (getf options :token)
                   :endpoint (getf options :endpoint)
                   :sendmail (getf options :sendmail)
                   :email-to (getf options :email-to)
                   :verbose (getf options :verbose)
                   :jql (first free-args))))