geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jason Dillon <ja...@planet57.com>
Subject GShell (longish)
Date Sun, 28 May 2006 21:03:42 GMT
Some of you may have noticed some commits to the sandbox for  
GShell... but just what is this GShell thingy?  I've been meaning to  
put some words to this on the dev list for a while... so here goes.

GShell is the second coming of Twiddle (3rd if you count the first  
iteration I did for a certain other app server).  But what the heck  
is Twiddle?  Well, over the years I have realized that I spend way to  
much time writing framework around command-line tools, just to get a  
simple task accomplished.  And each time I need to add a tiny other  
little feature I end up doing it all over again.  Twiddle was  
intended to be a simple framework for implementing command-line  
tools, where only the functionality needs to be implemented, none of  
the plumbing.

But what plumbing is there for command-line tools?  Well, that  
becomes more apparent when you start to think about how commands  
(plural) can coexist and cooperate together.  At that point you have  
the commands option parsing and functionality... plus interaction  
with input/output streams and environment variables, etc.

<rant>
But Jason, why not use use the system's shell for this stuff?  Well,  
as many of you know... the Windows cmd.exe sucks ass, and despite the  
profits of vista hoping that ms-foolios are going to fix it, I can't  
assume they will, since they have had years to pull their heads out  
and see the folly of batch.
</rant>

But, more so... I want to be able to SSH into my application server  
and run those commands.  I want to be able to launch a script  
(language of my choice) in the server from a remote terminal and have  
it just work as I would expect it to.  IMO that is really where the  
benefit of the common plumbing is.

Yet even before we get there, the plumbing allows for use to build  
simple and *consistent* command-line tools.  Adding a new tool is as  
simple as adding a new jar to a directory, no need for more scripts  
to maintain, or configuration files, yada yada.

Another key facet to GShell is (or will be) its ability to load  
command sets into categories.  This is basically a namespace not  
unlike a directory in normal-shell terms, which a set of related  
commands exit.  For example, all 'jmx' command can be organized in  
the a 'jmx' category, etc.

  * * *

Anyways, so what I have done so far is... I dug up the old Geronimo  
Twiddle code from CVS, and started re-implementing... and in comes  
GShell.

Initially I was using Spring to wire up command prototypes... then  
after talking to David Blevins I started looking into using the  
ResourceFinder to dynamically find property files.  Currently the  
impl is in-between both, as I'm still wrestling for how to make use  
of IoC to configure components in the lightest possible fashion.

So, I've shelved some of that plumbing and moved on to the  
interactive console bits.  I've always wanted Readline/Editline-like  
support, but never liked the native requirements.  And then a few  
weeks ago I found JLine ( http://jline.sourceforge.net/ ), which at  
least on Unix does not require any native libs (though does exec  
stty).  Anyways, the result is that you can run GShell out of the box  
and get Readline/Editline support for a rich command-line  
experience.  Not sure yet how JLine is going to play with SSH/Telnet  
streams, but I think that can wait until later.

Still unsure about the IoC bits, I moved on to piecing together a  
parser which will take a single or multiline string and convert that  
into a tree structure representing the command-line to be executed.   
I'm trying for something that can handle most things that BASH or ZSH  
can (leaning towards ZSH since it kicks ass all over BASH).

This is currently where I am at now... with just the very basics of a  
parser in place, some command-discovery currently done via  
ResourceFinder... but no IoC, and a simple JLine console and some  
example commands.

  * * *

So what can GShell do now?  Um, some... but not that much.

I've put together the basic build system, which by default will spit  
out an assembly archive with all of the standard and extension  
commands configured.  The one caveat is that you must build xbean/ 
trunk/xbean-finder first, since that is not yet published anywhere.

But you can:

svn co https://svn.apache.org/repos/asf/geronimo/sandbox/gshell/ 
trunk/ gshell
cd gshell
mvn
gunzip -c gshell-assembly/target/gshell-1.0.0-SNAPSHOT-bin.tar.gz |  
tar xf -
./gshell-1.0.0-SNAPSHOT/bin/gshell

At this point you've got a GShell running (and on Unix you should get  
a nice jline interface, windows too but that has not been tested).

Standard commands that are implemented are:

     echo
     cat
     exit
     java
     set
     help (broken currently)

Extended commands:

     script

All commands take a '--help' or '-h' to spit out what they can do and  
how you configure them to do it.  As mentioned help is broken, as it  
was based on the Spring impl to discover commands, pending some work  
on how to use IoC (or not) to find all commands.

 > echo --help
echo -- write arguments to the commands output

usage: echo [options] [string ...]
     -h,--help    Display this help message
     -n           Do not print the trailing newline character

 > cat --help
cat -- concatenate and print files

usage: cat [options] [file ...]
     -h,--help    Display this help message
     -n           Number the output lines, starting at 1

 > exit --help
exit -- exit the virtual machine

usage: exit [options]
     -c,--code     Use the given exit code
     -h,--help     Display this help message

 > java --help
java -- execute a java application

usage: java [options] <classname> [arguments]
     -M,--method    Invoke a named method
     -h,--help      Display this help message

 > set --help
set -- set a variable or property

usage: set [options] <name=value>
     -h,--help    Display this help message

     help (broken currently)

 > script --help
script -- scripting language integration

usage: script [options]
     -e,--expression     Evaluate the given expression
     -h,--help           Display this help message
     -i,--interactive    Run interactive mode
     -l,--lang           Specify the scripting language

The script command is a simple front-end to BSH, which will if you  
add a BSH engine jar to lib/* will allow you to invoke an interactive  
(jshell) interpreter or evaluate an expression.  Eventually it will  
be able to execute a script from a URL or pipe when the parser bits  
are finished.

NOTE: Command syntax subject to change ;-)

  * * *

What's next?  Well, still gotta figure out the IoC bits, which  
container, no container, etc.  Gotta finish the parser, and figure  
out how to line pipelines (ie. echo "foo" | cat -).

Need to get the command context and environment settled.  One option  
I am leaning towards is allowing the command environment (command  
variables that is) to deal with objects not just strings.  This makes  
the entire environment much more rich.  For example, a JMX 'connect'  
command could return a Connection object, which could be assigned to  
'jmx.connection' variable, and then subsequently JMX commands could  
reuse that object.  As in:

 > jmx.connection=`jmx/connect service:jmx:whatever`
 > jmx/invoke mydomain:name=App operation1
 > jmx/invoke mydomain:name=App operation2

Here, operation1 and operation2 both use the connection that was set  
to the variable 'jmx.connection'.  'jmx.connection' is the default  
variable, but could be specified by:

 > jmx/invoke -c ${connection} mydomain:name=App operation1

Anyways, the point is that instead of commands taking a String[] and  
returning an int, which is modeled after Unix commands, that they  
take an Object[] and return an Object.  This could mimic the unix  
style, but also opens the doors to some fairly larger possibilities.

  * * *

Um, okay... enough I think for now ;-)

Anyone who made it this far and know about JavaCC using JJTree want  
to drop some knowledge on how best to get the shell grammar parsed?   
Its been years since I was using JavaCC, its slowly coming back to  
me, but I could use a hand if one is available.

Questions and comments are welcome.

Cheers,

--jason

Mime
View raw message