TODO in shellopts-2.0.0.pre.13 vs TODO in shellopts-2.0.0.pre.14
- old
+ new
@@ -1,136 +1,16 @@
-
-TODO
- o Rethink #error and #fail <- The use-case is one-file ruby scripts. Idea: Only use in main exe file?
- o Create exceptions: UserError SystemFail and allow them to be used instead of #error and #fail
- ? Remove ! from OptionStruct#subcommand return value. We know we're
- processing commands so there is no need to have a distinct name and it
- feels a lot more intuitive without it
- o Add validation block to ShellOpts class methods
- o Get rid of key_name. Define #name on Grammar::Node instead
- o Define #name to the string name of the option/command without prefixed '--'
- for options. This can cause collisions but they can be avoided using aliases
- o Clean-up
- o Grammar::options -> Grammar::option_multihash
- o Clean-up identifiers etc.
- o Un-multi-izing Grammar::option_multihash and turn it into a regular hash from key to option
- o subcommand vs. command consistency
- o Implement ObjectStruct#key! and ObjectStruct#value! (?)
- o Allow command_alias == nil to suppress the method
- o Raise on non-existing names/keys. Only return nil for declared names/keys that are not present
- o Use hash_tree
- o Also allow assignment to usage string for ShellOpts::ShellOpts objects
- o Create a ShellOpts.args method? It would be useful when processing commands:
- case opt
- when "command"
- call_command_method(ShellOpts.args[1], ShellOpts.args[2])
- end
- ShellOpts.args would be a shorthand for ShellOpts.shellopts.args
- Another option would be to create an argument-processing method:
- shellopts.argv(2) -> call error if not exactly two arguments else return elements
- o Add a ShellOpts.option method:
- file = ShellOpts.option("--file")
- This will only work for options on the outermost level... maybe:
- file = ShellOpts.option("load! --file")
- o Check on return value from #process block to see if all options was handled:
- case opt
- when '-v'; verbose = true # Return value 'true' is ok
- # Unhandled option means return value is nil
- end
- o Consolidate some of the 3 variations of #error and #fail
- o Add a option flag for solitary options (--help)
- o Make a #to_yaml
- o Make an official dump method for debug
- o Make a note that all options are processed at once and not as-you-go
- o Test that arguments with spaces work
- o Long version usage strings (major release)
- o Doc: Example of processing of sub-commands and sub-sub-commands
-
- + Add a 'mandatory' argument to #subcommand
- + More tests
- + More doc
- + Implement value-name-before-flags rule
- + Kill option array values
- + Kill key forms
- + Rename Option#opt to Option#name
- + Have all Ast objects to be on [key, name, value] form
- + Change #=>i, $=>f and introduce b (boolean)
- + Unshift program name to usage definition string before compiling
- + Rename to UsageCompiler and ArgvParser
- + Make usage-string handle commands
- + Change !cmd to cmd!
- + Clean-up terminology: Option-name is used for names with and without the prefixed dashes
- + Rename Option#has_argument? and #optional? to something else
- + Fix location reporting of compiler errors
- + Allow '--' in usage so that everything after can be used as USAGE in error messages
- + Handle pretty-printing of usage string in handling of ParserError
- + Compiler.new.compile(usage), Parser.new(compiled_program).parse(argv)
- + Check for duplicate option in the parser
- + Handle CompilerError
- + Use nil value as the name of the top 'command'
- + Refactor compilation to avoid having the Command objects throw CompilerErrors
- + Change to 'parser.parse' / 'parser.parse3'
- + Use first long option as symbolic key
- + Use full option names everywhere (eg. '--all' instead of 'all')
-
- - Revert change from '#' -> 'i'
- - Guard against reserved 'object_id' name in OpenStruct
- - Default value ('=' -> ':')
- Default values are better handled in the calling program
-
- ? More specialized exceptions: "MissingArgumentError" etc.
-
-LATER
- o Allow '-a' and '--aa' in usage
- o Allow single-line comments
- o Allow multi-line comments
- o Regex as option value spec
- o "FILE", "DIR", "NEWFILE", "NEWDIR" as keyword in option value spec
- RFILE, RDIR
- WFILE, WDIR
- EFILE, EDIR
- o Octal and hexadecimal integers
- o Escape of separator in lists
- o Handle output of subcommand usage like "cmd1 cmd1.cmd2 cmd2"
- o Command-specific arguments: clone! o,opt ++ ARG1 ARG2...
- o Hostname and email as basic types
-
-ON TO_H BRANCH
- ShellOpts.process(usage, argv) { |opt,val| ... } => args
- ShellOpts.process(usage, argv) { |key,opt,val| ... } => args
-
- opts = ShellOpts.new(usage, argv, defaults = {})
- opts = ShellOpts.new(usage, argv, defaults = OpenStruct.new)
-
- opts.args
- opts.to_a
- opts.to_h
- opts.to_openstruct
-
- opts.each { |opt,val| ... }
- opts.each { |key,opt,val| ... }
-
-LONG FORMAT
-
- PROGRAM = File.basename(ARGV.first)
- USAGE = "-a -f FILE -lvh FILE..."
- DESCR = %(
- Short description
-
- Longer description
- )
- OPTIONS = %(
- -a,--all
- Process all files
-
- -f, --file=FILE
- Process file
-
- !command
- This is a command
-
- --this-is-a-command-option
- Options for commands are nested
-
- ...
- )
+o Somehow escape comments where a line starts with an option name
+o 'help' should list commands in declaration order
+o 'help' should use all levels by default
+o 'help' should always include top-level options (try setting levels: 10 and
+ see top-level options are gone
+o Special handling of --help arguments so that '--help command' is possible
+o Support for paging of help:
+ begin
+ file = Tempfile.new("prick")
+ file.puts HELP.split("\n").map { |l| l.sub(/^ /, "") }
+ file.flush
+ system "less #{file.path}"
+ ensure
+ file.close
+ end