[racket] command-line macro and raco subcommands

From: Neil Van Dyke (neil at neilvandyke.org)
Date: Mon Dec 26 16:50:02 EST 2011

When using the "command-line" macro for parsing "raco" commands with 
subcommands (e.g., "raco mycommand mysubcommand arg ..."), is there a 
better way than the code fragment at the end of this message?

The main problem I have with this code fragment is that "raco mycommand 
--help" is not very helpful, because it doesn't list the actual subcommands:

$ raco mcfly --help
raco mcfly [ <option> ... ] [<subcommand>] [<subcommand-arg>] ...
  where <option> is one of
   --help, -h : Show this help
   -- : Do not treat any remaining argument as a switch (at this level)
  Multiple single-letter switches can be combined after one `-'; for
   example: `-h-' is the same as `-h --'

If the "command-line" macro can't do subcommands better, than I'll 
probably use it only for the individual subcommand-specific parses.

I don't want the subcommand to be a ``flag'', although the 
"command-line" macro could handle it then.

The code fragment is:

(let-values (((subcommand subcommand-args)
                #:program (current-program)
                #:args    ((subcommand #f) . subcommand-arg)
                (values subcommand subcommand-arg))))
   (parameterize ((current-command-line-arguments
                   (list->vector subcommand-args)))
     (let loop-subcommand ((subcommand subcommand))
       (cond ((not subcommand)
              (printf "*DEBUG* no subcommand\n")
              ;; TODO: !!!
             ;; Subcommands:
             ((equal? subcommand "dev-links")
              (printf "*DEBUG* dev-links\n")
              (parameterize ((current-subcommand subcommand))
                (update-dev-links (command-line
                                   #:program (current-program)
                                   (("--no-server" "--ns")
                                    "Do not use the PLaneT server"
                                    ;; TODO: !!!
                                   #:args    directory-tree-to-search
             ((equal? subcommand "setup-all")
              (printf "*DEBUG* setup-all\n")
              (parameterize ((current-subcommand subcommand))
                ;; TODO: !!!
             ((equal? subcommand "setup-package")
              (printf "*DEBUG* setup-package\n")
              (parameterize ((current-subcommand subcommand))
                ;; TODO: !!!
             ((equal? subcommand "view")
              (printf "*DEBUG* view\n")
              (parameterize ((current-subcommand subcommand))
                ;; TODO: !!!
             ;; Abbreviations:
             ((equal? subcommand "dl") (loop-subcommand "dev-links"))
             ((equal? subcommand "sa") (loop-subcommand "setup-all"))
             ((equal? subcommand "sp") (loop-subcommand "setup-package"))
             ((equal? subcommand "v")  (loop-subcommand "view"))
             ;; Error:
              (fatal-command-line-error "Invalid subcommand ~S" 

     (printf "*DEBUG* fell out of loop-subcommand\n")
     ;; TODO: !!!


Posted on the users mailing list.