(Arne Babenhauserheide)
2016-10-29: add example for complex commandline-handling add example for complex commandline-handling
diff --git a/examples/commandline-handling.w b/examples/commandline-handling.w new file mode 100755 --- /dev/null +++ b/examples/commandline-handling.w @@ -0,0 +1,203 @@ +#!/usr/bin/env sh +# -*- wisp -*- +guile-2.0 -L $(dirname $(dirname $(realpath "$0"))) -c '(import (wisp-scheme) (language wisp spec))' +exec guile-2.0 -L $(dirname $(dirname $(realpath "$0"))) --language=wisp -e '(examples commandline-handling)' -s "$0" "$@" +; !# + +;; This is an example for complex commandline handling for a tool +;; which takes a list of tasks to run as arguments. + +define-module : examples commandline-handling + . #:export : main + +import + ice-9 format + srfi srfi-1 + srfi srfi-37 + ice-9 popen ; for pipe-open* + ice-9 rdelim ; for read-string + + + +define : runcommand cmd + let* + : port : open-input-pipe cmd + output : read-string port + display output + newline + + +define : run-my-shell-command + . "Run a predefined shell command" + let + : + cmd + string-join + list "for i in {1..5}; do echo $i; done" + when : debug? + display cmd : current-error-port + newline : current-error-port + runcommand cmd + + +define : help . args ; args used for simpler option parsing + if + and + >= (length args) 3 + third args + member (string->symbol (third args)) : task-list ; help got an argument + let* + : fun : string->symbol : third args + mod : resolve-module '(examples commandline-handling) + doc : procedure-documentation : module-ref mod fun + format #t "~a\n\n~a\n" fun doc + format #t "Usage: commandline-handling.w [option ...] [--] [task ...] + +Run the selected tasks given on the commandline. + + -h [TASK] --help[=TASK] + display this help or infomation about the task and exit + -V --version output version information and exit + --tasks list all available tasks + -d [LEVEL] --debug[=LEVEL] + set logging to debug or to the given level + +Defined tasks: + + ~a + +" : string-join : map symbol->string : task-list + exit 0 + + +define : version + display "commandline-handling 0.0.0 + +Copyright (C) 2016 Arne Babenhauserheide, for IMK-ASF at Karlsruhe Institute for Technology +See the file COPYING. There is NO warranty. +" + +define help-option + option '(#\h "help") + . #f #t help + +define version-option + option '(#\V "version") + . #f #f + λ : option name arg operands + version + exit 0 + +define : debug? + equal? 'debug : assoc-ref %options 'log-level + + +define debug-option + let + : required #f + optional #t ; can take an argument + option '(#\d "debug") + . required optional + λ : option name arg operands + if arg + set! %options : alist-cons 'log-level (string->symbol arg) %options + set! %options : alist-cons 'log-level 'debug %options + format : current-error-port + . "debug: activate log level ~a\n" + if arg arg 'debug + . operands + + +define utility-procedures + ' parse-args main run-task task-list runcommand debug? + +define debug-procedures + ' tasks help options version + +define : task-list + let : : mod : resolve-module '(examples commandline-handling) + delete #f + module-map + λ : x y + if + and + procedure? : module-ref mod x + not : member x utility-procedures + if : equal? 'debug : assoc-ref %options 'log-level + . #t + not : member x debug-procedures + . x + . #f + . mod + +define : tasks . args + map : λ (x) (display x)(newline) + task-list + +define tasks-option + option '("tasks") + . #f #f + λ : option name arg operands + tasks + exit 0 + + +define %options + ' + log-level . info + +define : options + format : current-error-port + . "Currently active options: ~A\n" + . %options + +define %option-list + list help-option version-option debug-option tasks-option + + +define : run-task task + let* + : mod : resolve-module '(examples commandline-handling) + t : string->symbol task + var : module-variable mod t + cond + var + let : : T : module-ref mod t + if : procedure? T + T + format : current-error-port + . "Not a procedure: ~a refers to ~a\n" task var + else + format : current-error-port + . "Unknown task: ~a\n" task + + +define : parse-args args + let + : + tasks + reverse + args-fold args + . %option-list + λ : option name arg operands + format : current-error-port + . "unrecognized command line argument name: ~a arg: ~a operands: ~a\n" + . name arg operands + exit 1 + λ : operand operands + cons operand operands + . '() + for-each + λ : task + if : and (equal? task "help") (not (null? (delete "help" tasks))) + map + λ : x + help #f #f x + delete "help" tasks + run-task task + . tasks + +define* : main args + if : null? : cdr args + help + parse-args : cdr args