Support for scripts in "warbler executable war" #10

Closed
ericanderson opened this Issue Feb 1, 2011 · 11 comments

Projects

None yet

5 participants

@ericanderson

Currently all command line args are passed into winstone. I think we should change the default behavior to the following:

  1. if no command line args exist, run via winstone.
  2. if args[0] == 'winstone', pass remaining args to winstone
  3. if gem.executables.include? args[0], pass remaining args to that gem executable
  4. else show help
@nicksieger
JRuby Team member

Proposed corrections:

  • For 2, use server
  • For 4, there should be a default operating mode. I still think if args[0] is not a gem executable then we should just pass args to the embedded server.
@jpshackelford

So this would allow bundling CLI in addition to the winstone server? I was just starting work on this and was assuming I'd need find away to slip in my own version of WarMain.java to handle the CLI parsing and delegation. Is that currently possible with this existing configuration file or do we need a code change even to replace WarMain.java during the packaging?

@jpshackelford

How were you thinking we'd detect whether we have packaged a gem executable for ARG[0] within the WAR?

@nicksieger
JRuby Team member

jpshackelford: it would probably need a code change. As for detecting gem executables, probably looking in WEB-INF/gems/bin/* for a script would suffice. The logic might need to be generalized depending on things like Bundler, bundle install --standalone, etc.

@jpshackelford

So what to you think about the following approach?

When a warbler user wants to allow cli options to be passed to an executable war, he includes a cli.properties file at some established location in the source tree. Warbler then bundles this file and uses a new WarMain class, e.g. WarMainCLI which handles the CLI parsing.

The keys of the property file are intended to match ARG[0] and its values tell us what gem/bin to load and how to set ARGV. Given a property such as:

mycommand = mygembin --switch --another ${ARGS}

WinMainCLI would:
1. check if ARG[0] == server and start winstone normally if found
2. attempt to match ARG[0] with a key in the property file (e.g. mycommand)
3. verify the existence of mygembin at WEB-INF/gems/gems//bin/
4. spin up the embedded ruby interpreter
5. set ARGV to ['--switch','--another', ...], replacing the ${ARGS} token with additional arguments passed to the executable WAR
6. load the file at the first matching path found in step #1

This approach allows the warbler user to select which executables are accessible and at which command. (I found many more bin files than expected in one of my wars and I don't really want to give the user access to all of them.)

If we also add a magic key 'default' that allows a non matching ARG[0] to map to gem bin file then we also have the capability of supporting sub-command style CLIs without having to specifically name the command, e.g. instead of

$ java -jar mycmd.war mycmd subcommand 

One could type:

$ java -jar mycmd.war subcommand

Of course we could simplify this whole approach if we want to support only one of the two models handled here:

  1. The war supports at most a single command, besides 'server', to which all args will be passed. (The use case I need.)

or

  1. The war maps commands passed on the CLI to one or more gem bin files bundled in the war.
@jpshackelford

On further reflection this is clearly not the simplest thing that works.

What if the WarMain class simply looks for the presence of a cli.rb in a canonical location inside the WAR and, if present, spins up the embedded ruby interpreter, sets ARGV and then loads cli.rb to handle command line processing. The cli.rb can do whatever it likes (including delegating to bundled gem bin file) and Warbler doesn't have the added complexity of command line processing.

It would be nice if the cli.rb could return a value to WarMain that it didn't find anything to do and that WarMain should start winstone as normal. RubyRuntimeAdapter#eval returns an IRubyObject so I suppose cli.rb could just evaluate to true or false to indicate whether or not to kick off winstone.

@ericanderson

I have a bunch of code that comes close but hits snags. I can push up to GH if you guys want to see.

I tried to inspect the gems available, look at their specs, look for executables that meet the conditions and execute them but its not as cut and dry as that.

@ericanderson

Doh. I deleted my warbler fork. Will have to start over. I still need this fairly badly :(

@tillsc

Anything new here? This would be soo cool!

@jkutner
JRuby Team member

This works as part of the runnable feature now.

@jkutner jkutner closed this Sep 9, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment