X-Git-Url: https://code.consxy.com/gitweb/gitweb.cgi?a=blobdiff_plain;f=src%2Fmain%2Fcli.lisp;h=697fb42a5e333e9b04e7fe7dff09ecfdede4b60f;hb=22bc93248268f84257732f90fd383848ed262ca4;hp=fb38f58570b0e4e47790a83ee76c4b214239bb63;hpb=10415e960ac74f2c07f693295b063c586ccc608f;p=candle diff --git a/src/main/cli.lisp b/src/main/cli.lisp index fb38f58..697fb42 100644 --- a/src/main/cli.lisp +++ b/src/main/cli.lisp @@ -10,11 +10,12 @@ (error-and-exit "Unknown command '~(~A~)'. See 'candle --help'.~%" command)) (defun job-info->line (job-info) - (format nil "~A (~A) ~A" - (subseq (first job-info) 0 8) + (format nil "~A:~A (~A) ~A" + (first job-info) + (subseq (second job-info) 0 8) (format nil "~{~2,,,'0@A/~2,,,'0@A/~A ~2,,,'0@A:~2,,,'0@A~}" - (utils:time-as-list (third job-info) :month :date :year :hr :min)) - (case (second job-info) + (utils:time-as-list (fourth job-info) :month :date :year :hr :min)) + (case (third job-info) (:succeeded (format nil "~c[1;32mPassed~c[0m" #\Esc #\Esc)) (:failed (format nil "~c[1;31mFailed~c[0m" #\Esc #\Esc)) (:queued "In queue") @@ -22,18 +23,18 @@ (:in-progress "In progress")))) (defmacro standard-cli (cmd options-in args usage remaining-args-required &rest success) -`(multiple-value-bind (parsed-options remaining-args error) (opera:process-arguments ,options-in ,args) - (cond - ((opera:option-present :help parsed-options) - (format t "~A" ,(if (eql usage :default) `(opera:usage ,cmd ,options-in) usage))) - ((eql error :unknown-option) - (error-and-exit "Unknown option: ~A. See '~A --help'.~%" (car remaining-args) ,cmd)) - ((eql error :required-argument-missing) - (error-and-exit "Missing argument for ~A. See '~A --help'.~%" (car remaining-args) ,cmd)) - ((and ,remaining-args-required (not remaining-args)) - (error-and-exit "~A required. See 'candle --help'.~%" ,remaining-args-required)) - (t - ,@success)))) + `(multiple-value-bind (parsed-options remaining-args error) (opera:process-arguments ,options-in ,args) + (cond + ((opera:option-present :help parsed-options) + (format t "~A" ,(if (eql usage :default) `(opera:usage ,cmd ,options-in) usage))) + ((eql error :unknown-option) + (error-and-exit "Unknown option: ~A. See '~A --help'.~%" (car remaining-args) ,cmd)) + ((eql error :required-argument-missing) + (error-and-exit "Missing argument for ~A. See '~A --help'.~%" (car remaining-args) ,cmd)) + ((and ,remaining-args-required (not remaining-args)) + (error-and-exit "~A required. See 'candle --help'.~%" ,remaining-args-required)) + (t + ,@success)))) ;;; Section for ./candle @@ -41,7 +42,9 @@ (standard-cli "candle" (main-options) (cdr sb-ext:*posix-argv*) (main-usage) "Command" (handler-case (if - (and (opera:option-present :port parsed-options) (not (parse-integer (opera:option-argument :port parsed-options) :junk-allowed t))) + (and + (opera:option-present :port parsed-options) + (not (parse-integer (opera:option-argument :port parsed-options) :junk-allowed t))) (error-and-exit "--port requires a number. See 'candle -h'~%") (let ((communication:*query-port* @@ -109,14 +112,21 @@ (defun add-project (args) (let ((options - '((:name :help :short "h" :long "help" :description "Print this usage.") - (:positional ":" :description " is the name of the project, which must be alphanumeric (hyphens are allowed), while is the location of the repository for cloning. This location must be accessible by the machine running candle.")))) + `((:name :help :short "h" :long "help" :description "Print this usage.") + (:positional ":" + :description + ,(format nil "~{~A~}" + (list + " is the name of the project, which must be alphanumeric (hyphens are allowed), while is the " + "location of the repository for cloning. This location must be accessible by the machine running candle." + "")))))) (standard-cli "candle project add" options args :default ":" (let* ((project-definition (car remaining-args)) (pos (position #\: project-definition))) (cond - ((not pos) (error-and-exit "Project definition ~A is not valid. See 'candle project add --help'.~%" project-definition)) + ((not pos) + (error-and-exit "Project definition ~A is not valid. See 'candle project add --help'.~%" project-definition)) (t (let* ((name (subseq project-definition 0 pos)) @@ -127,17 +137,17 @@ (defun delete-project (args) (let ((options - '((:name :help :short "h" :long "help" :description "Print this usage.") - (:positional "" :description " is the name of the project to delete")))) + '((:name :help :short "h" :long "help" :description "Print this usage.") + (:positional "" :description " is the name of the project to delete")))) (standard-cli "candle project delete" options args :default "" - (communication:query `(candle:delete-project ,(car remaining-args))) - (format t "Removed project ~A~%" (car remaining-args))))) + (communication:query `(candle:delete-project ,(car remaining-args))) + (format t "Removed project ~A~%" (car remaining-args))))) (defun show-project (args) (let ((options - '((:name :help :short "h" :long "help" :description "Print this usage.") - (:positional "" :description " is the name of the project to show")))) + '((:name :help :short "h" :long "help" :description "Print this usage.") + (:positional "" :description " is the name of the project to show")))) (standard-cli "candle project show" options args :default "" (let* ((branch-infos (communication:query `(candle:project-branch-information ,(car remaining-args)))) @@ -147,29 +157,39 @@ (format t (format nil "~~~A@A: ~~A~~%" width) (first branch-info) (job-info->line (second branch-info)))) - (sort branch-infos #'< :key (lambda (branch-info) (third (second branch-info))))))))) + (sort branch-infos #'< :key (lambda (branch-info) (fourth (second branch-info))))))))) (defun refresh-project (args) (let ((options - '((:name :help :short "h" :long "help" :description "Print this usage.") - (:positional "" :description " is the name of the project to refresh")))) + '((:name :help :short "h" :long "help" :description "Print this usage.") + (:positional "" :description " is the name of the project to refresh")))) (standard-cli "candle project refresh" options args :default "" (communication:query `(candle:refresh-project ,(car remaining-args))) (format t "Refreshed project ~A~%" (car remaining-args))))) (defun list-projects () - (format t "~{~{~A ~A~}~%~}" (communication:query `(candle:list-projects)))) + (format t "~{~A~%~}" + (mapcar + (lambda (info) + (format nil "~A ~A~A" + (car info) + (cadr info) + (if (zerop (caddr info)) "" (format nil " (~A branches ~c[1;31mfailing~c[0m)" (caddr info) #\Esc #\Esc)))) + (communication:query `(candle:list-projects))))) (defun project-failures (args) (let ((options - '((:name :help :short "h" :long "help" :description "Print this usage.") - (:name :project :long "project" :variable-name "PROJECT" :takes-argument t :description "Restrict failures to project named by PROJECT")))) + '((:name :help :short "h" :long "help" :description "Print this usage.") + (:name :project :long "project" :variable-name "PROJECT" :takes-argument t + :description "Restrict failures to project named by PROJECT")))) (standard-cli "candle project failures" options args :default nil (format t "~A" (communication:query - `(candle:failures ,(when (opera:option-present :project parsed-options) (opera:option-argument :project parsed-options)))))))) + `(candle:failures + ,(when (opera:option-present :project parsed-options) + (opera:option-argument :project parsed-options)))))))) ;;; Section for ./candle job @@ -199,13 +219,16 @@ (defun job-list (args) (let ((options - '((:name :help :short "h" :long "help" :description "Print this usage.") - (:name :project :long "project" :variable-name "PROJECT" :takes-argument t :description "Restrict jobs to project named by PROJECT")))) + '((:name :help :short "h" :long "help" :description "Print this usage.") + (:name :project :long "project" :variable-name "PROJECT" :takes-argument t + :description "Restrict jobs to project named by PROJECT")))) (standard-cli "candle job list" options args :default nil (format t "~{~A~%~}" (mapcar #'job-info->line - (sort (communication:query `(candle:project-job-information ,(opera:option-argument :project parsed-options))) #'< :key #'third)))))) + (sort + (communication:query `(candle:project-job-information ,(opera:option-argument :project parsed-options))) + #'< :key #'fourth)))))) (defun decompose-job-definition (job-definition) (let @@ -219,8 +242,9 @@ (defun job-log (args) (let ((options - '((:name :help :short "h" :long "help" :description "Print this usage.") - (:positional ":" :description " is the name of the project, while is the sha of the job in question.")))) + '((:name :help :short "h" :long "help" :description "Print this usage.") + (:positional ":" + :description " is the name of the project, while is the sha of the job in question.")))) (standard-cli "candle job log" options args :default ":" (multiple-value-bind (project-name sha) (decompose-job-definition (car remaining-args)) (if project-name @@ -230,8 +254,9 @@ (defun retry-job (args) (let ((options - '((:name :help :short "h" :long "help" :description "Print this usage.") - (:positional ":" :description " is the name of the project, while is the sha of the job in question.")))) + '((:name :help :short "h" :long "help" :description "Print this usage.") + (:positional ":" + :description " is the name of the project, while is the sha of the job in question.")))) (standard-cli "candle job retry" options args :default ":" (multiple-value-bind (project-name sha) (decompose-job-definition (car remaining-args)) (if project-name @@ -244,6 +269,21 @@ (defmethod execute-command ((command (eql :run)) args) (let - ((options '((:name :help :short "h" :long "help" :description "Print this usage.")))) - (standard-cli "run" options args :default nil - (when (not (candle:run)) (sb-ext:exit :code 1))))) + ((options + '((:name :help :short "h" :long "help" :description "Print this usage.") + (:name :task :long "task" :variable-name "TASK" :takes-argument t :description "Run TASK") + (:name :env :long "env" :variable-name "ENV" :takes-argument t + :description "Runs candle with *candle-environment* set to ENV as a keyword.")))) + (standard-cli "candle run" options args :default nil + (when (opera:option-present :env parsed-options) + (setf candle:*environment* (intern (string-upcase (opera:option-argument :env parsed-options)) :keyword))) + (cond + ((opera:option-present :task parsed-options) + (let + ((tasks (candle:list-tasks)) + (specified-task (intern (string-upcase (opera:option-argument :task parsed-options)) :keyword))) + (if + (not (find specified-task (candle:list-tasks))) + (error-and-exit "Task ~(~A~) does not exist in .candle file" specified-task) + (candle:run specified-task)))) + (t (when (not (candle:run)) (sb-ext:exit :code 1)))))))