;;; build-app.lisp -- Contains the command line frontend definition ;;; to build the cli, simply load this file from the command line. (asdf:load-system "oneliners.cli") (defpackage #:oneliners.cli.app (:use #:cl #:net.didierverna.clon) (:local-nicknames (#:a #:alexandria) (#:cli #:oneliners.cli))) (in-package :oneliners.cli.app) ;;; HELP TEXTS (defparameter +invite-help-text+ "") ;;; CLON SYNOPSIS DEFINITION (defsynopsis (:postfix "[TERMS ...] | N [ARGS ...]") (group (:header "Search") (text :contents "Usage: ol [OPTIONS] [TERMS ...]") (text :contents "Each term may be a command name or some tag like 'server' or 'tunnel'") (lispobj :long-name "count" :argument-type :optional :argument-name "Count" :default-value 10 :description "The maximum number of results to return." :typespec 'integer) (flag :long-name "not-flagged" :description "Request that no flagged oneliners are returned.")) (text :contents " ") (group (:header "Running Oneliners") (text :contents "Usage: ol [OPTIONS] N [ARGS ...]") (text :contents "Runs the Nth search result with possible arguments ARGS.") (flag :long-name "clip" :description "Force an attempt to copy the oneliner to the clipboard instead of running it.")) (text :contents " ") (group (:header "Help") (flag :long-name "help" :description "Print this help menu.") (enum :long-name "help-topic" :enum '(:admin :wiki :invites) :argument-name "TOPIC" :description "Print help for a topic. Topics are: wiki, admin, invites")) (group (:header "Wiki" :hidden t) (text :contents "This section documents options used to add and edit oneliners in the wiki.") (flag :long-name "add-interactive" :description "Interactively add a new oneliner") (flag :long-name "update-interactive" :description "Interactively edit a oneliner and update the wiki.")) (group (:header "Admin" :hidden t) (flag :long-name "invite" :description "Request an invite token to send to a friend.") (stropt :long-name "redeem" :argument-type :optional :default-value "DUMMY-TOKEN" :argument-name "TOKEN" :description "Redeem an invite token. See also --help-topic=invites")) (group (:header "Invites" :hidden t) (text :contents +invite-help-text+))) ;;; HELPERS (defun find-group-with-header (header) "This function should be built in. Is it? How to know? The documentation is both extensive and trash. Any manual that expects you to go to sleep with it at night is written for the author more than the users." (loop for item in (net.didierverna.clon::items *synopsis*) when (and (typep item 'net.didierverna.clon::group) (string-equal header (net.didierverna.clon::header item))) return item)) ;;; MAIN ENTRY POINT (defun main () "Entry point for our standalone application." (make-context) (when (getopt :long-name "help") (help ) (uiop:quit)) (a:when-let (topic (getopt :long-name "help-topic")) (help :item (find-group-with-header (symbol-name topic))) (uiop:quit)) (let ((arguments (remainder))) (unless arguments (help) (uiop:quit)) (alexandria:when-let (hist-number (parse-integer (first arguments) :junk-allowed t)) (format t "TBD: Going to run command ~a with arguments ~a~%" hist-number (rest arguments)) (uiop:quit)) (cli:search-for-oneliners arguments :)) (uiop:quit)) ;;; DUMP EXECUTABLE (dump "ol" main)