[CommandBox 3.9] Menu of "supported" engines

I work on multiple releases of a big app, each of which support only certain CFML engine versions. The CommandBox/CFConfig combination makes it wonderfully easy to run the same code, dbs, settings, file system artifacts, etc, against different engines and versions. But of course I’d like to make it even easier for our people if I can…

Is there any way to provide a “menu” of supported engine/version combinations for CommandBox running in a given location in the file system?

In my case, source code for each release is in a separate dir on my machine. It’d be great to cd CommandBox to one of them, and somehow bring up a “menu” of, say, ACF2016, ACF11, ACF10, ACF9, Lucee4, Lucee5, etc, whichever engine releases that app release supports. Ideally that engines “menu” would be easily configurable for each app release.

I keep using “menu” in quotes because I don’t care a lot what format it’s in, as long as it’s clear to users (devs), and can somehow start an instance running the selected engine. It could be a popup in the tray menu, for instance, but I think that only appears when an engine instance is running. Right? It could be some kind of picker in the CommandBox cmd line interface, really anything clear and doable.

Is anything like that possible?

In a super ideal world, the menu could be generated on the fly by code that examines some files in the app I want to run that say which engine versions are supported. I’d need to check, but I think as of now that info is in code, not data, but could be accessed via CFML. Down the road, if having it as data (xml/json/etc) would be better, that could happen too.

Extracting the supported versions would be my problem. The question I’m asking here is, what sort of menu could be created, how, and could it be dynamic?

Thanks.

I'm now loving Gradle for doing stuff like this. I wrote a little
CommandBox DSL for it, where each project (optionally) has its own
cmdbox install, and the server and cfconfig files come from the DSL and
are generated on the fly, so you can do like:

server {
    name = 'lucee4'
    app {
        cfengine = "lucee@4.5"
        serverHomeDirectory = "${project.lucee4homeDir}"
    }
}

server {
    name = 'lucee5'
    app {
        cfengine = "lucee@5"
        serverHomeDirectory = "${project.lucee5homeDir}"
    }
}

And you can stick it in loops and whatnot so it's all dynamic and just
really pretty neat. (The config for mappings and whatnot is similar,
and the cool thing abut them is you can define one 'template' and then
just change say the cfengine type and server name for each one after and
they'll all have the same settings other than that, etc..)

So it'd be a snap to write something that say looked in a CFC for the
supported engines and then created servers for them, and so when you log
into that instance of CommandBox and do something like 'server list' it
would just show you the ones you have defined for that project.

I don't see why the exact same thing couldn't be done with CommandBox
itself, versus using Gradle. I don't know if you can define a custom
servers.json path, but that'd be one way (or same-ish type of deal I'm
doing-- so you could just copy a pre-defined servers.json file into the
project's cmdbox home and then start with `box --commandbox_home=...`
and viola, you're in like Flynn.

The auto-complete is as good as a menu IMHO, since you don't have to
remember what servers are available, instead hitting tab if you don't
remember...

That said, we've been thinking about ways to make the multi-server stuff
better, and one thing would be a "watchdog" process, where we just keep
an instance of cmdbox open all the time and have it manage the servers.
That'd have one central menu for all servers, with like, options for
starting various ones on boot, etc..

Anyways tho, long story short, yes, there are a few ways you can do it
right now, and a few future ways percolating. Right now I think a
custom cmdbox home per project would work pretty well out of the box, or
if you're feeling brave I could put the gradle stuff out there, it's
pretty cool but is a million percent going to change so might want to
hold off until I've got it how I think I'll keep it for a while. :slight_smile:

I recommend the custom home because then you can just blow the stuff
away without worry, and it's a handy thing to know about in general for
doing the kinds of things you're wanting to do.

(Ha! Long story short he says, and then goes on for 6 more pages...)

-Denny

Just create a server.json file for each engine. Look at this example in the ColdBox repo where we’ve done the same thing to make our Travis CI build testing a little easier.
https://github.com/ColdBox/coldbox-platform

You can see there are the following files:

server-adobe-aether.json
server-adobe@10.json
server-adobe@11.json
server-adobe@2016.json
server-lucee@4.5.json
server-lucee@5.json

When I look in the repo, I can see all the engines we run the tests against, and if I want to start one of those engine, I just run this:

start server-lucee@5.json
or you can even just do this:
start lucee@5

If there was some type of `server init` call versus just the start call,
you could do something like have a script which added those server
configs postInstall, so they'd show up automagically in `server list`.

Or get all fancy and generate the configs based off a string found in a
CFC or some such, and then do the `server init` off those...

I think the only way to get them in there without starting them first is
to generate/copy a servers.json file. The `server list` command could
also be modified to pick up 'server-*.json' files and list them, though
I'd like the `server init` deal so it's exploded and ready...

Den

An alternate command would be very useful for this, similar to server list, but showing server-xxx.json files in the current CB directory, rather than named servers you’ve run.

I’m all for mechanisms that make it easy to set up an environment that’s simple for someone else to run. I want to say to a dev, OK, install CommandBox, put these files in each directory you want to be a web server root, then cmd > box > ?, and you’ll get a menu of engines you can run there, simple as that.

I'm thinking `server list` should already list any "server*.json" files
in the current directory, so updating that'd take care of that bit.

There's a couple ways you could do it right now I think (just
spit-balling here) by doing either a little 'setupDevEnv' slug that had
a postInstall which populates a CommandBox/servers.json file or whatnot,
or probably even better, create a 'setupDevEnv' task and use that:
https://commandbox.ortusbooks.com/content/task-runners.html

