Hi, I've already sent an email concerning limitation of Command interface few months ago. I totally developted a shell engine from scratch.
My shell is registering in OSGI container as a service. Other services register ShellExtension. Registration of extension initiate an update process on the shell service. Shell extension provides a simple interface which allow retrieval of extension commands. Each command provides information like short help, complete help, description and version. You can chain commands, use variables (in global shell context or session context). It supports short and long option (- and -- flags), whitespaces and some other features. Best Regards, Stevens On Wed, Dec 31, 2008 at 1:02 PM, Trejkaz <[email protected]> wrote: > The Command API is currently... > > public void execute(String command, PrintStream out, PrintStream err) > > After having written a few commands, I find myself doing two things a lot. > > Firstly, I find myself parsing command-lines. > > Currently all my parameters are whitespace-free but that's about to > change. So now I need a full parser which handles quotes in a > sensible fashion consistent with my other commands, and indeed Felix's > existing commands. > > It seems like the ultimate solution to this part would have been to > pass the command as a String[] instead of the raw command. Obviously > I can write my own convenience API for this, but I started wondering > if Felix is already hiding something like this..? > > Secondly, I find myself wondering how to handle sub-commands. And > this is where the mail gets big. Sorry about that. for tl;dr types, > scroll down to my proposed interfaces and points below those. > > Effectively having solved the parser problem already (which I haven't > solved correctly actually, but for the sake of discussion - the real > code splits on \s+) I now find myself implementing my own sub-command > framework. > > Main problems: > > * For getUsage() to contain a full description of what my top-level > command can do, it takes multiple lines. But Felix then shows the > whole thing from the help command. > * Putting all the commands as methods on one class starts to become > unmanageable and then you create a sub-command API, and: > * The API for sub-commands looks awfully similar to the API for commands. > > Possible resolution: > > In my case I went with the main command parsing its first argument and > then switching to different methods. > > I started wondering if there was a "proper" way to do this, and on > investigation I see other commands doing this all themselves too, like > "obr help". Why not invert it? Can't "help" show obr in the list > with a getShortUsage(), and then "help obr" shows the list of > sub-commands? You could almost allow getName() to contain spaces and > then improve the shell to do better matching. Or you could have an > explicit API for getting the sub-commands for a given command, and > then each one can have shortUsage and fullUsage. > > I don't want to turn this into a "let's design a Command API" > discussion, but _if_ I were writing a new command API from scratch, I > guess ideally I would like to see this bare minimum: > > public interface Command { > > // If a top-level service comment then this needs to be unique > in the shell service. > String getName(); > > // "help" or "help obr" would show these: > String getShortUsage(); > String getShortDescription(); > > // "help obr list" would show these: > String getFullUsage(); > String getFullDescription(); > > /** > * Executes a command. > * > * @param context the context in which the command is being > run. All parameters passed through here. > */ > public void execute(CommandContext context); > > /** > * Gets all sub-commands. These are commands where {...@link > #getName()} > * would return the name of the sub-command, > */ > Command[] getSubCommands(); > } > > public interface CommandContext { > String getCommandLine(); > String[] getCommand(); > PrintStream getErrorStream(); > PrintStream getOutputStream(); > } > > Good points: > * You can extend the context later without disrupting the API > > Deficiencies: > * On the other hand extending the *context* isn't possible. Commons > Chain solves this for their command model by going all out and just > putting a map in there, which is possibly too much. (And well, > they're not a shell either. So you would have to pass out and err > streams as parameters too, to actually use that.) > * Still passes the full command in the parameters. Purists would say > this is pointless and that it would be more reusable if it only passed > the parameters, which would make it possible to change the location of > commands in the tree without rewriting the command. > > But... why develop a brand new command API? There are already two > good ones out there which I'm aware of... > > 1. GShell's Command API - GShell is also in itself a good shell too, > with proper autocompletion for commands, and this is exposed > throughout the API as well. > > 2. JNode's Command API - I have seen people tout JNode's as being > better than GShell... but it is LGPL but JNode have never really > advertised their code base as a collection of reusable components. > > Both of these are trying to solve the same problem of making a generic > API where commands, help, completion and everything are considered. I > would say JNode's is marginally better because if its notion of > argument types. > > I guess what I'm wondering is, was there a particular reason Felix's > is the way it is, or is it because the codebase was pull in from > wherever and nobody has really used it intensively yet? > > > TX > > P.S. And on a side-note... I have been wondering how to get > user-level access control for commands, to control who can do what. > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] > > -- Le respect commence par celui de l'environnement

