From a468af255082c649a9e55a0fbdfe9c9f372f9b6f Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 9 Jan 2017 17:54:40 -0600 Subject: [PATCH 01/45] Bump for new snapshot --- build/build.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/build/build.xml b/build/build.xml index 1540df5f4..fcf1d29e2 100644 --- a/build/build.xml +++ b/build/build.xml @@ -16,7 +16,6 @@ External Dependencies: - From d7dc604b4fbb7de8f32a408d6b08bf2dc63f07a8 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 9 Jan 2017 17:56:19 -0600 Subject: [PATCH 02/45] patch bump --- build/build.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/build/build.xml b/build/build.xml index fcf1d29e2..dba8289c2 100644 --- a/build/build.xml +++ b/build/build.xml @@ -16,6 +16,7 @@ External Dependencies: + From be68e23294e85a4bb473d889ab0968769c13da38 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 9 Jan 2017 18:00:00 -0600 Subject: [PATCH 03/45] Bump to Runwar bleeding edge --- build/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build.properties b/build/build.properties index 305a04c03..dae0c603a 100644 --- a/build/build.properties +++ b/build/build.properties @@ -16,7 +16,7 @@ cfml.cli.version=${cfml.loader.version}.${cfml.version} lucee.version=${cfml.version} jre.version=1.8.0_102 launch4j.version=3.4 -runwar.version=3.5.0 +runwar.version=3.6.0-SNAPSHOT #build locations build.type=localdev From 8fef62926b5d90a25a86fc45a16863a05106779b Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 9 Jan 2017 18:27:07 -0600 Subject: [PATCH 04/45] Update Brew box tap template to match correct format --- build/brew-template.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/brew-template.rb b/build/brew-template.rb index 3b6560840..506dc4fea 100644 --- a/build/brew-template.rb +++ b/build/brew-template.rb @@ -24,7 +24,7 @@ def install end test do - system "box", "--commandbox_home=~/", "version" - system "box", "--commandbox_home=~/", "help" + system "#{bin}/box", "--commandbox_home=~/", "version" + system "#{bin}/box", "--commandbox_home=~/", "help" end end From 84be3a4267d006cad606455cdf0f9287a822c7ea Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 10 Jan 2017 17:17:41 -0600 Subject: [PATCH 05/45] COMMANDBOX-553 --- src/java/cliloader/LoaderCLIMain.java | 10 ++++-- src/java/cliloader/Util.java | 47 +++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/java/cliloader/LoaderCLIMain.java b/src/java/cliloader/LoaderCLIMain.java index 17569f49d..494b87b45 100644 --- a/src/java/cliloader/LoaderCLIMain.java +++ b/src/java/cliloader/LoaderCLIMain.java @@ -606,7 +606,7 @@ public static void main( String[] arguments ) throws Throwable{ if( !versionFileMatches( versionFile, VERSION_PROPERTIES_PATH ) ) { String autoUpdate = props.getProperty( "cfml.cli.autoupdate" ); if( autoUpdate != null && Boolean.parseBoolean( autoUpdate ) ) { - log.warn( "\n*updating installed version" ); + log.warn( "\n*updating installed jars" ); updateLibs = true; versionFile.delete(); } else { @@ -622,7 +622,13 @@ public static void main( String[] arguments ) throws Throwable{ System.out.println( "Library path: " + libDir ); System.out .println( "Initializing libraries -- this will only happen once, and takes a few seconds..." ); - Util.removePreviousLibs( libDir ); + + // Try to delete the Runwar jar first since it's the most likely to be locked. + // If it fails, this method will just abort before we get any farther into deleting stuff. + Util.checkIfJarsLocked( libDir, "runwar" ); + // Ok, try deleting for real. If any of these jars fail to delete, we'll still holler at the user and abort the upgrade + Util.removePreviousLibs( libDir ); + Util.unzipInteralZip( classLoader, LIB_ZIP_PATH, libDir, debug ); // Wipe out existing /cfml/system folder to remove any deleted files diff --git a/src/java/cliloader/Util.java b/src/java/cliloader/Util.java index a52ed79dd..6ac6fac99 100644 --- a/src/java/cliloader/Util.java +++ b/src/java/cliloader/Util.java @@ -227,15 +227,56 @@ static String readFile( String path, Charset encoding ) throws IOException{ return new String( encoded, encoding ); } + /** + * Attempt to delete the Runwar jar and exit if it looks like locks exist on the file + * Do this first, since it's the most likely file to be locked and we can abort before destroying any other files + * @param libDir The folder to look in + * @param nameContains Match a jar with this in the name + */ + public static void checkIfJarsLocked( File libDir, String nameContains ){ + if( libDir.exists() + && libDir.listFiles( new ExtFilter( ".jar" ) ).length > 0 ) { + for( File previous : libDir.listFiles( new ExtFilter( ".jar" ) )) { + // Look for runwar{version}.jar + if( previous.getAbsolutePath().toLowerCase().contains( nameContains ) ) { + try { + boolean result = previous.delete(); + + if( !result ) { + System.err.println( "CommandBox is having problems deleting your previous jars to complete the upgrade." ); + System.err.println( "Please close all open consoles and stop all running servers before trying again." ); + System.exit( 1 ); + } + + } catch ( Exception e ) { + System.err.println( "CommandBox is having problems deleting your previous jars to complete the upgrade." ); + System.err.println( "Error: " + e.getMessage() ); + System.err.println( "Please close all open consoles and stop all running servers before trying again." ); + System.exit( 1 ); + } + } + } + } + } + public static void removePreviousLibs( File libDir ){ if( libDir.exists() && libDir.listFiles( new ExtFilter( ".jar" ) ).length > 0 ) { for( File previous : libDir.listFiles( new ExtFilter( ".jar" ) )) { try { - previous.delete(); + boolean result = previous.delete(); + + if( !result ) { + System.err.println( "CommandBox could not delete the jar [" + previous.getAbsolutePath() + "]" ); + System.err.println( "Please close all open consoles and stop all running servers before trying again." ); + System.exit( 1 ); + } + } catch ( Exception e ) { - System.err.println( "Could not delete previous lib: " - + previous.getAbsolutePath() ); + System.err.println( "CommandBox could not delete the jar [" + previous.getAbsolutePath() + "]" ); + System.err.println( "Error: " + e.getMessage() ); + System.err.println( "Please close all open consoles and stop all running servers before trying again." ); + System.exit( 1 ); } } } From c2da27dfc6bd93683d3d7df54adadd76d6e90a7c Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 10 Jan 2017 17:33:26 -0600 Subject: [PATCH 06/45] COMMANDBOX-553 --- src/java/cliloader/Util.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/java/cliloader/Util.java b/src/java/cliloader/Util.java index 6ac6fac99..a86611027 100644 --- a/src/java/cliloader/Util.java +++ b/src/java/cliloader/Util.java @@ -243,15 +243,19 @@ public static void checkIfJarsLocked( File libDir, String nameContains ){ boolean result = previous.delete(); if( !result ) { + System.err.println( "" ); System.err.println( "CommandBox is having problems deleting your previous jars to complete the upgrade." ); System.err.println( "Please close all open consoles and stop all running servers before trying again." ); + Thread.sleep( 5000 ); System.exit( 1 ); } } catch ( Exception e ) { + System.err.println( "" ); System.err.println( "CommandBox is having problems deleting your previous jars to complete the upgrade." ); System.err.println( "Error: " + e.getMessage() ); System.err.println( "Please close all open consoles and stop all running servers before trying again." ); + try { Thread.sleep( 5000 ); } catch( Throwable t ){} System.exit( 1 ); } } @@ -267,15 +271,19 @@ public static void removePreviousLibs( File libDir ){ boolean result = previous.delete(); if( !result ) { + System.err.println( "" ); System.err.println( "CommandBox could not delete the jar [" + previous.getAbsolutePath() + "]" ); System.err.println( "Please close all open consoles and stop all running servers before trying again." ); + Thread.sleep( 5000 ); System.exit( 1 ); } } catch ( Exception e ) { + System.err.println( "" ); System.err.println( "CommandBox could not delete the jar [" + previous.getAbsolutePath() + "]" ); System.err.println( "Error: " + e.getMessage() ); System.err.println( "Please close all open consoles and stop all running servers before trying again." ); + try { Thread.sleep( 5000 ); } catch( Throwable t ){} System.exit( 1 ); } } From 88b2ae3a2c84d54d067b2138eb885facc70ccc83 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 10 Jan 2017 17:33:43 -0600 Subject: [PATCH 07/45] COMMANDBOX-553 --- build/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build.properties b/build/build.properties index dae0c603a..68022595c 100644 --- a/build/build.properties +++ b/build/build.properties @@ -11,7 +11,7 @@ java.debug=true #dependencies dependencies.dir=${basedir}/lib cfml.version=4.5.4.017 -cfml.loader.version=1.4.6 +cfml.loader.version=1.4.7 cfml.cli.version=${cfml.loader.version}.${cfml.version} lucee.version=${cfml.version} jre.version=1.8.0_102 From b308375d8a9409f33c2b8abb94433fdd5362961d Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 11 Jan 2017 23:09:13 -0600 Subject: [PATCH 08/45] COMMANDBOX-554 --- src/cfml/system/services/ServerService.cfc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index e913f03dc..31fb86bc9 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -567,7 +567,8 @@ component accessors="true" singleton { var javaagent = serverinfo.cfengine contains 'lucee' ? '-javaagent:#libdir#/lucee-inst.jar' : ''; // Regardless of a custom server home, this is still used for various temp files and logs - directoryCreate( getCustomServerFolder( serverInfo ), true, true ); + serverinfo.customServerFolder = getCustomServerFolder( serverInfo ); + directoryCreate( serverinfo.customServerFolder, true, true ); // Not sure what Runwar does with this, but it wants to know what CFEngine we're starting (if we know) var CFEngineName = ''; @@ -582,7 +583,7 @@ component accessors="true" singleton { if( serverInfo.WARPath == '' ){ // This will install the engine war to start, possibly downloading it first - var installDetails = serverEngineService.install( cfengine=serverInfo.cfengine, basedirectory=getCustomServerFolder( serverInfo ), serverInfo=serverInfo, serverHomeDirectory=serverInfo.serverHomeDirectory ); + var installDetails = serverEngineService.install( cfengine=serverInfo.cfengine, basedirectory=serverinfo.customServerFolder, serverInfo=serverInfo, serverHomeDirectory=serverInfo.serverHomeDirectory ); serverInfo.serverHomeDirectory = installDetails.installDir; // TODO: As of 3.5 this is for backwards compat. Remove in later version serverInfo.serverHome = installDetails.installDir; @@ -638,7 +639,7 @@ component accessors="true" singleton { serverInfo.serverHomeDirectory = serverInfo.WARPath; } // Create a custom server folder to house the logs - serverInfo.logdir = getCustomServerFolder( serverInfo ) & "/logs"; + serverInfo.logdir = serverinfo.customServerFolder & "/logs"; serverInfo.consolelogPath = serverInfo.logdir & '/server.out.txt'; } @@ -721,7 +722,7 @@ component accessors="true" singleton { } // Serialize tray options and write to temp file - var trayOptionsPath = getCustomServerFolder( serverInfo ) & '/trayOptions.json'; + var trayOptionsPath = serverinfo.customServerFolder & '/trayOptions.json'; var trayJSON = { 'title' : processName, 'tooltip' : processName, From 6c0def8870605634a8544f81c079fbf923fc4857 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 12 Jan 2017 10:15:52 -0600 Subject: [PATCH 09/45] COMMANDBOX-555 --- src/cfml/system/util/REPLParser.cfc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cfml/system/util/REPLParser.cfc b/src/cfml/system/util/REPLParser.cfc index a82790700..0edb84e73 100644 --- a/src/cfml/system/util/REPLParser.cfc +++ b/src/cfml/system/util/REPLParser.cfc @@ -85,7 +85,9 @@ component accessors="true" singleton { **/ function getCommandPreparedForEvaluation() { var cfml = getCommandAsString(); - cfml = reReplaceNoCase( cfml, ";", "", "all" ); + // Trailing semicolons cause syntax error with evaluate() BIF so remove them and the following still work as execpted (returning the value) + // REPL> foo = 'bar'; + cfml = reReplaceNoCase( cfml, ";$", "" ); return cfml; } From e902f559127c7150751dee3d940570405dc48fb6 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 12 Jan 2017 13:35:17 -0600 Subject: [PATCH 10/45] COMMANDBOX-556 --- .../interceptors/packageScripts.cfc | 4 ++ .../commands/server/forget.cfc | 4 +- .../system/services/InterceptorService.cfc | 2 +- src/cfml/system/services/ServerService.cfc | 69 ++++++++----------- 4 files changed, 37 insertions(+), 42 deletions(-) diff --git a/src/cfml/system/modules_app/package-commands/interceptors/packageScripts.cfc b/src/cfml/system/modules_app/package-commands/interceptors/packageScripts.cfc index 2440ef2b2..a1a9f7c08 100644 --- a/src/cfml/system/modules_app/package-commands/interceptors/packageScripts.cfc +++ b/src/cfml/system/modules_app/package-commands/interceptors/packageScripts.cfc @@ -21,10 +21,14 @@ component { function postModuleLoad() { processScripts( 'postModuleLoad' ); } function preModuleUnLoad() { processScripts( 'preModuleUnLoad' ); } function postModuleUnload() { processScripts( 'postModuleUnload' ); } + function preServerStart() { processScripts( 'preServerStart' ); } function onServerInstall() { processScripts( 'onServerInstall', interceptData.serverinfo.webroot ); } function onServerStart() { processScripts( 'onServerStart', interceptData.serverinfo.webroot ); } function onServerStop() { processScripts( 'onServerStop', interceptData.serverinfo.webroot ); } + function preServerForget() { processScripts( 'preServerForget', interceptData.serverinfo.webroot ); } + function postServerForget() { processScripts( 'postServerForget', interceptData.serverinfo.webroot ); } + function onException() { processScripts( 'onException' ); } // preInstall gets package requesting the installation because dep isn't installed yet diff --git a/src/cfml/system/modules_app/server-commands/commands/server/forget.cfc b/src/cfml/system/modules_app/server-commands/commands/server/forget.cfc index b54e19711..f1a534420 100644 --- a/src/cfml/system/modules_app/server-commands/commands/server/forget.cfc +++ b/src/cfml/system/modules_app/server-commands/commands/server/forget.cfc @@ -58,7 +58,9 @@ component { "Really forget & delete server '#serverinfo.name#' forever [y/n]?"; if( arguments.force || confirm( askMessage ) ){ - print.line( serverService.forget( serverInfo, arguments.all ) ); + servers.each( function( ID ){ + print.line( serverService.forget( servers[ arguments.ID ] ) ); + } ); } else { print.orangeLine( "Cancelling forget command" ); } diff --git a/src/cfml/system/services/InterceptorService.cfc b/src/cfml/system/services/InterceptorService.cfc index baca2c8f6..b9a446f9e 100644 --- a/src/cfml/system/services/InterceptorService.cfc +++ b/src/cfml/system/services/InterceptorService.cfc @@ -33,7 +33,7 @@ component accessors=true singleton { // Module lifecycle 'preModuleLoad','postModuleLoad','preModuleUnLoad','postModuleUnload', // Server lifecycle - 'preServerStart','onServerStart','onServerInstall','onServerStop', + 'preServerStart','onServerStart','onServerInstall','onServerStop','preServerForget','postServerForget', // Error handling 'onException', // Package lifecycle diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 31fb86bc9..cc579da11 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -1110,52 +1110,41 @@ component accessors="true" singleton { * @serverInfo.hint struct of server info (ports, etc.) * @all.hint remove ALL servers **/ - function forget( required struct serverInfo, boolean all=false ){ - if( !arguments.all ){ - var servers = getServers(); - var serverdir = getCustomServerFolder( arguments.serverInfo ); - - // Catch this to gracefully handle where the OS or another program - // has the folder locked. - try { + function forget( required struct serverInfo ){ + var servers = getServers(); + var serverdir = getCustomServerFolder( arguments.serverInfo ); + + interceptorService.announceInterception( 'preServerForget', { serverInfo=serverInfo } ); - // try to delete interal server dir server - if( directoryExists( serverDir ) ){ - directoryDelete( serverdir, true ); - } - - // Server home may be custom, so delete it as well - if( len( serverInfo.serverHomeDirectory ) && directoryExists( serverInfo.serverHomeDirectory ) ){ - directoryDelete( serverInfo.serverHomeDirectory, true ); - } - + // Catch this to gracefully handle where the OS or another program + // has the folder locked. + try { - } catch( any e ) { - consoleLogger.error( '#e.message##chr(10)#Did you leave the server running? ' ); - logger.error( '#e.message# #e.detail#' , e.stackTrace ); - return ''; + // try to delete interal server dir server + if( directoryExists( serverDir ) ){ + directoryDelete( serverdir, true ); } - // try to delete from config first - structDelete( servers, arguments.serverInfo.id ); - setServers( servers ); + // Server home may be custom, so delete it as well + if( len( serverInfo.serverHomeDirectory ) && directoryExists( serverInfo.serverHomeDirectory ) ){ + directoryDelete( serverInfo.serverHomeDirectory, true ); + } - // return message - return "Poof! Wiped out server " & serverInfo.name; - } else { - var serverNames = getServerNames(); - setServers( {} ); - // Catch this to gracefully handle where the OS or another program - // has the folder locked. - try { - directoryDelete( variables.customServerDirectory, true ); - directoryCreate( variables.customServerDirectory ); - } catch( any e ) { - consoleLogger.error( '#e.message##chr(10)#Did you leave a server running? ' ); - logger.error( '#e.message# #e.detail#' , e.stackTrace ); - } - return "Poof! All servers (#arrayToList( serverNames )#) have been wiped."; + + } catch( any e ) { + consoleLogger.error( '#e.message##chr(10)#Did you leave the server running? ' ); + logger.error( '#e.message# #e.detail#' , e.stackTrace ); + return serverInfo.name + ' not deleted.'; } + + // Remove from config + structDelete( servers, arguments.serverInfo.id ); + setServers( servers ); + + interceptorService.announceInterception( 'postServerForget', { serverInfo=serverInfo } ); + + // return message + return "Poof! Wiped out server " & serverInfo.name; } /** From 229a9b92f4c25d39f64f1dadd5c3c185b2b02cdf Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 12 Jan 2017 14:03:01 -0600 Subject: [PATCH 11/45] COMMANDBOX-556 --- .../modules_app/server-commands/commands/server/forget.cfc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cfml/system/modules_app/server-commands/commands/server/forget.cfc b/src/cfml/system/modules_app/server-commands/commands/server/forget.cfc index f1a534420..d5ead7fde 100644 --- a/src/cfml/system/modules_app/server-commands/commands/server/forget.cfc +++ b/src/cfml/system/modules_app/server-commands/commands/server/forget.cfc @@ -59,7 +59,9 @@ component { if( arguments.force || confirm( askMessage ) ){ servers.each( function( ID ){ - print.line( serverService.forget( servers[ arguments.ID ] ) ); + print + .line( serverService.forget( servers[ arguments.ID ] ) ) + .toConsole(); } ); } else { print.orangeLine( "Cancelling forget command" ); From a85ad80e3e3c2841ed3b93c8cfc6898e54153bc6 Mon Sep 17 00:00:00 2001 From: Gavin Pickin Date: Thu, 19 Jan 2017 07:50:19 -0800 Subject: [PATCH 12/45] Update InterceptorMethodScript.txt --- .../coldbox-commands/templates/InterceptorMethodScript.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfml/system/modules_app/coldbox-commands/templates/InterceptorMethodScript.txt b/src/cfml/system/modules_app/coldbox-commands/templates/InterceptorMethodScript.txt index f554a28e7..d0128ca67 100644 --- a/src/cfml/system/modules_app/coldbox-commands/templates/InterceptorMethodScript.txt +++ b/src/cfml/system/modules_app/coldbox-commands/templates/InterceptorMethodScript.txt @@ -1,3 +1,3 @@ - void function |interceptionPoint|( event, rc, pc, interceptData, buffer ){ + void function |interceptionPoint|( event, rc, prc, interceptData, buffer ){ } From 24222e6f3d11eac287e07910d46d762be92a530e Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 19 Jan 2017 12:33:37 -0600 Subject: [PATCH 13/45] Ludicrus speed --- src/cfml/Application.cfc | 2 +- src/cfml/system/Bootstrap.cfm | 2 +- .../coldbox-commands/commands/coldbox/create/app.cfc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cfml/Application.cfc b/src/cfml/Application.cfc index 75d1e5dab..b3305830c 100644 --- a/src/cfml/Application.cfc +++ b/src/cfml/Application.cfc @@ -10,7 +10,7 @@ component{ this.name = "CommandBox CLI"; this.sessionmanagement = "false"; - this.applicationTimeout = createTimeSpan( 7, 0, 0, 0 ); + this.applicationTimeout = createTimeSpan( 999999, 0, 0, 0 ); // Move everything over to this mapping which is the "root" of our app CFMLRoot = getDirectoryFromPath( getMetadata( this ).path ); diff --git a/src/cfml/system/Bootstrap.cfm b/src/cfml/system/Bootstrap.cfm index c0784c7e1..05c081335 100644 --- a/src/cfml/system/Bootstrap.cfm +++ b/src/cfml/system/Bootstrap.cfm @@ -11,7 +11,7 @@ I am a CFM because the CLI seems to need a .cfm file to call This file will stay running the entire time the shell is open ---> - + #chr( 27 )#[32m#chr( 27 )#[40m#chr( 27 )#[1m _____ _ ____ diff --git a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/app.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/app.cfc index f6fd6d04b..d05472349 100644 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/app.cfc +++ b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/app.cfc @@ -65,7 +65,7 @@ component { /** * @name The name of the app you want to create - * @skeleton The name of the app skeleton to generate + * @skeleton The name of the app skeleton to generate (or an endpoint ID like a forgebox slug) * @skeleton.optionsUDF skeletonComplete * @directory The directory to create the app in and creates the directory if it does not exist. Defaults to your current working directory. * @init "init" the directory as a package if it isn't already From fb45c14a5fcbf3cf76100f14b7d99bae892b2e4c Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 19 Jan 2017 15:55:03 -0600 Subject: [PATCH 14/45] COMMANDBOX-558 --- src/cfml/system/services/ServerService.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index cc579da11..a07430f39 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -757,7 +757,7 @@ component accessors="true" singleton { var thispassthroughJVMArgs = ''; } - var args = ' #thisJVMArgs# -jar #variables.jarPath#' + var args = ' #thisJVMArgs# -jar "#variables.jarPath#"' // debug and background need to parse as a single token. Leave the = & ' --background=#background# --port #serverInfo.port# --host #serverInfo.host# --debug=#serverInfo.debug#' & ' --stop-port #serverInfo.stopsocket# --processname "#processName#" --log-dir "#serverInfo.logDir#"' From 5079d94b4668857db67bf88a15a1579e752c588e Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Fri, 20 Jan 2017 02:16:26 -0600 Subject: [PATCH 15/45] COMMANDBOX-558 --- src/cfml/system/services/ServerService.cfc | 129 ++++++++++++--------- src/cfml/system/util/Parser.cfc | 7 +- 2 files changed, 81 insertions(+), 55 deletions(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index a07430f39..38ed3a2c0 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -715,11 +715,6 @@ component accessors="true" singleton { tmp &= thisPath.startsWith( '/' ) ? thisPath : '/' & thisPath; errorPages = errorPages.listAppend( tmp ); } - // Bug in runwar requires me to completley omit this param unless it's populated - // https://github.com/cfmlprojects/runwar/issues/33 - if( len( errorPages ) ) { - errorPages = '--error-pages="#errorPages#"'; - } // Serialize tray options and write to temp file var trayOptionsPath = serverinfo.customServerFolder & '/trayOptions.json'; @@ -732,74 +727,105 @@ component accessors="true" singleton { var background = !(serverProps.console ?: false); // The java arguments to execute: Shared server, custom web configs + // This is an array of tokens to send to the process builder + var args = []; + + // "borrow" the CommandBox commandline parser to tokenize the JVM args. Not perfect, but close. Handles quoted values with spaces. + var argTokens = parser.tokenizeInput( serverInfo.JVMargs ) + .map( function( i ){ + // Clean up a couple escapes the parser does that we don't need + return i.replace( '\=', '=', 'all' ).replace( '\\', '\', 'all' ); + }); + // Add in heap size and java agent + argTokens + .append( '-Xmx#serverInfo.heapSize#m' ) + .append( '-Xms#serverInfo.heapSize#m' ); + if( len( trim( javaAgent ) ) ) { argTokens.append( javaagent ); } + + args + .append( '-jar' ).append( variables.jarPath ) + .append( '--background' ).append( background ) + .append( '--port' ).append( serverInfo.port ) + .append( '--host' ).append( serverInfo.host ) + .append( '--debug' ).append( serverInfo.debug ) + .append( '--stop-port' ).append( serverInfo.stopsocket ) + .append( '--processname' ).append( processName ) + .append( '--log-dir' ).append( serverInfo.logDir ) + .append( '--open-browser' ).append( serverInfo.openbrowser ) + .append( ' --open-url' ).append( ( serverInfo.SSLEnable ? 'https://#serverInfo.host#:#serverInfo.SSLPort#' : 'http://#serverInfo.host#:#serverInfo.port#' ) ) + .append( '--server-name' ).append( serverInfo.name ) + .append( '--tray-icon' ).append( serverInfo.trayIcon ) + .append( '--tray-config' ).append( trayOptionsPath ) + .append( '--servlet-rest-mappings' ).append( '/rest/*,/api/*' ) + .append( '--directoryindex' ).append( serverInfo.directoryBrowsing ) + .append( '--timeout' ).append( serverInfo.startTimeout ) + .append( serverInfo.runwarArgs.listToArray( ' ' ), true ); + + if( len( errorPages ) ) { + args.append( '--error-pages' ).append( errorPages ); + } + if( len( CFEngineName ) ) { + args.append( ' --cfengine-name' ).append( CFEngineName ); + } + if( len( serverInfo.welcomeFiles ) ) { + args.append( ' --welcome-files' ).append( erverInfo.welcomeFiles ); + } + if( len( CLIAliases ) ) { + args.append( ' --dirs' ).append( CLIAliases ); + } + + // If background, wrap up JVM args to pass through to background servers // "real" JVM args must come before Runwar args, so creating two variables, once of which will always be empty. if( background ) { - var thisJVMArgs = ''; - // "borrow" the CommandBox commandline parser to tokenize the JVM args. Not perfect, but close. Handles quoted values with spaces. - var argTokens = parser.tokenizeInput( serverInfo.JVMargs ) - .map( function( i ){ - // Clean up a couple escapes the parser does that we don't need - return i.replace( '\=', '=', 'all' ).replace( '\\', '\', 'all' ); - }); - // Add in heap size and java agent - argTokens - .append( '-Xmx#serverInfo.heapSize#m' ) - .append( '-Xms#serverInfo.heapSize#m' ); - if( len( trim( javaAgent ) ) ) { argTokens.append( '#javaagent#' ); } - - argString = argTokens.toList( ';' ).replace( '"', '\"', 'all' ); - - var thispassthroughJVMArgs = '--jvm-args="#argString#"'; + var argString = argTokens.toList( ';' ).replace( '"', '\"', 'all' ); + if( len( argString ) ) { + args.append( '--jvm-args="#argString#"' ); + } // If foreground, just stick them in. } else { - var thisJVMArgs = ' -Xmx#serverInfo.heapSize#m -Xms#serverInfo.heapSize#m #javaagent# #serverInfo.JVMargs# '; - var thispassthroughJVMArgs = ''; + argTokens.each( function(i) { args.prepend( i ); } ); } - var args = ' #thisJVMArgs# -jar "#variables.jarPath#"' - // debug and background need to parse as a single token. Leave the = - & ' --background=#background# --port #serverInfo.port# --host #serverInfo.host# --debug=#serverInfo.debug#' - & ' --stop-port #serverInfo.stopsocket# --processname "#processName#" --log-dir "#serverInfo.logDir#"' - & ' --open-browser #serverInfo.openbrowser#' - & ' --open-url ' & ( serverInfo.SSLEnable ? 'https://#serverInfo.host#:#serverInfo.SSLPort#' : 'http://#serverInfo.host#:#serverInfo.port#' ) - & ( len( CFEngineName ) ? ' --cfengine-name "#CFEngineName#"' : '' ) - & ' --server-name "#serverInfo.name#" #errorPages#' - & ( len( serverInfo.welcomeFiles ) ? ' --welcome-files "#serverInfo.welcomeFiles#" ' : '' ) - & ' --tray-icon "#serverInfo.trayIcon#" --tray-config "#trayOptionsPath#" --servlet-rest-mappings "/rest/*,/api/*"' - & ' --directoryindex "#serverInfo.directoryBrowsing#" ' - & ( len( CLIAliases ) ? ' --dirs "#CLIAliases#"' : '' ) - & ' #serverInfo.runwarArgs# --timeout #serverInfo.startTimeout# #thispassthroughJVMArgs# '; - + args.append( '-war' ); + // Starting a WAR if (serverInfo.WARPath != "" ) { - args &= " -war ""#serverInfo.WARPath#"""; + args.append( serverInfo.WARPath ); // Stand alone server } else { - args &= " -war ""#serverInfo.webroot#"""; + args.append( serverInfo.webroot ); } + // Custom web.xml (doesn't work right now) if ( Len( Trim( serverInfo.webXml ) ) && false ) { - args &= " --web-xml-path ""#serverInfo.webXml#"""; + args.append( '--web-xml-path' ).append( serverInfo.webXml ); // Default is in WAR home } else { - args &= " --web-xml-path ""#serverInfo.serverHomeDirectory#/WEB-INF/web.xml"""; + args.append( '--web-xml-path' ).append( '#serverInfo.serverHomeDirectory#/WEB-INF/web.xml' ); } if( len( serverInfo.libDirs ) ) { // Have to get rid of empty list elements - args &= " --lib-dirs ""#serverInfo.libDirs.listChangeDelims( ',', ',' )#"""; + args.append( '--lib-dirs' ).append( serverInfo.libDirs.listChangeDelims( ',', ',' ) ); } // Incorporate SSL to command if( serverInfo.SSLEnable ){ - args &= " --http-enable #serverInfo.HTTPEnable# --ssl-enable #serverInfo.SSLEnable# --ssl-port #serverInfo.SSLPort#"; + args + .append( '--http-enable' ).append( serverInfo.HTTPEnable ) + .append( '--ssl-enable' ).append( serverInfo.SSLEnable ) + .append( '--ssl-port' ).append( serverInfo.SSLPort ); } - if( serverInfo.SSLEnable && serverInfo.SSLCert != "") { - args &= " --ssl-cert ""#serverInfo.SSLCert#"" --ssl-key ""#serverInfo.SSLKey#"" --ssl-keypass ""#serverInfo.SSLKeyPass#"""; + if( serverInfo.SSLEnable && serverInfo.SSLCert != "" ) { + args + .append( '--ssl-cert' ).append( serverInfo.SSLCert ) + .append( '--ssl-key' ).append( serverInfo.SSLKey ) + .append( '--ssl-keypass' ).append( serverInfo.SSLKeyPass ); } + // Incorporate rewrites to command - args &= " --urlrewrite-enable #serverInfo.rewritesEnable#"; + args.append( '--urlrewrite-enable' ).append( serverInfo.rewritesEnable ); if( serverInfo.rewritesEnable ){ if( !fileExists(serverInfo.rewritesConfig) ){ @@ -808,14 +834,14 @@ component accessors="true" singleton { consoleLogger.error( '.' ); return; } - args &= " --urlrewrite-file ""#serverInfo.rewritesConfig#"""; + args.append( '--urlrewrite-file' ).append( serverInfo.rewritesConfig ); } // change status to starting + persist serverInfo.status = "starting"; setServerInfo( serverInfo ); if( serverInfo.debug ) { - var cleanedArgs = cr & ' ' & trim( replaceNoCase( args, ' -', cr & ' -', 'all' ) ); + var cleanedArgs = cr & ' ' & trim( replaceNoCase( args.toList( ' ' ), ' -', cr & ' -', 'all' ) ); consoleLogger.debug("Server start command: #javaCommand# #cleanedArgs#"); } @@ -824,9 +850,8 @@ component accessors="true" singleton { // Construct a new process object var processBuilder = createObject( "java", "java.lang.ProcessBuilder" ); // Pass array of tokens comprised of command plus arguments - var processTokens = [ variables.javaCommand ] - processTokens.append( args.listToArray( ' ' ), true ); - processBuilder.init( processTokens ); + args.prepend( variables.javaCommand ); + processBuilder.init( args ); // Conjoin standard error and output for convenience. processBuilder.redirectErrorStream( true ); // Kick off actual process @@ -843,7 +868,7 @@ component accessors="true" singleton { try{ // save server info and persist - serverInfo.statusInfo = { command:variables.javaCommand, arguments:attributes.args, result:'' }; + serverInfo.statusInfo = { command:variables.javaCommand, arguments:attributes.args.toList( ' ' ), result:'' }; serverInfo.status="starting"; setServerInfo( serverInfo ); diff --git a/src/cfml/system/util/Parser.cfc b/src/cfml/system/util/Parser.cfc index db7e3fa3b..f83839c59 100644 --- a/src/cfml/system/util/Parser.cfc +++ b/src/cfml/system/util/Parser.cfc @@ -260,10 +260,8 @@ component { arguments.argValue = replace( arguments.argValue, chr( 9 ), "\t", "all" ); return arguments.argValue; } - - // ----------------------------- Private --------------------------------------------- - private function unwrapQuotes( theString ) { + function unwrapQuotes( theString ) { // If the value is wrapped with backticks, leave them be. That is a signal to the CommandService // that the string is special and needs to be evaluated as an expression. if( left( theString, 1 ) == '"' || left( theString, 1 ) == "'" ) { @@ -272,6 +270,9 @@ component { return theString; } + + // ----------------------------- Private --------------------------------------------- + private function removeEscapedChars( theString ) { theString = replaceNoCase( theString, "\\", '__backSlash__', "all" ); theString = replaceNoCase( theString, "\'", '__singleQuote__', "all" ); From 5ce93a78a20e73fbbfd1c18ebd5faf7f93d72a89 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Fri, 20 Jan 2017 13:56:14 -0600 Subject: [PATCH 16/45] COMMANDBOX-559 --- .../system/modules_app/server-commands/commands/server/list.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfml/system/modules_app/server-commands/commands/server/list.cfc b/src/cfml/system/modules_app/server-commands/commands/server/list.cfc index e1209eec6..503bffcc0 100644 --- a/src/cfml/system/modules_app/server-commands/commands/server/list.cfc +++ b/src/cfml/system/modules_app/server-commands/commands/server/list.cfc @@ -91,7 +91,7 @@ component { print.indentedLine( "host: " & thisServerInfo.host ); if( len( thisServerInfo.engineName ) ) { - print.indentedLine( "CF Engine: " & thisServerInfo.engineName & ' ' & serverInfo.engineVersion ); + print.indentedLine( "CF Engine: " & thisServerInfo.engineName & ' ' & thisServerInfo.engineVersion ); } if( len( thisServerInfo.WARPath ) ) { print.indentedLine( "WARPath: " & thisServerInfo.WARPath ); From 0b2012974c5b5b04307393560a2d4e1aec64e5b9 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Fri, 20 Jan 2017 20:25:38 -0600 Subject: [PATCH 17/45] Stop yelling! --- .../commands/coldbox/create/app.cfc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/app.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/app.cfc index d05472349..166e98d66 100644 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/app.cfc +++ b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/app.cfc @@ -50,14 +50,14 @@ component { // Map these shortcut names to the actual ForgeBox slugs variables.templateMap = { - Advanced = 'cbtemplate-advanced', - AdvancedScript = 'cbtemplate-advanced-script', - ElixirVueJS = 'cbtemplate-elixir-vuejs', - ElixirBower = 'cbtemplate-elixir-bower', - Elixir = 'cbtemplate-elixir', - rest = 'cbtemplate-rest', - Simple = 'cbtemplate-simple', - SuperSimple = 'cbtemplate-supersimple' + 'Advanced' = 'cbtemplate-advanced', + 'AdvancedScript' = 'cbtemplate-advanced-script', + 'ElixirVueJS' = 'cbtemplate-elixir-vuejs', + 'ElixirBower' = 'cbtemplate-elixir-bower', + 'Elixir' = 'cbtemplate-elixir', + 'rest' = 'cbtemplate-rest', + 'Simple' = 'cbtemplate-simple', + 'SuperSimple' = 'cbtemplate-supersimple' }; return this; From ba3bb397257d5c82c51a6b67d0ff37dd2a9f3ddd Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Sat, 21 Jan 2017 00:29:35 -0600 Subject: [PATCH 18/45] Tidying up extra whitespace of doom --- src/cfml/system/services/ServerService.cfc | 12 ++++++------ src/cfml/system/util/FileSystem.cfc | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 38ed3a2c0..68b8c44ab 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -744,7 +744,7 @@ component accessors="true" singleton { args .append( '-jar' ).append( variables.jarPath ) - .append( '--background' ).append( background ) + .append( '--background=background' ) .append( '--port' ).append( serverInfo.port ) .append( '--host' ).append( serverInfo.host ) .append( '--debug' ).append( serverInfo.debug ) @@ -752,7 +752,7 @@ component accessors="true" singleton { .append( '--processname' ).append( processName ) .append( '--log-dir' ).append( serverInfo.logDir ) .append( '--open-browser' ).append( serverInfo.openbrowser ) - .append( ' --open-url' ).append( ( serverInfo.SSLEnable ? 'https://#serverInfo.host#:#serverInfo.SSLPort#' : 'http://#serverInfo.host#:#serverInfo.port#' ) ) + .append( '--open-url' ).append( ( serverInfo.SSLEnable ? 'https://#serverInfo.host#:#serverInfo.SSLPort#' : 'http://#serverInfo.host#:#serverInfo.port#' ) ) .append( '--server-name' ).append( serverInfo.name ) .append( '--tray-icon' ).append( serverInfo.trayIcon ) .append( '--tray-config' ).append( trayOptionsPath ) @@ -765,13 +765,13 @@ component accessors="true" singleton { args.append( '--error-pages' ).append( errorPages ); } if( len( CFEngineName ) ) { - args.append( ' --cfengine-name' ).append( CFEngineName ); + args.append( '--cfengine-name' ).append( CFEngineName ); } if( len( serverInfo.welcomeFiles ) ) { - args.append( ' --welcome-files' ).append( erverInfo.welcomeFiles ); + args.append( '--welcome-files' ).append( erverInfo.welcomeFiles ); } if( len( CLIAliases ) ) { - args.append( ' --dirs' ).append( CLIAliases ); + args.append( '--dirs' ).append( CLIAliases ); } @@ -1159,7 +1159,7 @@ component accessors="true" singleton { } catch( any e ) { consoleLogger.error( '#e.message##chr(10)#Did you leave the server running? ' ); logger.error( '#e.message# #e.detail#' , e.stackTrace ); - return serverInfo.name + ' not deleted.'; + return serverInfo.name & ' not deleted.'; } // Remove from config diff --git a/src/cfml/system/util/FileSystem.cfc b/src/cfml/system/util/FileSystem.cfc index 73eed4c00..1e2fbc184 100644 --- a/src/cfml/system/util/FileSystem.cfc +++ b/src/cfml/system/util/FileSystem.cfc @@ -101,9 +101,9 @@ component accessors="true" singleton { // build command var javaCommand = createObject( "java", "java.io.File").init( javaPath ).getCanonicalPath(); // take care of spaces in command - if( javaCommand contains " " ){ +/* if( javaCommand contains " " ){ javaCommand = """#javaCommand#"""; - } + }*/ return javaCommand; } From e80713684ac5bf49f9f80b5e87e32ee7288b5bf0 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 25 Jan 2017 20:58:32 -0500 Subject: [PATCH 19/45] Interpolate variable --- src/cfml/system/services/ServerService.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 68b8c44ab..76037a0fc 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -744,7 +744,7 @@ component accessors="true" singleton { args .append( '-jar' ).append( variables.jarPath ) - .append( '--background=background' ) + .append( '--background=#background#' ) .append( '--port' ).append( serverInfo.port ) .append( '--host' ).append( serverInfo.host ) .append( '--debug' ).append( serverInfo.debug ) From f07cace5717858afb23064a24fa6a97b7f768486 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 2 Feb 2017 21:13:49 -0600 Subject: [PATCH 20/45] Yet more fixes for paths with spaces in them. --- src/cfml/system/services/ServerService.cfc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 76037a0fc..980568bfa 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -564,7 +564,7 @@ component accessors="true" singleton { var launchUtil = java.LaunchUtil; // Default java agent for embedded Lucee engine - var javaagent = serverinfo.cfengine contains 'lucee' ? '-javaagent:#libdir#/lucee-inst.jar' : ''; + var javaagent = serverinfo.cfengine contains 'lucee' ? '"-javaagent:#libdir#/lucee-inst.jar"' : ''; // Regardless of a custom server home, this is still used for various temp files and logs serverinfo.customServerFolder = getCustomServerFolder( serverInfo ); @@ -605,15 +605,15 @@ component accessors="true" singleton { if( serverInfo.cfengine contains "lucee" ) { // Detect Lucee 4.x if( installDetails.version.listFirst( '.' ) < 5 ) { - javaagent = "-javaagent:#serverInfo.serverHomeDirectory#/WEB-INF/lib/lucee-inst.jar"; + javaagent = '"-javaagent:#serverInfo.serverHomeDirectory#/WEB-INF/lib/lucee-inst.jar"'; } else { // Lucee 5+ doesn't need the Java agent - javaagent = ""; + javaagent = ''; } } // If external Railo server, set the java agent if( serverInfo.cfengine contains "railo" ) { - javaagent = "-javaagent:#serverInfo.serverHomeDirectory#/WEB-INF/lib/railo-inst.jar"; + javaagent = '"-javaagent:#serverInfo.serverHomeDirectory#/WEB-INF/lib/railo-inst.jar"'; } // The process native name @@ -740,7 +740,7 @@ component accessors="true" singleton { argTokens .append( '-Xmx#serverInfo.heapSize#m' ) .append( '-Xms#serverInfo.heapSize#m' ); - if( len( trim( javaAgent ) ) ) { argTokens.append( javaagent ); } + if( len( trim( javaAgent ) ) ) { argTokens.append( javaagent ); } args .append( '-jar' ).append( variables.jarPath ) @@ -841,8 +841,8 @@ component accessors="true" singleton { setServerInfo( serverInfo ); if( serverInfo.debug ) { - var cleanedArgs = cr & ' ' & trim( replaceNoCase( args.toList( ' ' ), ' -', cr & ' -', 'all' ) ); - consoleLogger.debug("Server start command: #javaCommand# #cleanedArgs#"); + var cleanedArgs = cr & ' ' & trim( reReplaceNoCase( args.toList( ' ' ), ' -| "-', cr & ' -', 'all' ) ); + consoleLogger.debug("Server start command: #javaCommand# #cleanedargs#"); } // needs to be unique in each run to avoid errors From ed4ca3559ebc61618f28f2b0861b5701228dd695 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Sat, 4 Feb 2017 12:02:47 -0600 Subject: [PATCH 21/45] Need to escape the ENTIRE token for it to pass thur --- src/cfml/system/services/ServerService.cfc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 980568bfa..89fc810d0 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -780,7 +780,7 @@ component accessors="true" singleton { if( background ) { var argString = argTokens.toList( ';' ).replace( '"', '\"', 'all' ); if( len( argString ) ) { - args.append( '--jvm-args="#argString#"' ); + args.append( '"--jvm-args=#argString#"' ); } // If foreground, just stick them in. } else { @@ -841,7 +841,7 @@ component accessors="true" singleton { setServerInfo( serverInfo ); if( serverInfo.debug ) { - var cleanedArgs = cr & ' ' & trim( reReplaceNoCase( args.toList( ' ' ), ' -| "-', cr & ' -', 'all' ) ); + var cleanedArgs = cr & ' ' & trim( reReplaceNoCase( args.toList( ' ' ), ' (-|"-)', cr & ' \1', 'all' ) ); consoleLogger.debug("Server start command: #javaCommand# #cleanedargs#"); } From 97c02b55ab817a784e3a51d031b35c1d5caf37cf Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 6 Feb 2017 14:59:13 -0600 Subject: [PATCH 22/45] Small formatting improvement for JVM args --- .../modules_app/server-commands/commands/server/status.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfml/system/modules_app/server-commands/commands/server/status.cfc b/src/cfml/system/modules_app/server-commands/commands/server/status.cfc index f37f0eea0..215fe41bc 100644 --- a/src/cfml/system/modules_app/server-commands/commands/server/status.cfc +++ b/src/cfml/system/modules_app/server-commands/commands/server/status.cfc @@ -152,7 +152,7 @@ component aliases='status,server info' { print.indentedLine( trim( thisServerInfo.statusInfo.command ) ); // Put each --arg or -arg on a new line - var args = trim( replaceNoCase( thisServerInfo.statusInfo.arguments, ' -', cr & '-', 'all' ) ); + var args = trim( reReplaceNoCase( thisServerInfo.statusInfo.arguments, ' (-|"-)', cr & '\1', 'all' ) ); print.indentedIndentedLine( args ) .line(); From 5a136c05a698ffc4d5bab2cd1b716891cb646ebb Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 7 Feb 2017 22:57:25 -0600 Subject: [PATCH 23/45] COMMANDBOX-567 --- src/cfml/system/services/PackageService.cfc | 45 ++++++++++++--------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/src/cfml/system/services/PackageService.cfc b/src/cfml/system/services/PackageService.cfc index f46a89812..e2ce4e929 100644 --- a/src/cfml/system/services/PackageService.cfc +++ b/src/cfml/system/services/PackageService.cfc @@ -902,7 +902,7 @@ component accessors="true" singleton { // If a package is not installed (possibly a dev dependency in production mode), then we skip it if( !value.isInstalled ) { if( verbose ){ - print.yellowLine( "#arguments.slug# is not installed, skipping.." ) + print.yellowLine( " * #arguments.slug# is not installed, skipping.." ) .toConsole(); } return; @@ -945,8 +945,8 @@ component accessors="true" singleton { } // verbose output if( verbose ){ - print.yellowLine( "* #arguments.slug# (#value.packageVersion#) -> #endpointData.endpointName# version: (#updateData.version#)" ) - .boldRedLine( updateData.isOutdated ? " ** #arguments.slug# is Outdated" : "" ) + print.yellowLine( " * #arguments.slug# (#value.packageVersion#) -> #endpointData.endpointName# version: (#updateData.version#)" ) + .boldRedText( updateData.isOutdated ? " * #arguments.slug# is Outdated#chr( 10 )#" : "" ) .toConsole(); } @@ -1006,24 +1006,33 @@ component accessors="true" singleton { if( structKeyExists( arguments.installPaths, dependency ) ) { var fullPackageInstallPath = fileSystemUtil.resolvePath( arguments.installPaths[ dependency ], arguments.basePath ); - var boxJSON = readPackageDescriptor( fullPackageInstallPath ); - thisDeps[ dependency ][ 'name' ] = boxJSON.name; - thisDeps[ dependency ][ 'shortDescription' ] = boxJSON.shortDescription; - thisDeps[ dependency ][ 'packageVersion' ] = boxJSON.version; - thisDeps[ dependency ][ 'isInstalled' ] = true; - if( boxJSON.createPackageDirectory ) { - // Back up to the "container" folder. The packge directory will be added back on installation - thisDeps[ dependency ][ 'directory' ] = listDeleteAt( fullPackageInstallPath, listLen( fullPackageInstallPath, '/\' ), '/\' ); + + if( directoryExists( fullPackageInstallPath ) ) { + var boxJSON = readPackageDescriptor( fullPackageInstallPath ); + thisDeps[ dependency ][ 'name' ] = boxJSON.name; + thisDeps[ dependency ][ 'shortDescription' ] = boxJSON.shortDescription; + thisDeps[ dependency ][ 'packageVersion' ] = boxJSON.version; + thisDeps[ dependency ][ 'isInstalled' ] = true; + + if( boxJSON.createPackageDirectory ) { + // Back up to the "container" folder. The package directory will be added back on installation + thisDeps[ dependency ][ 'directory' ] = listDeleteAt( fullPackageInstallPath, listLen( fullPackageInstallPath, '/\' ), '/\' ); + } else { + thisDeps[ dependency ][ 'directory' ] = fullPackageInstallPath; + } + + // Down the rabbit hole + buildChildren( boxJSON, thisDeps[ dependency ], fullPackageInstallPath ); + } else { - thisDeps[ dependency ][ 'directory' ] = fullPackageInstallPath; + thisDeps[ dependency ][ 'isInstalled' ] = false; } - - // Down the rabbit hole - buildChildren( boxJSON, thisDeps[ dependency ], fullPackageInstallPath ); - } else { - // If we don't have an install path for this package, we don't know about its dependencies - thisDeps[ dependency ][ 'dependencies' ] = {}; + } + + // If we don't have an install path for this package, we don't know about its dependencies + thisDeps[ dependency ][ 'dependencies' ] = thisDeps[ dependency ][ 'dependencies' ] ?: {}; + } return thisDeps; From 7c0f105e6f49880205d6a6a946dfa381f04ec912 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Fri, 10 Feb 2017 20:45:07 -0600 Subject: [PATCH 24/45] Typo --- src/cfml/system/services/ServerService.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 89fc810d0..709e99714 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -768,7 +768,7 @@ component accessors="true" singleton { args.append( '--cfengine-name' ).append( CFEngineName ); } if( len( serverInfo.welcomeFiles ) ) { - args.append( '--welcome-files' ).append( erverInfo.welcomeFiles ); + args.append( '--welcome-files' ).append( serverInfo.welcomeFiles ); } if( len( CLIAliases ) ) { args.append( '--dirs' ).append( CLIAliases ); From 64db6bc6ab9916ced5804715e032d5851b049fa8 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Sat, 11 Feb 2017 00:09:06 -0600 Subject: [PATCH 25/45] Work around for jvmargs and stop --- src/cfml/system/services/ServerService.cfc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 709e99714..331466d2a 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -780,6 +780,7 @@ component accessors="true" singleton { if( background ) { var argString = argTokens.toList( ';' ).replace( '"', '\"', 'all' ); if( len( argString ) ) { + argString = '-D_foo=bar;#argString#;-D__foo=bar'; args.append( '"--jvm-args=#argString#"' ); } // If foreground, just stick them in. From 0ec704231ce64a5dcc16b0498f9beb7b623a1165 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Sun, 12 Feb 2017 16:46:56 -0600 Subject: [PATCH 26/45] COMMANDBOX-570 --- src/cfml/system/services/ServerService.cfc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 331466d2a..1cd818e27 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -1205,7 +1205,17 @@ component accessors="true" singleton { java.InetAddress.getByName( arguments.host ) ); serverSocket.close(); return true; - } catch( any var e ) { + } catch( java.net.UnknownHostException var e ) { + // In this case, the host name doesn't exist, so we really don't know about the port, but we'll say it's available + // otherwise, old, stopped servers who's host entries no longer exist will show up as running. + return true; + } catch( java.net.BindException var e ) { + // Same as above-- the IP address/host isn't bound to any local adapters. Probably a host file entry went missing. + if( e.message contains 'Cannot assign requested address' ) { + return true; + } + // We're assuming that any other error means the address was in use. + // Java doesn't provide a specific message or exception type for this unfortunately. return false; } } From c1013176c4f123ae7f67d0d3c2e6f6b00e86433f Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 13 Feb 2017 23:16:38 -0600 Subject: [PATCH 27/45] COMMANDBOX-571 --- src/cfml/system/services/ServerService.cfc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 1cd818e27..14adf909b 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -422,12 +422,20 @@ component accessors="true" singleton { // If the last port we used is taken, remove it from consideration. if( serverInfo.port == 0 || !isPortAvailable( serverInfo.host, serverInfo.port ) ) { serverInfo.delete( 'port' ); } // Port is the only setting that automatically carries over without being specified since it's random. - serverInfo.port = serverProps.port ?: serverJSON.web.http.port ?: serverInfo.port ?: getRandomPort( serverInfo.host ); + serverInfo.port = serverProps.port ?: serverJSON.web.http.port ?: defaults.web.http.port ?: serverInfo.port ?: getRandomPort( serverInfo.host ); // Double check that the port in the user params or server.json isn't in use if( !isPortAvailable( serverInfo.host, serverInfo.port ) ) { consoleLogger.error( "." ); - consoleLogger.error( "You asked for port [#( serverProps.port ?: serverJSON.web.http.port ?: '?' )#] in your #( serverProps.keyExists( 'port' ) ? 'start params' : 'server.json' )# but it's already in use so I'm ignoring it and choosing a random one for you." ); + var badPortlocation = 'config'; + if( serverProps.keyExists( 'port' ) ) { + badPortlocation = 'start params'; + } else if ( len( defaults.web.http.port ?: '' ) ) { + badPortlocation = 'server.json'; + } else { + badPortlocation = 'config server defaults'; + } + consoleLogger.error( "You asked for port [#( serverProps.port ?: serverJSON.web.http.port ?: defaults.web.http.port ?: '?' )#] in your #badPortlocation# but it's already in use so I'm ignoring it and choosing a random one for you." ); consoleLogger.error( "." ); serverInfo.port = getRandomPort( serverInfo.host ); } From 4a3e0024a8581cbe85986df774ddbb0b88c9ae71 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 13 Feb 2017 23:21:15 -0600 Subject: [PATCH 28/45] COMMANDBOX-572 --- src/cfml/system/services/ServerService.cfc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 14adf909b..4667e80a1 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -1387,7 +1387,7 @@ component accessors="true" singleton { } /** - * Get server info for webroot, if not created, it will init a new server info entry + * Get server info for webroot * @webroot.hint root directory for served content **/ struct function getServerInfo( required webroot , required name){ @@ -1407,8 +1407,6 @@ component accessors="true" singleton { serverInfo.name = listLast( arguments.webroot, "\/" ); // Store it in server struct servers[ webrootHash ] = serverInfo; - // persist it - setServers( servers ); } // Return the new record From 3ce90d5a9c249c47219d3cecb6250c8e8cc15d5a Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 16 Feb 2017 16:07:43 -0600 Subject: [PATCH 29/45] COMMANDBOX-575 --- src/cfml/system/services/ModuleService.cfc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cfml/system/services/ModuleService.cfc b/src/cfml/system/services/ModuleService.cfc index 8b3cd6c11..a3ae2a352 100644 --- a/src/cfml/system/services/ModuleService.cfc +++ b/src/cfml/system/services/ModuleService.cfc @@ -345,7 +345,13 @@ for( var moduleName in modules ){ // Verify the exception and inclusion lists if( canLoad( moduleName ) ){ - activateModule( moduleName ); + try { + activateModule( moduleName ); + } catch( any var e ) { + systemOutput( 'Module [#moduleName#] failed to load! Check the logs for more info.', true ); + systemOutput( e.message & chr( 10 ) & (e.detail ?: '') , true ); + instance.logger.error( 'Module [#moduleName#] failed to load!', e ); + } } } From 58e9965562d97a96bf15776dfb9d61e0ff05a0dd Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 16 Feb 2017 16:10:14 -0600 Subject: [PATCH 30/45] COMMANDBOX-502 --- .../system-commands/commands/run.cfc | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/cfml/system/modules_app/system-commands/commands/run.cfc b/src/cfml/system/modules_app/system-commands/commands/run.cfc index ef9ae92e6..9952c48b5 100644 --- a/src/cfml/system/modules_app/system-commands/commands/run.cfc +++ b/src/cfml/system/modules_app/system-commands/commands/run.cfc @@ -47,30 +47,46 @@ component{ function run( required command ){ - +/* var executeResult = ""; - var executeError = ""; + var executeError = "";*/ // Prep the command to run in the OS-specific shell if( fileSystemUtil.isWindows() ) { // Pass through Windows' command shell, /a outputs ANSI formatting, /c runs as a command - arguments.command = [ 'cmd','/a','/c', arguments.command ]; + var commandArray = [ 'cmd','/a','/c', arguments.command ]; } else { - // Pass through bash in interactive mode to expand aliases like "ll". - // -c runs input as a command, && exists cleanly from the shell as long as the original command ran successfully + // Pass through bash in interactive mode with -i to expand aliases like "ll". + // -c runs input as a command, "&& exits" cleanly from the shell as long as the original command ran successfully var nativeShell = configService.getSetting( 'nativeShell', '/bin/bash' ); - arguments.command = [ nativeShell,'-i','-c', arguments.command & ' && exit']; + commandArray = [ nativeShell,'-i','-c', arguments.command & ' && exit' ]; } try{ // grab the current working directory - var pwd = fileSystemUtil.resolvePath( '' ); - var CWD = createObject( 'java', 'java.io.File' ).init( pwd ); - + var CWDFile = createObject( 'java', 'java.io.File' ).init( fileSystemUtil.resolvePath( '' ) ); + + var exitCode = createObject( "java", "java.lang.ProcessBuilder" ) + .init( commandArray ) + // Do you believe in magic? + .inheritIO() + .directory( CWDFile ) + .start() + .waitFor(); + + // This works great on Windows. + // On Linux, the standard input (keyboard) is not being piped to the background process. + // Also on Linux, the word "exit" appears in the output. The output stream needs to be intercepted to clean it up. + + if( exitCode != 0 ) { + error( 'Command returned failing exit code [#exitCode#]' ); + } + +/* // execute the server command var process = createObject( 'java', 'java.lang.Runtime' ) .getRuntime() - .exec( '#arguments.command#', javaCast( "null", "" ), CWD ); + .exec( '#commandArray#', javaCast( "null", "" ), CWDFile ); var commandResult = createObject( 'java', 'lucee.commons.cli.Command' ) .execute( process ); @@ -95,7 +111,7 @@ component{ executeError = trim( executeError ); } print.redText( executeError ); - } + }*/ } catch (any e) { error( '#e.message##CR##e.detail#' ); From 29ef99900fb1028f6f6183980705ea4b6602d035 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 16 Feb 2017 23:09:12 -0600 Subject: [PATCH 31/45] COMMANDBOX-576 --- src/cfml/system/services/PackageService.cfc | 36 +++++++++++++++------ 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/cfml/system/services/PackageService.cfc b/src/cfml/system/services/PackageService.cfc index e2ce4e929..1684e374a 100644 --- a/src/cfml/system/services/PackageService.cfc +++ b/src/cfml/system/services/PackageService.cfc @@ -211,6 +211,19 @@ component accessors="true" singleton { // If the user gave us a directory, use it above all else if( structKeyExists( arguments, 'directory' ) ) { installDirectory = arguments.directory; + + // If this is an initial install (not a dependency) into a folder somehwere inside the CommandBox home, + // make sure we save correctly to CommandBox's user module box.json. + var commandBoxCFMLHome = expandPath( '/commandbox' ).replace( '\', '/', 'all' ); + installDirectory = installDirectory.replace( '\', '/', 'all' ); + + // If we're already in the CommandBox (a submodule of a commandbox module, most likely) + if( installDirectory contains commandBoxCFMLHome ) { + // Override the install directories to the CommandBox CFML root + arguments.currentWorkingDirectory = installDirectory.listDeleteAt( installDirectory.listLen( '/\' ), '/\' ); + arguments.packagePathRequestingInstallation = arguments.currentWorkingDirectory; + } + } // Next, see if the containing project has an install path configured for this dependency already. @@ -287,10 +300,20 @@ component accessors="true" singleton { installDirectory = arguments.packagePathRequestingInstallation & '/modules/contentbox/modules_user'; // CommandBox Modules } else if( packageType == 'commandbox-modules' ) { - // Override the install directories to the CommandBox CFML root - arguments.currentWorkingDirectory = expandPath( '/commandbox' ); - arguments.packagePathRequestingInstallation = expandPath( '/commandbox' ) - installDirectory = expandPath( '/commandbox/modules' ); + var commandBoxCFMLHome = expandPath( '/commandbox' ).replace( '\', '/', 'all' ); + arguments.packagePathRequestingInstallation = arguments.packagePathRequestingInstallation.replace( '\', '/', 'all' ); + + // If we're already in the CommandBox (a submodule of a commandbox module, most likely) + if( arguments.packagePathRequestingInstallation contains commandBoxCFMLHome ) { + // Then just nest as normal. + installDirectory = arguments.packagePathRequestingInstallation & '/modules'; + } else { + // Override the install directories to the CommandBox CFML root + arguments.currentWorkingDirectory = commandBoxCFMLHome; + arguments.packagePathRequestingInstallation = commandBoxCFMLHome; + installDirectory = expandPath( '/commandbox/modules' ); + } + // Flag the shell to reload after this command is finished. consoleLogger.warn( "Shell will be reloaded after installation." ); shell.reload( false ); @@ -476,11 +499,6 @@ component accessors="true" singleton { currentWorkingDirectory = arguments.currentWorkingDirectory, // Original dir packagePathRequestingInstallation = installDirectory // directory for smart dependencies to use }; - - // If the user didn't specify this, don't pass it since it overrides the package's desired install location - if( structKeyExists( arguments, 'directory' ) ) { - params.directory = arguments.directory; - } // Recursivley install them installPackage( argumentCollection = params ); From 942ae14a44793e1d62aba2b51a50dae78777862f Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 20 Feb 2017 14:44:31 -0600 Subject: [PATCH 32/45] COMMANDBOX-578 --- build/build.properties | 2 +- src/cfml/system/Shell.cfc | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/build.properties b/build/build.properties index 68022595c..d0f5cc480 100644 --- a/build/build.properties +++ b/build/build.properties @@ -10,7 +10,7 @@ java.debug=true #dependencies dependencies.dir=${basedir}/lib -cfml.version=4.5.4.017 +cfml.version=4.5.5.006 cfml.loader.version=1.4.7 cfml.cli.version=${cfml.loader.version}.${cfml.version} lucee.version=${cfml.version} diff --git a/src/cfml/system/Shell.cfc b/src/cfml/system/Shell.cfc index ef8382f22..8efae22d9 100644 --- a/src/cfml/system/Shell.cfc +++ b/src/cfml/system/Shell.cfc @@ -563,11 +563,11 @@ component accessors="true" singleton { if( lines != 0 ){ for( var idx=1; idx <= lines; idx++) { var tc = arguments.err.tagcontext[ idx ]; + if( idx > 1 ) { + variables.reader.print( print.boldCyanText( "called from " ) ); + } + variables.reader.print( variables.print.boldCyanText( "#tc.template#: line #tc.line##variables.cr#" )); if( len( tc.codeprinthtml ) ){ - if( idx > 1 ) { - variables.reader.print( print.boldCyanText( "called from " ) ); - } - variables.reader.print( variables.print.boldCyanText( "#tc.template#: line #tc.line##variables.cr#" )); variables.reader.print( variables.print.text( variables.formatterUtil.HTML2ANSI( tc.codeprinthtml ) ) ); } } From a5d11bd86072ce6010b903104d2c8c8bd8489834 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 21 Feb 2017 12:30:58 -0600 Subject: [PATCH 33/45] COMMANDBOX-571 --- src/cfml/system/services/CommandService.cfc | 2 +- src/cfml/system/services/ServerService.cfc | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/cfml/system/services/CommandService.cfc b/src/cfml/system/services/CommandService.cfc index 08e82fbcd..db988527e 100644 --- a/src/cfml/system/services/CommandService.cfc +++ b/src/cfml/system/services/CommandService.cfc @@ -703,7 +703,7 @@ component accessors="true" singleton { var commandData = createCommandData( fullCFCPath, commandName ); // This will catch nasty parse errors so the shell can keep loading } catch( any e ){ - systemOutput( 'Error registering command [#fullCFCPath#] #CR#' ); + systemOutput( 'Error registering command [#fullCFCPath#] #CR##e.message# #e.detail ?: ''##CR#Check the logs with [system-log | open] for more info.', true ); logger.error( 'Error registering command [#fullCFCPath#]. #e.message# #e.detail ?: ''#', e.stackTrace ); // pretty print the exception // shell.printError( e ); diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 4667e80a1..e477cf4a7 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -422,7 +422,11 @@ component accessors="true" singleton { // If the last port we used is taken, remove it from consideration. if( serverInfo.port == 0 || !isPortAvailable( serverInfo.host, serverInfo.port ) ) { serverInfo.delete( 'port' ); } // Port is the only setting that automatically carries over without being specified since it's random. - serverInfo.port = serverProps.port ?: serverJSON.web.http.port ?: defaults.web.http.port ?: serverInfo.port ?: getRandomPort( serverInfo.host ); + serverInfo.port = serverProps.port ?: serverJSON.web.http.port ?: serverInfo.port ?: defaults.web.http.port; + // Server default is 0 not null. + if( serverInfo.port == 0 ) { + serverInfo.port = getRandomPort( serverInfo.host ); + } // Double check that the port in the user params or server.json isn't in use if( !isPortAvailable( serverInfo.host, serverInfo.port ) ) { From bd535014e347ee259fd262c30125f5293fdd1306 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 22 Feb 2017 11:03:45 -0600 Subject: [PATCH 34/45] Quick fix for directory that doesn't exist. --- src/cfml/system/services/ServerService.cfc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index e477cf4a7..cc458990e 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -1489,6 +1489,7 @@ component accessors="true" singleton { var newJSON = formatterUtil.formatJSON( serializeJSON( arguments.data ) ); // Try to prevent bunping the date modified for no reason if( oldJSON != newJSON ) { + directoryCreate( getDirectoryFromPath( arguments.configFilePath ), true, true ); fileWrite( arguments.configFilePath, newJSON ); } } From a64994e73f018f93fde92f9e8815262a5ba55301 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 28 Feb 2017 13:01:08 -0500 Subject: [PATCH 35/45] Try to make Macs work --- src/cfml/system/services/ServerService.cfc | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index cc458990e..87b9e936f 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -576,7 +576,7 @@ component accessors="true" singleton { var launchUtil = java.LaunchUtil; // Default java agent for embedded Lucee engine - var javaagent = serverinfo.cfengine contains 'lucee' ? '"-javaagent:#libdir#/lucee-inst.jar"' : ''; + var javaagent = serverinfo.cfengine contains 'lucee' ? '-javaagent:#libdir#/lucee-inst.jar' : ''; // Regardless of a custom server home, this is still used for various temp files and logs serverinfo.customServerFolder = getCustomServerFolder( serverInfo ); @@ -617,7 +617,7 @@ component accessors="true" singleton { if( serverInfo.cfengine contains "lucee" ) { // Detect Lucee 4.x if( installDetails.version.listFirst( '.' ) < 5 ) { - javaagent = '"-javaagent:#serverInfo.serverHomeDirectory#/WEB-INF/lib/lucee-inst.jar"'; + javaagent = '-javaagent:#serverInfo.serverHomeDirectory#/WEB-INF/lib/lucee-inst.jar'; } else { // Lucee 5+ doesn't need the Java agent javaagent = ''; @@ -625,7 +625,7 @@ component accessors="true" singleton { } // If external Railo server, set the java agent if( serverInfo.cfengine contains "railo" ) { - javaagent = '"-javaagent:#serverInfo.serverHomeDirectory#/WEB-INF/lib/railo-inst.jar"'; + javaagent = '-javaagent:#serverInfo.serverHomeDirectory#/WEB-INF/lib/railo-inst.jar'; } // The process native name @@ -746,7 +746,7 @@ component accessors="true" singleton { var argTokens = parser.tokenizeInput( serverInfo.JVMargs ) .map( function( i ){ // Clean up a couple escapes the parser does that we don't need - return i.replace( '\=', '=', 'all' ).replace( '\\', '\', 'all' ); + return parser.unwrapQuotes( i.replace( '\=', '=', 'all' ).replace( '\\', '\', 'all' ) ) ; }); // Add in heap size and java agent argTokens @@ -786,14 +786,13 @@ component accessors="true" singleton { args.append( '--dirs' ).append( CLIAliases ); } - + // If background, wrap up JVM args to pass through to background servers // "real" JVM args must come before Runwar args, so creating two variables, once of which will always be empty. if( background ) { - var argString = argTokens.toList( ';' ).replace( '"', '\"', 'all' ); + var argString = argTokens.toList( ';' ); //.replace( '"', '\"', 'all' ); if( len( argString ) ) { - argString = '-D_foo=bar;#argString#;-D__foo=bar'; - args.append( '"--jvm-args=#argString#"' ); + args.append( '--jvm-args=#trim( argString )#' ); } // If foreground, just stick them in. } else { From 40fd4d5affaa7b4ce253410abdde787bb963ad11 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 28 Feb 2017 23:07:41 -0600 Subject: [PATCH 36/45] Sometimes creates compilation error. --- src/cfml/system/services/ServerService.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 87b9e936f..157390662 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -639,7 +639,7 @@ component accessors="true" singleton { serverInfo.serverHomeDirectory = reReplaceNoCase( serverInfo.WARPath, '(.*)(\.zip|\.war)', '\1' ); // Expand the war if it doesn't exist or we're forcing - if( !directoryExists( serverInfo.serverHomeDirectory ) || serverProps.force ?: false ) { + if( !directoryExists( serverInfo.serverHomeDirectory ) || ( serverProps.force ?: false ) ) { consoleLogger.info( "Exploding WAR archive..."); directoryCreate( serverInfo.serverHomeDirectory, true, true ); zip action="unzip" file="#serverInfo.WARPath#" destination="#serverInfo.serverHomeDirectory#" overwrite="true"; From 3abcb9ff6270244442b8daa394d16cbd5b303092 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 7 Mar 2017 23:29:53 -0600 Subject: [PATCH 37/45] Fixed typo for Gavin!! --- src/cfml/system/services/ServerEngineService.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfml/system/services/ServerEngineService.cfc b/src/cfml/system/services/ServerEngineService.cfc index 51f5ad876..81ca30df6 100644 --- a/src/cfml/system/services/ServerEngineService.cfc +++ b/src/cfml/system/services/ServerEngineService.cfc @@ -236,7 +236,7 @@ component accessors="true" singleton="true" { if( previousEngineTag != thisEngineTag ) { consoleLogger.warn( "You've asked for the engine [#thisEngineTag#] to be started," ); consoleLogger.warn( "but this server home already has [#previousEngineTag#] deployed to it!" ); - consoleLogger.warn( "In orer to get the new version, you need to run 'server forget' on this server and start it again." ); + consoleLogger.warn( "In order to get the new version, you need to run 'server forget' on this server and start it again." ); } consoleLogger.info( "WAR/zip archive already installed."); From e347e4e4c5d60ab2f58eed3af463a404c564a5bb Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 8 Mar 2017 14:58:34 -0600 Subject: [PATCH 38/45] COMMANDBOX-587 --- .../modules_app/testbox-commands/commands/testbox/run.cfc | 1 + src/cfml/system/services/CommandService.cfc | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cfml/system/modules_app/testbox-commands/commands/testbox/run.cfc b/src/cfml/system/modules_app/testbox-commands/commands/testbox/run.cfc index c80f30431..2b82fa728 100644 --- a/src/cfml/system/modules_app/testbox-commands/commands/testbox/run.cfc +++ b/src/cfml/system/modules_app/testbox-commands/commands/testbox/run.cfc @@ -109,6 +109,7 @@ component { print.green( " " & results.filecontent ); } else if( results.responseheader[ "x-testbox-totalFail" ] gt 0 ){ // print Failure report + setExitCode( 1 ); print.yellow( " " & results.filecontent ); } else if( results.responseheader[ "x-testbox-totalError" ] gt 0 ){ // print Failure report diff --git a/src/cfml/system/services/CommandService.cfc b/src/cfml/system/services/CommandService.cfc index db988527e..46bc94640 100644 --- a/src/cfml/system/services/CommandService.cfc +++ b/src/cfml/system/services/CommandService.cfc @@ -289,6 +289,10 @@ component accessors="true" singleton { interceptorService.announceInterception( 'preCommand', { commandInfo=commandInfo, parameterInfo=parameterInfo } ); + // Successful command execution resets exit code to 0. Set this prior to running the command since the command + // may explicitly set the exit code to 1 but not call the error() method. + shell.setExitCode( 0 ); + // Run the command try { var result = commandInfo.commandReference.CFC.run( argumentCollection = parameterInfo.namedParameters ); @@ -321,9 +325,6 @@ component accessors="true" singleton { } } - // Successful command execution resets exit code to 0 - shell.setExitCode( 0 ); - // Remove it from the stack instance.callStack.deleteAt( 1 ); @@ -340,7 +341,6 @@ component accessors="true" singleton { result = interceptData.result; } // End loop over command chain - return result; } From 59809e48745cb79a1a5dbed99acf08a49a80e5a1 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 8 Mar 2017 21:13:06 -0600 Subject: [PATCH 39/45] COMMANDBOX-502 --- .../system-commands/commands/run.cfc | 105 +++++++++++------- 1 file changed, 67 insertions(+), 38 deletions(-) diff --git a/src/cfml/system/modules_app/system-commands/commands/run.cfc b/src/cfml/system/modules_app/system-commands/commands/run.cfc index 9952c48b5..bea681db5 100644 --- a/src/cfml/system/modules_app/system-commands/commands/run.cfc +++ b/src/cfml/system/modules_app/system-commands/commands/run.cfc @@ -66,52 +66,81 @@ component{ // grab the current working directory var CWDFile = createObject( 'java', 'java.io.File' ).init( fileSystemUtil.resolvePath( '' ) ); - var exitCode = createObject( "java", "java.lang.ProcessBuilder" ) + var Redirect = createObject( "java", "java.lang.ProcessBuilder$Redirect" ); + process = createObject( "java", "java.lang.ProcessBuilder" ) .init( commandArray ) - // Do you believe in magic? - .inheritIO() + // Assume CommandBox's standard input for this process + .redirectInput(Redirect.INHERIT) + // Combine standard error and standard out + .redirectErrorStream( true ) .directory( CWDFile ) - .start() - .waitFor(); + .start(); // This works great on Windows. // On Linux, the standard input (keyboard) is not being piped to the background process. - // Also on Linux, the word "exit" appears in the output. The output stream needs to be intercepted to clean it up. - if( exitCode != 0 ) { - error( 'Command returned failing exit code [#exitCode#]' ); + // needs to be unique in each run to avoid errors + var threadName = '#createUUID()#'; + + // Spin up a thread to capture the standard out and error from the server + thread name="#threadName#" { + try{ + + var inputStream = process.getInputStream(); + var inputStreamReader = createObject( 'java', 'java.io.InputStreamReader' ).init( inputStream ); + var bufferedReader = createObject( 'java', 'java.io.BufferedReader' ).init( inputStreamReader ); + + // These two patterns need to be stripped off the output. + var exit = 'exit'; + var jobControl = 'bash: no job control in this shell'; + + var char = bufferedReader.read(); + var token = ''; + while( char != -1 ){ + token &= chr( char ); + + // Only output if we arent matching any of the forbidden patterns above. + if( !exit.startsWith( trim( token ) ) + && !jobControl.startsWith( trim( token ) ) ) { + // Build up our output + print + .text( token ) + .toConsole(); + + token = ''; + } + + char = bufferedReader.read(); + } // End of inputStream + + // Output any trailing text as long as it isn't a match + if( !trim( token ).startsWith( exit ) + && !trim( token ).startsWith( jobControl ) ) { + print + .text( token ) + .toConsole(); + } + + } catch( any e ) { + logger.error( e.message & ' ' & e.detail, e.stacktrace ); + print.line( e.message & ' ' & e.detail, e.stacktrace ); + } finally { + // Make sure we always close the file or the process will never quit! + if( isDefined( 'bufferedReader' ) ) { + bufferedReader.close(); + } + } } -/* - // execute the server command - var process = createObject( 'java', 'java.lang.Runtime' ) - .getRuntime() - .exec( '#commandArray#', javaCast( "null", "" ), CWDFile ); - var commandResult = createObject( 'java', 'lucee.commons.cli.Command' ) - .execute( process ); - - // I don't like the idea of potentially removing significant whitespace, but commands like pwd - // come with an extra line break that is a pain if you want to pipe into another command - var executeResult = trim( commandResult.getOutput() ); - var executeError = trim( commandResult.getError() ); - - // Output Results - if( !isNull( executeResult ) && len( executeResult ) ) { - print.Text( executeResult ); - } - // Output error - if( !isNull( executeError ) && len( executeError ) ) { - // Clean up standard error from Unix interactive shell workaround - if( !fileSystemUtil.isWindows() && right( executeError, 4 ) == 'exit' ) { - executeError = mid( executeError, 1, len( executeError )-4 ); - } - // Clean up annoying warnings abour job control in some shells. - if( !fileSystemUtil.isWindows() && findNoCase( 'bash: no job control in this shell', executeError ) ) { - executeError = replaceNoCase( executeError, 'bash: no job control in this shell', '' ); - executeError = trim( executeError ); - } - print.redText( executeError ); - }*/ + var exitCode = process.waitFor(); + + thread action="join" name="#threadName#"; + + print.line(); + + if( exitCode != 0 ) { + error( 'Command returned failing exit code [#exitCode#]' ); + } } catch (any e) { error( '#e.message##CR##e.detail#' ); From a54e84f94ab29b702883eb6af369757ccba29e0c Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 8 Mar 2017 22:28:09 -0600 Subject: [PATCH 40/45] COMMANDBOX-502 --- src/cfml/system/Shell.cfc | 2 ++ .../modules_app/system-commands/commands/run.cfc | 14 +++++--------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/cfml/system/Shell.cfc b/src/cfml/system/Shell.cfc index 8efae22d9..655a98f84 100644 --- a/src/cfml/system/Shell.cfc +++ b/src/cfml/system/Shell.cfc @@ -529,6 +529,8 @@ component accessors="true" singleton { if( ! ( lastChar == chr( 10 ) || lastChar == chr( 13 ) ) ) { variables.reader.println(); } + } else { + variables.reader.println(); } return ''; diff --git a/src/cfml/system/modules_app/system-commands/commands/run.cfc b/src/cfml/system/modules_app/system-commands/commands/run.cfc index bea681db5..ca067c42a 100644 --- a/src/cfml/system/modules_app/system-commands/commands/run.cfc +++ b/src/cfml/system/modules_app/system-commands/commands/run.cfc @@ -1,7 +1,6 @@ /** * Execute an operating system level command in the native shell. The binary must be in the PATH, or you can specify the full - * path to it. This command will wait for the OS exectuable to complete. This cannot be used for any commands that require - * interactivity or don't exit automatically or the call will hang indefinitely. + * path to it. This command will wait for the OS exectuable to complete but will flush the output as it is received. * . * {code:bash} * run myApp.exe @@ -47,9 +46,6 @@ component{ function run( required command ){ -/* - var executeResult = ""; - var executeError = "";*/ // Prep the command to run in the OS-specific shell if( fileSystemUtil.isWindows() ) { @@ -101,7 +97,9 @@ component{ // Only output if we arent matching any of the forbidden patterns above. if( !exit.startsWith( trim( token ) ) - && !jobControl.startsWith( trim( token ) ) ) { + && !jobControl.startsWith( trim( token ) ) + && !char == 13 + && !char == 10 ) { // Build up our output print .text( token ) @@ -117,7 +115,7 @@ component{ if( !trim( token ).startsWith( exit ) && !trim( token ).startsWith( jobControl ) ) { print - .text( token ) + .text( trim( token ) ) .toConsole(); } @@ -136,8 +134,6 @@ component{ thread action="join" name="#threadName#"; - print.line(); - if( exitCode != 0 ) { error( 'Command returned failing exit code [#exitCode#]' ); } From 216f9b741c9af2f8cba53c3d71592868c8520e8f Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 9 Mar 2017 11:33:35 -0600 Subject: [PATCH 41/45] syntax update --- src/cfml/system/modules_app/system-commands/commands/run.cfc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cfml/system/modules_app/system-commands/commands/run.cfc b/src/cfml/system/modules_app/system-commands/commands/run.cfc index ca067c42a..05f3528d0 100644 --- a/src/cfml/system/modules_app/system-commands/commands/run.cfc +++ b/src/cfml/system/modules_app/system-commands/commands/run.cfc @@ -62,11 +62,11 @@ component{ // grab the current working directory var CWDFile = createObject( 'java', 'java.io.File' ).init( fileSystemUtil.resolvePath( '' ) ); - var Redirect = createObject( "java", "java.lang.ProcessBuilder$Redirect" ); + var redirect = createObject( "java", "java.lang.ProcessBuilder$Redirect" ); process = createObject( "java", "java.lang.ProcessBuilder" ) .init( commandArray ) // Assume CommandBox's standard input for this process - .redirectInput(Redirect.INHERIT) + .redirectInput( redirect.INHERIT ) // Combine standard error and standard out .redirectErrorStream( true ) .directory( CWDFile ) From 9f12cc1a7fab7bcb1166f605b7990b4bb1cb057a Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 9 Mar 2017 11:37:10 -0600 Subject: [PATCH 42/45] redirect exit output to dev null --- src/cfml/system/modules_app/system-commands/commands/run.cfc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cfml/system/modules_app/system-commands/commands/run.cfc b/src/cfml/system/modules_app/system-commands/commands/run.cfc index 05f3528d0..b0c392d28 100644 --- a/src/cfml/system/modules_app/system-commands/commands/run.cfc +++ b/src/cfml/system/modules_app/system-commands/commands/run.cfc @@ -55,7 +55,7 @@ component{ // Pass through bash in interactive mode with -i to expand aliases like "ll". // -c runs input as a command, "&& exits" cleanly from the shell as long as the original command ran successfully var nativeShell = configService.getSetting( 'nativeShell', '/bin/bash' ); - commandArray = [ nativeShell,'-i','-c', arguments.command & ' && exit' ]; + commandArray = [ nativeShell,'-i','-c', arguments.command & ' && ( exit > /dev/null )' ]; } try{ @@ -87,7 +87,7 @@ component{ var bufferedReader = createObject( 'java', 'java.io.BufferedReader' ).init( inputStreamReader ); // These two patterns need to be stripped off the output. - var exit = 'exit'; + var exit = 'foo'; var jobControl = 'bash: no job control in this shell'; var char = bufferedReader.read(); From df5f0f7b2da85d95f5d3d7ba0ce1c9b2affdaed8 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 9 Mar 2017 11:53:20 -0600 Subject: [PATCH 43/45] COMMANDBOX-502 Mac tests for the process builder and exit codes. --- .../system-commands/commands/run.cfc | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/cfml/system/modules_app/system-commands/commands/run.cfc b/src/cfml/system/modules_app/system-commands/commands/run.cfc index b0c392d28..e79194281 100644 --- a/src/cfml/system/modules_app/system-commands/commands/run.cfc +++ b/src/cfml/system/modules_app/system-commands/commands/run.cfc @@ -55,22 +55,22 @@ component{ // Pass through bash in interactive mode with -i to expand aliases like "ll". // -c runs input as a command, "&& exits" cleanly from the shell as long as the original command ran successfully var nativeShell = configService.getSetting( 'nativeShell', '/bin/bash' ); - commandArray = [ nativeShell,'-i','-c', arguments.command & ' && ( exit > /dev/null )' ]; + commandArray = [ nativeShell, '-i', '-c', arguments.command & ' && ( exit $? > /dev/null )' ]; } try{ // grab the current working directory var CWDFile = createObject( 'java', 'java.io.File' ).init( fileSystemUtil.resolvePath( '' ) ); - - var redirect = createObject( "java", "java.lang.ProcessBuilder$Redirect" ); - process = createObject( "java", "java.lang.ProcessBuilder" ) + var exitCode = createObject( "java", "java.lang.ProcessBuilder" ) .init( commandArray ) // Assume CommandBox's standard input for this process - .redirectInput( redirect.INHERIT ) + //.redirectInput( redirect.INHERIT ) // Combine standard error and standard out - .redirectErrorStream( true ) + //.redirectErrorStream( true ) + .inheritIO() .directory( CWDFile ) - .start(); + .start() + .waitFor(); // This works great on Windows. // On Linux, the standard input (keyboard) is not being piped to the background process. @@ -78,7 +78,8 @@ component{ // needs to be unique in each run to avoid errors var threadName = '#createUUID()#'; - // Spin up a thread to capture the standard out and error from the server + /** + * // Spin up a thread to capture the standard out and error from the server thread name="#threadName#" { try{ @@ -129,16 +130,15 @@ component{ } } } - var exitCode = process.waitFor(); - - thread action="join" name="#threadName#"; + //thread action="join" name="#threadName#"; + */ if( exitCode != 0 ) { error( 'Command returned failing exit code [#exitCode#]' ); } - } catch (any e) { + } catch( any e ){ error( '#e.message##CR##e.detail#' ); } From de74abae094a96d09160caecdd97ba6395341d5a Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 9 Mar 2017 18:44:59 -0600 Subject: [PATCH 44/45] Cleanup and bump BE to 3.6.0 --- build/build.xml | 2 +- .../system-commands/commands/run.cfc | 74 ++----------------- 2 files changed, 8 insertions(+), 68 deletions(-) diff --git a/build/build.xml b/build/build.xml index dba8289c2..07394aa1c 100644 --- a/build/build.xml +++ b/build/build.xml @@ -16,7 +16,7 @@ External Dependencies: - + diff --git a/src/cfml/system/modules_app/system-commands/commands/run.cfc b/src/cfml/system/modules_app/system-commands/commands/run.cfc index e79194281..c27305956 100644 --- a/src/cfml/system/modules_app/system-commands/commands/run.cfc +++ b/src/cfml/system/modules_app/system-commands/commands/run.cfc @@ -63,76 +63,16 @@ component{ var CWDFile = createObject( 'java', 'java.io.File' ).init( fileSystemUtil.resolvePath( '' ) ); var exitCode = createObject( "java", "java.lang.ProcessBuilder" ) .init( commandArray ) - // Assume CommandBox's standard input for this process - //.redirectInput( redirect.INHERIT ) - // Combine standard error and standard out - //.redirectErrorStream( true ) - .inheritIO() + // Do you believe in magic + // This works great on Mac/Windows. + // On Linux, the standard input (keyboard) is not being piped to the background process. + .inheritIO() + // Sets current working directory for the process .directory( CWDFile ) + // Fires process async .start() + // waits for it to exit, returning the exit code .waitFor(); - - // This works great on Windows. - // On Linux, the standard input (keyboard) is not being piped to the background process. - - // needs to be unique in each run to avoid errors - var threadName = '#createUUID()#'; - - /** - * // Spin up a thread to capture the standard out and error from the server - thread name="#threadName#" { - try{ - - var inputStream = process.getInputStream(); - var inputStreamReader = createObject( 'java', 'java.io.InputStreamReader' ).init( inputStream ); - var bufferedReader = createObject( 'java', 'java.io.BufferedReader' ).init( inputStreamReader ); - - // These two patterns need to be stripped off the output. - var exit = 'foo'; - var jobControl = 'bash: no job control in this shell'; - - var char = bufferedReader.read(); - var token = ''; - while( char != -1 ){ - token &= chr( char ); - - // Only output if we arent matching any of the forbidden patterns above. - if( !exit.startsWith( trim( token ) ) - && !jobControl.startsWith( trim( token ) ) - && !char == 13 - && !char == 10 ) { - // Build up our output - print - .text( token ) - .toConsole(); - - token = ''; - } - - char = bufferedReader.read(); - } // End of inputStream - - // Output any trailing text as long as it isn't a match - if( !trim( token ).startsWith( exit ) - && !trim( token ).startsWith( jobControl ) ) { - print - .text( trim( token ) ) - .toConsole(); - } - - } catch( any e ) { - logger.error( e.message & ' ' & e.detail, e.stacktrace ); - print.line( e.message & ' ' & e.detail, e.stacktrace ); - } finally { - // Make sure we always close the file or the process will never quit! - if( isDefined( 'bufferedReader' ) ) { - bufferedReader.close(); - } - } - } - var exitCode = process.waitFor(); - //thread action="join" name="#threadName#"; - */ if( exitCode != 0 ) { error( 'Command returned failing exit code [#exitCode#]' ); From 1c500dcd4553ad20fd2512d4f5a62f1c730b2e8d Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 9 Mar 2017 22:14:06 -0600 Subject: [PATCH 45/45] Bump for 3.6.0 build --- build/build.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/build.xml b/build/build.xml index 07394aa1c..8b4d7391a 100644 --- a/build/build.xml +++ b/build/build.xml @@ -16,8 +16,8 @@ External Dependencies: - - + +