We can see what Brad thinks, and then perhaps you could open a ticket
for the `server list` command to have it also show any config-based ones
in the current directory just so it doesn't fall off the radar.

-Denny

Maybe I’m missing something really obvious, but it seems like you’re spending an awful lot of time on what sounds like just some basic human communication with your team. I’m not sure how you currently keep the other devs from “accidentally” starting up a server with the wrong version, but this sounds a like a feature whereby your car won’t drive to Wal-mart if there’s already milk in the fridge at home. Just seems like you’re looking for a solution under the wrong rock. If you have the desire to communicate with your team and let them know what versions of CF they can/should start the site with, or even the names of some specific server.json files then why not just put a readme.md in the root for them to look at. (Kind of like just bringing the shopping list along with you)

As far as a feature that lists out all server.json files in a directory, we have that. It’s called the “dir” command. Works great. You could even just go crazy with it and throw in some file globbing:
dir server*.json
I’m not sure we need anything other than that for people to be able to see what files are in a folder.

And finally, to Denny’s earlier point, if you really really want to create a little wizard or something that holds your devs hands through choosing a server, starts it up, makes their lunch, and pats them on back once it’s running you can always use a Task Runner for that. It still sounds like more work than them just typing “start lucee5-server.json” and getting on with it, but hey…
Here’s an example I just whipped together. There’s no validation, but it works. Throw this in a file called “task.cfc” and just run “task run” from the command line in your web root

component {

function run() {

var files = globber()
.setPattern( filesystemUtil.resolvePath( ‘server*.json’ ) )
.asArray()
.matches();

print
.line( ‘------------------------------------------’ )
.boldWhiteOnBlueLine( ‘Hello, and welcome to Server-O-Matic 5000.’ )
.boldWhiteOnBlueLine( 'Please choose a server to start: ’ )
.line( ‘------------------------------------------’ )
.line();

files.each( function( path, i ){
print.line( i & ') ’ & path.listLast( ‘/’ ) );
} );

print.line();
var theServer = ask( message='Enter the number of the server to run: ', defaultResponse=1 );

command( ‘server start’ )
.params( files[ theServer ].listLast( ‘/’ ) )
.run();
}

}

Thanks!

~Brad

ColdBox/CommandBox Developer Advocate
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

If your devs ain't eat'n well, they won't think well- pack dem lunches!

Heh. Seriously though, I'm so freakishly lazy that I'd rather just hit
tab + a letter or two + tab than actually check. Especially if it
varied by project and I was switching projects a lot.

Just kind of seemed like when I checked out the cfconfig project and
started up cmdbox it should have tab-completed the available server
definitions in the directory there-- if I mistype a name it would start
a new different server and I might not realize it, neh?

Having to do different build stuff depending on environment isn't
unusual, using tasks is a good way to capture that-- much nicer to say
"run that task", than "First start the server, then run the data
population command, then copy file x to y" (you should probably put nice
comments in the task explaining what it's doing though-- which works out
nicer actually because the docs are with the commands themselves).

So take a look at what Brad posted Dave, I think they'd come in handy
for the kinds of things you're doing-- environment provisioning, etc..

-Den

Denny, the lack of tab completion on server names in CFConfig is on my list to get done.

Thanks!

~Brad

ColdBox/CommandBox Developer Advocate
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com