From f729bbc2ece58700ce51728b635c1bdcc51dab0e Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 23 Feb 2016 21:29:55 -0800 Subject: [PATCH 001/129] Bump BE version to 3.1.0 --- build/build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build.xml b/build/build.xml index c2e8cd5bc..a37361c02 100644 --- a/build/build.xml +++ b/build/build.xml @@ -15,7 +15,7 @@ External Dependencies: - + From 29df721777b96cfa019a6625b539ae6df7d7783d Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 2 Mar 2016 13:44:58 -0600 Subject: [PATCH 002/129] COMMANDBOX-347 Fix CFML functions from recipes --- .../modules/system-commands/commands/recipe.cfc | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/cfml/system/modules/system-commands/commands/recipe.cfc b/src/cfml/system/modules/system-commands/commands/recipe.cfc index d990b81c4..2b66dd778 100644 --- a/src/cfml/system/modules/system-commands/commands/recipe.cfc +++ b/src/cfml/system/modules/system-commands/commands/recipe.cfc @@ -1,7 +1,7 @@ /** * The recipe commands allows you to execute a collection of CommandBox commands * usually in a file.boxr recipe file. CommandBox will iterate and execute each - * of the commands for you in succession. Lines that start with a # will be ignored as comments. + * of the commands for you in succession. Lines that start with a # followed by whitespace will be ignored as comments. * . * {code:bash} * recipe myRecipe.boxr @@ -81,8 +81,9 @@ component { for( var thisCommand in commands ){ thisCommand = trim( thisCommand ); - // Ignore blank lines and comments - if( !thisCommand.len() || thisCommand.startsWith( '##' ) ) { + // Ignore blank lines and comments. + // Comments are any line that starts with a hash followed by some form of whitespace. + if( !thisCommand.len() || reFindNoCase( '##\s', thisCommand ) ) { continue; } // Turn echo on @@ -96,12 +97,7 @@ component { print.line( thisCommand ); continue; } - - // Ignore blank lines and comments - if( !thisCommand.len() || thisCommand.startsWith( '##' ) ) { - continue; - } - + try{ // If echo is on, display the command if( isEcho ) { From 5781ac57e18c397f9a62b307084c87c411cab6ad Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 7 Mar 2016 17:21:31 -0600 Subject: [PATCH 003/129] COMMANDBOX-350 #resolve Exception in packageservice determining testbox slug runner --- src/CommandBox.json | 1 + .../testbox-commands/commands/testbox/run.cfc | 8 +- src/cfml/system/services/PackageService.cfc | 88 +++++++++---------- 3 files changed, 48 insertions(+), 49 deletions(-) create mode 100644 src/CommandBox.json diff --git a/src/CommandBox.json b/src/CommandBox.json new file mode 100644 index 000000000..9e26dfeeb --- /dev/null +++ b/src/CommandBox.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/cfml/system/modules/testbox-commands/commands/testbox/run.cfc b/src/cfml/system/modules/testbox-commands/commands/testbox/run.cfc index 722236e4b..bd3b75a4a 100644 --- a/src/cfml/system/modules/testbox-commands/commands/testbox/run.cfc +++ b/src/cfml/system/modules/testbox-commands/commands/testbox/run.cfc @@ -45,7 +45,6 @@ component { string testSpecs, string outputFile ){ - var runnerURL = ''; // If a URL is passed, used it if( left( arguments.runner, 4 ) == 'http' ) { @@ -53,8 +52,12 @@ component { // Otherwise, try to get one from box.json } else { runnerURL = packageService.getTestBoxRunner( getCWD(), arguments.runner ); + // Validate runner + if( !len( runnerURL ) ){ + return error( '(#arguments.runner#) it not a valid runner in your box.json. Runners found are: #packageService.readPackageDescriptor( getCWD() ).testbox.runner.toString()#' ); + } } - + // If we failed to find a URL, throw an error if( left( runnerURL, 4 ) != 'http' ) { return error( '[#runnerURL#] it not a valid URL, or does not match a runner slug in your box.json.' ); @@ -88,7 +91,6 @@ component { return error( 'Error executing tests: #CR# #e.message##CR##e.detail#' ); } - // Do we have an output file if( !isNull( arguments.outputFile ) ){ // This will make each directory canonical and absolute diff --git a/src/cfml/system/services/PackageService.cfc b/src/cfml/system/services/PackageService.cfc index 91829cd35..171dbe2d7 100644 --- a/src/cfml/system/services/PackageService.cfc +++ b/src/cfml/system/services/PackageService.cfc @@ -32,7 +32,7 @@ component accessors="true" singleton { /** * Checks to see if a box.json exists in a given directory - * @directory.hint The directory to examine + * @directory The directory to examine */ public function isPackage( required string directory ) { // If the packge has a box.json in the root... @@ -41,7 +41,7 @@ component accessors="true" singleton { /** * Returns the path to the package descriptor - * @directory.hint The directory that is the root of the package + * @directory The directory that is the root of the package */ public function getDescriptorPath( required string directory ) { return directory & '/box.json'; @@ -53,14 +53,14 @@ component accessors="true" singleton { * * @slug.ID Identifier of the packge to install. If no ID is passed, all dependencies in the CDW will be installed. * @slug.optionsUDF slugComplete - * @directory.hint The directory to install in. This will override the packages's box.json install dir if provided. - * @save.hint Save the installed package as a dependancy in box.json (if it exists) - * @saveDev.hint Save the installed package as a dev dependancy in box.json (if it exists) - * @production.hint When calling this command with no slug to install all dependencies, set this to true to ignore devDependencies. - * @currentWorkingDirectory.hint Root of the application (used for finding box.json) - * @verbose.hint If set, it will produce much more verbose information about the package installation - * @force.hint When set to true, it will force dependencies to be installed whether they already exist or not - * @packagePathRequestingInstallation.hint If installing smart dependencies packages (like ColdBox modules) that are capable of being nested, this is our current level + * @directory The directory to install in. This will override the packages's box.json install dir if provided. + * @save Save the installed package as a dependancy in box.json (if it exists) + * @saveDev Save the installed package as a dev dependancy in box.json (if it exists) + * @production When calling this command with no slug to install all dependencies, set this to true to ignore devDependencies. + * @currentWorkingDirectory Root of the application (used for finding box.json) + * @verbose If set, it will produce much more verbose information about the package installation + * @force When set to true, it will force dependencies to be installed whether they already exist or not + * @packagePathRequestingInstallation If installing smart dependencies packages (like ColdBox modules) that are capable of being nested, this is our current level **/ function installPackage( required string ID, @@ -494,10 +494,10 @@ component accessors="true" singleton { * Uninstalls a package and its dependencies * @slug.ID Identifier of the packge to uninstall. * @slug.optionsUDF slugComplete - * @directory.hint The directory to install in. This will override the packages's box.json install dir if provided. - * @save.hint Remove package as a dependancy in box.json (if it exists) - * @saveDev.hint Remove package as a dev dependancy in box.json (if it exists) - * @currentWorkingDirectory.hint Root of the application (used for finding box.json) + * @directory The directory to install in. This will override the packages's box.json install dir if provided. + * @save Remove package as a dependancy in box.json (if it exists) + * @saveDev Remove package as a dev dependancy in box.json (if it exists) + * @currentWorkingDirectory Root of the application (used for finding box.json) **/ function uninstallPackage( required string ID, @@ -615,12 +615,12 @@ component accessors="true" singleton { /** * Adds a dependency to a packge - * @currentWorkingDirectory.hint The directory that is the root of the package - * @packageName.hint Package to add a a dependency - * @version.hint Version of the dependency - * @installDirectory.hint The location that the package is installed to including the container folder. - * @installDirectoryIsDedicated.hint True if the package was placed in a dedicated folder - * @dev.hint True if this is a development depenency, false if it is a production dependency + * @currentWorkingDirectory The directory that is the root of the package + * @packageName Package to add a a dependency + * @version Version of the dependency + * @installDirectory The location that the package is installed to including the container folder. + * @installDirectoryIsDedicated True if the package was placed in a dedicated folder + * @dev True if this is a development depenency, false if it is a production dependency */ public function addDependency( required string currentWorkingDirectory, @@ -684,9 +684,9 @@ component accessors="true" singleton { /** * Removes a dependency from a packge if it exists - * @directory.hint The directory that is the root of the package - * @packageName.hint Package to add a a dependency - * @dev.hint True if this is a development depenency, false if it is a production dependency + * @directory The directory that is the root of the package + * @packageName Package to add a a dependency + * @dev True if this is a development depenency, false if it is a production dependency */ public function removeDependency( required string directory, required string packageName ) { // Get box.json, create empty if it doesn't exist @@ -719,8 +719,8 @@ component accessors="true" singleton { /** * Gets a TestBox runner URL from box.json with an optional slug to look up. If no slug is passed, the first runner will be used - * @directory.hint The directory that is the root of the package - * @slug.hint An optional runner slug to look for in the list of runners + * @directory The directory that is the root of the package + * @slug An optional runner slug to look for in the list of runners */ public function getTestBoxRunner( required string directory, string slug='' ) { // Get box.json, create empty if it doesn't exist @@ -731,17 +731,14 @@ component accessors="true" singleton { // If there is a slug and runners is an array, look it up if ( len( arguments.slug ) && isArray( runners ) ){ - for( var thisRunner in runners ){ - // Does the string passed in match the slug of this runner? - if( structKeyExists( thisRunner, arguments.runner ) ) { - runnerURL = thisRunner[ arguments.runner ]; - break; + // Does the string passed in match the slug of this runner? If so, return it + if( structKeyExists( thisRunner, arguments.slug ) ) { + return thisRunner[ arguments.slug ]; } } - - return runnerURL; - + // If we got here, we could not find slug, advice back with an empty runner + return ''; } // Just get the first one we can find @@ -760,12 +757,11 @@ component accessors="true" singleton { // We failed to find anything return ''; - } /** * Get the default package description, AKA box.json - * @defaults.hint A struct of default values to be merged into the empty, default document + * @defaults A struct of default values to be merged into the empty, default document */ public function newPackageDescriptor( struct defaults={} ) { @@ -785,7 +781,7 @@ component accessors="true" singleton { * Get the box.json as data from the passed directory location. * Any missing properties will be defaulted with our box.json template. * If you plan on writing the box.json back out to disk, use readPackageDescriptorRaw() instead. - * @directory.hint The directory to search for the box.json + * @directory The directory to search for the box.json */ struct function readPackageDescriptor( required directory ){ // Merge this JSON with defaults @@ -797,7 +793,7 @@ component accessors="true" singleton { * then we return an empty struct. This method will NOT default box.json properties * and will return JUST what was defined. Make sure you use existence checks when * using the returned data structure - * @directory.hint The directory to search for the box.json + * @directory The directory to search for the box.json */ struct function readPackageDescriptorRaw( required directory ){ @@ -821,8 +817,8 @@ component accessors="true" singleton { /** * Write the box.json data as a JSON file - * @JSONData.hint The JSON data to write to the file. Can be a struct, or the string JSON - * @directory.hint The directory to write the box.json + * @JSONData The JSON data to write to the file. Can be a struct, or the string JSON + * @directory The directory to write the box.json */ function writePackageDescriptor( required any JSONData, required directory ){ @@ -835,10 +831,10 @@ component accessors="true" singleton { /** * Return an array of all outdated depdendencies in a project. - * @directory.hint The directory of the package to start in - * @print.hint The print buffer used for command operation - * @verbose.hint Outputs additional information about each package as it is checked - * @includeSlugs.hint A commit-delimited list of slugs to include. Empty means include everything. + * @directory The directory of the package to start in + * @print The print buffer used for command operation + * @verbose Outputs additional information about each package as it is checked + * @includeSlugs A commit-delimited list of slugs to include. Empty means include everything. * * @return An array of structs of outdated dependencies */ @@ -913,7 +909,7 @@ component accessors="true" singleton { /** * Builds a struct of structs that represents the dependency hierarchy - * @directory.hint The directory of the package to start in + * @directory The directory of the package to start in */ function buildDependencyHierarchy( required directory ){ @@ -967,8 +963,8 @@ component accessors="true" singleton { /** * Dynamic completion for property name based on contents of box.json - * @directory.hint The package root - * @all.hint Pass false to ONLY suggest existing property names. True will suggest all possible box.json properties. + * @directory The package root + * @all Pass false to ONLY suggest existing property names. True will suggest all possible box.json properties. */ function completeProperty( required directory, all=false ) { var props = []; From a8705f0d5e6be8b4291ad55e8fcd64ed56dc11d6 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 8 Mar 2016 16:48:24 -0600 Subject: [PATCH 004/129] COMMANDBOX-351 Fix checking out sha1 hash --- src/cfml/system/endpoints/Git.cfc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cfml/system/endpoints/Git.cfc b/src/cfml/system/endpoints/Git.cfc index 164cad6c0..3f712ac54 100644 --- a/src/cfml/system/endpoints/Git.cfc +++ b/src/cfml/system/endpoints/Git.cfc @@ -66,8 +66,7 @@ component accessors="true" implements="IEndpoint" singleton { try { // Clone the repo locally into a temp folder var cloneCommand = Git.cloneRepository() - .setURI( GitURL ) - .setBranch( branch ) + .setURI( GitURL ) .setCloneSubmodules( true ) .setDirectory( localPath ) .setProgressMonitor( progressMonitor ); @@ -76,6 +75,9 @@ component accessors="true" implements="IEndpoint" singleton { local.result = secureCloneCommand( cloneCommand ) .call(); + // Checkout branch, tag, or commit hash. + local.result.checkout().setName( branch ).call(); + } catch( any var e ) { throw( message="Error Cloning Git repository", detail="#e.message#", type="endpointException"); } finally { From 2d6bc47f973f42cf1c72d5fd650d9b9fada68543 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 21 Mar 2016 09:44:11 -0500 Subject: [PATCH 005/129] COMMANDBOX-352 #resolve Missing 'models' namespace on model test creation --- .../coldbox-commands/templates/testing/ModelBDDContent.txt | 2 +- .../templates/testing/ModelBDDContentScript.txt | 2 +- .../coldbox-commands/templates/testing/ModelTestContent.txt | 2 +- .../templates/testing/ModelTestContentScript.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDContent.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDContent.txt index 9d5e907be..bbf7ff447 100644 --- a/src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDContent.txt +++ b/src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDContent.txt @@ -3,7 +3,7 @@ The base model test case will use the 'model' annotation as the instantiation pa and then create it, prepare it for mocking and then place it in the variables scope as 'model'. It is your responsibility to update the model annotation instantiation path and init your model. ---> - + diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDContentScript.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDContentScript.txt index 6c047d1b2..278fdba2a 100644 --- a/src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDContentScript.txt +++ b/src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDContentScript.txt @@ -3,7 +3,7 @@ * and then create it, prepare it for mocking and then place it in the variables scope as 'model'. It is your * responsibility to update the model annotation instantiation path and init your model. */ -component extends="coldbox.system.testing.BaseModelTest" model="|modelName|"{ +component extends="coldbox.system.testing.BaseModelTest" model="models.|modelName|"{ /*********************************** LIFE CYCLE Methods ***********************************/ diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/ModelTestContent.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/ModelTestContent.txt index 4966b4447..41994562f 100644 --- a/src/cfml/system/modules/coldbox-commands/templates/testing/ModelTestContent.txt +++ b/src/cfml/system/modules/coldbox-commands/templates/testing/ModelTestContent.txt @@ -3,7 +3,7 @@ * and then create it, prepare it for mocking and then place it in the variables scope as 'model'. It is your * responsibility to update the model annotation instantiation path and init your model. ---> - + diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/ModelTestContentScript.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/ModelTestContentScript.txt index dc6fa3f7b..c92c0d55c 100644 --- a/src/cfml/system/modules/coldbox-commands/templates/testing/ModelTestContentScript.txt +++ b/src/cfml/system/modules/coldbox-commands/templates/testing/ModelTestContentScript.txt @@ -3,7 +3,7 @@ * and then create it, prepare it for mocking and then place it in the variables scope as 'model'. It is your * responsibility to update the model annotation instantiation path and init your model. */ -component extends="coldbox.system.testing.BaseModelTest" model="|modelName|"{ +component extends="coldbox.system.testing.BaseModelTest" model="models.|modelName|"{ void function setup(){ super.setup(); From 24fef752516ad145aa18d95eb9133bd5392fa2e8 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Tue, 22 Mar 2016 10:34:08 -0500 Subject: [PATCH 006/129] COMMANDBOX-353 #resolve Creation of API Docs for internal CommandBox Core --- apidocs/box.json | 7 +------ apidocs/internal.cfm | 29 +++++++++++++++++++++++++++++ apidocs/server.json | 9 +++++++++ build/build.properties | 2 +- build/build.xml | 28 +++++++++++++++++++++++----- 5 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 apidocs/internal.cfm create mode 100644 apidocs/server.json diff --git a/apidocs/box.json b/apidocs/box.json index cb6ad0d33..596aafe8e 100644 --- a/apidocs/box.json +++ b/apidocs/box.json @@ -3,7 +3,6 @@ "version":"1.0.0", "slug":"commandbox-apidocs", "private":true, - "defaultPort":8989, "dependencies":{ "docbox":"https://github.com/Ortus-Solutions/DocBox/archive/v2.0.4.zip" }, @@ -12,9 +11,5 @@ }, "installPaths":{ "docbox":"docbox" - }, - "ignore":[ - "**/.*", - "tests" - ] + } } \ No newline at end of file diff --git a/apidocs/internal.cfm b/apidocs/internal.cfm new file mode 100644 index 000000000..9a675e25f --- /dev/null +++ b/apidocs/internal.cfm @@ -0,0 +1,29 @@ + + + + +try{ + docName = "CommandBox-APIDocs"; + docbox = new docBox.DocBox( + properties = { + projectTitle = "CommandBox Internal v#url.version#", + outputDir = url.path + } + ); + docbox.generate( + source = expandPath( "/commandbox/system" ), + mapping = "commandbox.system", + excludes = "system\/(modules)" + ); +} catch ( Any e ){ + writeOutput( e.message & e.detail ); + writeDump( "
" & e.stacktrace ); + abort; +} +
+ +

Command Internal API Docs Done!

+Go to Docs! +
\ No newline at end of file diff --git a/apidocs/server.json b/apidocs/server.json new file mode 100644 index 000000000..9267b9c85 --- /dev/null +++ b/apidocs/server.json @@ -0,0 +1,9 @@ +{ + "force":true, + "openbrowser":"false", + "web":{ + "http":{ + "port":8989 + } + } +} \ No newline at end of file diff --git a/build/build.properties b/build/build.properties index e47ad6fb2..fa6f36fa3 100644 --- a/build/build.properties +++ b/build/build.properties @@ -46,7 +46,7 @@ ortus.repoPRDURL=http://downloads.ortussolutions.com #apidocs properties dir.apidocs=../apidocs apidocs.port=8989 -url.apidocs=http://localhost:${apidocs.port}/index.cfm +url.apidocs=http://localhost:${apidocs.port} ### testwar settings ### default.cfengine=railo diff --git a/build/build.xml b/build/build.xml index a37361c02..5f72ce91a 100644 --- a/build/build.xml +++ b/build/build.xml @@ -393,22 +393,40 @@ External Dependencies: + - - - - + + + + + + + + + + + + + + + + + + From 81cdf3f69d89a125e62cbdd887b12a46b8b367fd Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 5 Apr 2016 14:19:41 -0500 Subject: [PATCH 007/129] COMMANDBOX-338 --- src/bin/box.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/bin/box.sh b/src/bin/box.sh index cafdb2e74..a706cd3c6 100755 --- a/src/bin/box.sh +++ b/src/bin/box.sh @@ -27,7 +27,7 @@ then fi # Prepare Java arguments -java_args='-client' +java_args=="$BOX_JAVA_ARGS -client" ############################################################################## ## OS SPECIFIC CLEANUP + ARGS @@ -42,7 +42,8 @@ CYGWIN*) Darwin) if [ -e /System/Library/Frameworks/JavaVM.framework ] then - java_args=' + java_args=" + $BOX_JAVA_ARGS -client -Dcom.apple.mrj.application.apple.menu.about.name=CommandBox -Dcom.apple.mrj.application.growbox.intrudes=false @@ -50,7 +51,7 @@ Darwin) -Xdock:name=CommandBox -Dfile.encoding=UTF-8 -Djava.awt.headless=true - ' + " fi ;; esac From aa18e4b2cb8805c5d11743ffcac78fb6568f6289 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 6 Apr 2016 17:01:46 -0500 Subject: [PATCH 008/129] COMMANDBOX-357 --- .../modules/system-commands/commands/tail.cfc | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/cfml/system/modules/system-commands/commands/tail.cfc b/src/cfml/system/modules/system-commands/commands/tail.cfc index 954a0967f..802918b0b 100644 --- a/src/cfml/system/modules/system-commands/commands/tail.cfc +++ b/src/cfml/system/modules/system-commands/commands/tail.cfc @@ -36,16 +36,30 @@ component { // move to the end of the file randomAccessFile.seek( position ); + // Was the last character a line feed. + // Remeber the CRLFs will be coming in reverse order + var lastLF = false; while( true ){ - + // stop looping if we have met our line limit or if end of file if ( position < 0 || lineCounter == arguments.lines ) { break; } var char = randomAccessFile.read(); - if ( char == 10 ) lineCounter += 1; + + // Only increment CRs that were preceeded by a LF + if ( char == 13 && !lastLF ) { + lineCounter += 1; + } + // Check for LF + if ( char == 10 ) { + lastLF=true; + lineCounter += 1; + } else { + lastLF=false; + } if ( char != -1 ) buffer.append( chr( char ) ); // move to the preceding character From b39c8609e4ae04b741caa0831b3059e663b86750 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 6 Apr 2016 17:03:10 -0500 Subject: [PATCH 009/129] COMMANDBOX-358 --- .../system-commands/commands/system-log.cfc | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/cfml/system/modules/system-commands/commands/system-log.cfc diff --git a/src/cfml/system/modules/system-commands/commands/system-log.cfc b/src/cfml/system/modules/system-commands/commands/system-log.cfc new file mode 100644 index 000000000..808c7ab55 --- /dev/null +++ b/src/cfml/system/modules/system-commands/commands/system-log.cfc @@ -0,0 +1,34 @@ +/** + * Outputs the path to the system log file + * . + * {code:bash} + * system-log + * {code} + * + * Combine with other commands to print the contents of the log to the console + * or open the log file in the default editor. + * . + * {code:bash} + * system-log | open + * system-log | cat + * system-log | tail + * {code} + **/ +component { + + /** + * @open Open the file + **/ + function run() { + + var system = createObject( "java", "java.lang.System" ); + var logFilePath = isNull( system.getProperty('cfml.cli.home') ) ? + system.getProperty( 'user.home' ) & "/.CommandBox/" : + system.getProperty( 'cfml.cli.home' ) + & "/logs/commandbox.log"; + + print.line( logFilePath ); + + } + +} \ No newline at end of file From 4f50f7f17e4ed7de704cdd4abb6ef4ff74d52ed8 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 6 Apr 2016 17:20:41 -0500 Subject: [PATCH 010/129] COMMANDBOX-335 --- .../commands/endpoint/register.cfc | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/cfml/system/modules/package-commands/commands/endpoint/register.cfc diff --git a/src/cfml/system/modules/package-commands/commands/endpoint/register.cfc b/src/cfml/system/modules/package-commands/commands/endpoint/register.cfc new file mode 100644 index 000000000..2047e2ed8 --- /dev/null +++ b/src/cfml/system/modules/package-commands/commands/endpoint/register.cfc @@ -0,0 +1,40 @@ +/** + * Registers a new user with an endpoint. The endpoint must be interactive. + * . + * {code:bash} + * endpoint register + * {code} + **/ +component { + + property name="EndpointService" inject="EndpointService"; + + /** + * @endpointName.hint Name of the endpoint for which to create the user + * @username.hint Username for this user + * @password.hint Password for this user + * @email.hint E-mail address + * @firstName.hint First name of the user + * @lastName.hint Last name of the user + **/ + function run( + required string endpointName, + required string username, + required string password, + required string email, + required string firstName, + required string lastName ) { + + try { + + endpointService.createEndpointUser( argumentCollection=arguments ); + + } catch( endpointException var e ) { + // This can include "expected" errors such as "Email already in use" + error( e.message, e.detail ); + } + + print.greenLine( 'User [#arguments.username#] created successfully in [#arguments.endpointName#]' ); + } + +} \ No newline at end of file From 81c01391842d71369344c4a9dbfece4c0f65aa97 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 6 Apr 2016 17:20:57 -0500 Subject: [PATCH 011/129] COMMANDBOX-336 --- .../commands/endpoint/login.cfc | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/cfml/system/modules/package-commands/commands/endpoint/login.cfc diff --git a/src/cfml/system/modules/package-commands/commands/endpoint/login.cfc b/src/cfml/system/modules/package-commands/commands/endpoint/login.cfc new file mode 100644 index 000000000..8ec98793a --- /dev/null +++ b/src/cfml/system/modules/package-commands/commands/endpoint/login.cfc @@ -0,0 +1,34 @@ +/** + * Authenticates a user with an endpoint. The endpoint must be interactive. + * . + * {code:bash} + * endpoint register + * {code} + **/ +component { + + property name="EndpointService" inject="EndpointService"; + + /** + * @endpointName.hint Name of the endpoint to log in to + * @username.hint Username for this user + * @password.hint Password for this user + **/ + function run( + required string endpointName, + required string username, + required string password ) { + + try { + + endpointService.loginEndpointUser( argumentCollection=arguments ); + + } catch( endpointException var e ) { + // This can include "expected" errors such as "Email already in use" + error( e.message, e.detail ); + } + + print.greenLine( 'User [#arguments.username#] authenticated successfully with [#arguments.endpointName#]' ); + } + +} \ No newline at end of file From 9327a617b6533dd43a52fa63d96f53969a0d5d01 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 6 Apr 2016 21:45:53 -0500 Subject: [PATCH 012/129] COMMANDBOX-336 --- .../commands/forgebox/apikey.cfc | 13 --------- .../commands/forgebox/credentials.cfc | 13 --------- .../commands/forgebox/login.cfc | 28 +++++++++++++++++++ .../commands/endpoint/login.cfc | 2 +- 4 files changed, 29 insertions(+), 27 deletions(-) delete mode 100644 src/cfml/system/modules/forgebox-commands/commands/forgebox/apikey.cfc delete mode 100644 src/cfml/system/modules/forgebox-commands/commands/forgebox/credentials.cfc create mode 100644 src/cfml/system/modules/forgebox-commands/commands/forgebox/login.cfc diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/apikey.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/apikey.cfc deleted file mode 100644 index dce2a8c4e..000000000 --- a/src/cfml/system/modules/forgebox-commands/commands/forgebox/apikey.cfc +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Description of command - **/ -component { - - /** - * - **/ - function run( ) { - print.line( "Command not implemented!" ); - } - -} \ No newline at end of file diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/credentials.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/credentials.cfc deleted file mode 100644 index dce2a8c4e..000000000 --- a/src/cfml/system/modules/forgebox-commands/commands/forgebox/credentials.cfc +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Description of command - **/ -component { - - /** - * - **/ - function run( ) { - print.line( "Command not implemented!" ); - } - -} \ No newline at end of file diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/login.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/login.cfc new file mode 100644 index 000000000..5021796cc --- /dev/null +++ b/src/cfml/system/modules/forgebox-commands/commands/forgebox/login.cfc @@ -0,0 +1,28 @@ +/** + * Authenticates a user with the ForgeBox endpoint. This command is a passthrough for the generic "endpoint login" command. + * . + * {code:bash} + * forgebox login + * {code} + **/ +component { + + /** + * @username.hint Username for this user + * @password.hint Password for this user + **/ + function run( + required string username, + required string password ) { + + // Default the endpointName + arguments.endpointName = 'forgebox'; + + // Defer to the generic command + command( 'endpoint login' ) + .params( argumentCollection=arguments ) + .run(); + + } + +} \ No newline at end of file diff --git a/src/cfml/system/modules/package-commands/commands/endpoint/login.cfc b/src/cfml/system/modules/package-commands/commands/endpoint/login.cfc index 8ec98793a..9a67078b2 100644 --- a/src/cfml/system/modules/package-commands/commands/endpoint/login.cfc +++ b/src/cfml/system/modules/package-commands/commands/endpoint/login.cfc @@ -2,7 +2,7 @@ * Authenticates a user with an endpoint. The endpoint must be interactive. * . * {code:bash} - * endpoint register + * endpoint login * {code} **/ component { From d8bc5e2c3a7002e51638614dcd619d6ca60781c0 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 6 Apr 2016 21:46:20 -0500 Subject: [PATCH 013/129] COMMANDBOX-335 --- .../commands/forgebox/register.cfc | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/register.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/register.cfc index dce2a8c4e..0c9f51691 100644 --- a/src/cfml/system/modules/forgebox-commands/commands/forgebox/register.cfc +++ b/src/cfml/system/modules/forgebox-commands/commands/forgebox/register.cfc @@ -1,13 +1,34 @@ /** - * Description of command + * Registers a new user with the Forgebox endpoint. This command is a passthrough for the generic "endpoint register" command. + * . + * {code:bash} + * forgebox register + * {code} **/ component { /** - * + * @username.hint Username for this user + * @password.hint Password for this user + * @email.hint E-mail address + * @firstName.hint First name of the user + * @lastName.hint Last name of the user **/ - function run( ) { - print.line( "Command not implemented!" ); + function run( + required string username, + required string password, + required string email, + required string firstName, + required string lastName ) { + + // Default the endpointName + arguments.endpointName = 'forgebox'; + + // Defer to the generic command + command( 'endpoint register' ) + .params( argumentCollection=arguments ) + .run(); + } } \ No newline at end of file From f684b6eb9564d77586dab08f865168145e70aa6d Mon Sep 17 00:00:00 2001 From: Dominic Watson Date: Mon, 11 Apr 2016 14:59:19 +0100 Subject: [PATCH 014/129] COMMANDBOX-360 Fix for double equals sign breaking nix shell script Tested on both a fedora and ubuntu based Linux distribution. The change to this file that introduced `JAVA_ARGS==...` broke the script in Linux. Using a single equals sign fixes the problem. --- src/bin/box.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bin/box.sh b/src/bin/box.sh index a706cd3c6..073d7bb76 100755 --- a/src/bin/box.sh +++ b/src/bin/box.sh @@ -27,7 +27,7 @@ then fi # Prepare Java arguments -java_args=="$BOX_JAVA_ARGS -client" +java_args="$BOX_JAVA_ARGS -client" ############################################################################## ## OS SPECIFIC CLEANUP + ARGS @@ -85,4 +85,4 @@ fi ############################################################################## exec "$java" $java_args cliloader.LoaderCLIMain "$@" -exit \ No newline at end of file +exit From cfdd4dea289d6eb7a616b5ad75dafc3424e4ab8b Mon Sep 17 00:00:00 2001 From: Dominic Watson Date: Mon, 11 Apr 2016 15:12:04 +0100 Subject: [PATCH 015/129] COMMANDBOX-361 Fixing permissions on box executable for linux distro users to be able to execute the file without sudo (these are the normal permissions used for /usr/bin/* binaries --- build/build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build.xml b/build/build.xml index 5f72ce91a..e36635b42 100644 --- a/build/build.xml +++ b/build/build.xml @@ -437,7 +437,7 @@ External Dependencies: - + From 1dc1a25c367c0ad42e9c353b9fe2557cc1f08c90 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 11 Apr 2016 16:33:27 -0500 Subject: [PATCH 016/129] Standardized semver formatting and naming --- src/cfml/system/util/SemanticVersion.cfc | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/cfml/system/util/SemanticVersion.cfc b/src/cfml/system/util/SemanticVersion.cfc index fa1cbb39f..9cf5e237c 100644 --- a/src/cfml/system/util/SemanticVersion.cfc +++ b/src/cfml/system/util/SemanticVersion.cfc @@ -5,7 +5,8 @@ www.coldbox.org | www.luismajano.com | www.ortussolutions.com ******************************************************************************** * @author Luis Majano & Brad Wood * Utility to parse and validate semantic versions -* Semantic version: major.minor.revision-alpha.1+build +* Semantic version: major.minor.revision-preReleaseID+build +* http://semver.org/ */ component singleton{ @@ -17,7 +18,7 @@ component singleton{ } function getDefaultsVersion() { - return { major = 1, minor = 0, revision = 0, beID = "", buildID = 0 }; + return { major = 1, minor = 0, revision = 0, preReleaseID = "", buildID = 0 }; } /** @@ -90,7 +91,7 @@ component singleton{ /** * Parse the semantic version. If no minor found, then 0. If not revision found, then 0. * If not Bleeding Edge bit, then empty. If not buildID, then 0 - * @return struct:{major,minor,revision,beid,buildid} + * @return struct:{major,minor,revision,preReleaseID,buildid} */ struct function parseVersion( required string version ){ var results = getDefaultsVersion(); @@ -99,9 +100,9 @@ component singleton{ results.buildID = find( "+", arguments.version ) ? listLast( arguments.version, "+" ) : '0'; // Remove build ID arguments.version = reReplace( arguments.version, "\+([^\+]*).$", "" ); - // Get BE ID Formalized Now we have major.minor.revision-alpha.1 - results.beID = find( "-", arguments.version ) ? listLast( arguments.version, "-" ) : ''; - // Remove beID + // Get preReleaseID Formalized Now we have major.minor.revision-alpha.1 + results.preReleaseID = find( "-", arguments.version ) ? listLast( arguments.version, "-" ) : ''; + // Remove preReleaseID arguments.version = reReplace( arguments.version, "\-([^\-]*).$", "" ); // Get Revision results.revision = getToken( arguments.version, 3, "." ); @@ -118,7 +119,7 @@ component singleton{ /** * Parse the incoming version string and conform it to semantic version. * If bleeding edge is not found it is omitted. - * @return string:{major.minor.revision.[beid]+buildid} + * @return string:{major.minor.revision[-preReleaseID]+buildid} */ string function parseVersionAsString( required string version ){ var sVersion = parseVersion( clean( trim( arguments.version ) ) ); @@ -128,21 +129,22 @@ component singleton{ /** * Parse the incoming version struct and output it as a string - * @return string:{major.minor.revision.[beid]+buildid} + * @return string:{major.minor.revision[-preReleaseID]+buildid} */ string function getVersionAsString( required struct sVersion ){ var defaultsVersion = getDefaultsVersion(); arguments.sVersion = defaultsVersion.append( arguments.sVersion ); - return ( "#sVersion.major#.#sVersion.minor#.#sVersion.revision#" & ( len( sVersion.beID ) ? "." & sVersion.beID : '' ) & "+#sVersion.buildID#" ); + return ( "#sVersion.major#.#sVersion.minor#.#sVersion.revision#" & ( len( sVersion.preReleaseID ) ? "-" & sVersion.preReleaseID : '' ) & "+#sVersion.buildID#" ); } /** * Verifies if the passed version string is in a pre-release state + * Pre-release is defined by the existance of a preRelease ID or a "0" major version */ boolean function isPreRelease( required string version ){ var pVersion = parseVersion( clean( trim( arguments.version ) ) ); - return len( pVersion.beID ) ? true : false; + return ( len( pVersion.preReleaseID ) || pVersion.major == 0 ) ? true : false; } /** From 239c0b47fe1b84df9622255c984c0efae29bbde9 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 12 Apr 2016 10:11:20 -0500 Subject: [PATCH 017/129] COMMANDBOX-362 Reduce cruft in error logs --- src/cfml/system/util/FileSystem.cfc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cfml/system/util/FileSystem.cfc b/src/cfml/system/util/FileSystem.cfc index 23cc478c1..301774a1c 100644 --- a/src/cfml/system/util/FileSystem.cfc +++ b/src/cfml/system/util/FileSystem.cfc @@ -114,7 +114,11 @@ component accessors="true" singleton { } } catch( any e ) { // Silently log this and we'll try a different method below - logger.error( '#e.message# #e.detail#' , e.stackTrace ); + if( e.message contains 'No application is associated with the specified file' ) { + logger.error( '#e.message# #e.detail#' ); + } else { + logger.error( '#e.message# #e.detail#' , e.stackTrace ); + } } // if we get here, then we don't support desktop awt class, most likely in headless mode. From 9aa2914ca73a86f30379f7521afcac62fdaff1dd Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 12 Apr 2016 10:12:03 -0500 Subject: [PATCH 018/129] COMMANDBOX-362 Improve messaging for connection failure --- src/cfml/system/util/ForgeBox.cfc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cfml/system/util/ForgeBox.cfc b/src/cfml/system/util/ForgeBox.cfc index e63dfd0f8..32d6d061e 100644 --- a/src/cfml/system/util/ForgeBox.cfc +++ b/src/cfml/system/util/ForgeBox.cfc @@ -276,11 +276,13 @@ or just add DEBUG to the root logger results.message = HTTPResults.errorDetail; if( len(HTTPResults.errorDetail) ){ results.error = true; } // Try to inflate JSON + if (isJSON(results.rawResponse)) { results.response = deserializeJSON(results.rawResponse,false); } else { - CommandBoxlogger.error( 'Something other than JSON returned', results.rawResponse ); - throw( "Uh-oh, ForgeBox returned something other than JSON. Check the logs.", 'forgebox' ); + var errorDetail = ( HTTPResults.errorDetail ?: '' ) & chr( 10 ) & ( HTTPResults.statuscode ?: HTTPResults.status_code ?: '' ); + CommandBoxlogger.error( 'Something other than JSON returned. #errorDetail#', 'Actual HTTP Response: ' & results.rawResponse ); + throw( 'Uh-oh, ForgeBox returned something other than JSON. Run "system-log | open" to see the full reponse.', 'forgebox', errorDetail ); } return results; From 67e82ed6865cc613535f12739e1d37ed1a7924c8 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 12 Apr 2016 10:13:53 -0500 Subject: [PATCH 019/129] COMMANDBOX-362 Typo --- src/cfml/system/util/ForgeBox.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfml/system/util/ForgeBox.cfc b/src/cfml/system/util/ForgeBox.cfc index 32d6d061e..8a98dc81f 100644 --- a/src/cfml/system/util/ForgeBox.cfc +++ b/src/cfml/system/util/ForgeBox.cfc @@ -282,7 +282,7 @@ or just add DEBUG to the root logger } else { var errorDetail = ( HTTPResults.errorDetail ?: '' ) & chr( 10 ) & ( HTTPResults.statuscode ?: HTTPResults.status_code ?: '' ); CommandBoxlogger.error( 'Something other than JSON returned. #errorDetail#', 'Actual HTTP Response: ' & results.rawResponse ); - throw( 'Uh-oh, ForgeBox returned something other than JSON. Run "system-log | open" to see the full reponse.', 'forgebox', errorDetail ); + throw( 'Uh-oh, ForgeBox returned something other than JSON. Run "system-log | open" to see the full response.', 'forgebox', errorDetail ); } return results; From 728a338876e7c94027f7e208a5626210baa680dd Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 12 Apr 2016 11:03:39 -0500 Subject: [PATCH 020/129] base Command cleanup --- src/cfml/system/BaseCommand.cfc | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/cfml/system/BaseCommand.cfc b/src/cfml/system/BaseCommand.cfc index 63f665ed2..4e0963c22 100644 --- a/src/cfml/system/BaseCommand.cfc +++ b/src/cfml/system/BaseCommand.cfc @@ -113,8 +113,7 @@ component accessors="true" singleton { /** * Use if if your command wants to give controlled feedback to the user without raising - * an actual exception which comes with a messy stack trace. "return" this command to stop execution of your command - * Alternativley, multuple errors can be printed by calling this method more than once prior to returning. + * an actual exception which comes with a messy stack trace. * Use clearPrintBuffer to wipe out any output accrued in the print buffer. * * return error( "We're sorry, but happy hour ended 20 minutes ago." ); @@ -136,8 +135,7 @@ component accessors="true" singleton { } /** - * Tells you if the error() method has been called on this command. Useful if you have several validation checks, and then want - * to return at the end if one of them failed. + * Tells you if the error() method has been called on this command. **/ function hasError() { return hasErrored; @@ -148,14 +146,20 @@ component accessors="true" singleton { * Useful for opening a new file for editing that was just created. **/ function openPath( path ) { - runCommand( "edit '#parser.escapeArg( arguments.path )#'" ); + // Defer to "open" command. + command( "open" ) + .params( arguments.path ) + .run(); } /** * This will open a URL in the user's browser **/ function openURL( theURL ) { - runCommand( "browse '#parser.escapeArg( arguments.theURL)#'" ); + // Defer to "browse" command. + command( "browse" ) + .params( arguments.theURL ) + .run(); } } \ No newline at end of file From 893e7a1f13fff1df46f0f207365077c151039ac3 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 12 Apr 2016 18:49:21 -0500 Subject: [PATCH 021/129] COMMANDBOX-359 new API format --- src/cfml/system/util/ForgeBox.cfc | 62 +++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/src/cfml/system/util/ForgeBox.cfc b/src/cfml/system/util/ForgeBox.cfc index 8a98dc81f..6122387d9 100644 --- a/src/cfml/system/util/ForgeBox.cfc +++ b/src/cfml/system/util/ForgeBox.cfc @@ -59,16 +59,16 @@ or just add DEBUG to the root logger - + var results = ""; // Invoke call - results = makeRequest(resource="json/types"); + results = makeRequest(resource="types"); // error if( results.error ){ - throw("Error making ForgeBox REST Call", 'forgebox', results.response.messages); + throw("Error making ForgeBox REST Call", 'forgebox', results.response.messages.toList() ); } return results.response.data; @@ -76,7 +76,7 @@ or just add DEBUG to the root logger - + if( isSimpleValue( variables.types ) OR arguments.force ){ @@ -88,7 +88,7 @@ or just add DEBUG to the root logger - + @@ -103,10 +103,10 @@ or just add DEBUG to the root logger }; // Invoke call - results = makeRequest(resource="json/entries",parameters=params); + results = makeRequest(resource="entries",parameters=params); // error if( results.error ){ - throw( "Error making ForgeBox REST Call", 'forgebox', results.response.messages ); + throw( "Error making ForgeBox REST Call", 'forgebox', results.response.messages.toList() ); } return results.response.data; @@ -120,11 +120,11 @@ or just add DEBUG to the root logger var results = ""; // Invoke call - results = makeRequest(resource="json/entry/#arguments.slug#"); + results = makeRequest(resource="entry/#arguments.slug#"); // error if( results.error ){ - throw( "Error making ForgeBox REST Call", 'forgebox', results.response.messages ); + throw( "Error making ForgeBox REST Call", 'forgebox', results.response.messages.toList() ); } return results.response.data; @@ -138,11 +138,11 @@ or just add DEBUG to the root logger var results = ""; // Invoke call - results = makeRequest(resource="json/slugcheck/#arguments.slug#"); + results = makeRequest(resource="slug-check/#arguments.slug#"); // error if( results.error ){ - throw( "Error making ForgeBox REST Call", 'forgebox', results.response.messages ); + throw( "Error making ForgeBox REST Call", 'forgebox', results.response.messages.toList() ); } return results.response.data; @@ -217,6 +217,46 @@ or just add DEBUG to the root logger return results.response.data; } + /** + * Publishes a package in ForgeBox + */ + function publish( + required string slug, + required string version, + required string boxJSON, + required string isStable=true, + string description='', + string installInstructions='', + string changeLog='', + required string APIToken ) { + + var body = { + slug : arguments.slug, + version : arguments.version, + boxJSON : arguments.boxJSON, + isStable : arguments.isStable, + description : arguments.description, + installInstructions : arguments.installInstructions, + changeLog : arguments.changeLog + }; + + var results = makeRequest( + resource = "publish", + headers = { + 'x-api-token' : arguments.APIToken, + 'Content-Type' : 'application/json' + }, + body = serializeJSON( body ), + method='post' ); + + // error + if( results.error ){ + throw( "Sorry, the package could not be published.", 'forgebox', arrayToList( results.response.messages ) ); + } + + return results.response.data; + } +
From 5dbe61c711a4493f595d5a5f95bd33007ba0327c Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 12 Apr 2016 18:49:49 -0500 Subject: [PATCH 022/129] COMMANDBOX-359 --- .../commands/forgebox/search.cfc | 10 +++++----- .../commands/forgebox/show.cfc | 19 +++++++++++-------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/search.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/search.cfc index 55cb595c6..98ff61ee8 100644 --- a/src/cfml/system/modules/forgebox-commands/commands/forgebox/search.cfc +++ b/src/cfml/system/modules/forgebox-commands/commands/forgebox/search.cfc @@ -30,19 +30,19 @@ component { print.line(); var activeCount = 0; - for( var entry in entries ) { + for( var entry in entries.results ) { if( val( entry.isactive ) && ( entry.title contains arguments.searchText - || entry.fname contains arguments.searchText - || entry.lname contains arguments.searchText + || entry.user.fname contains arguments.searchText + || entry.user.lname contains arguments.searchText || entry.typeName contains arguments.searchText || entry.summary contains arguments.searchText ) ) { activeCount++; print.blackOnWhite( ' #entry.title# ' ); - print.boldText( ' ( #entry.fname# #entry.lname# )' ); - print.boldGreenLine( ' #repeatString( '*', val( entry.entryRating ) )#' ); + print.boldText( ' ( #entry.user.fname# #entry.user.lname# )' ); + print.boldGreenLine( ' #repeatString( '*', val( entry.avgRating ) )#' ); print.line( 'Version: #entry.version#' ); print.line( 'Type: #entry.typeName#' ); print.line( 'Slug: "#entry.slug#"' ); diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/show.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/show.cfc index 895840a2f..e3b8ccc37 100644 --- a/src/cfml/system/modules/forgebox-commands/commands/forgebox/show.cfc +++ b/src/cfml/system/modules/forgebox-commands/commands/forgebox/show.cfc @@ -85,7 +85,11 @@ component aliases="show" { var entryData = forgebox.getEntry( orderBy ); slug = orderBy; } catch( any e ) { - error( 'Parameter [#orderBy#] isn''t a valid orderBy, type, or slug. Valid orderBys are [#lcase( listChangeDelims( forgeboxOrders.keyList(), ', ' ) )#] See possible types with "forgebox types".' ); + if( e.detail contains 'The entry slug sent is invalid' ) { + error( 'Parameter [#orderBy#] isn''t a valid orderBy, type, or slug. Valid orderBys are [#lcase( listChangeDelims( forgeboxOrders.keyList(), ', ' ) )#] See possible types with "forgebox types".' ); + } else { + rethrow; + } } } } @@ -114,9 +118,8 @@ component aliases="show" { // We might have gotten this above var entryData = entryData ?: forgebox.getEntry( slug ); - - // entrylink,createdate,lname,isactive,installinstructions,typename,version,hits,coldboxversion,sourceurl,slug,homeurl,typeslug, - // downloads,entryid,fname,changelog,updatedate,downloadurl,title,entryrating,summary,username,description,email + // numberOfRatings,boxjson,isActive,typeName,version,hits,sourceURL,slug,createdDate,typeSlug,downloads,updatedDate,entryID, + // ratings,versions,avgRating,downloadURL,changelog,installs,title,user,description,summary,homeURL if( !val( entryData.isActive ) ) { error( 'The ForgeBox entry [#entryData.title#] is inactive, we highly recommed NOT installing it or contact the author about it' ); @@ -124,16 +127,16 @@ component aliases="show" { print.line(); print.blackOnWhite( ' #entryData.title# ' ) - .boldText( ' ( #entryData.fname# #entryData.lname#, #entryData.email# )' ) - .boldGreenLine( ' #repeatString( '*', val( entryData.entryRating ) )#' ); + .boldText( ' ( #entryData.user.fname# #entryData.user.lname#, #entryData.user.email# )' ) + .boldGreenLine( ' #repeatString( '*', val( entryData.avgRating ) )#' ); print.line() .yellowLine( #formatterUtil.HTML2ANSI( entryData.description )# ) .line() .line( 'Type: #entryData.typeName#' ) .line( 'Slug: "#entryData.slug#"' ) .line( 'Summary: #entryData.summary#' ) - .line( 'Created On: #entryData.createdate#' ) - .line( 'Updated On: #entryData.updateDate#' ) + .line( 'Created On: #dateFormat( entryData.createdDate )#' ) + .line( 'Updated On: #dateFormat( entryData.updatedDate )#' ) .line( 'Version: #entryData.version#' ) .line( 'ForgeBox Views: #entryData.hits#' ) .line( 'Downloads: #entryData.downloads#' ) From 9e4caf6c18e5623da80ef17e60effbb35b28b4ba Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 12 Apr 2016 18:50:34 -0500 Subject: [PATCH 023/129] COMMANDBOX-337 --- src/cfml/system/endpoints/ForgeBox.cfc | 26 +++++++++++++- .../commands/forgebox/publish.cfc | 26 ++++++++++++++ .../commands/endpoint/publish.cfc | 34 +++++++++++++++++++ src/cfml/system/services/EndpointService.cfc | 32 +++++++++++++++-- 4 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 src/cfml/system/modules/forgebox-commands/commands/forgebox/publish.cfc create mode 100644 src/cfml/system/modules/package-commands/commands/endpoint/publish.cfc diff --git a/src/cfml/system/endpoints/ForgeBox.cfc b/src/cfml/system/endpoints/ForgeBox.cfc index e55f5f35e..a037b9bb0 100644 --- a/src/cfml/system/endpoints/ForgeBox.cfc +++ b/src/cfml/system/endpoints/ForgeBox.cfc @@ -17,6 +17,7 @@ component accessors="true" implements="IEndpointInteractive" singleton { property name="semanticVersion" inject="semanticVersion"; property name="artifactService" inject="ArtifactService"; property name="packageService" inject="packageService"; + property name="configService" inject="configService"; property name="fileSystemUtil" inject="FileSystem"; property name="fileEndpoint" inject="commandbox.system.endpoints.File"; @@ -123,7 +124,30 @@ component accessors="true" implements="IEndpointInteractive" singleton { } public function publish( required string path ) { - throw( 'Not implemented' ); + + if( !packageService.isPackage( arguments.path ) ) { + throw( 'Sorry but [#arguments.path#] isn''t a package.', 'endpointException', 'Please double check you''re in the correct directory or use "package init" to turn your directory into a package.' ); + } + + var boxJSON = packageService.readPackageDescriptor( arguments.path ); + + var props = {} + props.slug = boxJSON.slug; + props.version = boxJSON.version; + props.boxJSON = serializeJSON( boxJSON ); + props.isStable = !semanticVersion.isPreRelease( boxJSON.version ); + props.description = boxJSON.description; + props.installInstructions = boxJSON.instructions; + props.changeLog = boxJSON.changeLog; + props.APIToken = configService.getSetting( 'endpoints.forgebox.APIToken', '' ); + + try { + forgebox.publish( argumentCollection=props ); + + } catch( forgebox var e ) { + // This can include "expected" errors such as "User not authenticated" + throw( e.message, 'endpointException', e.detail ); + } } diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/publish.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/publish.cfc new file mode 100644 index 000000000..677a73e6d --- /dev/null +++ b/src/cfml/system/modules/forgebox-commands/commands/forgebox/publish.cfc @@ -0,0 +1,26 @@ +/** + * Publishes a package with the ForgeBox endpoint. This command is a passthrough for the generic "endpoint publish" command. + * . + * {code:bash} + * forgebox publish + * {code} + **/ +component aliases="publish" { + + /** + * @username.hint Username for this user + **/ + function run( + string directory='' ) { + + // Default the endpointName + arguments.endpointName = 'forgebox'; + + // Defer to the generic command + command( 'endpoint publish' ) + .params( argumentCollection=arguments ) + .run(); + + } + +} \ No newline at end of file diff --git a/src/cfml/system/modules/package-commands/commands/endpoint/publish.cfc b/src/cfml/system/modules/package-commands/commands/endpoint/publish.cfc new file mode 100644 index 000000000..2caa28c07 --- /dev/null +++ b/src/cfml/system/modules/package-commands/commands/endpoint/publish.cfc @@ -0,0 +1,34 @@ +/** + * Publishes a package with an endpoint. The endpoint must be interactive. + * . + * {code:bash} + * endpoint publish + * {code} + **/ +component { + + property name="EndpointService" inject="EndpointService"; + + /** + * @endpointName.hint Name of the endpoint for which to publish the package + * @username.hint Username for this user + **/ + function run( + required string endpointName, + string directory='' ) { + // This will make each directory canonical and absolute + arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); + + try { + + endpointService.publishEndpointPackage( argumentCollection=arguments ); + + } catch( endpointException var e ) { + // This can include "expected" errors such as "Email already in use" + error( e.message, e.detail ); + } + + print.greenLine( 'Package published successfully in [#arguments.endpointName#]' ); + } + +} \ No newline at end of file diff --git a/src/cfml/system/services/EndpointService.cfc b/src/cfml/system/services/EndpointService.cfc index ac9718c35..cf1c181ec 100644 --- a/src/cfml/system/services/EndpointService.cfc +++ b/src/cfml/system/services/EndpointService.cfc @@ -195,9 +195,9 @@ component accessors="true" singleton { // Confirm is interactive endpoint if( !isInstanceOf( endpoint, 'IEndpointInteractive' ) ) { - throw( "Sorry, the endpoint [#arguments.endpointName#] does not support registering users.", 'endpointException' ); } + throw( "Sorry, the endpoint [#arguments.endpointName#] does not support logging in users.", 'endpointException' ); } - // Create the user + // Login the user var APIToken = endpoint.login( argumentCollection=arguments ); // Store the APIToken @@ -205,4 +205,32 @@ component accessors="true" singleton { } + /** + * A facade to publish a user with an interactive endpoint. Keeping this logic here so I can standardize the storage + * of the APIToken and make it reusable outside of the command. + */ + function publishEndpointPackage( + required string endpointName, + required string directory + ) { + // Get all endpoints that are registered + var endpointRegistry = getEndpointRegistry(); + // Confirm endpoint name exists + if( !endpointRegistry.keyExists( arguments.endpointName ) ) { + throw( "Sorry, the endpoint [#arguments.endpointName#] doesn't exist. Valid names are [#endpointRegistry.keyList()#]", 'endpointException' ); + } + + // Get endpoint object + var endpoint = getEndpoint( arguments.endpointName ); + + // Confirm is interactive endpoint + if( !isInstanceOf( endpoint, 'IEndpointInteractive' ) ) { + throw( "Sorry, the endpoint [#arguments.endpointName#] does not support publishing packages users.", 'endpointException' ); } + + arguments.path = arguments.directory; + // Publish the package + endpoint.publish( argumentCollection=arguments ); + + } + } \ No newline at end of file From 08ca0c9dd3df42f476c3352163b6c849d81eed48 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 12 Apr 2016 23:38:58 -0500 Subject: [PATCH 024/129] COMMANDBOX-359 --- .../modules/package-commands/commands/package/install.cfc | 5 +++-- .../modules/package-commands/commands/package/uninstall.cfc | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/cfml/system/modules/package-commands/commands/package/install.cfc b/src/cfml/system/modules/package-commands/commands/package/install.cfc index be85bce2c..77d38c28e 100644 --- a/src/cfml/system/modules/package-commands/commands/package/install.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/install.cfc @@ -156,9 +156,9 @@ component aliases="install" { var result = []; // Cache in command if( !structKeyExists( variables, 'entries' ) ) { - variables.entries = forgebox.getEntries(); + variables.entries = forgebox.getEntries().results; } - + // Loop over results and append all active ForgeBox entries for( var entry in variables.entries ) { if( val( entry.isactive ) ) { @@ -170,3 +170,4 @@ component aliases="install" { } } + diff --git a/src/cfml/system/modules/package-commands/commands/package/uninstall.cfc b/src/cfml/system/modules/package-commands/commands/package/uninstall.cfc index a9df1763f..9185dc56f 100644 --- a/src/cfml/system/modules/package-commands/commands/package/uninstall.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/uninstall.cfc @@ -73,7 +73,7 @@ component aliases="uninstall" { var result = []; // Cache in command if( !structKeyExists( variables, 'entries' ) ) { - variables.entries = forgebox.getEntries(); + variables.entries = forgebox.getEntries().results; } // Loop over results and append all active ForgeBox entries From 64c54807d5943f665bf4077b5ec916dbbaccb381 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 12 Apr 2016 23:42:13 -0500 Subject: [PATCH 025/129] COMMANDBOX-364 --- src/cfml/system/endpoints/ForgeBox.cfc | 65 +++++++++----------- src/cfml/system/endpoints/HTTP.cfc | 2 + src/cfml/system/services/ArtifactService.cfc | 40 +++++++++--- 3 files changed, 64 insertions(+), 43 deletions(-) diff --git a/src/cfml/system/endpoints/ForgeBox.cfc b/src/cfml/system/endpoints/ForgeBox.cfc index a037b9bb0..fac9b44da 100644 --- a/src/cfml/system/endpoints/ForgeBox.cfc +++ b/src/cfml/system/endpoints/ForgeBox.cfc @@ -18,6 +18,7 @@ component accessors="true" implements="IEndpointInteractive" singleton { property name="artifactService" inject="ArtifactService"; property name="packageService" inject="packageService"; property name="configService" inject="configService"; + property name="endpointService" inject="endpointService"; property name="fileSystemUtil" inject="FileSystem"; property name="fileEndpoint" inject="commandbox.system.endpoints.File"; @@ -30,37 +31,19 @@ component accessors="true" implements="IEndpointInteractive" singleton { } public string function resolvePackage( required string package, boolean verbose=false ) { - var entryData = {}; var slug = parseSlug( arguments.package ); var version = parseVersion( arguments.package ); // If we have a specific version and it exists in artifacts, use it. Otherwise, to ForgeBox!! if( semanticVersion.isExactVersion( version ) && artifactService.artifactExists( slug, version ) ) { - consoleLogger.info( "Package found in local artifacts!"); + consoleLogger.info( "Package found in local artifacts!"); + // Install the package + var thisArtifactPath = artifactService.getArtifactPath( slug, version ); + // Defer to file endpoint + return fileEndpoint.resolvePackage( thisArtifactPath, arguments.verbose ); } else { - entryData = getPackage( slug, version, arguments.verbose ); - version = entryData.version; - } - - // Assert: at this point, the package is downloaded and exists in the local artifact cache - - // Install the package - var thisArtifactPath = artifactService.getArtifactPath( slug, version ); - - // Defer to file endpoint - packagePath = fileEndpoint.resolvePackage( thisArtifactPath, arguments.verbose ); - - // Cheat for people who set a version, slug, or type in ForgeBox, but didn't put it in their box.json - // We can only do this if we talked to ForgeBox, but I'm trying hard not to use network IO if I can get the package from artifacts. - if( structCount( entryData ) ) { - var boxJSON = packageService.readPackageDescriptorRaw( packagePath ); - if( !structKeyExists( boxJSON, 'type' ) || !len( boxJSON.type ) ) { boxJSON.type = entryData.typeslug; } - if( !structKeyExists( boxJSON, 'slug' ) || !len( boxJSON.slug ) ) { boxJSON.slug = entryData.slug; } - if( !structKeyExists( boxJSON, 'version' ) || !len( boxJSON.version ) ) { boxJSON.version = entryData.version; } - packageService.writePackageDescriptor( boxJSON, packagePath ); + return getPackage( slug, version, arguments.verbose ); } - return packagePath; - } public function getDefaultName( required string package ) { @@ -189,31 +172,41 @@ component accessors="true" implements="IEndpointInteractive" singleton { // If the local artifact doesn't exist, download and create it if( !artifactService.artifactExists( slug, version ) ) { - consoleLogger.info( "Starting download of: '#slug#'..." ); + // Test package location to see what endpoint we can refer to. + var endpointData = endpointService.resolveEndpoint( entryData.downloadURL, 'fakePath' ); - // Store the package locally in the temp dir - var packageTempPath = forgebox.install( slug, tempDir ); + consoleLogger.info( "Deferring to [#endpointData.endpointName#] endpoint for ForgeBox entry [#slug#]..." ); - // Store it locally in the artfact cache - artifactService.createArtifact( slug, version, packageTempPath ); - - // Clean up the temp file - fileDelete( packageTempPath ); + var packagePath = endpointData.endpoint.resolvePackage( endpointData.package, arguments.verbose ); + // Cheat for people who set a version, slug, or type in ForgeBox, but didn't put it in their box.json + var boxJSON = packageService.readPackageDescriptorRaw( packagePath ); + if( !structKeyExists( boxJSON, 'type' ) || !len( boxJSON.type ) ) { boxJSON.type = entryData.typeslug; } + if( !structKeyExists( boxJSON, 'slug' ) || !len( boxJSON.slug ) ) { boxJSON.slug = entryData.slug; } + if( !structKeyExists( boxJSON, 'version' ) || !len( boxJSON.version ) ) { boxJSON.version = entryData.version; } + packageService.writePackageDescriptor( boxJSON, packagePath ); + + consoleLogger.info( "Storing download in artifact cache..." ); + + // Store it locally in the artfact cache + artifactService.createArtifact( slug, version, packagePath ); + consoleLogger.info( "Done." ); + return packagePath; + } else { consoleLogger.info( "Package found in local artifacts!"); + var thisArtifactPath = artifactService.getArtifactPath( slug, version ); + // Defer to file endpoint + return fileEndpoint.resolvePackage( thisArtifactPath, arguments.verbose ); } } catch( forgebox var e ) { // This can include "expected" errors such as "slug not found" throw( '#e.message##CR##e.detail#', 'endpointException' ); - } - - return entryData; - + } } private function parseSlug( required string package ) { diff --git a/src/cfml/system/endpoints/HTTP.cfc b/src/cfml/system/endpoints/HTTP.cfc index dcead369f..6ecf863ee 100644 --- a/src/cfml/system/endpoints/HTTP.cfc +++ b/src/cfml/system/endpoints/HTTP.cfc @@ -31,6 +31,8 @@ component accessors=true implements="IEndpoint" singleton { var fileName = 'temp#randRange( 1, 1000 )#.zip'; var fullPath = tempDir & '/' & fileName; + consoleLogger.info( "Downloading [#getNamePrefixes() & ':' & package#]" ); + try { // Download File var result = progressableDownloader.download( diff --git a/src/cfml/system/services/ArtifactService.cfc b/src/cfml/system/services/ArtifactService.cfc index c1138131f..c6d84d5b2 100644 --- a/src/cfml/system/services/ArtifactService.cfc +++ b/src/cfml/system/services/ArtifactService.cfc @@ -140,18 +140,23 @@ component accessors="true" singleton { * * @packageName.hint The package name to look for * @version.hint The version of the package to look for - * @packageZip.hint A file path to a local zip file that contains the package + * @packagePath.hint A file path to a local zip file that contains the package */ - ArtifactService function createArtifact( required packageName, required version, required packageZip ) { + ArtifactService function createArtifact( required packageName, required version, required packagePath ) { + + // If we were given a folder, defer to another method + if( directoryExists( arguments.packagePath ) ) { + return createArtifactFromFolder( arguments.packageName, arguments.version, arguments.packagePath ); + } // Validate the package path - if( !fileExists( arguments.packageZip ) ) { - throw( 'Cannot create artifact [#arguments.packageName#], the file doesn''t exist', arguments.packageZip ); + if( !fileExists( arguments.packagePath ) ) { + throw( 'Cannot create artifact [#arguments.packageName#], the file doesn''t exist', arguments.packagePath ); } // Validate the package is a zip - if( right( arguments.packageZip, 4 ) != '.zip' ) { - throw( 'Cannot create artifact [#arguments.packageName#], the file isn''t a zip', arguments.packageZip ); + if( right( arguments.packagePath, 4 ) != '.zip' ) { + throw( 'Cannot create artifact [#arguments.packageName#], the file isn''t a zip', arguments.packagePath ); } // Where will this artifact live? @@ -161,7 +166,28 @@ component accessors="true" singleton { directorycreate( getDirectoryFromPath( thisArtifactPath ), true, true ); // Here's your new home - fileCopy( arguments.packageZip, thisArtifactPath ); + fileCopy( arguments.packagePath, thisArtifactPath ); + + return this; + } + + /** + * Store a package in the artifact cache. + * This expects that the package is already downloaded and stored somewhere on the local filesystem. + * + * @packageName.hint The package name to look for + * @version.hint The version of the package to look for + * @packageFolder.hint A file path to a local folder that contains the package + */ + private function createArtifactFromFolder( required packageName, required version, required packageFolder ) { + + // Where will this artifact live? + var thisArtifactPath = getArtifactPath( arguments.packageName, arguments.version ); + + // Create dir if it doesn't exist + directorycreate( getDirectoryFromPath( thisArtifactPath ), true, true ); + + zip action='zip' source=arguments.packageFolder file=thisArtifactPath; return this; } From 1d3fe628a88c0f66bdbb9935170be8e3e488d3e6 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 13 Apr 2016 00:41:31 -0500 Subject: [PATCH 026/129] COMMANDBOX-359 --- .../modules/forgebox-commands/commands/forgebox/show.cfc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/show.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/show.cfc index e3b8ccc37..7f8843e1b 100644 --- a/src/cfml/system/modules/forgebox-commands/commands/forgebox/show.cfc +++ b/src/cfml/system/modules/forgebox-commands/commands/forgebox/show.cfc @@ -155,12 +155,12 @@ component aliases="show" { print.line(); var activeCount = 0; - for( var entry in entries ) { + for( var entry in entries.results ) { if( val( entry.isactive ) ) { activeCount++; print.blackOnWhite( ' #entry.title# ' ); - print.boldText( ' ( #entry.fname# #entry.lname# )' ); - print.boldGreenLine( ' #repeatString( '*', val( entry.entryRating ) )#' ); + print.boldText( ' ( #entry.user.fname# #entry.user.lname# )' ); + print.boldGreenLine( ' #repeatString( '*', val( entry.avgRating ) )#' ); print.line( 'Type: #entry.typeName#' ); print.line( 'Slug: "#entry.slug#"' ); print.Yellowline( '#left( entry.summary, 200 )#' ); From dc3c6f2ae0c940e5802085a32fe121a1769b3dbe Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 13 Apr 2016 00:43:15 -0500 Subject: [PATCH 027/129] OMMANDBOX-337 --- src/cfml/system/endpoints/ForgeBox.cfc | 23 ++++++++++++++++++++++- src/cfml/system/util/ForgeBox.cfc | 8 +++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/cfml/system/endpoints/ForgeBox.cfc b/src/cfml/system/endpoints/ForgeBox.cfc index fac9b44da..9827858c8 100644 --- a/src/cfml/system/endpoints/ForgeBox.cfc +++ b/src/cfml/system/endpoints/ForgeBox.cfc @@ -120,10 +120,31 @@ component accessors="true" implements="IEndpointInteractive" singleton { props.boxJSON = serializeJSON( boxJSON ); props.isStable = !semanticVersion.isPreRelease( boxJSON.version ); props.description = boxJSON.description; + props.descriptionFormat = 'text'; props.installInstructions = boxJSON.instructions; + props.installInstructionsFormat = 'text'; props.changeLog = boxJSON.changeLog; + props.changeLogFormat = 'text'; props.APIToken = configService.getSetting( 'endpoints.forgebox.APIToken', '' ); - + + // Look for readme, instruction, and changelog files + for( var item in [ + { variable : 'description', file : 'readme' }, + { variable : 'installInstructions', file : 'instructions' }, + { variable : 'changelog', file : 'changelog' } + ] ) { + // Check for no ext or .txt or .md in reverse precendence. + for( var ext in [ '', '.txt', '.md' ] ) { + // Case insensitive search for file name + var files = directoryList(path=arguments.path,filter=function( path ){ return path contains ( item.file & ext); } ) + if( arrayLen( files ) ) { + // If found, read in the first one found. + props[ item.variable ] = fileRead( files[ 1 ] ); + props[ item.variable & 'Format' ] = ( ext == '.md' ? 'md' : 'text' ); + } + } + } + try { forgebox.publish( argumentCollection=props ); diff --git a/src/cfml/system/util/ForgeBox.cfc b/src/cfml/system/util/ForgeBox.cfc index 6122387d9..b8c527bca 100644 --- a/src/cfml/system/util/ForgeBox.cfc +++ b/src/cfml/system/util/ForgeBox.cfc @@ -226,8 +226,11 @@ or just add DEBUG to the root logger required string boxJSON, required string isStable=true, string description='', + string descriptionFormat='text', string installInstructions='', + string installInstructionsFormat='text', string changeLog='', + string changeLogFormat='text', required string APIToken ) { var body = { @@ -236,8 +239,11 @@ or just add DEBUG to the root logger boxJSON : arguments.boxJSON, isStable : arguments.isStable, description : arguments.description, + descriptionFormat : arguments.descriptionFormat, installInstructions : arguments.installInstructions, - changeLog : arguments.changeLog + installInstructionsFormat : arguments.installInstructionsFormat, + changeLog : arguments.changeLog, + changeLogFormat : arguments.changeLogFormat }; var results = makeRequest( From 721557dd05031e0a759ae9dd3652fd4ed2e77d2f Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 13 Apr 2016 02:14:14 -0500 Subject: [PATCH 028/129] COMMANDBOX-337 target install versions --- src/cfml/system/endpoints/ForgeBox.cfc | 38 ++++++++++++++++----- src/cfml/system/util/SemanticVersion.cfc | 43 ++++++++++++++++++++++-- 2 files changed, 70 insertions(+), 11 deletions(-) diff --git a/src/cfml/system/endpoints/ForgeBox.cfc b/src/cfml/system/endpoints/ForgeBox.cfc index 9827858c8..2f7309c4f 100644 --- a/src/cfml/system/endpoints/ForgeBox.cfc +++ b/src/cfml/system/endpoints/ForgeBox.cfc @@ -162,10 +162,9 @@ component accessors="true" implements="IEndpointInteractive" singleton { try { // Info consoleLogger.warn( "Verifying package '#slug#' in ForgeBox, please wait..." ); - - // TODO: Check ForgeBox for highest version that satisfies what was requested. - + var entryData = forgebox.getEntry( slug ); + // Verbose info if( arguments.verbose ){ consoleLogger.debug( "Package data retrieved: ", entryData ); @@ -182,14 +181,35 @@ component accessors="true" implements="IEndpointInteractive" singleton { throw( 'No download URL provided in ForgeBox. Manual install only.', 'endpointException' ); } + entryData.versions.sort( function( a, b ) { return 0-semanticVersion.compare( a.version, b.version ) } ); + + var found = false; + for( var thisVersion in entryData.versions ) { + if( semanticVersion.satisfies( thisVersion.version, arguments.version ) ) { + arguments.version = thisVersion.version; + found = true; + break; + } + } + + if( !found ) { + // If we requsted stable and all releases are pre-release, just grab the latest + if( arguments.version == 'stable' && arrayLen( entryData.versions ) ) { + arguments.version = entryData.versions[ 1 ].version; + } else { + throw( 'Version [#arguments.version#] not found for package [#arguments.slug#].', 'endpointException' ); + } + } + + consoleLogger.info( "Installing version [#arguments.version#]." ); + + // entryData.versions.each( function( i ) { systemOutput( i.version, true ); } ); + var packageType = entryData.typeSlug; - version = entryData.version; // Advice we found it consoleLogger.info( "Verified entry in ForgeBox: '#slug#'" ); - - arguments.version = entryData.version; - + // If the local artifact doesn't exist, download and create it if( !artifactService.artifactExists( slug, version ) ) { @@ -235,10 +255,10 @@ component accessors="true" implements="IEndpointInteractive" singleton { } private function parseVersion( required string package ) { - var version = ''; + var version = 'stable'; // foo@1.0.0 if( arguments.package contains '@' ) { - // Note this can also be a semvar range like 1.2.x, >2.0.0, or 1.0.4-2.x + // Note this can also be a semver range like 1.2.x, >2.0.0, or 1.0.4-2.x // For now I'm assuming it's a specific version version = listRest( arguments.package, '@' ); } diff --git a/src/cfml/system/util/SemanticVersion.cfc b/src/cfml/system/util/SemanticVersion.cfc index 9cf5e237c..8e8256b27 100644 --- a/src/cfml/system/util/SemanticVersion.cfc +++ b/src/cfml/system/util/SemanticVersion.cfc @@ -21,6 +21,26 @@ component singleton{ return { major = 1, minor = 0, revision = 0, preReleaseID = "", buildID = 0 }; } + function compare( + required string current, + required string target, + boolean checkBuildID=true ) { + + // versions are identical + if( isEQ( arguments.current, arguments.target ) ) { + return 0; + } + + // first is 'smaller' than the second + if( isNew( arguments.current, arguments.target ) ) { + return -1; + // first is 'larger' than the second + } else { + return 1; + } + + } + /** * Checks if target version is a newer semantic version than the passed current version * Note: To confirm to semvar, I think this needs to defer to gt(). @@ -58,13 +78,23 @@ component singleton{ return true; } + // pre-release Check + if( target.major eq current.major AND + target.minor eq current.minor AND + target.revision eq current.revision AND + // preReleaseID is either alphabetically higher, or target has no prereleaes id and current does. + ( target.preReleaseID gt current.preReleaseID || ( !len( target.preReleaseID ) && len( current.preReleaseID ) ) ) ) { + return true; + } + // BuildID verification is turned on? if( !arguments.checkBuildID ){ return false; } // Build Check if( target.major eq current.major AND target.minor eq current.minor AND - target.revision eq current.revision AND + target.revision eq current.revision AND + target.preReleaseID eq current.preReleaseID AND target.buildID gt current.buildID ){ return true; } @@ -84,7 +114,16 @@ component singleton{ * */ boolean function satisfies( required string version, required string range ){ - // TODO: This is just a quick fix. The satisfies() method needs actually implemented to handle ranges + // TODO: This is just a quick fix. The satisfies() method needs actually implemented to handle ranges + + if( range == 'be' ) { + return true; + } + + if( range == 'stable' && !isPreRelease( version ) ) { + return true; + } + return isEQ( arguments.version, arguments.range ); } From bd6635e7b6a57031eb96d81ae3908dab328439a5 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 14 Apr 2016 04:15:53 -0500 Subject: [PATCH 029/129] COMMANDBOX-366 Semantic version --- src/cfml/system/util/SemanticVersion.cfc | 428 +++++++++++++++++- tests/Application.cfc | 4 +- .../cfml/system/util/TestSemanticVersion.cfc | 262 +++++++++++ tests/runner.cfm | 2 +- 4 files changed, 669 insertions(+), 27 deletions(-) create mode 100644 tests/cfml/system/util/TestSemanticVersion.cfc diff --git a/src/cfml/system/util/SemanticVersion.cfc b/src/cfml/system/util/SemanticVersion.cfc index 8e8256b27..1ed835573 100644 --- a/src/cfml/system/util/SemanticVersion.cfc +++ b/src/cfml/system/util/SemanticVersion.cfc @@ -7,6 +7,7 @@ www.coldbox.org | www.luismajano.com | www.ortussolutions.com * Utility to parse and validate semantic versions * Semantic version: major.minor.revision-preReleaseID+build * http://semver.org/ +* https://github.com/npm/node-semver */ component singleton{ @@ -27,12 +28,12 @@ component singleton{ boolean checkBuildID=true ) { // versions are identical - if( isEQ( arguments.current, arguments.target ) ) { + if( isEQ( arguments.current, arguments.target, checkBuildID ) ) { return 0; } // first is 'smaller' than the second - if( isNew( arguments.current, arguments.target ) ) { + if( isNew( arguments.current, arguments.target, checkBuildID ) ) { return -1; // first is 'larger' than the second } else { @@ -58,8 +59,8 @@ component singleton{ Semantic version: major.minor.revision-alpha.1+build **/ - var current = parseVersion( clean( trim( arguments.current ) ) ); - var target = parseVersion( clean( trim( arguments.target ) ) ); + var current = parseVersion( arguments.current ); + var target = parseVersion( arguments.target ); // Major check if( target.major gt current.major ){ @@ -78,12 +79,17 @@ component singleton{ return true; } + // A little hacky, but less code than what I had. + // Basically, an empty pre release ID needs to sort AFTER a non-empty one. + if( !len( target.preReleaseID ) ) { target.preReleaseID = 'zzzzzzzzzzzzzzzzzz'; } + if( !len( current.preReleaseID ) ) { current.preReleaseID = 'zzzzzzzzzzzzzzzzzz'; } + // pre-release Check if( target.major eq current.major AND target.minor eq current.minor AND target.revision eq current.revision AND // preReleaseID is either alphabetically higher, or target has no prereleaes id and current does. - ( target.preReleaseID gt current.preReleaseID || ( !len( target.preReleaseID ) && len( current.preReleaseID ) ) ) ) { + target.preReleaseID gt current.preReleaseID ) { return true; } @@ -106,7 +112,8 @@ component singleton{ * Clean a version string from leading = or v */ string function clean( required version ){ - return reReplaceNoCase( arguments.version, "^(v|=)", "" ); + version = trim( version ); + return reReplaceNoCase( arguments.version, "^[=v]*", "" ); } /** @@ -114,7 +121,8 @@ component singleton{ * */ boolean function satisfies( required string version, required string range ){ - // TODO: This is just a quick fix. The satisfies() method needs actually implemented to handle ranges + + arguments.version = clean( arguments.version ); if( range == 'be' ) { return true; @@ -123,16 +131,374 @@ component singleton{ if( range == 'stable' && !isPreRelease( version ) ) { return true; } - + + // An array of comparator sets. At least one of the comparator sets needs to + // satisfy. Each comparator of a given comparator set must match for the set to pass. + var semverRange = buildRange( range ); + + // Only one of our comparatorSets in the range need to match + for( var comparatorSet in semverRange ) { + // If the version we're inspecting is a pre-release, don't consider it unless at least one comparator in this + // set specifically mentions a pre release matching this major.minor.revision. + if( isPreRelease( arguments.version ) && !interestedInPreReleasesOfThisVersion( comparatorSet, arguments.version ) ) { + continue; + } + var setResult = false; + // Each comparator in the set much match + for( var comparator in comparatorSet ) { + setResult = evaluateComparator( comparator, arguments.version ); + // Short circuit if at least one comparator in this set has failed + if( !setResult ) { break; } + } + // If this comparatorSet passed, we've seen all we need to see + if( setResult ) { return true; } + } + + // If we made it here, none of the comparatorSets in our range matched + return false; + + return isEQ( arguments.version, arguments.range ); } + + private function evaluateComparator( required struct comparator, version ) { + switch( comparator.operator ) { + case "<": + return isNew( arguments.version, comparator.version ); + break; + case "<=": + return isNew( arguments.version, comparator.version ) || isEq( comparator.version, arguments.version ); + break; + case ">": + return isNew( comparator.version, arguments.version ); + break; + case ">=": + return isNew( comparator.version, arguments.version ) || isEq( comparator.version, arguments.version ); + break; + case "=": + return isEq( comparator.version, arguments.version ); + break; + default: + return false; + } + } + + private function interestedInPreReleasesOfThisVersion( required array comparatorSet, required string version ) { + var sVersion = parseVersion( arguments.version ); + // Look at each comparator + for( var comparator in arguments.comparatorSet ) { + // And see if there is a pre release version that matches major.minor.revision + if( isPreRelease( comparator.version ) + && comparator.sVersion.major == sVersion.major + && comparator.sVersion.minor == sVersion.minor + && comparator.sVersion.revision == sVersion.revision) { + return true; + } + } + return false; + } + + private function buildRange( required string range ) { + // A character that I hope will never be part of an actual range so split easier. + // Comprator sets inside a range are delimited by " || " + arguments.range = replaceNoCase( arguments.range, ' || ', '•', 'all' ); + var semverRange = listToArray( arguments.range, '•' ); + + // An empty range becomes * + if( !arrayLen( semverRange ) ) { + semverRange = [ '*' ]; + } + + // Loop over each comparator set and parse + semverRange = semverRange.map( function( i ) { + return buildComparatorSet( i ); + } ); + + return semverRange; + } + + private function buildComparatorSet( required string set ) { + var comparatorSet = []; + + // Check for a hyphen range + if( set contains ' - ' ) { + set = replaceNoCase( set, ' - ', '•', 'all' ); + var lowerBound = listFirst( set, '•' ); + var upperBound = listLast( set, '•' ); + + lowerBound = replaceNoCase( lowerBound, '*', 'x', 'all' ); + upperBound = replaceNoCase( upperBound, '*', 'x', 'all' ); + + sVersion = parseVersion( lowerBound, 'x' ); + + comparatorSet.append( + expandXRanges( { + operator : '>=', + sVersion : sVersion, + version : getVersionAsString( sVersion ) + } ), + true + ); + + sVersion = parseVersion( upperBound, 'x' ); + + comparatorSet.append( + expandXRanges( { + operator : '<=', + sVersion : sVersion, + version : getVersionAsString( sVersion ) + } ), + true + ); + + return comparatorSet; + } + + // Comparators are delimited by whitespace + for( var comparator in listToArray( set, ' ' ) ) { + + // standardize * to x + comparator = replaceNoCase( comparator, '*', 'x', 'all' ); + // >=1.2.3 + if( comparator.startsWith( '>=' ) ) { + var version = right( comparator, len( comparator )-2 ); + var operator = '>='; + // <=1.2.3 + } else if( comparator.startsWith( '<=' ) ) { + var version = right( comparator, len( comparator )-2 ); + var operator = '<='; + // >1.2.3 + } else if( comparator.startsWith( '>' ) ) { + var version = right( comparator, len( comparator )-1 ); + var operator = '>'; + // <1.2.3 + } else if( comparator.startsWith( '<' ) ) { + var version = right( comparator, len( comparator )-1 ); + var operator = '<'; + // =1.2.3 + } else if( comparator.startsWith( '=' ) ) { + var operator = '='; + var version = right( comparator, len( comparator )-1 ); + // ~1.2.3 + } else if( comparator.startsWith( '~' ) ) { + var operator = '~'; + var version = right( comparator, len( comparator )-1 ); + // ^1.2.3 + } else if( comparator.startsWith( '^' ) ) { + var operator = '^'; + var version = right( comparator, len( comparator )-1 ); + // 1.2.3 + } else { + var version = comparator; + var operator = '='; + } + + // Missing bits become x. So 1.3 becomes 1.3.x + sVersion = parseVersion( version, 'x' ); + comparatorSet.append( + // Convert 1.x into multiple comparators + expandXRanges( { + operator : operator, + sVersion : sVersion, + version : getVersionAsString( sVersion ) + } ), + true + ); + + } + + return comparatorSet; + } + + private function expandXRanges( required struct sComparator ) { + var comparatorSet = []; + + switch( sComparator.operator ) { + case "<": + // <1.1.x becomes <1.1.0 + // <1.x becomes <1.0.0 + + if( sComparator.sVersion.major == 'x' ) { sComparator.sVersion.major = '0'; } + if( sComparator.sVersion.minor == 'x' ) { sComparator.sVersion.minor = '0'; } + if( sComparator.sVersion.revision == 'x' ) { sComparator.sVersion.revision = '0'; } + sComparator.version = getVersionAsString( sComparator.sVersion ); + comparatorSet.append( sComparator ); + break; + case "<=": + // <=1.x becomes <2.0.0 + if( sComparator.sVersion.minor == 'x' ) { + + sComparator.sVersion.minor = '0'; + sComparator.sVersion.revision = '0'; + sComparator.sVersion.major++; + sComparator.operator = '<'; + sComparator.version = getVersionAsString( sComparator.sVersion ); + comparatorSet.append( sComparator ); + + // <=1.0.x becomes <1.1.0 + } else if( sComparator.sVersion.revision == 'x' ) { + + sComparator.sVersion.revision = '0'; + sComparator.sVersion.minor++; + sComparator.operator = '<'; + sComparator.version = getVersionAsString( sComparator.sVersion ); + comparatorSet.append( sComparator ); + + } + else { + comparatorSet.append( sComparator ); + } + break; + case ">": + // >1.x becomes >=2.0.0 + if( sComparator.sVersion.minor == 'x' ) { + + sComparator.sVersion.minor = '0'; + sComparator.sVersion.revision = '0'; + sComparator.sVersion.major++; + sComparator.operator = '>='; + sComparator.version = getVersionAsString( sComparator.sVersion ); + comparatorSet.append( sComparator ); + + // >1.0.x becomes >=1.1.0 + } else if( sComparator.sVersion.revision == 'x' ) { + + sComparator.sVersion.revision = '0'; + sComparator.sVersion.minor++; + sComparator.operator = '>='; + sComparator.version = getVersionAsString( sComparator.sVersion ); + comparatorSet.append( sComparator ); + + } + else { + comparatorSet.append( sComparator ); + } + break; + case ">=": + // >=1.1.x becomes >=1.1.0 + // >=1.x becomes >=1.0.0 + + if( sComparator.sVersion.major == 'x' ) { sComparator.sVersion.major = '0'; } + if( sComparator.sVersion.minor == 'x' ) { sComparator.sVersion.minor = '0'; } + if( sComparator.sVersion.revision == 'x' ) { sComparator.sVersion.revision = '0'; } + sComparator.version = getVersionAsString( sComparator.sVersion ); + comparatorSet.append( sComparator ); + break; + case "=": + // * becomes >=0.0.0 + if( sComparator.sVersion.major == 'x' ) { + + sComparator.sVersion.major = 0; + sComparator.sVersion.minor = 0; + sComparator.sVersion.revision = 0; + sComparator.operator = '>='; + sComparator.version = getVersionAsString( sComparator.sVersion ); + comparatorSet.append( sComparator ); + + // 1.x becomes >=1.0.0 < 2.0.0 + } else if ( sComparator.sVersion.minor == 'x' ) { + + sComparator.sVersion.minor = 0; + sComparator.sVersion.revision = 0; + sComparator.operator = '>='; + sComparator.version = getVersionAsString( sComparator.sVersion ); + comparatorSet.append( duplicate( sComparator ) ); + + sComparator.sVersion.major++; + sComparator.operator = '<'; + sComparator.version = getVersionAsString( sComparator.sVersion ); + comparatorSet.append( sComparator ); + + + // 1.0.x becomes >=1.0.0 < 1.1.0 + } else if( sComparator.sVersion.revision == 'x' ) { + + sComparator.sVersion.revision = 0; + sComparator.operator = '>='; + sComparator.version = getVersionAsString( sComparator.sVersion ); + comparatorSet.append( duplicate( sComparator ) ); + + sComparator.sVersion.minor++; + sComparator.operator = '<'; + sComparator.version = getVersionAsString( sComparator.sVersion ); + comparatorSet.append( sComparator ); + + } else { + comparatorSet.append( sComparator ); + } + break; + case "~": + // ~1.2 Same as 1.2.x + // ~1 Same as 1.x + // ~0.2 Same as 0.2.x + // ~0 Same as 0.x + if( sComparator.sVersion.minor== 'x' || sComparator.sVersion.revision== 'x' ) { + sComparator.operator = '='; + // Recursivley handle as an X range + comparatorSet.append( expandXRanges( sComparator ), true ); + } else { + + // ~0.2.3 becomes >=0.2.3 <0.3.0 + // ~1.2.3 becomes >=1.2.3 <1.3.0 + sComparator.operator = '>='; + sComparator.version = getVersionAsString( sComparator.sVersion ); + comparatorSet.append( duplicate( sComparator ) ); + + sComparator.operator = '<'; + sComparator.sVersion.minor++; + sComparator.sVersion.revision = 0; + sComparator.sVersion.preReleaseID = ''; + sComparator.version = getVersionAsString( sComparator.sVersion ); + comparatorSet.append( sComparator ); + } + break; + case "^": + // ^1.2.3 becomes >=1.2.3 <2.0.0 + // ^0.2.3 becomes >=0.2.3 <0.3.0 + // ^0.0.3 becomes >=0.0.3 <0.0.4 + // ^1.2.3-beta.2 becomes >=1.2.3-beta.2 <2.0.0 + // ^1.2.x becomes >=1.2.0 <2.0.0 + // ^0.0.x becomes >=0.0.0 <0.1.0 + // ^0.0 becomes >=0.0.0 <0.1.0 + // ^1.x becomes >=1.0.0 <2.0.0 + // ^0.x becomes >=0.0.0 <1.0.0 + var sComparator2 = duplicate( sComparator ); + sComparator2.operator = '>='; + if( sComparator2.sVersion.major == 'x' ) { sComparator2.sVersion.major = '0'; } + if( sComparator2.sVersion.minor == 'x' ) { sComparator2.sVersion.minor = '0'; } + if( sComparator2.sVersion.revision == 'x' ) { sComparator2.sVersion.revision = '0'; } + sComparator2.version = getVersionAsString( sComparator2.sVersion ); + comparatorSet.append( sComparator2 ); + + sComparator.operator = '<'; + sComparator.sVersion.preReleaseID = ''; + if( sComparator.sVersion.major != 0 || sComparator.sVersion.minor == 'x' ) { + sComparator.sVersion.major++; + sComparator.sVersion.minor = 0; + sComparator.sVersion.revision = 0; + } else if( sComparator.sVersion.minor != 0 || sComparator.sVersion.revision == 'x' ) { + sComparator.sVersion.minor++; + sComparator.sVersion.revision = 0; + } else { + sComparator.sVersion.revision++; + } + + sComparator.version = getVersionAsString( sComparator.sVersion ); + comparatorSet.append( sComparator ); + + break; + } + + return comparatorSet; + } /** * Parse the semantic version. If no minor found, then 0. If not revision found, then 0. * If not Bleeding Edge bit, then empty. If not buildID, then 0 * @return struct:{major,minor,revision,preReleaseID,buildid} */ - struct function parseVersion( required string version ){ + struct function parseVersion( required string version, missingValuePlaceholder ){ + arguments.version = clean( arguments.version ); var results = getDefaultsVersion(); // Get build ID first @@ -145,11 +511,11 @@ component singleton{ arguments.version = reReplace( arguments.version, "\-([^\-]*).$", "" ); // Get Revision results.revision = getToken( arguments.version, 3, "." ); - if( results.revision == "" ){ results.revision = 0; } + if( results.revision == "" ){ results.revision = missingValuePlaceholder ?: 0; } // Get Minor + Major results.minor = getToken( arguments.version, 2, "." ); - if( results.minor == "" ){ results.minor = 0; } + if( results.minor == "" ){ results.minor = missingValuePlaceholder ?: 0; } results.major = getToken( arguments.version, 1, "." ); return results; @@ -157,12 +523,12 @@ component singleton{ /** * Parse the incoming version string and conform it to semantic version. - * If bleeding edge is not found it is omitted. + * If preReleaseID is not found it is omitted. * @return string:{major.minor.revision[-preReleaseID]+buildid} */ - string function parseVersionAsString( required string version ){ - var sVersion = parseVersion( clean( trim( arguments.version ) ) ); - return getVersionAsString( sVersion ); + string function parseVersionAsString( required string version, boolean includeBuildID=true ){ + var sVersion = parseVersion( arguments.version ); + return getVersionAsString( sVersion, includeBuildID ); } @@ -170,20 +536,24 @@ component singleton{ * Parse the incoming version struct and output it as a string * @return string:{major.minor.revision[-preReleaseID]+buildid} */ - string function getVersionAsString( required struct sVersion ){ + string function getVersionAsString( required struct sVersion, boolean includeBuildID=true ){ var defaultsVersion = getDefaultsVersion(); arguments.sVersion = defaultsVersion.append( arguments.sVersion ); - return ( "#sVersion.major#.#sVersion.minor#.#sVersion.revision#" & ( len( sVersion.preReleaseID ) ? "-" & sVersion.preReleaseID : '' ) & "+#sVersion.buildID#" ); + if( includeBuildID ) { + return ( "#sVersion.major#.#sVersion.minor#.#sVersion.revision#" & ( len( sVersion.preReleaseID ) ? "-" & sVersion.preReleaseID : '' ) & "+#sVersion.buildID#" ); + } else { + return ( "#sVersion.major#.#sVersion.minor#.#sVersion.revision#" & ( len( sVersion.preReleaseID ) ? "-" & sVersion.preReleaseID : '' ) ); + } } /** * Verifies if the passed version string is in a pre-release state - * Pre-release is defined by the existance of a preRelease ID or a "0" major version + * Pre-release is defined by the existance of a preRelease ID */ boolean function isPreRelease( required string version ){ - var pVersion = parseVersion( clean( trim( arguments.version ) ) ); + var pVersion = parseVersion( arguments.version ); - return ( len( pVersion.preReleaseID ) || pVersion.major == 0 ) ? true : false; + return ( len( pVersion.preReleaseID ) ) ? true : false; } /** @@ -191,23 +561,33 @@ component singleton{ * current.hint The current version of the system * target.hint The target version to check */ - boolean function isEQ( required string current, required string target ){ + boolean function isEQ( required string current, required string target, boolean checkBuildID=true ){ /** Semantic version: major.minor.revision-alpha.1+build **/ - var current = parseVersionAsString( arguments.current ); - var target = parseVersionAsString( arguments.target ); + var current = parseVersionAsString( arguments.current, checkBuildID ); + var target = parseVersionAsString( arguments.target, checkBuildID ); return ( current == target ); } /** - * UNIMPLEMENTED * True if a specific version, false if a range that could match multiple versions * version.hint A string that contains a version or a range */ boolean function isExactVersion( required string version ) { + if( version contains '*' ) return false; + if( version contains 'x.' ) return false; + if( version contains '.x' ) return false; + if( version contains '>=' ) return false; + if( version contains '<=' ) return false; + if( version contains '<' ) return false; + if( version contains '>' ) return false; + if( version contains ' - ' ) return false; + if( version contains '~' ) return false; + if( version contains '^' ) return false; + if( version contains ' || ' ) return false; return len( trim( version ) ) > 0; } diff --git a/tests/Application.cfc b/tests/Application.cfc index 9c4f05a89..e8b42b31a 100644 --- a/tests/Application.cfc +++ b/tests/Application.cfc @@ -10,8 +10,8 @@ component { this.mappings[ '/testbox' ] = 'testbox'; this.mappings[ '/commandbox' ] = '../src/cfml'; this.mappings[ '/wirebox' ] = '../src/cfml/system/wirebox'; - this.mappings[ '/mxunit' ] = 'testbox/system/testing/compat'; - + this.mappings[ '/mxunit' ] = '/testbox/system/compat'; + boolean function onRequestStart( required targetPage ){ new wirebox.system.ioc.Injector( 'tests.config.WireBox' ); return true; diff --git a/tests/cfml/system/util/TestSemanticVersion.cfc b/tests/cfml/system/util/TestSemanticVersion.cfc new file mode 100644 index 000000000..95e294215 --- /dev/null +++ b/tests/cfml/system/util/TestSemanticVersion.cfc @@ -0,0 +1,262 @@ +component name="TestPrint" extends="mxunit.framework.TestCase" { + + public void function testDefaultVersion() { + var semver = application.wirebox.getInstance( 'semanticVersion' ); + var defaultVersion = semver.getDefaultsVersion(); + assertEquals( defaultVersion, { major = 1, minor = 0, revision = 0, preReleaseID = "", buildID = 0 } ); + } + + public void function testClean() { + var semver = application.wirebox.getInstance( 'semanticVersion' ); + assertEquals( semver.clean( '1.0.0' ), '1.0.0' ); + assertEquals( semver.clean( 'v1.0.0' ), '1.0.0' ); + assertEquals( semver.clean( '=1.0.0' ), '1.0.0' ); + assertEquals( semver.clean( ' =v1.2.3 ' ), '1.2.3' ); + } + + public void function testParseVersionAsString() { + var semver = application.wirebox.getInstance( 'semanticVersion' ); + assertEquals( semver.parseVersionAsString( '1.0.0' ), '1.0.0+0' ); + assertEquals( semver.parseVersionAsString( '1.0.0+123' ), '1.0.0+123' ); + assertEquals( semver.parseVersionAsString( '1.0.0-alpha+123' ), '1.0.0-alpha+123' ); + assertEquals( semver.parseVersionAsString( '1' ), '1.0.0+0' ); + } + + public void function testIsPreRelease() { + var semver = application.wirebox.getInstance( 'semanticVersion' ); + assertFalse( semver.isPreRelease( '1.0.0' ) ); + assertTrue( semver.isPreRelease( '1.0.0-alpha' ) ); + } + + public void function testIsEQ() { + var semver = application.wirebox.getInstance( 'semanticVersion' ); + assertTrue( semver.isEQ( '1.0.0', '1.0.0' ) ); + assertTrue( semver.isEQ( '1', '1.0.0+0' ) ); + assertTrue( semver.isEQ( '1.0', '1.0.0+0' ) ); + assertTrue( semver.isEQ( '1.0.0', '1.0.0+0' ) ); + assertFalse( semver.isEQ( '1.0.0', '1.0.0-f+0' ) ); + assertFalse( semver.isEQ( '1.0.0', '2.0.0' ) ); + } + + public void function testIsExactVersion() { + var semver = application.wirebox.getInstance( 'semanticVersion' ); + assertTrue( semver.isExactVersion( '1.0.0' ) ); + assertTrue( semver.isExactVersion( '1.0.0-alpha' ) ); + assertTrue( semver.isExactVersion( '1.0.0+123' ) ); + assertTrue( semver.isExactVersion( '1.0.0-alpha+123' ) ); + assertFalse( semver.isExactVersion( '*' ) ); + assertFalse( semver.isExactVersion( '^2.2.1' ) ); + assertFalse( semver.isExactVersion( '~2.2.0' ) ); + assertFalse( semver.isExactVersion( '>2.1' ) ); + assertFalse( semver.isExactVersion( '1.0.0 - 1.2.0' ) ); + assertFalse( semver.isExactVersion( '>1.0.0-alpha' ) ); + assertFalse( semver.isExactVersion( '>=1.0.0-rc.0 <1.0.1' ) ); + assertFalse( semver.isExactVersion( '^2 <2.2 || > 2.3' ) ); + } + + public void function testIsNew() { + var semver = application.wirebox.getInstance( 'semanticVersion' ); + assertTrue( semver.isNew( '1.0.0', '2.0.0' ) ); + assertTrue( semver.isNew( '1', '2' ) ); + assertTrue( semver.isNew( '1.0.0', '1.1.0' ) ); + assertTrue( semver.isNew( '1.0.0', '1.0.1' ) ); + assertTrue( semver.isNew( '1.0.0-alpha', '1.0.0' ) ); + assertTrue( semver.isNew( '1.0.0-alpha', '1.0.0-alpha.1' ) ); + assertTrue( semver.isNew( '1.0.0-alpha.1', '1.0.0-alpha.2' ) ); + assertTrue( semver.isNew( '1.0.0-alpha', '1.0.0-beta' ) ); + assertTrue( semver.isNew( '1.0.0+0', '1.0.0+1' ) ); + assertTrue( semver.isNew( '1.0.0+123', '1.0.0+124' ) ); + assertFalse( semver.isNew( '1.0.0+0', '1.0.0+1', false ) ); + + + assertFalse( semver.isNew( '2.0.0', '1.0.0' ) ); + assertFalse( semver.isNew( '2', '1' ) ); + assertFalse( semver.isNew( '1.1.0', '1.0.0' ) ); + assertFalse( semver.isNew( '1.0.1', '1.0.0' ) ); + assertFalse( semver.isNew( '1.0.0', '1.0.0-alpha' ) ); + assertFalse( semver.isNew( '1.0.0-alpha.1', '1.0.0-alpha' ) ); + assertFalse( semver.isNew( '1.0.0-alpha.2', '1.0.0-alpha.1' ) ); + assertFalse( semver.isNew( '1.0.0-beta', '1.0.0-alpha' ) ); + assertFalse( semver.isNew( '1.0.0+1', '1.0.0+0' ) ); + assertFalse( semver.isNew( '1.0.0+124', '1.0.0+123' ) ); + assertFalse( semver.isNew( '1.0.0+1', '1.0.0+0', false ) ); + } + + public void function testCompare() { + var semver = application.wirebox.getInstance( 'semanticVersion' ); + assertEquals( semver.compare( '1.0.0', '2.0.0' ), -1 ); + assertEquals( semver.compare( '1', '2' ), -1 ); + assertEquals( semver.compare( '1.0.0', '1.1.0' ), -1 ); + assertEquals( semver.compare( '1.0.0', '1.0.1' ), -1 ); + assertEquals( semver.compare( '1.0.0-alpha', '1.0.0' ), -1 ); + assertEquals( semver.compare( '1.0.0-alpha', '1.0.0-alpha.1' ), -1 ); + assertEquals( semver.compare( '1.0.0-alpha.1', '1.0.0-alpha.2' ), -1 ); + assertEquals( semver.compare( '1.0.0-alpha', '1.0.0-beta' ), -1 ); + assertEquals( semver.compare( '1.0.0+0', '1.0.0+1' ), -1 ); + assertEquals( semver.compare( '1.0.0+123', '1.0.0+124' ), -1 ); + assertEquals( semver.compare( '1.0.0+0', '1.0.0+1', false ), 0 ); + + assertEquals( semver.compare( '2.0.0', '1.0.0' ), 1 ); + assertEquals( semver.compare( '2', '1' ), 1 ); + assertEquals( semver.compare( '1.1.0', '1.0.0' ), 1 ); + assertEquals( semver.compare( '1.0.1', '1.0.0' ), 1 ); + assertEquals( semver.compare( '1.0.0', '1.0.0-alpha' ), 1 ); + assertEquals( semver.compare( '1.0.0-alpha.1', '1.0.0-alpha' ), 1 ); + assertEquals( semver.compare( '1.0.0-alpha.2', '1.0.0-alpha.1' ), 1 ); + assertEquals( semver.compare( '1.0.0-beta', '1.0.0-alpha' ), 1 ); + assertEquals( semver.compare( '1.0.0+1', '1.0.0+0' ), 1 ); + assertEquals( semver.compare( '1.0.0+124', '1.0.0+123' ), 1 ); + assertEquals( semver.compare( '1.0.0+1', '1.0.0+0', false ), 0 ); + + assertEquals( semver.compare( '', '' ), 0 ); + assertEquals( semver.compare( '1.0.0', '1.0.0' ), 0 ); + assertEquals( semver.compare( '1', '1.0.0+0' ), 0 ); + assertEquals( semver.compare( '1.0', '1.0.0+0' ), 0 ); + assertEquals( semver.compare( '1.0.0', '1.0.0+0' ), 0 ); + } + + public void function testSatisfies() { + var semver = application.wirebox.getInstance( 'semanticVersion' ); + +// assertTrue( semver.satisfies( '1.0.0', '1.0.0+0' ) ); + //assertTrue( semver.satisfies( '1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3' ) ); + + assertTrue( semver.satisfies( '1.0.0', '<2.0.0' ) ); + assertTrue( semver.satisfies( '0.5', '<1.0.0' ) ); + assertFalse( semver.satisfies( '1.0.0', '<1.0.0' ) ); + + assertTrue( semver.satisfies( '2.0.0', '>1.0.0' ) ); + assertFalse( semver.satisfies( '1.0.0', '>1.0.0' ) ); + + assertTrue( semver.satisfies( '1.0.0', '>=1.0.0' ) ); + assertTrue( semver.satisfies( '2.0.0', '>=1.0.0' ) ); + + assertTrue( semver.satisfies( '2.0.0', '<=2.0.0' ) ); + assertTrue( semver.satisfies( '1.0.0', '<=2.0.0' ) ); + + assertTrue( semver.satisfies( '1.0.0', '1.0.0' ) ); + assertTrue( semver.satisfies( '1.0.0', 'v1.0.0' ) ); + assertTrue( semver.satisfies( 'v1.0.0', '1.0.0' ) ); + assertTrue( semver.satisfies( 'v1.0.0', 'v1.0.0' ) ); + assertTrue( semver.satisfies( '1.0.0', '=1.0.0' ) ); + + assertTrue( semver.satisfies( '1.5.0', '>1.0.0 <2.0.0' ) ); + assertFalse( semver.satisfies( '1.0.0', '>1.0.0 <2.0.0' ) ); + assertFalse( semver.satisfies( '2.0.0', '>1.0.0 <2.0.0' ) ); + assertFalse( semver.satisfies( '2.5.0', '>1.0.0 <2.0.0' ) ); + assertFalse( semver.satisfies( '1.0.0', '>2.0.0 <3.0.0' ) ); + + assertTrue( semver.satisfies( '1.0.0', '>=1.0.0 <=2.0.0' ) ); + assertTrue( semver.satisfies( '2.0.0', '>=1.0.0 <=2.0.0' ) );; + + assertTrue( semver.satisfies( '1.0.0', '1.0.0 || 2.0.0' ) ); + assertTrue( semver.satisfies( '2.0.0', '1.0.0 || 2.0.0' ) ); + assertFalse( semver.satisfies( '3.0.0', '1.0.0 || 2.0.0' ) ); + + assertTrue( semver.satisfies( '1.0.0', '>=1.0.0 <=1.5.0 || >=2.0.0 <=2.5.0' ) ); + assertTrue( semver.satisfies( '1.1.0', '>=1.0.0 <=1.5.0 || >=2.0.0 <=2.5.0' ) ); + assertTrue( semver.satisfies( '1.2.0', '>=1.0.0 <=1.5.0 || >=2.0.0 <=2.5.0' ) ); + assertTrue( semver.satisfies( '1.5.0', '>=1.0.0 <=1.5.0 || >=2.0.0 <=2.5.0' ) ); + assertTrue( semver.satisfies( '2.0.0', '>=1.0.0 <=1.5.0 || >=2.0.0 <=2.5.0' ) ); + assertTrue( semver.satisfies( '2.1.0', '>=1.0.0 <=1.5.0 || >=2.0.0 <=2.5.0' ) ); + assertTrue( semver.satisfies( '2.5.0', '>=1.0.0 <=1.5.0 || >=2.0.0 <=2.5.0' ) ); + + assertFalse( semver.satisfies( '0.9.9', '>=1.0.0 <=1.5.0 || >=2.0.0 <=2.5.0' ) ); + assertFalse( semver.satisfies( '1.6.0', '>=1.0.0 <=1.5.0 || >=2.0.0 <=2.5.0' ) ); + assertFalse( semver.satisfies( '1.9.0', '>=1.0.0 <=1.5.0 || >=2.0.0 <=2.5.0' ) ); + assertFalse( semver.satisfies( '2.6.0', '>=1.0.0 <=1.5.0 || >=2.0.0 <=2.5.0' ) ); + + assertTrue( semver.satisfies( '1.0.0', '' ) ); + assertTrue( semver.satisfies( '1.0.0', '*' ) ); + assertTrue( semver.satisfies( '1.0.0', 'x' ) ); + + assertTrue( semver.satisfies( '0.5', '0.x' ) ); + assertTrue( semver.satisfies( '1.0.0', '1.x' ) ); + assertTrue( semver.satisfies( '1.5.0', '1.x' ) ); + assertTrue( semver.satisfies( '1.9.0', '1.x' ) ); + assertFalse( semver.satisfies( '0.9.0', '1.x' ) ); + assertFalse( semver.satisfies( '2.0.0', '1.x' ) ); + + assertTrue( semver.satisfies( '1.0.0', '1.0.x' ) ); + assertTrue( semver.satisfies( '1.0.1', '1.0.x' ) ); + assertTrue( semver.satisfies( '1.0.9', '1.0.x' ) ); + assertFalse( semver.satisfies( '0.9.9', '1.0.x' ) ); + assertFalse( semver.satisfies( '1.1.0', '1.0.x' ) ); + + assertTrue( semver.satisfies( '1.0.0', '<2.0.x' ) ); + assertTrue( semver.satisfies( '1.9.9', '<2.0.x' ) ); + assertFalse( semver.satisfies( '2.0.0', '<2.0.x' ) ); + assertFalse( semver.satisfies( '2.1.0', '<2.0.x' ) ); + + assertTrue( semver.satisfies( '2.0.0', '<=2.0.x' ) ); + assertTrue( semver.satisfies( '2.0.1', '<=2.0.x' ) ); + assertTrue( semver.satisfies( '2.0.9', '<=2.0.x' ) ); + assertFalse( semver.satisfies( '2.1.0', '<=2.0.x' ) ); + + assertTrue( semver.satisfies( '2.0.0', '<=2.x' ) ); + assertTrue( semver.satisfies( '2.9.0', '<=2.x' ) ); + assertTrue( semver.satisfies( '2.9.9', '<=2.x' ) ); + assertFalse( semver.satisfies( '3.0.0', '<=2.x' ) ); + + assertTrue( semver.satisfies( '3.0.0', '>2.x' ) ); + assertFalse( semver.satisfies( '2.1.0', '>2.x' ) ); + + assertTrue( semver.satisfies( '2.1.0', '>2.0.x' ) ); + assertFalse( semver.satisfies( '2.0.1', '>2.0.x' ) ); + + assertTrue( semver.satisfies( '2.0.0', '>=2.x' ) ); + assertFalse( semver.satisfies( '1.9.0', '>=2.x' ) ); + + assertTrue( semver.satisfies( '2.1.0', '>=2.1.x' ) ); + assertFalse( semver.satisfies( '2.0.9', '>=2.1.x' ) ); + + assertTrue( semver.satisfies( '1.2.3-alpha.7', '>1.2.3-alpha.3' ) ); + assertFalse( semver.satisfies( '3.4.5-alpha.9', '>1.2.3-alpha.3' ) ); + + assertTrue( semver.satisfies( '1.2.3', '~1.2.3' ) ); + assertTrue( semver.satisfies( '1.2.9', '~1.2.3' ) ); + assertFalse( semver.satisfies( '1.3.0', '~1.2.3' ) ); + + assertTrue( semver.satisfies( '0.2.3', '~0.2.3' ) ); + assertTrue( semver.satisfies( '0.2.9', '~0.2.3' ) ); + assertFalse( semver.satisfies( '0.3.0', '~0.2.3' ) ); + + assertTrue( semver.satisfies( '1.2.0', '~1.2' ) ); + assertTrue( semver.satisfies( '1.5.0', '~1' ) ); + assertTrue( semver.satisfies( '0.2.5', '~0.2' ) ); + assertTrue( semver.satisfies( '0.5.0', '~0' ) ); + + assertTrue( semver.satisfies( '1.2.3-beta.2', '~1.2.3-beta.2' ) ); + assertTrue( semver.satisfies( '1.2.3-beta.3', '~1.2.3-beta.2' ) ); + assertTrue( semver.satisfies( '1.2.3', '~1.2.3-beta.2' ) ); + assertTrue( semver.satisfies( '1.2.4', '~1.2.3-beta.2' ) ); + assertFalse( semver.satisfies( '1.2.4-beta.2', '~1.2.3-beta.2' ) ); + + + assertTrue( semver.satisfies( '2.0.0', '1.2.3 - 2.3.4' ) ); + assertTrue( semver.satisfies( '1.2.3', '1.2.3 - 2.3.4' ) ); + assertTrue( semver.satisfies( '2.3.4', '1.2.3 - 2.3.4' ) ); + assertFalse( semver.satisfies( '1.2.2', '1.2.3 - 2.3.4' ) ); + assertFalse( semver.satisfies( '2.3.5', '1.2.3 - 2.3.4' ) ); + + assertTrue( semver.satisfies( '2.0.0', '1.2 - 2.3.4' ) ); + assertTrue( semver.satisfies( '1.2.0', '1.2 - 2.3.4' ) ); + + assertTrue( semver.satisfies( '2.3.9', '1.2.3 - 2.3' ) ); + assertFalse( semver.satisfies( '2.4.0', '1.2.3 - 2.3' ) ); + + assertTrue( semver.satisfies( '1.9.9', '^1.2.3' ) ); + assertTrue( semver.satisfies( '0.2.4', '^0.2.3' ) ); + assertTrue( semver.satisfies( '0.0.3', '^0.0.3' ) ); + assertTrue( semver.satisfies( '1.5.0', '^1.2.3-beta.2' ) ); + assertTrue( semver.satisfies( '1.9.9', '^1.2.x' ) ); + assertTrue( semver.satisfies( '0.0.1', '^0.0.x' ) ); + assertTrue( semver.satisfies( '0.0.1', '^0.0' ) ); + assertTrue( semver.satisfies( '1.5.0', '^1.x' ) ); + assertTrue( semver.satisfies( '0.5.0', '^0.x' ) ); + + assertTrue( semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') ); + + } + +} \ No newline at end of file diff --git a/tests/runner.cfm b/tests/runner.cfm index 7b0a23b38..625de823f 100644 --- a/tests/runner.cfm +++ b/tests/runner.cfm @@ -1,7 +1,7 @@ - + From b8625c628828b848917a1c365c9654b6338ebae7 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Fri, 15 Apr 2016 14:52:21 -0400 Subject: [PATCH 030/129] Updates for all coldbox templates --- .../templates/ActionContent.txt | 2 +- .../templates/ActionContentScript.txt | 5 ++++- .../templates/HandlerContent.txt | 2 +- .../templates/HandlerContentScript.txt | 2 ++ .../templates/InterceptorContent.txt | 2 +- .../templates/InterceptorContentScript.txt | 2 +- .../templates/crud/HandlerContent.txt | 8 +++++-- .../coldbox-commands/templates/crud/edit.txt | 2 +- .../templates/crud/editor.txt | 22 ++++++++++--------- .../coldbox-commands/templates/crud/new.txt | 2 +- .../templates/modules/ModuleConfig.cfc | 4 ++-- .../templates/modules/ModuleConfigScript.cfc | 4 ++-- 12 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/cfml/system/modules/coldbox-commands/templates/ActionContent.txt b/src/cfml/system/modules/coldbox-commands/templates/ActionContent.txt index 787c21e79..e2a062ebb 100644 --- a/src/cfml/system/modules/coldbox-commands/templates/ActionContent.txt +++ b/src/cfml/system/modules/coldbox-commands/templates/ActionContent.txt @@ -2,5 +2,5 @@ - +
\ No newline at end of file diff --git a/src/cfml/system/modules/coldbox-commands/templates/ActionContentScript.txt b/src/cfml/system/modules/coldbox-commands/templates/ActionContentScript.txt index 168352e3d..c5aa476e8 100644 --- a/src/cfml/system/modules/coldbox-commands/templates/ActionContentScript.txt +++ b/src/cfml/system/modules/coldbox-commands/templates/ActionContentScript.txt @@ -1,3 +1,6 @@ - function |action|(event,rc,prc){ + /** + * |action| + */ + function |action|( event, rc, prc ){ event.setView( "|Name|/|action|" ); } \ No newline at end of file diff --git a/src/cfml/system/modules/coldbox-commands/templates/HandlerContent.txt b/src/cfml/system/modules/coldbox-commands/templates/HandlerContent.txt index 644799730..80728bf67 100644 --- a/src/cfml/system/modules/coldbox-commands/templates/HandlerContent.txt +++ b/src/cfml/system/modules/coldbox-commands/templates/HandlerContent.txt @@ -1,4 +1,4 @@ - + this.prehandler_only = ""; diff --git a/src/cfml/system/modules/coldbox-commands/templates/HandlerContentScript.txt b/src/cfml/system/modules/coldbox-commands/templates/HandlerContentScript.txt index 22d746aa9..eb1edc4c0 100644 --- a/src/cfml/system/modules/coldbox-commands/templates/HandlerContentScript.txt +++ b/src/cfml/system/modules/coldbox-commands/templates/HandlerContentScript.txt @@ -27,6 +27,8 @@ component{ } function onError( event, rc, prc, faultAction, exception, eventArguments ){ } + function onInvalidHTTPMethod( event, rc, prc, faultAction, eventArguments ){ + } */ |EventActions| diff --git a/src/cfml/system/modules/coldbox-commands/templates/InterceptorContent.txt b/src/cfml/system/modules/coldbox-commands/templates/InterceptorContent.txt index 94e195a1f..9b97e48e1 100644 --- a/src/cfml/system/modules/coldbox-commands/templates/InterceptorContent.txt +++ b/src/cfml/system/modules/coldbox-commands/templates/InterceptorContent.txt @@ -1,4 +1,4 @@ - + diff --git a/src/cfml/system/modules/coldbox-commands/templates/InterceptorContentScript.txt b/src/cfml/system/modules/coldbox-commands/templates/InterceptorContentScript.txt index db12d473f..e2bae0d89 100644 --- a/src/cfml/system/modules/coldbox-commands/templates/InterceptorContentScript.txt +++ b/src/cfml/system/modules/coldbox-commands/templates/InterceptorContentScript.txt @@ -1,7 +1,7 @@ /** * |Description| */ -component { +component extends="coldbox.system.Interceptor"{ void function configure(){ diff --git a/src/cfml/system/modules/coldbox-commands/templates/crud/HandlerContent.txt b/src/cfml/system/modules/coldbox-commands/templates/crud/HandlerContent.txt index 881b1319f..12f254738 100644 --- a/src/cfml/system/modules/coldbox-commands/templates/crud/HandlerContent.txt +++ b/src/cfml/system/modules/coldbox-commands/templates/crud/HandlerContent.txt @@ -2,14 +2,18 @@ * Manage |entityPlural| * It will be your responsibility to fine tune this template, add validations, try/catch blocks, logging, etc. */ -component{ +component extends="coldbox.system.EventHandler"{ // DI Virtual Entity Service property name="ormService" inject="entityService:|entity|"; // HTTP Method Security this.allowedMethods = { - index = "GET", new = "GET", edit = "GET", delete = "POST,DELETE", save = "POST,PUT" + index = "GET", + new = "GET", + edit = "GET", + delete = "POST,DELETE", + save = "POST,PUT" }; /** diff --git a/src/cfml/system/modules/coldbox-commands/templates/crud/edit.txt b/src/cfml/system/modules/coldbox-commands/templates/crud/edit.txt index ec93067a8..3187394bc 100644 --- a/src/cfml/system/modules/coldbox-commands/templates/crud/edit.txt +++ b/src/cfml/system/modules/coldbox-commands/templates/crud/edit.txt @@ -1 +1 @@ - #renderView(view="|entityPlural|/editor", args={title="Update |entity|"})# \ No newline at end of file + #renderView( view="|entityPlural|/editor", args={ title = "Update |entity|" } )# \ No newline at end of file diff --git a/src/cfml/system/modules/coldbox-commands/templates/crud/editor.txt b/src/cfml/system/modules/coldbox-commands/templates/crud/editor.txt index ba697e3a1..e6d39e0f8 100644 --- a/src/cfml/system/modules/coldbox-commands/templates/crud/editor.txt +++ b/src/cfml/system/modules/coldbox-commands/templates/crud/editor.txt @@ -18,16 +18,18 @@ #html.startForm( action='|entityPlural|.save' )# - #html.entityFields( entity=prc.|entity|, - groupWrapper="div class='form-group'", - class="form-control", - fieldWrapper="", - labelWrapper="", - textAreas="", - booleanSelect=true, - manyToOne={}, - manyToMany={}, - showRelations=true)# + #html.entityFields( + entity=prc.|entity|, + groupWrapper="div class='form-group'", + class="form-control", + fieldWrapper="", + labelWrapper="", + textAreas="", + booleanSelect=true, + manyToOne={}, + manyToMany={}, + showRelations=true + )#
diff --git a/src/cfml/system/modules/coldbox-commands/templates/crud/new.txt b/src/cfml/system/modules/coldbox-commands/templates/crud/new.txt index 6e9e35b35..6227a8517 100644 --- a/src/cfml/system/modules/coldbox-commands/templates/crud/new.txt +++ b/src/cfml/system/modules/coldbox-commands/templates/crud/new.txt @@ -1,3 +1,3 @@ -#renderView(view="|entityPlural|/editor", args={title="Create |entity|"})# +#renderView( view="|entityPlural|/editor", args={title="Create |entity|"} )# \ No newline at end of file diff --git a/src/cfml/system/modules/coldbox-commands/templates/modules/ModuleConfig.cfc b/src/cfml/system/modules/coldbox-commands/templates/modules/ModuleConfig.cfc index a6adc3b36..11266a06f 100644 --- a/src/cfml/system/modules/coldbox-commands/templates/modules/ModuleConfig.cfc +++ b/src/cfml/system/modules/coldbox-commands/templates/modules/ModuleConfig.cfc @@ -90,9 +90,9 @@ Optional Methods // SES Routes routes = [ // Module Entry Point - {pattern="/", handler="home",action="index"}, + { pattern="/", handler="home", action="index" }, // Convention Route - {pattern="/:handler/:action?"} + { pattern="/:handler/:action?" } ]; // Custom Declared Points diff --git a/src/cfml/system/modules/coldbox-commands/templates/modules/ModuleConfigScript.cfc b/src/cfml/system/modules/coldbox-commands/templates/modules/ModuleConfigScript.cfc index 98baf7f91..4518e18a2 100644 --- a/src/cfml/system/modules/coldbox-commands/templates/modules/ModuleConfigScript.cfc +++ b/src/cfml/system/modules/coldbox-commands/templates/modules/ModuleConfigScript.cfc @@ -89,9 +89,9 @@ component { // SES Routes routes = [ // Module Entry Point - {pattern="/", handler="home",action="index"}, + { pattern="/", handler="home", action="index" }, // Convention Route - {pattern="/:handler/:action?"} + { pattern="/:handler/:action?" } ]; // Custom Declared Points From 76a7a547a35f9c08c5c3910361e85344cde8538b Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Sat, 16 Apr 2016 20:13:09 -0500 Subject: [PATCH 031/129] finalizing package updates --- src/cfml/system/endpoints/ForgeBox.cfc | 55 ++++++++++++++----- .../commands/forgebox/show.cfc | 3 + .../commands/package/list.cfc | 2 +- .../commands/package/update.cfc | 2 +- src/cfml/system/services/PackageService.cfc | 18 ++++-- src/cfml/system/util/SemanticVersion.cfc | 12 ++-- 6 files changed, 66 insertions(+), 26 deletions(-) diff --git a/src/cfml/system/endpoints/ForgeBox.cfc b/src/cfml/system/endpoints/ForgeBox.cfc index 2f7309c4f..882facb59 100644 --- a/src/cfml/system/endpoints/ForgeBox.cfc +++ b/src/cfml/system/endpoints/ForgeBox.cfc @@ -53,17 +53,44 @@ component accessors="true" implements="IEndpointInteractive" singleton { public function getUpdate( required string package, required string version, boolean verbose=false ) { var slug = parseSlug( arguments.package ); - var version = parseVersion( arguments.package ); + var boxJSONversion = parseVersion( arguments.package ); var result = { isOutdated = false, version = '' }; + // Only bother checking if we have a version range. If an exact version is stored in + // box.json, we're never going to update it anyway. + if( semanticVersion.isExactVersion( boxJSONversion ) ) { + return result; + } + // Verify in ForgeBox - var fbData = forgebox.getEntry( slug ); - // Verify if we are outdated, internally isNew() parses the incoming strings - result.isOutdated = semanticVersion.isNew( current=version, target=fbData.version ); - result.version = fbData.version; + var entryData = forgebox.getEntry( slug ); + + entryData.versions.sort( function( a, b ) { return semanticVersion.compare( b.version, a.version ) } ); + + var found = false; + for( var thisVersion in entryData.versions ) { + // Look for a version on ForgeBox that satisfies our range + if( semanticVersion.satisfies( thisVersion.version, boxJSONversion ) ) { + result.version = thisVersion.version; + found = true; + // Only flag it as outdated if the matching version is newer. + if( semanticVersion.isNew( current=version, target=thisVersion.version, checkBuildID=false ) ) { + result.isOutdated = true; + } + break; + } + } + + if( !found ) { + // If we requsted stable and all releases are pre-release, just grab the latest + if( boxJSONversion == 'stable' && arrayLen( entryData.versions ) ) { + result.version = entryData.versions[ 1 ].version; + result.isOutdated = true; + } + } return result; } @@ -176,17 +203,14 @@ component accessors="true" implements="IEndpointInteractive" singleton { if( !val( entryData.isActive ) ) { throw( 'The ForgeBox entry [#entryData.title#] is inactive.', 'endpointException' ); } - - if( !len( entryData.downloadurl ) ) { - throw( 'No download URL provided in ForgeBox. Manual install only.', 'endpointException' ); - } - entryData.versions.sort( function( a, b ) { return 0-semanticVersion.compare( a.version, b.version ) } ); + entryData.versions.sort( function( a, b ) { return semanticVersion.compare( b.version, a.version ) } ); var found = false; for( var thisVersion in entryData.versions ) { if( semanticVersion.satisfies( thisVersion.version, arguments.version ) ) { arguments.version = thisVersion.version; + var downloadURL = thisVersion.downloadURL; found = true; break; } @@ -196,10 +220,15 @@ component accessors="true" implements="IEndpointInteractive" singleton { // If we requsted stable and all releases are pre-release, just grab the latest if( arguments.version == 'stable' && arrayLen( entryData.versions ) ) { arguments.version = entryData.versions[ 1 ].version; + var downloadURL = thisVersion.downloadURL; } else { - throw( 'Version [#arguments.version#] not found for package [#arguments.slug#].', 'endpointException' ); + throw( 'Version [#arguments.version#] not found for package [#arguments.slug#].', 'endpointException', 'Available versions are [#entryData.versions.map( function( i ){ return ' ' & i.version; } ).toList()#]' ); } } + + if( !len( downloadurl ) ) { + throw( 'No download URL provided in ForgeBox. Manual install only.', 'endpointException' ); + } consoleLogger.info( "Installing version [#arguments.version#]." ); @@ -214,7 +243,7 @@ component accessors="true" implements="IEndpointInteractive" singleton { if( !artifactService.artifactExists( slug, version ) ) { // Test package location to see what endpoint we can refer to. - var endpointData = endpointService.resolveEndpoint( entryData.downloadURL, 'fakePath' ); + var endpointData = endpointService.resolveEndpoint( downloadURL, 'fakePath' ); consoleLogger.info( "Deferring to [#endpointData.endpointName#] endpoint for ForgeBox entry [#slug#]..." ); @@ -224,7 +253,7 @@ component accessors="true" implements="IEndpointInteractive" singleton { var boxJSON = packageService.readPackageDescriptorRaw( packagePath ); if( !structKeyExists( boxJSON, 'type' ) || !len( boxJSON.type ) ) { boxJSON.type = entryData.typeslug; } if( !structKeyExists( boxJSON, 'slug' ) || !len( boxJSON.slug ) ) { boxJSON.slug = entryData.slug; } - if( !structKeyExists( boxJSON, 'version' ) || !len( boxJSON.version ) ) { boxJSON.version = entryData.version; } + if( !structKeyExists( boxJSON, 'version' ) || !len( boxJSON.version ) ) { boxJSON.version = version; } packageService.writePackageDescriptor( boxJSON, packagePath ); consoleLogger.info( "Storing download in artifact cache..." ); diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/show.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/show.cfc index 7f8843e1b..8d3d4eda4 100644 --- a/src/cfml/system/modules/forgebox-commands/commands/forgebox/show.cfc +++ b/src/cfml/system/modules/forgebox-commands/commands/forgebox/show.cfc @@ -35,6 +35,7 @@ component aliases="show" { // DI property name="forgeBox" inject="ForgeBox"; + property name="semanticVersion" inject="semanticVersion"; function onDIComplete() { variables.forgeboxOrders = forgebox.ORDER; @@ -125,6 +126,7 @@ component aliases="show" { error( 'The ForgeBox entry [#entryData.title#] is inactive, we highly recommed NOT installing it or contact the author about it' ); } + entryData.versions.sort( function( a, b ) { return semanticVersion.compare( b.version, a.version ) } ); print.line(); print.blackOnWhite( ' #entryData.title# ' ) .boldText( ' ( #entryData.user.fname# #entryData.user.lname#, #entryData.user.email# )' ) @@ -135,6 +137,7 @@ component aliases="show" { .line( 'Type: #entryData.typeName#' ) .line( 'Slug: "#entryData.slug#"' ) .line( 'Summary: #entryData.summary#' ) + .line( 'Versions: #entryData.versions.map( function( i ){ return ' ' & i.version; } ).toList()#' ) .line( 'Created On: #dateFormat( entryData.createdDate )#' ) .line( 'Updated On: #dateFormat( entryData.updatedDate )#' ) .line( 'Version: #entryData.version#' ) diff --git a/src/cfml/system/modules/package-commands/commands/package/list.cfc b/src/cfml/system/modules/package-commands/commands/package/list.cfc index 41a6f8c23..941da5876 100644 --- a/src/cfml/system/modules/package-commands/commands/package/list.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/list.cfc @@ -64,7 +64,7 @@ component aliases="list" { print.text( prefix & branch & ' ' ); - print[ ( dependency.dev ? 'boldYellowline' : 'boldLine' ) ]( '#dependencyName# (#dependency.version#)' ); + print[ ( dependency.dev ? 'boldYellowline' : 'boldLine' ) ]( '#dependencyName# (#dependency.packageVersion#)' ); if( arguments.verbose ) { if( len( dependency.name ) ) { diff --git a/src/cfml/system/modules/package-commands/commands/package/update.cfc b/src/cfml/system/modules/package-commands/commands/package/update.cfc index ad39b4287..4508c5562 100644 --- a/src/cfml/system/modules/package-commands/commands/package/update.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/update.cfc @@ -89,7 +89,7 @@ component aliases="update" { print.magentaLine( "Starting update of #oldID# ").toConsole(); // install it - runCommand( "install ID='#parser.escapeArg( newID )#' verbose=#arguments.verbose# --force" ); + runCommand( "install ID='#parser.escapeArg( newID )#' verbose=#arguments.verbose# --force --!save" ); } } diff --git a/src/cfml/system/services/PackageService.cfc b/src/cfml/system/services/PackageService.cfc index 171dbe2d7..44169253c 100644 --- a/src/cfml/system/services/PackageService.cfc +++ b/src/cfml/system/services/PackageService.cfc @@ -507,11 +507,12 @@ component accessors="true" singleton { ){ interceptorService.announceInterception( 'preUninstall', { uninstallArgs=arguments } ); + + // In case someone types "uninstall coldbox@4.0.0" + var packageName = listFirst( arguments.ID, '@' ); consoleLogger.info( '.'); - consoleLogger.info( 'Uninstalling package: #arguments.ID#'); - - var packageName = arguments.ID; + consoleLogger.info( 'Uninstalling package: #packageName#'); var uninstallDirectory = ''; @@ -608,7 +609,7 @@ component accessors="true" singleton { consoleLogger.info( "Dependency removed from box.json." ); } - consoleLogger.info( "'#arguments.ID#' has been uninstalled" ); + consoleLogger.info( "'#packageName#' has been uninstalled" ); interceptorService.announceInterception( 'postUninstall', { uninstallArgs=arguments } ); } @@ -644,8 +645,15 @@ component accessors="true" singleton { } // Add/overwrite this dependency + if( endpointData.endpointName == 'forgebox' ) { - dependencies[ arguments.packageName ] = arguments.version; + + if( listLen( endpointData.package, '@' ) > 1 ) { + dependencies[ arguments.packageName ] = listLast( endpointData.package, '@' ); + } else { + // caret version range (^1.2.3) allows updates that don't bump the major version. + dependencies[ arguments.packageName ] = '^' & arguments.version; + } } else { dependencies[ arguments.packageName ] = endpointData.ID; } diff --git a/src/cfml/system/util/SemanticVersion.cfc b/src/cfml/system/util/SemanticVersion.cfc index 1ed835573..16b5b74aa 100644 --- a/src/cfml/system/util/SemanticVersion.cfc +++ b/src/cfml/system/util/SemanticVersion.cfc @@ -158,25 +158,25 @@ component singleton{ return false; - return isEQ( arguments.version, arguments.range ); + return isEQ( arguments.version, arguments.range, false ); } private function evaluateComparator( required struct comparator, version ) { switch( comparator.operator ) { case "<": - return isNew( arguments.version, comparator.version ); + return isNew( arguments.version, comparator.version, false ); break; case "<=": - return isNew( arguments.version, comparator.version ) || isEq( comparator.version, arguments.version ); + return isNew( arguments.version, comparator.version, false ) || isEq( comparator.version, arguments.version, false ); break; case ">": - return isNew( comparator.version, arguments.version ); + return isNew( comparator.version, arguments.version, false ); break; case ">=": - return isNew( comparator.version, arguments.version ) || isEq( comparator.version, arguments.version ); + return isNew( comparator.version, arguments.version, false ) || isEq( comparator.version, arguments.version, false ); break; case "=": - return isEq( comparator.version, arguments.version ); + return isEq( comparator.version, arguments.version, false ); break; default: return false; From 2bd7a3b6e9bc631e38751530fa627f2abcf4e226 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 20 Apr 2016 13:00:06 -0500 Subject: [PATCH 032/129] COMMANDBOX-367 Fix for small progress bars --- src/cfml/system/util/ProgressBar.cfc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/cfml/system/util/ProgressBar.cfc b/src/cfml/system/util/ProgressBar.cfc index a63b130e2..734b1359a 100644 --- a/src/cfml/system/util/ProgressBar.cfc +++ b/src/cfml/system/util/ProgressBar.cfc @@ -40,12 +40,14 @@ component singleton { var progressBarTemplate = '@@@% [=>] $$$$$$$ / ^^^^^^^ (&&&&&&&&)'; // Dynamically assign the remaining width to the moving progress bar var nonProgressChars = len( progressBarTemplate ) - 1; - var progressChars = totalWidth - nonProgressChars; + // Minimum progressbar length is 5. It will wrap if the user's console is super short, but I'm not sure I care. + var progressChars = max( totalWidth - nonProgressChars, 5 ); // Clear the line ansi.eraseLine(ansiErase.ALL); - // Move cursor back to the far left - ansi.cursorLeft( totalWidth ); + // Windows DOS can have a window size larger than the reported terminal size. Moving the cursor left + // a ridiculous amount seems to have no ill-affect so we're just going to make darn sure we're up against the left side. + ansi.cursorLeft( totalWidth+99999 ); // Get the template var progressRendered = progressBarTemplate; @@ -55,7 +57,7 @@ component singleton { // Replace actual progress bar var progressSize = int( progressChars * (arguments.percent/100) ); - var barChars = repeatString( '=', progressSize ) & '>' & repeatString( ' ', progressChars-progressSize ); + var barChars = repeatString( '=', progressSize ) & '>' & repeatString( ' ', max( progressChars-progressSize, 0 ) ); progressRendered = replace( progressRendered, '=>', barChars ); // Replace sizes and speed From 7db13f2e278e6769b7e3ab44cbf405db3881172e Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 21 Apr 2016 00:42:04 -0500 Subject: [PATCH 033/129] Short circuit for stable logic --- src/cfml/system/util/SemanticVersion.cfc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cfml/system/util/SemanticVersion.cfc b/src/cfml/system/util/SemanticVersion.cfc index 16b5b74aa..4f2ee5425 100644 --- a/src/cfml/system/util/SemanticVersion.cfc +++ b/src/cfml/system/util/SemanticVersion.cfc @@ -130,6 +130,8 @@ component singleton{ if( range == 'stable' && !isPreRelease( version ) ) { return true; + } else if( range == 'stable' ) { + return false; } // An array of comparator sets. At least one of the comparator sets needs to From 06a308364fde41a49a6564eccfb703611083fa38 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 21 Apr 2016 15:55:35 -0500 Subject: [PATCH 034/129] Update to stage URL so BE can work --- src/cfml/system/util/ForgeBox.cfc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cfml/system/util/ForgeBox.cfc b/src/cfml/system/util/ForgeBox.cfc index b8c527bca..554b107f3 100644 --- a/src/cfml/system/util/ForgeBox.cfc +++ b/src/cfml/system/util/ForgeBox.cfc @@ -47,8 +47,8 @@ or just add DEBUG to the root logger // Setup Properties - variables.APIURL = "http://www.coldbox.org/api/forgebox"; - //variables.APIURL = "http://forgebox.stg.ortussolutions.com/api/v1/"; + // variables.APIURL = "http://www.coldbox.org/api/forgebox"; + variables.APIURL = "http://forgebox.stg.ortussolutions.com/api/v1/"; variables.installURL = "http://www.coldbox.org/forgebox/install/"; variables.types = ""; From 0bbf2189785f0e0747b9c969599cab85c41ae781 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 21 Apr 2016 17:10:24 -0500 Subject: [PATCH 035/129] COMMANDBOX-346 SDK format --- build/build.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/build/build.xml b/build/build.xml index e36635b42..9c9db48df 100644 --- a/build/build.xml +++ b/build/build.xml @@ -442,9 +442,21 @@ External Dependencies: + + + + + + + + + + + + From 15aa2c47e7e79a3353a7ed02d445aabe5fa07caa Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Fri, 22 Apr 2016 11:26:26 -0500 Subject: [PATCH 036/129] Ignore local api docs --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c3c4d33eb..c82f2bea1 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ build/launch4j tests/testbox /mxunit /apidocs/CommandBox-CommandDocs/ +/apidocs/CommandBox-APIDocs/ build-local.properties build/resources src/cfml/.version From c38d2eaba02000526944591ac4b68d1299031e00 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Fri, 22 Apr 2016 11:26:37 -0500 Subject: [PATCH 037/129] Fix for pagination --- src/cfml/system/util/ForgeBox.cfc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cfml/system/util/ForgeBox.cfc b/src/cfml/system/util/ForgeBox.cfc index 554b107f3..0b79bcced 100644 --- a/src/cfml/system/util/ForgeBox.cfc +++ b/src/cfml/system/util/ForgeBox.cfc @@ -97,8 +97,8 @@ or just add DEBUG to the root logger var results = ""; var params = { orderBY = arguments.orderby, - maxrows = arguments.maxrows, - startrow = arguments.startrow, + max = arguments.maxrows, + offset = arguments.startrow-1, typeSlug = arguments.typeSlug }; From db4cc966c6b6b4023389d8af114535a9c1cae4e3 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Fri, 22 Apr 2016 12:23:43 -0500 Subject: [PATCH 038/129] COMMANDBOX-370 --- src/cfml/system/Completor.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfml/system/Completor.cfc b/src/cfml/system/Completor.cfc index d412d322b..63b611b4e 100644 --- a/src/cfml/system/Completor.cfc +++ b/src/cfml/system/Completor.cfc @@ -296,7 +296,7 @@ component singleton { // Call function to populate dynamic values if( structKeyExists( completorData[ paramName ], 'optionsUDF' ) ) { var completorFunctionName = completorData[ paramName ][ 'optionsUDF' ]; - var additions = commandInfo.commandReference.CFC[ completorFunctionName ](); + var additions = commandInfo.commandReference.CFC[ completorFunctionName ]( paramSoFar=arguments.paramSoFar ); if( isArray( additions ) ) { addAllIfMatch( candidates, additions, paramSoFar ); } From ffec2df89c2be8b8d8c0f7d64f18cf7a49b80241 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Fri, 22 Apr 2016 15:48:20 -0500 Subject: [PATCH 039/129] HTTPS required and post doesn't follow redirects. --- src/cfml/system/util/ForgeBox.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfml/system/util/ForgeBox.cfc b/src/cfml/system/util/ForgeBox.cfc index 0b79bcced..d5b146c8d 100644 --- a/src/cfml/system/util/ForgeBox.cfc +++ b/src/cfml/system/util/ForgeBox.cfc @@ -48,7 +48,7 @@ or just add DEBUG to the root logger // Setup Properties // variables.APIURL = "http://www.coldbox.org/api/forgebox"; - variables.APIURL = "http://forgebox.stg.ortussolutions.com/api/v1/"; + variables.APIURL = "https://forgebox.stg.ortussolutions.com/api/v1/"; variables.installURL = "http://www.coldbox.org/forgebox/install/"; variables.types = ""; From bc5cffc9871b9c425e6372b778b4cbfc96b118df Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 26 Apr 2016 23:34:13 -0500 Subject: [PATCH 040/129] COMMANDBOX-374 --- build/build.xml | 2 +- .../commands/package/version.cfc | 93 ++++++++++++++++--- src/cfml/system/util/SemanticVersion.cfc | 2 +- 3 files changed, 84 insertions(+), 13 deletions(-) diff --git a/build/build.xml b/build/build.xml index 9c9db48df..c1fd51065 100644 --- a/build/build.xml +++ b/build/build.xml @@ -685,7 +685,7 @@ External Dependencies: --> - + diff --git a/src/cfml/system/modules/package-commands/commands/package/version.cfc b/src/cfml/system/modules/package-commands/commands/package/version.cfc index 00463e995..8e13332f8 100644 --- a/src/cfml/system/modules/package-commands/commands/package/version.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/version.cfc @@ -29,30 +29,40 @@ component aliases="bump" { property name='packageService' inject='PackageService'; + property name='configService' inject='ConfigService'; property name='semanticVersion' inject='semanticVersion'; property name='parser' inject='Parser'; /** - * @property.hint Name of the property to clear - * @property.optionsUDF completeProperty + * @version The new version to set into this package + * @message The message to use when commiting the new tag + * @tagVersion Whether or not to tag the repo + * @force Skip the check if to see if the Git repo is clean + * @major Increment the major version number + * @minor Increment the minor version number + * @patch Increment the patch version number **/ function run( string version='', + string message, + boolean tagVersion, + boolean force = false, boolean major, boolean minor, boolean patch ) { // the CWD is our "package" - var directory = getCWD(); + arguments.directory = getCWD(); // Read the box.json. Missing values will NOT be defaulted. - var boxJSON = packageService.readPackageDescriptorRaw( directory ); - var versionObject = semanticVersion.parseVersion( semanticVersion.clean( trim( boxJSON.version ?: '' ) ) ); + var boxJSON = packageService.readPackageDescriptorRaw( arguments.directory ); + var versionObject = semanticVersion.parseVersion( trim( boxJSON.version ?: '' ) ); if( len( arguments.version ) ) { // Set a specific version - setVersion( arguments.version ); + arguments.version = semanticVersion.clean( arguments.version ); + setVersion( argumentCollection=arguments ); } else if( structKeyExists( arguments, 'major' ) && arguments.major ) { @@ -60,20 +70,23 @@ component aliases="bump" { versionObject.major = val( versionObject.major ) + 1; versionObject.minor = 0; versionObject.revision = 0; - setVersion( semanticVersion.getVersionAsString( versionObject ) ); + arguments.version = semanticVersion.getVersionAsString( versionObject ); + setVersion( argumentCollection=arguments ); } else if( structKeyExists( arguments, 'minor' ) && arguments.minor ) { // Bump minor versionObject.minor = val( versionObject.minor ) + 1; versionObject.revision = 0; - setVersion( semanticVersion.getVersionAsString( versionObject ) ); + arguments.version = semanticVersion.getVersionAsString( versionObject ); + setVersion( argumentCollection=arguments ); } else if( structKeyExists( arguments, 'patch' ) && arguments.patch ) { // Bump patch versionObject.revision = val( versionObject.revision ) + 1; - setVersion( semanticVersion.getVersionAsString( versionObject ) ); + arguments.version = semanticVersion.getVersionAsString( versionObject ); + setVersion( argumentCollection=arguments ); } else { @@ -83,8 +96,66 @@ component aliases="bump" { } - function setVersion( required string version ) { - runCommand( 'package set version="' & parser.escapeArg( arguments.version ) & '"' ); + function setVersion( required string version, boolean tagVersion, string message, string directory, required boolean force ) { + + command( 'package set' ) + .params( version=arguments.version ) + .run(); + + // If this package is also a Git repository + var repoPath = '#arguments.directory#/.git'; + arguments.tagVersion = arguments.tagVersion ?: ConfigService.getSetting( 'tagVersion', true ); + if( directoryExists( repoPath ) && arguments.tagVersion ) { + print.yellowLine( 'Package is a Git repo. Tagging...' ); + + try { + + // The main Git API + var GitAPI = createObject( 'java', 'org.eclipse.jgit.api.Git' ); + + var git = GitAPI.open( createObject( 'java', 'java.io.File' ).init( repoPath ) ); + var diffs = git.diff() + .setCached( true ) + .setShowNameAndStatusOnly( true ) + .call(); + + // Make sure there aren't staged file ready to commit (clean working dir) + if( arrayLen( diffs ) && !arguments.force ) { + print.line() + .boldRedLine( 'The working directory is not clean.' ); + for( var entryDiff in diffs ) { + print.yellowLine( entryDiff.getChangeType() & ' ' & entryDiff.getNewPath() ); + } + error( 'Cannot tag Git repo. Please commit file, or use --force flag to skip this check' ); + } + + arguments.message = arguments.message ?: ConfigService.getSetting( 'tagVersionMessage', '${version}' ); + arguments.message = replaceNoCase( arguments.message, '${version}', arguments.version, 'all' ); + + // Add the box.json + git.add() + .addFilepattern( 'box.json' ) + .call(); + + // Commit the box.json + git.commit() + .setMessage( arguments.message ) + .call(); + + // Tag this version + git.tag() + .setName( 'v#arguments.version#' ) + .setMessage( arguments.message ) + .call(); + + print.yellowLine( 'Tag [v#arguments.version#] created.' ); + } catch( any var e ) { + logger.error( 'Error tagging Git repository with new version.', e ); + error( 'Error tagging Git repository with new version.', e.message & ' ' & e.detail ); + } + } + + } } \ No newline at end of file diff --git a/src/cfml/system/util/SemanticVersion.cfc b/src/cfml/system/util/SemanticVersion.cfc index 4f2ee5425..830b132f5 100644 --- a/src/cfml/system/util/SemanticVersion.cfc +++ b/src/cfml/system/util/SemanticVersion.cfc @@ -541,7 +541,7 @@ component singleton{ string function getVersionAsString( required struct sVersion, boolean includeBuildID=true ){ var defaultsVersion = getDefaultsVersion(); arguments.sVersion = defaultsVersion.append( arguments.sVersion ); - if( includeBuildID ) { + if( includeBuildID && sVersion.buildID != 0 ) { return ( "#sVersion.major#.#sVersion.minor#.#sVersion.revision#" & ( len( sVersion.preReleaseID ) ? "-" & sVersion.preReleaseID : '' ) & "+#sVersion.buildID#" ); } else { return ( "#sVersion.major#.#sVersion.minor#.#sVersion.revision#" & ( len( sVersion.preReleaseID ) ? "-" & sVersion.preReleaseID : '' ) ); From 3788af8a9845f9ccf51751d4e1e0f6295995b101 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 26 Apr 2016 23:44:24 -0500 Subject: [PATCH 041/129] COMMANDBOX-372 --- .../package-commands/commands/endpoint/publish.cfc | 9 +++++++-- .../package-commands/commands/package/version.cfc | 9 +++++++-- src/cfml/system/services/InterceptorService.cfc | 2 +- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/cfml/system/modules/package-commands/commands/endpoint/publish.cfc b/src/cfml/system/modules/package-commands/commands/endpoint/publish.cfc index 2caa28c07..29c15b63c 100644 --- a/src/cfml/system/modules/package-commands/commands/endpoint/publish.cfc +++ b/src/cfml/system/modules/package-commands/commands/endpoint/publish.cfc @@ -7,7 +7,8 @@ **/ component { - property name="EndpointService" inject="EndpointService"; + property name="EndpointService" inject="EndpointService"; + property name='interceptorService' inject='interceptorService'; /** * @endpointName.hint Name of the endpoint for which to publish the package @@ -18,7 +19,9 @@ component { string directory='' ) { // This will make each directory canonical and absolute arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); - + + interceptorService.announceInterception( 'prePublish', { publishArgs=arguments } ); + try { endpointService.publishEndpointPackage( argumentCollection=arguments ); @@ -28,6 +31,8 @@ component { error( e.message, e.detail ); } + interceptorService.announceInterception( 'postPublish', { publishArgs=arguments } ); + print.greenLine( 'Package published successfully in [#arguments.endpointName#]' ); } diff --git a/src/cfml/system/modules/package-commands/commands/package/version.cfc b/src/cfml/system/modules/package-commands/commands/package/version.cfc index 8e13332f8..f882c3620 100644 --- a/src/cfml/system/modules/package-commands/commands/package/version.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/version.cfc @@ -31,7 +31,7 @@ component aliases="bump" { property name='packageService' inject='PackageService'; property name='configService' inject='ConfigService'; property name='semanticVersion' inject='semanticVersion'; - property name='parser' inject='Parser'; + property name='interceptorService' inject='interceptorService'; /** * @version The new version to set into this package @@ -98,6 +98,8 @@ component aliases="bump" { function setVersion( required string version, boolean tagVersion, string message, string directory, required boolean force ) { + interceptorService.announceInterception( 'preVersion', { versionArgs=arguments } ); + command( 'package set' ) .params( version=arguments.version ) .run(); @@ -152,7 +154,10 @@ component aliases="bump" { } catch( any var e ) { logger.error( 'Error tagging Git repository with new version.', e ); error( 'Error tagging Git repository with new version.', e.message & ' ' & e.detail ); - } + } + + interceptorService.announceInterception( 'postVersion', { versionArgs=arguments } ); + } diff --git a/src/cfml/system/services/InterceptorService.cfc b/src/cfml/system/services/InterceptorService.cfc index 3a5eafc29..6fa1e99e8 100644 --- a/src/cfml/system/services/InterceptorService.cfc +++ b/src/cfml/system/services/InterceptorService.cfc @@ -34,7 +34,7 @@ component accessors=true singleton { // Error handling 'onException', // Package lifecycle - 'preInstall','postInstall','preUninstall','postUninstall' + 'preInstall','postInstall','preUninstall','postUninstall','preVersion','postVersion','prePublish','postPublish' ] ); return this; From c2be94815c8c7cacc8daff306e4273003aec20a2 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 26 Apr 2016 23:48:30 -0500 Subject: [PATCH 042/129] COMMANDBOX-374 Bump loader for new jGit jar --- build/build.properties | 2 +- src/cfml/system/{ => util}/Completor.cfc | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/cfml/system/{ => util}/Completor.cfc (100%) diff --git a/build/build.properties b/build/build.properties index fa6f36fa3..ea1d594f2 100644 --- a/build/build.properties +++ b/build/build.properties @@ -12,7 +12,7 @@ java.pack200=false #dependencies dependencies.dir=${basedir}/lib cfml.version=4.5.2.018 -cfml.loader.version=1.1.0 +cfml.loader.version=1.2.0 cfml.cli.version=${cfml.loader.version}.${cfml.version} lucee.version=4.5.2.018 jre.version=1.8.0_72 diff --git a/src/cfml/system/Completor.cfc b/src/cfml/system/util/Completor.cfc similarity index 100% rename from src/cfml/system/Completor.cfc rename to src/cfml/system/util/Completor.cfc From d7810f9fda930599f0010764b487312aef880e71 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 27 Apr 2016 00:33:52 -0500 Subject: [PATCH 043/129] COMMANDBOX-371 --- .../modules/package-commands/ModuleConfig.cfc | 3 ++ .../commands/package/version.cfc | 5 +- .../interceptors/packageScripts.cfc | 52 +++++++++++++++++++ 3 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc diff --git a/src/cfml/system/modules/package-commands/ModuleConfig.cfc b/src/cfml/system/modules/package-commands/ModuleConfig.cfc index a400988b5..e76acbebc 100644 --- a/src/cfml/system/modules/package-commands/ModuleConfig.cfc +++ b/src/cfml/system/modules/package-commands/ModuleConfig.cfc @@ -7,5 +7,8 @@ */ component { function configure() { + interceptors = [ + { class="#moduleMapping#.interceptors.packageScripts" } + ]; } } \ No newline at end of file diff --git a/src/cfml/system/modules/package-commands/commands/package/version.cfc b/src/cfml/system/modules/package-commands/commands/package/version.cfc index f882c3620..25d7e5df5 100644 --- a/src/cfml/system/modules/package-commands/commands/package/version.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/version.cfc @@ -91,7 +91,8 @@ component aliases="bump" { } else { // Output the version - runCommand( 'package show version' ); + return command( 'package show version' ) + .run( returnOutput=true ); } } @@ -150,7 +151,7 @@ component aliases="bump" { .setMessage( arguments.message ) .call(); - print.yellowLine( 'Tag [v#arguments.version#] created.' ); + print.yellowLine( 'Tag [v#arguments.version#] created.' ).toConsole(); } catch( any var e ) { logger.error( 'Error tagging Git repository with new version.', e ); error( 'Error tagging Git repository with new version.', e.message & ' ' & e.detail ); diff --git a/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc b/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc new file mode 100644 index 000000000..fa4edfdc3 --- /dev/null +++ b/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc @@ -0,0 +1,52 @@ +/** +********************************************************************************* +* Copyright Since 2014 CommandBox by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood +* +* I am an interceptor that listens to all the interception points and runs package scripts for them if they exist. +* +*/ +component { + property name="packageService" inject="packageService"; + property name="shell" inject="shell"; + property name='consoleLogger' inject='logbox:logger:console'; + + function onCLIStart() { processScripts( 'onCLIStart' ); } + function onCLIExit() { processScripts( 'onCLIExit' ); } + function preCommand() { processScripts( 'preCommand' ); } + function postCommand() { processScripts( 'postCommand' ); } + function preModuleLoad() { processScripts( 'preModuleLoad' ); } + function postModuleLoad() { processScripts( 'postModuleLoad' ); } + function preModuleUnLoad() { processScripts( 'preModuleUnLoad' ); } + function postModuleUnload() { processScripts( 'postModuleUnload' ); } + function onServerStart() { processScripts( 'onServerStart', interceptData.serverinfo.webroot ); } + function onServerStop() { processScripts( 'onServerStop', interceptData.serverinfo.webroot ); } + function onException() { processScripts( 'onException' ); } + function preInstall() { processScripts( 'preInstall' ); } + function postInstall() { processScripts( 'postInstall' ); } + function preUninstall() { processScripts( 'preUninstall' ); } + function postUninstall() { processScripts( 'postUninstall' ); } + function preVersion() { processScripts( 'preVersion' ); } + function postVersion() { processScripts( 'postVersion' ); } + function prePublish() { processScripts( 'prePublish' ); } + function postPublish() { processScripts( 'postPublish' ); } + + function processScripts( required string interceptionPoint, string directory=shell.pwd() ) { + // Read the box.json from this package (if it exists) + var boxJSON = packageService.readPackageDescriptor( arguments.directory ); + // If there is a scripts object with a matching key for this interceptor.... + if( boxJSON.keyExists( 'scripts' ) && isStruct( boxJSON.scripts ) && boxJSON.scripts.keyExists( interceptionPoint ) ) { + var thisScript = boxJSON.scripts[ interceptionPoint ]; + + consoleLogger.debug( "." ); + consoleLogger.warn( 'Running #interceptionPoint# package script.' ); + consoleLogger.debug( '> ' & thisScript ); + + // ... then run the script! + shell.callCommand( thisScript ); + } + } + +} \ No newline at end of file From 32d43031036e0eb8505f5525faebcfc5b33b05dd Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 27 Apr 2016 11:33:18 -0500 Subject: [PATCH 044/129] Run script in proper CWD. --- .../modules/package-commands/interceptors/packageScripts.cfc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc b/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc index fa4edfdc3..c598bd15a 100644 --- a/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc +++ b/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc @@ -44,8 +44,11 @@ component { consoleLogger.warn( 'Running #interceptionPoint# package script.' ); consoleLogger.debug( '> ' & thisScript ); - // ... then run the script! + // ... then run the script! (in the context of the package's working directory) + var previousCWD = shell.pwd(); + shell.cd( arguments.directory ); shell.callCommand( thisScript ); + shell.cd( previousCWD ); } } From c274c7c508ae8132d2e96a17a563863d12e52e9e Mon Sep 17 00:00:00 2001 From: denuno Date: Wed, 27 Apr 2016 14:20:36 -0600 Subject: [PATCH 045/129] initial go at #77 (multi-engine support) --- src/cfml/system/config/WireBox.cfc | 10 +- .../commands/server/forget.cfc | 1 + .../server-commands/commands/server/start.cfc | 13 + .../server-commands/commands/server/stop.cfc | 2 + .../system/services/ServerArtifactService.cfc | 194 +++++++++ src/cfml/system/services/ServerService.cfc | 111 +++++- src/cfml/system/util/cfdependency.cfc | 377 ++++++++++++++++++ tests/Application.cfc | 5 - .../services/TestServerArtifactService.cfc | 94 +++++ 9 files changed, 781 insertions(+), 26 deletions(-) create mode 100644 src/cfml/system/services/ServerArtifactService.cfc create mode 100644 src/cfml/system/util/cfdependency.cfc create mode 100644 tests/cfml/system/services/TestServerArtifactService.cfc diff --git a/src/cfml/system/config/WireBox.cfc b/src/cfml/system/config/WireBox.cfc index adfa99b5a..6a30197f1 100644 --- a/src/cfml/system/config/WireBox.cfc +++ b/src/cfml/system/config/WireBox.cfc @@ -38,6 +38,7 @@ component extends="wirebox.system.ioc.config.Binder" { system.getProperty( 'user.home' ) & "/.CommandBox/" : system.getProperty( 'cfml.cli.home' ); var tempDir = homedir & "/temp"; var artifactDir = homedir & "/artifacts"; + var serverArtifactDir = homedir & "/serverartifacts"; var userDir = system.getProperty( "user.dir" ); var commandHistoryFile = homedir & "/.history-command"; var REPLScriptHistoryFile = homedir & "/.history-repl-script"; @@ -50,7 +51,12 @@ component extends="wirebox.system.ioc.config.Binder" { ]; var ortusArtifactsURL = 'http://integration.stg.ortussolutions.com/artifacts/'; var ortusPRDArtifactsURL = 'http://downloads.ortussolutions.com/'; - + // engine versions, first is default - for lucee, first is internal version + var cfengineVersions = { + "lucee":["4.5.2.018","5.0.0.243-SNAPSHOT"] + ,"adobe":["11.0.0.289974","2016.0.0.297996","10.0.12.286680","9.0.2.282541"] + ,"railo":["4.2.1.008"] + }; // map constants map( 'system@constants' ).toValue( system ); @@ -66,6 +72,8 @@ component extends="wirebox.system.ioc.config.Binder" { map( 'ortusArtifactsURL@constants' ).toValue( ortusArtifactsURL ); map( 'ortusPRDArtifactsURL@constants' ).toValue( ortusPRDArtifactsURL ); map( 'rewritesDefaultConfig@constants' ).toValue( "#homeDir#/cfml/system/config/urlrewrite.xml" ); + map( 'serverArtifactDir@constants' ).toValue( serverArtifactDir ); + map( 'cfengineVersions@constants' ).toValue( cfengineVersions ); // Map Java Classes map( 'commandHistoryFile@java' ).toJava( "jline.console.history.FileHistory" ) diff --git a/src/cfml/system/modules/server-commands/commands/server/forget.cfc b/src/cfml/system/modules/server-commands/commands/server/forget.cfc index 3c73e2537..d9871518a 100644 --- a/src/cfml/system/modules/server-commands/commands/server/forget.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/forget.cfc @@ -29,6 +29,7 @@ component { Boolean force=false ){ // Discover by shortname or webroot + arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); var serverInfo = serverService.getServerInfoByDiscovery( arguments.directory, arguments.name ); // Verify server info diff --git a/src/cfml/system/modules/server-commands/commands/server/start.cfc b/src/cfml/system/modules/server-commands/commands/server/start.cfc index 9249f11ac..441d4e8aa 100644 --- a/src/cfml/system/modules/server-commands/commands/server/start.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/start.cfc @@ -31,6 +31,10 @@ component aliases="start" { * @stopPort stop socket listener port number * @force force start if status is not stopped * @debug sets debug log level + * @cfengine sets the cfml engine type + * @cfengine.optionsUDF cfengineNameComplete + * @cfengineVersion sets the cfml engine version + * @cfengineVersion.optionsUDF cfengineVersionComplete * @webConfigDir custom location for web context configuration * @serverConfigDir custom location for server configuration * @libDirs comma-separated list of extra lib directories for the server @@ -59,6 +63,8 @@ component aliases="start" { Numeric stopPort, Boolean force, Boolean debug, + String cfengine, + String WARPath, String webConfigDir, String serverConfigDir, String libDirs, @@ -92,4 +98,11 @@ component aliases="start" { return serverService.getServerNames(); } + /** + * Complete cfengine names + */ + function cfengineNameComplete() { + return serverService.getCFEngineNames(); + } + } \ No newline at end of file diff --git a/src/cfml/system/modules/server-commands/commands/server/stop.cfc b/src/cfml/system/modules/server-commands/commands/server/stop.cfc index adce8996e..fb80171d4 100644 --- a/src/cfml/system/modules/server-commands/commands/server/stop.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/stop.cfc @@ -26,9 +26,11 @@ component aliases="stop" { boolean forget=false, boolean all=false ){ + if( arguments.all ) { var servers = serverService.getServers(); } else { + arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); // Discover by shortname or webroot and get server info var servers = { id: serverService.getServerInfoByDiscovery( directory = arguments.directory, diff --git a/src/cfml/system/services/ServerArtifactService.cfc b/src/cfml/system/services/ServerArtifactService.cfc new file mode 100644 index 000000000..eb4128a57 --- /dev/null +++ b/src/cfml/system/services/ServerArtifactService.cfc @@ -0,0 +1,194 @@ +/** +********************************************************************************* +* Copyright Since 2005 ColdBox Platform by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood, Luis Majano, Denny Valliant +* +* I handle artifacts, which are basically just a cache of downloaded packages. +* +* Artifacts are stored in this format: +* /packageName/version/packageName.zip +* +* We are not currently using a group ID, but we may need to in the future +* +*/ +component accessors="true" singleton="true" { + + // DI + property name='artifactDir' inject='serverArtifactDir@constants'; + property name='tempDir' inject='tempDir@constants'; + property name='packageService' inject='PackageService'; + property name='logger' inject='logbox:logger:{this}'; + property name='consoleLogger' inject='logbox:logger:console'; + property name="cfdependency" inject="cfdependency"; + property name="cfengineVersions" inject="cfengineVersions@constants"; + property name='cr' inject='cr@constants'; + + /** + * DI complete + */ + function onDIComplete() { + // Create the artifacts directory if it doesn't exist + if( !directoryExists( variables.artifactDir ) ) { + directoryCreate( variables.artifactDir ); + } + cfdependency.setLocalRepositoryPath(variables.artifactDir); + cfdependency.addRemoteRepository( "ortusstaging", "http://integration.staging.ortussolutions.com/artifacts/" ); + } + + /** + * Gets the path for the local artifact + * @artifact artifact coordinates to get path for` + **/ + public function getPathForLocalArtifact( required artifact ) { + var artifactPath = cfdependency.getPathForLocalArtifact(artifact); + return artifactPath; + } + + /** + * Checks engine and version, returning default version if version is empty + * @cfengine CFML Engine name (lucee, adobe, railo) + * @version Version number or empty to get default + **/ + public function checkVersion( required cfengine, required version) { + if(isNull(cfengineVersions[cfengine])) { + throw( message="unknown cfengine type: " & cfengine ); + } + if(version == "") { + version = cfengineVersions[cfengine][1]; + } else { + var versions = cfengineVersions[cfengine]; + var valid = false; + for(var ver in versions) { + if(ver.toLowerCase().startsWith(lcase(version))) { + version = ver; + valid = true; + } + } + if(!valid) { + throw( message="unknown #cfengine# version: " & version ); + } + } + return version; + } + + /** + * install the server if not already installed to the target directory + * @cfengine CFML Engine name (lucee, adobe, railo) + * @basedirectory base directory for server install + * @version Version number or empty to use default + **/ + public function install( required cfengine, required basedirectory, force=false) { + version = find("@",cfengine) ? listLast(cfengine,"@") : ""; + cfengine = listFirst(cfengine,"@"); + basedirectory = !basedirectory.endsWith("/") ? basedirectory & "/" : basedirectory; + var engineVersion = checkVersion(cfengine=cfengine,version=version); + var installDir = basedirectory & cfengine & "-" & engineVersion; + if(!fileExists(installDir & "/WEB-INF/web.xml") || force) { + consoleLogger.info("Installing #cfengine# #engineVersion# in #installDir#"); + if( cfengine == "adobe" ) { + installAdobe( destination=installDir, version=engineVersion ); + } else if (cfengine == "railo") { + installRailo( destination=installDir, version=engineVersion ); + } else if (cfengine == "lucee") { + installLucee( destination=installDir, version=engineVersion ); + } else { + throw( message="unknown engine type:" & cfengine ); + } + } else { + consoleLogger.info("Using #cfengine# in #installDir#"); + } + return installDir; + } + + /** + * install adobe + * @destination target directory + * @version Version number or empty to use default + **/ + public function installAdobe( required destination, required version ) { + var artifact = "com.adobe:coldfusion:war:#version#"; + var compat = "com.adobe:coldfusion:zip:compat:#version#"; + if(left(version,2) == 10 || left(version,2) == 11 || left(version,4) == 2016) { + var compat = "com.adobe:coldfusion:zip:compat:11.0.0.289974"; + var artifactPath = cfdependency.get(dependencies=[artifact,compat], dest=destination, unzip=true); + } else { + var artifactPath = cfdependency.get(dependencies=[artifact], dest=destination, unzip=true); + } + // set password to "commandbox" + fileWrite(destination & "/WEB-INF/cfusion/lib/password.properties", + "rdspassword=#cr#password=commandbox#cr#encrypted=false"); + return artifactPath; + } + + /** + * install lucee + * @destination target directory + * @version Version number or empty to use default + **/ + public function installLucee( required destination, required version ) { + var artifact = "org.lucee:lucee.war:war:#version#"; + var artifactPath = cfdependency.get(dependencies=[artifact], dest=destination, unzip=true); + configureWebXML(cfengine="lucee",source="#destination#/WEB-INF/web.xml",destination="#destination#/WEB-INF/web.xml"); + return artifactPath; + } + + /** + * install railo + * @destination target directory + * @version Version number or empty to use default + **/ + public function installRailo( required destination, required version ) { + var artifact = "org.getrailo:railo.war:war:#version#"; + var artifactPath = cfdependency.get(dependencies=[artifact], dest=destination, unzip=true); + configureWebXML(cfengine="railo",source="#destination#/WEB-INF/web.xml",destination="#destination#/WEB-INF/web.xml"); + return artifactPath; + } + + /** + * configure web.xml file for Lucee and Railo + * @cfengine lucee or railo + * @source source web.xml + * @destination target web.xml + **/ + public function configureWebXML(required cfengine, required source, destination) { + var webXML = XMLParse(source); + var servlets = xmlSearch(webXML,"//:servlet-class[text()='#lcase(cfengine)#.loader.servlet.CFMLServlet']"); + var initParam = xmlElemnew(webXML,"http://java.sun.com/xml/ns/javaee","init-param"); + initParam.XmlChildren[1] = xmlElemnew(webXML,"param-name"); + initParam.XmlChildren[1].XmlText = "#lcase(cfengine)#-web-directory"; + initParam.XmlChildren[2] = xmlElemnew(webXML,"param-value"); + initParam.XmlChildren[2].XmlText = "/WEB-INF/#lcase(cfengine)#/{web-context-label}"; + arrayInsertAt(servlets[1].XmlParent.XmlChildren,4,initParam); + var xlt = ' + + + + '; + fileWrite(destination,toString(XmlTransform(webXML,xlt))); + return true; + } + + /** + * Dynamic completion for cfengine + */ + function getCFEngineNames() { + var engineNames = ["lucee","adobe","railo"]; + var namesAndVersions = []; + for (var name in engineNames) { + for (var version in cfengineVersions[name]) { + arrayAppend(namesAndVersions,name & "@" & ucase(version)); + } + } + return namesAndVersions; + } + + /** + * Dynamic completion for cfengine + */ + function getCFEngineVersions(required cfengine) { + return cfengineVersions[cfengine]; + } + +} \ No newline at end of file diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 36b0a9d8b..7007b66d7 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -43,8 +43,10 @@ component accessors="true" singleton { property name='interceptorService' inject='interceptorService'; property name='JSONService' inject='JSONService'; property name='packageService' inject='packageService'; + property name='serverArtifactService' inject='serverArtifactService'; property name='consoleLogger' inject='logbox:logger:console'; property name='wirebox' inject='wirebox'; + property name="cfengineVersions" inject="cfengineVersions@constants"; /** * Constructor @@ -144,7 +146,10 @@ component accessors="true" singleton { libDirs : '', webConfigDir : '', serverConfigDir :variables.serverHomeDirectory, - webXML : '' + webXML : '', + standalone : false, + WARPath : "", + cfengine : "lucee" }, runwar : { args : '' @@ -161,22 +166,26 @@ component accessors="true" singleton { Struct serverProps ){ + if(isNull(serverProps.name)) { + serverProps.name = listLast( serverProps.directory, "\/" ); + } + // Discover by shortname or server and get server info var serverInfo = getServerInfoByDiscovery( directory = serverProps.directory, - name = serverProps.name ?: '' + name = serverProps.name ); // Was it found, or new server? if( structIsEmpty( serverInfo ) ){ // We need a new entry - serverInfo = getServerInfo( serverProps.directory ); + serverInfo = getServerInfo( serverProps.directory, serverProps.name ); } // Get package descriptor var boxJSON = packageService.readPackageDescriptor( serverInfo.webroot ); // Get server descriptor - var serverJSON = readServerJSON( serverInfo.webroot ); + var serverJSON = readServerJSON( serverInfo.webroot , serverProps.name); // Get defaults var defaults = getDefaultServerJSON(); @@ -197,6 +206,9 @@ component accessors="true" singleton { for( var prop in serverProps ) { if( !isNull( serverProps[ prop ] ) && prop != 'directory' && prop != 'saveSettings' ) { switch(prop) { + case "name": + serverJSON[ 'name' ] = serverProps[ prop ]; + break; case "port": serverJSON[ 'web' ][ 'http' ][ 'port' ] = serverProps[ prop ]; break; @@ -218,6 +230,12 @@ component accessors="true" singleton { case "webXML": serverJSON[ 'app' ][ 'webXML' ] = serverProps[ prop ]; break; + case "cfengine": + serverJSON[ 'app' ][ 'cfengine' ] = serverProps[ prop ]; + break; + case "WARPath": + serverJSON[ 'app' ][ 'WARPath' ] = serverProps[ prop ]; + break; case "HTTPEnable": serverJSON[ 'web' ][ 'HTTP' ][ 'enable' ] = serverProps[ prop ]; break; @@ -265,9 +283,9 @@ component accessors="true" singleton { // Setup serverinfo according to params // Hand-entered values take precendence, then settings saved in server.json, and finally defaults. // The big servers.json is only used to keep a record of the last values the server was started with + serverInfo.name = serverProps.name; serverInfo.debug = serverProps.debug ?: serverJSON.debug ?: defaults.debug; serverInfo.openbrowser = serverProps.openbrowser ?: serverJSON.openbrowser ?: defaults.openbrowser; - serverInfo.name = serverProps.name ?: listLast( serverInfo.webroot, "\/" ); serverInfo.host = serverProps.host ?: serverJSON.web.host ?: defaults.web.host; serverInfo.port = serverProps.port ?: serverJSON.web.http.port ?: getRandomPort( serverInfo.host ); serverInfo.stopsocket = serverProps.stopsocket ?: serverJSON.stopsocket ?: getRandomPort( serverInfo.host ); @@ -276,6 +294,8 @@ component accessors="true" singleton { serverInfo.libDirs = serverProps.libDirs ?: serverJSON.app.libDirs ?: defaults.app.libDirs; serverInfo.trayIcon = serverProps.trayIcon ?: serverJSON.trayIcon ?: defaults.trayIcon; serverInfo.webXML = serverProps.webXML ?: serverJSON.app.webXML ?: defaults.app.webXML; + serverInfo.cfengine = serverProps.cfengine ?: serverJSON.app.cfengine ?: defaults.app.cfengine; + serverInfo.WARPath = serverProps.WARPath ?: serverJSON.app.WARPath ?: defaults.app.WARPath; serverInfo.SSLEnable = serverProps.SSLEnable ?: serverJSON.web.SSL.enable ?: defaults.web.SSL.enable; serverInfo.HTTPEnable = serverProps.HTTPEnable ?: serverJSON.web.HTTP.enable ?: defaults.web.HTTP.enable; serverInfo.SSLPort = serverProps.SSLPort ?: serverJSON.web.SSL.port ?: defaults.web.SSL.port; @@ -307,16 +327,41 @@ component accessors="true" singleton { // The process native name var processName = serverInfo.name is "" ? "CommandBox" : serverInfo.name; + var javaagent = serverinfo.cfengine == "lucee" ? "" : "-javaagent:""#libdir#/lucee-inst.jar"""; + if( serverInfo.cfengine != "lucee" && serverInfo.cfengine != "lucee@" & cfengineVersions["lucee"][1]){ + try { + installDir = serverArtifactService.install( cfengine=serverInfo.cfengine, basedirectory=serverInfo.webConfigDir ); + } catch (any e) { + consoleLogger.error("Error installing server - " & e.message); + consoleLogger.error(e.detail.replaceAll(",","#chr(10)#")); + return; + } + if(serverInfo.cfengine == "lucee") { + javaagent = "-javaagent:""#installDir#/WEB-INF/lib/lucee-inst.jar"""; + } + if(serverInfo.cfengine == "railo") { + javaagent = "-javaagent:""#installDir#/WEB-INF/lib/railo-inst.jar"""; + } + } + // The java arguments to execute: Shared server, custom web configs var args = " #serverInfo.JVMargs# -Xmx#serverInfo.heapSize#m -Xms#serverInfo.heapSize#m" - & " -javaagent:""#libdir#/lucee-inst.jar"" -jar ""#variables.jarPath#""" - & " -war ""#serverInfo.webroot#"" --background=true --port #serverInfo.port# --host #serverInfo.host# --debug #serverInfo.debug#" + & " #javaagent# -jar ""#variables.jarPath#""" + & " --background=true --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 http://#serverInfo.host#:#serverInfo.port#" - & " --cfengine-name lucee --server-name ""#serverInfo.name#"" --lib-dirs ""#libDirs#""" + & " --cfengine-name #serverInfo.cfengine# --server-name ""#serverInfo.name#""" & " --tray-icon ""#serverInfo.trayIcon#"" --tray-config ""#libdir#/traymenu.json""" & " --directoryindex ""#serverInfo.directoryBrowsing#"" --cfml-web-config ""#serverInfo.webConfigDir#""" - & " --cfml-server-config ""#serverInfo.serverConfigDir#"" #serverInfo.runwarArgs# "; + & " --cfml-server-config ""#serverInfo.serverConfigDir#"" #serverInfo.runwarArgs# "; + // standalone or not + if( serverInfo.cfengine != "lucee" && serverInfo.cfengine != "lucee@" & cfengineVersions["lucee"][1]){ + args &= " -war ""#serverInfo.webroot#"" --lib-dirs ""#installDir#/WEB-INF/lib"" --web-xml-path ""#installDir#/WEB-INF/web.xml"""; + } else if (serverInfo.WARPath != "") { + args &= " -war ""#serverInfo.webroot#"""; + } else { + args &= " -war ""#serverInfo.webroot#"" --lib-dirs ""#libDirs#"""; + } // Incorporate SSL to command if( serverInfo.SSLEnable ){ args &= " --http-enable #serverInfo.HTTPEnable# --ssl-enable #serverInfo.SSLEnable# --ssl-port #serverInfo.SSLPort#"; @@ -345,6 +390,9 @@ component accessors="true" singleton { // change status to starting + persist serverInfo.status = "starting"; setServerInfo( serverInfo ); + if(serverInfo.debug) { + consoleLogger.debug("Server start command: #javaCommand# #args#"); + } // thread the execution var threadName = 'server#hash( serverInfo.webroot )##createUUID()#'; thread name="#threadName#" serverInfo=serverInfo args=args { @@ -367,6 +415,7 @@ component accessors="true" singleton { } } + // She'll be coming 'round the mountain when she comes... consoleLogger.warn( "The server for #serverInfo.webroot# is starting on #serverInfo.host#:#serverInfo.port#... type 'server status' to see result" ); @@ -424,10 +473,11 @@ component accessors="true" singleton { if( !arguments.all ){ var servers = getServers(); var serverdir = getCustomServerFolder( arguments.serverInfo ); - var serverJSONPath = arguments.serverInfo.webroot & '/server.json'; + var defaultServerJSONPath = arguments.serverInfo.webroot & '/server.json'; + var serverJSONPath = arguments.serverInfo.webroot & '/server-#arguments.serverInfo.name#.json'; // try to delete from config first - structDelete( servers, hash( arguments.serverInfo.webroot ) ); + structDelete( servers, hash( arguments.serverInfo.webroot & arguments.serverInfo.name ) ); setServers( servers ); // try to delete server if( directoryExists( serverDir ) ){ @@ -445,6 +495,9 @@ component accessors="true" singleton { if( fileExists( serverJSONPath ) ) { fileDelete( serverJSONPath ); } + if( fileExists( defaultServerJSONPath ) ) { + fileDelete( defaultServerJSONPath ); + } // return message return "Poof! Wiped out server " & serverInfo.name; } else { @@ -490,7 +543,7 @@ component accessors="true" singleton { **/ function setServerInfo( required struct serverInfo ){ var servers = getServers(); - var webrootHash = hash( arguments.serverInfo.webroot ); + var webrootHash = hash( arguments.serverInfo.webroot & arguments.serverInfo.name); if( arguments.serverInfo.webroot == "" ){ throw( "The webroot cannot be empty!" ); @@ -524,7 +577,7 @@ component accessors="true" singleton { for( var thisKey in results ){ // Backwards compat-- add in server id if it doesn't exist for older versions of CommandBox if( isNull( results[ thisKey ].id ) ){ - results[ thisKey ].id = hash( results[ thisKey ].webroot ); + results[ thisKey ].id = hash( results[ thisKey ].webroot & results[ thisKey ].name ); updateRequired = true; } // Future-proof server info by guaranteeing that all properties will exist in the @@ -548,7 +601,10 @@ component accessors="true" singleton { struct function getServerInfoByDiscovery( required directory="", required name="" ){ // Discover by shortname or webroot if( len( arguments.name ) ){ - return getServerInfoByName( arguments.name ); + var foundServer = getServerInfoByName( arguments.name ); + if(!isNull(foundServer)) { + return foundServer; + } } var webroot = arguments.directory is "" ? shell.pwd() : arguments.directory; @@ -599,9 +655,9 @@ component accessors="true" singleton { * Get server info for webroot, if not created, it will init a new server info entry * @webroot.hint root directory for served content **/ - struct function getServerInfo( required webroot ){ + struct function getServerInfo( required webroot , required name){ var servers = getServers(); - var webrootHash = hash( arguments.webroot ); + var webrootHash = hash( arguments.webroot & arguments.name); var statusInfo = {}; if( !directoryExists( arguments.webroot ) ){ @@ -667,10 +723,13 @@ component accessors="true" singleton { * Read a server.json file. If it doesn't exist, returns an empty struct * This only returns properties specifically set in the file. */ - struct function readServerJSON( required string directory ) { - var filePath = arguments.directory & '/server.json'; - if( fileExists( filePath ) ) { - return deserializeJSON( fileRead( filePath ) ); + struct function readServerJSON( required string directory , string name="") { + var defaultServerJSON = arguments.directory & '/server.json'; + var serverJSON = arguments.directory & '/server-#name#.json'; + if( fileExists( serverJSON ) ) { + return deserializeJSON( fileRead( serverJSON ) ); + } else if(fileExists( defaultServerJSON )) { + return deserializeJSON( fileRead( defaultServerJSON ) ); } else { return {}; } @@ -681,9 +740,21 @@ component accessors="true" singleton { */ function saveServerJSON( required string directory, required struct data ) { var filePath = arguments.directory & '/server.json'; + if(fileExists(filePath)) { + var existingProps = readServerJSON(directory); + if(!isNull(data.name) && (isNull(existingProps.name) || existingProps.name != data.name)) { + filePath = arguments.directory & '/server-#data.name#.json'; + } + } fileWrite( filePath, formatterUtil.formatJSON( serializeJSON( arguments.data ) ) ); } + /** + * Dynamic completion for cfengine + */ + function getCFEngineNames() { + return serverArtifactService.getCFEngineNames(); + } /** * Dynamic completion for property name based on contents of server.json diff --git a/src/cfml/system/util/cfdependency.cfc b/src/cfml/system/util/cfdependency.cfc new file mode 100644 index 000000000..0294323ed --- /dev/null +++ b/src/cfml/system/util/cfdependency.cfc @@ -0,0 +1,377 @@ +component { + + cfdependency.version = "2.0.0"; + + function init(localRepo=getDirectoryFromPath(getMetadata(this).path) & "/repo", repositories="default", javatools = false) { + localRepositoryPath = localRepo; + remotes = []; + paths = {}; + thisdir = getDirectoryFromPath(getMetadata(this).path); + if(isSimpleValue(repositories) && repositories == "default") { + addDefaultRepositories(); + } else { + for(var repo in repositories){ + addRemoteRepository(repo.name,repo.url,repo.type); + } + } + if(javatools) { + get(["cfml:javatools:zip:1.1.0"]); + } + } +/* + * AETHER + **/ + + function onMissingMethod( methodName, methodArguments ) { + if(isNull(aether)) { + if(!fileExists(localRepositoryPath & "org/cfmlprojects/aether/#cfdependency.version#/aether-#cfdependency.version#.jar")) { + get(["cfml:javatools:zip:1.1.0"]); + get(["org.cfmlprojects:aether:jar:#cfdependency.version#"]); + } + javaloader = create("cfml:javatools","LibraryLoader").init(pathlist=thisdir & "aether/lib/", id="aether-classloader"); + aether = new aether.Aether(localPath=localRepositoryPath, javaloader=javaloader, repositories=remotes); + } + return aether.callMethod(argumentCollection=arguments); + } + +/* + * /AETHER + **/ + + public function setLocalRepositoryPath(required path) { + localRepositoryPath = path; + } + + public function create(required dependency, required componentName, args) { +// return new "#paths[dependency]#.#componentName#" (argumentColection = args); + return createObject("#paths[dependency].cfcPath#.#componentName#"); + } + public function dirFor(required dependency) { + return createObject("#paths[dependency].directory#"); + } + + public function get(required array dependencies, dest="", unzip = "", transitive=true) { + var artifacts = simpleResolve(dependencies=dependencies,transitive=transitive); + var managedDest = dest == "" ? true : false; + var directories = ""; + if (dest == "") { + dest = expandPath("/WEB-INF/cfdependency"); + if(!directoryExists(dest)) { + directoryCreate(dest); + } + } + for(var artifact in artifacts) { + var file = artifact.file; + var versionSafe = rereplace(artifact.version,"[\.-]","_","all"); + var groupDir = replace(artifact.groupId,".","/","all"); + var todir = managedDest ? dest & "/#groupDir#/#artifact.artifactId#/#versionSafe#" : dest; + artifact.directory = todir; + directories = listContains(directories,todir) ? directories : listAppend(directories,todir); + paths["#artifact.groupId#:#artifact.artifactId#"] = { + cfcPath = "WEB-INF.cfdependency.#artifact.groupId#.#artifact.artifactId#.#versionSafe#", + directory = todir + }; + if(!directoryExists(todir)) { + directoryCreate(todir,true); + } + if(file.endsWith(".zip") && unzip == "") { + unzip = true; + } + unzip = unzip == "" ? false : unzip; + if(unzip && zipContentDiffers(file,dest)) { + zip action="unzip" file="#file#" destination="#todir#" overwrite=true; + } else { + fileCopy(file,todir); + } + } + return {artifacts = artifacts, directories = directories}; + } + + public function simpleResolve(required dependencies, Boolean transitive = true, scope="runtime") { + var artifacts = []; + if(isArray(dependencies)) { + for(var afact in dependencies) { + var arrayFiles = simpleResolve(afact,transitive,scope); + for(var file in arrayFiles) { + arrayAppend(artifacts,file); + } + } + return artifacts; + } + var artifact = toArtifact(dependencies); + var artifactPom = toPomArtifact(dependencies); + var filePath = getPathForLocalArtifact(dependencies); + artifact.file = filePath; + if(artifact.version.endsWith("SNAPSHOT") || !fileExists(filePath) || !hashMatch(filePath)) { + var pomfile = getRemoteArtifact(artifactPom); + artifact.file = getRemoteArtifact(dependencies); + arrayAppend(artifacts,artifact); + if(transitive) { + var mavenData = xmlParse(pomFile); + var deps = xmlSearch(mavendata,"//*[name() = 'project']/*[name()='dependencies']/*[name()='dependency']"); + for(var depXml in deps) { + var dep = {}; + for(var el in depXML.XmlChildren) { + dep[el.xmlName] = el.xmlText; + } + if(!isNull(dep.version) && (isNull(dep.scope) || dep.scope == scope)) { + var depArtifact = toArtifact(dep); + depArtifact.file = getRemoteArtifact(depArtifact); + arrayAppend(artifacts, depArtifact); + } + } + } + } else { + arrayAppend(artifacts,artifact); + } + return artifacts; + } + + public function addRemoteRepository(required name,required repourl, type="default"){ + var repo = { name : name, type: type, repourl: repourl }; + arrayAppend(variables.remotes,repo); + if(!isNull(aether)) + aether.addRemoteRepository(name,repourl,type); + } + + private function addDefaultRepositories(){ + var userHome = createObject("java","java.lang.System").getProperty("user.home"); + addRemoteRepository( "cfdistro", "file://#userHome#/cfdistro/artifacts/" ); + addRemoteRepository( "cfmlprojects", "http://cfmlprojects.org/artifacts/" ); + addRemoteRepository( "central", "http://repo1.maven.org/maven2/" ); + } + + public function toArtifact( Required coords, Struct properties={} ) { + var artifact = {groupId:"", artifactId:"", extension:"jar", classifier:"", version:""}; + if(isStruct(coords)) { + structAppend(artifact,coords); + return artifact; + } + var java = { + Pattern : createObject("java","java.util.regex.Pattern") + }; + var p = java.Pattern.compile( "([^: ]+):([^: ]+)(:([^: ]*)(:([^: ]+))?)?:([^: ]+)" ); + var m = p.matcher( coords ); + if ( !m.matches() ){ + throw( message = "Bad artifact coordinates " & coords + & ", expected format is :[:[:]]:" ); + } + artifact.groupId = m.group( 1 ); + artifact.artifactId = m.group( 2 ); + artifact.extension = isEmpty(m.group( 4 )) ? "jar" : m.group( 4 ); + artifact.type = artifact.extension; + artifact.classifier = isEmpty(m.group( 6 )) ? "" : m.group( 6 ); + artifact.version = m.group( 7 ); + artifact.file = ""; + artifact.properties = properties; + return artifact; + } + + public function toPomArtifact( required artifact ) { + artifact = toArtifact(artifact); + var pom = duplicate(artifact); + pom.extension = "pom"; + pom.type = artifact.extension; + pom.classifier = ""; + return pom; + } + + public function getPathForArtifact( Required artifact ) { + artifact = toArtifact(artifact); + var slashGroupId = replace( artifact.groupId, ".", "/", "all" ); + var classifierPath = artifact.classifier == "" ? "" : "-#artifact.classifier#"; + var artifactPath = "#slashGroupId#/#artifact.artifactId#/#artifact.version#/#artifact.artifactId#-#artifact.version##classifierPath#.#artifact.extension#"; + return artifactPath; + } + + public function getPathForLocalArtifact( Required artifact ) { + var artifactPath = localRepositoryPath & "/" & getPathForArtifact(artifact); + return artifactPath; + } + + private function getRemoteArtifact(artifact) { + artifact = toArtifact(artifact); + var filePath = getPathForArtifact(artifact); + var mavenMetaPath = getDirectoryFromPath(filePath).replaceAll(artifact.version&"\/$","") & "maven-metadata.xml"; + var mavenMetaFile = getRemoteFile(mavenMetaPath); + mavenMetaPath = getDirectoryFromPath(filePath) & "maven-metadata.xml"; + try { + mavenMetaFile = getRemoteFile(mavenMetaPath); + } catch(any e) { + // not all artifacts have a maven-metadata.xml, but snapshots should for sure + } + if(artifact.version.toUpperCase().endsWith("SNAPSHOT")) { + var snapshot = getSnapshotVersion(mavenMetaFile); + filePath = rereplace(filePath,"SNAPSHOT\.(.+)","#snapshot#.\1"); + getRemoteFile(filePath); + } else { + getRemoteFile(filePath); + } + return localRepositoryPath & "/" & filePath; + } + + private function getRemoteFile(filepath) { + var localPath = localRepositoryPath & "/" & filepath; + logMessage( "resolving #filepath# (#localPath#)" ); + if(hashMatch(localPath)) { + logMessage( "already resolved #filepath# (#localPath#)" ); + return localPath; + } + for(var repository in remotes) { + logMessage( "Trying remote repository #repository.name#..." ); + var fileUrl = repository.repourl & filepath; + logMessage( "Downloading #fileUrl#..." ); + if(!directoryExists(getDirectoryFromPath(localPath))) + directoryCreate(getDirectoryFromPath(localPath)); + httpGet("#fileUrl#.md5","#localPath#.md5"); + httpGet("#fileUrl#.sha1","#localPath#.sha1"); +// createObject("java","java.lang.System").out.println("Getting #fileURL# to #localPath#"); + httpGet("#fileUrl#","#localPath#"); + if( hashMatch(localPath)) { + break; + } else { + if(fileExists(localPath)) { + var hashes = lcase(serializeJSON(getHash(localPath))); + logMessage( "incorrect hash for #localPath# #hashes#" ); + } + } + } + if( !hashMatch(localPath)) { + var hashes = lcase(serializeJSON(getHash(localPath))); + logMessage( "could not get #filePath# or hash incorrect #hashes#" ); + throw(message="could not get #filePath# or hash incorrect #hashes#",detail=messages.toString()); + } + return localPath; + } + + public function httpGet(uri,toFile){ + var httpResult = ""; + if(uri.startsWith("file:")) { + if(fileExists(uri)) { + fileCopy(uri,toFile); + logMessage("Copied #uri# to #toFile#"); + } + } else { + http url=uri file=toFile result="httpResult" timeout="300" getAsBinary="true"; + if(httpResult.status_code != 200) { + fileDelete(toFile); + logMessage("#httpResult.statuscode# error for #uri#"); + } else { + logMessage("Downloaded #uri# to #toFile#"); + } + } + } + + private function getSnapshotVersion(mavenMetaFile) { + var mavenData = xmlParse(mavenMetaFile); + var snapshots = xmlSearch(mavendata,"//*[name() = 'metadata']/*[name() = 'versioning']/*[name()='snapshot']"); + return snapshots[1].XmlChildren[1].XmlText & "-" & snapshots[1].XmlChildren[2].XmlText; + } + + private Boolean function hashMatch(filePath) { + var hashes = getHash(filePath); + var fileHash = hashes.fileHash; + var goodHash = hashes.goodHash; + if( fileHash != "" && fileHash == goodHash) { + return true; + } + return false; + } + + private any function getHash(filePath) { + if(fileExists("#filePath#.sha1") && fileExists(filePath)) { + var fileHash = lcase(hash(fileReadBinary(filePath),"sha1")); + var goodHash = lcase(fileRead(filePath & ".sha1")); + } else if(fileExists("#filePath#.md5") && fileExists(filePath)) { + var fileHash = lcase(hash(fileReadBinary(filePath),"md5")); + var goodHash = lcase(fileRead(filePath & ".md5")); + } else { + var fileHash = ""; + var goodHash = ""; + } + return {fileHash:fileHash,goodHash:goodHash}; + } + + private Boolean function hasValidHash(artifact) { + var filePath = getPathForLocalArtifact(artifact); + return hashMatch(filePath); + } + + public function zipContentDiffers(zipfile,targetDirectory) { + var zf = createObject("java","java.util.zip.ZipFile").init(zipFile); + var e = zf.entries(); + while (e.hasMoreElements()) { + var ze = e.nextElement(); + if(!fileExists(targetDirectory & "/#ze.getName()#")) { + return true; + } + if(!ze.isDirectory()) { + var crc = crc32(targetDirectory & "/#ze.getName()#"); + if(ze.getCrc() != crc) { + return true; + } + } + } + zf.close(); + return false; + } + + function crc322(file) { + var input = fileReadBinary(file); + var bytes = input; + var java = { + CRC32 = createObject("java","java.util.zip.CRC32") + }; + var checksum = java.CRC32.init(); + checksum.reset(); + checksum.update(bytes, 0, len(bytes)); + var checksumValue = checksum.getValue(); + return checksumValue; + } + + + public function crc32(file) { + var java = { + CRC32 = createObject("java","java.util.zip.CRC32") + ,BufferedInputStream = createObject("java","java.io.BufferedInputStream") + ,ByteArrayOutputStream = createObject("java","java.io.ByteArrayOutputStream") + ,ReflectArray = createObject("java","java.lang.reflect.Array") + ,FileInputStream = createObject("java","java.io.FileInputStream") + ,File = createObject("java","java.io.File") + ,Long = createObject("java","java.lang.Long") + }; + var bis = java.BufferedInputStream.init(java.FileInputStream.init(java.File.init(arguments.file))); + var read = 0; + var checksum = java.CRC32.init(); + var buffer = java.ByteArrayOutputStream.init().toByteArray().getClass().getComponentType(); + buffer = java.ReflectArray.newInstance(buffer, 4096); + while ((read = bis.read(buffer)) != -1) { + checksum.update(buffer, 0, read); + } + bis.close(); + return checksum.getValue(); + } + + public function logMessage(message){ + if(isNull(messages)) { + messages = []; + } + arrayAppend(messages,message); + } + + public function getInstance(){ + if ( instance == null ){ + lock type="exclusive" timeout="3" { + if ( isNull(instance) ){ + instance = new Manager(); + } + } + } + return instance; + } + + public function dropInstance(){ + instance = javacast("null",""); + } + +} \ No newline at end of file diff --git a/tests/Application.cfc b/tests/Application.cfc index 9c4f05a89..f9c79b8c0 100644 --- a/tests/Application.cfc +++ b/tests/Application.cfc @@ -6,11 +6,6 @@ component { this.sessionmanagement="true"; // mappings - this.mappings[ "/tests" ] = getDirectoryFromPath( getCurrentTemplatePath() ); - this.mappings[ '/testbox' ] = 'testbox'; - this.mappings[ '/commandbox' ] = '../src/cfml'; - this.mappings[ '/wirebox' ] = '../src/cfml/system/wirebox'; - this.mappings[ '/mxunit' ] = 'testbox/system/testing/compat'; boolean function onRequestStart( required targetPage ){ new wirebox.system.ioc.Injector( 'tests.config.WireBox' ); diff --git a/tests/cfml/system/services/TestServerArtifactService.cfc b/tests/cfml/system/services/TestServerArtifactService.cfc new file mode 100644 index 000000000..76460d12f --- /dev/null +++ b/tests/cfml/system/services/TestServerArtifactService.cfc @@ -0,0 +1,94 @@ +component extends="mxunit.framework.TestCase" { + + public void function beforeTests() { + workDir = expandPath("/tests/work"); + resourceDir = expandPath("/tests/resource"); + if(directoryExists(workDir)){ + directoryDelete(workDir,true); + } + directoryCreate(workDir); + } + + public void function setUp() { + //application.wirebox.clearSingletons(); + setting requesttimeout="240"; + shell = application.wirebox.getInstance( 'Shell' ); + serverArtifactService = application.wirebox.getInstance( 'ServerArtifactService' ); + artifactDir = application.wirebox.getInstance( 'serverArtifactDir@constants' ); + workDir = expandPath("/tests/work"); + } + + public void function testInstallLucee() { + var artifacts = serverArtifactService.install(cfengine="lucee", basedirectory=workDir); + assertTrue(artifacts.endsWith("4.5.2.018")); + request.debug(artifacts); + } + + public void function testInstallLucee5() { + var artifacts = serverArtifactService.install(cfengine="lucee@5.0.0.243-SNAPSHOT", basedirectory=workDir); + assertTrue(artifacts.endsWith("5.0.0.243-SNAPSHOT")); + request.debug(artifacts); + } + + public void function testInstallAdobe() { + var artifacts = serverArtifactService.install(cfengine="adobe", basedirectory=workDir); + assertTrue(artifacts.endsWith("11.0.0.289974")); + request.debug(artifacts); + } + + public void function testInstallAdobe9() { + var artifacts = serverArtifactService.install(cfengine="adobe@9.0.2.282541", basedirectory=workDir); + assertTrue(artifacts.endsWith("9.0.2.282541")); + request.debug(artifacts); + } + + public void function testInstallRailo() { + var artifacts = serverArtifactService.install(cfengine="railo", basedirectory=workDir); + assertTrue(artifacts.endsWith("4.2.1.008")); + request.debug(artifacts); + } + + public void function testCheckVersion() { + var version = serverArtifactService.checkVersion(cfengine="railo", version="4"); + assertEquals("4.2.1.008",version); + version = serverArtifactService.checkVersion(cfengine="railo", version="4.2"); + assertEquals("4.2.1.008",version); + version = serverArtifactService.checkVersion(cfengine="railo", version="4.2.1"); + assertEquals("4.2.1.008",version); + version = serverArtifactService.checkVersion(cfengine="railo", version=""); + assertEquals("4.2.1.008",version); + + version = serverArtifactService.checkVersion(cfengine="lucee", version="4"); + assertEquals("4.5.2.018",version); + version = serverArtifactService.checkVersion(cfengine="lucee", version="4.5"); + assertEquals("4.5.2.018",version); + version = serverArtifactService.checkVersion(cfengine="lucee", version="5"); + assertEquals("5.0.0.236-SNAPSHOT",version); + version = serverArtifactService.checkVersion(cfengine="lucee", version=""); + assertEquals("4.5.2.018",version); + + version = serverArtifactService.checkVersion(cfengine="adobe", version="9"); + assertEquals("9.0.2.282541",version); + version = serverArtifactService.checkVersion(cfengine="adobe", version="10"); + assertEquals("10.0.12.286680",version); + version = serverArtifactService.checkVersion(cfengine="adobe", version="11"); + assertEquals("11.0.0.289974",version); + version = serverArtifactService.checkVersion(cfengine="adobe", version=""); + assertEquals("11.0.0.289974",version); + } + + public void function testConfigureRailo() { + var source = resourceDir & "/railo/web.xml"; + var destination = workDir & "/railo-web.xml"; + var artifacts = serverArtifactService.configureWebXML("railo",source, destination); + debug(artifacts); + } + + public void function testConfigureLucee() { + var source = resourceDir & "/lucee/web.xml"; + var destination = workDir & "/lucee-web.xml"; + var artifacts = serverArtifactService.configureWebXML("lucee",source, destination); + debug(artifacts); + } + +} \ No newline at end of file From 6e0b1875bf95de8fe2a04e9b7047b9890296f658 Mon Sep 17 00:00:00 2001 From: denuno Date: Wed, 27 Apr 2016 14:44:07 -0600 Subject: [PATCH 046/129] tweaks doc generation to use custom commandbox home to avoid any version incompatabilities, and bumps jre version --- build/build.properties | 7 ++++--- build/build.xml | 31 +++++++++++++++++++++++++------ 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/build/build.properties b/build/build.properties index ea1d594f2..1a9690877 100644 --- a/build/build.properties +++ b/build/build.properties @@ -15,9 +15,9 @@ cfml.version=4.5.2.018 cfml.loader.version=1.2.0 cfml.cli.version=${cfml.loader.version}.${cfml.version} lucee.version=4.5.2.018 -jre.version=1.8.0_72 +jre.version=1.8.0_77 launch4j.version=3.4 -runwar.version=3.3.3 +runwar.version=3.3.5 #build locations build.type=localdev @@ -49,10 +49,11 @@ apidocs.port=8989 url.apidocs=http://localhost:${apidocs.port} ### testwar settings ### -default.cfengine=railo +default.cfengine=lucee war.contextpath=/ war.name=${distro.name} war.target.dir=${temp.dir}/${war.name}.war +server.jvm.args=-Xms256M -Xmx1024M -Djava.net.preferIPv4Stack=true -Dcfml.cli.home=${build.location}/temp/CommandBoxHome cfdistro.build.file=${user.home}/cfdistro/build.xml railo.javac.compiler=1.7 add.libs.dir=../lib diff --git a/build/build.xml b/build/build.xml index c1fd51065..1bc57c276 100644 --- a/build/build.xml +++ b/build/build.xml @@ -26,6 +26,7 @@ External Dependencies: + @@ -48,6 +49,12 @@ External Dependencies: Loading base properties + + + + + + @@ -101,6 +108,17 @@ External Dependencies: + + + + + + + + + + + @@ -383,14 +401,15 @@ External Dependencies: + - + - + @@ -425,7 +444,7 @@ External Dependencies: - + @@ -568,7 +587,6 @@ External Dependencies: - - + - + + From ba27c0df6d98de356e15180716237c9ecaec2b92 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 28 Apr 2016 11:10:20 -0500 Subject: [PATCH 047/129] Cleaned up error messaging a bit --- src/cfml/system/util/ForgeBox.cfc | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/cfml/system/util/ForgeBox.cfc b/src/cfml/system/util/ForgeBox.cfc index d5b146c8d..d1c8ca048 100644 --- a/src/cfml/system/util/ForgeBox.cfc +++ b/src/cfml/system/util/ForgeBox.cfc @@ -278,18 +278,21 @@ or just add DEBUG to the root logger var results = {error=false,response={},message="",responseheader={},rawResponse=""}; var HTTPResults = ""; var param = ""; - var jsonRegex = "^(\{|\[)(.)*(\}|\])$"; var APIURL = configService.getSetting( 'endpoints.forgebox.APIURL', getAPIURL() ); + if( APIURL.endsWith( '/' ) ) { + APIURL = left( APIURL, len( APIURL )-1 ); + } // Default Content Type if( NOT structKeyExists(arguments.headers,"content-type") ){ arguments.headers["content-type"] = ""; } + var thisURL = '#APIURL#/#arguments.resource#'; @@ -326,7 +329,13 @@ or just add DEBUG to the root logger if (isJSON(results.rawResponse)) { results.response = deserializeJSON(results.rawResponse,false); } else { - var errorDetail = ( HTTPResults.errorDetail ?: '' ) & chr( 10 ) & ( HTTPResults.statuscode ?: HTTPResults.status_code ?: '' ); + var errorDetail = ( HTTPResults.errorDetail ?: '' ); + var statusMessage = ( HTTPResults.statuscode ?: HTTPResults.status_code ?: '' ); + // Only append the status message if it's different than the errorDetail + if( errorDetail != statusMessage ) { + errorDetail &= chr( 10 ) & statusMessage; + } + errorDetail = ucase( arguments.method ) & ' ' &thisURL & chr( 10 ) & errorDetail; CommandBoxlogger.error( 'Something other than JSON returned. #errorDetail#', 'Actual HTTP Response: ' & results.rawResponse ); throw( 'Uh-oh, ForgeBox returned something other than JSON. Run "system-log | open" to see the full response.', 'forgebox', errorDetail ); } From 24a25e6c918ba2605060d8bbaac4edc5552e59d9 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 28 Apr 2016 21:52:32 -0500 Subject: [PATCH 048/129] Don't need version any more --- .../system/modules/forgebox-commands/commands/forgebox/show.cfc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/show.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/show.cfc index 8d3d4eda4..7ea6e7296 100644 --- a/src/cfml/system/modules/forgebox-commands/commands/forgebox/show.cfc +++ b/src/cfml/system/modules/forgebox-commands/commands/forgebox/show.cfc @@ -140,7 +140,6 @@ component aliases="show" { .line( 'Versions: #entryData.versions.map( function( i ){ return ' ' & i.version; } ).toList()#' ) .line( 'Created On: #dateFormat( entryData.createdDate )#' ) .line( 'Updated On: #dateFormat( entryData.updatedDate )#' ) - .line( 'Version: #entryData.version#' ) .line( 'ForgeBox Views: #entryData.hits#' ) .line( 'Downloads: #entryData.downloads#' ) .line( 'Installs: #entryData.installs#' ) From 8fd987dda1cd07b8f19e732ad441d58ba9cf5250 Mon Sep 17 00:00:00 2001 From: denuno Date: Fri, 29 Apr 2016 12:39:55 -0600 Subject: [PATCH 049/129] bump runwar version to pull in windows path fix, and remove cfengineVersion from server start command --- build/build.properties | 2 +- .../system/modules/server-commands/commands/server/start.cfc | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/build/build.properties b/build/build.properties index 1a9690877..e63cc5f5b 100644 --- a/build/build.properties +++ b/build/build.properties @@ -17,7 +17,7 @@ cfml.cli.version=${cfml.loader.version}.${cfml.version} lucee.version=4.5.2.018 jre.version=1.8.0_77 launch4j.version=3.4 -runwar.version=3.3.5 +runwar.version=3.3.6 #build locations build.type=localdev diff --git a/src/cfml/system/modules/server-commands/commands/server/start.cfc b/src/cfml/system/modules/server-commands/commands/server/start.cfc index 441d4e8aa..159afc8ff 100644 --- a/src/cfml/system/modules/server-commands/commands/server/start.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/start.cfc @@ -33,8 +33,7 @@ component aliases="start" { * @debug sets debug log level * @cfengine sets the cfml engine type * @cfengine.optionsUDF cfengineNameComplete - * @cfengineVersion sets the cfml engine version - * @cfengineVersion.optionsUDF cfengineVersionComplete + * @WARPath sets the path to an existing war to use * @webConfigDir custom location for web context configuration * @serverConfigDir custom location for server configuration * @libDirs comma-separated list of extra lib directories for the server @@ -105,4 +104,4 @@ component aliases="start" { return serverService.getCFEngineNames(); } -} \ No newline at end of file +} From 5d6d00362f93f7fb822b8fde3b0ebac7837132d1 Mon Sep 17 00:00:00 2001 From: denuno Date: Fri, 29 Apr 2016 13:30:35 -0600 Subject: [PATCH 050/129] bump runwar version to fix missing task bar --- build/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build.properties b/build/build.properties index e63cc5f5b..a67fdb0a6 100644 --- a/build/build.properties +++ b/build/build.properties @@ -17,7 +17,7 @@ cfml.cli.version=${cfml.loader.version}.${cfml.version} lucee.version=4.5.2.018 jre.version=1.8.0_77 launch4j.version=3.4 -runwar.version=3.3.6 +runwar.version=3.4.0 #build locations build.type=localdev From 9bd0db7eb1cfd9d58f5f391993681287aa8d2104 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Sat, 30 Apr 2016 23:22:18 -0500 Subject: [PATCH 051/129] Account for versions --- 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 7007b66d7..86ad19515 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -336,10 +336,10 @@ component accessors="true" singleton { consoleLogger.error(e.detail.replaceAll(",","#chr(10)#")); return; } - if(serverInfo.cfengine == "lucee") { + if(serverInfo.cfengine contains "lucee") { javaagent = "-javaagent:""#installDir#/WEB-INF/lib/lucee-inst.jar"""; } - if(serverInfo.cfengine == "railo") { + if(serverInfo.cfengine contains "railo") { javaagent = "-javaagent:""#installDir#/WEB-INF/lib/railo-inst.jar"""; } } From 1957da68393fc48ed9fae4e6489b9cd5203027d1 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Sat, 30 Apr 2016 23:55:47 -0500 Subject: [PATCH 052/129] COMMANDBOX-375 --- src/cfml/system/endpoints/Git.cfc | 33 +++++++++++++++---- .../commandbox/jgit/CommandCaller.java | 32 ++++++++++++++++++ 2 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 src/java/com/ortussolutions/commandbox/jgit/CommandCaller.java diff --git a/src/cfml/system/endpoints/Git.cfc b/src/cfml/system/endpoints/Git.cfc index 3f712ac54..91344d3c6 100644 --- a/src/cfml/system/endpoints/Git.cfc +++ b/src/cfml/system/endpoints/Git.cfc @@ -62,7 +62,11 @@ component accessors="true" implements="IEndpoint" singleton { // Temporary location to place the repo var localPath = createObject( 'java', 'java.io.File' ).init( "#tempDir#/git_#randRange( 1, 1000 )#" ); - + + // This will trap the full java exceptions to work around this annoying behavior: + // https://luceeserver.atlassian.net/browse/LDEV-454 + var CommandCaller = createObject( 'java', 'com.ortussolutions.commandbox.jgit.CommandCaller' ).init(); + try { // Clone the repo locally into a temp folder var cloneCommand = Git.cloneRepository() @@ -70,16 +74,33 @@ component accessors="true" implements="IEndpoint" singleton { .setCloneSubmodules( true ) .setDirectory( localPath ) .setProgressMonitor( progressMonitor ); - + // Conditionally apply security - local.result = secureCloneCommand( cloneCommand ) - .call(); + var command = secureCloneCommand( cloneCommand ); + // call with our special java wrapper + local.result = CommandCaller.call( command ); // Checkout branch, tag, or commit hash. - local.result.checkout().setName( branch ).call(); + CommandCaller.call( local.result.checkout().setName( branch ) ); } catch( any var e ) { - throw( message="Error Cloning Git repository", detail="#e.message#", type="endpointException"); + // If the exception came from the Java call, this exception won't be null + var theRealJavaException = CommandCaller.getException(); + + // If it's null, that just means some other CFML code must have blown chunks above. + if( isNull( theRealJavaException ) ) { + throw( message="Error Cloning Git repository", detail="#e.message#", type="endpointException"); + } else { + var deepMessage = ''; + // Start at the top level and work around way down to the root cause. + do { + deepMessage &= '#theRealJavaException.toString()# #chr( 10 )#'; + theRealJavaException = theRealJavaException.getCause() + } while( !isNull( theRealJavaException ) ) + + throw( message="Error Cloning Git repository", detail="#deepMessage#", type="endpointException"); + } + } finally { // Release file system locks on the repo if( structKeyExists( local, 'result' ) ) { diff --git a/src/java/com/ortussolutions/commandbox/jgit/CommandCaller.java b/src/java/com/ortussolutions/commandbox/jgit/CommandCaller.java new file mode 100644 index 000000000..17a5d28cd --- /dev/null +++ b/src/java/com/ortussolutions/commandbox/jgit/CommandCaller.java @@ -0,0 +1,32 @@ +/** +********************************************************************************* +* Copyright Since 2014 CommandBox by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood, Luis Majano +* +* I implement the SSH callback class for jGit to support SSH +*/ +package com.ortussolutions.commandbox.jgit; + +import org.eclipse.jgit.api.GitCommand; +import java.lang.Exception; + +public class CommandCaller { + + private Throwable exception; + + public Object call( GitCommand command ) throws Exception { + + try { + return command.call(); + } catch( Throwable e ) { + this.exception = e; + throw new Exception( "Error calling command.", e ); + } + } + + public Throwable getException() { + return this.exception; + } +} From 40536c738f21d47bec001a4cffb1110433bb6cd3 Mon Sep 17 00:00:00 2001 From: denuno Date: Sun, 1 May 2016 22:48:47 -0600 Subject: [PATCH 053/129] bump runwar version to be sure we get the one compiled with 1.7 target --- build/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build.properties b/build/build.properties index a67fdb0a6..77c99d208 100644 --- a/build/build.properties +++ b/build/build.properties @@ -17,7 +17,7 @@ cfml.cli.version=${cfml.loader.version}.${cfml.version} lucee.version=4.5.2.018 jre.version=1.8.0_77 launch4j.version=3.4 -runwar.version=3.4.0 +runwar.version=3.4.1 #build locations build.type=localdev From f0c82440411da1bd84e6f372d3f16287ac41ca86 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 2 May 2016 00:20:02 -0500 Subject: [PATCH 054/129] COMMANDBOX-376 --- .../commands/coldbox/reinit.cfc | 4 +- .../server-commands/commands/server/start.cfc | 12 +-- .../server-commands/commands/server/stop.cfc | 6 +- src/cfml/system/services/ConfigService.cfc | 16 +++- src/cfml/system/services/ServerService.cfc | 93 ++++++++++--------- 5 files changed, 77 insertions(+), 54 deletions(-) diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/reinit.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/reinit.cfc index 8c21aafed..2361a81a8 100644 --- a/src/cfml/system/modules/coldbox-commands/commands/coldbox/reinit.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/reinit.cfc @@ -18,8 +18,8 @@ component aliases="fwreinit" { /** * @password.hint The FWReinit password **/ - function run( password="1" ){ - var serverInfo = serverService.getServerInfoByWebroot( getCWD() ); + function run( password="1", name="" ){ + var serverInfo = serverService.getServerInfoByWebroot( getCWD(), arguments.name ); if( structCount( serverInfo ) eq 0 ){ print.boldRedLine( "No server configurations found for '#getCWD()#', so have no clue what to reinit buddy!" ); diff --git a/src/cfml/system/modules/server-commands/commands/server/start.cfc b/src/cfml/system/modules/server-commands/commands/server/start.cfc index 159afc8ff..f6a48e78e 100644 --- a/src/cfml/system/modules/server-commands/commands/server/start.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/start.cfc @@ -31,9 +31,6 @@ component aliases="start" { * @stopPort stop socket listener port number * @force force start if status is not stopped * @debug sets debug log level - * @cfengine sets the cfml engine type - * @cfengine.optionsUDF cfengineNameComplete - * @WARPath sets the path to an existing war to use * @webConfigDir custom location for web context configuration * @serverConfigDir custom location for server configuration * @libDirs comma-separated list of extra lib directories for the server @@ -52,6 +49,9 @@ component aliases="start" { * @JVMArgs Additional JVM args to use when starting the server. Use "server status --verbose" to debug * @runwarArgs Additional Runwar options to use when starting the server. Use "server status --verbose" to debug * @saveSettings Save start settings in server.json + * @cfengine sets the cfml engine type + * @cfengine.optionsUDF cfengineNameComplete + * @WARPath sets the path to an existing war to use **/ function run( String name, @@ -62,8 +62,6 @@ component aliases="start" { Numeric stopPort, Boolean force, Boolean debug, - String cfengine, - String WARPath, String webConfigDir, String serverConfigDir, String libDirs, @@ -81,7 +79,9 @@ component aliases="start" { boolean directoryBrowsing, String JVMArgs, String runwarArgs, - boolean saveSettings=true + boolean saveSettings=true, + String cfengine, + String WARPath ){ // Resolve path as used locally arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); diff --git a/src/cfml/system/modules/server-commands/commands/server/stop.cfc b/src/cfml/system/modules/server-commands/commands/server/stop.cfc index fb80171d4..9c57c3a83 100644 --- a/src/cfml/system/modules/server-commands/commands/server/stop.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/stop.cfc @@ -50,6 +50,9 @@ component aliases="stop" { var serverInfo = servers[ id ]; if( serverInfo.status == 'stopped' ) { + if( structCount( servers ) == 1 ) { + print.yellowLine( serverInfo.name & ' already stopped..' ).toConsole(); + } continue; } @@ -57,7 +60,8 @@ component aliases="stop" { var results = serverService.stop( serverInfo ); if( results.error ){ - error( results.messages ); + print.boldWhiteOnRedLine( 'ERROR' ); + print.boldRedLine( results.messages ); } else { print.line( results.messages ); } diff --git a/src/cfml/system/services/ConfigService.cfc b/src/cfml/system/services/ConfigService.cfc index a1d2f01b1..fbb4c5553 100644 --- a/src/cfml/system/services/ConfigService.cfc +++ b/src/cfml/system/services/ConfigService.cfc @@ -20,7 +20,8 @@ component accessors="true" singleton { property name='formatterUtil' inject='formatter'; property name='ModuleService' inject='ModuleService'; property name='JSONService' inject='JSONService'; - + property name='ServerService' inject='ServerService'; + /** * Constructor */ @@ -43,8 +44,10 @@ component accessors="true" singleton { 'endpoints', 'endpoints.forgebox', 'endpoints.forgebox.APIToken', - 'endpoints.forgebox.APIURL' - + 'endpoints.forgebox.APIURL', + // Servers + 'server', + 'server.defaults' ]); setConfigFilePath( '/commandbox-home/CommandBox.json' ); @@ -59,6 +62,13 @@ component accessors="true" singleton { return this; } + function onDIComplete() { + var serverProps = serverService.completeProperty( 'fake', true ); + for( var prop in serverProps ) { + variables.possibleConfigSettings.append( 'server.defaults.#prop#' ); + } + } + function setConfigSettings( required struct configSettings ) { variables.configSettings = arguments.configSettings; saveConfig(); diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 86ad19515..430d723b3 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -34,19 +34,16 @@ component accessors="true" singleton { * Where the Run War jar path is */ property name="jarPath"; - /** - * Default server settings - */ - property name="defaultServerJSON"; property name='rewritesDefaultConfig' inject='rewritesDefaultConfig@constants'; - property name='interceptorService' inject='interceptorService'; + property name='interceptorService' inject='interceptorService'; + property name='ConfigService' inject='ConfigService'; property name='JSONService' inject='JSONService'; property name='packageService' inject='packageService'; - property name='serverArtifactService' inject='serverArtifactService'; + property name='serverArtifactService' inject='serverArtifactService'; property name='consoleLogger' inject='logbox:logger:console'; property name='wirebox' inject='wirebox'; - property name="cfengineVersions" inject="cfengineVersions@constants"; + property name="cfengineVersions" inject="cfengineVersions@constants"; /** * Constructor @@ -110,51 +107,57 @@ component accessors="true" singleton { } function onDIComplete() { + } + + function getDefaultServerJSON() { + // pull default settings from config to mix in below. + // The structure of server.defaults in Config settings matches the default server.json layout here. + var d = ConfigService.getSetting( 'server.defaults', {} ); - setDefaultServerJSON( { - name : '', - openBrowser : true, - stopsocket : 0, - debug : false, - trayicon : '#variables.libdir#/trayicon.png', + return { + name : d.name ?: '', + openBrowser : d.openBrowser ?: true, + stopsocket : d.stopsocket ?: 0, + debug : d.debug ?: false, + trayicon : d.trayicon ?: '#variables.libdir#/trayicon.png', jvm : { - heapSize : 512, - args : '' + heapSize : d.jvm.heapSize ?: 512, + args : d.jvm.args ?: '' }, web : { - host : '127.0.0.1', - directoryBrowsing : true, - webroot : '', + host : d.web.host ?: '127.0.0.1', + directoryBrowsing : d.web.directoryBrowsing ?: true, + webroot : d.web.webroot ?: '', http : { - port : 0, - enable : true + port : d.web.http.port ?: 0, + enable : d.web.http.enable ?: true }, ssl : { - enable : false, - port : 1443, - cert : '', - key : '', - keyPass : '' + enable : d.web.ssl.enable ?: false, + port : d.web.ssl.port ?: 1443, + cert : d.web.ssl.cert ?: '', + key : d.web.ssl.key ?: '', + keyPass : d.web.ssl.keyPass ?: '' }, rewrites : { - enable : false, - config : variables.rewritesDefaultConfig + enable : d.web.rewrites.enable ?: false, + config : d.web.rewrites.config ?: variables.rewritesDefaultConfig } }, app : { - logDir : '', - libDirs : '', - webConfigDir : '', - serverConfigDir :variables.serverHomeDirectory, - webXML : '', - standalone : false, - WARPath : "", - cfengine : "lucee" + logDir : d.app.logDir ?: '', + libDirs : d.app.libDirs ?: '', + webConfigDir : d.app.webConfigDir ?: '', + serverConfigDir : d.app.serverConfigDir ?: variables.serverHomeDirectory, + webXML : d.app.webXML ?: '', + standalone : d.app.standalone ?: false, + WARPath : d.app.WARPath ?: "", + cfengine : d.app.cfengine ?: "lucee" }, runwar : { - args : '' + args : d.runwar.args ?: '' } - } ); + }; } /** @@ -294,8 +297,6 @@ component accessors="true" singleton { serverInfo.libDirs = serverProps.libDirs ?: serverJSON.app.libDirs ?: defaults.app.libDirs; serverInfo.trayIcon = serverProps.trayIcon ?: serverJSON.trayIcon ?: defaults.trayIcon; serverInfo.webXML = serverProps.webXML ?: serverJSON.app.webXML ?: defaults.app.webXML; - serverInfo.cfengine = serverProps.cfengine ?: serverJSON.app.cfengine ?: defaults.app.cfengine; - serverInfo.WARPath = serverProps.WARPath ?: serverJSON.app.WARPath ?: defaults.app.WARPath; serverInfo.SSLEnable = serverProps.SSLEnable ?: serverJSON.web.SSL.enable ?: defaults.web.SSL.enable; serverInfo.HTTPEnable = serverProps.HTTPEnable ?: serverJSON.web.HTTP.enable ?: defaults.web.HTTP.enable; serverInfo.SSLPort = serverProps.SSLPort ?: serverJSON.web.SSL.port ?: defaults.web.SSL.port; @@ -308,6 +309,8 @@ component accessors="true" singleton { serverInfo.directoryBrowsing = serverProps.directoryBrowsing ?: serverJSON.web.directoryBrowsing ?: defaults.web.directoryBrowsing; serverInfo.JVMargs = serverProps.JVMargs ?: serverJSON.JVM.args ?: defaults.JVM.args; serverInfo.runwarArgs = serverProps.runwarArgs ?: serverJSON.runwar.args ?: defaults.runwar.args; + serverInfo.cfengine = serverProps.cfengine ?: serverJSON.app.cfengine ?: defaults.app.cfengine; + serverInfo.WARPath = serverProps.WARPath ?: serverJSON.app.WARPath ?: defaults.app.WARPath; serverInfo.logdir = serverInfo.webConfigDir & "/log"; @@ -599,6 +602,7 @@ component accessors="true" singleton { * @name.hint The name to find */ struct function getServerInfoByDiscovery( required directory="", required name="" ){ + // Discover by shortname or webroot if( len( arguments.name ) ){ var foundServer = getServerInfoByName( arguments.name ); @@ -608,7 +612,7 @@ component accessors="true" singleton { } var webroot = arguments.directory is "" ? shell.pwd() : arguments.directory; - return getServerInfoByWebroot( fileSystemUtil.resolvePath( webroot ) ); + return getServerInfoByWebroot( fileSystemUtil.resolvePath( webroot ), arguments.name ); } /** @@ -644,8 +648,13 @@ component accessors="true" singleton { * Get a server information struct by webrot, if not found it returns an empty struct * @webroot.hint The webroot to find */ - struct function getServerInfoByWebroot( required webroot ){ - var webrootHash = hash( arguments.webroot ); + struct function getServerInfoByWebroot( required webroot, name='' ){ + + if( arguments.name == '' ) { + arguments.name = listLast( arguments.webroot, "\/" ); + } + + var webrootHash = hash( arguments.webroot & arguments.name ); var servers = getServers(); return structKeyExists( servers, webrootHash ) ? servers[ webrootHash ] : {}; From aecea054c221b1930f3adf305497e498aaa06d37 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 3 May 2016 00:22:14 -0500 Subject: [PATCH 055/129] COMMANDBOX-377 --- src/cfml/system/config/WireBox.cfc | 2 - src/cfml/system/endpoints/ForgeBox.cfc | 6 +- src/cfml/system/services/PackageService.cfc | 2 +- .../system/services/ServerArtifactService.cfc | 104 ++++++++++-------- src/cfml/system/services/ServerService.cfc | 21 ++-- .../services/TestServerArtifactService.cfc | 1 - 6 files changed, 76 insertions(+), 60 deletions(-) diff --git a/src/cfml/system/config/WireBox.cfc b/src/cfml/system/config/WireBox.cfc index 6a30197f1..e5c667635 100644 --- a/src/cfml/system/config/WireBox.cfc +++ b/src/cfml/system/config/WireBox.cfc @@ -38,7 +38,6 @@ component extends="wirebox.system.ioc.config.Binder" { system.getProperty( 'user.home' ) & "/.CommandBox/" : system.getProperty( 'cfml.cli.home' ); var tempDir = homedir & "/temp"; var artifactDir = homedir & "/artifacts"; - var serverArtifactDir = homedir & "/serverartifacts"; var userDir = system.getProperty( "user.dir" ); var commandHistoryFile = homedir & "/.history-command"; var REPLScriptHistoryFile = homedir & "/.history-repl-script"; @@ -72,7 +71,6 @@ component extends="wirebox.system.ioc.config.Binder" { map( 'ortusArtifactsURL@constants' ).toValue( ortusArtifactsURL ); map( 'ortusPRDArtifactsURL@constants' ).toValue( ortusPRDArtifactsURL ); map( 'rewritesDefaultConfig@constants' ).toValue( "#homeDir#/cfml/system/config/urlrewrite.xml" ); - map( 'serverArtifactDir@constants' ).toValue( serverArtifactDir ); map( 'cfengineVersions@constants' ).toValue( cfengineVersions ); // Map Java Classes diff --git a/src/cfml/system/endpoints/ForgeBox.cfc b/src/cfml/system/endpoints/ForgeBox.cfc index 882facb59..5a3204f99 100644 --- a/src/cfml/system/endpoints/ForgeBox.cfc +++ b/src/cfml/system/endpoints/ForgeBox.cfc @@ -220,7 +220,7 @@ component accessors="true" implements="IEndpointInteractive" singleton { // If we requsted stable and all releases are pre-release, just grab the latest if( arguments.version == 'stable' && arrayLen( entryData.versions ) ) { arguments.version = entryData.versions[ 1 ].version; - var downloadURL = thisVersion.downloadURL; + var downloadURL = entryData.versions[ 1 ].downloadURL; } else { throw( 'Version [#arguments.version#] not found for package [#arguments.slug#].', 'endpointException', 'Available versions are [#entryData.versions.map( function( i ){ return ' ' & i.version; } ).toList()#]' ); } @@ -231,9 +231,7 @@ component accessors="true" implements="IEndpointInteractive" singleton { } consoleLogger.info( "Installing version [#arguments.version#]." ); - - // entryData.versions.each( function( i ) { systemOutput( i.version, true ); } ); - + var packageType = entryData.typeSlug; // Advice we found it diff --git a/src/cfml/system/services/PackageService.cfc b/src/cfml/system/services/PackageService.cfc index 44169253c..d3ef58377 100644 --- a/src/cfml/system/services/PackageService.cfc +++ b/src/cfml/system/services/PackageService.cfc @@ -68,7 +68,7 @@ component accessors="true" singleton { boolean save=false, boolean saveDev=false, boolean production=false, - string currentWorkingDirectory, + string currentWorkingDirectory=shell.pwd(), boolean verbose=false, boolean force=false, string packagePathRequestingInstallation = arguments.currentWorkingDirectory diff --git a/src/cfml/system/services/ServerArtifactService.cfc b/src/cfml/system/services/ServerArtifactService.cfc index eb4128a57..4c0710af0 100644 --- a/src/cfml/system/services/ServerArtifactService.cfc +++ b/src/cfml/system/services/ServerArtifactService.cfc @@ -5,46 +5,24 @@ ******************************************************************************** * @author Brad Wood, Luis Majano, Denny Valliant * -* I handle artifacts, which are basically just a cache of downloaded packages. -* -* Artifacts are stored in this format: -* /packageName/version/packageName.zip -* -* We are not currently using a group ID, but we may need to in the future * */ component accessors="true" singleton="true" { // DI - property name='artifactDir' inject='serverArtifactDir@constants'; - property name='tempDir' inject='tempDir@constants'; - property name='packageService' inject='PackageService'; - property name='logger' inject='logbox:logger:{this}'; - property name='consoleLogger' inject='logbox:logger:console'; - property name="cfdependency" inject="cfdependency"; - property name="cfengineVersions" inject="cfengineVersions@constants"; - property name='cr' inject='cr@constants'; + property name='tempDir' inject='tempDir@constants'; + property name='packageService' inject='PackageService'; + property name='logger' inject='logbox:logger:{this}'; + property name='consoleLogger' inject='logbox:logger:console'; + property name="cfengineVersions" inject="cfengineVersions@constants"; + property name='cr' inject='cr@constants'; /** * DI complete */ function onDIComplete() { - // Create the artifacts directory if it doesn't exist - if( !directoryExists( variables.artifactDir ) ) { - directoryCreate( variables.artifactDir ); - } - cfdependency.setLocalRepositoryPath(variables.artifactDir); - cfdependency.addRemoteRepository( "ortusstaging", "http://integration.staging.ortussolutions.com/artifacts/" ); } - /** - * Gets the path for the local artifact - * @artifact artifact coordinates to get path for` - **/ - public function getPathForLocalArtifact( required artifact ) { - var artifactPath = cfdependency.getPathForLocalArtifact(artifact); - return artifactPath; - } /** * Checks engine and version, returning default version if version is empty @@ -108,18 +86,15 @@ component accessors="true" singleton="true" { * @version Version number or empty to use default **/ public function installAdobe( required destination, required version ) { - var artifact = "com.adobe:coldfusion:war:#version#"; - var compat = "com.adobe:coldfusion:zip:compat:#version#"; - if(left(version,2) == 10 || left(version,2) == 11 || left(version,4) == 2016) { - var compat = "com.adobe:coldfusion:zip:compat:11.0.0.289974"; - var artifactPath = cfdependency.get(dependencies=[artifact,compat], dest=destination, unzip=true); - } else { - var artifactPath = cfdependency.get(dependencies=[artifact], dest=destination, unzip=true); - } + + var versionInstalled = installEngineArchive( 'adobe-coldFusion-cf-engine@#version#', destination ); + + if( left( versionInstalled, 2 ) == 10 || left( version, 2 ) == 11 || left( version, 4 ) == 2016 ) { + installEngineArchive( 'adobe-coldFusion-cf-engine-tomcat-libs', destination ); + } + // set password to "commandbox" - fileWrite(destination & "/WEB-INF/cfusion/lib/password.properties", - "rdspassword=#cr#password=commandbox#cr#encrypted=false"); - return artifactPath; + fileWrite(destination & "/WEB-INF/cfusion/lib/password.properties", "rdspassword=#cr#password=commandbox#cr#encrypted=false"); } /** @@ -128,10 +103,10 @@ component accessors="true" singleton="true" { * @version Version number or empty to use default **/ public function installLucee( required destination, required version ) { - var artifact = "org.lucee:lucee.war:war:#version#"; - var artifactPath = cfdependency.get(dependencies=[artifact], dest=destination, unzip=true); + + installEngineArchive( 'lucee-cf-engine@#version#', destination ); + configureWebXML(cfengine="lucee",source="#destination#/WEB-INF/web.xml",destination="#destination#/WEB-INF/web.xml"); - return artifactPath; } /** @@ -140,12 +115,51 @@ component accessors="true" singleton="true" { * @version Version number or empty to use default **/ public function installRailo( required destination, required version ) { - var artifact = "org.getrailo:railo.war:war:#version#"; - var artifactPath = cfdependency.get(dependencies=[artifact], dest=destination, unzip=true); + + installEngineArchive( 'railo-cf-engine@#version#', destination ); + configureWebXML(cfengine="railo",source="#destination#/WEB-INF/web.xml",destination="#destination#/WEB-INF/web.xml"); - return artifactPath; } + + /* + * Downloads a CF engine endpoint and unzips the "Engine.[WAR|zip] archive into the destination + */ + function installEngineArchive( required string ID, required string destination ) { + var thisTempDir = tempDir & '/' & createUUID(); + var versionInstalled = '0'; + + packageService.installPackage( ID=arguments.ID, directory=thisTempDir, save=false ); + + if( packageService.isPackage( thisTempDir ) ) { + var boxJSON = packageService.readPackageDescriptor( thisTempDir ); + versionInstalled = boxJSON.version; + } + + var theArchive = ''; + for( var thisFile in directoryList( thisTempDir ) ) { + if( listFindNoCase( 'war,zip', listLast( thisFile, '.' ) ) ) { + theArchive = thisFile; + } + } + + if( thisFile == '' ) { + throw( "Package didn't contain a war or zip archive." ); + } + + consoleLogger.info( "Exploding WAR/zip archive..."); + zip action="unzip" file="#thisFile#" destination="#destination#" overwrite="true"; + + // Catch this to gracefully handle where the OS or another program + // has the folder locked. + try { + directoryDelete( thisTempDir, true ); + } catch( any e ) { + consoleLogger.error( '#e.message##CR#The folder is possibly locked by another program.' ); + logger.error( '#e.message# #e.detail#' , e.stackTrace ); + } + return versionInstalled; + } /** * configure web.xml file for Lucee and Railo * @cfengine lucee or railo diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 430d723b3..6f5142df3 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -208,10 +208,8 @@ component accessors="true" singleton { // Save hand-entered properties in our server.json for next time for( var prop in serverProps ) { if( !isNull( serverProps[ prop ] ) && prop != 'directory' && prop != 'saveSettings' ) { + // Only need switch cases for properties that are nested or use different name switch(prop) { - case "name": - serverJSON[ 'name' ] = serverProps[ prop ]; - break; case "port": serverJSON[ 'web' ][ 'http' ][ 'port' ] = serverProps[ prop ]; break; @@ -312,8 +310,8 @@ component accessors="true" singleton { serverInfo.cfengine = serverProps.cfengine ?: serverJSON.app.cfengine ?: defaults.app.cfengine; serverInfo.WARPath = serverProps.WARPath ?: serverJSON.app.WARPath ?: defaults.app.WARPath; - serverInfo.logdir = serverInfo.webConfigDir & "/log"; - + serverInfo.logdir = serverInfo.webConfigDir & "/logs"; + interceptorService.announceInterception( 'onServerStart', { serverInfo=serverInfo } ); var launchUtil = java.LaunchUtil; @@ -333,7 +331,9 @@ component accessors="true" singleton { var javaagent = serverinfo.cfengine == "lucee" ? "" : "-javaagent:""#libdir#/lucee-inst.jar"""; if( serverInfo.cfengine != "lucee" && serverInfo.cfengine != "lucee@" & cfengineVersions["lucee"][1]){ try { - installDir = serverArtifactService.install( cfengine=serverInfo.cfengine, basedirectory=serverInfo.webConfigDir ); + var installDir = serverArtifactService.install( cfengine=serverInfo.cfengine, basedirectory=serverInfo.webConfigDir ); + serverInfo.logdir = installDir & "/logs"; + } catch (any e) { consoleLogger.error("Error installing server - " & e.message); consoleLogger.error(e.detail.replaceAll(",","#chr(10)#")); @@ -345,8 +345,15 @@ component accessors="true" singleton { if(serverInfo.cfengine contains "railo") { javaagent = "-javaagent:""#installDir#/WEB-INF/lib/railo-inst.jar"""; } + // Using built in server that hasn't been started before + } else if( !directoryExists( serverInfo.webConfigDir & '/WEB-INF' ) ) { + serverInfo.webConfigDir &= '/lucee-#cfengineVersions["lucee"][1]#'; + serverInfo.logdir = serverInfo.webConfigDir & "/logs"; } - + + directoryCreate( serverInfo.logDir, true, true ); + + // The java arguments to execute: Shared server, custom web configs var args = " #serverInfo.JVMargs# -Xmx#serverInfo.heapSize#m -Xms#serverInfo.heapSize#m" & " #javaagent# -jar ""#variables.jarPath#""" diff --git a/tests/cfml/system/services/TestServerArtifactService.cfc b/tests/cfml/system/services/TestServerArtifactService.cfc index 76460d12f..0b79717bd 100644 --- a/tests/cfml/system/services/TestServerArtifactService.cfc +++ b/tests/cfml/system/services/TestServerArtifactService.cfc @@ -14,7 +14,6 @@ component extends="mxunit.framework.TestCase" { setting requesttimeout="240"; shell = application.wirebox.getInstance( 'Shell' ); serverArtifactService = application.wirebox.getInstance( 'ServerArtifactService' ); - artifactDir = application.wirebox.getInstance( 'serverArtifactDir@constants' ); workDir = expandPath("/tests/work"); } From 082ebc13ed21c3540e85c1b7120df14e5e59794d Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 3 May 2016 01:16:56 -0500 Subject: [PATCH 056/129] COMMANDBOX-377 --- .../system/services/ServerArtifactService.cfc | 105 ++++++------------ 1 file changed, 37 insertions(+), 68 deletions(-) diff --git a/src/cfml/system/services/ServerArtifactService.cfc b/src/cfml/system/services/ServerArtifactService.cfc index 4c0710af0..2b9b9231f 100644 --- a/src/cfml/system/services/ServerArtifactService.cfc +++ b/src/cfml/system/services/ServerArtifactService.cfc @@ -16,40 +16,6 @@ component accessors="true" singleton="true" { property name='consoleLogger' inject='logbox:logger:console'; property name="cfengineVersions" inject="cfengineVersions@constants"; property name='cr' inject='cr@constants'; - - /** - * DI complete - */ - function onDIComplete() { - } - - - /** - * Checks engine and version, returning default version if version is empty - * @cfengine CFML Engine name (lucee, adobe, railo) - * @version Version number or empty to get default - **/ - public function checkVersion( required cfengine, required version) { - if(isNull(cfengineVersions[cfengine])) { - throw( message="unknown cfengine type: " & cfengine ); - } - if(version == "") { - version = cfengineVersions[cfengine][1]; - } else { - var versions = cfengineVersions[cfengine]; - var valid = false; - for(var ver in versions) { - if(ver.toLowerCase().startsWith(lcase(version))) { - version = ver; - valid = true; - } - } - if(!valid) { - throw( message="unknown #cfengine# version: " & version ); - } - } - return version; - } /** * install the server if not already installed to the target directory @@ -58,27 +24,22 @@ component accessors="true" singleton="true" { * @version Version number or empty to use default **/ public function install( required cfengine, required basedirectory, force=false) { - version = find("@",cfengine) ? listLast(cfengine,"@") : ""; - cfengine = listFirst(cfengine,"@"); - basedirectory = !basedirectory.endsWith("/") ? basedirectory & "/" : basedirectory; - var engineVersion = checkVersion(cfengine=cfengine,version=version); - var installDir = basedirectory & cfengine & "-" & engineVersion; - if(!fileExists(installDir & "/WEB-INF/web.xml") || force) { - consoleLogger.info("Installing #cfengine# #engineVersion# in #installDir#"); - if( cfengine == "adobe" ) { - installAdobe( destination=installDir, version=engineVersion ); - } else if (cfengine == "railo") { - installRailo( destination=installDir, version=engineVersion ); - } else if (cfengine == "lucee") { - installLucee( destination=installDir, version=engineVersion ); - } else { - throw( message="unknown engine type:" & cfengine ); - } - } else { - consoleLogger.info("Using #cfengine# in #installDir#"); - } - return installDir; - } + var version = find("@",cfengine) ? listLast(cfengine,"@") : ""; + cfengine = listFirst(cfengine,"@"); + basedirectory = !basedirectory.endsWith("/") ? basedirectory & "/" : basedirectory; + + consoleLogger.info("Installing #cfengine# #version# in #basedirectory#"); + + if( cfengine == "adobe" ) { + return installAdobe( destination=basedirectory, version=version ); + } else if (cfengine == "railo") { + return installRailo( destination=basedirectory, version=version ); + } else if (cfengine == "lucee") { + return installLucee( destination=basedirectory, version=version ); + } else { + throw( message="unknown engine type:" & cfengine ); + } + } /** * install adobe @@ -87,14 +48,17 @@ component accessors="true" singleton="true" { **/ public function installAdobe( required destination, required version ) { - var versionInstalled = installEngineArchive( 'adobe-coldFusion-cf-engine@#version#', destination ); + var installDir = installEngineArchive( 'adobe-coldFusion-cf-engine@#version#', destination, 'adobe' ); - if( left( versionInstalled, 2 ) == 10 || left( version, 2 ) == 11 || left( version, 4 ) == 2016 ) { - installEngineArchive( 'adobe-coldFusion-cf-engine-tomcat-libs', destination ); + // Tomcat versions of Adobe CF require some extra jars + if( installDir contains 'adobe-10.' || installDir contains 'adobe-11.' || installDir contains 'adobe-2016.' ) { + installEngineArchive( 'adobe-coldFusion-cf-engine-tomcat-libs', destination, 'adobe', installDir ); } // set password to "commandbox" - fileWrite(destination & "/WEB-INF/cfusion/lib/password.properties", "rdspassword=#cr#password=commandbox#cr#encrypted=false"); + fileWrite( installDir & "/WEB-INF/cfusion/lib/password.properties", "rdspassword=#cr#password=commandbox#cr#encrypted=false"); + + return installDir; } /** @@ -104,9 +68,10 @@ component accessors="true" singleton="true" { **/ public function installLucee( required destination, required version ) { - installEngineArchive( 'lucee-cf-engine@#version#', destination ); + var installDir = installEngineArchive( 'lucee-cf-engine@#version#', destination, 'lucee' ); - configureWebXML(cfengine="lucee",source="#destination#/WEB-INF/web.xml",destination="#destination#/WEB-INF/web.xml"); + configureWebXML(cfengine="lucee",source="#installDir#/WEB-INF/web.xml",destination="#installDir#/WEB-INF/web.xml"); + return installDir; } /** @@ -116,16 +81,18 @@ component accessors="true" singleton="true" { **/ public function installRailo( required destination, required version ) { - installEngineArchive( 'railo-cf-engine@#version#', destination ); + var installDir = installEngineArchive( 'railo-cf-engine@#version#', destination, 'railo' ); - configureWebXML(cfengine="railo",source="#destination#/WEB-INF/web.xml",destination="#destination#/WEB-INF/web.xml"); + configureWebXML(cfengine="railo",source="#installDir#/WEB-INF/web.xml",destination="#installDir#/WEB-INF/web.xml"); + + return installDir; } /* * Downloads a CF engine endpoint and unzips the "Engine.[WAR|zip] archive into the destination */ - function installEngineArchive( required string ID, required string destination ) { + function installEngineArchive( required string ID, required string destination, required string cfengine, string installDir ) { var thisTempDir = tempDir & '/' & createUUID(); var versionInstalled = '0'; @@ -133,7 +100,7 @@ component accessors="true" singleton="true" { if( packageService.isPackage( thisTempDir ) ) { var boxJSON = packageService.readPackageDescriptor( thisTempDir ); - versionInstalled = boxJSON.version; + versionInstalled = boxJSON.version; } var theArchive = ''; @@ -143,12 +110,14 @@ component accessors="true" singleton="true" { } } - if( thisFile == '' ) { + if( theArchive == '' ) { throw( "Package didn't contain a war or zip archive." ); } + + var installDir = arguments.installDir ?: destination & cfengine & "-" & replace( versionInstalled, '+', '.', 'all' ); consoleLogger.info( "Exploding WAR/zip archive..."); - zip action="unzip" file="#thisFile#" destination="#destination#" overwrite="true"; + zip action="unzip" file="#thisFile#" destination="#installDir#" overwrite="true"; // Catch this to gracefully handle where the OS or another program // has the folder locked. @@ -158,7 +127,7 @@ component accessors="true" singleton="true" { consoleLogger.error( '#e.message##CR#The folder is possibly locked by another program.' ); logger.error( '#e.message# #e.detail#' , e.stackTrace ); } - return versionInstalled; + return installDir; } /** * configure web.xml file for Lucee and Railo From 54abe51785d3930b5769d57c53c9d0dca6fdd3bf Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 3 May 2016 01:32:50 -0500 Subject: [PATCH 057/129] allow any forgebox id --- src/cfml/system/services/ServerArtifactService.cfc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cfml/system/services/ServerArtifactService.cfc b/src/cfml/system/services/ServerArtifactService.cfc index 2b9b9231f..997715f32 100644 --- a/src/cfml/system/services/ServerArtifactService.cfc +++ b/src/cfml/system/services/ServerArtifactService.cfc @@ -25,19 +25,19 @@ component accessors="true" singleton="true" { **/ public function install( required cfengine, required basedirectory, force=false) { var version = find("@",cfengine) ? listLast(cfengine,"@") : ""; - cfengine = listFirst(cfengine,"@"); + engineName = listFirst(cfengine,"@"); basedirectory = !basedirectory.endsWith("/") ? basedirectory & "/" : basedirectory; - consoleLogger.info("Installing #cfengine# #version# in #basedirectory#"); + consoleLogger.info("Installing #engineName# #version# in #basedirectory#"); - if( cfengine == "adobe" ) { + if( engineName contains "adobe" ) { return installAdobe( destination=basedirectory, version=version ); - } else if (cfengine == "railo") { + } else if (engineName contains "railo") { return installRailo( destination=basedirectory, version=version ); - } else if (cfengine == "lucee") { + } else if (engineName contains "lucee") { return installLucee( destination=basedirectory, version=version ); } else { - throw( message="unknown engine type:" & cfengine ); + return installEngineArchive( cfengine, basedirectory, engineName ); } } From 24e8f33c2d61ab8a015a942ddb1c9338fd365ba3 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 3 May 2016 09:57:25 -0500 Subject: [PATCH 058/129] Refactored names and removed un-used code. --- ...actService.cfc => ServerEngineService.cfc} | 0 src/cfml/system/services/ServerService.cfc | 8 +- src/cfml/system/util/cfdependency.cfc | 377 ------------------ .../services/TestServerArtifactService.cfc | 40 +- 4 files changed, 24 insertions(+), 401 deletions(-) rename src/cfml/system/services/{ServerArtifactService.cfc => ServerEngineService.cfc} (100%) delete mode 100644 src/cfml/system/util/cfdependency.cfc diff --git a/src/cfml/system/services/ServerArtifactService.cfc b/src/cfml/system/services/ServerEngineService.cfc similarity index 100% rename from src/cfml/system/services/ServerArtifactService.cfc rename to src/cfml/system/services/ServerEngineService.cfc diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 6f5142df3..f5c3a7f64 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -37,10 +37,10 @@ component accessors="true" singleton { property name='rewritesDefaultConfig' inject='rewritesDefaultConfig@constants'; property name='interceptorService' inject='interceptorService'; - property name='ConfigService' inject='ConfigService'; + property name='ConfigService' inject='ConfigService'; property name='JSONService' inject='JSONService'; property name='packageService' inject='packageService'; - property name='serverArtifactService' inject='serverArtifactService'; + property name='serverEngineService' inject='serverEngineService'; property name='consoleLogger' inject='logbox:logger:console'; property name='wirebox' inject='wirebox'; property name="cfengineVersions" inject="cfengineVersions@constants"; @@ -331,7 +331,7 @@ component accessors="true" singleton { var javaagent = serverinfo.cfengine == "lucee" ? "" : "-javaagent:""#libdir#/lucee-inst.jar"""; if( serverInfo.cfengine != "lucee" && serverInfo.cfengine != "lucee@" & cfengineVersions["lucee"][1]){ try { - var installDir = serverArtifactService.install( cfengine=serverInfo.cfengine, basedirectory=serverInfo.webConfigDir ); + var installDir = serverEngineService.install( cfengine=serverInfo.cfengine, basedirectory=serverInfo.webConfigDir ); serverInfo.logdir = installDir & "/logs"; } catch (any e) { @@ -769,7 +769,7 @@ component accessors="true" singleton { * Dynamic completion for cfengine */ function getCFEngineNames() { - return serverArtifactService.getCFEngineNames(); + return serverEngineService.getCFEngineNames(); } /** diff --git a/src/cfml/system/util/cfdependency.cfc b/src/cfml/system/util/cfdependency.cfc deleted file mode 100644 index 0294323ed..000000000 --- a/src/cfml/system/util/cfdependency.cfc +++ /dev/null @@ -1,377 +0,0 @@ -component { - - cfdependency.version = "2.0.0"; - - function init(localRepo=getDirectoryFromPath(getMetadata(this).path) & "/repo", repositories="default", javatools = false) { - localRepositoryPath = localRepo; - remotes = []; - paths = {}; - thisdir = getDirectoryFromPath(getMetadata(this).path); - if(isSimpleValue(repositories) && repositories == "default") { - addDefaultRepositories(); - } else { - for(var repo in repositories){ - addRemoteRepository(repo.name,repo.url,repo.type); - } - } - if(javatools) { - get(["cfml:javatools:zip:1.1.0"]); - } - } -/* - * AETHER - **/ - - function onMissingMethod( methodName, methodArguments ) { - if(isNull(aether)) { - if(!fileExists(localRepositoryPath & "org/cfmlprojects/aether/#cfdependency.version#/aether-#cfdependency.version#.jar")) { - get(["cfml:javatools:zip:1.1.0"]); - get(["org.cfmlprojects:aether:jar:#cfdependency.version#"]); - } - javaloader = create("cfml:javatools","LibraryLoader").init(pathlist=thisdir & "aether/lib/", id="aether-classloader"); - aether = new aether.Aether(localPath=localRepositoryPath, javaloader=javaloader, repositories=remotes); - } - return aether.callMethod(argumentCollection=arguments); - } - -/* - * /AETHER - **/ - - public function setLocalRepositoryPath(required path) { - localRepositoryPath = path; - } - - public function create(required dependency, required componentName, args) { -// return new "#paths[dependency]#.#componentName#" (argumentColection = args); - return createObject("#paths[dependency].cfcPath#.#componentName#"); - } - public function dirFor(required dependency) { - return createObject("#paths[dependency].directory#"); - } - - public function get(required array dependencies, dest="", unzip = "", transitive=true) { - var artifacts = simpleResolve(dependencies=dependencies,transitive=transitive); - var managedDest = dest == "" ? true : false; - var directories = ""; - if (dest == "") { - dest = expandPath("/WEB-INF/cfdependency"); - if(!directoryExists(dest)) { - directoryCreate(dest); - } - } - for(var artifact in artifacts) { - var file = artifact.file; - var versionSafe = rereplace(artifact.version,"[\.-]","_","all"); - var groupDir = replace(artifact.groupId,".","/","all"); - var todir = managedDest ? dest & "/#groupDir#/#artifact.artifactId#/#versionSafe#" : dest; - artifact.directory = todir; - directories = listContains(directories,todir) ? directories : listAppend(directories,todir); - paths["#artifact.groupId#:#artifact.artifactId#"] = { - cfcPath = "WEB-INF.cfdependency.#artifact.groupId#.#artifact.artifactId#.#versionSafe#", - directory = todir - }; - if(!directoryExists(todir)) { - directoryCreate(todir,true); - } - if(file.endsWith(".zip") && unzip == "") { - unzip = true; - } - unzip = unzip == "" ? false : unzip; - if(unzip && zipContentDiffers(file,dest)) { - zip action="unzip" file="#file#" destination="#todir#" overwrite=true; - } else { - fileCopy(file,todir); - } - } - return {artifacts = artifacts, directories = directories}; - } - - public function simpleResolve(required dependencies, Boolean transitive = true, scope="runtime") { - var artifacts = []; - if(isArray(dependencies)) { - for(var afact in dependencies) { - var arrayFiles = simpleResolve(afact,transitive,scope); - for(var file in arrayFiles) { - arrayAppend(artifacts,file); - } - } - return artifacts; - } - var artifact = toArtifact(dependencies); - var artifactPom = toPomArtifact(dependencies); - var filePath = getPathForLocalArtifact(dependencies); - artifact.file = filePath; - if(artifact.version.endsWith("SNAPSHOT") || !fileExists(filePath) || !hashMatch(filePath)) { - var pomfile = getRemoteArtifact(artifactPom); - artifact.file = getRemoteArtifact(dependencies); - arrayAppend(artifacts,artifact); - if(transitive) { - var mavenData = xmlParse(pomFile); - var deps = xmlSearch(mavendata,"//*[name() = 'project']/*[name()='dependencies']/*[name()='dependency']"); - for(var depXml in deps) { - var dep = {}; - for(var el in depXML.XmlChildren) { - dep[el.xmlName] = el.xmlText; - } - if(!isNull(dep.version) && (isNull(dep.scope) || dep.scope == scope)) { - var depArtifact = toArtifact(dep); - depArtifact.file = getRemoteArtifact(depArtifact); - arrayAppend(artifacts, depArtifact); - } - } - } - } else { - arrayAppend(artifacts,artifact); - } - return artifacts; - } - - public function addRemoteRepository(required name,required repourl, type="default"){ - var repo = { name : name, type: type, repourl: repourl }; - arrayAppend(variables.remotes,repo); - if(!isNull(aether)) - aether.addRemoteRepository(name,repourl,type); - } - - private function addDefaultRepositories(){ - var userHome = createObject("java","java.lang.System").getProperty("user.home"); - addRemoteRepository( "cfdistro", "file://#userHome#/cfdistro/artifacts/" ); - addRemoteRepository( "cfmlprojects", "http://cfmlprojects.org/artifacts/" ); - addRemoteRepository( "central", "http://repo1.maven.org/maven2/" ); - } - - public function toArtifact( Required coords, Struct properties={} ) { - var artifact = {groupId:"", artifactId:"", extension:"jar", classifier:"", version:""}; - if(isStruct(coords)) { - structAppend(artifact,coords); - return artifact; - } - var java = { - Pattern : createObject("java","java.util.regex.Pattern") - }; - var p = java.Pattern.compile( "([^: ]+):([^: ]+)(:([^: ]*)(:([^: ]+))?)?:([^: ]+)" ); - var m = p.matcher( coords ); - if ( !m.matches() ){ - throw( message = "Bad artifact coordinates " & coords - & ", expected format is :[:[:]]:" ); - } - artifact.groupId = m.group( 1 ); - artifact.artifactId = m.group( 2 ); - artifact.extension = isEmpty(m.group( 4 )) ? "jar" : m.group( 4 ); - artifact.type = artifact.extension; - artifact.classifier = isEmpty(m.group( 6 )) ? "" : m.group( 6 ); - artifact.version = m.group( 7 ); - artifact.file = ""; - artifact.properties = properties; - return artifact; - } - - public function toPomArtifact( required artifact ) { - artifact = toArtifact(artifact); - var pom = duplicate(artifact); - pom.extension = "pom"; - pom.type = artifact.extension; - pom.classifier = ""; - return pom; - } - - public function getPathForArtifact( Required artifact ) { - artifact = toArtifact(artifact); - var slashGroupId = replace( artifact.groupId, ".", "/", "all" ); - var classifierPath = artifact.classifier == "" ? "" : "-#artifact.classifier#"; - var artifactPath = "#slashGroupId#/#artifact.artifactId#/#artifact.version#/#artifact.artifactId#-#artifact.version##classifierPath#.#artifact.extension#"; - return artifactPath; - } - - public function getPathForLocalArtifact( Required artifact ) { - var artifactPath = localRepositoryPath & "/" & getPathForArtifact(artifact); - return artifactPath; - } - - private function getRemoteArtifact(artifact) { - artifact = toArtifact(artifact); - var filePath = getPathForArtifact(artifact); - var mavenMetaPath = getDirectoryFromPath(filePath).replaceAll(artifact.version&"\/$","") & "maven-metadata.xml"; - var mavenMetaFile = getRemoteFile(mavenMetaPath); - mavenMetaPath = getDirectoryFromPath(filePath) & "maven-metadata.xml"; - try { - mavenMetaFile = getRemoteFile(mavenMetaPath); - } catch(any e) { - // not all artifacts have a maven-metadata.xml, but snapshots should for sure - } - if(artifact.version.toUpperCase().endsWith("SNAPSHOT")) { - var snapshot = getSnapshotVersion(mavenMetaFile); - filePath = rereplace(filePath,"SNAPSHOT\.(.+)","#snapshot#.\1"); - getRemoteFile(filePath); - } else { - getRemoteFile(filePath); - } - return localRepositoryPath & "/" & filePath; - } - - private function getRemoteFile(filepath) { - var localPath = localRepositoryPath & "/" & filepath; - logMessage( "resolving #filepath# (#localPath#)" ); - if(hashMatch(localPath)) { - logMessage( "already resolved #filepath# (#localPath#)" ); - return localPath; - } - for(var repository in remotes) { - logMessage( "Trying remote repository #repository.name#..." ); - var fileUrl = repository.repourl & filepath; - logMessage( "Downloading #fileUrl#..." ); - if(!directoryExists(getDirectoryFromPath(localPath))) - directoryCreate(getDirectoryFromPath(localPath)); - httpGet("#fileUrl#.md5","#localPath#.md5"); - httpGet("#fileUrl#.sha1","#localPath#.sha1"); -// createObject("java","java.lang.System").out.println("Getting #fileURL# to #localPath#"); - httpGet("#fileUrl#","#localPath#"); - if( hashMatch(localPath)) { - break; - } else { - if(fileExists(localPath)) { - var hashes = lcase(serializeJSON(getHash(localPath))); - logMessage( "incorrect hash for #localPath# #hashes#" ); - } - } - } - if( !hashMatch(localPath)) { - var hashes = lcase(serializeJSON(getHash(localPath))); - logMessage( "could not get #filePath# or hash incorrect #hashes#" ); - throw(message="could not get #filePath# or hash incorrect #hashes#",detail=messages.toString()); - } - return localPath; - } - - public function httpGet(uri,toFile){ - var httpResult = ""; - if(uri.startsWith("file:")) { - if(fileExists(uri)) { - fileCopy(uri,toFile); - logMessage("Copied #uri# to #toFile#"); - } - } else { - http url=uri file=toFile result="httpResult" timeout="300" getAsBinary="true"; - if(httpResult.status_code != 200) { - fileDelete(toFile); - logMessage("#httpResult.statuscode# error for #uri#"); - } else { - logMessage("Downloaded #uri# to #toFile#"); - } - } - } - - private function getSnapshotVersion(mavenMetaFile) { - var mavenData = xmlParse(mavenMetaFile); - var snapshots = xmlSearch(mavendata,"//*[name() = 'metadata']/*[name() = 'versioning']/*[name()='snapshot']"); - return snapshots[1].XmlChildren[1].XmlText & "-" & snapshots[1].XmlChildren[2].XmlText; - } - - private Boolean function hashMatch(filePath) { - var hashes = getHash(filePath); - var fileHash = hashes.fileHash; - var goodHash = hashes.goodHash; - if( fileHash != "" && fileHash == goodHash) { - return true; - } - return false; - } - - private any function getHash(filePath) { - if(fileExists("#filePath#.sha1") && fileExists(filePath)) { - var fileHash = lcase(hash(fileReadBinary(filePath),"sha1")); - var goodHash = lcase(fileRead(filePath & ".sha1")); - } else if(fileExists("#filePath#.md5") && fileExists(filePath)) { - var fileHash = lcase(hash(fileReadBinary(filePath),"md5")); - var goodHash = lcase(fileRead(filePath & ".md5")); - } else { - var fileHash = ""; - var goodHash = ""; - } - return {fileHash:fileHash,goodHash:goodHash}; - } - - private Boolean function hasValidHash(artifact) { - var filePath = getPathForLocalArtifact(artifact); - return hashMatch(filePath); - } - - public function zipContentDiffers(zipfile,targetDirectory) { - var zf = createObject("java","java.util.zip.ZipFile").init(zipFile); - var e = zf.entries(); - while (e.hasMoreElements()) { - var ze = e.nextElement(); - if(!fileExists(targetDirectory & "/#ze.getName()#")) { - return true; - } - if(!ze.isDirectory()) { - var crc = crc32(targetDirectory & "/#ze.getName()#"); - if(ze.getCrc() != crc) { - return true; - } - } - } - zf.close(); - return false; - } - - function crc322(file) { - var input = fileReadBinary(file); - var bytes = input; - var java = { - CRC32 = createObject("java","java.util.zip.CRC32") - }; - var checksum = java.CRC32.init(); - checksum.reset(); - checksum.update(bytes, 0, len(bytes)); - var checksumValue = checksum.getValue(); - return checksumValue; - } - - - public function crc32(file) { - var java = { - CRC32 = createObject("java","java.util.zip.CRC32") - ,BufferedInputStream = createObject("java","java.io.BufferedInputStream") - ,ByteArrayOutputStream = createObject("java","java.io.ByteArrayOutputStream") - ,ReflectArray = createObject("java","java.lang.reflect.Array") - ,FileInputStream = createObject("java","java.io.FileInputStream") - ,File = createObject("java","java.io.File") - ,Long = createObject("java","java.lang.Long") - }; - var bis = java.BufferedInputStream.init(java.FileInputStream.init(java.File.init(arguments.file))); - var read = 0; - var checksum = java.CRC32.init(); - var buffer = java.ByteArrayOutputStream.init().toByteArray().getClass().getComponentType(); - buffer = java.ReflectArray.newInstance(buffer, 4096); - while ((read = bis.read(buffer)) != -1) { - checksum.update(buffer, 0, read); - } - bis.close(); - return checksum.getValue(); - } - - public function logMessage(message){ - if(isNull(messages)) { - messages = []; - } - arrayAppend(messages,message); - } - - public function getInstance(){ - if ( instance == null ){ - lock type="exclusive" timeout="3" { - if ( isNull(instance) ){ - instance = new Manager(); - } - } - } - return instance; - } - - public function dropInstance(){ - instance = javacast("null",""); - } - -} \ No newline at end of file diff --git a/tests/cfml/system/services/TestServerArtifactService.cfc b/tests/cfml/system/services/TestServerArtifactService.cfc index 0b79717bd..8a7279b74 100644 --- a/tests/cfml/system/services/TestServerArtifactService.cfc +++ b/tests/cfml/system/services/TestServerArtifactService.cfc @@ -13,80 +13,80 @@ component extends="mxunit.framework.TestCase" { //application.wirebox.clearSingletons(); setting requesttimeout="240"; shell = application.wirebox.getInstance( 'Shell' ); - serverArtifactService = application.wirebox.getInstance( 'ServerArtifactService' ); + serverEngineService = application.wirebox.getInstance( 'serverEngineService' ); workDir = expandPath("/tests/work"); } public void function testInstallLucee() { - var artifacts = serverArtifactService.install(cfengine="lucee", basedirectory=workDir); + var artifacts = serverEngineService.install(cfengine="lucee", basedirectory=workDir); assertTrue(artifacts.endsWith("4.5.2.018")); request.debug(artifacts); } public void function testInstallLucee5() { - var artifacts = serverArtifactService.install(cfengine="lucee@5.0.0.243-SNAPSHOT", basedirectory=workDir); + var artifacts = serverEngineService.install(cfengine="lucee@5.0.0.243-SNAPSHOT", basedirectory=workDir); assertTrue(artifacts.endsWith("5.0.0.243-SNAPSHOT")); request.debug(artifacts); } public void function testInstallAdobe() { - var artifacts = serverArtifactService.install(cfengine="adobe", basedirectory=workDir); + var artifacts = serverEngineService.install(cfengine="adobe", basedirectory=workDir); assertTrue(artifacts.endsWith("11.0.0.289974")); request.debug(artifacts); } public void function testInstallAdobe9() { - var artifacts = serverArtifactService.install(cfengine="adobe@9.0.2.282541", basedirectory=workDir); + var artifacts = serverEngineService.install(cfengine="adobe@9.0.2.282541", basedirectory=workDir); assertTrue(artifacts.endsWith("9.0.2.282541")); request.debug(artifacts); } public void function testInstallRailo() { - var artifacts = serverArtifactService.install(cfengine="railo", basedirectory=workDir); + var artifacts = serverEngineService.install(cfengine="railo", basedirectory=workDir); assertTrue(artifacts.endsWith("4.2.1.008")); request.debug(artifacts); } public void function testCheckVersion() { - var version = serverArtifactService.checkVersion(cfengine="railo", version="4"); + var version = serverEngineService.checkVersion(cfengine="railo", version="4"); assertEquals("4.2.1.008",version); - version = serverArtifactService.checkVersion(cfengine="railo", version="4.2"); + version = serverEngineService.checkVersion(cfengine="railo", version="4.2"); assertEquals("4.2.1.008",version); - version = serverArtifactService.checkVersion(cfengine="railo", version="4.2.1"); + version = serverEngineService.checkVersion(cfengine="railo", version="4.2.1"); assertEquals("4.2.1.008",version); - version = serverArtifactService.checkVersion(cfengine="railo", version=""); + version = serverEngineService.checkVersion(cfengine="railo", version=""); assertEquals("4.2.1.008",version); - version = serverArtifactService.checkVersion(cfengine="lucee", version="4"); + version = serverEngineService.checkVersion(cfengine="lucee", version="4"); assertEquals("4.5.2.018",version); - version = serverArtifactService.checkVersion(cfengine="lucee", version="4.5"); + version = serverEngineService.checkVersion(cfengine="lucee", version="4.5"); assertEquals("4.5.2.018",version); - version = serverArtifactService.checkVersion(cfengine="lucee", version="5"); + version = serverEngineService.checkVersion(cfengine="lucee", version="5"); assertEquals("5.0.0.236-SNAPSHOT",version); - version = serverArtifactService.checkVersion(cfengine="lucee", version=""); + version = serverEngineService.checkVersion(cfengine="lucee", version=""); assertEquals("4.5.2.018",version); - version = serverArtifactService.checkVersion(cfengine="adobe", version="9"); + version = serverEngineService.checkVersion(cfengine="adobe", version="9"); assertEquals("9.0.2.282541",version); - version = serverArtifactService.checkVersion(cfengine="adobe", version="10"); + version = serverEngineService.checkVersion(cfengine="adobe", version="10"); assertEquals("10.0.12.286680",version); - version = serverArtifactService.checkVersion(cfengine="adobe", version="11"); + version = serverEngineService.checkVersion(cfengine="adobe", version="11"); assertEquals("11.0.0.289974",version); - version = serverArtifactService.checkVersion(cfengine="adobe", version=""); + version = serverEngineService.checkVersion(cfengine="adobe", version=""); assertEquals("11.0.0.289974",version); } public void function testConfigureRailo() { var source = resourceDir & "/railo/web.xml"; var destination = workDir & "/railo-web.xml"; - var artifacts = serverArtifactService.configureWebXML("railo",source, destination); + var artifacts = serverEngineService.configureWebXML("railo",source, destination); debug(artifacts); } public void function testConfigureLucee() { var source = resourceDir & "/lucee/web.xml"; var destination = workDir & "/lucee-web.xml"; - var artifacts = serverArtifactService.configureWebXML("lucee",source, destination); + var artifacts = serverEngineService.configureWebXML("lucee",source, destination); debug(artifacts); } From 64d2687a93b9ff2abef9f587539234fa6483e677 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 3 May 2016 10:05:45 -0500 Subject: [PATCH 059/129] Additional Comments --- src/cfml/system/services/ServerEngineService.cfc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/cfml/system/services/ServerEngineService.cfc b/src/cfml/system/services/ServerEngineService.cfc index 997715f32..444cda92f 100644 --- a/src/cfml/system/services/ServerEngineService.cfc +++ b/src/cfml/system/services/ServerEngineService.cfc @@ -91,6 +91,12 @@ component accessors="true" singleton="true" { /* * Downloads a CF engine endpoint and unzips the "Engine.[WAR|zip] archive into the destination + * The WAR will be placed in a folder named {cfengine}-{version}/ unless an installDir is supplied. + * + * @ID The endpoint ID to use for the CF Engine. + * @destination The folder where this site's servers are stored. + * @cfengine The name of this engine. Used to created the final folder to store the WAR. + * @installDir If passed in, use this location to install the WAR instead of auto-calculating it. */ function installEngineArchive( required string ID, required string destination, required string cfengine, string installDir ) { var thisTempDir = tempDir & '/' & createUUID(); From 487b7882a58da4662150e1969cfd3a7fc03d97ce Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 3 May 2016 12:04:18 -0500 Subject: [PATCH 060/129] Cleanup --- .../services/TestServerArtifactService.cfc | 93 ------------------- 1 file changed, 93 deletions(-) delete mode 100644 tests/cfml/system/services/TestServerArtifactService.cfc diff --git a/tests/cfml/system/services/TestServerArtifactService.cfc b/tests/cfml/system/services/TestServerArtifactService.cfc deleted file mode 100644 index 8a7279b74..000000000 --- a/tests/cfml/system/services/TestServerArtifactService.cfc +++ /dev/null @@ -1,93 +0,0 @@ -component extends="mxunit.framework.TestCase" { - - public void function beforeTests() { - workDir = expandPath("/tests/work"); - resourceDir = expandPath("/tests/resource"); - if(directoryExists(workDir)){ - directoryDelete(workDir,true); - } - directoryCreate(workDir); - } - - public void function setUp() { - //application.wirebox.clearSingletons(); - setting requesttimeout="240"; - shell = application.wirebox.getInstance( 'Shell' ); - serverEngineService = application.wirebox.getInstance( 'serverEngineService' ); - workDir = expandPath("/tests/work"); - } - - public void function testInstallLucee() { - var artifacts = serverEngineService.install(cfengine="lucee", basedirectory=workDir); - assertTrue(artifacts.endsWith("4.5.2.018")); - request.debug(artifacts); - } - - public void function testInstallLucee5() { - var artifacts = serverEngineService.install(cfengine="lucee@5.0.0.243-SNAPSHOT", basedirectory=workDir); - assertTrue(artifacts.endsWith("5.0.0.243-SNAPSHOT")); - request.debug(artifacts); - } - - public void function testInstallAdobe() { - var artifacts = serverEngineService.install(cfengine="adobe", basedirectory=workDir); - assertTrue(artifacts.endsWith("11.0.0.289974")); - request.debug(artifacts); - } - - public void function testInstallAdobe9() { - var artifacts = serverEngineService.install(cfengine="adobe@9.0.2.282541", basedirectory=workDir); - assertTrue(artifacts.endsWith("9.0.2.282541")); - request.debug(artifacts); - } - - public void function testInstallRailo() { - var artifacts = serverEngineService.install(cfengine="railo", basedirectory=workDir); - assertTrue(artifacts.endsWith("4.2.1.008")); - request.debug(artifacts); - } - - public void function testCheckVersion() { - var version = serverEngineService.checkVersion(cfengine="railo", version="4"); - assertEquals("4.2.1.008",version); - version = serverEngineService.checkVersion(cfengine="railo", version="4.2"); - assertEquals("4.2.1.008",version); - version = serverEngineService.checkVersion(cfengine="railo", version="4.2.1"); - assertEquals("4.2.1.008",version); - version = serverEngineService.checkVersion(cfengine="railo", version=""); - assertEquals("4.2.1.008",version); - - version = serverEngineService.checkVersion(cfengine="lucee", version="4"); - assertEquals("4.5.2.018",version); - version = serverEngineService.checkVersion(cfengine="lucee", version="4.5"); - assertEquals("4.5.2.018",version); - version = serverEngineService.checkVersion(cfengine="lucee", version="5"); - assertEquals("5.0.0.236-SNAPSHOT",version); - version = serverEngineService.checkVersion(cfengine="lucee", version=""); - assertEquals("4.5.2.018",version); - - version = serverEngineService.checkVersion(cfengine="adobe", version="9"); - assertEquals("9.0.2.282541",version); - version = serverEngineService.checkVersion(cfengine="adobe", version="10"); - assertEquals("10.0.12.286680",version); - version = serverEngineService.checkVersion(cfengine="adobe", version="11"); - assertEquals("11.0.0.289974",version); - version = serverEngineService.checkVersion(cfengine="adobe", version=""); - assertEquals("11.0.0.289974",version); - } - - public void function testConfigureRailo() { - var source = resourceDir & "/railo/web.xml"; - var destination = workDir & "/railo-web.xml"; - var artifacts = serverEngineService.configureWebXML("railo",source, destination); - debug(artifacts); - } - - public void function testConfigureLucee() { - var source = resourceDir & "/lucee/web.xml"; - var destination = workDir & "/lucee-web.xml"; - var artifacts = serverEngineService.configureWebXML("lucee",source, destination); - debug(artifacts); - } - -} \ No newline at end of file From cc79998cb2891617165e6c10b89ffd3d8be6195d Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 3 May 2016 13:22:46 -0500 Subject: [PATCH 061/129] Tomcat libs are now merged with wars --- src/cfml/system/services/ServerEngineService.cfc | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/cfml/system/services/ServerEngineService.cfc b/src/cfml/system/services/ServerEngineService.cfc index 444cda92f..e5dc88b81 100644 --- a/src/cfml/system/services/ServerEngineService.cfc +++ b/src/cfml/system/services/ServerEngineService.cfc @@ -49,12 +49,7 @@ component accessors="true" singleton="true" { public function installAdobe( required destination, required version ) { var installDir = installEngineArchive( 'adobe-coldFusion-cf-engine@#version#', destination, 'adobe' ); - - // Tomcat versions of Adobe CF require some extra jars - if( installDir contains 'adobe-10.' || installDir contains 'adobe-11.' || installDir contains 'adobe-2016.' ) { - installEngineArchive( 'adobe-coldFusion-cf-engine-tomcat-libs', destination, 'adobe', installDir ); - } - + // set password to "commandbox" fileWrite( installDir & "/WEB-INF/cfusion/lib/password.properties", "rdspassword=#cr#password=commandbox#cr#encrypted=false"); From b9e3283d1d28aba8c136717471c689b6d1ed3fac Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 3 May 2016 15:18:31 -0500 Subject: [PATCH 062/129] Optmize WAR installation --- src/cfml/system/endpoints/ForgeBox.cfc | 82 ++++++++++-------- .../system/services/ServerEngineService.cfc | 84 +++++++++++-------- 2 files changed, 97 insertions(+), 69 deletions(-) diff --git a/src/cfml/system/endpoints/ForgeBox.cfc b/src/cfml/system/endpoints/ForgeBox.cfc index 5a3204f99..f51d5f850 100644 --- a/src/cfml/system/endpoints/ForgeBox.cfc +++ b/src/cfml/system/endpoints/ForgeBox.cfc @@ -181,6 +181,49 @@ component accessors="true" implements="IEndpointInteractive" singleton { } } + /* + * Figures out what version of a package would be installed with a given semver range without actually going through the installation. + * @slug Slug of package + * @version Version range to satisfy + * @entryData Optional struct of entryData which skips the ForgeBox call. + */ + function findSatisfyingVersion( required string slug, required string version, struct entryData ) { + + // Use passed in entrydata, or go get it from ForgeBox. + var entryData = arguments.entryData ?: forgebox.getEntry( arguments.slug ); + + entryData.versions.sort( function( a, b ) { return semanticVersion.compare( b.version, a.version ) } ); + + var found = false; + for( var thisVersion in entryData.versions ) { + if( semanticVersion.satisfies( thisVersion.version, arguments.version ) ) { + return thisVersion; + } + } + + // If we requsted stable and all releases are pre-release, just grab the latest + if( arguments.version == 'stable' && arrayLen( entryData.versions ) ) { + return entryData.versions[ 1 ]; + } else { + throw( 'Version [#arguments.version#] not found for package [#arguments.slug#].', 'endpointException', 'Available versions are [#entryData.versions.map( function( i ){ return ' ' & i.version; } ).toList()#]' ); + } + } + + public function parseSlug( required string package ) { + return listFirst( arguments.package, '@' ); + } + + public function parseVersion( required string package ) { + var version = 'stable'; + // foo@1.0.0 + if( arguments.package contains '@' ) { + // Note this can also be a semver range like 1.2.x, >2.0.0, or 1.0.4-2.x + // For now I'm assuming it's a specific version + version = listRest( arguments.package, '@' ); + } + return version; + } + // Private methods @@ -204,27 +247,9 @@ component accessors="true" implements="IEndpointInteractive" singleton { throw( 'The ForgeBox entry [#entryData.title#] is inactive.', 'endpointException' ); } - entryData.versions.sort( function( a, b ) { return semanticVersion.compare( b.version, a.version ) } ); - - var found = false; - for( var thisVersion in entryData.versions ) { - if( semanticVersion.satisfies( thisVersion.version, arguments.version ) ) { - arguments.version = thisVersion.version; - var downloadURL = thisVersion.downloadURL; - found = true; - break; - } - } - - if( !found ) { - // If we requsted stable and all releases are pre-release, just grab the latest - if( arguments.version == 'stable' && arrayLen( entryData.versions ) ) { - arguments.version = entryData.versions[ 1 ].version; - var downloadURL = entryData.versions[ 1 ].downloadURL; - } else { - throw( 'Version [#arguments.version#] not found for package [#arguments.slug#].', 'endpointException', 'Available versions are [#entryData.versions.map( function( i ){ return ' ' & i.version; } ).toList()#]' ); - } - } + var satisfyingVersion = findSatisfyingVersion( slug, version, entryData ); + arguments.version = satisfyingVersion.version; + var downloadURL = satisfyingVersion.downloadURL; if( !len( downloadurl ) ) { throw( 'No download URL provided in ForgeBox. Manual install only.', 'endpointException' ); @@ -276,20 +301,5 @@ component accessors="true" implements="IEndpointInteractive" singleton { throw( '#e.message##CR##e.detail#', 'endpointException' ); } } - - private function parseSlug( required string package ) { - return listFirst( arguments.package, '@' ); - } - - private function parseVersion( required string package ) { - var version = 'stable'; - // foo@1.0.0 - if( arguments.package contains '@' ) { - // Note this can also be a semver range like 1.2.x, >2.0.0, or 1.0.4-2.x - // For now I'm assuming it's a specific version - version = listRest( arguments.package, '@' ); - } - return version; - } } \ No newline at end of file diff --git a/src/cfml/system/services/ServerEngineService.cfc b/src/cfml/system/services/ServerEngineService.cfc index e5dc88b81..a9b163fc2 100644 --- a/src/cfml/system/services/ServerEngineService.cfc +++ b/src/cfml/system/services/ServerEngineService.cfc @@ -12,32 +12,31 @@ component accessors="true" singleton="true" { // DI property name='tempDir' inject='tempDir@constants'; property name='packageService' inject='PackageService'; + property name='endpointService' inject='EndpointService'; property name='logger' inject='logbox:logger:{this}'; property name='consoleLogger' inject='logbox:logger:console'; property name="cfengineVersions" inject="cfengineVersions@constants"; property name='cr' inject='cr@constants'; + property name='shell' inject='shell'; /** * install the server if not already installed to the target directory * @cfengine CFML Engine name (lucee, adobe, railo) * @basedirectory base directory for server install - * @version Version number or empty to use default **/ - public function install( required cfengine, required basedirectory, force=false) { + public function install( required cfengine, required basedirectory ) { var version = find("@",cfengine) ? listLast(cfengine,"@") : ""; engineName = listFirst(cfengine,"@"); basedirectory = !basedirectory.endsWith("/") ? basedirectory & "/" : basedirectory; - - consoleLogger.info("Installing #engineName# #version# in #basedirectory#"); - - if( engineName contains "adobe" ) { + + if( engineName == "adobe" ) { return installAdobe( destination=basedirectory, version=version ); - } else if (engineName contains "railo") { + } else if (engineName == "railo") { return installRailo( destination=basedirectory, version=version ); - } else if (engineName contains "lucee") { + } else if (engineName == "lucee") { return installLucee( destination=basedirectory, version=version ); } else { - return installEngineArchive( cfengine, basedirectory, engineName ); + return installEngineArchive( cfengine, basedirectory ); } } @@ -47,12 +46,10 @@ component accessors="true" singleton="true" { * @version Version number or empty to use default **/ public function installAdobe( required destination, required version ) { - - var installDir = installEngineArchive( 'adobe-coldFusion-cf-engine@#version#', destination, 'adobe' ); - + var installDir = installEngineArchive( 'adobe-coldFusion-cf-engine@#version#', destination ); // set password to "commandbox" + // TODO: Just make this changes directly in the WAR files fileWrite( installDir & "/WEB-INF/cfusion/lib/password.properties", "rdspassword=#cr#password=commandbox#cr#encrypted=false"); - return installDir; } @@ -62,9 +59,7 @@ component accessors="true" singleton="true" { * @version Version number or empty to use default **/ public function installLucee( required destination, required version ) { - - var installDir = installEngineArchive( 'lucee-cf-engine@#version#', destination, 'lucee' ); - + var installDir = installEngineArchive( 'lucee-cf-engine@#version#', destination ); configureWebXML(cfengine="lucee",source="#installDir#/WEB-INF/web.xml",destination="#installDir#/WEB-INF/web.xml"); return installDir; } @@ -75,11 +70,8 @@ component accessors="true" singleton="true" { * @version Version number or empty to use default **/ public function installRailo( required destination, required version ) { - - var installDir = installEngineArchive( 'railo-cf-engine@#version#', destination, 'railo' ); - - configureWebXML(cfengine="railo",source="#installDir#/WEB-INF/web.xml",destination="#installDir#/WEB-INF/web.xml"); - + var installDir = installEngineArchive( 'railo-cf-engine@#version#', destination ); + configureWebXML(cfengine="railo",source="#installDir#/WEB-INF/web.xml",destination="#installDir#/WEB-INF/web.xml"); return installDir; } @@ -90,32 +82,56 @@ component accessors="true" singleton="true" { * * @ID The endpoint ID to use for the CF Engine. * @destination The folder where this site's servers are stored. - * @cfengine The name of this engine. Used to created the final folder to store the WAR. - * @installDir If passed in, use this location to install the WAR instead of auto-calculating it. */ - function installEngineArchive( required string ID, required string destination, required string cfengine, string installDir ) { + function installEngineArchive( + required string ID, + required string destination + ) { var thisTempDir = tempDir & '/' & createUUID(); - var versionInstalled = '0'; + + // Find out what endpoint will service them and ask the endpoint what their name is. + var endpointData = endpointService.resolveEndpoint( ID, shell.pwd() ); + var endpoint = endpointData.endpoint; + var engineName = endpoint.getDefaultName( ID ); + + // In order to prevent uneccessary work, we're going to try REALLY hard to figure out exactly what engine will be installed + // before it actually happens so we can skip this whole mess if it's already in place. + if( endpointData.endpointName == 'forgebox' ) { + + // if our endpoint is ForgeBox, figure out what version it is going to install. + var satisfyingVersion = endpoint.findSatisfyingVersion( endpoint.parseSlug( ID ), endpoint.parseVersion( ID ) ); + var installDir = destination & engineName & "-" & replace( satisfyingVersion.version, '+', '.', 'all' ); + + } else { + + // For all other endpoints, create a predictable folder based on the endpoint ID. + // If the file that the endpoint points to changes, you'll have to forget the server to pick up changes. + // The alternative is re-downloading the engine EVERY. SINGLE. TIME. + var installDir = destination & engineName; + + } + + // Check to see if this WAR has already been exploded + if( fileExists( installDir & '/WEB-INF/web.xml' ) ) { + consoleLogger.info( "WAR/zip archive already installed."); + return installDir; + } + // Install the engine via our standard package service packageService.installPackage( ID=arguments.ID, directory=thisTempDir, save=false ); - if( packageService.isPackage( thisTempDir ) ) { - var boxJSON = packageService.readPackageDescriptor( thisTempDir ); - versionInstalled = boxJSON.version; - } - + // Look for a war or zip archive inside the package var theArchive = ''; for( var thisFile in directoryList( thisTempDir ) ) { if( listFindNoCase( 'war,zip', listLast( thisFile, '.' ) ) ) { theArchive = thisFile; } } - + + // If there's no archive, we don't know what to do! if( theArchive == '' ) { throw( "Package didn't contain a war or zip archive." ); } - - var installDir = arguments.installDir ?: destination & cfengine & "-" & replace( versionInstalled, '+', '.', 'all' ); consoleLogger.info( "Exploding WAR/zip archive..."); zip action="unzip" file="#thisFile#" destination="#installDir#" overwrite="true"; @@ -132,6 +148,8 @@ component accessors="true" singleton="true" { } /** * configure web.xml file for Lucee and Railo + * TODO: Just make these changes directly in the WAR files + * * @cfengine lucee or railo * @source source web.xml * @destination target web.xml From a096fb364a2fff79bab16ac8292a2f910eda6e1f Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 3 May 2016 17:05:59 -0500 Subject: [PATCH 063/129] COMMANDBOX-378 --- src/cfml/system/services/ServerService.cfc | 103 ++++++++++-------- src/java/cliloader/LoaderCLIMain.java | 10 +- src/resources/traymenu-adobe.json | 5 + src/resources/traymenu-default.json | 4 + .../{traymenu.json => traymenu-lucee.json} | 0 src/resources/traymenu-railo.json | 6 + 6 files changed, 80 insertions(+), 48 deletions(-) create mode 100644 src/resources/traymenu-adobe.json create mode 100644 src/resources/traymenu-default.json rename src/resources/{traymenu.json => traymenu-lucee.json} (100%) create mode 100644 src/resources/traymenu-railo.json diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index f5c3a7f64..6cb0277e1 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -326,7 +326,7 @@ component accessors="true" singleton { if( !directoryExists( serverInfo.logDir ) ){ directoryCreate( serverInfo.logDir ); } // The process native name - var processName = serverInfo.name is "" ? "CommandBox" : serverInfo.name; + var processName = ( serverInfo.name is "" ? "CommandBox" : serverInfo.name ) & ' [' & serverinfo.cfengine & ']'; var javaagent = serverinfo.cfengine == "lucee" ? "" : "-javaagent:""#libdir#/lucee-inst.jar"""; if( serverInfo.cfengine != "lucee" && serverInfo.cfengine != "lucee@" & cfengineVersions["lucee"][1]){ @@ -351,55 +351,66 @@ component accessors="true" singleton { serverInfo.logdir = serverInfo.webConfigDir & "/logs"; } + // This is due to a bug in RunWar not creating the right directory for the logs directoryCreate( serverInfo.logDir, true, true ); - - // The java arguments to execute: Shared server, custom web configs - var args = " #serverInfo.JVMargs# -Xmx#serverInfo.heapSize#m -Xms#serverInfo.heapSize#m" - & " #javaagent# -jar ""#variables.jarPath#""" - & " --background=true --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 http://#serverInfo.host#:#serverInfo.port#" - & " --cfengine-name #serverInfo.cfengine# --server-name ""#serverInfo.name#""" - & " --tray-icon ""#serverInfo.trayIcon#"" --tray-config ""#libdir#/traymenu.json""" - & " --directoryindex ""#serverInfo.directoryBrowsing#"" --cfml-web-config ""#serverInfo.webConfigDir#""" - & " --cfml-server-config ""#serverInfo.serverConfigDir#"" #serverInfo.runwarArgs# "; - // standalone or not - if( serverInfo.cfengine != "lucee" && serverInfo.cfengine != "lucee@" & cfengineVersions["lucee"][1]){ - args &= " -war ""#serverInfo.webroot#"" --lib-dirs ""#installDir#/WEB-INF/lib"" --web-xml-path ""#installDir#/WEB-INF/web.xml"""; - } else if (serverInfo.WARPath != "") { - args &= " -war ""#serverInfo.webroot#"""; - } else { - args &= " -war ""#serverInfo.webroot#"" --lib-dirs ""#libDirs#"""; - } - // Incorporate SSL to command - if( serverInfo.SSLEnable ){ - args &= " --http-enable #serverInfo.HTTPEnable# --ssl-enable #serverInfo.SSLEnable# --ssl-port #serverInfo.SSLPort#"; - } - if( serverInfo.SSLEnable && serverInfo.SSLCert != "") { - args &= " --ssl-cert ""#serverInfo.SSLCert#"" --ssl-key ""#serverInfo.SSLKey#"" --ssl-keypass ""#serverInfo.SSLKeyPass#"""; - } - // Incorporate web-xml to command - if ( Len( Trim( serverInfo.webXml ?: "" ) ) ) { - args &= " --web-xml-path ""#serverInfo.webXml#"""; - } - // Incorporate rewrites to command - args &= " --urlrewrite-enable #serverInfo.rewritesEnable#"; - - if( serverInfo.rewritesEnable ){ - serverInfo.rewritesConfig = fileSystemUtil.resolvePath( serverInfo.rewritesConfig ); - if( !fileExists(serverInfo.rewritesConfig) ){ - return "URL rewrite config not found #serverInfo.rewritesConfig#"; - } - args &= " --urlrewrite-file ""#serverInfo.rewritesConfig#"""; + // Guess the proper set of tray icons based on the cfengine name. + var trayConfigJSON = '#libdir#/traymenu-default.json'; + if( serverInfo.cfengine contains "lucee" ) { + trayConfigJSON = '#libdir#/traymenu-lucee.json'; + } else if( serverInfo.cfengine contains "railo" ) { + trayConfigJSON = '#libdir#/traymenu-railo.json'; + } else if( serverInfo.cfengine contains "adobe" ) { + trayConfigJSON = '#libdir#/traymenu-adobe.json'; + } + + // The java arguments to execute: Shared server, custom web configs + var args = " #serverInfo.JVMargs# -Xmx#serverInfo.heapSize#m -Xms#serverInfo.heapSize#m" + & " #javaagent# -jar ""#variables.jarPath#""" + & " --background=true --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 http://#serverInfo.host#:#serverInfo.port#" + & " --cfengine-name #serverInfo.cfengine# --server-name ""#serverInfo.name#""" + & " --tray-icon ""#serverInfo.trayIcon#"" --tray-config ""#trayConfigJSON#""" + & " --directoryindex ""#serverInfo.directoryBrowsing#"" --cfml-web-config ""#serverInfo.webConfigDir#""" + & " --cfml-server-config ""#serverInfo.serverConfigDir#"" #serverInfo.runwarArgs# "; + // standalone or not + if( serverInfo.cfengine != "lucee" && serverInfo.cfengine != "lucee@" & cfengineVersions["lucee"][1]){ + args &= " -war ""#serverInfo.webroot#"" --lib-dirs ""#installDir#/WEB-INF/lib"" --web-xml-path ""#installDir#/WEB-INF/web.xml"""; + } else if (serverInfo.WARPath != "") { + args &= " -war ""#serverInfo.webroot#"""; + } else { + args &= " -war ""#serverInfo.webroot#"" --lib-dirs ""#libDirs#"""; + } + // Incorporate SSL to command + if( serverInfo.SSLEnable ){ + args &= " --http-enable #serverInfo.HTTPEnable# --ssl-enable #serverInfo.SSLEnable# --ssl-port #serverInfo.SSLPort#"; + } + if( serverInfo.SSLEnable && serverInfo.SSLCert != "") { + args &= " --ssl-cert ""#serverInfo.SSLCert#"" --ssl-key ""#serverInfo.SSLKey#"" --ssl-keypass ""#serverInfo.SSLKeyPass#"""; + } + // Incorporate web-xml to command + if ( Len( Trim( serverInfo.webXml ?: "" ) ) ) { + args &= " --web-xml-path ""#serverInfo.webXml#"""; + } + // Incorporate rewrites to command + args &= " --urlrewrite-enable #serverInfo.rewritesEnable#"; + + if( serverInfo.rewritesEnable ){ + serverInfo.rewritesConfig = fileSystemUtil.resolvePath( serverInfo.rewritesConfig ); + if( !fileExists(serverInfo.rewritesConfig) ){ + return "URL rewrite config not found #serverInfo.rewritesConfig#"; } - - // Persist server information - setServerInfo( serverInfo ); + args &= " --urlrewrite-file ""#serverInfo.rewritesConfig#"""; + } + + // Persist server information + setServerInfo( serverInfo ); - // change status to starting + persist - serverInfo.status = "starting"; - setServerInfo( serverInfo ); + // change status to starting + persist + serverInfo.status = "starting"; + setServerInfo( serverInfo ); + if(serverInfo.debug) { consoleLogger.debug("Server start command: #javaCommand# #args#"); } diff --git a/src/java/cliloader/LoaderCLIMain.java b/src/java/cliloader/LoaderCLIMain.java index 71f7be037..37192c8eb 100644 --- a/src/java/cliloader/LoaderCLIMain.java +++ b/src/java/cliloader/LoaderCLIMain.java @@ -622,8 +622,14 @@ public static void main( String[] arguments ) throws Throwable{ cli_home.getPath() + "/engine" ), debug ); Util.copyInternalFile( classLoader, "resource/trayicon.png", new File( libDir, "trayicon.png" ) ); - Util.copyInternalFile( classLoader, "resource/traymenu.json", - new File( libDir, "traymenu.json" ) ); + Util.copyInternalFile( classLoader, "resource/traymenu-adobe.json", + new File( libDir, "traymenu-adobe.json" ) ); + Util.copyInternalFile( classLoader, "resource/traymenu-railo.json", + new File( libDir, "traymenu-railo.json" ) ); + Util.copyInternalFile( classLoader, "resource/traymenu-lucee.json", + new File( libDir, "traymenu-lucee.json" ) ); + Util.copyInternalFile( classLoader, "resource/traymenu-default.json", + new File( libDir, "traymenu-default.json" ) ); Util.copyInternalFile( classLoader, VERSION_PROPERTIES_PATH, new File( libDir, "version.properties" ) ); System.out.println( "" ); diff --git a/src/resources/traymenu-adobe.json b/src/resources/traymenu-adobe.json new file mode 100644 index 000000000..835854b1f --- /dev/null +++ b/src/resources/traymenu-adobe.json @@ -0,0 +1,5 @@ +[ +{"label":"Stop Server (${runwar.processName})", "action":"stopserver"} +,{"label":"Open Browser", "action":"openbrowser", "url":"http://${runwar.host}:${runwar.port}/"} +,{"label":"Open Server Admin", "action":"openbrowser", "url":"http://${runwar.host}:${runwar.port}/CFIDE/administrator/enter.cfm"} +] diff --git a/src/resources/traymenu-default.json b/src/resources/traymenu-default.json new file mode 100644 index 000000000..79a8ca7d4 --- /dev/null +++ b/src/resources/traymenu-default.json @@ -0,0 +1,4 @@ +[ +{"label":"Stop Server (${runwar.processName})", "action":"stopserver"} +,{"label":"Open Browser", "action":"openbrowser", "url":"http://${runwar.host}:${runwar.port}/"} +] diff --git a/src/resources/traymenu.json b/src/resources/traymenu-lucee.json similarity index 100% rename from src/resources/traymenu.json rename to src/resources/traymenu-lucee.json diff --git a/src/resources/traymenu-railo.json b/src/resources/traymenu-railo.json new file mode 100644 index 000000000..140efa2a2 --- /dev/null +++ b/src/resources/traymenu-railo.json @@ -0,0 +1,6 @@ +[ +{"label":"Stop Server (${runwar.processName})", "action":"stopserver"} +,{"label":"Open Browser", "action":"openbrowser", "url":"http://${runwar.host}:${runwar.port}/"} +,{"label":"Open Server Admin", "action":"openbrowser", "url":"http://${runwar.host}:${runwar.port}/railo-context/admin/server.cfm"} +,{"label":"Open Web Admin", "action":"openbrowser", "url":"http://${runwar.host}:${runwar.port}/railo-context/admin/web.cfm"} +] From fbcc89ac49fb1a0529241de60eab8093765eca9e Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 3 May 2016 22:29:33 -0500 Subject: [PATCH 064/129] Final removal of hard-coded versions --- src/cfml/system/config/WireBox.cfc | 8 +-- .../system/services/ServerEngineService.cfc | 68 +++++++++---------- src/cfml/system/services/ServerService.cfc | 37 +++++----- 3 files changed, 55 insertions(+), 58 deletions(-) diff --git a/src/cfml/system/config/WireBox.cfc b/src/cfml/system/config/WireBox.cfc index e5c667635..60b231d9a 100644 --- a/src/cfml/system/config/WireBox.cfc +++ b/src/cfml/system/config/WireBox.cfc @@ -51,11 +51,6 @@ component extends="wirebox.system.ioc.config.Binder" { var ortusArtifactsURL = 'http://integration.stg.ortussolutions.com/artifacts/'; var ortusPRDArtifactsURL = 'http://downloads.ortussolutions.com/'; // engine versions, first is default - for lucee, first is internal version - var cfengineVersions = { - "lucee":["4.5.2.018","5.0.0.243-SNAPSHOT"] - ,"adobe":["11.0.0.289974","2016.0.0.297996","10.0.12.286680","9.0.2.282541"] - ,"railo":["4.2.1.008"] - }; // map constants map( 'system@constants' ).toValue( system ); @@ -71,8 +66,7 @@ component extends="wirebox.system.ioc.config.Binder" { map( 'ortusArtifactsURL@constants' ).toValue( ortusArtifactsURL ); map( 'ortusPRDArtifactsURL@constants' ).toValue( ortusPRDArtifactsURL ); map( 'rewritesDefaultConfig@constants' ).toValue( "#homeDir#/cfml/system/config/urlrewrite.xml" ); - map( 'cfengineVersions@constants' ).toValue( cfengineVersions ); - + // Map Java Classes map( 'commandHistoryFile@java' ).toJava( "jline.console.history.FileHistory" ) .initWith( createObject( "java", "java.io.File" ).init( commandHistoryFile ) ) diff --git a/src/cfml/system/services/ServerEngineService.cfc b/src/cfml/system/services/ServerEngineService.cfc index a9b163fc2..7eb7944e5 100644 --- a/src/cfml/system/services/ServerEngineService.cfc +++ b/src/cfml/system/services/ServerEngineService.cfc @@ -15,7 +15,6 @@ component accessors="true" singleton="true" { property name='endpointService' inject='EndpointService'; property name='logger' inject='logbox:logger:{this}'; property name='consoleLogger' inject='logbox:logger:console'; - property name="cfengineVersions" inject="cfengineVersions@constants"; property name='cr' inject='cr@constants'; property name='shell' inject='shell'; @@ -46,11 +45,11 @@ component accessors="true" singleton="true" { * @version Version number or empty to use default **/ public function installAdobe( required destination, required version ) { - var installDir = installEngineArchive( 'adobe-coldFusion-cf-engine@#version#', destination ); + var installDetails = installEngineArchive( 'adobe-coldFusion-cf-engine@#version#', destination ); // set password to "commandbox" // TODO: Just make this changes directly in the WAR files - fileWrite( installDir & "/WEB-INF/cfusion/lib/password.properties", "rdspassword=#cr#password=commandbox#cr#encrypted=false"); - return installDir; + fileWrite( installDetails.installDir & "/WEB-INF/cfusion/lib/password.properties", "rdspassword=#cr#password=commandbox#cr#encrypted=false"); + return installDetails; } /** @@ -59,9 +58,11 @@ component accessors="true" singleton="true" { * @version Version number or empty to use default **/ public function installLucee( required destination, required version ) { - var installDir = installEngineArchive( 'lucee-cf-engine@#version#', destination ); - configureWebXML(cfengine="lucee",source="#installDir#/WEB-INF/web.xml",destination="#installDir#/WEB-INF/web.xml"); - return installDir; + var installDetails = installEngineArchive( 'lucee-cf-engine@#version#', destination ); + if( !installDetails.internal ) { + configureWebXML(cfengine="lucee",source="#installDetails.installDir#/WEB-INF/web.xml",destination="#installDetails.installDir#/WEB-INF/web.xml"); + } + return installDetails; } /** @@ -70,9 +71,9 @@ component accessors="true" singleton="true" { * @version Version number or empty to use default **/ public function installRailo( required destination, required version ) { - var installDir = installEngineArchive( 'railo-cf-engine@#version#', destination ); - configureWebXML(cfengine="railo",source="#installDir#/WEB-INF/web.xml",destination="#installDir#/WEB-INF/web.xml"); - return installDir; + var installDetails = installEngineArchive( 'railo-cf-engine@#version#', destination ); + configureWebXML(cfengine="railo",source="#installDetails.installDir#/WEB-INF/web.xml",destination="#installDetails.installDir#/WEB-INF/web.xml"); + return installDetails; } @@ -87,35 +88,48 @@ component accessors="true" singleton="true" { required string ID, required string destination ) { + + var installDetails = { + internal : false, + version : '', + installDir : '' + }; + var thisTempDir = tempDir & '/' & createUUID(); // Find out what endpoint will service them and ask the endpoint what their name is. var endpointData = endpointService.resolveEndpoint( ID, shell.pwd() ); var endpoint = endpointData.endpoint; - var engineName = endpoint.getDefaultName( ID ); + var engineName = endpoint.getDefaultName( arguments.ID ); // In order to prevent uneccessary work, we're going to try REALLY hard to figure out exactly what engine will be installed // before it actually happens so we can skip this whole mess if it's already in place. if( endpointData.endpointName == 'forgebox' ) { // if our endpoint is ForgeBox, figure out what version it is going to install. - var satisfyingVersion = endpoint.findSatisfyingVersion( endpoint.parseSlug( ID ), endpoint.parseVersion( ID ) ); - var installDir = destination & engineName & "-" & replace( satisfyingVersion.version, '+', '.', 'all' ); + var satisfyingVersion = endpoint.findSatisfyingVersion( endpoint.parseSlug( arguments.ID ), endpoint.parseVersion( arguments.ID ) ); + installDetails.installDir = destination & engineName & "-" & replace( satisfyingVersion.version, '+', '.', 'all' ); + installDetails.version = satisfyingVersion.version; } else { // For all other endpoints, create a predictable folder based on the endpoint ID. // If the file that the endpoint points to changes, you'll have to forget the server to pick up changes. // The alternative is re-downloading the engine EVERY. SINGLE. TIME. - var installDir = destination & engineName; + installDetails.installDir = destination & engineName; } + if( listFirst( arguments.ID, '@' ) == 'lucee-cf-engine' && server.lucee.version == replace( installDetails.version, '+', '.', 'all' ) ) { + installDetails.internal = true; + return installDetails; + } + // Check to see if this WAR has already been exploded - if( fileExists( installDir & '/WEB-INF/web.xml' ) ) { + if( fileExists( installDetails.installDir & '/WEB-INF/web.xml' ) ) { consoleLogger.info( "WAR/zip archive already installed."); - return installDir; - } + return installDetails; + } // Install the engine via our standard package service packageService.installPackage( ID=arguments.ID, directory=thisTempDir, save=false ); @@ -134,7 +148,7 @@ component accessors="true" singleton="true" { } consoleLogger.info( "Exploding WAR/zip archive..."); - zip action="unzip" file="#thisFile#" destination="#installDir#" overwrite="true"; + zip action="unzip" file="#thisFile#" destination="#installDetails.installDir#" overwrite="true"; // Catch this to gracefully handle where the OS or another program // has the folder locked. @@ -144,7 +158,7 @@ component accessors="true" singleton="true" { consoleLogger.error( '#e.message##CR#The folder is possibly locked by another program.' ); logger.error( '#e.message# #e.detail#' , e.stackTrace ); } - return installDir; + return installDetails; } /** * configure web.xml file for Lucee and Railo @@ -176,21 +190,7 @@ component accessors="true" singleton="true" { * Dynamic completion for cfengine */ function getCFEngineNames() { - var engineNames = ["lucee","adobe","railo"]; - var namesAndVersions = []; - for (var name in engineNames) { - for (var version in cfengineVersions[name]) { - arrayAppend(namesAndVersions,name & "@" & ucase(version)); - } - } - return namesAndVersions; + return ["lucee","adobe","railo"]; } - /** - * Dynamic completion for cfengine - */ - function getCFEngineVersions(required cfengine) { - return cfengineVersions[cfengine]; - } - } \ No newline at end of file diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 6cb0277e1..da3f22ea8 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -43,7 +43,6 @@ component accessors="true" singleton { property name='serverEngineService' inject='serverEngineService'; property name='consoleLogger' inject='logbox:logger:console'; property name='wirebox' inject='wirebox'; - property name="cfengineVersions" inject="cfengineVersions@constants"; /** * Constructor @@ -329,27 +328,28 @@ component accessors="true" singleton { var processName = ( serverInfo.name is "" ? "CommandBox" : serverInfo.name ) & ' [' & serverinfo.cfengine & ']'; var javaagent = serverinfo.cfengine == "lucee" ? "" : "-javaagent:""#libdir#/lucee-inst.jar"""; - if( serverInfo.cfengine != "lucee" && serverInfo.cfengine != "lucee@" & cfengineVersions["lucee"][1]){ + if( serverInfo.WARPath == '' ){ try { - var installDir = serverEngineService.install( cfengine=serverInfo.cfengine, basedirectory=serverInfo.webConfigDir ); - serverInfo.logdir = installDir & "/logs"; + var installDetails = serverEngineService.install( cfengine=serverInfo.cfengine, basedirectory=serverInfo.webConfigDir ); + serverInfo.logdir = installDetails.installDir & "/logs"; } catch (any e) { consoleLogger.error("Error installing server - " & e.message); consoleLogger.error(e.detail.replaceAll(",","#chr(10)#")); return; } - if(serverInfo.cfengine contains "lucee") { - javaagent = "-javaagent:""#installDir#/WEB-INF/lib/lucee-inst.jar"""; + if( !installDetails.internal && serverInfo.cfengine contains "lucee" ) { + javaagent = "-javaagent:""#installDetails.installDir#/WEB-INF/lib/lucee-inst.jar"""; } - if(serverInfo.cfengine contains "railo") { - javaagent = "-javaagent:""#installDir#/WEB-INF/lib/railo-inst.jar"""; + if( !installDetails.internal && serverInfo.cfengine contains "railo" ) { + javaagent = "-javaagent:""#installDetails.installDir#/WEB-INF/lib/railo-inst.jar"""; } - // Using built in server that hasn't been started before - } else if( !directoryExists( serverInfo.webConfigDir & '/WEB-INF' ) ) { - serverInfo.webConfigDir &= '/lucee-#cfengineVersions["lucee"][1]#'; - serverInfo.logdir = serverInfo.webConfigDir & "/logs"; - } + // Using built in server that hasn't been started before + if( installDetails.internal && !directoryExists( serverInfo.webConfigDir & '/WEB-INF' ) ) { + serverInfo.webConfigDir = installDetails.installDir; + serverInfo.logdir = serverInfo.webConfigDir & "/logs"; + } + } // This is due to a bug in RunWar not creating the right directory for the logs directoryCreate( serverInfo.logDir, true, true ); @@ -374,11 +374,14 @@ component accessors="true" singleton { & " --tray-icon ""#serverInfo.trayIcon#"" --tray-config ""#trayConfigJSON#""" & " --directoryindex ""#serverInfo.directoryBrowsing#"" --cfml-web-config ""#serverInfo.webConfigDir#""" & " --cfml-server-config ""#serverInfo.serverConfigDir#"" #serverInfo.runwarArgs# "; - // standalone or not - if( serverInfo.cfengine != "lucee" && serverInfo.cfengine != "lucee@" & cfengineVersions["lucee"][1]){ - args &= " -war ""#serverInfo.webroot#"" --lib-dirs ""#installDir#/WEB-INF/lib"" --web-xml-path ""#installDir#/WEB-INF/web.xml"""; - } else if (serverInfo.WARPath != "") { + + // Starting a WAR + if (serverInfo.WARPath != "" ) { args &= " -war ""#serverInfo.webroot#"""; + // Stand alone server + } else if( !installDetails.internal ){ + args &= " -war ""#serverInfo.webroot#"" --lib-dirs ""#installDetails.installDir#/WEB-INF/lib"" --web-xml-path ""#installDetails.installDir#/WEB-INF/web.xml"""; + // internal server } else { args &= " -war ""#serverInfo.webroot#"" --lib-dirs ""#libDirs#"""; } From 28d0854862e2a1fd68dcd273b94314475610e0c3 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 3 May 2016 22:36:27 -0500 Subject: [PATCH 065/129] comments and scoping --- src/cfml/system/endpoints/ForgeBox.cfc | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/cfml/system/endpoints/ForgeBox.cfc b/src/cfml/system/endpoints/ForgeBox.cfc index f51d5f850..a91fbab8e 100644 --- a/src/cfml/system/endpoints/ForgeBox.cfc +++ b/src/cfml/system/endpoints/ForgeBox.cfc @@ -190,29 +190,37 @@ component accessors="true" implements="IEndpointInteractive" singleton { function findSatisfyingVersion( required string slug, required string version, struct entryData ) { // Use passed in entrydata, or go get it from ForgeBox. - var entryData = arguments.entryData ?: forgebox.getEntry( arguments.slug ); + arguments.entryData = arguments.entryData ?: forgebox.getEntry( arguments.slug ); - entryData.versions.sort( function( a, b ) { return semanticVersion.compare( b.version, a.version ) } ); + arguments.entryData.versions.sort( function( a, b ) { return semanticVersion.compare( b.version, a.version ) } ); var found = false; - for( var thisVersion in entryData.versions ) { + for( var thisVersion in arguments.entryData.versions ) { if( semanticVersion.satisfies( thisVersion.version, arguments.version ) ) { return thisVersion; } } // If we requsted stable and all releases are pre-release, just grab the latest - if( arguments.version == 'stable' && arrayLen( entryData.versions ) ) { - return entryData.versions[ 1 ]; + if( arguments.version == 'stable' && arrayLen( arguments.entryData.versions ) ) { + return arguments.entryData.versions[ 1 ]; } else { - throw( 'Version [#arguments.version#] not found for package [#arguments.slug#].', 'endpointException', 'Available versions are [#entryData.versions.map( function( i ){ return ' ' & i.version; } ).toList()#]' ); + throw( 'Version [#arguments.version#] not found for package [#arguments.slug#].', 'endpointException', 'Available versions are [#arguments.entryData.versions.map( function( i ){ return ' ' & i.version; } ).toList()#]' ); } } + /* + * Parses just the slug portion out of an endpoint ID + * @package The full endpointID like foo@1.0.0 + */ public function parseSlug( required string package ) { return listFirst( arguments.package, '@' ); } - + + /* + * Parses just the version portion out of an endpoint ID + * @package The full endpointID like foo@1.0.0 + */ public function parseVersion( required string package ) { var version = 'stable'; // foo@1.0.0 From 6524f7014a1e58664f160b732c9934c3c21a5c2c Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 3 May 2016 22:44:33 -0500 Subject: [PATCH 066/129] Spacing fixes --- .../system/services/ServerEngineService.cfc | 234 +++++++++--------- 1 file changed, 119 insertions(+), 115 deletions(-) diff --git a/src/cfml/system/services/ServerEngineService.cfc b/src/cfml/system/services/ServerEngineService.cfc index 7eb7944e5..85a74581b 100644 --- a/src/cfml/system/services/ServerEngineService.cfc +++ b/src/cfml/system/services/ServerEngineService.cfc @@ -9,78 +9,80 @@ */ component accessors="true" singleton="true" { - // DI - property name='tempDir' inject='tempDir@constants'; - property name='packageService' inject='PackageService'; - property name='endpointService' inject='EndpointService'; - property name='logger' inject='logbox:logger:{this}'; - property name='consoleLogger' inject='logbox:logger:console'; - property name='cr' inject='cr@constants'; - property name='shell' inject='shell'; - - /** - * install the server if not already installed to the target directory - * @cfengine CFML Engine name (lucee, adobe, railo) - * @basedirectory base directory for server install - **/ - public function install( required cfengine, required basedirectory ) { - var version = find("@",cfengine) ? listLast(cfengine,"@") : ""; - engineName = listFirst(cfengine,"@"); - basedirectory = !basedirectory.endsWith("/") ? basedirectory & "/" : basedirectory; + // DI + property name='tempDir' inject='tempDir@constants'; + property name='packageService' inject='PackageService'; + property name='endpointService' inject='EndpointService'; + property name='logger' inject='logbox:logger:{this}'; + property name='consoleLogger' inject='logbox:logger:console'; + property name='cr' inject='cr@constants'; + property name='shell' inject='shell'; + + /** + * install the server if not already installed to the target directory + * + * @cfengine CFML Engine name (lucee, adobe, railo) + * @basedirectory base directory for server install + **/ + public function install( required cfengine, required basedirectory ) { + var version = find( "@", cfengine ) ? listLast( cfengine, "@" ) : ""; + var engineName = listFirst(cfengine,"@"); + arguments.basedirectory = !arguments.basedirectory.endsWith( "/" ) ? arguments.basedirectory & "/" : arguments.basedirectory; if( engineName == "adobe" ) { - return installAdobe( destination=basedirectory, version=version ); + return installAdobe( destination=arguments.basedirectory, version=version ); } else if (engineName == "railo") { - return installRailo( destination=basedirectory, version=version ); + return installRailo( destination=arguments.basedirectory, version=version ); } else if (engineName == "lucee") { - return installLucee( destination=basedirectory, version=version ); + return installLucee( destination=arguments.basedirectory, version=version ); } else { - return installEngineArchive( cfengine, basedirectory ); + return installEngineArchive( cfengine, arguments.basedirectory ); } } - /** - * install adobe - * @destination target directory - * @version Version number or empty to use default - **/ - public function installAdobe( required destination, required version ) { - var installDetails = installEngineArchive( 'adobe-coldFusion-cf-engine@#version#', destination ); - // set password to "commandbox" - // TODO: Just make this changes directly in the WAR files - fileWrite( installDetails.installDir & "/WEB-INF/cfusion/lib/password.properties", "rdspassword=#cr#password=commandbox#cr#encrypted=false"); - return installDetails; - } + /** + * install adobe + * + * @destination target directory + * @version Version number or empty to use default + **/ + public function installAdobe( required destination, required version ) { + var installDetails = installEngineArchive( 'adobe-coldFusion-cf-engine@#version#', destination ); + // set password to "commandbox" + // TODO: Just make this changes directly in the WAR files + fileWrite( installDetails.installDir & "/WEB-INF/cfusion/lib/password.properties", "rdspassword=#cr#password=commandbox#cr#encrypted=false" ); + return installDetails; + } - /** - * install lucee - * @destination target directory - * @version Version number or empty to use default - **/ - public function installLucee( required destination, required version ) { + /** + * install lucee + * + * @destination target directory + * @version Version number or empty to use default + **/ + public function installLucee( required destination, required version ) { var installDetails = installEngineArchive( 'lucee-cf-engine@#version#', destination ); if( !installDetails.internal ) { - configureWebXML(cfengine="lucee",source="#installDetails.installDir#/WEB-INF/web.xml",destination="#installDetails.installDir#/WEB-INF/web.xml"); - } - return installDetails; - } + configureWebXML( cfengine="lucee", source="#installDetails.installDir#/WEB-INF/web.xml", destination="#installDetails.installDir#/WEB-INF/web.xml" ); } + return installDetails; + } - /** - * install railo - * @destination target directory - * @version Version number or empty to use default - **/ - public function installRailo( required destination, required version ) { + /** + * install railo + * + * @destination target directory + * @version Version number or empty to use default + **/ + public function installRailo( required destination, required version ) { var installDetails = installEngineArchive( 'railo-cf-engine@#version#', destination ); - configureWebXML(cfengine="railo",source="#installDetails.installDir#/WEB-INF/web.xml",destination="#installDetails.installDir#/WEB-INF/web.xml"); - return installDetails; - } - + configureWebXML( cfengine="railo", source="#installDetails.installDir#/WEB-INF/web.xml", destination="#installDetails.installDir#/WEB-INF/web.xml" ); + return installDetails; + } /* * Downloads a CF engine endpoint and unzips the "Engine.[WAR|zip] archive into the destination * The WAR will be placed in a folder named {cfengine}-{version}/ unless an installDir is supplied. - * + * * @ID The endpoint ID to use for the CF Engine. * @destination The folder where this site's servers are stored. */ @@ -95,43 +97,44 @@ component accessors="true" singleton="true" { installDir : '' }; - var thisTempDir = tempDir & '/' & createUUID(); - + var thisTempDir = tempDir & '/' & createUUID(); + // Find out what endpoint will service them and ask the endpoint what their name is. var endpointData = endpointService.resolveEndpoint( ID, shell.pwd() ); var endpoint = endpointData.endpoint; - var engineName = endpoint.getDefaultName( arguments.ID ); - - // In order to prevent uneccessary work, we're going to try REALLY hard to figure out exactly what engine will be installed - // before it actually happens so we can skip this whole mess if it's already in place. - if( endpointData.endpointName == 'forgebox' ) { - - // if our endpoint is ForgeBox, figure out what version it is going to install. - var satisfyingVersion = endpoint.findSatisfyingVersion( endpoint.parseSlug( arguments.ID ), endpoint.parseVersion( arguments.ID ) ); - installDetails.installDir = destination & engineName & "-" & replace( satisfyingVersion.version, '+', '.', 'all' ); - installDetails.version = satisfyingVersion.version; - - } else { - - // For all other endpoints, create a predictable folder based on the endpoint ID. - // If the file that the endpoint points to changes, you'll have to forget the server to pick up changes. - // The alternative is re-downloading the engine EVERY. SINGLE. TIME. - installDetails.installDir = destination & engineName; - - } - - if( listFirst( arguments.ID, '@' ) == 'lucee-cf-engine' && server.lucee.version == replace( installDetails.version, '+', '.', 'all' ) ) { - installDetails.internal = true; - return installDetails; - } - - // Check to see if this WAR has already been exploded - if( fileExists( installDetails.installDir & '/WEB-INF/web.xml' ) ) { - consoleLogger.info( "WAR/zip archive already installed."); + var engineName = endpoint.getDefaultName( arguments.ID ); + + // In order to prevent uneccessary work, we're going to try REALLY hard to figure out exactly what engine will be installed + // before it actually happens so we can skip this whole mess if it's already in place. + if( endpointData.endpointName == 'forgebox' ) { + + // if our endpoint is ForgeBox, figure out what version it is going to install. + var satisfyingVersion = endpoint.findSatisfyingVersion( endpoint.parseSlug( arguments.ID ), endpoint.parseVersion( arguments.ID ) ); + installDetails.installDir = destination & engineName & "-" & replace( satisfyingVersion.version, '+', '.', 'all' ); + installDetails.version = satisfyingVersion.version; + + } else { + + // For all other endpoints, create a predictable folder based on the endpoint ID. + // If the file that the endpoint points to changes, you'll have to forget the server to pick up changes. + // The alternative is re-downloading the engine EVERY. SINGLE. TIME. + installDetails.installDir = destination & engineName; + + } + + // If we're starting a Lucee server whose version matches the CLI engine, then don't download anyting, we're using internal jars. + if( listFirst( arguments.ID, '@' ) == 'lucee-cf-engine' && server.lucee.version == replace( installDetails.version, '+', '.', 'all' ) ) { + installDetails.internal = true; return installDetails; - } - - // Install the engine via our standard package service + } + + // Check to see if this WAR has already been exploded + if( fileExists( installDetails.installDir & '/WEB-INF/web.xml' ) ) { + consoleLogger.info( "WAR/zip archive already installed."); + return installDetails; + } + + // Install the engine via our standard package service packageService.installPackage( ID=arguments.ID, directory=thisTempDir, save=false ); // Look for a war or zip archive inside the package @@ -160,37 +163,38 @@ component accessors="true" singleton="true" { } return installDetails; } - /** - * configure web.xml file for Lucee and Railo - * TODO: Just make these changes directly in the WAR files - * - * @cfengine lucee or railo - * @source source web.xml - * @destination target web.xml - **/ - public function configureWebXML(required cfengine, required source, destination) { - var webXML = XMLParse(source); - var servlets = xmlSearch(webXML,"//:servlet-class[text()='#lcase(cfengine)#.loader.servlet.CFMLServlet']"); - var initParam = xmlElemnew(webXML,"http://java.sun.com/xml/ns/javaee","init-param"); - initParam.XmlChildren[1] = xmlElemnew(webXML,"param-name"); - initParam.XmlChildren[1].XmlText = "#lcase(cfengine)#-web-directory"; - initParam.XmlChildren[2] = xmlElemnew(webXML,"param-value"); - initParam.XmlChildren[2].XmlText = "/WEB-INF/#lcase(cfengine)#/{web-context-label}"; - arrayInsertAt(servlets[1].XmlParent.XmlChildren,4,initParam); + + /** + * configure web.xml file for Lucee and Railo + * TODO: Just make these changes directly in the WAR files + * + * @cfengine lucee or railo + * @source source web.xml + * @destination target web.xml + **/ + public function configureWebXML(required cfengine, required source, destination) { + var webXML = XMLParse(source); + var servlets = xmlSearch(webXML,"//:servlet-class[text()='#lcase(cfengine)#.loader.servlet.CFMLServlet']"); + var initParam = xmlElemnew(webXML,"http://java.sun.com/xml/ns/javaee","init-param"); + initParam.XmlChildren[1] = xmlElemnew(webXML,"param-name"); + initParam.XmlChildren[1].XmlText = "#lcase(cfengine)#-web-directory"; + initParam.XmlChildren[2] = xmlElemnew(webXML,"param-value"); + initParam.XmlChildren[2].XmlText = "/WEB-INF/#lcase(cfengine)#/{web-context-label}"; + arrayInsertAt(servlets[1].XmlParent.XmlChildren,4,initParam); var xlt = ' '; - fileWrite(destination,toString(XmlTransform(webXML,xlt))); - return true; - } + fileWrite(destination,toString(XmlTransform(webXML,xlt))); + return true; + } - /** - * Dynamic completion for cfengine - */ - function getCFEngineNames() { - return ["lucee","adobe","railo"]; - } - + /** + * Dynamic completion for cfengine + */ + function getCFEngineNames() { + return ["lucee","adobe","railo"]; + } + } \ No newline at end of file From afc36ff7754bb24145f7dcf79fde8c82b9343fcc Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 3 May 2016 22:45:52 -0500 Subject: [PATCH 067/129] More spacing --- .../system/services/ServerEngineService.cfc | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/cfml/system/services/ServerEngineService.cfc b/src/cfml/system/services/ServerEngineService.cfc index 85a74581b..62063a0c3 100644 --- a/src/cfml/system/services/ServerEngineService.cfc +++ b/src/cfml/system/services/ServerEngineService.cfc @@ -168,25 +168,25 @@ component accessors="true" singleton="true" { * configure web.xml file for Lucee and Railo * TODO: Just make these changes directly in the WAR files * - * @cfengine lucee or railo - * @source source web.xml - * @destination target web.xml + * @cfengine lucee or railo + * @source source web.xml + * @destination target web.xml **/ - public function configureWebXML(required cfengine, required source, destination) { - var webXML = XMLParse(source); - var servlets = xmlSearch(webXML,"//:servlet-class[text()='#lcase(cfengine)#.loader.servlet.CFMLServlet']"); + public function configureWebXML( required cfengine, required source, destination ) { + var webXML = XMLParse( source ); + var servlets = xmlSearch(webXML,"//:servlet-class[text()='#lcase( cfengine )#.loader.servlet.CFMLServlet']"); var initParam = xmlElemnew(webXML,"http://java.sun.com/xml/ns/javaee","init-param"); initParam.XmlChildren[1] = xmlElemnew(webXML,"param-name"); - initParam.XmlChildren[1].XmlText = "#lcase(cfengine)#-web-directory"; + initParam.XmlChildren[1].XmlText = "#lcase( cfengine )#-web-directory"; initParam.XmlChildren[2] = xmlElemnew(webXML,"param-value"); - initParam.XmlChildren[2].XmlText = "/WEB-INF/#lcase(cfengine)#/{web-context-label}"; + initParam.XmlChildren[2].XmlText = "/WEB-INF/#lcase( cfengine )#/{web-context-label}"; arrayInsertAt(servlets[1].XmlParent.XmlChildren,4,initParam); var xlt = ' '; - fileWrite(destination,toString(XmlTransform(webXML,xlt))); + fileWrite( destination, toString( XmlTransform( webXML, xlt) ) ); return true; } @@ -194,7 +194,7 @@ component accessors="true" singleton="true" { * Dynamic completion for cfengine */ function getCFEngineNames() { - return ["lucee","adobe","railo"]; + return [ "lucee","adobe","railo" ]; } } \ No newline at end of file From 6eccfd3c03363136fa8468c726dbd028a0c1f020 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 3 May 2016 22:51:46 -0500 Subject: [PATCH 068/129] variable naming and spacing --- src/cfml/system/services/ServerEngineService.cfc | 14 +++++++------- src/cfml/system/services/ServerService.cfc | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/cfml/system/services/ServerEngineService.cfc b/src/cfml/system/services/ServerEngineService.cfc index 62063a0c3..0f34c28ba 100644 --- a/src/cfml/system/services/ServerEngineService.cfc +++ b/src/cfml/system/services/ServerEngineService.cfc @@ -22,21 +22,21 @@ component accessors="true" singleton="true" { * install the server if not already installed to the target directory * * @cfengine CFML Engine name (lucee, adobe, railo) - * @basedirectory base directory for server install + * @baseDirectory base directory for server install **/ - public function install( required cfengine, required basedirectory ) { + public function install( required cfengine, required baseDirectory ) { var version = find( "@", cfengine ) ? listLast( cfengine, "@" ) : ""; var engineName = listFirst(cfengine,"@"); - arguments.basedirectory = !arguments.basedirectory.endsWith( "/" ) ? arguments.basedirectory & "/" : arguments.basedirectory; + arguments.baseDirectory = !arguments.baseDirectory.endsWith( "/" ) ? arguments.baseDirectory & "/" : arguments.baseDirectory; if( engineName == "adobe" ) { - return installAdobe( destination=arguments.basedirectory, version=version ); + return installAdobe( destination=arguments.baseDirectory, version=version ); } else if (engineName == "railo") { - return installRailo( destination=arguments.basedirectory, version=version ); + return installRailo( destination=arguments.baseDirectory, version=version ); } else if (engineName == "lucee") { - return installLucee( destination=arguments.basedirectory, version=version ); + return installLucee( destination=arguments.baseDirectory, version=version ); } else { - return installEngineArchive( cfengine, arguments.basedirectory ); + return installEngineArchive( cfengine, arguments.baseDirectory ); } } diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index da3f22ea8..a633f4ce6 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -37,7 +37,7 @@ component accessors="true" singleton { property name='rewritesDefaultConfig' inject='rewritesDefaultConfig@constants'; property name='interceptorService' inject='interceptorService'; - property name='ConfigService' inject='ConfigService'; + property name='configService' inject='ConfigService'; property name='JSONService' inject='JSONService'; property name='packageService' inject='packageService'; property name='serverEngineService' inject='serverEngineService'; @@ -168,7 +168,7 @@ component accessors="true" singleton { Struct serverProps ){ - if(isNull(serverProps.name)) { + if( isNull( serverProps.name ) ) { serverProps.name = listLast( serverProps.directory, "\/" ); } @@ -627,7 +627,7 @@ component accessors="true" singleton { // Discover by shortname or webroot if( len( arguments.name ) ){ var foundServer = getServerInfoByName( arguments.name ); - if(!isNull(foundServer)) { + if( !isNull( foundServer ) ) { return foundServer; } } From 40c25650e9e88a374217132f3cc1a4877c90e3de Mon Sep 17 00:00:00 2001 From: denuno Date: Wed, 4 May 2016 00:55:35 -0600 Subject: [PATCH 069/129] fixes WEB-INF/cfform directory being created in project dir on some adobe versions, and bumps runwar so we get the downgraded undertow that still works with java 7 --- build/build.properties | 2 +- src/cfml/system/services/ServerEngineService.cfc | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/build/build.properties b/build/build.properties index 77c99d208..a19f7ff3a 100644 --- a/build/build.properties +++ b/build/build.properties @@ -17,7 +17,7 @@ cfml.cli.version=${cfml.loader.version}.${cfml.version} lucee.version=4.5.2.018 jre.version=1.8.0_77 launch4j.version=3.4 -runwar.version=3.4.1 +runwar.version=3.4.2 #build locations build.type=localdev diff --git a/src/cfml/system/services/ServerEngineService.cfc b/src/cfml/system/services/ServerEngineService.cfc index 0f34c28ba..8a4cb8036 100644 --- a/src/cfml/system/services/ServerEngineService.cfc +++ b/src/cfml/system/services/ServerEngineService.cfc @@ -51,6 +51,12 @@ component accessors="true" singleton="true" { // set password to "commandbox" // TODO: Just make this changes directly in the WAR files fileWrite( installDetails.installDir & "/WEB-INF/cfusion/lib/password.properties", "rdspassword=#cr#password=commandbox#cr#encrypted=false" ); + // set flex log dir to prevent WEB-INF/cfform being created in project dir + if (fileExists(installDetails.installDir & "/WEB-INF/cfform/flex-config.xml")) { + var flexConfig = fileRead(installDetails.installDir & "/WEB-INF/cfform/flex-config.xml"); + flexConfig = replace(flexConfig, "/WEB-INF/", installDetails.installDir & "/WEB-INF","all"); + fileWrite(installDetails.installDir & "/WEB-INF/cfform/flex-config.xml", flexConfig); + } return installDetails; } From 0abeb4b6af8ad605bedfbddb515dc5eb258d8691 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 4 May 2016 09:35:20 -0500 Subject: [PATCH 070/129] Tons of Comments just for @lmajano ! --- .../commandbox/jgit/CommandCaller.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/java/com/ortussolutions/commandbox/jgit/CommandCaller.java b/src/java/com/ortussolutions/commandbox/jgit/CommandCaller.java index 17a5d28cd..bcaeb106a 100644 --- a/src/java/com/ortussolutions/commandbox/jgit/CommandCaller.java +++ b/src/java/com/ortussolutions/commandbox/jgit/CommandCaller.java @@ -5,7 +5,10 @@ ******************************************************************************** * @author Brad Wood, Luis Majano * -* I implement the SSH callback class for jGit to support SSH +* This class is a java wrapper to call JGit commands and trap the FULL exceptions +* that might be thrown to work around a Lucee bug that discards the "cause" of +* exceptions. Create an instance of this class to call a JGit command and if it +* throws an exception, if your CFML catch, use getException() to get the real error */ package com.ortussolutions.commandbox.jgit; @@ -16,6 +19,13 @@ public class CommandCaller { private Throwable exception; + /** + * Use this method to call a Jgit command for you and capture any exceptions that are thrown. + * + * @param command The Jgit object to call + * @return Whatever results that come back from the Jgit command's calling + * @throws Exception + */ public Object call( GitCommand command ) throws Exception { try { @@ -26,6 +36,11 @@ public Object call( GitCommand command ) throws Exception { } } + /** + * If an exception is thrown from the call() method, this will return the original Java exception + * Otherwise, this will return null. + * @return Original java exception from the Jgit command, if it errored. + */ public Throwable getException() { return this.exception; } From 57c852e456cefbd685e8723632faaf77e0966e84 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 4 May 2016 10:41:55 -0500 Subject: [PATCH 071/129] Oops, missed some --- .../com/ortussolutions/commandbox/jgit/CommandCaller.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/java/com/ortussolutions/commandbox/jgit/CommandCaller.java b/src/java/com/ortussolutions/commandbox/jgit/CommandCaller.java index bcaeb106a..ae2c5cc6e 100644 --- a/src/java/com/ortussolutions/commandbox/jgit/CommandCaller.java +++ b/src/java/com/ortussolutions/commandbox/jgit/CommandCaller.java @@ -29,10 +29,18 @@ public class CommandCaller { public Object call( GitCommand command ) throws Exception { try { + + // Try to run the command return command.call(); + + // if it errors } catch( Throwable e ) { + + // Store the exception this.exception = e; + // And rethrow. Lucee 4.x will strip off the cause. throw new Exception( "Error calling command.", e ); + } } From 565f9c4845630a0649411d3d7c7af4d30f78094f Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 4 May 2016 13:39:55 -0500 Subject: [PATCH 072/129] Resolve WAR path correctly --- .../system/modules/server-commands/commands/server/start.cfc | 1 + src/cfml/system/services/ServerService.cfc | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cfml/system/modules/server-commands/commands/server/start.cfc b/src/cfml/system/modules/server-commands/commands/server/start.cfc index f6a48e78e..3142f3bbf 100644 --- a/src/cfml/system/modules/server-commands/commands/server/start.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/start.cfc @@ -85,6 +85,7 @@ component aliases="start" { ){ // Resolve path as used locally arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); + arguments.WARPath = fileSystemUtil.resolvePath( arguments.WARPath ); // startup the server return serverService.start( serverProps = arguments ); diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index a633f4ce6..6cad7f43d 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -376,8 +376,9 @@ component accessors="true" singleton { & " --cfml-server-config ""#serverInfo.serverConfigDir#"" #serverInfo.runwarArgs# "; // Starting a WAR + systemOutput( serverinfo.WARPath, true ); if (serverInfo.WARPath != "" ) { - args &= " -war ""#serverInfo.webroot#"""; + args &= " -war ""#serverInfo.WARPath#"""; // Stand alone server } else if( !installDetails.internal ){ args &= " -war ""#serverInfo.webroot#"" --lib-dirs ""#installDetails.installDir#/WEB-INF/lib"" --web-xml-path ""#installDetails.installDir#/WEB-INF/web.xml"""; From 2c7679738746aac345f8f791a5defb6ba1cad463 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 4 May 2016 14:57:39 -0500 Subject: [PATCH 073/129] Null check --- .../system/modules/server-commands/commands/server/start.cfc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cfml/system/modules/server-commands/commands/server/start.cfc b/src/cfml/system/modules/server-commands/commands/server/start.cfc index 3142f3bbf..7ba148748 100644 --- a/src/cfml/system/modules/server-commands/commands/server/start.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/start.cfc @@ -85,7 +85,9 @@ component aliases="start" { ){ // Resolve path as used locally arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); - arguments.WARPath = fileSystemUtil.resolvePath( arguments.WARPath ); + if( !isNull( WARPath ) ) { + arguments.WARPath = fileSystemUtil.resolvePath( arguments.WARPath ); + } // startup the server return serverService.start( serverProps = arguments ); From 68fe8069aa45803368f65f04457944a6b98dd1ef Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 4 May 2016 14:57:47 -0500 Subject: [PATCH 074/129] Typo --- .../system/modules/server-commands/commands/server/status.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfml/system/modules/server-commands/commands/server/status.cfc b/src/cfml/system/modules/server-commands/commands/server/status.cfc index 1c7db7209..4d0afbf06 100644 --- a/src/cfml/system/modules/server-commands/commands/server/status.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/status.cfc @@ -86,7 +86,7 @@ component aliases='status' { || arguments.showAll ){ - // Null Checks, to guarnatee correct struct. + // Null Checks, to guarantee correct struct. structAppend( thisServerInfo, serverService.newServerInfoStruct(), false ); // Are we doing JSON? From 085304026e22da670e110e618a9b3f6718d15ae3 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 4 May 2016 14:58:04 -0500 Subject: [PATCH 075/129] Clean up engine name --- .../system/services/ServerEngineService.cfc | 3 ++- src/cfml/system/services/ServerService.cfc | 17 +++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/cfml/system/services/ServerEngineService.cfc b/src/cfml/system/services/ServerEngineService.cfc index 8a4cb8036..e52f470be 100644 --- a/src/cfml/system/services/ServerEngineService.cfc +++ b/src/cfml/system/services/ServerEngineService.cfc @@ -25,7 +25,7 @@ component accessors="true" singleton="true" { * @baseDirectory base directory for server install **/ public function install( required cfengine, required baseDirectory ) { - var version = find( "@", cfengine ) ? listLast( cfengine, "@" ) : ""; + var version = listLen( cfengine, "@" )>1 ? listLast( cfengine, "@" ) : ""; var engineName = listFirst(cfengine,"@"); arguments.baseDirectory = !arguments.baseDirectory.endsWith( "/" ) ? arguments.baseDirectory & "/" : arguments.baseDirectory; @@ -68,6 +68,7 @@ component accessors="true" singleton="true" { **/ public function installLucee( required destination, required version ) { var installDetails = installEngineArchive( 'lucee-cf-engine@#version#', destination ); + if( !installDetails.internal ) { configureWebXML( cfengine="lucee", source="#installDetails.installDir#/WEB-INF/web.xml", destination="#installDetails.installDir#/WEB-INF/web.xml" ); } return installDetails; diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 6cad7f43d..9fdf1a64c 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -151,7 +151,7 @@ component accessors="true" singleton { webXML : d.app.webXML ?: '', standalone : d.app.standalone ?: false, WARPath : d.app.WARPath ?: "", - cfengine : d.app.cfengine ?: "lucee" + cfengine : d.app.cfengine ?: "" }, runwar : { args : d.runwar.args ?: '' @@ -310,7 +310,15 @@ component accessors="true" singleton { serverInfo.WARPath = serverProps.WARPath ?: serverJSON.app.WARPath ?: defaults.app.WARPath; serverInfo.logdir = serverInfo.webConfigDir & "/logs"; - + + if( !len( serverInfo.WARPath ) && !len( serverInfo.cfengine ) ) { + serverInfo.cfengine = 'lucee@' & server.lucee.version; + } + + if( serverInfo.cfengine.endsWith( '@' ) ) { + serverInfo.cfengine = left( serverInfo.cfengine, len( serverInfo.cfengine ) - 1 ); + } + interceptorService.announceInterception( 'onServerStart', { serverInfo=serverInfo } ); var launchUtil = java.LaunchUtil; @@ -327,7 +335,8 @@ component accessors="true" singleton { // The process native name var processName = ( serverInfo.name is "" ? "CommandBox" : serverInfo.name ) & ' [' & serverinfo.cfengine & ']'; - var javaagent = serverinfo.cfengine == "lucee" ? "" : "-javaagent:""#libdir#/lucee-inst.jar"""; + var javaagent = serverinfo.cfengine contains 'lucee' ? '-javaagent:"#libdir#/lucee-inst.jar"' : ''; + var CFEngineName = serverinfo.cfengine contains 'lucee' ? 'lucee' : 'na'; if( serverInfo.WARPath == '' ){ try { var installDetails = serverEngineService.install( cfengine=serverInfo.cfengine, basedirectory=serverInfo.webConfigDir ); @@ -370,7 +379,7 @@ component accessors="true" singleton { & " --background=true --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 http://#serverInfo.host#:#serverInfo.port#" - & " --cfengine-name #serverInfo.cfengine# --server-name ""#serverInfo.name#""" + & " --cfengine-name ""#CFEngineName#"" --server-name ""#serverInfo.name#""" & " --tray-icon ""#serverInfo.trayIcon#"" --tray-config ""#trayConfigJSON#""" & " --directoryindex ""#serverInfo.directoryBrowsing#"" --cfml-web-config ""#serverInfo.webConfigDir#""" & " --cfml-server-config ""#serverInfo.serverConfigDir#"" #serverInfo.runwarArgs# "; From 408b19cdc511e1d1fdce48304c7e181f4facfce5 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 5 May 2016 11:45:48 -0500 Subject: [PATCH 076/129] Lot the error --- src/cfml/system/services/ServerService.cfc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 9fdf1a64c..7b4360ad0 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -40,7 +40,7 @@ component accessors="true" singleton { property name='configService' inject='ConfigService'; property name='JSONService' inject='JSONService'; property name='packageService' inject='packageService'; - property name='serverEngineService' inject='serverEngineService'; + property name='serverEngineService' inject='serverEngineService'; property name='consoleLogger' inject='logbox:logger:console'; property name='wirebox' inject='wirebox'; @@ -343,6 +343,7 @@ component accessors="true" singleton { serverInfo.logdir = installDetails.installDir & "/logs"; } catch (any e) { + logger.error( '#e.message# #e.detail#' , e.stackTrace ); consoleLogger.error("Error installing server - " & e.message); consoleLogger.error(e.detail.replaceAll(",","#chr(10)#")); return; From d52913a21d42a020025e44c66da12b47396d1509 Mon Sep 17 00:00:00 2001 From: Eric Peterson Date: Thu, 5 May 2016 15:24:24 -0600 Subject: [PATCH 077/129] Announce postVersion even if not tagging in Git --- .../modules/package-commands/commands/package/version.cfc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/cfml/system/modules/package-commands/commands/package/version.cfc b/src/cfml/system/modules/package-commands/commands/package/version.cfc index 25d7e5df5..8e546b05d 100644 --- a/src/cfml/system/modules/package-commands/commands/package/version.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/version.cfc @@ -156,12 +156,11 @@ component aliases="bump" { logger.error( 'Error tagging Git repository with new version.', e ); error( 'Error tagging Git repository with new version.', e.message & ' ' & e.detail ); } - - interceptorService.announceInterception( 'postVersion', { versionArgs=arguments } ); } - + + interceptorService.announceInterception( 'postVersion', { versionArgs=arguments } ); } -} \ No newline at end of file +} From 8fefba5a224578937e9245139df5ade8837d0d88 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Fri, 6 May 2016 14:01:07 -0500 Subject: [PATCH 078/129] Improved start docs --- .../server-commands/commands/server/start.cfc | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/cfml/system/modules/server-commands/commands/server/start.cfc b/src/cfml/system/modules/server-commands/commands/server/start.cfc index 7ba148748..9d06049ef 100644 --- a/src/cfml/system/modules/server-commands/commands/server/start.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/start.cfc @@ -15,6 +15,29 @@ * {code:bash} * server start heapSize=768 * {code} + * . + * The default CF engine is the version of Lucee Server that the CLI is running on. + * You can also start Adobe ColdFusion engines as well as Railo Server using the "cfengine" parameter. + * Specify an engine version after an @ sign like you would on package installation. + * . + * {code:bash} + * server start cfengine=railo + * server start cfengine=adobe + * server start cfengine=adobe@11.0 + * {code} + * . + * cfengine can also be any valid Endpoint ID that points to a ForgeBox entry, HTTP URL, etc. + * . + * {code:bash} + * server start cfengine=http://downloads.ortussolutions.com/adobe/coldfusion/9.0.2/cf-engine-9.0.2.zip + * {code} + * . + * You can also start up a local WAR file with the WARPath parmeter. + * . + * {code:bash} + * server start WARPath=/path/to/explodedWAR + * server start WARPath=/path/to/WARArchive.war + * {code} **/ component aliases="start" { From f631a442a62b795ae17d3f47e3c68e79e32edd5b Mon Sep 17 00:00:00 2001 From: denuno Date: Fri, 6 May 2016 17:15:30 -0600 Subject: [PATCH 079/129] bump runwar to pull in theoretical fixes for 3 or so outstanding issues --- build/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build.properties b/build/build.properties index a19f7ff3a..ee48b4b60 100644 --- a/build/build.properties +++ b/build/build.properties @@ -17,7 +17,7 @@ cfml.cli.version=${cfml.loader.version}.${cfml.version} lucee.version=4.5.2.018 jre.version=1.8.0_77 launch4j.version=3.4 -runwar.version=3.4.2 +runwar.version=3.4.3 #build locations build.type=localdev From 4dd1fe8a77e40597ed63d2d58ebb7361345d3da0 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Sat, 7 May 2016 21:59:24 -0500 Subject: [PATCH 080/129] Force loader version bump for new jars --- build/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build.properties b/build/build.properties index ee48b4b60..293312829 100644 --- a/build/build.properties +++ b/build/build.properties @@ -12,7 +12,7 @@ java.pack200=false #dependencies dependencies.dir=${basedir}/lib cfml.version=4.5.2.018 -cfml.loader.version=1.2.0 +cfml.loader.version=1.3.0 cfml.cli.version=${cfml.loader.version}.${cfml.version} lucee.version=4.5.2.018 jre.version=1.8.0_77 From 394f11ade53f40393b53c231399c55e904f0ceb7 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Sun, 8 May 2016 18:42:58 -0500 Subject: [PATCH 081/129] COMMANDBOX-380 Allow input masking --- src/cfml/system/BaseCommand.cfc | 5 +++-- src/cfml/system/Shell.cfc | 19 +++++++++---------- src/cfml/system/services/CommandService.cfc | 3 ++- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/cfml/system/BaseCommand.cfc b/src/cfml/system/BaseCommand.cfc index 4e0963c22..a9609ac7f 100644 --- a/src/cfml/system/BaseCommand.cfc +++ b/src/cfml/system/BaseCommand.cfc @@ -67,10 +67,11 @@ component accessors="true" singleton { /** * Ask the user a question and wait for response * @message.hint message to prompt the user with + * @mask.hint When not empty, keyboard input is masked as that character **/ - function ask( required message ) { + function ask( required message, string mask='' ) { print.toConsole(); - return shell.ask( arguments.message ); + return shell.ask( arguments.message, arguments.mask ); } /** diff --git a/src/cfml/system/Shell.cfc b/src/cfml/system/Shell.cfc index 1b61c83c9..c30ed1f42 100644 --- a/src/cfml/system/Shell.cfc +++ b/src/cfml/system/Shell.cfc @@ -190,12 +190,18 @@ component accessors="true" singleton { /** * ask the user a question and wait for response * @message.hint message to prompt the user with + * @mask.hint When not empty, keyboard input is masked as that character * * @return the response from the user **/ - string function ask( message ) { - // read reponse - var input = variables.reader.readLine( arguments.message ); + string function ask( message, string mask='' ) { + if( len( arguments.mask ) ) { + // read reponse while masking input + var input = variables.reader.readLine( arguments.message, javacast( "char", left( arguments.mask, 1 ) ) ); + } else { + // read reponse + var input = variables.reader.readLine( arguments.message ); + } // Reset back to default prompt setPrompt(); @@ -357,8 +363,6 @@ component accessors="true" singleton { * @input.hint command line to run if running externally **/ Boolean function run( input="", silent=false ) { - var mask = "*"; - var trigger = "su"; // init reload to false, just in case variables.reloadshell = false; @@ -401,11 +405,6 @@ component accessors="true" singleton { return false; } - // If we input the special word then we will mask the next line. - if( ( !isNull( trigger ) ) && ( line.compareTo( trigger ) == 0 ) ){ - line = variables.reader.readLine( "password> ", javacast( "char", mask ) ); - } - // If there's input, try to run it. if( len( trim( line ) ) ) { callCommand( command=line, initialCommand=true ); diff --git a/src/cfml/system/services/CommandService.cfc b/src/cfml/system/services/CommandService.cfc index c13f9ad68..f7d486483 100644 --- a/src/cfml/system/services/CommandService.cfc +++ b/src/cfml/system/services/CommandService.cfc @@ -708,7 +708,8 @@ component accessors="true" singleton { } // Strings else { - return shell.ask( message ); + // If the param name contains the word "password", then mask the input. + return shell.ask( message, ( param.name contains 'password' ? '*' : '' ) ); } }; From 57ee52b529c2309b79629aec6c3952243f5c6ae2 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Sun, 8 May 2016 23:12:40 -0500 Subject: [PATCH 082/129] Bump JLine version --- build/build.properties | 2 +- build/build.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/build.properties b/build/build.properties index 293312829..0b561fa29 100644 --- a/build/build.properties +++ b/build/build.properties @@ -12,7 +12,7 @@ java.pack200=false #dependencies dependencies.dir=${basedir}/lib cfml.version=4.5.2.018 -cfml.loader.version=1.3.0 +cfml.loader.version=1.3.1 cfml.cli.version=${cfml.loader.version}.${cfml.version} lucee.version=4.5.2.018 jre.version=1.8.0_77 diff --git a/build/build.xml b/build/build.xml index 1bc57c276..e995dc6d2 100644 --- a/build/build.xml +++ b/build/build.xml @@ -702,7 +702,7 @@ External Dependencies: --> - + From 7332e7872a1e4329cc70f7295caf63025df70994 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 9 May 2016 00:10:36 -0500 Subject: [PATCH 083/129] Fix reqression in JLine with print --- src/cfml/system/Shell.cfc | 40 +++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/cfml/system/Shell.cfc b/src/cfml/system/Shell.cfc index c30ed1f42..15fc2afc9 100644 --- a/src/cfml/system/Shell.cfc +++ b/src/cfml/system/Shell.cfc @@ -194,14 +194,18 @@ component accessors="true" singleton { * * @return the response from the user **/ - string function ask( message, string mask='' ) { - if( len( arguments.mask ) ) { - // read reponse while masking input - var input = variables.reader.readLine( arguments.message, javacast( "char", left( arguments.mask, 1 ) ) ); - } else { - // read reponse - var input = variables.reader.readLine( arguments.message ); - } + string function ask( message, string mask='', string buffer='' ) { + + // read reponse while masking input + var input = variables.reader.readLine( + // Prompt for the user + arguments.message, + // Optionally mask their input + len( arguments.mask ) ? javacast( "char", left( arguments.mask, 1 ) ) : javacast( "null", '' ), + // Optionally pre-fill a default response for them + len( arguments.buffer ) ? javacast( "String", arguments.buffer ) : javacast( "null", '' ) + ); + // Reset back to default prompt setPrompt(); @@ -260,8 +264,8 @@ component accessors="true" singleton { } } - variables.reader.print( '' ); - variables.reader.print( '' ); + variables.reader.getOutput().write( '' ); + variables.reader.getOutput().write( '' ); return this; } @@ -352,7 +356,7 @@ component accessors="true" singleton { writedump(var=arguments.string, output="console"); arguments.string = ""; } - variables.reader.print( arguments.string ); + variables.reader.getOutput().write( arguments.string ); variables.reader.flush(); return this; @@ -515,13 +519,13 @@ component accessors="true" singleton { variables.logger.error( '#arguments.err.message# #arguments.err.detail ?: ''#', arguments.err.stackTrace ?: '' ); - variables.reader.print( variables.print.whiteOnRedLine( 'ERROR' ) ); + variables.reader.getOutput().write( variables.print.whiteOnRedLine( 'ERROR' ) ); variables.reader.println(); - variables.reader.print( variables.print.boldRedText( variables.formatterUtil.HTML2ANSI( arguments.err.message ) ) ); + variables.reader.getOutput().write( variables.print.boldRedText( variables.formatterUtil.HTML2ANSI( arguments.err.message ) ) ); variables.reader.println(); if( structKeyExists( arguments.err, 'detail' ) ) { - variables.reader.print( variables.print.boldRedText( variables.formatterUtil.HTML2ANSI( arguments.err.detail ) ) ); + variables.reader.getOutput().write( variables.print.boldRedText( variables.formatterUtil.HTML2ANSI( arguments.err.detail ) ) ); variables.reader.println(); } if( structKeyExists( arguments.err, 'tagcontext' ) ){ @@ -531,16 +535,16 @@ component accessors="true" singleton { var tc = arguments.err.tagcontext[ idx ]; if( len( tc.codeprinthtml ) ){ if( idx > 1 ) { - variables.reader.print( print.boldCyanText( "called from " ) ); + variables.reader.getOutput().write( 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 ) ) ); + variables.reader.getOutput().write( variables.print.boldCyanText( "#tc.template#: line #tc.line##variables.cr#" )); + variables.reader.getOutput().write( variables.print.text( variables.formatterUtil.HTML2ANSI( tc.codeprinthtml ) ) ); } } } } if( structKeyExists( arguments.err, 'stacktrace' ) ) { - variables.reader.print( arguments.err.stacktrace ); + variables.reader.getOutput().write( arguments.err.stacktrace ); } variables.reader.println(); From e80fd2f3486ca11aed73d8ab4e766e8895f3e09d Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 9 May 2016 19:25:31 -0500 Subject: [PATCH 084/129] Fix for correct CFEngine value --- src/cfml/system/services/ServerService.cfc | 51 ++++++++++++++-------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 7b4360ad0..977ad1da0 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -335,31 +335,44 @@ component accessors="true" singleton { // The process native name var processName = ( serverInfo.name is "" ? "CommandBox" : serverInfo.name ) & ' [' & serverinfo.cfengine & ']'; + + // Default java agent for embedded Lucee engine var javaagent = serverinfo.cfengine contains 'lucee' ? '-javaagent:"#libdir#/lucee-inst.jar"' : ''; - var CFEngineName = serverinfo.cfengine contains 'lucee' ? 'lucee' : 'na'; - if( serverInfo.WARPath == '' ){ - try { - var installDetails = serverEngineService.install( cfengine=serverInfo.cfengine, basedirectory=serverInfo.webConfigDir ); - serverInfo.logdir = installDetails.installDir & "/logs"; - - } catch (any e) { - logger.error( '#e.message# #e.detail#' , e.stackTrace ); - consoleLogger.error("Error installing server - " & e.message); - consoleLogger.error(e.detail.replaceAll(",","#chr(10)#")); - return; - } - if( !installDetails.internal && serverInfo.cfengine contains "lucee" ) { - javaagent = "-javaagent:""#installDetails.installDir#/WEB-INF/lib/lucee-inst.jar"""; - } - if( !installDetails.internal && serverInfo.cfengine contains "railo" ) { - javaagent = "-javaagent:""#installDetails.installDir#/WEB-INF/lib/railo-inst.jar"""; - } + + // Not sure what Runwar does with this, but it wants to know what CFEngine we're starting (if we know) + var CFEngineName = 'lucee'; + CFEngineName = serverinfo.cfengine contains 'lucee' ? 'lucee' : CFEngineName; + CFEngineName = serverinfo.cfengine contains 'railo' ? 'railo' : CFEngineName; + CFEngineName = serverinfo.cfengine contains 'adobe' ? 'adobe' : CFEngineName; + + // As long as there's no WAR Path, let's install the engine to use. + if( serverInfo.WARPath == '' ){ + try { + // This will install the engine war to start, possibly downloading it first + var installDetails = serverEngineService.install( cfengine=serverInfo.cfengine, basedirectory=serverInfo.webConfigDir ); + serverInfo.logdir = installDetails.installDir & "/logs"; + + // Not sure we need this ultimatley, but errors were really ugly when getting this up and running. + } catch (any e) { + logger.error( '#e.message# #e.detail#' , e.stackTrace ); + consoleLogger.error("Error installing server - " & e.message); + consoleLogger.error(e.detail.replaceAll(",","#chr(10)#")); + return; + } + // If external Lucee server, set the java agent + if( !installDetails.internal && serverInfo.cfengine contains "lucee" ) { + javaagent = "-javaagent:""#installDetails.installDir#/WEB-INF/lib/lucee-inst.jar"""; + } + // If external Railo server, set the java agent + if( !installDetails.internal && serverInfo.cfengine contains "railo" ) { + javaagent = "-javaagent:""#installDetails.installDir#/WEB-INF/lib/railo-inst.jar"""; + } // Using built in server that hasn't been started before if( installDetails.internal && !directoryExists( serverInfo.webConfigDir & '/WEB-INF' ) ) { serverInfo.webConfigDir = installDetails.installDir; serverInfo.logdir = serverInfo.webConfigDir & "/logs"; } - } + } // This is due to a bug in RunWar not creating the right directory for the logs directoryCreate( serverInfo.logDir, true, true ); From 1d0c4fb01beb5ff8a1a5c83734c4b85821e674c1 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 9 May 2016 21:23:01 -0500 Subject: [PATCH 085/129] Don't pass cfengine to Runwar if we don't know it --- src/cfml/system/services/ServerService.cfc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 977ad1da0..10f40691c 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -340,7 +340,7 @@ component accessors="true" singleton { var javaagent = serverinfo.cfengine contains 'lucee' ? '-javaagent:"#libdir#/lucee-inst.jar"' : ''; // Not sure what Runwar does with this, but it wants to know what CFEngine we're starting (if we know) - var CFEngineName = 'lucee'; + var CFEngineName = ''; CFEngineName = serverinfo.cfengine contains 'lucee' ? 'lucee' : CFEngineName; CFEngineName = serverinfo.cfengine contains 'railo' ? 'railo' : CFEngineName; CFEngineName = serverinfo.cfengine contains 'adobe' ? 'adobe' : CFEngineName; @@ -393,7 +393,8 @@ component accessors="true" singleton { & " --background=true --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 http://#serverInfo.host#:#serverInfo.port#" - & " --cfengine-name ""#CFEngineName#"" --server-name ""#serverInfo.name#""" + & ( len( CFEngineName ) ? " --cfengine-name ""#CFEngineName#""" : "" ) + & " --server-name ""#serverInfo.name#""" & " --tray-icon ""#serverInfo.trayIcon#"" --tray-config ""#trayConfigJSON#""" & " --directoryindex ""#serverInfo.directoryBrowsing#"" --cfml-web-config ""#serverInfo.webConfigDir#""" & " --cfml-server-config ""#serverInfo.serverConfigDir#"" #serverInfo.runwarArgs# "; From 1989e3764aff0c790f50d00da194dcc8dcf3688c Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 10 May 2016 16:55:24 -0500 Subject: [PATCH 086/129] COMMANDBOX-293 --- build/build.properties | 2 +- src/cfml/Application.cfc | 2 ++ src/cfml/system/BaseCommand.cfc | 8 ++++++++ src/cfml/system/Shell.cfc | 12 ++++++++++-- .../testbox-commands/commands/testbox/run.cfc | 1 + src/cfml/system/services/CommandService.cfc | 3 +++ src/java/cliloader/LoaderCLIMain.java | 7 +++++++ src/resources/error-cli.cfm | 1 + 8 files changed, 33 insertions(+), 3 deletions(-) diff --git a/build/build.properties b/build/build.properties index 0b561fa29..097a66290 100644 --- a/build/build.properties +++ b/build/build.properties @@ -12,7 +12,7 @@ java.pack200=false #dependencies dependencies.dir=${basedir}/lib cfml.version=4.5.2.018 -cfml.loader.version=1.3.1 +cfml.loader.version=1.3.2 cfml.cli.version=${cfml.loader.version}.${cfml.version} lucee.version=4.5.2.018 jre.version=1.8.0_77 diff --git a/src/cfml/Application.cfc b/src/cfml/Application.cfc index 6af90b6a1..02356f202 100644 --- a/src/cfml/Application.cfc +++ b/src/cfml/Application.cfc @@ -31,6 +31,8 @@ component{ function onError( any exception, string eventName ) { + createObject( 'java', 'java.lang.System' ).setProperty( 'cfml.cli.exitCode', '1' ); + // Try to log this to LogBox try { application.wireBox.getLogBox().getRootLogger().error( '#exception.message# #exception.detail ?: ''#', exception.stackTrace ); diff --git a/src/cfml/system/BaseCommand.cfc b/src/cfml/system/BaseCommand.cfc index a9609ac7f..7e8953622 100644 --- a/src/cfml/system/BaseCommand.cfc +++ b/src/cfml/system/BaseCommand.cfc @@ -123,6 +123,7 @@ component accessors="true" singleton { * @clearPrintBuffer.hint Wipe out the print buffer or not, it does not by default **/ function error( required message, detail='', clearPrintBuffer=false ) { + setExitCode( 1 ); hasErrored = true; if( arguments.clearPrintBuffer ) { // Wipe @@ -142,6 +143,13 @@ component accessors="true" singleton { return hasErrored; } + /** + * Sets the OS exit code + **/ + function setExitCode( required string exitCode ) { + return shell.setExitCode( arguments.exitCode ); + } + /** * This will open a file or folder externally in the default editor for the user. * Useful for opening a new file for editing that was just created. diff --git a/src/cfml/system/Shell.cfc b/src/cfml/system/Shell.cfc index 15fc2afc9..d9dfd4b21 100644 --- a/src/cfml/system/Shell.cfc +++ b/src/cfml/system/Shell.cfc @@ -141,8 +141,6 @@ component accessors="true" singleton { } - - /** * Exists the shell **/ @@ -152,6 +150,14 @@ component accessors="true" singleton { return this; } + /** + * Set's the OS Exit code to be used + **/ + Shell function setExitCode( required string exitCode ) { + createObject( 'java', 'java.lang.System' ).setProperty( 'cfml.cli.exitCode', arguments.exitCode ); + return this; + } + /** * Sets reload flag, relaoded from shell.cfm @@ -514,6 +520,8 @@ component accessors="true" singleton { **/ Shell function printError( required err ){ + setExitCode( 1 ); + getInterceptorService().announceInterception( 'onException', { exception=err } ); variables.logger.error( '#arguments.err.message# #arguments.err.detail ?: ''#', arguments.err.stackTrace ?: '' ); diff --git a/src/cfml/system/modules/testbox-commands/commands/testbox/run.cfc b/src/cfml/system/modules/testbox-commands/commands/testbox/run.cfc index bd3b75a4a..c80f30431 100644 --- a/src/cfml/system/modules/testbox-commands/commands/testbox/run.cfc +++ b/src/cfml/system/modules/testbox-commands/commands/testbox/run.cfc @@ -112,6 +112,7 @@ component { print.yellow( " " & results.filecontent ); } else if( results.responseheader[ "x-testbox-totalError" ] gt 0 ){ // print Failure report + setExitCode( 1 ); print.boldRed( " " & results.filecontent ); } diff --git a/src/cfml/system/services/CommandService.cfc b/src/cfml/system/services/CommandService.cfc index f7d486483..59647169b 100644 --- a/src/cfml/system/services/CommandService.cfc +++ b/src/cfml/system/services/CommandService.cfc @@ -270,6 +270,9 @@ component accessors="true" singleton { // Now, where were we? rethrow; } + + // Successful command execution resets exit code to 0 + shell.setExitCode( 0 ); // Remove it from the stack instance.callStack.deleteAt( 1 ); diff --git a/src/java/cliloader/LoaderCLIMain.java b/src/java/cliloader/LoaderCLIMain.java index 37192c8eb..9431ae00c 100644 --- a/src/java/cliloader/LoaderCLIMain.java +++ b/src/java/cliloader/LoaderCLIMain.java @@ -212,6 +212,13 @@ && new File( cliArguments.get( 0 ) ).isFile() ) { e.getCause().printStackTrace(); } } + + + if( debug ) { + System.out.println( "cfml.cli.exitCode: " + Integer.parseInt( System.getProperty("cfml.cli.exitCode","0") ) ); + } + exitCode = Integer.parseInt( System.getProperty("cfml.cli.exitCode","0") ); + cl.close(); System.out.flush(); System.setOut( originalOut ); diff --git a/src/resources/error-cli.cfm b/src/resources/error-cli.cfm index a9c117814..8cbf77c34 100644 --- a/src/resources/error-cli.cfm +++ b/src/resources/error-cli.cfm @@ -1,3 +1,4 @@ + From 0dda0bad71df58d1b72b0e764be5113e6586c663 Mon Sep 17 00:00:00 2001 From: denuno Date: Tue, 10 May 2016 16:35:28 -0600 Subject: [PATCH 087/129] bump runwar version to test fixes --- build/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build.properties b/build/build.properties index 097a66290..67c3094b1 100644 --- a/build/build.properties +++ b/build/build.properties @@ -17,7 +17,7 @@ cfml.cli.version=${cfml.loader.version}.${cfml.version} lucee.version=4.5.2.018 jre.version=1.8.0_77 launch4j.version=3.4 -runwar.version=3.4.3 +runwar.version=3.4.4 #build locations build.type=localdev From dadc34cc7c89f4fe81825875145411cd2e04e1a2 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 11 May 2016 16:45:13 -0500 Subject: [PATCH 088/129] Open correct URL --- src/cfml/system/services/ServerService.cfc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 10f40691c..b32f898ee 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -392,7 +392,8 @@ component accessors="true" singleton { & " #javaagent# -jar ""#variables.jarPath#""" & " --background=true --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 http://#serverInfo.host#:#serverInfo.port#" + & " --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#""" & " --tray-icon ""#serverInfo.trayIcon#"" --tray-config ""#trayConfigJSON#""" From 96d326fa9c7fb7cd519ba8e956c56d84c5e675ce Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 11 May 2016 21:22:54 -0500 Subject: [PATCH 089/129] Rolling back Jline, too many bugs --- build/build.properties | 2 +- build/build.xml | 2 +- src/cfml/system/Shell.cfc | 20 ++++++++++---------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/build/build.properties b/build/build.properties index 67c3094b1..b366deb03 100644 --- a/build/build.properties +++ b/build/build.properties @@ -12,7 +12,7 @@ java.pack200=false #dependencies dependencies.dir=${basedir}/lib cfml.version=4.5.2.018 -cfml.loader.version=1.3.2 +cfml.loader.version=1.3.3 cfml.cli.version=${cfml.loader.version}.${cfml.version} lucee.version=4.5.2.018 jre.version=1.8.0_77 diff --git a/build/build.xml b/build/build.xml index e995dc6d2..f5ba1f014 100644 --- a/build/build.xml +++ b/build/build.xml @@ -702,7 +702,7 @@ External Dependencies: --> - + diff --git a/src/cfml/system/Shell.cfc b/src/cfml/system/Shell.cfc index d9dfd4b21..7d7304da9 100644 --- a/src/cfml/system/Shell.cfc +++ b/src/cfml/system/Shell.cfc @@ -270,8 +270,8 @@ component accessors="true" singleton { } } - variables.reader.getOutput().write( '' ); - variables.reader.getOutput().write( '' ); + variables.reader.print( '' ); + variables.reader.print( '' ); return this; } @@ -362,7 +362,7 @@ component accessors="true" singleton { writedump(var=arguments.string, output="console"); arguments.string = ""; } - variables.reader.getOutput().write( arguments.string ); + variables.reader.print( arguments.string ); variables.reader.flush(); return this; @@ -527,13 +527,13 @@ component accessors="true" singleton { variables.logger.error( '#arguments.err.message# #arguments.err.detail ?: ''#', arguments.err.stackTrace ?: '' ); - variables.reader.getOutput().write( variables.print.whiteOnRedLine( 'ERROR' ) ); + variables.reader.print( variables.print.whiteOnRedLine( 'ERROR' ) ); variables.reader.println(); - variables.reader.getOutput().write( variables.print.boldRedText( variables.formatterUtil.HTML2ANSI( arguments.err.message ) ) ); + variables.reader.print( variables.print.boldRedText( variables.formatterUtil.HTML2ANSI( arguments.err.message ) ) ); variables.reader.println(); if( structKeyExists( arguments.err, 'detail' ) ) { - variables.reader.getOutput().write( variables.print.boldRedText( variables.formatterUtil.HTML2ANSI( arguments.err.detail ) ) ); + variables.reader.print( variables.print.boldRedText( variables.formatterUtil.HTML2ANSI( arguments.err.detail ) ) ); variables.reader.println(); } if( structKeyExists( arguments.err, 'tagcontext' ) ){ @@ -543,16 +543,16 @@ component accessors="true" singleton { var tc = arguments.err.tagcontext[ idx ]; if( len( tc.codeprinthtml ) ){ if( idx > 1 ) { - variables.reader.getOutput().write( print.boldCyanText( "called from " ) ); + variables.reader.print( print.boldCyanText( "called from " ) ); } - variables.reader.getOutput().write( variables.print.boldCyanText( "#tc.template#: line #tc.line##variables.cr#" )); - variables.reader.getOutput().write( variables.print.text( variables.formatterUtil.HTML2ANSI( tc.codeprinthtml ) ) ); + variables.reader.print( variables.print.boldCyanText( "#tc.template#: line #tc.line##variables.cr#" )); + variables.reader.print( variables.print.text( variables.formatterUtil.HTML2ANSI( tc.codeprinthtml ) ) ); } } } } if( structKeyExists( arguments.err, 'stacktrace' ) ) { - variables.reader.getOutput().write( arguments.err.stacktrace ); + variables.reader.print( arguments.err.stacktrace ); } variables.reader.println(); From 5ef9a71873be209f9e3e4851422424e7f3b36e8d Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 11 May 2016 21:24:51 -0500 Subject: [PATCH 090/129] Latest runwar goodness --- build/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build.properties b/build/build.properties index b366deb03..f5e479b87 100644 --- a/build/build.properties +++ b/build/build.properties @@ -17,7 +17,7 @@ cfml.cli.version=${cfml.loader.version}.${cfml.version} lucee.version=4.5.2.018 jre.version=1.8.0_77 launch4j.version=3.4 -runwar.version=3.4.4 +runwar.version=3.4.5 #build locations build.type=localdev From 611b70a139bd87b0d4c2433b01facb737baaad63 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 11 May 2016 22:38:23 -0500 Subject: [PATCH 091/129] COMMANDBOX-355 --- .../commands/coldbox/create/app.cfc | 90 +++++++++---------- src/cfml/system/services/CommandService.cfc | 2 +- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/app.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/app.cfc index 0ea8bbf12..a5430a6b6 100644 --- a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/app.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/app.cfc @@ -1,25 +1,26 @@ /** * Create a blank ColdBox app from one of our app skeletons. By default it will create -* in your current directory. Use the "pwd" command to find out what directory you're currently in. +* in your current directory. * . -* You can choose what app skeleton to use as well as override the directory it's created in. -* The built-in app skeletons are located in the .CommandBox/cfml/skeletons/ directory and include: -* . -* By default, ColdBox 4.x compatible templates will be used +* {code:bash} +* coldbox create app myApp +* {code} +* . +* Here are the basic skeltons that are available for you. * - Advanced * - AdvancedScript (default) * - rest * - Simple * - SuperSimple -* . -* These templates are compatible with the previous version of ColdBox (3.x) -* - Advancedv3 -* - AdvancedScriptv3 -* - Simplev3 -* - SuperSimplev3 * . * {code:bash} -* coldbox create app myApp +* coldbox create app skeleton=rest +* {code} +* . +* The skeleton parameter can also be any valid Endpoint ID, which includes a Git repo or HTTP URL pointing to a package. +* . +* {code:bash} +* coldbox create app skeleton=http://site.com/myCustomAppTemplate.zip * {code} * . * Use the "installColdBox" parameter to install the latest stable version of ColdBox from ForgeBox @@ -34,21 +35,24 @@ * **/ component { - - /** - * The location of our skeletons - */ - property name="skeletonLocation"; // DI property name="packageService" inject="PackageService"; - property name='parser' inject='Parser'; /** * Constructor */ function init(){ - variables.skeletonLocation = expandPath( '/coldbox-commands/skeletons/' ); + + // Map these shortcut names to the actual ForgeBox slugs + variables.templateMap = { + Advanced = 'cbtemplate-advanced', + AdvancedScript = 'cbtemplate-advanced-script', + rest = 'cbtemplate-rest', + Simple = 'cbtemplate-simple', + SuperSimple = 'cbtemplate-supersimple' + }; + return this; } @@ -84,29 +88,27 @@ component { // This will make the directory canonical and absolute arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); - - // get the right skeleton - var skeletonZip = skeletonLocation & arguments.skeleton & '.zip'; // Validate directory, if it doesn't exist, create it. if( !directoryExists( arguments.directory ) ) { directoryCreate( arguments.directory ); } - - // Validate skeleton - if( !fileExists( skeletonZip ) ) { - var options = directoryList( path=skeletonLocation, listInfo='name', sort="name" ); - return error( "The app skeleton [#skeletonZip#] doesn't exist. Valid options are #replaceNoCase( arrayToList( options, ', ' ), '.zip', '', 'all' )#" ); + + // If the skeleton is one of our "shortcut" names + if( variables.templateMap.keyExists( arguments.skeleton ) ) { + // Replace it with the actual ForgeBox slug name. + arguments.skeleton = variables.templateMap[ arguments.skeleton ]; } - - // Unzip the skeleton! - zip - action="unzip" - destination="#arguments.directory#" - file="#skeletonZip#"; - - print.line() - .greenLine( '#skeleton# Application successfully created in [#arguments.directory#]' ); + + // Install the skeleton + packageService.installPackage( + ID = arguments.skeleton, + directory = arguments.directory, + save = false, + saveDev = false, + production = true, + currentWorkingDirectory = arguments.directory + ); // Check for the @appname@ in .project files if( fileExists( "#arguments.directory#/.project" ) ){ @@ -120,11 +122,12 @@ component { var originalPath = getCWD(); // init must be run from CWD shell.cd( arguments.directory ); - runCommand( 'init - name="#parser.escapeArg( arguments.name )#" - slug="#parser.escapeArg( replace( arguments.name, ' ', '', 'all' ) )#" - wizard=#arguments.initWizard#' - ); + command( 'init' ) + .params( + name=arguments.name, + slug=replace( arguments.name, ' ', '', 'all' ), + wizard=arguments.initWizard ) + .run(); shell.cd( originalPath ); } @@ -166,10 +169,7 @@ component { * Returns an array of coldbox skeletons available */ function skeletonComplete( ) { - var skeletons = directoryList( path=expandPath("../skeletons"), listInfo="name", filter="*.zip" ); - return skeletons.map( function( required string skeleton ) { - return skeleton.reReplaceNoCase( "\.zip$", "", "once" ); - } ); + return variables.templateMap.keyList().listToArray(); } } \ No newline at end of file diff --git a/src/cfml/system/services/CommandService.cfc b/src/cfml/system/services/CommandService.cfc index 59647169b..93cfb6b9f 100644 --- a/src/cfml/system/services/CommandService.cfc +++ b/src/cfml/system/services/CommandService.cfc @@ -524,7 +524,7 @@ component accessors="true" singleton { } catch( any e ){ // Log the full exception with stack trace logger.error( 'Error creating command [#commandData.fullCFCPath#]. #e.message# #e.detail ?: ''#', e.stackTrace ); - throw( message='Error creating command [#commandData.fullCFCPath#]', detail="#e.message# #CR# #e.detail ?: ''#", type="commandException"); + throw( message='Error creating command [#commandData.fullCFCPath#]', detail="#e.message# #CR# #e.detail ?: ''# #CR# #e.stacktrace#", type="commandException"); } } // CFC exists check return true; From ea03e64771b21b6f107159e3a150e1241d65d433 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 12 May 2016 16:49:39 -0500 Subject: [PATCH 092/129] COMMANDBOX-341 --- .../package-commands/commands/package/install.cfc | 2 +- src/cfml/system/services/PackageService.cfc | 14 +++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/cfml/system/modules/package-commands/commands/package/install.cfc b/src/cfml/system/modules/package-commands/commands/package/install.cfc index 77d38c28e..f8a850a8e 100644 --- a/src/cfml/system/modules/package-commands/commands/package/install.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/install.cfc @@ -110,7 +110,7 @@ component aliases="install" { string directory, boolean save=true, boolean saveDev=false, - boolean production=false, + boolean production, boolean verbose=false, boolean force=false ){ diff --git a/src/cfml/system/services/PackageService.cfc b/src/cfml/system/services/PackageService.cfc index d3ef58377..eebc3bee0 100644 --- a/src/cfml/system/services/PackageService.cfc +++ b/src/cfml/system/services/PackageService.cfc @@ -67,7 +67,7 @@ component accessors="true" singleton { string directory, boolean save=false, boolean saveDev=false, - boolean production=false, + boolean production, string currentWorkingDirectory=shell.pwd(), boolean verbose=false, boolean force=false, @@ -79,6 +79,9 @@ component accessors="true" singleton { // If there is a package to install, install it if( len( arguments.ID ) ) { + // By default, a specific package install doesn't include dev dependencies + arguments.production = arguments.production ?: true; + // Verbose info if( arguments.verbose ){ consoleLogger.debug( "Save:#arguments.save# SaveDev:#arguments.saveDev# Production:#arguments.production# Directory:#arguments.directory#" ); @@ -284,7 +287,7 @@ component accessors="true" singleton { ignorePatterns.append( '/box.json' ); } } - + // I give up, just stick it in the CWD if( !len( installDirectory ) ) { installDirectory = arguments.currentWorkingDirectory; @@ -401,6 +404,10 @@ component accessors="true" singleton { // read it... var artifactDescriptor = readPackageDescriptor( arguments.currentWorkingDirectory ); var installDirectory = arguments.currentWorkingDirectory; + + // By default, a general package install includes dev dependencies + arguments.production = arguments.production ?: false; + } // and grab all the dependencies @@ -433,7 +440,8 @@ component accessors="true" singleton { // Nested dependencies are already in the box.json, but the save will update the installPaths save = ( isSaving && !isDev ), saveDev = ( isSaving && isDev ), - production = arguments.production, + // Nested packages never get dev dependencies + production = true, currentWorkingDirectory = arguments.currentWorkingDirectory, // Original dir packagePathRequestingInstallation = installDirectory // directory for smart dependencies to use }; From 5c2ae8759a63e2946f7b6872230649e3e8761473 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 12 May 2016 17:41:52 -0500 Subject: [PATCH 093/129] This won't work until we can stay on Jline 2.14 --- src/cfml/system/Shell.cfc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cfml/system/Shell.cfc b/src/cfml/system/Shell.cfc index 7d7304da9..352bc9a6c 100644 --- a/src/cfml/system/Shell.cfc +++ b/src/cfml/system/Shell.cfc @@ -207,9 +207,10 @@ component accessors="true" singleton { // Prompt for the user arguments.message, // Optionally mask their input - len( arguments.mask ) ? javacast( "char", left( arguments.mask, 1 ) ) : javacast( "null", '' ), + len( arguments.mask ) ? javacast( "char", left( arguments.mask, 1 ) ) : javacast( "null", '' )//, + // This won't work until we can upgrade to Jline 2.14 // Optionally pre-fill a default response for them - len( arguments.buffer ) ? javacast( "String", arguments.buffer ) : javacast( "null", '' ) + // len( arguments.buffer ) ? javacast( "String", arguments.buffer ) : javacast( "null", '' ) ); // Reset back to default prompt From 92c8b952756daed1aa2cc075557abe4f4a5914fb Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 12 May 2016 22:34:50 -0500 Subject: [PATCH 094/129] COMMANDBOX-348 --- src/cfml/system/services/PackageService.cfc | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/cfml/system/services/PackageService.cfc b/src/cfml/system/services/PackageService.cfc index eebc3bee0..e1caa31dd 100644 --- a/src/cfml/system/services/PackageService.cfc +++ b/src/cfml/system/services/PackageService.cfc @@ -868,6 +868,15 @@ component accessors="true" singleton { // Only check slugs we're supposed to if( !len( includeSlugs ) || listFindNoCase( includeSlugs, arguments.slug ) ) { + // 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.." ) + .toConsole(); + } + return; + } + // Contains an enpoint if( value.version contains ':' ) { var ID = value.version; @@ -935,7 +944,8 @@ component accessors="true" singleton { 'slug' : boxJSON.slug, 'shortDescription' : boxJSON.shortDescription, 'version': boxJSON.version, - 'packageVersion': boxJSON.version + 'packageVersion': boxJSON.version, + 'isInstalled': true }; buildChildren( boxJSON, tree, arguments.directory); return tree; @@ -955,7 +965,8 @@ component accessors="true" singleton { 'dev' : arguments.dev, 'name' : '', 'shortDescription' : '', - 'packageVersion' : '' + 'packageVersion' : '', + 'isInstalled': false }; if( structKeyExists( arguments.installPaths, dependency ) ) { @@ -965,6 +976,7 @@ component accessors="true" singleton { thisDeps[ dependency ][ 'name' ] = boxJSON.name; thisDeps[ dependency ][ 'shortDescription' ] = boxJSON.shortDescription; thisDeps[ dependency ][ 'packageVersion' ] = boxJSON.version; + thisDeps[ dependency ][ 'isInstalled' ] = true; // Down the rabbit hole buildChildren( boxJSON, thisDeps[ dependency ], fullPackageInstallPath ); From d09e73a4f15d211846278834efb7a2572211cf2f Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 12 May 2016 22:55:17 -0500 Subject: [PATCH 095/129] COMMANDBOX-381 --- .../modules/server-commands/commands/server/start.cfc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/cfml/system/modules/server-commands/commands/server/start.cfc b/src/cfml/system/modules/server-commands/commands/server/start.cfc index 9d06049ef..20b25ce4d 100644 --- a/src/cfml/system/modules/server-commands/commands/server/start.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/start.cfc @@ -112,6 +112,14 @@ component aliases="start" { arguments.WARPath = fileSystemUtil.resolvePath( arguments.WARPath ); } + // This is a common mis spelling + if( structKeyExists( arguments, 'rewritesEnabled' ) ) { + print.yellowLine( 'Auto-correcting "rewritesEnabled" to "rewritesEnable".' ); + // Let's fix that up for them. + arguments.rewritesEnable = arguments.rewritesEnabled; + structDelete( arguments, 'rewritesEnabled' ); + } + // startup the server return serverService.start( serverProps = arguments ); } From 572baa36338d1dc32aa192506e8e3631ab03e637 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Fri, 13 May 2016 00:36:51 -0500 Subject: [PATCH 096/129] COMMANDBOX-349 --- src/cfml/system/services/CommandService.cfc | 50 ++++- src/cfml/system/util/StringDistance.cfc | 192 ++++++++++++++++++++ 2 files changed, 241 insertions(+), 1 deletion(-) create mode 100644 src/cfml/system/util/StringDistance.cfc diff --git a/src/cfml/system/services/CommandService.cfc b/src/cfml/system/services/CommandService.cfc index 93cfb6b9f..68490f6b2 100644 --- a/src/cfml/system/services/CommandService.cfc +++ b/src/cfml/system/services/CommandService.cfc @@ -15,9 +15,11 @@ component accessors="true" singleton { property name='system' inject='System@constants'; property name='cr' inject='cr@constants'; property name='logger' inject='logbox:logger:{this}'; + property name='consoleLogger' inject='logbox:logger:console'; property name='wirebox' inject='wirebox'; property name='commandLocations' inject='commandLocations@constants'; property name='interceptorService' inject='interceptorService'; + property name='stringDistance' inject='StringDistance'; property name='configured' default="false" type="boolean"; @@ -118,6 +120,11 @@ component accessors="true" singleton { **/ function runCommandline( required string line ){ + if( left( arguments.line, 4 ) == 'box ' && len( arguments.line ) > 4 ) { + consoleLogger.warn( "Removing extra text [box ] from start of command. You don't need that here." ); + arguments.line = right( arguments.line, len( arguments.line ) - 4 ); + } + // Resolve the command they are wanting to run var commandChain = resolveCommand( line ); @@ -167,7 +174,8 @@ component accessors="true" singleton { // If nothing was found, bail out here. if( !commandInfo.found ){ - throw( message='Command "#line#" cannot be resolved.', detail='Please type "#trim( "help #listChangeDelims( commandInfo.commandString, ' ', '.' )#" )#" for assistance.', type="commandException"); + var detail = generateListOfSimilarCommands( commandInfo ); + throw( message='Command "#line#" cannot be resolved.', detail=detail, type="commandException"); } // For help commands squish all the parameters together into one exactly as typed @@ -295,6 +303,45 @@ component accessors="true" singleton { } + /** + * Generate a smart list of possible commands that the user meant to type + */ + function generateListOfSimilarCommands( required struct commandInfo ) { + var allCommands = getCommands().keyArray().map( function( i ) { return lcase( listChangeDelims( i, ' ', '.' ) ); } ); + var matchedSoFar = lcase( listChangeDelims( arguments.commandInfo.commandString, ' ', '.' ) ); + var originalLine = arguments.commandInfo.originalLine; + var candidates = []; + + for( var option in allCommands ) { + // If we matched a partial command, only consider commands starting with that match + if( len( matchedSoFar ) && !option.startsWith( matchedSoFar ) ) { + continue; + } + // Ignore help commands + if( listLast( option, ' ' ) == 'help' ) { + continue; + } + var thisOriginalLine = originalLine; + // Try to ignore params + if( listLen( option, ' ' ) < listLen( originalLine, ' ' ) ) { + thisOriginalLine = originalLine.listToArray( ' ' ).slice( 1, listLen( option, ' ' ) ).toList( ' ' ); + + } + var comparison = stringDistance.stringSimilarity( option, thisOriginalLine, 2 ); + if( comparison.similarity > .80 ) { + candidates.append( ' ' & option ); + } + } + + var helpText = ''; + if( arrayLen( candidates ) ) { + helpText &= '#chr( 10 )#Did you mean: #chr( 10 )##candidates.toList( chr( 10 ) )##chr( 10 )#'; + } + helpText &= '#chr( 10 )#Please type "#trim( "help #matchedSoFar#" )#" for assistance.'; + return helpText; + } + + /** * Evaluates any expressions as a command string and puts the output in its place. */ @@ -443,6 +490,7 @@ component accessors="true" singleton { } var results = { + originalLine = tokens.toList( ' ' ), commandString = '', commandReference = cmds, parameters = [], diff --git a/src/cfml/system/util/StringDistance.cfc b/src/cfml/system/util/StringDistance.cfc new file mode 100644 index 000000000..03f977b6f --- /dev/null +++ b/src/cfml/system/util/StringDistance.cfc @@ -0,0 +1,192 @@ +/** +* +* StringSimilarity +* Brad Wood +* brad@bradwood.com +* May 2007 +* Code adopted from Siderite Zackwehdex's Blog +* http://siderite.blogspot.com/2007/04/super-fast-and-accurate-string-distance.html +*/ +component singleton { + + /** + * @s1 First string to be compared + * @s2 Second string to be compared + * @maxOffset Average number of characters that s1 will deviate from s2 at any given point. + * This is used to control how far ahead the function looks to try and find the + * end of a peice of inserted text. Play with it to suit. + */ + + function stringSimilarity( s1, s2, maxOffset) + { + var c = 0; + var offset1 = 0; + var offset2 = 0; + var lcs = 0; + // These two strings will contain the "highlighted" version + var _s1 = createObject("java","java.lang.StringBuffer").init(javacast("int",len(s1)*3)); + var _s2 = createObject("java","java.lang.StringBuffer").init(javacast("int",len(s2)*3)); + // These charactes will surround differences in the strings + // (Inserted into _s1 and _s2) + var h1 = chr( 27 ) & "[1m"; + var h2 = chr( 27 ) & "[0m"; + var return_struct = structNew(); + // If both strings are empty + if (not len(trim(s1)) and not len(trim(s2))) + { + return_struct.lcs = 0; + return_struct.similarity = 1; + return_struct.distance = 0; + return_struct.s1 = ""; + return_struct.s2 = ""; + return return_struct; + } + // If s2 is empty, but s1 isn't + if (len(trim(s1)) and not len(trim(s2))) + { + return_struct.lcs = 0; + return_struct.similarity = 0; + return_struct.distance = len(s1); + return_struct.s1 = h1 & s1 & h2; + return_struct.s2 = ""; + return return_struct; + } + // If s1 is empty, but s2 isn't + else if (len(trim(s2)) and not len(trim(s1))) + { + return_struct.lcs = 0; + return_struct.similarity = 0; + return_struct.distance = len(s2); + return_struct.s1 = ""; + return_struct.s2 = h1 & s2 & h2; + return return_struct; + } + + // Examine the strings, one character at a time, anding at the shortest string + // The offset adjusts for extra characters in either string. + while ((c + offset1 lt len(s1)) + and (c + offset2 lt len(s2))) + { + // Pull the next charactes out of s1 anbd s2 + next_s1 = mid(s1,c + offset1+1,iif(not c,3,1)); // First time through check the first three + next_s2 = mid(s2,c + offset2+1,iif(not c,3,1)); // First time through check the first three + // If they are equal + if (compare(next_s1,next_s2) eq 0) + { + // Our longeset Common String just got one bigger + lcs = lcs + 1; + // Append the characters onto the "highlighted" version + _s1.append(left(next_s1,1)); + _s2.append(left(next_s2,1)); + } + // The next two charactes did not match + // Now we will go into a sub-loop while we attempt to + // find our place again. We will only search as long as + // our maxOffset allows us to. + else + { + // Don't reset the offsets, just back them up so you + // have a point of reference + old_offset1 = offset1; + old_offset2 = offset2; + _s1_deviation = ""; + _s2_deviation = ""; + // Loop for as long as allowed by our offset + // to see if we can match up again + for (i = 0; i lt maxOffset; i=i+1) + { + next_s1 = mid(s1,c + offset1 + i+1,3); // Increments each time through. + len_next_s1 = len(next_s1); + bookmarked_s1 = mid(s1,c + offset1+1,3); // stays the same + next_s2 = mid(s2,c + offset2 + i+1,3); // Increments each time through. + len_next_s2 = len(next_s2); + bookmarked_s2 = mid(s2,c + offset2+1,3); // stays the same + + // If we reached the end of both of the strings + if(not len_next_s1 and not len_next_s2) + { + // Quit + break; + } + // These variables keep track of how far we have deviated in the + // string while trying to find our match again. + _s1_deviation = _s1_deviation & left(next_s1,1); + _s2_deviation = _s2_deviation & left(next_s2,1); + // It looks like s1 has a match down the line which fits + // where we left off in s2 + if (compare(next_s1,bookmarked_s2) eq 0) + { + // s1 is now offset THIS far from s2 + offset1 = offset1+i; + // Our longeset Common String just got bigger + lcs = lcs + 1; + // Now that we match again, break to the main loop + break; + } + + // It looks like s2 has a match down the line which fits + // where we left off in s1 + if (compare(next_s2,bookmarked_s1) eq 0) + { + // s2 is now offset THIS far from s1 + offset2 = offset2+i; + // Our longeset Common String just got bigger + lcs = lcs + 1; + // Now that we match again, break to the main loop + break; + } + } + //This is the number of inserted characters were found + added_offset1 = offset1 - old_offset1; + added_offset2 = offset2 - old_offset2; + + // We reached our maxoffset and couldn't match up the strings + if(added_offset1 eq 0 and added_offset2 eq 0) + { + _s1.append(h1 & left(_s1_deviation,added_offset1+1) & h2); + _s2.append(h1 & left(_s2_deviation,added_offset2+1) & h2); + } + // s2 had extra characters + else if(added_offset1 eq 0 and added_offset2 gt 0) + { + _s1.append(left(_s1_deviation,1)); + _s2.append(h1 & left(_s2_deviation,added_offset2) & h2 & right(_s2_deviation,1)); + } + // s1 had extra characters + else if(added_offset1 gt 0 and added_offset2 eq 0) + { + _s1.append(h1 & left(_s1_deviation,added_offset1) & h2 & right(_s1_deviation,1)); + _s2.append(left(_s2_deviation,1)); + } + } + c=c+1; + } + // Anything left at the end of s1 is extra + if(c + offset1 lt len(s1)) + { + _s1.append(h1 & right(s1,len(s1)-(c + offset1)) & h2); + } + // Anything left at the end of s2 is extra + if(c + offset2 lt len(s2)) + { + _s2.append(h1 & right(s2,len(s2)-(c + offset2)) & h2); + } + + // Distance is the average string length minus the longest common string + distance = (len(s1) + len(s2))/2 - lcs; + // Whcih string was longest? + maxLen = iif(len(s1) gt len(s2),de(len(s1)),de(len(s2))); + // Similarity is the distance divided by the max length + similarity = iif(maxLen eq 0,1,1-(distance/maxLen)); + // Return what we found. + return_struct.lcs = lcs; + return_struct.similarity = similarity; + return_struct.distance = distance; + return_struct.s1 = _s1.toString(); // "highlighted" version + return_struct.s2 = _s2.toString(); // "highlighted" version + return return_struct; + } + + + +} \ No newline at end of file From 752d058c2929a38812508cdf64d3652263f39e8e Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Fri, 13 May 2016 10:31:42 -0500 Subject: [PATCH 097/129] COMMANDBOX-341 --- src/cfml/system/services/PackageService.cfc | 23 ++++++++++----------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/cfml/system/services/PackageService.cfc b/src/cfml/system/services/PackageService.cfc index e1caa31dd..5251345a7 100644 --- a/src/cfml/system/services/PackageService.cfc +++ b/src/cfml/system/services/PackageService.cfc @@ -511,7 +511,8 @@ component accessors="true" singleton { required string ID, string directory, boolean save=false, - required string currentWorkingDirectory + required string currentWorkingDirectory, + string packagePathRequestingUninstallation = arguments.currentWorkingDirectory ){ interceptorService.announceInterception( 'preUninstall', { uninstallArgs=arguments } ); @@ -538,15 +539,9 @@ component accessors="true" singleton { uninstallDirectory = fileSystemUtil.resolvePath( installPaths[ packageName ] ); } } - - // If all else fails, just use the current directory - if( !len( uninstallDirectory ) ) { - consoleLogger.warn( "No install path found in box.json, looking in the current working directory."); - uninstallDirectory = arguments.currentWorkingDirectory & '/' & packageName; - } // See if the package exists here - if( directoryExists( uninstallDirectory ) ) { + if( len( uninstallDirectory ) && directoryExists( uninstallDirectory ) ) { // Get the dependencies of the package we're about to uninstalled var boxJSON = readPackageDescriptor( uninstallDirectory ); @@ -577,7 +572,8 @@ component accessors="true" singleton { ID = dependency, // Only save the first level save = false, - currentWorkingDirectory = arguments.currentWorkingDirectory + currentWorkingDirectory = uninstallDirectory, + packagePathRequestingUninstallation=arguments.packagePathRequestingUninstallation }; // If the user didn't specify this, don't pass it since it overrides the package's desired install location @@ -592,7 +588,7 @@ component accessors="true" singleton { } // end is not module // uninstall the package - if( directoryExists( uninstallDirectory ) ) { + if( len( uninstallDirectory ) && directoryExists( uninstallDirectory ) ) { // Catch this to gracefully handle where the OS or another program // has the folder locked. @@ -603,6 +599,11 @@ component accessors="true" singleton { logger.error( '#e.message# #e.detail#' , e.stackTrace ); } + consoleLogger.info( "'#packageName#' has been uninstalled" ); + + } else if( !len( uninstallDirectory ) ) { + consoleLogger.debug( "Package [#packageName#] skipped, it doesn't appear to be installed." ); + } else { consoleLogger.error( 'Package [#uninstallDirectory#] not found.' ); } @@ -617,8 +618,6 @@ component accessors="true" singleton { consoleLogger.info( "Dependency removed from box.json." ); } - consoleLogger.info( "'#packageName#' has been uninstalled" ); - interceptorService.announceInterception( 'postUninstall', { uninstallArgs=arguments } ); } From 8b1d3844de96087cc9aaf18acd30564ed626ac73 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 16 May 2016 14:45:44 -0500 Subject: [PATCH 098/129] COMMANDBOX-384 --- .../modules/package-commands/commands/package/version.cfc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cfml/system/modules/package-commands/commands/package/version.cfc b/src/cfml/system/modules/package-commands/commands/package/version.cfc index 8e546b05d..f15632342 100644 --- a/src/cfml/system/modules/package-commands/commands/package/version.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/version.cfc @@ -76,6 +76,7 @@ component aliases="bump" { } else if( structKeyExists( arguments, 'minor' ) && arguments.minor ) { // Bump minor + versionObject.major = val( versionObject.major ); versionObject.minor = val( versionObject.minor ) + 1; versionObject.revision = 0; arguments.version = semanticVersion.getVersionAsString( versionObject ); @@ -84,6 +85,8 @@ component aliases="bump" { } else if( structKeyExists( arguments, 'patch' ) && arguments.patch ) { // Bump patch + versionObject.major = val( versionObject.major ); + versionObject.minor = val( versionObject.minor ); versionObject.revision = val( versionObject.revision ) + 1; arguments.version = semanticVersion.getVersionAsString( versionObject ); setVersion( argumentCollection=arguments ); From ecc341d66b52a860a0f08c3ff97ed0cbed65d709 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 17 May 2016 00:02:03 -0500 Subject: [PATCH 099/129] COMMANDBOX-385 --- src/cfml/system/endpoints/ForgeBox.cfc | 8 ++++- src/cfml/system/util/ForgeBox.cfc | 44 ++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/cfml/system/endpoints/ForgeBox.cfc b/src/cfml/system/endpoints/ForgeBox.cfc index a91fbab8e..841322680 100644 --- a/src/cfml/system/endpoints/ForgeBox.cfc +++ b/src/cfml/system/endpoints/ForgeBox.cfc @@ -42,7 +42,7 @@ component accessors="true" implements="IEndpointInteractive" singleton { // Defer to file endpoint return fileEndpoint.resolvePackage( thisArtifactPath, arguments.verbose ); } else { - return getPackage( slug, version, arguments.verbose ); + return getPackage( slug, version, arguments.verbose ); } } @@ -264,6 +264,12 @@ component accessors="true" implements="IEndpointInteractive" singleton { } consoleLogger.info( "Installing version [#arguments.version#]." ); + + try { + forgeBox.recordInstall( arguments.slug, arguments.version ); + } catch( forgebox var e ) { + consoleLogger.warn( e.message & CR & e.detail ); + } var packageType = entryData.typeSlug; diff --git a/src/cfml/system/util/ForgeBox.cfc b/src/cfml/system/util/ForgeBox.cfc index d1c8ca048..5dffa3c2b 100644 --- a/src/cfml/system/util/ForgeBox.cfc +++ b/src/cfml/system/util/ForgeBox.cfc @@ -263,6 +263,50 @@ or just add DEBUG to the root logger return results.response.data; } + /** + * Tracks an install + */ + function recordInstall( + required string slug, + string version='' ) { + + var thisResource = "install/#arguments.slug#"; + if( len( arguments.version ) ) { + thisResource &= "/#arguments.version#"; + } + + var results = makeRequest( resource=thisResource, method='post' ); + + // error + if( results.error ){ + throw( "Something went wrong tracking this installation.", 'forgebox', arrayToList( results.response.messages ) ); + } + + return results.response.data; + } + + /** + * Tracks a download + */ + function recordDownload( + required string slug, + string version ) { + + var thisResource = "install/#arguments.slug#"; + if( len( arguments.version ) ) { + thisResource &= "/#arguments.version#"; + } + + var results = makeRequest( resource=thisResource, parameters=arguments, method='post' ); + + // error + if( results.error ){ + throw( "Something went wrong tracking this download.", 'forgebox', arrayToList( results.response.messages ) ); + } + + return results.response.data; + } + From 352b6a103933f8b0b1e88e11ddf8f3d016c3e9f4 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 17 May 2016 15:34:58 -0500 Subject: [PATCH 100/129] COMMANDBOX-369 --- .../commands/forgebox/search.cfc | 37 +++++++------------ src/cfml/system/util/ForgeBox.cfc | 4 +- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/search.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/search.cfc index 98ff61ee8..1f8460b73 100644 --- a/src/cfml/system/modules/forgebox-commands/commands/forgebox/search.cfc +++ b/src/cfml/system/modules/forgebox-commands/commands/forgebox/search.cfc @@ -10,7 +10,8 @@ component { // DI - property name="forgeBox" inject="ForgeBox"; + property name="forgeBox" inject="ForgeBox"; + property name="semanticVersion" inject="semanticVersion"; /** * @searchText.hint Text to search on @@ -23,37 +24,27 @@ component { try { // Get the entries - var entries = forgebox.getEntries(); + var entries = forgebox.getEntries( searchTerm = arguments.searchText ); // entrylink,createdate,lname,isactive,installinstructions,typename,version,hits,coldboxversion,sourceurl,slug,homeurl,typeslug, // downloads,entryid,fname,changelog,updatedate,downloadurl,title,entryrating,summary,username,description print.line(); - var activeCount = 0; for( var entry in entries.results ) { - if( val( entry.isactive ) - && ( - entry.title contains arguments.searchText - || entry.user.fname contains arguments.searchText - || entry.user.lname contains arguments.searchText - || entry.typeName contains arguments.searchText - || entry.summary contains arguments.searchText - ) ) { - activeCount++; - print.blackOnWhite( ' #entry.title# ' ); - print.boldText( ' ( #entry.user.fname# #entry.user.lname# )' ); - print.boldGreenLine( ' #repeatString( '*', val( entry.avgRating ) )#' ); - print.line( 'Version: #entry.version#' ); - print.line( 'Type: #entry.typeName#' ); - print.line( 'Slug: "#entry.slug#"' ); - print.Yellowline( '#left( entry.summary, 200 )#' ); - print.line(); - print.line(); - } + entry.versions.sort( function( a, b ) { return semanticVersion.compare( b.version, a.version ) } ); + print.blackOnWhite( ' #entry.title# ' ) + .boldText( ' ( #entry.user.fname# #entry.user.lname# )' ) + .boldGreenLine( ' #repeatString( '*', val( entry.avgRating ) )#' ) + .line( 'Versions: #entry.versions.map( function( i ){ return ' ' & i.version; } ).toList()#' ) + .line( 'Type: #entry.typeName#' ) + .line( 'Slug: "#entry.slug#"' ) + .yellowline( '#left( entry.summary, 200 )#' ) + .line() + .line(); } print.line(); - print.boldCyanline( ' Found #activeCount# record#(activeCount == 1 ? '': 's')#.' ); + print.boldCyanline( " Showing #entries.count# of #entries.totalRecords# record#( entries.count == 1 ? '' : 's' )#." ); } catch( forgebox var e ) { // This can include "expected" errors such as "slug not found" diff --git a/src/cfml/system/util/ForgeBox.cfc b/src/cfml/system/util/ForgeBox.cfc index 5dffa3c2b..08755d690 100644 --- a/src/cfml/system/util/ForgeBox.cfc +++ b/src/cfml/system/util/ForgeBox.cfc @@ -93,13 +93,15 @@ or just add DEBUG to the root logger + var results = ""; var params = { orderBY = arguments.orderby, max = arguments.maxrows, offset = arguments.startrow-1, - typeSlug = arguments.typeSlug + typeSlug = arguments.typeSlug, + searchTerm = arguments.searchTerm }; // Invoke call From c5e931aab4fefdadc95d9d5c9dde1efcd7b080e4 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 17 May 2016 23:01:55 -0500 Subject: [PATCH 101/129] COMMANDBOX-368 --- .../commands/package/install.cfc | 25 +++++++++---------- .../commands/package/uninstall.cfc | 24 ++++++------------ .../commands/package/update.cfc | 14 +++++++++++ src/cfml/system/util/ForgeBox.cfc | 20 ++++++++++++++- 4 files changed, 52 insertions(+), 31 deletions(-) diff --git a/src/cfml/system/modules/package-commands/commands/package/install.cfc b/src/cfml/system/modules/package-commands/commands/package/install.cfc index f8a850a8e..f63fe9954 100644 --- a/src/cfml/system/modules/package-commands/commands/package/install.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/install.cfc @@ -152,21 +152,20 @@ component aliases="install" { } // Auto-complete list of IDs - function IDComplete() { - var result = []; - // Cache in command - if( !structKeyExists( variables, 'entries' ) ) { - variables.entries = forgebox.getEntries().results; + function IDComplete( string paramSoFar ) { + if( !len( trim( paramSoFar ) ) ) { + return []; } - - // Loop over results and append all active ForgeBox entries - for( var entry in variables.entries ) { - if( val( entry.isactive ) ) { - result.append( entry.slug ); - } + try { + return forgebox.slugSearch( arguments.paramSoFar ); + } catch( forgebox var e ) { + print + .line() + .yellowLine( e.message & chr( 10 ) & e.detail ) + .toConsole(); + getShell().getReader().redrawLine(); } - - return result; + return []; } } diff --git a/src/cfml/system/modules/package-commands/commands/package/uninstall.cfc b/src/cfml/system/modules/package-commands/commands/package/uninstall.cfc index 9185dc56f..d64264a4a 100644 --- a/src/cfml/system/modules/package-commands/commands/package/uninstall.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/uninstall.cfc @@ -19,11 +19,6 @@ **/ component aliases="uninstall" { - /** - * The ForgeBox entries cache - */ - property name="entries"; - // DI property name="forgeBox" inject="ForgeBox"; property name="packageService" inject="PackageService"; @@ -70,20 +65,15 @@ component aliases="uninstall" { // Auto-complete list of slugs function slugComplete() { - var result = []; - // Cache in command - if( !structKeyExists( variables, 'entries' ) ) { - variables.entries = forgebox.getEntries().results; - } + var results = []; + var directory = getCWD(); - // Loop over results and append all active ForgeBox entries - for( var entry in variables.entries ) { - if( val( entry.isactive ) ) { - result.append( entry.slug ); - } + if( packageService.isPackage( directory ) ) { + var BoxJSON = packageService.readPackageDescriptor( directory ); + results.append( BoxJSON.installPaths.keyArray(), true ); } - - return result; + + return results; } } \ No newline at end of file diff --git a/src/cfml/system/modules/package-commands/commands/package/update.cfc b/src/cfml/system/modules/package-commands/commands/package/update.cfc index 4508c5562..c2e07c72d 100644 --- a/src/cfml/system/modules/package-commands/commands/package/update.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/update.cfc @@ -38,6 +38,7 @@ component aliases="update" { /** * Update all or one outdated dependencies * @slug A comma-delimmited list of slugs to update. Pass nothing to update all packages. + * @slug.optionsUDF slugComplete * @verbose Outputs additional information about each package * @force Forces an update without confirmations **/ @@ -117,4 +118,17 @@ component aliases="update" { } // end for } + + // Auto-complete list of slugs + function slugComplete() { + var results = []; + var directory = getCWD(); + + if( packageService.isPackage( directory ) ) { + var BoxJSON = packageService.readPackageDescriptor( directory ); + results.append( BoxJSON.installPaths.keyArray(), true ); + } + + return results; + } } \ No newline at end of file diff --git a/src/cfml/system/util/ForgeBox.cfc b/src/cfml/system/util/ForgeBox.cfc index 08755d690..0ed022860 100644 --- a/src/cfml/system/util/ForgeBox.cfc +++ b/src/cfml/system/util/ForgeBox.cfc @@ -299,7 +299,7 @@ or just add DEBUG to the root logger thisResource &= "/#arguments.version#"; } - var results = makeRequest( resource=thisResource, parameters=arguments, method='post' ); + var results = makeRequest( resource=thisResource, method='post' ); // error if( results.error ){ @@ -309,6 +309,24 @@ or just add DEBUG to the root logger return results.response.data; } + + /** + * Autocomplete for slugs + */ + function slugSearch( required string searchTerm ) { + + var thisResource = "slugs/#arguments.searchTerm#"; + + var results = makeRequest( resource=thisResource, method='get' ); + + // error + if( results.error ){ + throw( "Error searching for slugs", 'forgebox', arrayToList( results.response.messages ) ); + } + + return results.response.data; + } + From 1a66ab81758c10c1ac5dc7accaa787ef08757676 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 17 May 2016 23:06:39 -0500 Subject: [PATCH 102/129] Comments and scoping --- .../modules/package-commands/commands/package/install.cfc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/cfml/system/modules/package-commands/commands/package/install.cfc b/src/cfml/system/modules/package-commands/commands/package/install.cfc index f63fe9954..163cf4da2 100644 --- a/src/cfml/system/modules/package-commands/commands/package/install.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/install.cfc @@ -153,18 +153,23 @@ component aliases="install" { // Auto-complete list of IDs function IDComplete( string paramSoFar ) { - if( !len( trim( paramSoFar ) ) ) { + // Only hit forgebox if they've typed something. + if( !len( trim( arguments.paramSoFar ) ) ) { return []; } try { + // Get auto-complete options return forgebox.slugSearch( arguments.paramSoFar ); } catch( forgebox var e ) { + // Gracefully handle ForgeBox issues print .line() .yellowLine( e.message & chr( 10 ) & e.detail ) .toConsole(); + // After outputting the message above on a new line, but the user back where they started. getShell().getReader().redrawLine(); } + // In case of error, break glass. return []; } From ec26fac0654f26b9eb6ea5f76d93e9c126ebe27a Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 18 May 2016 01:06:59 -0500 Subject: [PATCH 103/129] COMMANDBOX-382 --- src/cfml/system/config/box.json.txt | 1 + .../commands/package/run-script.cfc | 37 +++++++++++++++++++ .../interceptors/packageScripts.cfc | 18 +-------- src/cfml/system/services/PackageService.cfc | 28 +++++++++++++- 4 files changed, 66 insertions(+), 18 deletions(-) create mode 100644 src/cfml/system/modules/package-commands/commands/package/run-script.cfc diff --git a/src/cfml/system/config/box.json.txt b/src/cfml/system/config/box.json.txt index 6cf2114f8..f2a6fb60e 100644 --- a/src/cfml/system/config/box.json.txt +++ b/src/cfml/system/config/box.json.txt @@ -31,6 +31,7 @@ dependencies : {}, devDependencies : {}, installPaths : {}, + scripts : {}, ignore : [], testbox :{ runner : [ diff --git a/src/cfml/system/modules/package-commands/commands/package/run-script.cfc b/src/cfml/system/modules/package-commands/commands/package/run-script.cfc new file mode 100644 index 000000000..a63f0be8a --- /dev/null +++ b/src/cfml/system/modules/package-commands/commands/package/run-script.cfc @@ -0,0 +1,37 @@ +/** + * Runs a package script, by name. Scripts are stored in box.json. + * . + * {code:bash} + * run-script myScript + * {code} + * . + **/ +component aliases="run-script" { + + property name="packageService" inject="PackageService"; + + /** + * @scriptName Name of the script to run + * @scriptName.optionsUDF scriptNameComplete + * @directory The path to your package + **/ + function run( required string scriptname, string directory='' ){ + + // This will make each directory canonical and absolute + arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); + + // package check + if( !packageService.isPackage( arguments.directory ) ) { + return error( '#arguments.directory# is not a package!' ); + } + + packageService.runScript( arguments.scriptName, arguments.directory, false ); + + } + + function scriptNameComplete() { + var boxJSON = packageService.readPackageDescriptor( shell.pwd() ); + return boxJSON.scripts.keyArray(); + } + +} \ No newline at end of file diff --git a/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc b/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc index c598bd15a..a7800689c 100644 --- a/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc +++ b/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc @@ -34,22 +34,8 @@ component { function postPublish() { processScripts( 'postPublish' ); } function processScripts( required string interceptionPoint, string directory=shell.pwd() ) { - // Read the box.json from this package (if it exists) - var boxJSON = packageService.readPackageDescriptor( arguments.directory ); - // If there is a scripts object with a matching key for this interceptor.... - if( boxJSON.keyExists( 'scripts' ) && isStruct( boxJSON.scripts ) && boxJSON.scripts.keyExists( interceptionPoint ) ) { - var thisScript = boxJSON.scripts[ interceptionPoint ]; - - consoleLogger.debug( "." ); - consoleLogger.warn( 'Running #interceptionPoint# package script.' ); - consoleLogger.debug( '> ' & thisScript ); - - // ... then run the script! (in the context of the package's working directory) - var previousCWD = shell.pwd(); - shell.cd( arguments.directory ); - shell.callCommand( thisScript ); - shell.cd( previousCWD ); - } + consoleLogger.debug( "." ); + packageService.runScript( arguments.interceptionPoint, arguments.directory ); } } \ No newline at end of file diff --git a/src/cfml/system/services/PackageService.cfc b/src/cfml/system/services/PackageService.cfc index 5251345a7..ac179fe2a 100644 --- a/src/cfml/system/services/PackageService.cfc +++ b/src/cfml/system/services/PackageService.cfc @@ -1008,5 +1008,29 @@ component accessors="true" singleton { return props; } - -} \ No newline at end of file + /** + * Nice wrapper to run a package script + * @scriptName Name of the package script to run + * @directory The package root + */ + function runScript( required string scriptName, string directory=shell.pwd(), boolean ignoreMissing=true ) { + + // Read the box.json from this package (if it exists) + var boxJSON = readPackageDescriptor( arguments.directory ); + // If there is a scripts object with a matching key for this interceptor.... + if( boxJSON.keyExists( 'scripts' ) && isStruct( boxJSON.scripts ) && boxJSON.scripts.keyExists( arguments.scriptName ) ) { + + var thisScript = boxJSON.scripts[ arguments.scriptName ]; + consoleLogger.warn( 'Running package script [#arguments.scriptName#].' ); + consoleLogger.debug( '> ' & thisScript ); + + // ... then run the script! (in the context of the package's working directory) + var previousCWD = shell.pwd(); + shell.cd( arguments.directory ); + shell.callCommand( thisScript ); + shell.cd( previousCWD ); + } else if( !arguments.ignoreMissing ) { + consoleLogger.error( 'The script [#arguments.scriptName#] does not exist in this package.' ); + } + } +} \ No newline at end of file From be2d04bbca61bf6438b719287431a64dc955245b Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 19 May 2016 01:14:25 -0500 Subject: [PATCH 104/129] COMMANDBOX-373 --- src/cfml/system/BaseCommand.cfc | 3 ++ src/cfml/system/services/CommandService.cfc | 60 ++++++++++++++++++--- src/cfml/system/util/Parser.cfc | 30 +++++++++-- tests/Application.cfc | 9 +++- 4 files changed, 91 insertions(+), 11 deletions(-) diff --git a/src/cfml/system/BaseCommand.cfc b/src/cfml/system/BaseCommand.cfc index 7e8953622..ecec1c009 100644 --- a/src/cfml/system/BaseCommand.cfc +++ b/src/cfml/system/BaseCommand.cfc @@ -147,6 +147,9 @@ component accessors="true" singleton { * Sets the OS exit code **/ function setExitCode( required string exitCode ) { + if( arguments.exitCode != 0 ) { + hasErrored = true; + } return shell.setExitCode( arguments.exitCode ); } diff --git a/src/cfml/system/services/CommandService.cfc b/src/cfml/system/services/CommandService.cfc index 68490f6b2..3c128c5e4 100644 --- a/src/cfml/system/services/CommandService.cfc +++ b/src/cfml/system/services/CommandService.cfc @@ -166,11 +166,29 @@ component accessors="true" singleton { } var i = 0; + // default behavior is to keep trucking + var previousCommandSeparator = ';'; + var lastCommandErrored = false; // If piping commands, each one will be an item in the chain. // i.e. forgebox show | grep | more // Would result in three separate, chained commands. for( var commandInfo in commandChain ){ i++; + + // If we've reached a command separator like "foo | bar" or "baz && bum", make note of it and continue + if( listFindNoCase( ';,|,||,&&', commandInfo.originalLine ) ) { + previousCommandSeparator = commandInfo.originalLine; + continue; + } + + if( previousCommandSeparator == '&&' && lastCommandErrored ) { + return result ?: ''; + } + + if( previousCommandSeparator == '||' && !lastCommandErrored ) { + return result ?: ''; + } + // If nothing was found, bail out here. if( !commandInfo.found ){ @@ -207,7 +225,7 @@ component accessors="true" singleton { // If this is not the first command in the chain, // set its first parameter with the output from the last command - if( structKeyExists( local, 'result' ) ){ + if( previousCommandSeparator == '|' && structKeyExists( local, 'result' ) ){ // Clean off trailing any CR to help with piping one-liner outputs as inputs to another command if( result.endsWith( chr( 10 ) ) && len( result ) > 1 ){ result = left( result, len( result ) - 1 ); @@ -226,6 +244,12 @@ component accessors="true" singleton { parameterInfo.positionalParameters.prepend( result ); } } + // If we're not piping, output what we've got + } else { + if( structKeyExists( local, 'result' ) && len( result ) ){ + shell.printString( result & cr ); + } + structDelete( local, 'result', false ); } // If we're using postitional params, convert them to named @@ -266,9 +290,9 @@ component accessors="true" singleton { // Run the command try { var result = commandInfo.commandReference.CFC.run( argumentCollection = parameterInfo.namedParameters ); + lastCommandErrored = commandInfo.commandReference.CFC.hasError(); } catch( any e ){ - // Clean up a bit - instance.callStack.clear(); + lastCommandErrored = true; // Dump out anything the command had printed so far var result = commandInfo.commandReference.CFC.getResult(); @@ -276,7 +300,17 @@ component accessors="true" singleton { shell.printString( result & cr ); } // Now, where were we? - rethrow; + if( arrayLen( commandChain ) > i && listFindNoCase( '||,;', commandChain[ i+1 ].originalLine ) ) { + if( e.type == 'commandException' ) { + shell.printError( { message : e.message, detail: e.detail } ); + } else { + shell.printError( e ); + } + } else { + // Clean up a bit + instance.callStack.clear(); + rethrow; + } } // Successful command execution resets exit code to 0 @@ -412,20 +446,34 @@ component accessors="true" singleton { // We've reached a pipe and there is at least one command resolved already and there are more tokens left if( token == '|' && commandsToResolve[ commandsToResolve.len() ].len() && i < tokens.len() ){ // Add a new command + commandsToResolve.append( [ '|' ] ); + commandsToResolve.append( [] ); + } else if( token == ';' && commandsToResolve[ commandsToResolve.len() ].len() && i < tokens.len() ){ + // Add a new command + commandsToResolve.append( [ ';' ] ); + commandsToResolve.append( [] ); + } else if( token == '&&' && commandsToResolve[ commandsToResolve.len() ].len() && i < tokens.len() ){ + // Add a new command + commandsToResolve.append( [ '&&' ] ); + commandsToResolve.append( [] ); + } else if( token == '||' && commandsToResolve[ commandsToResolve.len() ].len() && i < tokens.len() ){ + // Add a new command + commandsToResolve.append( [ '||' ] ); commandsToResolve.append( [] ); } else if( token == '>' && commandsToResolve[ commandsToResolve.len() ].len() && i < tokens.len() ){ // Add a new command + commandsToResolve.append( [ '|' ] ); commandsToResolve.append( [ 'fileWrite' ] ); } else if( token == '>>' && commandsToResolve[ commandsToResolve.len() ].len() && i < tokens.len() ){ // Add a new command + commandsToResolve.append( [ '|' ] ); commandsToResolve.append( [ 'fileAppend' ] ); - } else { + } else if( !listFindNoCase( '|,;,>,>>,&&', token ) ) { //Append this token to the last command commandsToResolve[ commandsToResolve.len() ].append( token ); } } - // command hierarchy var cmds = getCommandHierarchy(); diff --git a/src/cfml/system/util/Parser.cfc b/src/cfml/system/util/Parser.cfc index 26eca509a..a50776ef6 100644 --- a/src/cfml/system/util/Parser.cfc +++ b/src/cfml/system/util/Parser.cfc @@ -78,10 +78,20 @@ component { // Whitespace demarcates tokens outside of quotes // Whitespace outside of a quoted string is dumped and not added to the token - if( trim(char) == '' ) { + if( trim(char) == '' || ( char == ';' && !isEscaped ) ) { + // If this is an unquoted, unescaped semi colon (;) + if( char == ';' ) { + if( len( token ) ) { + tokens.append( token); + token = ''; + } + tokens.append( char ); + prevEscaped = isEscaped; + prevChar = char; + continue; // Don't break if an = is next ... - if( left( trim( remainingChars ), 1 ) == '=' ) { + } else if( left( trim( remainingChars ), 1 ) == '=' ) { isWaitingOnValue = true; prevEscaped = isEscaped; prevChar = char; @@ -217,6 +227,9 @@ component { * ' --> \' * ` --> \` * = --> \= + * ; --> \; + * & --> \& + * | --> \| * [line break] --> \n * [tab] --> \t */ @@ -226,6 +239,9 @@ component { arguments.argValue = replace( arguments.argValue, "'", "\'", "all" ); arguments.argValue = replace( arguments.argValue, "`", "\`", "all" ); arguments.argValue = replace( arguments.argValue, "=", "\=", "all" ); + arguments.argValue = replace( arguments.argValue, ";", "\;", "all" ); + arguments.argValue = replace( arguments.argValue, "&", "\&", "all" ); + arguments.argValue = replace( arguments.argValue, "|", "\|", "all" ); arguments.argValue = replace( arguments.argValue, CR, "\n", "all" ); arguments.argValue = replace( arguments.argValue, chr( 9 ), "\t", "all" ); return arguments.argValue; @@ -249,7 +265,10 @@ component { theString = replaceNoCase( theString, '\`', '__backtick__', "all" ); theString = replaceNoCase( theString, '\n', '__newLine__', "all" ); theString = replaceNoCase( theString, '\t', '__tab__', "all" ); - return replaceNoCase( theString, '\=', '__equalSign__', "all" ); + theString = replaceNoCase( theString, '\=', '__equalSign__', "all" ); + theString = replaceNoCase( theString, '\;', '__semiColon__', "all" ); + theString = replaceNoCase( theString, '\&', '__ampersand__', "all" ); + return replaceNoCase( theString, '\|', '__pipe__', "all" ); } private function replaceEscapedChars( theString ) { @@ -259,7 +278,10 @@ component { theString = replaceNoCase( theString, '__backtick__', '`', "all" ); theString = replaceNoCase( theString, '__newLine__', CR, "all" ); theString = replaceNoCase( theString, '__tab__', chr( 9 ), "all" ); - return replaceNoCase( theString, '__equalSign__', '=', "all" ); + theString = replaceNoCase( theString, '__equalSign__', '=', "all" ); + theString = replaceNoCase( theString, '__semiColon__', ';', "all" ); + theString = replaceNoCase( theString, '__ampersand__', '&', "all" ); + return replaceNoCase( theString, '__pipe__', '|', "all" ); } diff --git a/tests/Application.cfc b/tests/Application.cfc index b35e49dca..21c825ced 100644 --- a/tests/Application.cfc +++ b/tests/Application.cfc @@ -4,7 +4,14 @@ component { this.applicationTimeout = createTimeSpan( 0, 0, 5, 0 ); this.sessionTimeout = createTimeSpan( 0, 0, 5, 0 ); this.sessionmanagement="true"; - + + // mappings + this.mappings[ "/tests" ] = getDirectoryFromPath( getCurrentTemplatePath() ); + this.mappings[ '/testbox' ] = 'testbox'; + this.mappings[ '/commandbox' ] = '../src/cfml'; + this.mappings[ '/wirebox' ] = '../src/cfml/system/wirebox'; + this.mappings[ '/mxunit' ] = '/testbox/system/compat'; + boolean function onRequestStart( required targetPage ){ new wirebox.system.ioc.Injector( 'tests.config.WireBox' ); return true; From 46bc1d818654d48221469a13ef778004efcb4512 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 19 May 2016 23:04:53 -0500 Subject: [PATCH 105/129] COMMANDBOX-379 --- .../config/server-icons/trayicon-cf09.png | Bin 0 -> 145676 bytes .../config/server-icons/trayicon-cf10.png | Bin 0 -> 150027 bytes .../config/server-icons/trayicon-cf11.png | Bin 0 -> 160974 bytes .../config/server-icons/trayicon-cf2016.png | Bin 0 -> 141242 bytes .../config/server-icons/trayicon-lucee.png | Bin 0 -> 187895 bytes .../config/server-icons/trayicon-railo.png | Bin 0 -> 157380 bytes src/cfml/system/services/CommandService.cfc | 10 +++- src/cfml/system/services/ServerService.cfc | 45 ++++++++++++++---- 8 files changed, 45 insertions(+), 10 deletions(-) create mode 100644 src/cfml/system/config/server-icons/trayicon-cf09.png create mode 100644 src/cfml/system/config/server-icons/trayicon-cf10.png create mode 100644 src/cfml/system/config/server-icons/trayicon-cf11.png create mode 100644 src/cfml/system/config/server-icons/trayicon-cf2016.png create mode 100644 src/cfml/system/config/server-icons/trayicon-lucee.png create mode 100644 src/cfml/system/config/server-icons/trayicon-railo.png diff --git a/src/cfml/system/config/server-icons/trayicon-cf09.png b/src/cfml/system/config/server-icons/trayicon-cf09.png new file mode 100644 index 0000000000000000000000000000000000000000..0189ad093bc8eca992c6a893dde9a3953f6b244f GIT binary patch literal 145676 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

3U$qvU?M>Smclk?QJA&jqAn- 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 literal 0 HcmV?d00001 diff --git a/src/cfml/system/config/server-icons/trayicon-cf10.png b/src/cfml/system/config/server-icons/trayicon-cf10.png new file mode 100644 index 0000000000000000000000000000000000000000..c952eca80d747fe66d37a280f161cc3aa15ac2f5 GIT binary patch literal 150027 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%0D*KA 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⪙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

q!U)PCg)fAB7yE__cYW&I9$LB2v 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 H#=-vwFwEbb literal 0 HcmV?d00001 diff --git a/src/cfml/system/config/server-icons/trayicon-cf11.png b/src/cfml/system/config/server-icons/trayicon-cf11.png new file mode 100644 index 0000000000000000000000000000000000000000..f703c26df24473cdda01df7ce950cfc72e9010e8 GIT binary patch literal 160974 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

-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 th4o+BoXFPj2Lny-H@xQACUegvvdA2 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

bSPHrwot61_=r2>`G&X_tI*4#GGC1-mjBl#@3` zVK^I`!GY#fP`XTy?SCOxA3tf$^kv6cT3ZlpKDy;$ZG0xjB*=hcL^y_K-y{lQ`;f

=$)DqiL~Gh{D7?#- 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 D(2=o5 literal 0 HcmV?d00001 diff --git a/src/cfml/system/config/server-icons/trayicon-lucee.png b/src/cfml/system/config/server-icons/trayicon-lucee.png new file mode 100644 index 0000000000000000000000000000000000000000..d90880ff887c19111f66f7f10badc321ad784adc GIT binary patch literal 187895 zcmeF(V~i!y+bH@rrrkYlPusSpZQHhOP1`nh+qP}nwr$>-_x~pMemdveoDU~Axs|N! zTC1K)twOSD)i2KulampJ`+@ZX2nYyHTuev-2na;&Ux9-7+tOu{y7Bi1%uzsG3F`0S z1!WZaw+?M5rtSy?MDzZy0Dpu?9RF>^aS~Q@QnWR3a@BV*2I4oeH83U+F?TR_wRNy` zBoI_&J?W^61OkH8wR2EWb<4cWly=w``swHCw{pimJ0M6^XP`cqzL^+78Qlx6CI@c9 zHN5kq3tUnK$8Rj%(hfA(hwrnE#8pyWQzl35csTmv#Pj>w+0^3e<^8#PLGISarnrCB3lHI?9~d7VvM`#=nY*lC z95>oR=RSSe*MO$%bjg6(TY$ZCxiF*AUHbzAxT@c`38pI0w+X0v0>F5y@S@s3{gK9Z zU%Y?3>fzo_sT0txZhC&<;+}E4A93ecz^Klv6W-lm5reJ|@`d|b93;l7a8)Z~J8yKp z5ar~y?1L%d-Cs2a(fibnkPn?z9I2+sT~hX^*3k71(KV$<-_0+dxYwx|Ds#pItPfGT zxqZs5T-mFto|H(oUk40c;D>}?Yv5jd`<>&j?x(8*l?hYN=aKDelmQ4^8AQqiS@@wH z(&Z4_~3}FaVP|_ z#HC)hot?flUoU8C*)XY7d@-MPuSA50udR^Cukh1BG|4+@<9~91=U##=xsa;JN*m?z zkO`vjsdphs=y&9C?YddOzo(R6fm@WZYlR7b z;$KWhx7#y8ZKn50!mc@G87_S3Zj+B$=)2kS;|esmdEl+4f0 zi@K(|oLqE9+6CR^-@C0-$EN4B?~`JLZO(9kaQ1hz&K*@ebpTx8@7IhgLG(Y zeq&=AY;8l=OT^G#o-3fkl8BJCgaa7ir@w*gwysn}!VPpUCYB|1u!pzBp!f8dBd5K+ z1U1;4BoV;^TYRH|j$NBDW0iZGM8>sToLD`qug$abfxso`ldolSa=TRIQxH37UDmVa z@o4;HR<6c8hunAt3aCI@{^BjAD7vf!9h<(YE;N*293eJf3xcc9f;2qaY9#X{kqR(HsgFi{Is6&g}K$|x+OW3R{97O z5-9BbEJ8MvnNK0b)ksIv(mIx#Y(nabFM{w5GH+D~S4q#oSJEh3^%IKJ!}D!=Vdz2+ zl9$Gh*QlfP02Oqq8)*(=me;_KpQAlOK9|jSO}}Y&A*oG(O6^P*$5)F>7*@64g-B66Mf|41c~|S2h#J*_(N}zjj07n zPq5w<1n&~W_?cJhlmD^9Q_@;9rw9>uBQ!>X9q6_Rdrk%(zf)RHXN@(|v!CLY*|$B; z)Hp!a)7CtZ4_&&97aNGoC!k`}_?m_wVl$YUR0UtYV}Dl0T-V!a5blWlC!q8d=I-}7 z7Tcf(*9si?_JdbTzLl#P3p0$p+)7qXD}C#8B~TU*Uz9-;-OQplgY%WU*Y<8yW`Nw* ztvJx(7R$>|kPq(XCr}a=V-Mh??DHLQp#F~WXGY^y@lY9}-&NDuX>c|3)B-D4`W`?bLM ze0%y0v$LL)5#)Mld?KLP;OoWUCK-I|>z}dQal}&XK540Q|HfB&y?}6L`k3%0;T>yv zqiZk`^F1~EEYbP>Hf_6L+wJvD`2IL-8z6&Q`vnaCwLO@sa%%c_NEWlU6cBma8vFV; zhW{=9TMI=2Q!Wq?CyKSDlH%Xt+gsgnU966_sCcvKp!0noGvq!m)X{dM_(_lKl{`ML zz?=przV6V+-j85*$z1a(&iK&{!-sr-kfKB_nk9F>%x8jP-qcdHVb+l%D0#jOW3 zuO|D~`Rwkhz&&KXjuFG#@$70IOTD)Av()!P&M}SBH;rb;>a{0~rt)X!C$uK!Wn^d2 z)@jF?6Q{^9ew6IgPRkXo)>yvp*Uiq3#Vl^0sIBLnajq4);-K;tg`ja&X8&5+UGFv@ zXCO~T%`wiC+1PZ=v(zg(&TTLLV@$Ez=p|9x9c#lzYV)U!FTUnFPoU_H9zVhY?)41+ zKJX>>^=zK!Z|wH&nLO74x*DdO>wIWj=99VR-cU4At9>`Orjr#P*FG1Sl|?c`mjpo< zo~D)UAr(CRa;0wHiY%J7nweY1Ps0E-(3O&Y0aF-IbRP<%FU8=CN~Y3+}6I_AE;N1kHdytIC!8I$)MOT5*$Ff4nUq`WO7xqKtv^I zac_n zghok1CqX}Rp?4f1;7>z9G}l*Nw=|bKTA$;0NuYt;m5-h~i8*xFEcX zf{CnC2jtH*HK_v+uCi=SFk%ScQv~fYMe8Hbzx}32-Tvd$&lbIpfHTaN6Q05VtH}gm zAX#8?fXh0KG^l8Zt3r2G)5s&=sSV#tJI&{0xl5vE1Lj$L^DNGhlDFi-VUb1BiozDE zt{f?}{XzDy!o*D(9Ba-H*kCSDD>Nr-jM3`uJ?}V{Bc#ptCt=bWIJ*<;@D0^=Opz&= z73SSkn@7;+UCiT&g3o@8e<5;?zo967QF&4UGtj66Nsx}Nyb%ZS{0y+cO6+;!)rzZh zb$xDmo)ZJ=x20IK|L2UIf9*k^8&Y1PkezV>A4Z#5+LeRb3`3GKiRV}%h>YlWB0G&K znvj(g~6gg5-xh1y-$Z+>5k3#ROS}hD%l8Q*Ca*^;V zP9?8)WIB9F28!Ko{KM*lKQC|L;GpK4p?(iD}uXKhd)z4)@ANJ%Rpfe624Q?;+?}VTyT!`FB zh6avMR?#^9U@ApAhP=S7JF^&SZw`8V@W8PC^r|~g)S!Z##**n2$L|B}>^9D_eWz2A z;DxxidLW0NmmiVvzd}h{8Zc%ZW~(%DXR!D~dYCE!BtR@qm^rM=(pBl|>6o!*5Yd0= zA(cY?Kxt4W%q1B6(Pvhh69v0iRcXhZJ}6r(mO7-+_+>IB@6aw65WQ51k>(iecwG<- zdEUKR13XCXRn8p3IVkmn!`ZHi#!<#7*6_e7uH9?yvNv*I%J4%xYh0MoY7%v)6Ytn@WwqkS##f(pmkQRQTPotOyfsolDI zoH@fx-0L_qtbz-Ng(9@W3)W9dZx2TLzySgbb*u*_KOLG3Zu*#SrLgSI6{=%$T& zGBDC%jy_dtJObf*sEep!LSBJJ*A_Y)I4boMrHUKxsRWfl0~J9F#C4BempYZ>gC6HG zaPO0&8oD8K*9eVKP7-WXMp;zALq;IxA&aX$q%@Z?%t>dI3z8shUE15vLBod%GWK$d z8RRA^O58_+%=8t_VUhjupa}nfy*I%z?IP!I3WvV1pS2a?>M^YzzooMr6@Okq3qzGg zgvg@9&zvR|hi<4w^Lu%HPKz{%Png_5rOtrcJXDA@SY|nV8V)m72`xjJT@zu*fy5## z_oJtnPW4U>SPTgn93uN8z_Ku~P2#$NKDe%;qn&gR_9w{e05$Kn-z`-EJmr#rc7ZjZm5%+K+$0nk+2qp0=70n z*KjA%Uq;gqx4FnPqob~|uw)8oP<~*9z|mhxR5U zVf&>nRpCZMlI2Dxt>1JHRv}(RUV{y1(bFn9Qb*Xr+|xfmV}Tl!80_EuZ1HO@`L9Xq ztn90-7&d=)W-2+xw8|aQqxOaMh1DfE#ysQ36|AXwy7N>3bpr&1E;Wg-}O1}xd z7}$aBstpo{Q}A@TMA|HgB8WPHj%Dx4tK%4Sbx}pBlP2u&IrUu~yg0?*^40&x zLRpdcA@s3AVF3uAbb3ifS}k`e5gb*c`>T|~+-~A8a?WRRF_)sv++Sir%6!3>DMDGo z^Xbf`-Rf|{hQzWo&;V=Nr zn2pj%n&l4 z7nc#M*4xv{J{-muF=|sS;3ZHu(i25G{OWJCVzoG@B{H>309t3@Q%f%lxe515Yh;J) zu4GR;Ek2b1oO9B)KhwZDB}98Q@Jl{k`wMTyHT5!N=~vox0q61B1BzSd!9psY#@GG zZe|l%AIXS&^}m(s3}qy66lH7RQ7Y!4nu7J%0(`>6>6}dRwi?mJL&LnuINr~oXN*9Y zv4M5+O&R&M6wWRMdXi7l?*8rQNHezBAX3LdjNPUS-w8xrVesU3rEA4Ex}qa%ftHZI z2z7}ifF0j{DnhE^$*qO7F3Z@ojG_?%UHP9ai1hV9XoQ(|@8UyG9s-t3xsBMli->EA zv<<6N-fmJm+`Y3FF8%zU9Gz&rGori5o86Ex4m z#*OzJuM%P;X(EwPX}i>$H3l8+!8O zPNvNqMa@(pl_T{3bVdAW1>s}lv@Jf>6ApAELgtXd=iAim3Hyvf7jHa1OAfy5cYEKZb5xNGug8HeO3d zQHFa=LONM?T5_p;nR2OFc6n?yk!-ZMnk>4auH0dp4?KK~(ok4EPzdXg1bzx~s5PGa zV_I*`^|j%ld0|~{jmqWYRBaAkvJ#1w=XrUfG;K-Z(nQVIN8W@Z$31CTXzcNv?koAA zFH|qnrZk~oCcUzGIC)lbrbK5hJ*IsejD*b1TGTA3P2wh1W`~;(dO5AYt~lIH9h9M= zXjo=Uo@rgo!lBf%it}BdmJ{E+82@>w!uB29xNDyS2YAJR?~=bUWC$R|hKLn$Ey5tT zYQ8c;M$As>uv(9~ku9o5^OFzewY6NgRYU&@{Bono%ogVEr65fy(IBz5ELbZp6X7Zq zB*gR&cFt5m!}N!)b$p=nwxBvzqFK#T$U6RasK-6`iRYC_$36Eyo2fZ2k)lm`_42;5<-4oy=zW@+X{v4`!WOrp0aMZbCi`%sxUb>?%bkd3dq zN*XF(ak51&MuZ*)WRH2?Xoi!jBRTMIqh573XdVWF-^l(rEVFTtwA;$%pjP@8M}Y&W zqOQwsvuL5%rlIFsYnY!aQa=*S$jD9`aS5#IU~*jy1mLFw9)cQ;A|%wOH8(%7m!eX_ zcri}Bh0z|ASCT1OPGnTj)7)#gy6O|SnVQLHUqvJ*sIFn(R3ozZjo6)KTCNp4S)Lkc zy>w>VMF!b7xKnTT$y2_j?7SLJo?UMC(Z>qFO#Lbcq4`tBJiE6&;oiFxnZa$axj4Nf z7g^OYaDEtwexpXS{-m=1z=#%J#S1|AFOqq-a=HARhZ7=zGI+I6LpkiaNsR?mb|3$_IdbL zMw5tmTJr-UC_4E&vAya;)9SZodh_pLwX*ERTXKnrw(2d0@VvLFLz&NCUU0LA59$y^>q;w3Kbpl?)VJ@ghPh|kZbpS4H^9efA=kDg%ZT5 z_m~2@FNbmka;P7&XDy+=cH}{xM${!_um5bh#r@Ng<7qwLxy*oWQUrO*pc;+Nzwx#9 zU0cTdJVr8qg~MzqM(>*Q`YqKzV|WLmdH=#~@w1kn5Y+(g>uG2qs>X}vQp9JS(2Y0c-@_;Da z_>?sMjfD(u!v0Sz*Yr%rDRoF58;&;}`hqua$KZPGDI50pXuBpM5b48B9+P8dr7d$fF1Cw} z8b=7OkP@ActcTP)PHa) zh*l9#QNy%H^JFtDQNF}Ek8je4(9$;PAHaN7b}64@&E?l*z%47Yo^EXlx>oc>=Q{IP zJ1(f0^IqucCa?U_mNMbBsk-Soke^&rTa!H3=gdc8lB+q76o!woaMpK18a%r0iWlh9~H4UlZ(wTb_fOd3I&a zeW(vODu!Mvt*jGvrK3!z6>$7Hrr&einFh5%VIaoa48F#DD8a9HzN#pcX>BYq(rv$K3=G z*NbGL>DO9c!&S&hXtB_IxRWu&o4)@n|rxLAb zVy-ZwW{8!J0QQ_%2T=hZu+Oo-w7Tqd8EG2(bZeL)BOounsv}Sg*jM@ddS;p7?n`1> zH1pPGd^T1+hw!a(K2|z*K$WvgjZCMHWga7m;~v~SsaY6ie1!Yzv$HsJx}Ba=Tn~Hn zhw@z4aLqT>p-&Tm0@~JcipG-wcveO~!-&{~j+tL3MJ@VU)LMk}3~1tz=!=)A&e-yV zMNHI6E&7dhy8XfaN?bR^o-4|@wkzH!lsWX|rvRr1f7}PxmGSsh>=o7Q{g&gWEZ|kO z?m^{ByT5+lZFEX|@g+k`aX)T6^6kmEVo=`6_|iMs-%g8ibVF&0Lmp0Cg!9fZ9xK&X z<)O9Da}+=&lwYxQut|eINcLBw2w$`)%Ng5Vl^lw_VCx@#;q$$s7>_@vJj7P^ zpT(sGn;E-kE92R3f)d^Mef7RYvm!!!nlpeo!*T@1;Wgvd&!`b7%AvFR%-auxZ&MLW z=@3sQ_M;-jLu2musLrXdMeLaq>P3^Ol+;h1#g-r`9s4vszw`ZyRCj_ybZ$^mlM$<1 zF-z>JuSkv)tjOREqaL!ntJv<-zPW9zKE6+NKr_TU_ubqC0Xk{L zn{{}DN`PyqHt*1M$uBTVczVxPk|!OaKH&{GtYxM!d#5&D#%S?3v) zy2L=yk#@`8Pf-B{?$#SYx&n^V>zp8a&1c1<)o&O{(O1O!zU|!TO8&FgxryaK^fB7Z z$E3SEQ)UpY0=RGfTla@Za(ECxHGj}R48fu5fd8tmvMJmk6QxD0Ji{09XNQ`_tHL%^ z^wuvgI^v`z)L)Z%1e&Inp`+xaH%a@u){H-Twi9>xzg-?Ou(`=EynMio!xM*;P} zU(&t^t4Z2&!uRg=wyeD@olDyXN-?DMHi;r=)CPSxo6I%^pQL}OK|GS(Rxa21U@60S zCbk+mYv7&*RVF^7uy{Yid|OeEi|uh}-Da8?*YIfaXH{l`e~Wl?bARDRA$aFv4y2GA zyD2@IO=w=sek2AAGkV>0oR70FYrq_%nM*TPI|{vOR7@d#`esyYsk9U~EoLPwD3?uV zDToY{c+-!ZwQ*zh%0?WehiN!9G&P{t3eBa%HiTP|_q>mH8$OM;g%|MxM9@=H=Fwtm+ zCh_sII4vNqqLc^-LiWX$U|PQMnPmCkH5`i03>wtDjX8Nc(Jv5X$0ki?uwTR!gF~qf z37cnPy`GBf36A*2(fR;wxCV8 zMN-WVr2VjyF7;%lHNC4y8Lywo8j1YLdaVQA*|O^XT%O+R=6Uc=q^#q$uQ7Zi?i=8o zupjNn=>lSV5t|)zF~?#7yf$#-7*9Gb*=+7ak)G02`Zkh-MEqg2ZO@T!?W+35`15@H zz}+CyT%fY&X)DvKf@_m20Kl%YY!%w(R_|)x{n5iTevR$X z#L0=ZFFh>rSE$J3R?s!l53e6|NxOe1?o4O+vgl=esZP^&wM;pKFE>`X{mrBQB~Jg( z3BSWyr$!AnpWn{k*JKXv1v=FTHbM5H$~R9h4$SW#%ZmEO_}K<^+kBc09cibto?xWK z0f$;6+Z?z$G!P*uUV&S^Q0V=j9`U=Z{$6&0()fF{9V2#q-JrLzkWZozZX2?;Fz}B~E-|`sBTv`24iM?;*z}EN$dCmG zKLV1KQZE7UCoA)U7T-ofDFICO_G{Zk5ePE7AmP4FW;!%G`&Rnz4L2(ShA=F(euqFY zkdL)q8bB0yQOYirwL>YKx>yYx9A~@s374Q2Q#Ww5GPnH9-OD_=h925;Z91+QO;63I zn%_4T_VlT4Fpo)xve6+{#tqZWPBE|H+gv1}pZ!E;Tf6drs#65l7;-ZVN_hD*G`W{A zLTIZN-ySr#lkZ%EN;L2xCM@0$OiAsMn~RliCOW=uU15hz`|C}>{n0x+7V zXM|L{?LP$wP1^#h-^S={nUP}0@NRV8pwj8cmh1aWSZws~+I}hH> z2ToJy^iu9rg{JjVhJ8?*BiB|&!i@FzUJWIQ-Ia+0ko4Ki(bD7s`5+N--+V zeu-o4m0DJsn(E{#v$u`rqK1fFRx-mS*m|*soo;g>#Cc^Jw$^qN4wsp!B-=(h|r2}6dM;_f<7mn;_!3G zC*Fn!81vCfwP?r$_v5dKSw8;>O{Volr)epREuU@8m7W(*v7arBYnYxeo%8OCr%sX4 zd{}@T?Y8z@j9@4MwuUxrCHEWnl7PeHsbAeD93V%x`q?nTNrxDP24#Bb9ku2E5DIC&jHrx z-YO@n?r|$m*S;!V%=!$Ry7St>FV?0zC{6Iq4>i!Fkf7+4Q+(_O3^OzFchD>vSgn`B z*jHIhMrN*)%#L$_JM*rbaIaNXs`>JOlqRZ442Q`C%A3@^oBakQ0(OEv({!&$lEHo( zgVh3#)dp+-&e20?)>T@02EEj=#Clxsfa;7P`BwvG%n+)umCWHL@(5W`-eeHMfG z4DQYVQGyY)t{~E`(d4@$B#-zr{l-SJ)#kF3X}D(^{!?#(W1dqHt$<&iVgNP2_e&YZShVISw180q zdX9fsO5E&atp6j427&a`rN2SQ*dsYtN=Rmrq0PQ+N^r#BAC{IA3(yrnNt27er6E_i z$|pn?TE^oP^I|riW(|t#a>`%>%K%CUY`y=-OiJ*C9gogTw&VTlsGlLkm*PUZRG0u$ z;WKwLjochJI)Qf*=7W5o9Q#dNn>dTVkf}rpB55>-QT?F!G|TNIBu2m<#;OG5hzQ<< zqdnx42qfP+xmVsybG^cE?;_pC1QRwlCb91ZbGSwn)aatI_t)kP4Y{-dyMe+RW3ayE z&~K}-g~*QnBaS>bi;DiULENS$va;rJ!j;3<5F45fu<R zGbZ}q73HSdScif+fn z%ID|DM(3Gf;NMm<#gdCy_oT@>b z{tO0Ng$v)ts^hR0SqL*9rLi!}sDW$|K@SyDZpf+m)!KQ^{-pm_tr+ktOhPJNIzxQ^ z6Ce8_rH*W%gdRqe($jLNqAHybT z<2!`8SirVX#RHvSGh;UU)uwrMuX1!oJCfQm4WfUj#qCA4pWX#Jgf|Tz+Xi>9Cn_<^ zXa2?`u+PJ)XPB^+TE#F|6S$IF)tgeMa68OJHq_WvTE5Upn~-c}9vC9<}1Y7Y`YCH#ShW z)rU{VbPSC?mxzZ{4B(l}S7%Wmc4;-}W}Yb&v!WrT>2$a%YZXvcpkjA_bRi(pj$H1K z6hn{^I`V}sU`hQwS{d8`rdz~$YU=vREl{bnu+T7w}sPW0zE;5DTFpF$7 zr}A*|z?|Ir@(r2tg|sNP!P(u8D(Nl37*Og(S_Gy#Dj6MxrjEqODVaVN>AfX)&AUFsP)ti_ zBNf^(A)P5J?IcoNOFu{N*z4m5Zk4!Hg&Fq?l^Gv4Rwc(y8x2|sG@OS`spLrSqkd(Z z1_6r!X_Te5c=t3TtUTqoqNq2qt2U+DgzLzZwGL~QIHZQ_C3Mcf76S}h+(`wM>)EZ> z?AM$q-9(yxsw#(56$YLs3PMNV0i+8Y6J#U;V`*g_>wljNj z3~kZuN=xoxzKyAFzaj`T%5~^9Xr%>fXB+FpUGv$69QHrNyA(KoGg1v+ZEQ2Ub&^q+ z*5B*H;?XnwI255U*%Jp4W&3blotQ2>8bcq5=Zs&kMxdV@!i`dv6Ti4@o+wcPsNps! z`>S}j2sg^|M(sWO2sb6U3WR5Pc4jaox<#x7%B3ib(!5HMT#xs8@JFhe^3JTqsk?_a zrYYGwVYS8)lyX#9q$y?DQz%JLU(Dx(HYXwv#c|EmN+-unS$!F7+OUV^6KkRd+Q08{Nd0)w~N4W7yKUvOb|eAkq32Nhf(W;3oeEyoP9`^~9DRCa@BE`7) z#rFlITG^4ZiLNaUNy*0C@pNENq9<;0Kc(@RB*76@>M-6?h$*ECm()xNluM|PCtN6|-W z0`jm{gab=uoE6+?@KuT+9S}@;Do^%1`hO{ALi%8V35!5`@J#T5O

p5*~u;z*9ox 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 ibF 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 Hu0mjfC2(P& literal 0 HcmV?d00001 diff --git a/src/cfml/system/config/server-icons/trayicon-railo.png b/src/cfml/system/config/server-icons/trayicon-railo.png new file mode 100644 index 0000000000000000000000000000000000000000..c4fdae9c4c3a59195ef5078492fa0f94b41ff88f GIT binary patch literal 157380 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 q5E@bWiFL2i)5xV}9g-u(DtJazWmbj5 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 literal 0 HcmV?d00001 diff --git a/src/cfml/system/services/CommandService.cfc b/src/cfml/system/services/CommandService.cfc index 3c128c5e4..4af3e1a83 100644 --- a/src/cfml/system/services/CommandService.cfc +++ b/src/cfml/system/services/CommandService.cfc @@ -299,13 +299,19 @@ component accessors="true" singleton { if( len( result ) ){ shell.printString( result & cr ); } - // Now, where were we? + // This is a little hacky, but basically if there are more commands in the chain that need to run, + // just print an exception and move on. Otherwise, throw so we can unwrap the call stack all the way + // back up. That is neccessary for command expressions that fail like "echo `cat noExists.txt`" + // since in that case I don't want to execute the "echo" command since the "cat" failed. if( arrayLen( commandChain ) > i && listFindNoCase( '||,;', commandChain[ i+1 ].originalLine ) ) { + // These are "expected" exceptions like validation errors that can be "pretty" if( e.type == 'commandException' ) { shell.printError( { message : e.message, detail: e.detail } ); + // These are catastrophic errors that warrant a full stack trace. } else { - shell.printError( e ); + shell.printError( e ); } + // Unwind the stack and cancell all commands in the chain. } else { // Clean up a bit instance.callStack.clear(); diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index b32f898ee..ef4f38244 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -118,7 +118,7 @@ component accessors="true" singleton { openBrowser : d.openBrowser ?: true, stopsocket : d.stopsocket ?: 0, debug : d.debug ?: false, - trayicon : d.trayicon ?: '#variables.libdir#/trayicon.png', + trayicon : d.trayicon ?: '', jvm : { heapSize : d.jvm.heapSize ?: 512, args : d.jvm.args ?: '' @@ -344,7 +344,7 @@ component accessors="true" singleton { CFEngineName = serverinfo.cfengine contains 'lucee' ? 'lucee' : CFEngineName; CFEngineName = serverinfo.cfengine contains 'railo' ? 'railo' : CFEngineName; CFEngineName = serverinfo.cfengine contains 'adobe' ? 'adobe' : CFEngineName; - + // As long as there's no WAR Path, let's install the engine to use. if( serverInfo.WARPath == '' ){ try { @@ -372,11 +372,36 @@ component accessors="true" singleton { serverInfo.webConfigDir = installDetails.installDir; serverInfo.logdir = serverInfo.webConfigDir & "/logs"; } - } - - // This is due to a bug in RunWar not creating the right directory for the logs - directoryCreate( serverInfo.logDir, true, true ); - + + // Find the correct tray icon for this server + if( !len( serverInfo.trayIcon ) ) { + if( serverInfo.cfengine contains "lucee" ) { + serverInfo.trayIcon = '/commandbox/system/config/server-icons/trayicon-lucee.png'; + } else if( serverInfo.cfengine contains "railo" ) { + serverInfo.trayIcon = '/commandbox/system/config/server-icons/trayicon-railo.png'; + } else if( serverInfo.cfengine contains "adobe" ) { + + if( listFirst( installDetails.version, '.' ) == 9 ) { + serverInfo.trayIcon = '/commandbox/system/config/server-icons/trayicon-cf09.png'; + } else if( listFirst( installDetails.version, '.' ) == 10 ) { + serverInfo.trayIcon = '/commandbox/system/config/server-icons/trayicon-cf10.png'; + } else if( listFirst( installDetails.version, '.' ) == 11 ) { + serverInfo.trayIcon = '/commandbox/system/config/server-icons/trayicon-cf11.png'; + } else if( listFirst( installDetails.version, '.' ) == 2016 ) { + serverInfo.trayIcon = '/commandbox/system/config/server-icons/trayicon-cf2016.png'; + } else { + serverInfo.trayIcon = '/commandbox/system/config/server-icons/trayicon-cf2016.png'; + } + + } + } + + } + + // Default tray icon + serverInfo.trayIcon = ( len( serverInfo.trayIcon ) ? serverInfo.trayIcon : '#variables.libdir#/trayicon.png' ); + serverInfo.trayIcon = expandPath( serverInfo.trayIcon ); + // Guess the proper set of tray icons based on the cfengine name. var trayConfigJSON = '#libdir#/traymenu-default.json'; if( serverInfo.cfengine contains "lucee" ) { @@ -385,7 +410,11 @@ component accessors="true" singleton { trayConfigJSON = '#libdir#/traymenu-railo.json'; } else if( serverInfo.cfengine contains "adobe" ) { trayConfigJSON = '#libdir#/traymenu-adobe.json'; - } + } + + // This is due to a bug in RunWar not creating the right directory for the logs + directoryCreate( serverInfo.logDir, true, true ); + // The java arguments to execute: Shared server, custom web configs var args = " #serverInfo.JVMargs# -Xmx#serverInfo.heapSize#m -Xms#serverInfo.heapSize#m" From 1baa5f40f1b00106e00a0da08a4ea550a7f5431f Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 24 May 2016 17:35:33 -0500 Subject: [PATCH 106/129] COMMANDBOX-387 --- .../modules/coldbox-commands/commands/coldbox/create/module.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/module.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/module.cfc index db35fd580..3209d123b 100644 --- a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/module.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/module.cfc @@ -30,7 +30,7 @@ component { cfmapping=arguments.name, modelNamespace=arguments.name, dependencies="", - directory='modules', + directory='modules_app', boolean script=true ){ // This will make each directory canonical and absolute From 9d8bc5f129dea4d52788d67d19b28a4b86f9d968 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 24 May 2016 17:49:43 -0500 Subject: [PATCH 107/129] Removing extra whitespace. --- .../modules/package-commands/interceptors/packageScripts.cfc | 1 - src/cfml/system/services/PackageService.cfc | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc b/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc index a7800689c..ce9d19750 100644 --- a/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc +++ b/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc @@ -34,7 +34,6 @@ component { function postPublish() { processScripts( 'postPublish' ); } function processScripts( required string interceptionPoint, string directory=shell.pwd() ) { - consoleLogger.debug( "." ); packageService.runScript( arguments.interceptionPoint, arguments.directory ); } diff --git a/src/cfml/system/services/PackageService.cfc b/src/cfml/system/services/PackageService.cfc index ac179fe2a..5ebdcffc5 100644 --- a/src/cfml/system/services/PackageService.cfc +++ b/src/cfml/system/services/PackageService.cfc @@ -1021,6 +1021,7 @@ component accessors="true" singleton { if( boxJSON.keyExists( 'scripts' ) && isStruct( boxJSON.scripts ) && boxJSON.scripts.keyExists( arguments.scriptName ) ) { var thisScript = boxJSON.scripts[ arguments.scriptName ]; + consoleLogger.debug( '.' ); consoleLogger.warn( 'Running package script [#arguments.scriptName#].' ); consoleLogger.debug( '> ' & thisScript ); From d82e5e31f1687ee86d11455af5b400cd511f04be Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 24 May 2016 20:50:19 -0500 Subject: [PATCH 108/129] COMMANDBOX-379 Add windows sized icons' --- .../config/server-icons/trayicon-cf09-32px.png | Bin 0 -> 1184 bytes .../config/server-icons/trayicon-cf10-32px.png | Bin 0 -> 1340 bytes .../config/server-icons/trayicon-cf11-32px.png | Bin 0 -> 1494 bytes .../config/server-icons/trayicon-cf2016-32px.png | Bin 0 -> 1141 bytes .../config/server-icons/trayicon-lucee-32px.png | Bin 0 -> 1641 bytes .../config/server-icons/trayicon-railo-32px.png | Bin 0 -> 1144 bytes src/cfml/system/services/ServerService.cfc | 15 ++++++++------- 7 files changed, 8 insertions(+), 7 deletions(-) create mode 100644 src/cfml/system/config/server-icons/trayicon-cf09-32px.png create mode 100644 src/cfml/system/config/server-icons/trayicon-cf10-32px.png create mode 100644 src/cfml/system/config/server-icons/trayicon-cf11-32px.png create mode 100644 src/cfml/system/config/server-icons/trayicon-cf2016-32px.png create mode 100644 src/cfml/system/config/server-icons/trayicon-lucee-32px.png create mode 100644 src/cfml/system/config/server-icons/trayicon-railo-32px.png diff --git a/src/cfml/system/config/server-icons/trayicon-cf09-32px.png b/src/cfml/system/config/server-icons/trayicon-cf09-32px.png new file mode 100644 index 0000000000000000000000000000000000000000..288a9e704b01038404025e5c7ff717ef306a88dd GIT binary patch literal 1184 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 literal 0 HcmV?d00001 diff --git a/src/cfml/system/config/server-icons/trayicon-cf11-32px.png b/src/cfml/system/config/server-icons/trayicon-cf11-32px.png new file mode 100644 index 0000000000000000000000000000000000000000..49453f2be1493f71801e6a22dc31cfa44aa18eb2 GIT binary patch literal 1494 zcmV;{1u6Q8P) zK~#9!#FuMKTtyUs&+=%IZs}6GiwNOSN}(;GCD5{Jny!f&YFbN;(U!(Ysz!d8h%x+W znz))Y#3+i}Bsd;r}VFw)UEvaoBimYo0Z_S4<2T!wQ?&()$<~Ev+{3e~dBF zXDCs7YI+{}2Pder8AUSyK0b3~SvC#GR25XL6|5Pu?Xi+x2cSZcH>2Un#h%C;*HFjUDq}!d2dm+JKdZD`5u2Ee}`uKr&p_1`LKvMhLj^ zjt*D(n9CXv2FJE{WD*+Bc0tF_e?i}^F_@m2hm_<5IJkcc?0>QVe7^#)IYKP)dTM%3`9+vSyBzR{>Kb$!6J$U`oLAqZ53=G{F*K`Tq)-fm#6b|Q0x2OTe zy0Q@X@#7a^3TI5^!CmRFb5|y;F|UF@dPX2IF&^E_V8o{zx8AZEo;$h&Hs)C(!fEV? z21J6>|5GPh1^msra@ba66>DBn0r*~4*65+8&vV~r5 zP7;(qoC&tngk|Bv02)Y77Qy>me#z&Z5(XM@YNy?|1}duxg$CMm5WlL1@4!qvhtO2t{|>pHNbk8WE1`&5DbxowgVEypO6* zJaRq@+TI7tM#ljfy8wzuK5DjO*U6wIP^CO?z$xIi6mGz5w^~zd`)L6DzL|*dZ<_m` zM|do%okq#xV~?VoLwOygfzRBt;RQzl))X`z?TUdnBKGZfM|HS3P*edr|3x=^a^{L2 zh-tXqhYN9^TXlocbLTGf9h=;}^=W*(T>?9uB^eE&>+QUJs{*TiC_mzJmoT8IsVX9z zYB~k$>srBm`L-A+8MECz32`W~eIyeTb1hQDQ<;k9 zD$Z*MUyiI8IS&L~yF%goYG&w~AS}DhpqsOoqN5jXN`C`Ec_0+dBEUgPSTV7t)Ci1< zB@NKGq47;nA)N(x2dBU5EUU`-IvR!YaScK&OV~gGdW9z?${T&+G`t%)m5q7Hg?w)t zC6UKOqy%I^Azj)Db<%q-?JVeMAJia-0qxStBVPMSYaV)+2wZHlSq|Ud$H8>ayod5K z!sz)sC{J)`Hh23mln?3LB2QpUI5h*_s&D_dADER7><+xNHp6nB59;6tO*PLCEj-%E zwiW59EOa3Fk0Jvwx)ynw$S^xk507*qoM6N<$f<6qik^lez literal 0 HcmV?d00001 diff --git a/src/cfml/system/config/server-icons/trayicon-cf2016-32px.png b/src/cfml/system/config/server-icons/trayicon-cf2016-32px.png new file mode 100644 index 0000000000000000000000000000000000000000..f88a75888789cd22678cc55e13f8cbe6b8a44805 GIT binary patch literal 1141 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 nqN0Jt1}HP)=)syqof(IE+&GaA> zl=L8odZ>a24}&-lLs4u&WQTRjWCua9osKz?xps3_=hphY@Ws8QNt+t|;Nzu9n&0pH z`@Uz%<#NP~OkCLQg~g9QQ=sDdD+5WR|F@VS0N@c=+B6=;C@CP4`fmgPoP*^>fmhO? zo?;|y20*At8XpQ3;aE)we-*pC~0>jlFEm~tv4ek?sBA{BcnM;4~W$#>}qnfo}RRhBdvdA3oh3DAT|6ay@) zZ6pin&oT(Tb~beoYuQrgeZ3vfB9T`aOG1FmPU*VKzLHe7UY7y0KW2$@-$_z_qB{?q z$_nqnLN*AxWe6l9S|nufK$tAw=p(aF!({$Tf@Cu@aD7A8g~>!IQL8T6iZRng<>iXw zUBtfQF!}X1Mkeo{)%4D~&e&qWAD$zbk>`a-RM75f(*X})CzQc$RW&j=mAOP*HxXI+ z`L2H&mLdGs>A9$^3_SYJU7pPhYO4XZX;A4BHRd zML&mqrj5-3IRxnLh+Y?TY-k{^wwv;GHj^SVy;tQbke_YdOYF4=veWMe`@)tz1FYv% z@`wThk>rvx{M1?R#r|JjC}3+&-z7G8egn*A(z&6bR~?V-+s~+gM=^&|%$`8KAoBI@ z5KADb!&tNa9b5K8*{%AM4=LgZ-l=T5%oso$P6$9E>i_fcF&cs+pf8o@lz^F;EPTr^ zQp=hdt2wlmS0&#)Y~g-fIUtd;nwbZC8--^KIKlWU`9!q_bSIr95IBh&R1{UNf|y2` z&IC#3{GdA%78Tk?b;j*t6BWlyO59%)U}TuN{wCLde9Wce9c9{% zVW?@&4VxvvHXAoKG(jsg7=H?U4X@?7z|_$Ut&$Kpjf8^O_b-C(!YZTEk83-2&0)wF zuf^=)6iBc~G#ZjYW}t~NuliJ>YXt(Y&4z&1cN78B7}pliZuEkWQKh$ZV+mVLpN=)+ z%rmFuGy+Y~T^qCtbQ^|Ap!>i-C7>e0G23ra*#iJH?~M3cfB^tJCYR*|1A}D%0000< KMNUMnLSTZIeFSR& literal 0 HcmV?d00001 diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index ef4f38244..259ee08d8 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -375,22 +375,23 @@ component accessors="true" singleton { // Find the correct tray icon for this server if( !len( serverInfo.trayIcon ) ) { + var iconSize = fileSystemUtil.isWindows() ? '-32px' : ''; if( serverInfo.cfengine contains "lucee" ) { - serverInfo.trayIcon = '/commandbox/system/config/server-icons/trayicon-lucee.png'; + serverInfo.trayIcon = '/commandbox/system/config/server-icons/trayicon-lucee#iconSize#.png'; } else if( serverInfo.cfengine contains "railo" ) { - serverInfo.trayIcon = '/commandbox/system/config/server-icons/trayicon-railo.png'; + serverInfo.trayIcon = '/commandbox/system/config/server-icons/trayicon-railo#iconSize#.png'; } else if( serverInfo.cfengine contains "adobe" ) { if( listFirst( installDetails.version, '.' ) == 9 ) { - serverInfo.trayIcon = '/commandbox/system/config/server-icons/trayicon-cf09.png'; + serverInfo.trayIcon = '/commandbox/system/config/server-icons/trayicon-cf09#iconSize#.png'; } else if( listFirst( installDetails.version, '.' ) == 10 ) { - serverInfo.trayIcon = '/commandbox/system/config/server-icons/trayicon-cf10.png'; + serverInfo.trayIcon = '/commandbox/system/config/server-icons/trayicon-cf10#iconSize#.png'; } else if( listFirst( installDetails.version, '.' ) == 11 ) { - serverInfo.trayIcon = '/commandbox/system/config/server-icons/trayicon-cf11.png'; + serverInfo.trayIcon = '/commandbox/system/config/server-icons/trayicon-cf11#iconSize#.png'; } else if( listFirst( installDetails.version, '.' ) == 2016 ) { - serverInfo.trayIcon = '/commandbox/system/config/server-icons/trayicon-cf2016.png'; + serverInfo.trayIcon = '/commandbox/system/config/server-icons/trayicon-cf2016#iconSize#.png'; } else { - serverInfo.trayIcon = '/commandbox/system/config/server-icons/trayicon-cf2016.png'; + serverInfo.trayIcon = '/commandbox/system/config/server-icons/trayicon-cf2016#iconSize#.png'; } } From 855b28cac4aa5ce0aa3af99c920df5c5f477bdf6 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 25 May 2016 11:38:20 -0500 Subject: [PATCH 109/129] Added additional help keywords ? and /? --- src/cfml/system/services/CommandService.cfc | 147 ++++++++++---------- 1 file changed, 74 insertions(+), 73 deletions(-) diff --git a/src/cfml/system/services/CommandService.cfc b/src/cfml/system/services/CommandService.cfc index 4af3e1a83..7f58d6aea 100644 --- a/src/cfml/system/services/CommandService.cfc +++ b/src/cfml/system/services/CommandService.cfc @@ -20,9 +20,9 @@ component accessors="true" singleton { property name='commandLocations' inject='commandLocations@constants'; property name='interceptorService' inject='interceptorService'; property name='stringDistance' inject='StringDistance'; - + property name='configured' default="false" type="boolean"; - + // TODO: Convert these to properties instance = { // A nested struct of the registered commands @@ -52,13 +52,13 @@ component accessors="true" singleton { wirebox.registerNewInstance( name='commandbox.system.BaseCommand', instancePath='commandbox.system.BaseCommand' ) .setAutowire( false ); } - + // map commands for( var commandLocation in commandLocations ){ - + // Ensure location exists if( !directoryExists( expandPath( commandLocation ) ) ){ - directoryCreate( expandPath( commandLocation ) ); + directoryCreate( expandPath( commandLocation ) ); } // Load up any commands initCommands( commandLocation, commandLocation ); @@ -74,16 +74,16 @@ component accessors="true" singleton { * @commandDirectory.hint The current directory we've recursed into * @commandPath.hint The dot-delimted path so far-- only used when recursing **/ - CommandService function initCommands( - required string baseCommandDirectory, - required string commandDirectory, - string commandPath='' + CommandService function initCommands( + required string baseCommandDirectory, + required string commandDirectory, + string commandPath='' ){ - var varDirs = DirectoryList( - path = arguments.commandDirectory, - recurse = false, - listInfo = 'query', - sort = 'type desc, name asc' + var varDirs = DirectoryList( + path = arguments.commandDirectory, + recurse = false, + listInfo = 'query', + sort = 'type desc, name asc' ); for( var dir in varDirs ){ // For CFC files, process them as a command @@ -119,16 +119,16 @@ component accessors="true" singleton { * @line.hint line to run **/ function runCommandline( required string line ){ - + if( left( arguments.line, 4 ) == 'box ' && len( arguments.line ) > 4 ) { consoleLogger.warn( "Removing extra text [box ] from start of command. You don't need that here." ); arguments.line = right( arguments.line, len( arguments.line ) - 4 ); } - + // Resolve the command they are wanting to run var commandChain = resolveCommand( line ); - - return runCommand( commandChain, line ); + + return runCommand( commandChain, line ); } /** @@ -137,17 +137,17 @@ component accessors="true" singleton { * @piped.hint Data to pipe in to the first command **/ function runCommandTokens( required array tokens, string piped ){ - + // Resolve the command they are wanting to run var commandChain = resolveCommandTokens( tokens ); - + // If there was piped input if( structKeyExists( arguments, 'piped' ) ) { return runCommand( commandChain, tokens.toList( ' ' ), arguments.piped ); } - + return runCommand( commandChain, tokens.toList( ' ' ) ); - + } /** @@ -155,11 +155,11 @@ component accessors="true" singleton { * @commandChain.hint the chain of commands to run **/ function runCommand( required array commandChain, required string line, string piped ){ - + if( structKeyExists( arguments, 'piped' ) ) { var result = arguments.piped; } - + // If nothing is returned, something bad happened (like an error instatiating the CFC) if( !commandChain.len() ){ return 'Command not run.'; @@ -174,21 +174,21 @@ component accessors="true" singleton { // Would result in three separate, chained commands. for( var commandInfo in commandChain ){ i++; - + // If we've reached a command separator like "foo | bar" or "baz && bum", make note of it and continue if( listFindNoCase( ';,|,||,&&', commandInfo.originalLine ) ) { previousCommandSeparator = commandInfo.originalLine; continue; } - + if( previousCommandSeparator == '&&' && lastCommandErrored ) { return result ?: ''; } - + if( previousCommandSeparator == '||' && !lastCommandErrored ) { return result ?: ''; } - + // If nothing was found, bail out here. if( !commandInfo.found ){ @@ -256,7 +256,7 @@ component accessors="true" singleton { if( arrayLen( parameterInfo.positionalParameters ) ){ parameterInfo.namedParameters = convertToNamedParameters( parameterInfo.positionalParameters, commandParams ); } - + // Merge flags into named params mergeFlagParameters( parameterInfo ); @@ -265,10 +265,10 @@ component accessors="true" singleton { // Ensure supplied params match the correct type validateParams( parameterInfo.namedParameters, commandParams ); - + // Evaluate parameter expressions evaluateExpressions( parameterInfo ); - + // Reset the printBuffer commandInfo.commandReference.CFC.reset(); @@ -293,7 +293,7 @@ component accessors="true" singleton { lastCommandErrored = commandInfo.commandReference.CFC.hasError(); } catch( any e ){ lastCommandErrored = true; - + // Dump out anything the command had printed so far var result = commandInfo.commandReference.CFC.getResult(); if( len( result ) ){ @@ -315,10 +315,10 @@ component accessors="true" singleton { } else { // Clean up a bit instance.callStack.clear(); - rethrow; + rethrow; } } - + // Successful command execution resets exit code to 0 shell.setExitCode( 0 ); @@ -351,7 +351,7 @@ component accessors="true" singleton { var matchedSoFar = lcase( listChangeDelims( arguments.commandInfo.commandString, ' ', '.' ) ); var originalLine = arguments.commandInfo.originalLine; var candidates = []; - + for( var option in allCommands ) { // If we matched a partial command, only consider commands starting with that match if( len( matchedSoFar ) && !option.startsWith( matchedSoFar ) ) { @@ -365,11 +365,11 @@ component accessors="true" singleton { // Try to ignore params if( listLen( option, ' ' ) < listLen( originalLine, ' ' ) ) { thisOriginalLine = originalLine.listToArray( ' ' ).slice( 1, listLen( option, ' ' ) ).toList( ' ' ); - + } var comparison = stringDistance.stringSimilarity( option, thisOriginalLine, 2 ); if( comparison.similarity > .80 ) { - candidates.append( ' ' & option ); + candidates.append( ' ' & option ); } } @@ -380,7 +380,7 @@ component accessors="true" singleton { helpText &= '#chr( 10 )#Please type "#trim( "help #matchedSoFar#" )#" for assistance.'; return helpText; } - + /** * Evaluates any expressions as a command string and puts the output in its place. @@ -389,23 +389,23 @@ component accessors="true" singleton { // For each parameter being passed into this command for( var paramName in parameterInfo.namedParameters ) { - + var paramValue = parameterInfo.namedParameters[ paramName ]; // Look for an expression "foo" flagged as "__expression__foo__expression__" var search = reFindNoCase( '__expression__.*?__expression__', paramValue, 1, true ); - + // As long as there are more expressions while( search.pos[1] ) { // Extract them var expression = mid( paramValue, search.pos[1], search.len[1] ); // Evaluate them var result = runCommandline( mid( expression, 15, len( expression )-28 ) ) ?: ''; - + // Clean off trailing any CR to help with piping one-liner outputs as inputs to another command if( result.endsWith( chr( 10 ) ) && len( result ) > 1 ){ result = left( result, len( result ) - 1 ); } - + // And stick their results in their place parameterInfo.namedParameters[ paramName ] = replaceNoCase( paramValue, expression, result, 'one' ); paramValue = parameterInfo.namedParameters[ paramName ]; @@ -430,7 +430,7 @@ component accessors="true" singleton { function resolveCommand( required string line ){ // Turn the users input into an array of tokens var tokens = parser.tokenizeInput( line ); - + return resolveCommandTokens( tokens ); } @@ -482,6 +482,7 @@ component accessors="true" singleton { // command hierarchy var cmds = getCommandHierarchy(); + var helpTokens = 'help,?,/?'; for( var commandTokens in commandsToResolve ){ @@ -490,12 +491,12 @@ component accessors="true" singleton { // If command ends with "help", switch it around to call the root help command // Ex. "coldbox help" becomes "help coldbox" // Don't do this if we're already in a help command or endless recursion will ensue. - if( tokens.len() > 1 && tokens.last() == 'help' && !inCommand( 'help' ) ){ + if( tokens.len() > 1 && listFindNoCase( helpTokens, tokens.last() ) && !inCommand( 'help' ) ){ // Move help to the beginning tokens.deleteAt( tokens.len() ); tokens.prepend( 'help' ); } - + // If the first token looks like a drive letter, then it's just a Windows user trying to "cd" to a different drive // A drive letter for these purposes will be defined as up to 3 letters folowed by a colon and an optional slash. if( tokens.len() && reFind( '^[a-z,A-Z]{1,3}:[\\,/]?$', tokens[1] ) ){ @@ -507,7 +508,7 @@ component accessors="true" singleton { // This is the droid you're looking for tokens = [ 'cd', drive ]; } - + // Shortcut for "run" command if first token starts with ! if( tokens.len() && len( tokens[1] ) > 1 && tokens[1].startsWith( '!' ) ) { // Trim the ! off @@ -515,11 +516,11 @@ component accessors="true" singleton { // tack on "run" tokens.prepend( 'run' ); } - + /* If command is "run", merge all remaining tokens into one string - * + * * run cmd /c dir - * would essentially be turned into + * would essentially be turned into * run "cmd /c dir" */ if( tokens.len() > 2 && tokens.first() == 'run' ) { @@ -533,12 +534,12 @@ component accessors="true" singleton { if( tokens.len() && len( tokens[1] ) > 1 && tokens[1].startsWith( '##' ) ) { // Trim the # off tokens[1] = right( tokens[1], len( tokens[1] ) - 1 ); - + // If it looks like we have named params, convert the "name" to be named if( tokens.len() > 1 && tokens[2] contains '=' ) { tokens[1] = 'name=' & tokens[1]; } - + // tack on "cfml" tokens.prepend( 'cfml' ); } @@ -566,13 +567,13 @@ component accessors="true" singleton { // If we've reached a command, we're done if( structKeyExists( results.commandReference, '$' ) ){ results.found = true; - + // Actual command data stored in a nested struct results.commandReference = results.commandReference[ '$' ]; - + // Create the command CFC instance if neccessary lazyLoadCommandCFC( results.commandReference ); - + break; // If this is a folder, check and see if it has a "help" command } else { @@ -590,7 +591,7 @@ component accessors="true" singleton { if( results.found && commandLength < tokensLength ){ results.parameters = tokens.slice( commandLength+1 ); } - + commandChain.append( results ); } // end loop over commands to resolve @@ -605,12 +606,12 @@ component accessors="true" singleton { * @commandData.hint Struct created by registerCommand() **/ private function lazyLoadCommandCFC( commandData ){ - + // Check for actual CFC instance, and lazy load if neccessary if( !structKeyExists( commandData, 'CFC' ) ){ // Create this command CFC try { - + // Check if command mapped? if( NOT wirebox.getBinder().mappingExists( "command-" & commandData.fullCFCPath ) ){ // feed this command to wirebox with virtual inheritance @@ -621,7 +622,7 @@ component accessors="true" singleton { } // retrieve, build and wire from wirebox commandData.CFC = wireBox.getInstance( "command-" & commandData.fullCFCPath ); - + // This will catch nasty parse errors so the shell can keep loading } catch( any e ){ // Log the full exception with stack trace @@ -629,9 +630,9 @@ component accessors="true" singleton { throw( message='Error creating command [#commandData.fullCFCPath#]', detail="#e.message# #CR# #e.detail ?: ''# #CR# #e.stacktrace#", type="commandException"); } } // CFC exists check - return true; + return true; } - + /** * Looks at the call stack to determine if we're currently "inside" a command. * Useful to prevent endless recursion. @@ -692,8 +693,8 @@ component accessors="true" singleton { var commandName = iif( len( commandPath ), de( commandPath & '.' ), '' ) & CFCName; // Build CFC's path var fullCFCPath = baseCommandDirectory & '.' & commandName; - - + + try { // Create a nice struct of command metadata var commandData = createCommandData( fullCFCPath, commandName ); @@ -728,8 +729,8 @@ component accessors="true" singleton { */ private struct function createCommandData( required fullCFCPath, required commandName ){ // Get Command MD? - var commandMD = getComponentMetadata( arguments.fullCFCPath ); - + var commandMD = getComponentMetadata( arguments.fullCFCPath ); + // Set up of command data var commandData = { fullCFCPath = arguments.fullCFCPath, @@ -760,10 +761,10 @@ component accessors="true" singleton { commandData.completor[ param.name ][ 'optionsUDF' ] = param.optionsUDF; } } - + break; } - } + } } else { commandData.parameters = []; } @@ -777,7 +778,7 @@ component accessors="true" singleton { */ function isCommandCFC( required struct commandData ){ var meta = arguments.commandData.commandMD; - + // Make sure command has a run() method for( var func in meta.functions ){ // Loop to find the "run()" method @@ -785,7 +786,7 @@ component accessors="true" singleton { return true; } } - + // Didn't find run() method return false; } @@ -810,17 +811,17 @@ component accessors="true" singleton { // Is this a boolean value if( structKeyExists( param, "type" ) and param.type == "boolean" ){ return shell.confirm( message & "(Yes/No)" ); - } + } // Strings else { - // If the param name contains the word "password", then mask the input. + // If the param name contains the word "password", then mask the input. return shell.ask( message, ( param.name contains 'password' ? '*' : '' ) ); } }; // Ask for value value = askValue(); - + // value entered matches the type! userNamedParams[ param.name ] = value; } @@ -842,7 +843,7 @@ component accessors="true" singleton { && !isValid( param.type, userNamedParams[ param.name ] ) ){ throw( message='Parameter [#param.name#] has a value of [#userNamedParams[ param.name ]#] which is not of type [#param.type#].', type="commandException"); - } + } } // end for loop return true; @@ -877,5 +878,5 @@ component accessors="true" singleton { // Add flags into named params arguments.parameterInfo.namedParameters.append( arguments.parameterInfo.flags ); } - + } \ No newline at end of file From 8f3d39af3d488da40cf13d1d8b17e327310a59ce Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 25 May 2016 23:19:54 -0500 Subject: [PATCH 110/129] Always show version on server tray icon --- src/cfml/system/services/ServerService.cfc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 259ee08d8..de17ff6a9 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -332,9 +332,6 @@ component accessors="true" singleton { // log directory location if( !directoryExists( serverInfo.logDir ) ){ directoryCreate( serverInfo.logDir ); } - // The process native name - var processName = ( serverInfo.name is "" ? "CommandBox" : serverInfo.name ) & ' [' & serverinfo.cfengine & ']'; - // Default java agent for embedded Lucee engine var javaagent = serverinfo.cfengine contains 'lucee' ? '-javaagent:"#libdir#/lucee-inst.jar"' : ''; @@ -344,12 +341,15 @@ component accessors="true" singleton { CFEngineName = serverinfo.cfengine contains 'lucee' ? 'lucee' : CFEngineName; CFEngineName = serverinfo.cfengine contains 'railo' ? 'railo' : CFEngineName; CFEngineName = serverinfo.cfengine contains 'adobe' ? 'adobe' : CFEngineName; + + var thisVersion = ''; // As long as there's no WAR Path, let's install the engine to use. if( serverInfo.WARPath == '' ){ try { // This will install the engine war to start, possibly downloading it first var installDetails = serverEngineService.install( cfengine=serverInfo.cfengine, basedirectory=serverInfo.webConfigDir ); + thisVersion = ' ' & installDetails.version; serverInfo.logdir = installDetails.installDir & "/logs"; // Not sure we need this ultimatley, but errors were really ugly when getting this up and running. @@ -372,7 +372,10 @@ component accessors="true" singleton { serverInfo.webConfigDir = installDetails.installDir; serverInfo.logdir = serverInfo.webConfigDir & "/logs"; } - + + // The process native name + var processName = ( serverInfo.name is "" ? "CommandBox" : serverInfo.name ) & ' [' & serverinfo.cfengine & thisVersion & ']'; + // Find the correct tray icon for this server if( !len( serverInfo.trayIcon ) ) { var iconSize = fileSystemUtil.isWindows() ? '-32px' : ''; From 50869afda37551ee9d5961d005cb2925187aaab1 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 25 May 2016 23:39:55 -0500 Subject: [PATCH 111/129] bump timeouts --- 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 de17ff6a9..981dcfb6c 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -431,7 +431,7 @@ component accessors="true" singleton { & " --server-name ""#serverInfo.name#""" & " --tray-icon ""#serverInfo.trayIcon#"" --tray-config ""#trayConfigJSON#""" & " --directoryindex ""#serverInfo.directoryBrowsing#"" --cfml-web-config ""#serverInfo.webConfigDir#""" - & " --cfml-server-config ""#serverInfo.serverConfigDir#"" #serverInfo.runwarArgs# "; + & " --cfml-server-config ""#serverInfo.serverConfigDir#"" #serverInfo.runwarArgs# --timeout 120"; // Starting a WAR systemOutput( serverinfo.WARPath, true ); @@ -486,7 +486,7 @@ component accessors="true" singleton { // save server info and persist serverInfo.statusInfo = { command:variables.javaCommand, arguments:attributes.args, result:'' }; setServerInfo( serverInfo ); - execute name=variables.javaCommand arguments=attributes.args timeout="50" variable="executeResult" errorVariable="executeError"; + execute name=variables.javaCommand arguments=attributes.args timeout="120" variable="executeResult" errorVariable="executeError"; serverInfo.status="running"; } catch (any e) { logger.error( "Error starting server: #e.message# #e.detail#", arguments ); From 6132e2db50a571586870beb75f7e39732642598f Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 26 May 2016 11:06:23 -0500 Subject: [PATCH 112/129] Account for LuceeServlet in Lucee 5 --- .../system/services/ServerEngineService.cfc | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/cfml/system/services/ServerEngineService.cfc b/src/cfml/system/services/ServerEngineService.cfc index e52f470be..4eb6374db 100644 --- a/src/cfml/system/services/ServerEngineService.cfc +++ b/src/cfml/system/services/ServerEngineService.cfc @@ -70,7 +70,7 @@ component accessors="true" singleton="true" { var installDetails = installEngineArchive( 'lucee-cf-engine@#version#', destination ); if( !installDetails.internal ) { - configureWebXML( cfengine="lucee", source="#installDetails.installDir#/WEB-INF/web.xml", destination="#installDetails.installDir#/WEB-INF/web.xml" ); } + configureWebXML( cfengine="lucee", version=installDetails.version, source="#installDetails.installDir#/WEB-INF/web.xml", destination="#installDetails.installDir#/WEB-INF/web.xml" ); } return installDetails; } @@ -82,7 +82,7 @@ component accessors="true" singleton="true" { **/ public function installRailo( required destination, required version ) { var installDetails = installEngineArchive( 'railo-cf-engine@#version#', destination ); - configureWebXML( cfengine="railo", source="#installDetails.installDir#/WEB-INF/web.xml", destination="#installDetails.installDir#/WEB-INF/web.xml" ); + configureWebXML( cfengine="railo", version=installDetails.version, source="#installDetails.installDir#/WEB-INF/web.xml", destination="#installDetails.installDir#/WEB-INF/web.xml" ); return installDetails; } @@ -179,7 +179,7 @@ component accessors="true" singleton="true" { * @source source web.xml * @destination target web.xml **/ - public function configureWebXML( required cfengine, required source, destination ) { + public function configureWebXML( required cfengine, required version, required source, destination ) { var webXML = XMLParse( source ); var servlets = xmlSearch(webXML,"//:servlet-class[text()='#lcase( cfengine )#.loader.servlet.CFMLServlet']"); var initParam = xmlElemnew(webXML,"http://java.sun.com/xml/ns/javaee","init-param"); @@ -188,6 +188,18 @@ component accessors="true" singleton="true" { initParam.XmlChildren[2] = xmlElemnew(webXML,"param-value"); initParam.XmlChildren[2].XmlText = "/WEB-INF/#lcase( cfengine )#/{web-context-label}"; arrayInsertAt(servlets[1].XmlParent.XmlChildren,4,initParam); + + // Lucee 5+ has a LuceeServlet as well as will create the WEB-INF by default in your web root + if( arguments.cfengine == 'lucee' && val( listFirst( arguments.version, '.' )) >= 5 ) { + var servlets = xmlSearch(webXML,"//:servlet-class[text()='#lcase( cfengine )#.loader.servlet.LuceeServlet']"); + var initParam = xmlElemnew(webXML,"http://java.sun.com/xml/ns/javaee","init-param"); + initParam.XmlChildren[1] = xmlElemnew(webXML,"param-name"); + initParam.XmlChildren[1].XmlText = "#lcase( cfengine )#-web-directory"; + initParam.XmlChildren[2] = xmlElemnew(webXML,"param-value"); + initParam.XmlChildren[2].XmlText = "/WEB-INF/#lcase( cfengine )#/{web-context-label}"; + arrayInsertAt(servlets[1].XmlParent.XmlChildren,4,initParam); + } + var xlt = ' From 0bc3f808a8190f93e430e1c6b043e236b3783434 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 26 May 2016 16:01:22 -0500 Subject: [PATCH 113/129] COMMANDBOX-389 --- .../modules/coldbox-commands/commands/coldbox/create/model.cfc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/model.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/model.cfc index eb6e50256..fdf4aa389 100644 --- a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/model.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/model.cfc @@ -134,6 +134,8 @@ component { // Loop Over methods to generate them for( var thisMethod in listToArray( arguments.methods ) ) { + if( thisMethod == 'init' ) { continue; } + thisMethod = trim( thisMethod ); allMethods = allMethods & replaceNoCase( modelMethodContent, '|method|', thisMethod, 'all' ) & cr & cr; From 3a352ab3aa55622a3ca94f869702f5a7d80e15df Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 31 May 2016 21:15:04 -0500 Subject: [PATCH 114/129] Add slug auto-complete for start command --- .../server-commands/commands/server/start.cfc | 19 +++++++++++++++++-- .../system/services/ServerEngineService.cfc | 7 ------- src/cfml/system/services/ServerService.cfc | 9 +-------- src/cfml/system/util/ForgeBox.cfc | 6 +++--- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/cfml/system/modules/server-commands/commands/server/start.cfc b/src/cfml/system/modules/server-commands/commands/server/start.cfc index 20b25ce4d..5ca819717 100644 --- a/src/cfml/system/modules/server-commands/commands/server/start.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/start.cfc @@ -43,6 +43,7 @@ component aliases="start" { // DI property name="serverService" inject="ServerService"; + property name="forgeBox" inject="ForgeBox"; /** * @name short name for this server` @@ -134,8 +135,22 @@ component aliases="start" { /** * Complete cfengine names */ - function cfengineNameComplete() { - return serverService.getCFEngineNames(); + function cfengineNameComplete( string paramSoFar ) { + + try { + // Get auto-complete options + return forgebox.slugSearch( arguments.paramSoFar, 'cf-engines' ); + } catch( forgebox var e ) { + // Gracefully handle ForgeBox issues + print + .line() + .yellowLine( e.message & chr( 10 ) & e.detail ) + .toConsole(); + // After outputting the message above on a new line, but the user back where they started. + getShell().getReader().redrawLine(); + } + // In case of error, break glass. + return []; } } diff --git a/src/cfml/system/services/ServerEngineService.cfc b/src/cfml/system/services/ServerEngineService.cfc index 4eb6374db..d975297d0 100644 --- a/src/cfml/system/services/ServerEngineService.cfc +++ b/src/cfml/system/services/ServerEngineService.cfc @@ -209,11 +209,4 @@ component accessors="true" singleton="true" { return true; } - /** - * Dynamic completion for cfengine - */ - function getCFEngineNames() { - return [ "lucee","adobe","railo" ]; - } - } \ No newline at end of file diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 981dcfb6c..fbbbc6e44 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -374,7 +374,7 @@ component accessors="true" singleton { } // The process native name - var processName = ( serverInfo.name is "" ? "CommandBox" : serverInfo.name ) & ' [' & serverinfo.cfengine & thisVersion & ']'; + var processName = ( serverInfo.name is "" ? "CommandBox" : serverInfo.name ) & ' [' & listFirst( serverinfo.cfengine, '@' ) & thisVersion & ']'; // Find the correct tray icon for this server if( !len( serverInfo.trayIcon ) ) { @@ -837,13 +837,6 @@ component accessors="true" singleton { } fileWrite( filePath, formatterUtil.formatJSON( serializeJSON( arguments.data ) ) ); } - - /** - * Dynamic completion for cfengine - */ - function getCFEngineNames() { - return serverEngineService.getCFEngineNames(); - } /** * Dynamic completion for property name based on contents of server.json diff --git a/src/cfml/system/util/ForgeBox.cfc b/src/cfml/system/util/ForgeBox.cfc index 0ed022860..ebbacead7 100644 --- a/src/cfml/system/util/ForgeBox.cfc +++ b/src/cfml/system/util/ForgeBox.cfc @@ -313,11 +313,11 @@ or just add DEBUG to the root logger /** * Autocomplete for slugs */ - function slugSearch( required string searchTerm ) { + function slugSearch( required string searchTerm, string typeSlug = '' ) { var thisResource = "slugs/#arguments.searchTerm#"; - - var results = makeRequest( resource=thisResource, method='get' ); + + var results = makeRequest( resource=thisResource, method='get', parameters={ typeSlug : arguments.typeSlug } ); // error if( results.error ){ From 15e9bbfaa42986fe0ba2e4b7199d091b9654a737 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 31 May 2016 21:51:03 -0500 Subject: [PATCH 115/129] Renamed colbox create controller to handler by default and aliased the controller command --- .../create/{controller.cfc => handler.cfc} | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) rename src/cfml/system/modules/coldbox-commands/commands/coldbox/create/{controller.cfc => handler.cfc} (88%) diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/controller.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/handler.cfc similarity index 88% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/controller.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/handler.cfc index 46e27ea86..7cc71e197 100644 --- a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/controller.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/handler.cfc @@ -1,17 +1,17 @@ /** -* Create a new controller (handler) in an existing ColdBox application. Make sure you are running this command in the root +* Create a new handler (controller) in an existing ColdBox application. Make sure you are running this command in the root * of your app for it to find the correct folder. You can optionally create the views as well as the integration tests for your -* new handler at the same time. By default, your new controller will be created in /handlers but you can override that with the directory param. +* new handler at the same time. By default, your new handler will be created in /handlers but you can override that with the directory param. * . * {code:bash} -* coldbox create controller myController index,foo,bar --open +* coldbox create handler myHandler index,foo,bar --open * {code} * **/ -component aliases='coldbox create handler' { +component aliases='coldbox create controller' { /** - * @name.hint Name of the controller to create without the .cfc. For packages, specify name as 'myPackage/myController' + * @name.hint Name of the handler to create without the .cfc. For packages, specify name as 'myPackage/myHandler' * @actions.hint A comma-delimited list of actions to generate * @views.hint Generate a view for each action * @viewsDirectory.hint The directory where your views are stored. Only used if views is set to true. @@ -20,10 +20,10 @@ component aliases='coldbox create handler' { * @testsDirectory.hint Your integration tests directory. Only used if integrationTests is true * @directory.hint The base directory to create your handler in and creates the directory if it does not exist. Defaults to 'handlers'. * @script.hint Generate content in script markup or tag markup - * @description.hint The controller hint description - * @open.hint Open the controller once generated + * @description.hint The handler hint description + * @open.hint Open the handler once generated **/ - function run( + function run( required name, actions='', boolean views=true, @@ -69,7 +69,7 @@ component aliases='coldbox create handler' { handlerTestContent = replaceNoCase( handlerTestContent, '|appMapping|', arguments.appMapping, 'all' ); handlerTestContent = replaceNoCase( handlerTestContent, '|handlerName|', arguments.name, 'all' ); handlerContent = replaceNoCase( handlerContent, '|Description|', arguments.description, 'all'); - + // Handle Actions if passed if( len( arguments.actions ) ) { var allActions = ''; @@ -124,11 +124,11 @@ component aliases='coldbox create handler' { file action='write' file='#testPath#' mode ='777' output='#handlerTestContent#'; print.greenLine( 'Created #testPath#' ); // open file - if( arguments.open ){ openPath( testPath ); } + if( arguments.open ){ openPath( testPath ); } } // open file - if( arguments.open ){ openPath( handlerPath ); } + if( arguments.open ){ openPath( handlerPath ); } } } \ No newline at end of file From 2a3c14854471691adbe6456cce141bf0df22da1e Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 31 May 2016 23:20:58 -0500 Subject: [PATCH 116/129] Removed unnecessary try/catch --- src/cfml/system/services/ServerService.cfc | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index fbbbc6e44..8536fc6a1 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -346,19 +346,12 @@ component accessors="true" singleton { // As long as there's no WAR Path, let's install the engine to use. if( serverInfo.WARPath == '' ){ - try { - // This will install the engine war to start, possibly downloading it first - var installDetails = serverEngineService.install( cfengine=serverInfo.cfengine, basedirectory=serverInfo.webConfigDir ); - thisVersion = ' ' & installDetails.version; - serverInfo.logdir = installDetails.installDir & "/logs"; - - // Not sure we need this ultimatley, but errors were really ugly when getting this up and running. - } catch (any e) { - logger.error( '#e.message# #e.detail#' , e.stackTrace ); - consoleLogger.error("Error installing server - " & e.message); - consoleLogger.error(e.detail.replaceAll(",","#chr(10)#")); - return; - } + + // This will install the engine war to start, possibly downloading it first + var installDetails = serverEngineService.install( cfengine=serverInfo.cfengine, basedirectory=serverInfo.webConfigDir ); + thisVersion = ' ' & installDetails.version; + serverInfo.logdir = installDetails.installDir & "/logs"; + // If external Lucee server, set the java agent if( !installDetails.internal && serverInfo.cfengine contains "lucee" ) { javaagent = "-javaagent:""#installDetails.installDir#/WEB-INF/lib/lucee-inst.jar"""; @@ -486,7 +479,8 @@ component accessors="true" singleton { // save server info and persist serverInfo.statusInfo = { command:variables.javaCommand, arguments:attributes.args, result:'' }; setServerInfo( serverInfo ); - execute name=variables.javaCommand arguments=attributes.args timeout="120" variable="executeResult" errorVariable="executeError"; + // Note this timeout is purposefully longer than the Runwar timeout so if the server takes too long, we get to capture the console info + execute name=variables.javaCommand arguments=attributes.args timeout="150" variable="executeResult" errorVariable="executeError"; serverInfo.status="running"; } catch (any e) { logger.error( "Error starting server: #e.message# #e.detail#", arguments ); From 317c36dc1de3d3df84af9b84f6633f86b7149ae0 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 31 May 2016 23:21:09 -0500 Subject: [PATCH 117/129] improve error message --- src/cfml/system/util/ForgeBox.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfml/system/util/ForgeBox.cfc b/src/cfml/system/util/ForgeBox.cfc index ebbacead7..7f42b4ea6 100644 --- a/src/cfml/system/util/ForgeBox.cfc +++ b/src/cfml/system/util/ForgeBox.cfc @@ -126,7 +126,7 @@ or just add DEBUG to the root logger // error if( results.error ){ - throw( "Error making ForgeBox REST Call", 'forgebox', results.response.messages.toList() ); + throw( "Error getting ForgeBox entry [#arguments.slug#]", 'forgebox', results.response.messages.toList() ); } return results.response.data; From e606138e867a54ec44d45d6c1325622434c731f6 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 31 May 2016 23:21:34 -0500 Subject: [PATCH 118/129] History display issue --- src/cfml/system/modules/system-commands/commands/history.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfml/system/modules/system-commands/commands/history.cfc b/src/cfml/system/modules/system-commands/commands/history.cfc index cd67da477..9dbecd64b 100644 --- a/src/cfml/system/modules/system-commands/commands/history.cfc +++ b/src/cfml/system/modules/system-commands/commands/history.cfc @@ -58,7 +58,7 @@ component { } else { var historyIterator = history.iterator(); while( historyIterator.hasNext() ) { - print.line( listLast( historyIterator.next(), ':' ) ); + print.line( listRest( historyIterator.next(), ':' ) ); } } // end clear? From a624e5b4f05ff70d10520f6e6dde2bc5d87cf983 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 1 Jun 2016 23:39:32 -0500 Subject: [PATCH 119/129] COMMANDBOX-392 --- .../system/services/ServerEngineService.cfc | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/cfml/system/services/ServerEngineService.cfc b/src/cfml/system/services/ServerEngineService.cfc index d975297d0..c96ab0643 100644 --- a/src/cfml/system/services/ServerEngineService.cfc +++ b/src/cfml/system/services/ServerEngineService.cfc @@ -54,7 +54,7 @@ component accessors="true" singleton="true" { // set flex log dir to prevent WEB-INF/cfform being created in project dir if (fileExists(installDetails.installDir & "/WEB-INF/cfform/flex-config.xml")) { var flexConfig = fileRead(installDetails.installDir & "/WEB-INF/cfform/flex-config.xml"); - flexConfig = replace(flexConfig, "/WEB-INF/", installDetails.installDir & "/WEB-INF","all"); + flexConfig = replace(flexConfig, "/WEB-INF/", installDetails.installDir & "/WEB-INF/","all"); fileWrite(installDetails.installDir & "/WEB-INF/cfform/flex-config.xml", flexConfig); } return installDetails; @@ -69,7 +69,7 @@ component accessors="true" singleton="true" { public function installLucee( required destination, required version ) { var installDetails = installEngineArchive( 'lucee-cf-engine@#version#', destination ); - if( !installDetails.internal ) { + if( !installDetails.internal && installDetails.initialInstall ) { configureWebXML( cfengine="lucee", version=installDetails.version, source="#installDetails.installDir#/WEB-INF/web.xml", destination="#installDetails.installDir#/WEB-INF/web.xml" ); } return installDetails; } @@ -81,8 +81,10 @@ component accessors="true" singleton="true" { * @version Version number or empty to use default **/ public function installRailo( required destination, required version ) { - var installDetails = installEngineArchive( 'railo-cf-engine@#version#', destination ); - configureWebXML( cfengine="railo", version=installDetails.version, source="#installDetails.installDir#/WEB-INF/web.xml", destination="#installDetails.installDir#/WEB-INF/web.xml" ); + var installDetails = installEngineArchive( 'railo-cf-engine@#version#', destination ); + if( installDetails.initialInstall ) { + configureWebXML( cfengine="railo", version=installDetails.version, source="#installDetails.installDir#/WEB-INF/web.xml", destination="#installDetails.installDir#/WEB-INF/web.xml" ); + } return installDetails; } @@ -101,7 +103,8 @@ component accessors="true" singleton="true" { var installDetails = { internal : false, version : '', - installDir : '' + installDir : '', + initialInstall : false }; var thisTempDir = tempDir & '/' & createUUID(); @@ -138,10 +141,11 @@ component accessors="true" singleton="true" { // Check to see if this WAR has already been exploded if( fileExists( installDetails.installDir & '/WEB-INF/web.xml' ) ) { consoleLogger.info( "WAR/zip archive already installed."); - return installDetails; + return installDetails; } // Install the engine via our standard package service + installDetails.initialInstall = true; packageService.installPackage( ID=arguments.ID, directory=thisTempDir, save=false ); // Look for a war or zip archive inside the package @@ -182,12 +186,14 @@ component accessors="true" singleton="true" { public function configureWebXML( required cfengine, required version, required source, destination ) { var webXML = XMLParse( source ); var servlets = xmlSearch(webXML,"//:servlet-class[text()='#lcase( cfengine )#.loader.servlet.CFMLServlet']"); + systemoutput( servlets, true ); var initParam = xmlElemnew(webXML,"http://java.sun.com/xml/ns/javaee","init-param"); initParam.XmlChildren[1] = xmlElemnew(webXML,"param-name"); initParam.XmlChildren[1].XmlText = "#lcase( cfengine )#-web-directory"; initParam.XmlChildren[2] = xmlElemnew(webXML,"param-value"); initParam.XmlChildren[2].XmlText = "/WEB-INF/#lcase( cfengine )#/{web-context-label}"; arrayInsertAt(servlets[1].XmlParent.XmlChildren,4,initParam); + systemoutput( servlets[1].XmlParent.XmlChildren, true ); // Lucee 5+ has a LuceeServlet as well as will create the WEB-INF by default in your web root if( arguments.cfengine == 'lucee' && val( listFirst( arguments.version, '.' )) >= 5 ) { From 0275c4752a5aa3b89af1b0125bc19521a448d6c9 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 2 Jun 2016 00:33:31 -0500 Subject: [PATCH 120/129] Update slug names --- src/cfml/system/services/ServerEngineService.cfc | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/cfml/system/services/ServerEngineService.cfc b/src/cfml/system/services/ServerEngineService.cfc index c96ab0643..555dc6117 100644 --- a/src/cfml/system/services/ServerEngineService.cfc +++ b/src/cfml/system/services/ServerEngineService.cfc @@ -47,7 +47,7 @@ component accessors="true" singleton="true" { * @version Version number or empty to use default **/ public function installAdobe( required destination, required version ) { - var installDetails = installEngineArchive( 'adobe-coldFusion-cf-engine@#version#', destination ); + var installDetails = installEngineArchive( 'adobe@#version#', destination ); // set password to "commandbox" // TODO: Just make this changes directly in the WAR files fileWrite( installDetails.installDir & "/WEB-INF/cfusion/lib/password.properties", "rdspassword=#cr#password=commandbox#cr#encrypted=false" ); @@ -67,7 +67,7 @@ component accessors="true" singleton="true" { * @version Version number or empty to use default **/ public function installLucee( required destination, required version ) { - var installDetails = installEngineArchive( 'lucee-cf-engine@#version#', destination ); + var installDetails = installEngineArchive( 'lucee@#version#', destination ); if( !installDetails.internal && installDetails.initialInstall ) { configureWebXML( cfengine="lucee", version=installDetails.version, source="#installDetails.installDir#/WEB-INF/web.xml", destination="#installDetails.installDir#/WEB-INF/web.xml" ); } @@ -81,7 +81,7 @@ component accessors="true" singleton="true" { * @version Version number or empty to use default **/ public function installRailo( required destination, required version ) { - var installDetails = installEngineArchive( 'railo-cf-engine@#version#', destination ); + var installDetails = installEngineArchive( 'railo@#version#', destination ); if( installDetails.initialInstall ) { configureWebXML( cfengine="railo", version=installDetails.version, source="#installDetails.installDir#/WEB-INF/web.xml", destination="#installDetails.installDir#/WEB-INF/web.xml" ); } @@ -133,7 +133,7 @@ component accessors="true" singleton="true" { } // If we're starting a Lucee server whose version matches the CLI engine, then don't download anyting, we're using internal jars. - if( listFirst( arguments.ID, '@' ) == 'lucee-cf-engine' && server.lucee.version == replace( installDetails.version, '+', '.', 'all' ) ) { + if( listFirst( arguments.ID, '@' ) == 'lucee' && server.lucee.version == replace( installDetails.version, '+', '.', 'all' ) ) { installDetails.internal = true; return installDetails; } @@ -186,14 +186,12 @@ component accessors="true" singleton="true" { public function configureWebXML( required cfengine, required version, required source, destination ) { var webXML = XMLParse( source ); var servlets = xmlSearch(webXML,"//:servlet-class[text()='#lcase( cfengine )#.loader.servlet.CFMLServlet']"); - systemoutput( servlets, true ); var initParam = xmlElemnew(webXML,"http://java.sun.com/xml/ns/javaee","init-param"); initParam.XmlChildren[1] = xmlElemnew(webXML,"param-name"); initParam.XmlChildren[1].XmlText = "#lcase( cfengine )#-web-directory"; initParam.XmlChildren[2] = xmlElemnew(webXML,"param-value"); initParam.XmlChildren[2].XmlText = "/WEB-INF/#lcase( cfengine )#/{web-context-label}"; arrayInsertAt(servlets[1].XmlParent.XmlChildren,4,initParam); - systemoutput( servlets[1].XmlParent.XmlChildren, true ); // Lucee 5+ has a LuceeServlet as well as will create the WEB-INF by default in your web root if( arguments.cfengine == 'lucee' && val( listFirst( arguments.version, '.' )) >= 5 ) { From fc9f0e25608beeb8db47f48ad7742f33e2d8b8e4 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 2 Jun 2016 12:06:40 -0500 Subject: [PATCH 121/129] partial changes --- .../server-commands/commands/server/start.cfc | 76 +++++++++++-------- src/cfml/system/services/ServerService.cfc | 38 ++++++---- 2 files changed, 68 insertions(+), 46 deletions(-) diff --git a/src/cfml/system/modules/server-commands/commands/server/start.cfc b/src/cfml/system/modules/server-commands/commands/server/start.cfc index 20b25ce4d..d0cb780e0 100644 --- a/src/cfml/system/modules/server-commands/commands/server/start.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/start.cfc @@ -45,36 +45,38 @@ component aliases="start" { property name="serverService" inject="ServerService"; /** - * @name short name for this server` - * @name.optionsUDF serverNameComplete - * @port port number - * @host bind to a host/ip - * @openbrowser open a browser after starting - * @directory web root for this server - * @stopPort stop socket listener port number - * @force force start if status is not stopped - * @debug sets debug log level - * @webConfigDir custom location for web context configuration - * @serverConfigDir custom location for server configuration - * @libDirs comma-separated list of extra lib directories for the server - * @trayIcon path to .png file for tray icon - * @webXML path to web.xml file used to configure the server - * @HTTPEnable enable HTTP - * @SSLEnable enable SSL - * @SSLPort SSL port number - * @SSLCert SSL certificate - * @SSLKey SSL key (required if SSLCert specified) - * @SSLKeyPass SSL key passphrase (required if SSLCert specified) - * @rewritesEnable enable URL rewriting (default false) - * @rewritesConfig optional URL rewriting config file path - * @heapSize The max heap size in megabytes you would like this server to start with, it defaults to 512mb - * @directoryBrowsing Enable/Disabled directory browsing, defaults to true - * @JVMArgs Additional JVM args to use when starting the server. Use "server status --verbose" to debug - * @runwarArgs Additional Runwar options to use when starting the server. Use "server status --verbose" to debug - * @saveSettings Save start settings in server.json - * @cfengine sets the cfml engine type + * @name short name for this server or a path to the server.json file. + * @name.optionsUDF serverNameComplete + * @port port number + * @host bind to a host/ip + * @openbrowser open a browser after starting + * @directory web root for this server + * @stopPort stop socket listener port number + * @force force start if status is not stopped + * @debug sets debug log level + * @webConfigDir custom location for web context configuration + * @serverConfigDir custom location for server configuration + * @libDirs comma-separated list of extra lib directories for the server + * @trayIcon path to .png file for tray icon + * @webXML path to web.xml file used to configure the server + * @HTTPEnable enable HTTP + * @SSLEnable enable SSL + * @SSLPort SSL port number + * @SSLCert SSL certificate + * @SSLKey SSL key (required if SSLCert specified) + * @SSLKeyPass SSL key passphrase (required if SSLCert specified) + * @rewritesEnable enable URL rewriting (default false) + * @rewritesConfig optional URL rewriting config file path + * @heapSize The max heap size in megabytes you would like this server to start with, it defaults to 512mb + * @directoryBrowsing Enable/Disabled directory browsing, defaults to true + * @JVMArgs Additional JVM args to use when starting the server. Use "server status --verbose" to debug + * @runwarArgs Additional Runwar options to use when starting the server. Use "server status --verbose" to debug + * @saveSettings Save start settings in server.json + * @cfengine sets the cfml engine type * @cfengine.optionsUDF cfengineNameComplete - * @WARPath sets the path to an existing war to use + * @WARPath sets the path to an existing war to use + * @serverConfigFile The path to the server.json file. Created if it doesn't exist. + **/ function run( String name, @@ -104,13 +106,20 @@ component aliases="start" { String runwarArgs, boolean saveSettings=true, String cfengine, - String WARPath + String WARPath, + String serverConfigFile='' ){ // Resolve path as used locally arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); if( !isNull( WARPath ) ) { arguments.WARPath = fileSystemUtil.resolvePath( arguments.WARPath ); } + if( len( serverConfigFile ) ) { + arguments.serverConfigFile = fileSystemUtil.resolvePath( arguments.serverConfigFile ); + if( !fileExists( arguments.serverConfigFile ) ) { + error( 'The serverConfigFile does not exist. [#arguments.serverConfigFile#]' ); + } + } // This is a common mis spelling if( structKeyExists( arguments, 'rewritesEnabled' ) ) { @@ -120,6 +129,13 @@ component aliases="start" { structDelete( arguments, 'rewritesEnabled' ); } + // As a convenient shorcut, allow the serverConfigFile to be passed via the name parameter. + var tmpName = arguments.name ?: ''; + var tmpNameResolved = fileSystemUtil.resolvePath( tmpName ); + if( !len( arguments.serverConfigFile ) && len( tmpName ) && fileExists( tmpNameResolved ) ) { + arguments.serverConfigFile = tmpNameResolved; + } + // startup the server return serverService.start( serverProps = arguments ); } diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 981dcfb6c..31dbb570b 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -172,6 +172,20 @@ component accessors="true" singleton { serverProps.name = listLast( serverProps.directory, "\/" ); } + if( !len( serverProps.serverConfigFile ) ) { + serverProps.serverConfigFile = serverProps.directory & "/server.json"; + } + + // Get server descriptor + var serverJSON = readServerJSON( serverProps.serverConfigFile ); + + if( len( serverJSON.web.wwwroot ?: '' ) ) { + serverProps.directory = fileSystemUtil.resolvePath( serverJSON.web.wwwroot, getDirectoryFromPath( serverProps.serverConfigFile ) ); + } + if( len( serverJSON.name ?: '' ) ) { + serverProps.name = serverJSON.name; + } + // Discover by shortname or server and get server info var serverInfo = getServerInfoByDiscovery( directory = serverProps.directory, @@ -186,8 +200,6 @@ component accessors="true" singleton { // Get package descriptor var boxJSON = packageService.readPackageDescriptor( serverInfo.webroot ); - // Get server descriptor - var serverJSON = readServerJSON( serverInfo.webroot , serverProps.name); // Get defaults var defaults = getDefaultServerJSON(); @@ -311,6 +323,10 @@ component accessors="true" singleton { serverInfo.logdir = serverInfo.webConfigDir & "/logs"; + + consoleLogger.info( "start server in - " & serverInfo.webroot ); + return; + if( !len( serverInfo.WARPath ) && !len( serverInfo.cfengine ) ) { serverInfo.cfengine = 'lucee@' & server.lucee.version; } @@ -812,13 +828,9 @@ component accessors="true" singleton { * Read a server.json file. If it doesn't exist, returns an empty struct * This only returns properties specifically set in the file. */ - struct function readServerJSON( required string directory , string name="") { - var defaultServerJSON = arguments.directory & '/server.json'; - var serverJSON = arguments.directory & '/server-#name#.json'; - if( fileExists( serverJSON ) ) { - return deserializeJSON( fileRead( serverJSON ) ); - } else if(fileExists( defaultServerJSON )) { - return deserializeJSON( fileRead( defaultServerJSON ) ); + struct function readServerJSON( required string path ) { + if( fileExists( path ) ) { + return deserializeJSON( fileRead( path ) ); } else { return {}; } @@ -829,12 +841,6 @@ component accessors="true" singleton { */ function saveServerJSON( required string directory, required struct data ) { var filePath = arguments.directory & '/server.json'; - if(fileExists(filePath)) { - var existingProps = readServerJSON(directory); - if(!isNull(data.name) && (isNull(existingProps.name) || existingProps.name != data.name)) { - filePath = arguments.directory & '/server-#data.name#.json'; - } - } fileWrite( filePath, formatterUtil.formatJSON( serializeJSON( arguments.data ) ) ); } @@ -852,7 +858,7 @@ component accessors="true" singleton { */ function completeProperty( required directory, all=false ) { // Get all config settings currently set - var props = JSONService.addProp( [], '', '', readServerJSON( arguments.directory ) ); + var props = JSONService.addProp( [], '', '', readServerJSON( arguments.directory & '/server.json' ) ); // If we want all possible options... if( arguments.all ) { From bb36f01f21d7ebf8b0c43fd5e7ddd3259e70c2b6 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 2 Jun 2016 12:26:47 -0500 Subject: [PATCH 122/129] COMMANDBOX-393 --- src/cfml/system/services/InterceptorService.cfc | 2 +- src/cfml/system/services/ServerService.cfc | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cfml/system/services/InterceptorService.cfc b/src/cfml/system/services/InterceptorService.cfc index 6fa1e99e8..b2a2dbcec 100644 --- a/src/cfml/system/services/InterceptorService.cfc +++ b/src/cfml/system/services/InterceptorService.cfc @@ -30,7 +30,7 @@ component accessors=true singleton { // Module lifecycle 'preModuleLoad','postModuleLoad','preModuleUnLoad','postModuleUnload', // Server lifecycle - 'onServerStart','onServerStop', + 'onServerStart','onServerInstall','onServerStop', // Error handling 'onException', // Package lifecycle diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 97749276d..00b6fccdf 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -359,12 +359,15 @@ component accessors="true" singleton { CFEngineName = serverinfo.cfengine contains 'adobe' ? 'adobe' : CFEngineName; var thisVersion = ''; + var processName = ( serverInfo.name is "" ? "CommandBox" : serverInfo.name ); // As long as there's no WAR Path, let's install the engine to use. if( serverInfo.WARPath == '' ){ // This will install the engine war to start, possibly downloading it first var installDetails = serverEngineService.install( cfengine=serverInfo.cfengine, basedirectory=serverInfo.webConfigDir ); + // This interception point can be used for additional configuration of the endine before it actually starts. + interceptorService.announceInterception( 'onServerInstall', { serverInfo=serverInfo, installDetails=installDetails } ); thisVersion = ' ' & installDetails.version; serverInfo.logdir = installDetails.installDir & "/logs"; From eaf2fb128343dd4f8ac70a045573aa40a10dc1a4 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 2 Jun 2016 17:25:13 -0500 Subject: [PATCH 123/129] COMMANDBOX-345 --- .../commands/coldbox/reinit.cfc | 2 +- .../server-commands/commands/server/clear.cfc | 28 +++++- .../commands/server/forget.cfc | 2 +- .../server-commands/commands/server/list.cfc | 34 +++---- .../server-commands/commands/server/set.cfc | 20 +++- .../server-commands/commands/server/show.cfc | 28 +++++- .../server-commands/commands/server/start.cfc | 20 ++-- src/cfml/system/services/ServerService.cfc | 94 +++++++++++++------ 8 files changed, 157 insertions(+), 71 deletions(-) diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/reinit.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/reinit.cfc index 2361a81a8..237f7b49c 100644 --- a/src/cfml/system/modules/coldbox-commands/commands/coldbox/reinit.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/reinit.cfc @@ -19,7 +19,7 @@ component aliases="fwreinit" { * @password.hint The FWReinit password **/ function run( password="1", name="" ){ - var serverInfo = serverService.getServerInfoByWebroot( getCWD(), arguments.name ); + var serverInfo = serverService.getServerInfoByDiscovery( getCWD(), arguments.name ); if( structCount( serverInfo ) eq 0 ){ print.boldRedLine( "No server configurations found for '#getCWD()#', so have no clue what to reinit buddy!" ); diff --git a/src/cfml/system/modules/server-commands/commands/server/clear.cfc b/src/cfml/system/modules/server-commands/commands/server/clear.cfc index ef456428b..042a9d188 100644 --- a/src/cfml/system/modules/server-commands/commands/server/clear.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/clear.cfc @@ -16,11 +16,31 @@ component { /** * @property.hint Name of the property to clear * @property.optionsUDF completeProperty + * @serverConfigFile The path to the server's JSON file. **/ - function run( required string property ) { - var directory = getCWD(); + function run( + required string property, + String serverConfigFile='' ) { + + // As a convenient shorcut, allow the serverConfigFile and propery parameter to be reversed because + // "server show foo.json name" reads better than "server show name foo.json" but maintains backwards compat + // for the simple use case of no JSON file as in "server show name" + var tmpPropertyResolved = fileSystemUtil.resolvePath( arguments.property ); + // Check if the property name end with ".json" and happens to exist as a file on disk, if so it's probably the property file + if( listLen( arguments.property, '.' ) > 1 && listLast( arguments.property, '.' ) == 'json' && fileExists( tmpPropertyResolved ) ) { + // If so, swap the property into the server config param. + arguments.property = arguments.serverConfigFile; + arguments.serverConfigFile = tmpPropertyResolved; + } else if( len( arguments.serverConfigFile ) ) { + arguments.serverConfigFile = fileSystemUtil.resolvePath( arguments.serverConfigFile ); + if( !fileExists( arguments.serverConfigFile ) ) { + error( 'The serverConfigFile does not exist. [#arguments.serverConfigFile#]' ); + } + } + // Default the server.json in the CWD + var thisServerConfigFile = ( len( arguments.serverConfigFile ) ? arguments.serverConfigFile : getCWD() & '/server.json' ); - var serverJSON = ServerService.readServerJSON( directory ); + var serverJSON = ServerService.readServerJSON( thisServerConfigFile ); try { JSONService.clear( serverJSON, arguments.property ); @@ -33,7 +53,7 @@ component { print.greenLine( 'Removed #arguments.property#' ); // Write the file back out. - ServerService.saveServerJSON( directory, serverJSON ); + ServerService.saveServerJSON( thisServerConfigFile, serverJSON ); } diff --git a/src/cfml/system/modules/server-commands/commands/server/forget.cfc b/src/cfml/system/modules/server-commands/commands/server/forget.cfc index d9871518a..fcd55f868 100644 --- a/src/cfml/system/modules/server-commands/commands/server/forget.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/forget.cfc @@ -31,7 +31,7 @@ component { // Discover by shortname or webroot arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); var serverInfo = serverService.getServerInfoByDiscovery( arguments.directory, arguments.name ); - + // Verify server info if( structIsEmpty( serverInfo ) AND arguments.all eq false ){ error( "The server you requested to forget was not found (webroot=#arguments.directory#, name=#arguments.name#)." ); diff --git a/src/cfml/system/modules/server-commands/commands/server/list.cfc b/src/cfml/system/modules/server-commands/commands/server/list.cfc index 4d53b5ab8..675257d4b 100644 --- a/src/cfml/system/modules/server-commands/commands/server/list.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/list.cfc @@ -84,22 +84,24 @@ component { if( arguments.verbose ) { - print.indentedLine( "host: " & thisServerInfo.host ) - .indentedLine( "HTTPEnable: " & thisServerInfo.HTTPEnable ) - .indentedLine( "port: " & thisServerInfo.port ) - .indentedLine( "SSLEnable: " & thisServerInfo.SSLEnable ) - .indentedLine( "SSLport: " & thisServerInfo.SSLport ) - .indentedLine( "rewritesEnable: " & ( thisServerInfo.rewritesEnable ?: "false" ) ) - .indentedLine( "stopsocket: " & thisServerInfo.stopsocket ) - .indentedLine( "logdir: " & thisServerInfo.logDir ) - .indentedLine( "debug: " & thisServerInfo.debug ) - .indentedLine( "ID: " & thisServerInfo.id ); - - if( len( thisServerInfo.libDirs ) ) { print.indentedLine( "libDirs: " & thisServerInfo.libDirs ); } - if( len( thisServerInfo.webConfigDir ) ) { print.indentedLine( "webConfigDir: " & thisServerInfo.webConfigDir ); } - if( len( thisServerInfo.serverConfigDir ) ) { print.indentedLine( "serverConfigDir: " & thisServerInfo.serverConfigDir ); } - if( len( thisServerInfo.webXML ) ) { print.indentedLine( "webXML: " & thisServerInfo.webXML ); } - if( len( thisServerInfo.trayicon ) ) { print.indentedLine( "trayicon: " & thisServerInfo.trayicon ); } + print.indentedLine( "host: " & thisServerInfo.host ) + .indentedLine( "webroot: " & thisServerInfo.webroot ) + .indentedLine( "HTTPEnable: " & thisServerInfo.HTTPEnable ) + .indentedLine( "port: " & thisServerInfo.port ) + .indentedLine( "SSLEnable: " & thisServerInfo.SSLEnable ) + .indentedLine( "SSLport: " & thisServerInfo.SSLport ) + .indentedLine( "rewritesEnable: " & ( thisServerInfo.rewritesEnable ?: "false" ) ) + .indentedLine( "stopsocket: " & thisServerInfo.stopsocket ) + .indentedLine( "logdir: " & thisServerInfo.logDir ) + .indentedLine( "debug: " & thisServerInfo.debug ) + .indentedLine( "ID: " & thisServerInfo.id ); + + if( len( thisServerInfo.libDirs ) ) { print.indentedLine( "libDirs: " & thisServerInfo.libDirs ); } + if( len( thisServerInfo.webConfigDir ) ) { print.indentedLine( "webConfigDir: " & thisServerInfo.webConfigDir ); } + if( len( thisServerInfo.serverConfigDir ) ) { print.indentedLine( "serverConfigDir: " & thisServerInfo.serverConfigDir ); } + if( len( thisServerInfo.webXML ) ) { print.indentedLine( "webXML: " & thisServerInfo.webXML ); } + if( len( thisServerInfo.trayicon ) ) { print.indentedLine( "trayicon: " & thisServerInfo.trayicon ); } + if( len( thisServerInfo.serverConfigFile ) ) { print.indentedLine( "serverConfigFile: " & thisServerInfo.serverConfigFile ); } } else { // Brief version diff --git a/src/cfml/system/modules/server-commands/commands/server/set.cfc b/src/cfml/system/modules/server-commands/commands/server/set.cfc index 3375a65fc..014e3907e 100644 --- a/src/cfml/system/modules/server-commands/commands/server/set.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/set.cfc @@ -47,23 +47,33 @@ component { * This param is a dummy param just to get the custom completor to work. * The actual parameter names will be whatever property name the user wants to set * @_.hint Pass any number of property names in followed by the value to set - * @_.optionsUDF completeProperty + * @_.optionsUDF completeProperty + * @serverConfigFile The path to the server's JSON file. * @append.hint If setting an array or struct, set to true to append instead of overwriting. **/ - function run( _, boolean append=false ) { + function run( + _, + String serverConfigFile='', + boolean append=false ) { + var thisAppend = arguments.append; - var directory = getCWD(); + + if( len( arguments.serverConfigFile ) ) { + arguments.serverConfigFile = fileSystemUtil.resolvePath( arguments.serverConfigFile ); + } + var thisServerConfigFile = ( len( arguments.serverConfigFile ) ? arguments.serverConfigFile : getCWD() & '/server.json' ); // Remove dummy args structDelete( arguments, '_' ); structDelete( arguments, 'append' ); + structDelete( arguments, 'serverConfigFile' ); - var serverJSON = ServerService.readServerJSON( directory ); + var serverJSON = ServerService.readServerJSON( thisServerConfigFile ); var results = JSONService.set( serverJSON, arguments, thisAppend ); // Write the file back out. - ServerService.saveServerJSON( directory, serverJSON ); + ServerService.saveServerJSON( thisServerConfigFile, serverJSON ); for( var message in results ) { print.greeLine( message ); diff --git a/src/cfml/system/modules/server-commands/commands/server/show.cfc b/src/cfml/system/modules/server-commands/commands/server/show.cfc index 54b6653ea..66b2cb45e 100644 --- a/src/cfml/system/modules/server-commands/commands/server/show.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/show.cfc @@ -27,12 +27,32 @@ component { /** * @property.hint The name of the property to show. Can nested to get "deep" properties * @property.optionsUDF completeProperty + * @serverConfigFile The path to the server's JSON file. **/ - function run( string property='' ) { - var directory = getCWD(); - + function run( + string property='', + String serverConfigFile='' ) { + + // As a convenient shorcut, allow the serverConfigFile and propery parameter to be reversed because + // "server show foo.json name" reads better than "server show name foo.json" but maintains backwards compat + // for the simple use case of no JSON file as in "server show name" + var tmpPropertyResolved = fileSystemUtil.resolvePath( arguments.property ); + // Check if the property name end with ".json" and happens to exist as a file on disk, if so it's probably the property file + if( listLen( arguments.property, '.' ) > 1 && listLast( arguments.property, '.' ) == 'json' && fileExists( tmpPropertyResolved ) ) { + // If so, swap the property into the server config param. + arguments.property = arguments.serverConfigFile; + arguments.serverConfigFile = tmpPropertyResolved; + } else if( len( arguments.serverConfigFile ) ) { + arguments.serverConfigFile = fileSystemUtil.resolvePath( arguments.serverConfigFile ); + if( !fileExists( arguments.serverConfigFile ) ) { + error( 'The serverConfigFile does not exist. [#arguments.serverConfigFile#]' ); + } + } + // Default the server.json in the CWD + var thisServerConfigFile = ( len( arguments.serverConfigFile ) ? arguments.serverConfigFile : getCWD() & '/server.json' ); + // Read without defaulted values - var serverJSON = ServerService.readServerJSON( directory ); + var serverJSON = ServerService.readServerJSON( thisServerConfigFile ); try { diff --git a/src/cfml/system/modules/server-commands/commands/server/start.cfc b/src/cfml/system/modules/server-commands/commands/server/start.cfc index 15a85b346..779a7600b 100644 --- a/src/cfml/system/modules/server-commands/commands/server/start.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/start.cfc @@ -76,7 +76,7 @@ component aliases="start" { * @cfengine sets the cfml engine type * @cfengine.optionsUDF cfengineNameComplete * @WARPath sets the path to an existing war to use - * @serverConfigFile The path to the server.json file. Created if it doesn't exist. + * @serverConfigFile The path to the server's JSON file. Created if it doesn't exist. **/ function run( @@ -84,7 +84,7 @@ component aliases="start" { Numeric port, String host, Boolean openbrowser, - String directory = "", + String directory, Numeric stopPort, Boolean force, Boolean debug, @@ -111,15 +111,14 @@ component aliases="start" { String serverConfigFile='' ){ // Resolve path as used locally - arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); - if( !isNull( WARPath ) ) { - arguments.WARPath = fileSystemUtil.resolvePath( arguments.WARPath ); + if( !isNull( arguments.directory ) ) { + arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); } - if( len( serverConfigFile ) ) { + if( !isNull( arguments.WARPath ) ) { + arguments.WARPath = fileSystemUtil.resolvePath( arguments.WARPath ); + } + if( len( arguments.serverConfigFile ) ) { arguments.serverConfigFile = fileSystemUtil.resolvePath( arguments.serverConfigFile ); - if( !fileExists( arguments.serverConfigFile ) ) { - error( 'The serverConfigFile does not exist. [#arguments.serverConfigFile#]' ); - } } // This is a common mis spelling @@ -133,8 +132,11 @@ component aliases="start" { // As a convenient shorcut, allow the serverConfigFile to be passed via the name parameter. var tmpName = arguments.name ?: ''; var tmpNameResolved = fileSystemUtil.resolvePath( tmpName ); + // Check if there was no config file specified, but the name was specified and happens to exist as a file on disk if( !len( arguments.serverConfigFile ) && len( tmpName ) && fileExists( tmpNameResolved ) ) { + // If so, swap the name into the server config param. arguments.serverConfigFile = tmpNameResolved; + structDelete( arguments, 'name' ); } // startup the server diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 00b6fccdf..278aacef7 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -168,29 +168,59 @@ component accessors="true" singleton { Struct serverProps ){ - if( isNull( serverProps.name ) ) { - serverProps.name = listLast( serverProps.directory, "\/" ); - } - + // TODO: The next big block is en excellent candiate to refactor into a method. + + var userProvidedServerConfigFile = true; + // If we have no config file path, assume it's called "server.json" in the web root. if( !len( serverProps.serverConfigFile ) ) { - serverProps.serverConfigFile = serverProps.directory & "/server.json"; + userProvidedServerConfigFile = false; + serverProps.serverConfigFile = fileSystemUtil.resolvePath( serverProps.directory ?: '' ) & "/server.json"; } // Get server descriptor + if( serverProps.debug ?: false ) { + consoleLogger.debug("Reading server JSON file:: #serverProps.serverConfigFile#"); + } var serverJSON = readServerJSON( serverProps.serverConfigFile ); + // Get the web root out of the server.json, if specified and make it relative to the actual server.json file. if( len( serverJSON.web.wwwroot ?: '' ) ) { serverProps.directory = fileSystemUtil.resolvePath( serverJSON.web.wwwroot, getDirectoryFromPath( serverProps.serverConfigFile ) ); + // Otherwise default to the directory the server's JSON file lives in (which defaults to the CWD) + } else { + serverProps.directory = getDirectoryFromPath( serverProps.serverConfigFile ); } - if( len( serverJSON.name ?: '' ) ) { + + // If user types a name, use that above all else + if( len( serverProps.name ?: '' ) ) { + // Do nothing, server.json is updated below + } else if( len( serverJSON.name ?: '' ) ) { + // otherwise use the name in the server config file if it's specified serverProps.name = serverJSON.name; - } + } else { + // otherwise default to the c urrent directory + // TODO: I don't care for this because it creates conflicts since many servers could have the name "wwwroot" on one machine. + serverProps.name = replace( listLast( serverProps.directory, "\/" ), ':', ''); + } // Discover by shortname or server and get server info var serverInfo = getServerInfoByDiscovery( directory = serverProps.directory, name = serverProps.name ); + // Keep this in sync in case we only came in with a directory + serverProps.name = serverInfo.name ?: serverProps.name; + // If the user didn't provide an explicit config file and it turns out last time we started a server by this name, we used a different + // config, let's re-read out that config JSON file to use instead of the default above. + if( !userProvidedServerConfigFile && len( serverInfo.serverConfigFile ?: '' ) && serverInfo.serverConfigFile != serverProps.serverConfigFile ) { + // Get server descriptor again + if( serverProps.debug ?: false ) { + consoleLogger.debug("Switching to server JSON file:: #serverInfo.serverConfigFile#"); + } + serverJSON = readServerJSON( serverInfo.serverConfigFile ); + serverProps.serverConfigFile = serverInfo.serverConfigFile; + } + // Was it found, or new server? if( structIsEmpty( serverInfo ) ){ @@ -218,7 +248,7 @@ component accessors="true" singleton { // Save hand-entered properties in our server.json for next time for( var prop in serverProps ) { - if( !isNull( serverProps[ prop ] ) && prop != 'directory' && prop != 'saveSettings' ) { + if( !isNull( serverProps[ prop ] ) && prop != 'directory' && prop != 'saveSettings' && prop != 'serverConfigFile' ) { // Only need switch cases for properties that are nested or use different name switch(prop) { case "port": @@ -288,7 +318,7 @@ component accessors="true" singleton { } // for loop if( !serverJSON.isEmpty() && serverProps.saveSettings ) { - saveServerJSON( serverInfo.webroot, serverJSON ); + saveServerJSON( serverProps.serverConfigFile, serverJSON ); } @@ -320,12 +350,15 @@ component accessors="true" singleton { serverInfo.runwarArgs = serverProps.runwarArgs ?: serverJSON.runwar.args ?: defaults.runwar.args; serverInfo.cfengine = serverProps.cfengine ?: serverJSON.app.cfengine ?: defaults.app.cfengine; serverInfo.WARPath = serverProps.WARPath ?: serverJSON.app.WARPath ?: defaults.app.WARPath; + serverInfo.serverConfigFile = serverProps.serverConfigFile; serverInfo.logdir = serverInfo.webConfigDir & "/logs"; - - consoleLogger.info( "start server in - " & serverInfo.webroot ); - return; + if( serverInfo.debug ) { + consoleLogger.info( "start server in - " & serverInfo.webroot ); + consoleLogger.info( "server name - " & serverInfo.name ); + consoleLogger.info( "server config file - " & serverProps.serverConfigFile ); + } if( !len( serverInfo.WARPath ) && !len( serverInfo.cfengine ) ) { serverInfo.cfengine = 'lucee@' & server.lucee.version; @@ -446,7 +479,6 @@ component accessors="true" singleton { & " --cfml-server-config ""#serverInfo.serverConfigDir#"" #serverInfo.runwarArgs# --timeout 120"; // Starting a WAR - systemOutput( serverinfo.WARPath, true ); if (serverInfo.WARPath != "" ) { args &= " -war ""#serverInfo.WARPath#"""; // Stand alone server @@ -486,7 +518,7 @@ component accessors="true" singleton { setServerInfo( serverInfo ); if(serverInfo.debug) { - consoleLogger.debug("Server start command: #javaCommand# #args#"); + consoleLogger.debug("Server start command: #javaCommand# #args#"); } // thread the execution var threadName = 'server#hash( serverInfo.webroot )##createUUID()#'; @@ -573,7 +605,7 @@ component accessors="true" singleton { var serverJSONPath = arguments.serverInfo.webroot & '/server-#arguments.serverInfo.name#.json'; // try to delete from config first - structDelete( servers, hash( arguments.serverInfo.webroot & arguments.serverInfo.name ) ); + structDelete( servers, arguments.serverInfo.id ); setServers( servers ); // try to delete server if( directoryExists( serverDir ) ){ @@ -690,7 +722,8 @@ component accessors="true" singleton { } /** - * Get a server information struct by name or directory + * Get a server information struct by name or directory. + * Returns empty struct if not found. * @directory.hint the directory to find * @name.hint The name to find */ @@ -699,13 +732,13 @@ component accessors="true" singleton { // Discover by shortname or webroot if( len( arguments.name ) ){ var foundServer = getServerInfoByName( arguments.name ); - if( !isNull( foundServer ) ) { + if( structCount( foundServer ) ) { return foundServer; } } var webroot = arguments.directory is "" ? shell.pwd() : arguments.directory; - return getServerInfoByWebroot( fileSystemUtil.resolvePath( webroot ), arguments.name ); + return getServerInfoByWebroot( fileSystemUtil.resolvePath( webroot ) ); } /** @@ -741,16 +774,15 @@ component accessors="true" singleton { * Get a server information struct by webrot, if not found it returns an empty struct * @webroot.hint The webroot to find */ - struct function getServerInfoByWebroot( required webroot, name='' ){ - - if( arguments.name == '' ) { - arguments.name = listLast( arguments.webroot, "\/" ); + struct function getServerInfoByWebroot( required webroot ){ + var servers = getServers(); + for( var thisServer in servers ){ + if( servers[ thisServer ].webroot == arguments.webroot ){ + return servers[ thisServer ]; + } } - - var webrootHash = hash( arguments.webroot & arguments.name ); - var servers = getServers(); - return structKeyExists( servers, webrootHash ) ? servers[ webrootHash ] : {}; + return {}; } /** @@ -816,8 +848,9 @@ component accessors="true" singleton { rewritesConfig : "", heapSize : 512, directoryBrowsing : true, - JVMargs : "", - runwarArgs : "" + JVMargs : "", + runwarArgs : "", + serverConfigFile : "" }; } @@ -836,9 +869,8 @@ component accessors="true" singleton { /** * Save a server.json file. */ - function saveServerJSON( required string directory, required struct data ) { - var filePath = arguments.directory & '/server.json'; - fileWrite( filePath, formatterUtil.formatJSON( serializeJSON( arguments.data ) ) ); + function saveServerJSON( required string configFilePath, required struct data ) { + fileWrite( arguments.configFilePath, formatterUtil.formatJSON( serializeJSON( arguments.data ) ) ); } /** From 5885b16f749583b4d630f9e4518f088311b2fa7a Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Fri, 3 Jun 2016 00:26:13 -0500 Subject: [PATCH 124/129] COMMANDBOX-345 --- .../server-commands/commands/server/cd.cfc | 4 +- .../commands/server/forget.cfc | 30 +- .../server-commands/commands/server/log.cfc | 27 +- .../server-commands/commands/server/open.cfc | 30 +- .../commands/server/restart.cfc | 27 +- .../server-commands/commands/server/start.cfc | 18 +- .../commands/server/status.cfc | 35 +- .../server-commands/commands/server/stop.cfc | 28 +- src/cfml/system/services/ServerService.cfc | 391 +++++++++++------- 9 files changed, 348 insertions(+), 242 deletions(-) diff --git a/src/cfml/system/modules/server-commands/commands/server/cd.cfc b/src/cfml/system/modules/server-commands/commands/server/cd.cfc index b0c085d1b..90cbc26c2 100644 --- a/src/cfml/system/modules/server-commands/commands/server/cd.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/cd.cfc @@ -22,9 +22,7 @@ component { // Verify server info if( structIsEmpty( serverInfo ) ){ - error( "The server you requested to stop was not found (#arguments.name#)." ); - print.line( "You can use the 'server list' command to get all the available servers." ); - return; + error( "The server you requested was not found.", "You can use the 'server list' command to get all the available servers." ); } var cdCommand = 'cd ' & '"#parser.escapeArg( serverInfo.webroot )#"'; diff --git a/src/cfml/system/modules/server-commands/commands/server/forget.cfc b/src/cfml/system/modules/server-commands/commands/server/forget.cfc index fcd55f868..33ec34465 100644 --- a/src/cfml/system/modules/server-commands/commands/server/forget.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/forget.cfc @@ -16,28 +16,28 @@ component { /** * Forgets one or all servers from persistent disk, removing all logs, configs, etc. * - * @name.hint Short name for the server + * @name.hint the short name of the server * @name.optionsUDF serverNameComplete - * @directory.hint Web root for the server + * @directory.hint web root for the server + * @serverConfigFile The path to the server's JSON file. * @all.hint Forget all servers * @force.hint Skip the "are you sure" confirmation **/ function run( - String name="", - String directory="", + string name, + string directory, + String serverConfigFile, Boolean all=false, Boolean force=false - ){ - // Discover by shortname or webroot - arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); - var serverInfo = serverService.getServerInfoByDiscovery( arguments.directory, arguments.name ); - - // Verify server info - if( structIsEmpty( serverInfo ) AND arguments.all eq false ){ - error( "The server you requested to forget was not found (webroot=#arguments.directory#, name=#arguments.name#)." ); - print.line( "You can use the 'server list' command to get all the available servers." ); - return; - } + ){ + if( !isNull( arguments.directory ) ) { + arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); + } + if( !isNull( arguments.serverConfigFile ) ) { + arguments.serverConfigFile = fileSystemUtil.resolvePath( arguments.serverConfigFile ); + } + var serverInfo = serverService.resolveServerDetails( arguments ).serverinfo; + // Confirm deletion var askMessage = arguments.all ? "Really forget & delete all servers (servers=#arrayToList( serverService.getServerNames() )#) forever [y/n]?" : "Really forget & delete server '#serverinfo.name#' forever [y/n]?"; diff --git a/src/cfml/system/modules/server-commands/commands/server/log.cfc b/src/cfml/system/modules/server-commands/commands/server/log.cfc index 70ad7e73e..d111ed637 100644 --- a/src/cfml/system/modules/server-commands/commands/server/log.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/log.cfc @@ -13,21 +13,30 @@ component { /** * Show server log * - * @name.hint short name for the server + * @name.hint the short name of the server * @name.optionsUDF serverNameComplete * @directory.hint web root for the server + * @serverConfigFile The path to the server's JSON file. **/ - function run( string name="", string directory="" ){ - // Discover by shortname or webroot - var serverInfo = serverService.getServerInfoByDiscovery( arguments.directory, arguments.name ); + function run( + string name, + string directory, + String serverConfigFile + ){ + if( !isNull( arguments.directory ) ) { + arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); + } + if( !isNull( arguments.serverConfigFile ) ) { + arguments.serverConfigFile = fileSystemUtil.resolvePath( arguments.serverConfigFile ); + } + var serverDetails = serverService.resolveServerDetails( arguments ); + var serverInfo = serverDetails.serverInfo; // Verify server info - if( structIsEmpty( serverInfo ) ){ - error( "The server you requested to log was not found (webroot=#arguments.directory#, name=#arguments.name#)." ); - print.line( "You can use the 'server list' command to get all the available servers." ); - return; + if( serverDetails.serverIsNew ){ + error( "The server you requested was not found.", "You can use the 'server list' command to get all the available servers." ); } - + var logfile = serverInfo.logdir & "/server.out.txt"; if( fileExists( logfile) ){ return fileRead( logfile ); diff --git a/src/cfml/system/modules/server-commands/commands/server/open.cfc b/src/cfml/system/modules/server-commands/commands/server/open.cfc index 3be3bb0c3..1266d65eb 100644 --- a/src/cfml/system/modules/server-commands/commands/server/open.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/open.cfc @@ -12,15 +12,29 @@ component { property name="serverService" inject="ServerService"; /** - * @URI An additional URI to go to when opening the server browser, else it just opens localhost:port - * @directory Web root for the server, auto-calculated if not passed - * @name Short name for the server + * @URI An additional URI to go to when opening the server browser, else it just opens localhost:port + * @name.hint the short name of the server + * @name.optionsUDF serverNameComplete + * @directory.hint web root for the server + * @serverConfigFile The path to the server's JSON file. **/ - function run( URI="/", directory="", name="" ){ - var serverInfo = serverService.getServerInfoByDiscovery( arguments.directory, arguments.name ); - - if( structCount( serverInfo ) eq 0 ){ - print.boldRedLine( "No server configurations found for directory:'#arguments.directory#' name:'#arguments.name#', so have no clue what to open buddy!" ); + function run( + URI="/", + string name, + string directory, + String serverConfigFile + ){ + if( !isNull( arguments.directory ) ) { + arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); + } + if( !isNull( arguments.serverConfigFile ) ) { + arguments.serverConfigFile = fileSystemUtil.resolvePath( arguments.serverConfigFile ); + } + var serverDetails = serverService.resolveServerDetails( arguments ); + var serverInfo = serverDetails.serverInfo; + + if( serverDetails.serverIsNew ){ + print.boldRedLine( "No server configurations found so have no clue what to open buddy!" ); } else { var thisURL = "localhost:#serverInfo.port##arguments.URI#"; print.greenLine( "Opening...#thisURL#" ); diff --git a/src/cfml/system/modules/server-commands/commands/server/restart.cfc b/src/cfml/system/modules/server-commands/commands/server/restart.cfc index d7c2b9523..8d3d9efd0 100644 --- a/src/cfml/system/modules/server-commands/commands/server/restart.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/restart.cfc @@ -14,29 +14,32 @@ component aliases="restart" { property name="packageService" inject="packageService"; /** - * @name.hint the short name of the server to restart + * @name.hint the short name of the server * @name.optionsUDF serverNameComplete * @directory.hint web root for the server + * @serverConfigFile The path to the server's JSON file. * @force.hint if passed, this will force restart the server * @openbrowser.hint open a browser after restarting, defaults to false **/ function run( - string name="", - string directory="", + string name, + string directory, + String serverConfigFile, boolean force=false, boolean openBrowser=false ){ - // Discover by shortname or webroot and get server info - var serverInfo = serverService.getServerInfoByDiscovery( - directory = arguments.directory, - name = arguments.name - ); + if( !isNull( arguments.directory ) ) { + arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); + } + if( !isNull( arguments.serverConfigFile ) ) { + arguments.serverConfigFile = fileSystemUtil.resolvePath( arguments.serverConfigFile ); + } + var serverDetails = serverService.resolveServerDetails( arguments ); + var serverInfo = serverDetails.serverInfo; // Verify server info - if( structIsEmpty( serverInfo ) ){ - error( "The server you requested to restart was not found (webroot=#arguments.directory#, name=#arguments.name#)." ); - print.line( "You can use the 'server list' command to get all the available servers." ); - return; + if( serverDetails.serverIsNew ){ + error( "The server you requested was not found.", "You can use the 'server list' command to get all the available servers." ); } var stopCommand = "server stop '#serverInfo.name#'"; diff --git a/src/cfml/system/modules/server-commands/commands/server/start.cfc b/src/cfml/system/modules/server-commands/commands/server/start.cfc index 779a7600b..585f40877 100644 --- a/src/cfml/system/modules/server-commands/commands/server/start.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/start.cfc @@ -108,17 +108,17 @@ component aliases="start" { boolean saveSettings=true, String cfengine, String WARPath, - String serverConfigFile='' + String serverConfigFile ){ // Resolve path as used locally if( !isNull( arguments.directory ) ) { arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); + } + if( !isNull( arguments.serverConfigFile ) ) { + arguments.serverConfigFile = fileSystemUtil.resolvePath( arguments.serverConfigFile ); } if( !isNull( arguments.WARPath ) ) { arguments.WARPath = fileSystemUtil.resolvePath( arguments.WARPath ); - } - if( len( arguments.serverConfigFile ) ) { - arguments.serverConfigFile = fileSystemUtil.resolvePath( arguments.serverConfigFile ); } // This is a common mis spelling @@ -129,16 +129,6 @@ component aliases="start" { structDelete( arguments, 'rewritesEnabled' ); } - // As a convenient shorcut, allow the serverConfigFile to be passed via the name parameter. - var tmpName = arguments.name ?: ''; - var tmpNameResolved = fileSystemUtil.resolvePath( tmpName ); - // Check if there was no config file specified, but the name was specified and happens to exist as a file on disk - if( !len( arguments.serverConfigFile ) && len( tmpName ) && fileExists( tmpNameResolved ) ) { - // If so, swap the name into the server config param. - arguments.serverConfigFile = tmpNameResolved; - structDelete( arguments, 'name' ); - } - // startup the server return serverService.start( serverProps = arguments ); } diff --git a/src/cfml/system/modules/server-commands/commands/server/status.cfc b/src/cfml/system/modules/server-commands/commands/server/status.cfc index 4d0afbf06..cd2910832 100644 --- a/src/cfml/system/modules/server-commands/commands/server/status.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/status.cfc @@ -38,16 +38,18 @@ component aliases='status' { /** * Show server status * - * @name.hint Short name for the server - * @name.optionsUDF ServerNameComplete - * @directory.hint Web root for the server + * @name.hint the short name of the server + * @name.optionsUDF serverNameComplete + * @directory.hint web root for the server + * @serverConfigFile The path to the server's JSON file. * @showAll.hint show all server statuses * @verbose.hint Show extra details * @json Output the server data as json **/ function run( - name='', - directory='', + string name, + string directory, + String serverConfigFile, boolean showAll=false, boolean verbose=false, boolean JSON=false @@ -62,13 +64,15 @@ component aliases='status' { ); return; } - - // scissors beats paper - if( len( trim( arguments.name ) ) ) { - arguments.directory = ''; - } else { - arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); - } + + if( !isNull( arguments.directory ) ) { + arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); + } + if( !isNull( arguments.serverConfigFile ) ) { + arguments.serverConfigFile = fileSystemUtil.resolvePath( arguments.serverConfigFile ); + } + var serverDetails = serverService.resolveServerDetails( arguments ); + var serverInfo = serverDetails.serverInfo; // Map the server statuses to a color var statusColors = { @@ -80,11 +84,8 @@ component aliases='status' { for( var thisKey in servers ){ var thisServerInfo = servers[ thisKey ]; - // If this is a directory or a name match OR are we just showing everything - if( thisServerInfo.webroot == arguments.directory - || thisServerInfo.name == arguments.name - || arguments.showAll - ){ + // If this is a server match OR are we just showing everything + if( thisServerInfo.id == serverInfo.id || arguments.showAll ){ // Null Checks, to guarantee correct struct. structAppend( thisServerInfo, serverService.newServerInfoStruct(), false ); diff --git a/src/cfml/system/modules/server-commands/commands/server/stop.cfc b/src/cfml/system/modules/server-commands/commands/server/stop.cfc index 9c57c3a83..686d0d1fd 100644 --- a/src/cfml/system/modules/server-commands/commands/server/stop.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/stop.cfc @@ -17,12 +17,14 @@ component aliases="stop" { * @name.hint the short name of the server to stop * @name.optionsUDF serverNameComplete * @directory.hint web root for the server + * @serverConfigFile The path to the server's JSON file. * @forget.hint if passed, this will also remove the directory information from disk * @all.hint If true, stop ALL running servers **/ function run( - string name="", - string directory="", + string name, + string directory, + String serverConfigFile, boolean forget=false, boolean all=false ){ @@ -30,19 +32,17 @@ component aliases="stop" { if( arguments.all ) { var servers = serverService.getServers(); } else { - arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); - // Discover by shortname or webroot and get server info - var servers = { id: serverService.getServerInfoByDiscovery( - directory = arguments.directory, - name = arguments.name - ) }; + + if( !isNull( arguments.directory ) ) { + arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); + } + if( !isNull( arguments.serverConfigFile ) ) { + arguments.serverConfigFile = fileSystemUtil.resolvePath( arguments.serverConfigFile ); + } + + // Look up the server that we're starting + var servers = { id: serverService.resolveServerDetails( arguments ).serverinfo }; - // Verify server info - if( structIsEmpty( servers.id ) ){ - error( "The server you requested to stop was not found (webroot=#arguments.directory#, name=#arguments.name#)." ); - print.line( "You can use the 'server list' command to get all the available servers." ); - return; - } } // End "all" check // Stop the server(s) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 278aacef7..ee4aefe17 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -168,168 +168,137 @@ component accessors="true" singleton { Struct serverProps ){ - // TODO: The next big block is en excellent candiate to refactor into a method. - - var userProvidedServerConfigFile = true; - // If we have no config file path, assume it's called "server.json" in the web root. - if( !len( serverProps.serverConfigFile ) ) { - userProvidedServerConfigFile = false; - serverProps.serverConfigFile = fileSystemUtil.resolvePath( serverProps.directory ?: '' ) & "/server.json"; - } - - // Get server descriptor - if( serverProps.debug ?: false ) { - consoleLogger.debug("Reading server JSON file:: #serverProps.serverConfigFile#"); - } - var serverJSON = readServerJSON( serverProps.serverConfigFile ); - - // Get the web root out of the server.json, if specified and make it relative to the actual server.json file. - if( len( serverJSON.web.wwwroot ?: '' ) ) { - serverProps.directory = fileSystemUtil.resolvePath( serverJSON.web.wwwroot, getDirectoryFromPath( serverProps.serverConfigFile ) ); - // Otherwise default to the directory the server's JSON file lives in (which defaults to the CWD) - } else { - serverProps.directory = getDirectoryFromPath( serverProps.serverConfigFile ); - } - - // If user types a name, use that above all else - if( len( serverProps.name ?: '' ) ) { - // Do nothing, server.json is updated below - } else if( len( serverJSON.name ?: '' ) ) { - // otherwise use the name in the server config file if it's specified - serverProps.name = serverJSON.name; - } else { - // otherwise default to the c urrent directory - // TODO: I don't care for this because it creates conflicts since many servers could have the name "wwwroot" on one machine. - serverProps.name = replace( listLast( serverProps.directory, "\/" ), ':', ''); - } - - // Discover by shortname or server and get server info - var serverInfo = getServerInfoByDiscovery( - directory = serverProps.directory, - name = serverProps.name - ); - // Keep this in sync in case we only came in with a directory - serverProps.name = serverInfo.name ?: serverProps.name; - // If the user didn't provide an explicit config file and it turns out last time we started a server by this name, we used a different - // config, let's re-read out that config JSON file to use instead of the default above. - if( !userProvidedServerConfigFile && len( serverInfo.serverConfigFile ?: '' ) && serverInfo.serverConfigFile != serverProps.serverConfigFile ) { - // Get server descriptor again - if( serverProps.debug ?: false ) { - consoleLogger.debug("Switching to server JSON file:: #serverInfo.serverConfigFile#"); - } - serverJSON = readServerJSON( serverInfo.serverConfigFile ); - serverProps.serverConfigFile = serverInfo.serverConfigFile; - } - - - // Was it found, or new server? - if( structIsEmpty( serverInfo ) ){ - // We need a new entry - serverInfo = getServerInfo( serverProps.directory, serverProps.name ); - } - - // Get package descriptor - var boxJSON = packageService.readPackageDescriptor( serverInfo.webroot ); - // Get defaults - var defaults = getDefaultServerJSON(); - - // Backwards compat with boxJSON default port. Remove in a future version - // The property in box.json is deprecated. - if( boxJSON.defaultPort > 0 ) { - - // Remove defaultPort from box.json and pretend it was - // manually typed which will cause server.json to save it. - serverProps.port = boxJSON.defaultPort; - - // Update box.json to remove defaultPort from disk - boxJSON.delete( 'defaultPort' ); - packageService.writePackageDescriptor( boxJSON, serverInfo.webroot ); - } + // Look up the server that we're starting + var serverDetails = resolveServerDetails( arguments.serverProps ); + + var defaultName = serverDetails.defaultName; + var defaultwebroot = serverDetails.defaultwebroot; + var defaultServerConfigFile = serverDetails.defaultServerConfigFile; + var serverJSON = serverDetails.serverJSON; + var serverInfo = serverDetails.serverinfo; + + // ************************************************************************************* + // Backwards compat for default port in box.json. Remove this eventually... // * + // * + // Get package descriptor // * + var boxJSON = packageService.readPackageDescriptor( serverInfo.webroot ); // * + // Get defaults // * + var defaults = getDefaultServerJSON(); // * + // * + // Backwards compat with boxJSON default port. Remove in a future version // * + // The property in box.json is deprecated. // * + if( boxJSON.defaultPort > 0 ) { // * + // * + // Remove defaultPort from box.json and pretend it was // * + // manually typed which will cause server.json to save it. // * + serverProps.port = boxJSON.defaultPort; // * + // * + // Update box.json to remove defaultPort from disk // * + boxJSON.delete( 'defaultPort' ); // * + packageService.writePackageDescriptor( boxJSON, serverInfo.webroot ); // * + } // * + // * + // End backwards compat for default port in box.json. // * + // ************************************************************************************* // Save hand-entered properties in our server.json for next time for( var prop in serverProps ) { - if( !isNull( serverProps[ prop ] ) && prop != 'directory' && prop != 'saveSettings' && prop != 'serverConfigFile' ) { - // Only need switch cases for properties that are nested or use different name - switch(prop) { - case "port": - serverJSON[ 'web' ][ 'http' ][ 'port' ] = serverProps[ prop ]; - break; - case "host": - serverJSON[ 'web' ][ 'host' ] = serverProps[ prop ]; - break; - case "stopPort": - serverJSON[ 'stopsocket' ] = serverProps[ prop ]; - break; - case "webConfigDir": - serverJSON[ 'app' ][ 'webConfigDir' ] = serverProps[ prop ]; - break; - case "serverConfigDir": - serverJSON[ 'app' ][ 'serverConfigDir' ] = serverProps[ prop ]; - break; - case "libDirs": - serverJSON[ 'app' ][ 'libDirs' ] = serverProps[ prop ]; - break; - case "webXML": - serverJSON[ 'app' ][ 'webXML' ] = serverProps[ prop ]; - break; - case "cfengine": - serverJSON[ 'app' ][ 'cfengine' ] = serverProps[ prop ]; - break; - case "WARPath": - serverJSON[ 'app' ][ 'WARPath' ] = serverProps[ prop ]; - break; - case "HTTPEnable": - serverJSON[ 'web' ][ 'HTTP' ][ 'enable' ] = serverProps[ prop ]; - break; - case "SSLEnable": - serverJSON[ 'web' ][ 'SSL' ][ 'enable' ] = serverProps[ prop ]; - break; - case "SSLPort": - serverJSON[ 'web' ][ 'SSL' ][ 'port' ] = serverProps[ prop ]; - break; - case "SSLCert": - serverJSON[ 'web' ][ 'SSL' ][ 'cert' ] = serverProps[ prop ]; - break; - case "SSLKey": - serverJSON[ 'web' ][ 'SSL' ][ 'key' ] = serverProps[ prop ]; - break; - case "SSLKeyPass": - serverJSON[ 'web' ][ 'SSL' ][ 'keyPass' ] = serverProps[ prop ]; - break; - case "rewritesEnable": - serverJSON[ 'web' ][ 'rewrites' ][ 'enable' ] = serverProps[ prop ]; - break; - case "rewritesConfig": - serverJSON[ 'web' ][ 'rewrites' ][ 'config' ] = serverProps[ prop ]; - break; - case "heapSize": - serverJSON[ 'JVM' ][ 'heapSize' ] = serverProps[ prop ]; - break; - case "JVMArgs": - serverJSON[ 'JVM' ][ 'args' ] = serverProps[ prop ]; - break; - case "runwarArgs": - serverJSON[ 'runwar' ][ 'args' ] = serverProps[ prop ]; - break; - default: - serverJSON[ prop ] = serverProps[ prop ]; - } // end switch - } // end if + // Ignore null props or ones that shouldn't be saved + if( isNull( serverProps[ prop ] ) || listFindNoCase( 'saveSettings,serverConfigFile,debug', prop ) ) { + continue; + } + // Only need switch cases for properties that are nested or use different name + switch(prop) { + case "port": + serverJSON[ 'web' ][ 'http' ][ 'port' ] = serverProps[ prop ]; + break; + case "host": + serverJSON[ 'web' ][ 'host' ] = serverProps[ prop ]; + break; + case "directory": + // Both of these are canonical already. + var thisDirectory = replace( serverProps[ prop ], '\', '/', 'all' ) & '/'; + var configPath = replace( fileSystemUtil.resolvePath( getDirectoryFromPath( defaultServerConfigFile ) ), '\', '/', 'all' ) & '/'; + // If the web root is south of the server's JSON, make it relative for better portability. + if( thisDirectory contains configPath ) { + thisDirectory = replaceNoCase( thisDirectory, configPath, '' ); + } + serverJSON[ 'web' ][ 'webroot' ] = thisDirectory; + break; + case "stopPort": + serverJSON[ 'stopsocket' ] = serverProps[ prop ]; + break; + case "webConfigDir": + serverJSON[ 'app' ][ 'webConfigDir' ] = serverProps[ prop ]; + break; + case "serverConfigDir": + serverJSON[ 'app' ][ 'serverConfigDir' ] = serverProps[ prop ]; + break; + case "libDirs": + serverJSON[ 'app' ][ 'libDirs' ] = serverProps[ prop ]; + break; + case "webXML": + serverJSON[ 'app' ][ 'webXML' ] = serverProps[ prop ]; + break; + case "cfengine": + serverJSON[ 'app' ][ 'cfengine' ] = serverProps[ prop ]; + break; + case "WARPath": + serverJSON[ 'app' ][ 'WARPath' ] = serverProps[ prop ]; + break; + case "HTTPEnable": + serverJSON[ 'web' ][ 'HTTP' ][ 'enable' ] = serverProps[ prop ]; + break; + case "SSLEnable": + serverJSON[ 'web' ][ 'SSL' ][ 'enable' ] = serverProps[ prop ]; + break; + case "SSLPort": + serverJSON[ 'web' ][ 'SSL' ][ 'port' ] = serverProps[ prop ]; + break; + case "SSLCert": + serverJSON[ 'web' ][ 'SSL' ][ 'cert' ] = serverProps[ prop ]; + break; + case "SSLKey": + serverJSON[ 'web' ][ 'SSL' ][ 'key' ] = serverProps[ prop ]; + break; + case "SSLKeyPass": + serverJSON[ 'web' ][ 'SSL' ][ 'keyPass' ] = serverProps[ prop ]; + break; + case "rewritesEnable": + serverJSON[ 'web' ][ 'rewrites' ][ 'enable' ] = serverProps[ prop ]; + break; + case "rewritesConfig": + serverJSON[ 'web' ][ 'rewrites' ][ 'config' ] = serverProps[ prop ]; + break; + case "heapSize": + serverJSON[ 'JVM' ][ 'heapSize' ] = serverProps[ prop ]; + break; + case "JVMArgs": + serverJSON[ 'JVM' ][ 'args' ] = serverProps[ prop ]; + break; + case "runwarArgs": + serverJSON[ 'runwar' ][ 'args' ] = serverProps[ prop ]; + break; + default: + serverJSON[ prop ] = serverProps[ prop ]; + } // end switch } // for loop if( !serverJSON.isEmpty() && serverProps.saveSettings ) { - saveServerJSON( serverProps.serverConfigFile, serverJSON ); + saveServerJSON( defaultServerConfigFile, serverJSON ); } // Setup serverinfo according to params // Hand-entered values take precendence, then settings saved in server.json, and finally defaults. // The big servers.json is only used to keep a record of the last values the server was started with - serverInfo.name = serverProps.name; serverInfo.debug = serverProps.debug ?: serverJSON.debug ?: defaults.debug; serverInfo.openbrowser = serverProps.openbrowser ?: serverJSON.openbrowser ?: defaults.openbrowser; serverInfo.host = serverProps.host ?: serverJSON.web.host ?: defaults.web.host; - serverInfo.port = serverProps.port ?: serverJSON.web.http.port ?: getRandomPort( serverInfo.host ); + // 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.stopsocket = serverProps.stopsocket ?: serverJSON.stopsocket ?: getRandomPort( serverInfo.host ); serverInfo.webConfigDir = serverProps.webConfigDir ?: serverJSON.app.webConfigDir ?: getCustomServerFolder( serverInfo ); serverInfo.serverConfigDir = serverProps.serverConfigDir ?: serverJSON.app.serverConfigDir ?: defaults.app.serverConfigDir; @@ -350,14 +319,18 @@ component accessors="true" singleton { serverInfo.runwarArgs = serverProps.runwarArgs ?: serverJSON.runwar.args ?: defaults.runwar.args; serverInfo.cfengine = serverProps.cfengine ?: serverJSON.app.cfengine ?: defaults.app.cfengine; serverInfo.WARPath = serverProps.WARPath ?: serverJSON.app.WARPath ?: defaults.app.WARPath; - serverInfo.serverConfigFile = serverProps.serverConfigFile; + + // These are already hammered out above, so no need to go through all the defaults. + serverInfo.serverConfigFile = defaultServerConfigFile; + serverInfo.name = defaultName; + serverInfo.webroot = defaultwebroot; serverInfo.logdir = serverInfo.webConfigDir & "/logs"; if( serverInfo.debug ) { consoleLogger.info( "start server in - " & serverInfo.webroot ); consoleLogger.info( "server name - " & serverInfo.name ); - consoleLogger.info( "server config file - " & serverProps.serverConfigFile ); + consoleLogger.info( "server config file - " & defaultServerConfigFile ); } if( !len( serverInfo.WARPath ) && !len( serverInfo.cfengine ) ) { @@ -562,6 +535,107 @@ component accessors="true" singleton { } + /** + * Unified logic to resolve a server given an optional name, directory, and server.json path. + * Returns resolved name, webroot, serverConfigFile, serverInfo from the last start and serverJSON + * + * @serverProps A struct that can contains name, directory, and/or serverConfigFile + * + * @returns a struct containing + * - defaultName + * - defaultwebroot + * - defaultServerConfigFile + * - serverJSON + * - serverInfo + */ + function resolveServerDetails( + required struct serverProps + ) { + + // As a convenient shorcut, allow the serverConfigFile to be passed via the name parameter. + var tmpName = serverProps.name ?: ''; + var tmpNameResolved = fileSystemUtil.resolvePath( tmpName ); + // Check if there was no config file specified, but the name was specified and happens to exist as a file on disk + if( !len( serverProps.serverConfigFile ?: '' ) && len( tmpName ) && fileExists( tmpNameResolved ) ) { + // If so, swap the name into the server config param. + serverProps.serverConfigFile = tmpNameResolved; + structDelete( serverProps, 'name' ); + } + + // If we have no config file path, assume it's called "server.json" in the web root. + if( len( serverProps.serverConfigFile ?: '' ) ) { + var defaultServerConfigFile = serverProps.serverConfigFile; + } else { + var defaultServerConfigFile = fileSystemUtil.resolvePath( serverProps.directory ?: '' ) & "/server.json"; + } + + // Get server descriptor from default location. + if( serverProps.debug ?: false ) { + consoleLogger.debug("Reading server JSON file:: #defaultServerConfigFile#"); + } + var serverJSON = readServerJSON( defaultServerConfigFile ); + + // Get the web root out of the server.json, if specified and make it relative to the actual server.json file. + if( len( serverJSON.web.webroot ?: '' ) ) { + var defaultwebroot = fileSystemUtil.resolvePath( serverJSON.web.webroot, getDirectoryFromPath( defaultServerConfigFile ) ); + if( serverProps.debug ?: false ) { + consoleLogger.debug("webroot pulled from server's JSON: #defaultwebroot#"); + } + // Otherwise default to the directory the server's JSON file lives in (which defaults to the CWD) + } else { + var defaultwebroot = fileSystemUtil.resolvePath( getDirectoryFromPath( defaultServerConfigFile ) ); + if( serverProps.debug ?: false ) { + consoleLogger.debug("webroot defaulted to current server's JSON path: #defaultwebroot#"); + } + } + + // If user types a name, use that above all else + if( len( serverProps.name ?: '' ) ) { + var defaultName = serverProps.name; + } else if( len( serverJSON.name ?: '' ) ) { + // otherwise use the name in the server config file if it's specified + var defaultName = serverJSON.name; + } else { + // otherwise default to the c urrent directory + // TODO: I don't care for this because it creates conflicts since many servers could have the name "webroot" on one machine. + var defaultName = replace( listLast( defaultwebroot, "\/" ), ':', ''); + } + + // Discover by shortname or server and get server info + var serverInfo = getServerInfoByDiscovery( + directory = defaultwebroot, + name = defaultName + ); + + var serverIsNew = false; + // If it wasn't found, create new server info using defaults + if( structIsEmpty( serverInfo ) ){ + // We need a new entry + serverIsNew = true; + serverInfo = getServerInfo( defaultwebroot, defaultName ); + } + + // If the user didn't provide an explicit config file and it turns out last time we started a server by this name, we used a different + // config, let's re-read out that config JSON file to use instead of the default above. + if( !len( serverProps.serverConfigFile ?: '' ) && len( serverInfo.serverConfigFile ?: '' ) && serverInfo.serverConfigFile != defaultServerConfigFile ) { + // Get server descriptor again + if( serverProps.debug ?: false ) { + consoleLogger.debug("Switching to server JSON file:: #serverInfo.serverConfigFile#"); + } + serverJSON = readServerJSON( serverInfo.serverConfigFile ); + defaultServerConfigFile = serverInfo.serverConfigFile; + } + + return { + defaultName : defaultName, + defaultwebroot : defaultwebroot, + defaultServerConfigFile : defaultServerConfigFile, + serverJSON : serverJSON, + serverInfo : serverinfo, + serverIsNew : serverIsNew + }; + } + /** * Stop server * @serverInfo.hint The server information struct: [ webroot, name, port, stopSocket, logDir, status, statusInfo ] @@ -665,6 +739,22 @@ component accessors="true" singleton { return portNumber; } + /** + * Find out if a given host/port is already bound + * @host.hint host to test port on, defaults 127.0.0.1 + **/ + function isPortAvailable( host="127.0.0.1", required port ){ + try { + var serverSocket = java.ServerSocket.init( javaCast( "int", arguments.port ), + javaCast( "int", 1 ), + java.InetAddress.getByName( arguments.host ) ); + serverSocket.close(); + return true; + } catch( any var e ) { + return false; + } + } + /** * persist server info * @serverInfo.hint struct of server info (ports, etc.) @@ -775,9 +865,10 @@ component accessors="true" singleton { * @webroot.hint The webroot to find */ struct function getServerInfoByWebroot( required webroot ){ + arguments.webroot = fileSystemUtil.resolvePath( arguments.webroot ); var servers = getServers(); for( var thisServer in servers ){ - if( servers[ thisServer ].webroot == arguments.webroot ){ + if( fileSystemUtil.resolvePath( servers[ thisServer ].webroot ) == arguments.webroot ){ return servers[ thisServer ]; } } From f3e68a2ba7f27d305bab504c7fff7adebd7f6cc7 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Fri, 3 Jun 2016 02:45:23 -0500 Subject: [PATCH 125/129] COMMANDBOX-345 --- .../server-commands/commands/server/list.cfc | 2 + src/cfml/system/services/ServerService.cfc | 67 +++++++++++++++---- 2 files changed, 56 insertions(+), 13 deletions(-) diff --git a/src/cfml/system/modules/server-commands/commands/server/list.cfc b/src/cfml/system/modules/server-commands/commands/server/list.cfc index 675257d4b..c34e89956 100644 --- a/src/cfml/system/modules/server-commands/commands/server/list.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/list.cfc @@ -96,6 +96,8 @@ component { .indentedLine( "debug: " & thisServerInfo.debug ) .indentedLine( "ID: " & thisServerInfo.id ); + if( len( thisServerInfo.cfengine ) ) { print.indentedLine( "cfengine: " & thisServerInfo.cfengine ); } + if( len( thisServerInfo.WARPath ) ) { print.indentedLine( "WARPath: " & thisServerInfo.WARPath ); } if( len( thisServerInfo.libDirs ) ) { print.indentedLine( "libDirs: " & thisServerInfo.libDirs ); } if( len( thisServerInfo.webConfigDir ) ) { print.indentedLine( "webConfigDir: " & thisServerInfo.webConfigDir ); } if( len( thisServerInfo.serverConfigDir ) ) { print.indentedLine( "serverConfigDir: " & thisServerInfo.serverConfigDir ); } diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index ee4aefe17..49291c1c7 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -562,9 +562,13 @@ component accessors="true" singleton { structDelete( serverProps, 'name' ); } - // If we have no config file path, assume it's called "server.json" in the web root. + // If a specific server.json file path was passed, use it. if( len( serverProps.serverConfigFile ?: '' ) ) { var defaultServerConfigFile = serverProps.serverConfigFile; + // Otherwise, if there was a specific name passed, default a named server.json file for them + } else if( len( serverProps.name ?: '' ) ) { + var defaultServerConfigFile = fileSystemUtil.resolvePath( serverProps.directory ?: '' ) & "/server-#serverProps.name#.json"; + // Otherwise, the default is called "server.json" in the web root. } else { var defaultServerConfigFile = fileSystemUtil.resolvePath( serverProps.directory ?: '' ) & "/server.json"; } @@ -596,20 +600,30 @@ component accessors="true" singleton { // otherwise use the name in the server config file if it's specified var defaultName = serverJSON.name; } else { - // otherwise default to the c urrent directory - // TODO: I don't care for this because it creates conflicts since many servers could have the name "webroot" on one machine. - var defaultName = replace( listLast( defaultwebroot, "\/" ), ':', ''); + var defaultName = ''; } // Discover by shortname or server and get server info var serverInfo = getServerInfoByDiscovery( - directory = defaultwebroot, - name = defaultName + directory = defaultwebroot, + name = defaultName, + serverConfigFile = serverProps.serverConfigFile ?: '' // Since this takes precendence, I only want to use it if it was actually specified ); + + if( len( serverInfo.name ?: '' ) ) { + defaultName = serverInfo.name; + } var serverIsNew = false; // If it wasn't found, create new server info using defaults if( structIsEmpty( serverInfo ) ){ + + if( !len( defaultName ) ) { + // If there is still no name, default to the current directory + // TODO: I don't care for this because it creates conflicts since many servers could have the name "webroot" on one machine. + defaultName = replace( listLast( defaultwebroot, "\/" ), ':', ''); + } + // We need a new entry serverIsNew = true; serverInfo = getServerInfo( defaultwebroot, defaultName ); @@ -631,7 +645,7 @@ component accessors="true" singleton { defaultwebroot : defaultwebroot, defaultServerConfigFile : defaultServerConfigFile, serverJSON : serverJSON, - serverInfo : serverinfo, + serverInfo : serverInfo, serverIsNew : serverIsNew }; } @@ -761,8 +775,9 @@ component accessors="true" singleton { **/ function setServerInfo( required struct serverInfo ){ var servers = getServers(); - var webrootHash = hash( arguments.serverInfo.webroot & arguments.serverInfo.name); - + var webrootHash = hash( arguments.serverInfo.webroot & ucase( arguments.serverInfo.name ) ); + arguments.serverInfo.id = webrootHash; + if( arguments.serverInfo.webroot == "" ){ throw( "The webroot cannot be empty!" ); } @@ -795,7 +810,7 @@ component accessors="true" singleton { for( var thisKey in results ){ // Backwards compat-- add in server id if it doesn't exist for older versions of CommandBox if( isNull( results[ thisKey ].id ) ){ - results[ thisKey ].id = hash( results[ thisKey ].webroot & results[ thisKey ].name ); + results[ thisKey ].id = hash( results[ thisKey ].webroot & ucase( results[ thisKey ].name ) ); updateRequired = true; } // Future-proof server info by guaranteeing that all properties will exist in the @@ -817,14 +832,22 @@ component accessors="true" singleton { * @directory.hint the directory to find * @name.hint The name to find */ - struct function getServerInfoByDiscovery( required directory="", required name="" ){ + struct function getServerInfoByDiscovery( required directory="", required name="", serverConfigFile="" ){ + + if( len( arguments.serverConfigFile ) ){ + var foundServer = getServerInfoByServerConfigFile( arguments.serverConfigFile ); + if( structCount( foundServer ) ) { + return foundServer; + } + return {}; + } - // Discover by shortname or webroot if( len( arguments.name ) ){ var foundServer = getServerInfoByName( arguments.name ); if( structCount( foundServer ) ) { return foundServer; } + return {}; } var webroot = arguments.directory is "" ? shell.pwd() : arguments.directory; @@ -846,6 +869,22 @@ component accessors="true" singleton { return {}; } + /** + * Get a server information struct by serverConfigFile if not found it returns an empty struct + * @name.serverConfigFile The serverConfigFile to find + */ + struct function getServerInfoByServerConfigFile( required serverConfigFile ){ + arguments.serverConfigFile = fileSystemUtil.resolvePath( arguments.serverConfigFile ); + var servers = getServers(); + for( var thisServer in servers ){ + if( fileSystemUtil.resolvePath( servers[ thisServer ].serverConfigFile ) == arguments.serverConfigFile ){ + return servers[ thisServer ]; + } + } + + return {}; + } + /** * Get all servers registered as an array of names */ @@ -882,7 +921,7 @@ component accessors="true" singleton { **/ struct function getServerInfo( required webroot , required name){ var servers = getServers(); - var webrootHash = hash( arguments.webroot & arguments.name); + var webrootHash = hash( arguments.webroot & ucase( arguments.name ) ); var statusInfo = {}; if( !directoryExists( arguments.webroot ) ){ @@ -941,6 +980,8 @@ component accessors="true" singleton { directoryBrowsing : true, JVMargs : "", runwarArgs : "", + cfengine : "", + WARPath : "", serverConfigFile : "" }; } From a43c463b8b96c2602ac42a26c4a698d41f5fb71e Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Fri, 3 Jun 2016 10:08:00 -0500 Subject: [PATCH 126/129] COMMANDBOX-345 comments and code cleanup --- src/cfml/system/services/ServerService.cfc | 32 ++++++++++++---------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 49291c1c7..4ec79186e 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -162,7 +162,7 @@ component accessors="true" singleton { /** * Start a server instance * - * @serverProps.hint A struct of settings to influence how to start the server + * @serverProps.hint A struct of settings to influence how to start the server. Params not provided by the user are null. **/ function start( Struct serverProps @@ -538,6 +538,8 @@ component accessors="true" singleton { /** * Unified logic to resolve a server given an optional name, directory, and server.json path. * Returns resolved name, webroot, serverConfigFile, serverInfo from the last start and serverJSON + * Use this for all 'server' commands that let a user specify the server they want by convention (CWD), + * name, directory, or server.json path. * * @serverProps A struct that can contains name, directory, and/or serverConfigFile * @@ -551,6 +553,7 @@ component accessors="true" singleton { function resolveServerDetails( required struct serverProps ) { + var locDebug = serverProps.debug ?: false; // As a convenient shorcut, allow the serverConfigFile to be passed via the name parameter. var tmpName = serverProps.name ?: ''; @@ -574,23 +577,18 @@ component accessors="true" singleton { } // Get server descriptor from default location. - if( serverProps.debug ?: false ) { - consoleLogger.debug("Reading server JSON file:: #defaultServerConfigFile#"); - } + // If starting by name and we guessed the server.json file name, this serverJSON maybe replaced later by another saved file. + if( locDebug ) { consoleLogger.debug("Reading server JSON file:: #defaultServerConfigFile#"); } var serverJSON = readServerJSON( defaultServerConfigFile ); // Get the web root out of the server.json, if specified and make it relative to the actual server.json file. if( len( serverJSON.web.webroot ?: '' ) ) { var defaultwebroot = fileSystemUtil.resolvePath( serverJSON.web.webroot, getDirectoryFromPath( defaultServerConfigFile ) ); - if( serverProps.debug ?: false ) { - consoleLogger.debug("webroot pulled from server's JSON: #defaultwebroot#"); - } + if( locDebug ) { consoleLogger.debug("webroot pulled from server's JSON: #defaultwebroot#"); } // Otherwise default to the directory the server's JSON file lives in (which defaults to the CWD) } else { var defaultwebroot = fileSystemUtil.resolvePath( getDirectoryFromPath( defaultServerConfigFile ) ); - if( serverProps.debug ?: false ) { - consoleLogger.debug("webroot defaulted to current server's JSON path: #defaultwebroot#"); - } + if( locDebug ) { consoleLogger.debug("webroot defaulted to current server's JSON path: #defaultwebroot#"); } } // If user types a name, use that above all else @@ -600,6 +598,7 @@ component accessors="true" singleton { // otherwise use the name in the server config file if it's specified var defaultName = serverJSON.name; } else { + // Don't do a final guess at the name yet so we don't affect the server discovery below. var defaultName = ''; } @@ -610,6 +609,7 @@ component accessors="true" singleton { serverConfigFile = serverProps.serverConfigFile ?: '' // Since this takes precendence, I only want to use it if it was actually specified ); + // If we found a server, set our name. if( len( serverInfo.name ?: '' ) ) { defaultName = serverInfo.name; } @@ -631,15 +631,19 @@ component accessors="true" singleton { // If the user didn't provide an explicit config file and it turns out last time we started a server by this name, we used a different // config, let's re-read out that config JSON file to use instead of the default above. - if( !len( serverProps.serverConfigFile ?: '' ) && len( serverInfo.serverConfigFile ?: '' ) && serverInfo.serverConfigFile != defaultServerConfigFile ) { + if( !len( serverProps.serverConfigFile ?: '' ) + && len( serverInfo.serverConfigFile ?: '' ) + && serverInfo.serverConfigFile != defaultServerConfigFile ) { + // Get server descriptor again - if( serverProps.debug ?: false ) { - consoleLogger.debug("Switching to server JSON file:: #serverInfo.serverConfigFile#"); - } + if( locDebug ) { consoleLogger.debug("Switching to server JSON file:: #serverInfo.serverConfigFile#"); } serverJSON = readServerJSON( serverInfo.serverConfigFile ); defaultServerConfigFile = serverInfo.serverConfigFile; } + // By now we've figured out the name, webroot, and serverConfigFile for this server. + // Also return the serverInfo of the last values the server was started with (if ever) + // and the serverJSON setting for the server, if they exist. return { defaultName : defaultName, defaultwebroot : defaultwebroot, From c66f1bac7b2f4c4f6e90e26b9abffd3d9531b99c Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Fri, 3 Jun 2016 14:38:25 -0500 Subject: [PATCH 127/129] Prevent semvar parsing from blowing up on invalid vers --- src/cfml/system/util/SemanticVersion.cfc | 20 +++++++++---------- .../cfml/system/util/TestSemanticVersion.cfc | 13 ++++++++---- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/cfml/system/util/SemanticVersion.cfc b/src/cfml/system/util/SemanticVersion.cfc index 830b132f5..f37124aab 100644 --- a/src/cfml/system/util/SemanticVersion.cfc +++ b/src/cfml/system/util/SemanticVersion.cfc @@ -332,7 +332,7 @@ component singleton{ sComparator.sVersion.minor = '0'; sComparator.sVersion.revision = '0'; - sComparator.sVersion.major++; + sComparator.sVersion.major=val( sComparator.sVersion.major )+1; sComparator.operator = '<'; sComparator.version = getVersionAsString( sComparator.sVersion ); comparatorSet.append( sComparator ); @@ -341,7 +341,7 @@ component singleton{ } else if( sComparator.sVersion.revision == 'x' ) { sComparator.sVersion.revision = '0'; - sComparator.sVersion.minor++; + sComparator.sVersion.minor=val( sComparator.sVersion.minor )+1; sComparator.operator = '<'; sComparator.version = getVersionAsString( sComparator.sVersion ); comparatorSet.append( sComparator ); @@ -357,7 +357,7 @@ component singleton{ sComparator.sVersion.minor = '0'; sComparator.sVersion.revision = '0'; - sComparator.sVersion.major++; + sComparator.sVersion.major=val( sComparator.sVersion.major )+1; sComparator.operator = '>='; sComparator.version = getVersionAsString( sComparator.sVersion ); comparatorSet.append( sComparator ); @@ -366,7 +366,7 @@ component singleton{ } else if( sComparator.sVersion.revision == 'x' ) { sComparator.sVersion.revision = '0'; - sComparator.sVersion.minor++; + sComparator.sVersion.minor=val(sComparator.sVersion.minor)+1; sComparator.operator = '>='; sComparator.version = getVersionAsString( sComparator.sVersion ); comparatorSet.append( sComparator ); @@ -406,7 +406,7 @@ component singleton{ sComparator.version = getVersionAsString( sComparator.sVersion ); comparatorSet.append( duplicate( sComparator ) ); - sComparator.sVersion.major++; + sComparator.sVersion.major=val( sComparator.sVersion.major )+1; sComparator.operator = '<'; sComparator.version = getVersionAsString( sComparator.sVersion ); comparatorSet.append( sComparator ); @@ -420,7 +420,7 @@ component singleton{ sComparator.version = getVersionAsString( sComparator.sVersion ); comparatorSet.append( duplicate( sComparator ) ); - sComparator.sVersion.minor++; + sComparator.sVersion.minor=val( sComparator.sVersion.minor )+1; sComparator.operator = '<'; sComparator.version = getVersionAsString( sComparator.sVersion ); comparatorSet.append( sComparator ); @@ -447,7 +447,7 @@ component singleton{ comparatorSet.append( duplicate( sComparator ) ); sComparator.operator = '<'; - sComparator.sVersion.minor++; + sComparator.sVersion.minor=val( sComparator.sVersion.minor )+1; sComparator.sVersion.revision = 0; sComparator.sVersion.preReleaseID = ''; sComparator.version = getVersionAsString( sComparator.sVersion ); @@ -475,14 +475,14 @@ component singleton{ sComparator.operator = '<'; sComparator.sVersion.preReleaseID = ''; if( sComparator.sVersion.major != 0 || sComparator.sVersion.minor == 'x' ) { - sComparator.sVersion.major++; + sComparator.sVersion.major=val( sComparator.sVersion.major )+1; sComparator.sVersion.minor = 0; sComparator.sVersion.revision = 0; } else if( sComparator.sVersion.minor != 0 || sComparator.sVersion.revision == 'x' ) { - sComparator.sVersion.minor++; + sComparator.sVersion.minor=val( sComparator.sVersion.minor )+1; sComparator.sVersion.revision = 0; } else { - sComparator.sVersion.revision++; + sComparator.sVersion.revision=val( sComparator.sVersion.revision )+1; } sComparator.version = getVersionAsString( sComparator.sVersion ); diff --git a/tests/cfml/system/util/TestSemanticVersion.cfc b/tests/cfml/system/util/TestSemanticVersion.cfc index 95e294215..9a381bf0e 100644 --- a/tests/cfml/system/util/TestSemanticVersion.cfc +++ b/tests/cfml/system/util/TestSemanticVersion.cfc @@ -16,10 +16,10 @@ component name="TestPrint" extends="mxunit.framework.TestCase" { public void function testParseVersionAsString() { var semver = application.wirebox.getInstance( 'semanticVersion' ); - assertEquals( semver.parseVersionAsString( '1.0.0' ), '1.0.0+0' ); + assertEquals( semver.parseVersionAsString( '1.0.0' ), '1.0.0' ); assertEquals( semver.parseVersionAsString( '1.0.0+123' ), '1.0.0+123' ); assertEquals( semver.parseVersionAsString( '1.0.0-alpha+123' ), '1.0.0-alpha+123' ); - assertEquals( semver.parseVersionAsString( '1' ), '1.0.0+0' ); + assertEquals( semver.parseVersionAsString( '1' ), '1.0.0' ); } public void function testIsPreRelease() { @@ -118,8 +118,8 @@ component name="TestPrint" extends="mxunit.framework.TestCase" { public void function testSatisfies() { var semver = application.wirebox.getInstance( 'semanticVersion' ); -// assertTrue( semver.satisfies( '1.0.0', '1.0.0+0' ) ); - //assertTrue( semver.satisfies( '1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3' ) ); + assertTrue( semver.satisfies( '1.0.0', '1.0.0+0' ) ); + assertTrue( semver.satisfies( '1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3' ) ); assertTrue( semver.satisfies( '1.0.0', '<2.0.0' ) ); assertTrue( semver.satisfies( '0.5', '<1.0.0' ) ); @@ -255,6 +255,11 @@ component name="TestPrint" extends="mxunit.framework.TestCase" { assertTrue( semver.satisfies( '1.5.0', '^1.x' ) ); assertTrue( semver.satisfies( '0.5.0', '^0.x' ) ); + // test invalid semvers just to make sure they don't error + assertfalse( semver.satisfies( '1.2.3', 'foo' ) ); + assertfalse( semver.satisfies( '1.2.3', 'foo.bar' ) ); + assertfalse( semver.satisfies( '1.2.3', 'foo.bar.baz' ) ); + assertTrue( semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') ); } From d5e11bb977f44219fe08a925fc9ccd9243fd9dac Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 13 Jun 2016 22:40:22 -0500 Subject: [PATCH 128/129] Switch to production ForgeBox URL --- src/cfml/system/util/ForgeBox.cfc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cfml/system/util/ForgeBox.cfc b/src/cfml/system/util/ForgeBox.cfc index 7f42b4ea6..1f0e380ca 100644 --- a/src/cfml/system/util/ForgeBox.cfc +++ b/src/cfml/system/util/ForgeBox.cfc @@ -47,8 +47,7 @@ or just add DEBUG to the root logger // Setup Properties - // variables.APIURL = "http://www.coldbox.org/api/forgebox"; - variables.APIURL = "https://forgebox.stg.ortussolutions.com/api/v1/"; + variables.APIURL = "https://forgebox.io/api/v1/"; variables.installURL = "http://www.coldbox.org/forgebox/install/"; variables.types = ""; From 68cb9c5c0777f05b14a4a67f19e77bd0e103bb19 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 13 Jun 2016 23:04:28 -0500 Subject: [PATCH 129/129] Final bump of stable version number --- build/build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build.xml b/build/build.xml index f5ba1f014..d60932884 100644 --- a/build/build.xml +++ b/build/build.xml @@ -16,7 +16,7 @@ External Dependencies: - +