I think my two options here are
- Go with a single GroovyScriptCommand that has a lame description defined in the annotation like "To get help for this script, run it with 'help' as the only argument"
- Do some crazy runtime class modification to add annotations to the subclass when the script name is known and load the description from the script if it is available and return some standard "no help" message if the script does not implement a description. I'm not yet sure how the script would do this. That is left as an exercise for future me.
I'm actually pretty happy with the GroovyScriptCommandFactory. This is the subclass of CommandFactory that is responsible for creating the instances of Command based on a string name. This is pretty easy as the string name of the command will be the name of the groovy command without the .groovy at the end. I decided to return a Command object even if the script requested doesn't exist so that the exception can be thrown when the Command.execute() method is called. Since CommandFactory.createCommand(String) does not throw exceptions I could only return null which isn't hugely helpful.
Unit tests work and I can read variables set in the script binding and write new ones which can be read by the unit tests. There's still a little more work to have the GroovyScriptCommandFactory get created on startup and be asked to create Commands. Right now there is only one hard coded CommandFactory called and it is configured by a property file. I'm not sure how flexible this needs to be or if I can just change it to create the original CommandFactory and the groovy one and call one or the other first. My gut reaction is to have the scripts override the built in commands as that's how bash works but I could easily see it going the other way as overwriting builtin commands is crazy making. Its like monkey patching in dynamic languages. Not for the faint of heart.