aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeddy Wing2022-05-08 18:07:27 +0200
committerTeddy Wing2022-05-08 18:07:27 +0200
commitca75a8f0f3860f0ac64eaf7fdeaec422912fcd99 (patch)
tree4ca0b4374e24e77e5a738c96d026b7cbbe482417
parent6a4dcbbaaf4f75fceb402ea073eb33d32445bbcb (diff)
downloadwajir-ca75a8f0f3860f0ac64eaf7fdeaec422912fcd99.tar.bz2
Parse command line options
* Define command line options for the program * Define Make rules to build a binary * Fix system entrypoint definition * Comment out some application code to test command line option parsing
-rw-r--r--Makefile11
-rw-r--r--src/main.lisp28
-rw-r--r--src/option.lisp104
-rw-r--r--wajir.asd7
4 files changed, 136 insertions, 14 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..03dbb2c
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,11 @@
+LISP ?= sbcl
+
+
+.PHONY: build
+build: wajir
+
+wajir: wajir.asd lib/* src/*.lisp
+ $(LISP) --load wajir.asd \
+ --eval '(ql:quickload :wajir)' \
+ --eval '(asdf:make :wajir)' \
+ --eval '(quit)'
diff --git a/src/main.lisp b/src/main.lisp
index 2ac7daf..938a950 100644
--- a/src/main.lisp
+++ b/src/main.lisp
@@ -7,14 +7,18 @@
;; Send email to ^maildir^program^ containing message with issue metadata
;; Continue to next page
- (let ((config (make-instance 'config
- :login "name@example.com"
- :token "atlassian-token"
- :endpoint "example.atlassian.net"
- :email-to "name@example.com"
- :jql "project = \"FAKE\" AND watcher != currentUser() AND key > \"FAKE-100\" ORDER BY created DESC")))
-
- (run config)))
+ (let ((config (parse-options)))
+ (format t "~S" config))
+
+ ; (let ((config (make-instance 'config
+ ; :login "name@example.com"
+ ; :token "atlassian-token"
+ ; :endpoint "example.atlassian.net"
+ ; :email-to "name@example.com"
+ ; :jql "project = \"FAKE\" AND watcher != currentUser() AND key > \"FAKE-100\" ORDER BY created DESC")))
+ ;
+ ; (run config))
+ )
(defun run (config)
(let ((basic-auth-token (cl-base64:string-to-base64-string
@@ -89,10 +93,10 @@
(when (verbose config)
(format t "Watching issue ~A~%" (gethash "key" issue)))
- (add-watcher
- (endpoint config)
- issue
- :basic-auth-token basic-auth-token)
+ ; (add-watcher
+ ; (endpoint config)
+ ; issue
+ ; :basic-auth-token basic-auth-token)
(if (sendmail config)
(deliver-email config issue)))
diff --git a/src/option.lisp b/src/option.lisp
new file mode 100644
index 0000000..4d1ce19
--- /dev/null
+++ b/src/option.lisp
@@ -0,0 +1,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))))
diff --git a/wajir.asd b/wajir.asd
index 1f95cf6..e050c93 100644
--- a/wajir.asd
+++ b/wajir.asd
@@ -13,17 +13,20 @@
:depends-on (:cl-base64
:cl-smtp
:com.inuoe.jzon
- :dexador)
+ :dexador
+ :sysexits
+ :unix-opts)
:components ((:module "src"
:serial t
:components ((:file "package")
(:file "config")
+ (:file "option")
(:file "email")
(:file "main"))))
:build-operation "program-op"
:build-pathname "wajir"
- :entry-point "wajir")
+ :entry-point "wajir:main")
#+sb-core-compression
(defmethod asdf:perform ((o asdf:image-op) (c asdf:system))