From c62c2bb867cf4ffe1dd9a6392682a8ab060065db Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 21 Jul 2016 00:24:19 -0500 Subject: [PATCH 01/91] Update for new snapshot version --- build/build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build.xml b/build/build.xml index e9a845df0..9792e0aca 100644 --- a/build/build.xml +++ b/build/build.xml @@ -15,7 +15,7 @@ External Dependencies: - + From 5c12f37b7272806a80991eb048a9d183a241f8dc Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 21 Jul 2016 11:04:22 -0500 Subject: [PATCH 02/91] Updated docs for version command --- .../package-commands/commands/package/version.cfc | 15 +++++++++++++++ src/cfml/system/services/ConfigService.cfc | 2 ++ 2 files changed, 17 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 f15632342..030e72440 100644 --- a/src/cfml/system/modules/package-commands/commands/package/version.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/version.cfc @@ -25,6 +25,21 @@ * . * If multiple version parts are specified, the "larger" one will be used starting with major. * If a version AND a flag are both supplied, the version will be used and the flag(s) ignored. + * + * If your package is a Git repo AND it is clean, this command will attempt to tag it with the new version number. + * You can provide an optional commit message for this tag: + * . + * {code:bash} + * bump --major message="finalizing release" + * {code} + * + * If you don't want the tagging functionality, provide the "tagVersion" flag or turn + * off the setting globally with config setting. + * . + * {code:bash} + * bump --major tagVersion=false + * config set tagVersion=false + * {code} **/ component aliases="bump" { diff --git a/src/cfml/system/services/ConfigService.cfc b/src/cfml/system/services/ConfigService.cfc index fbb4c5553..52bd446c7 100644 --- a/src/cfml/system/services/ConfigService.cfc +++ b/src/cfml/system/services/ConfigService.cfc @@ -40,6 +40,8 @@ component accessors="true" singleton { 'proxy.password', // used in "run" command for a custom Unix shell 'nativeShell', + // used in "bump" command + 'tagVersion', // Endpoint data 'endpoints', 'endpoints.forgebox', From c6fa9fe851e62b6c3fcc3b8eb445110fec1c91bc Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 25 Jul 2016 11:56:03 -0500 Subject: [PATCH 03/91] incorrect argument hint --- .../modules/artifacts-commands/commands/artifacts/remove.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfml/system/modules/artifacts-commands/commands/artifacts/remove.cfc b/src/cfml/system/modules/artifacts-commands/commands/artifacts/remove.cfc index 861d71143..640ddbf9a 100644 --- a/src/cfml/system/modules/artifacts-commands/commands/artifacts/remove.cfc +++ b/src/cfml/system/modules/artifacts-commands/commands/artifacts/remove.cfc @@ -29,7 +29,7 @@ component { property name='artifactService' inject='artifactService'; /** - * @packages.hint Comma-delimited list of packages to remove + * @package.hint Comma-delimited list of packages to remove * @version.hint If passed, it will try to remove a specific package version * @force.hint Do not confirm, just delete **/ From 14c5f0b8899e225b42534bfe2d0f052d02b801e4 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 25 Jul 2016 13:14:03 -0500 Subject: [PATCH 04/91] COMMANDBOX-416 --- .../system-commands/commands/touch.cfc | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/cfml/system/modules/system-commands/commands/touch.cfc b/src/cfml/system/modules/system-commands/commands/touch.cfc index 3ddef771c..2398ea32a 100644 --- a/src/cfml/system/modules/system-commands/commands/touch.cfc +++ b/src/cfml/system/modules/system-commands/commands/touch.cfc @@ -5,6 +5,13 @@ * touch file.txt * {code} * . + * Use the open parameter to open the file in your default editor after creating it + * . + * {code:bash} + * touch index.cfm --open + * {code} + * + * . * Use the force parameter to overwrite the contents of the file to be empty even if it exists. * . * {code:bash} @@ -15,10 +22,14 @@ component aliases="new" { /** - * @file.hint File to create - * @force.hint If forced, then file will be recreated even if it exists + * @file File to create + * @force If forced, then file will be recreated even if it exists + * @open Open the file after creating it **/ - function run( required file, boolean force=false ) { + function run( + required file, + boolean force=false, + boolean open=false ) { arguments.file = fileSystemUtil.resolvePath( arguments.file ); @@ -33,12 +44,19 @@ component aliases="new" { // check for update or creation if( !oFile.exists() ){ oFile.createNewFile(); - return "#fileName# created!"; + print.line( "#fileName# created!" ); } else { oFile.setLastModified( now().getTime() ); - return "#fileName# last modified bit updated!"; + print.line( "#fileName# last modified bit updated!" ); } + // Open file for the user + if( arguments.open ){ + // Defer to the "edit" command. + command( 'edit' ) + .params( arguments.file ) + .run(); + } } From 13de258dada486a466c6e1f486666fcbb917d590 Mon Sep 17 00:00:00 2001 From: Jon Clausen Date: Tue, 26 Jul 2016 09:08:28 -0400 Subject: [PATCH 05/91] update homebrew file to current spec w/ devel block --- build/brew-template.rb | 40 ++++++++++++++++------------------------ 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/build/brew-template.rb b/build/brew-template.rb index 5b2d3ed4c..819b45575 100644 --- a/build/brew-template.rb +++ b/build/brew-template.rb @@ -1,17 +1,23 @@ -require "formula" -# Version update PR to Homebrew requires only the information below: class Commandbox < Formula desc "CFML embedded server, package manager, and app scaffolding tools" - homepage "http://www.ortussolutions.com/products/commandbox" - url "@repoURL@/ortussolutions/commandbox/@version@/commandbox-bin-@version@.zip" - sha256 "@sha256@" + homepage "https://www.ortussolutions.com/products/commandbox" + url "@repoPRDURL@/ortussolutions/commandbox/@version@/commandbox-bin-@stable-version@.zip" + sha256 "@stable-sha256@" + version "@stable-version@" + + devel do + url "@repoURL@/ortussolutions/commandbox/@version@/commandbox-bin-@version@.zip" + sha256 "@sha256@" + version "@version@" + end + + bottle :unneeded - depends_on :arch => :x86_64 depends_on :java => "1.7+" resource "apidocs" do - url "@repoURL@/ortussolutions/commandbox/@version@/commandbox-apidocs-@version@.zip" - sha256 "@apidocs.sha256@" + url "@repoPRDURL@/ortussolutions/commandbox/@version@/commandbox-apidocs-@stable-version@.zip" + sha256 "@apidocs.stable-sha256@" end def install @@ -19,22 +25,8 @@ def install doc.install resource("apidocs") end - def caveats; <<-EOS.undent - CommandBox is licensed as open source software under the GNU Lesser General Public License v3 - - License information at: - http://www.gnu.org/licenses/lgpl-3.0.en.html - - For full CommandBox documentation visit: - https://ortus.gitbooks.io/commandbox-documentation/ - - Source Code: - https://github.com/Ortus-Solutions/commandbox - EOS - end - test do - system "box", "install" - system "box", "--version" + system "box", "--commandbox_home=~/", "version" + system "box", "--commandbox_home=~/", "help" end end From 3487ad1c2c25f8f682ccc48c28eb984187267df0 Mon Sep 17 00:00:00 2001 From: Jon Clausen Date: Tue, 26 Jul 2016 09:09:56 -0400 Subject: [PATCH 06/91] Update homebrew build to auto-commit to tap repo --- build/build.xml | 80 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 56 insertions(+), 24 deletions(-) diff --git a/build/build.xml b/build/build.xml index 9792e0aca..ca8a6b4dc 100644 --- a/build/build.xml +++ b/build/build.xml @@ -352,54 +352,86 @@ External Dependencies: + + + + + + + + + + + + encoding="UTF-8" /> @be@ + + @stable-version@ + + + @stable-sha256@ + @version@ + @repoPRDURL@ + + @repoURL@ @sha256@ - - @apidocs.sha256@ + + @apidocs.stable-sha256@ - - - - - @be@ - - - @version@ - - - @repoURL@ - - - @sha256@ - - - @apidocs.sha256@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 8fa1f708d3319bae62306f3fc453b6ad175ad6e5 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Tue, 26 Jul 2016 09:11:35 -0400 Subject: [PATCH 07/91] COMMANDBOX-419 #resolve coldbox create app command does not list all templates --- .../commands/coldbox/create/app.cfc | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 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 a5430a6b6..6152b8235 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 @@ -9,6 +9,9 @@ * Here are the basic skeltons that are available for you. * - Advanced * - AdvancedScript (default) +* - elixir +* - elixir-bower +* - elixir-vuejs * - rest * - Simple * - SuperSimple @@ -46,11 +49,14 @@ component { // 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' + Advanced = 'cbtemplate-advanced', + AdvancedScript = 'cbtemplate-advanced-script', + ElixirVueJS = 'cbtemplate-elixir-vuejs', + ElixirBower = 'cbtemplate-elixir-bower', + Elixir = 'cbtemplate-elixir', + rest = 'cbtemplate-rest', + Simple = 'cbtemplate-simple', + SuperSimple = 'cbtemplate-supersimple' }; return this; From 9f04c22b0bb0fb13e0450046f1064d3549e11b01 Mon Sep 17 00:00:00 2001 From: Jon Clausen Date: Tue, 26 Jul 2016 09:13:28 -0400 Subject: [PATCH 08/91] cleanup tap directory after push --- build/build.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/build.xml b/build/build.xml index ca8a6b4dc..251039f8f 100644 --- a/build/build.xml +++ b/build/build.xml @@ -433,6 +433,8 @@ External Dependencies: + + From f42d13ff9eefaa4c5cb999ad55340689a39d8f01 Mon Sep 17 00:00:00 2001 From: Jon Clausen Date: Tue, 26 Jul 2016 11:39:07 -0400 Subject: [PATCH 09/91] fix version placeholder in stable version retreival --- build/build.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/build.xml b/build/build.xml index 251039f8f..b7af4a550 100644 --- a/build/build.xml +++ b/build/build.xml @@ -359,8 +359,8 @@ External Dependencies: - - + + From 247a1e6c6782e809feec0cad0c2e523c3009043e Mon Sep 17 00:00:00 2001 From: Jon Clausen Date: Tue, 26 Jul 2016 12:23:02 -0400 Subject: [PATCH 10/91] fix path leftover from old homebrew build process --- build/build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build.xml b/build/build.xml index b7af4a550..5948f5474 100644 --- a/build/build.xml +++ b/build/build.xml @@ -389,7 +389,7 @@ External Dependencies: @repoPRDURL@ - + @repoURL@ From 64ca6226012afd7a966e098a020d0e76572aa487 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 26 Jul 2016 17:23:54 -0500 Subject: [PATCH 11/91] COMMANDBOX-422 --- src/cfml/system/services/CommandService.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfml/system/services/CommandService.cfc b/src/cfml/system/services/CommandService.cfc index 7f58d6aea..597f8513f 100644 --- a/src/cfml/system/services/CommandService.cfc +++ b/src/cfml/system/services/CommandService.cfc @@ -780,7 +780,7 @@ component accessors="true" singleton { var meta = arguments.commandData.commandMD; // Make sure command has a run() method - for( var func in meta.functions ){ + for( var func in meta.functions ?: [] ){ // Loop to find the "run()" method if( func.name == 'run' ){ return true; From 131965cdbf3231d7bab51ec2597f4f1c53f83f4f Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 26 Jul 2016 17:32:21 -0500 Subject: [PATCH 12/91] COMMANDBOX-421 --- .../modules/package-commands/commands/package/version.cfc | 8 +++++--- .../package-commands/interceptors/packageScripts.cfc | 1 + src/cfml/system/services/InterceptorService.cfc | 2 +- 3 files changed, 7 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 030e72440..4c446ac44 100644 --- a/src/cfml/system/modules/package-commands/commands/package/version.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/version.cfc @@ -123,6 +123,8 @@ component aliases="bump" { .params( version=arguments.version ) .run(); + interceptorService.announceInterception( 'postVersion', { versionArgs=arguments } ); + // If this package is also a Git repository var repoPath = '#arguments.directory#/.git'; arguments.tagVersion = arguments.tagVersion ?: ConfigService.getSetting( 'tagVersion', true ); @@ -175,9 +177,9 @@ component aliases="bump" { error( 'Error tagging Git repository with new version.', e.message & ' ' & e.detail ); } - } - - interceptorService.announceInterception( 'postVersion', { versionArgs=arguments } ); + } // end is Git repo and are we tagging? + + interceptorService.announceInterception( 'onRelease', { directory=arguments.directory, version=arguments.version } ); } diff --git a/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc b/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc index ce9d19750..c1d6ac44d 100644 --- a/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc +++ b/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc @@ -30,6 +30,7 @@ component { function postUninstall() { processScripts( 'postUninstall' ); } function preVersion() { processScripts( 'preVersion' ); } function postVersion() { processScripts( 'postVersion' ); } + function onRelease() { processScripts( 'onRelease' ); } function prePublish() { processScripts( 'prePublish' ); } function postPublish() { processScripts( 'postPublish' ); } diff --git a/src/cfml/system/services/InterceptorService.cfc b/src/cfml/system/services/InterceptorService.cfc index ad12d6356..a9f3ace05 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','preVersion','postVersion','prePublish','postPublish','preUnpublish','postUnpublish' + 'preInstall','postInstall','preUninstall','postUninstall','preVersion','postVersion','prePublish','postPublish','preUnpublish','postUnpublish','onRelease' ] ); return this; From b7c3d7bccb81ab3ce6a2289b742e0eb051489e9e Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 26 Jul 2016 18:09:09 -0500 Subject: [PATCH 13/91] COMMANDBOX-187 --- src/cfml/system/endpoints/ForgeBox.cfc | 11 +++++++++-- src/cfml/system/util/ForgeBox.cfc | 24 ++++++++++++------------ 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/cfml/system/endpoints/ForgeBox.cfc b/src/cfml/system/endpoints/ForgeBox.cfc index 6e7ac9dec..35ea7eb62 100644 --- a/src/cfml/system/endpoints/ForgeBox.cfc +++ b/src/cfml/system/endpoints/ForgeBox.cfc @@ -85,8 +85,15 @@ component accessors="true" implements="IEndpointInteractive" singleton { return result; } - // Verify in ForgeBox - var entryData = forgebox.getEntry( slug ); + try { + + // Verify in ForgeBox + var entryData = forgebox.getEntry( slug ); + + } catch( forgebox var e ) { + // This can include "expected" errors such as "Email already in use" + throw( e.message, 'endpointException', e.detail ); + } entryData.versions.sort( function( a, b ) { return semanticVersion.compare( b.version, a.version ) } ); diff --git a/src/cfml/system/util/ForgeBox.cfc b/src/cfml/system/util/ForgeBox.cfc index e69796552..576d07b95 100644 --- a/src/cfml/system/util/ForgeBox.cfc +++ b/src/cfml/system/util/ForgeBox.cfc @@ -68,7 +68,7 @@ or just add DEBUG to the root logger results = makeRequest(resource="types"); // error - if( results.error ){ + if( results.response.error ){ throw("Error making ForgeBox REST Call", 'forgebox', results.response.messages.toList() ); } @@ -108,7 +108,7 @@ or just add DEBUG to the root logger // Invoke call results = makeRequest(resource="entries",parameters=params); // error - if( results.error ){ + if( results.response.error ){ throw( "Error making ForgeBox REST Call", 'forgebox', results.response.messages.toList() ); } @@ -124,9 +124,9 @@ or just add DEBUG to the root logger // Invoke call results = makeRequest(resource="entry/#arguments.slug#"); - + // error - if( results.error ){ + if( results.response.error ){ throw( "Error getting ForgeBox entry [#arguments.slug#]", 'forgebox', results.response.messages.toList() ); } @@ -144,7 +144,7 @@ or just add DEBUG to the root logger results = makeRequest(resource="slug-check/#arguments.slug#"); // error - if( results.error ){ + if( results.response.error ){ throw( "Error making ForgeBox REST Call", 'forgebox', results.response.messages.toList() ); } @@ -196,7 +196,7 @@ or just add DEBUG to the root logger var results = makeRequest( resource="register", parameters=arguments, method='post' ); // error - if( results.error ){ + if( results.response.error ){ throw( "Sorry, the user could not be added.", 'forgebox', arrayToList( results.response.messages ) ); } @@ -213,7 +213,7 @@ or just add DEBUG to the root logger var results = makeRequest( resource="authenticate", parameters=arguments, method='post' ); // error - if( results.error ){ + if( results.response.error ){ throw( "Sorry, the user could not be logged in.", 'forgebox', arrayToList( results.response.messages ) ); } @@ -259,7 +259,7 @@ or just add DEBUG to the root logger method='post' ); // error - if( results.error ){ + if( results.response.error ){ throw( "Sorry, the package could not be published.", 'forgebox', arrayToList( results.response.messages ) ); } @@ -282,7 +282,7 @@ or just add DEBUG to the root logger var results = makeRequest( resource=thisResource, method='post', headers={ 'x-api-token' : arguments.APIToken } ); // error - if( results.error ){ + if( results.response.error ){ throw( "Something went wrong unplublishing.", 'forgebox', arrayToList( results.response.messages ) ); } @@ -305,7 +305,7 @@ or just add DEBUG to the root logger var results = makeRequest( resource=thisResource, method='post' ); // error - if( results.error ){ + if( results.response.error ){ throw( "Something went wrong tracking this installation.", 'forgebox', arrayToList( results.response.messages ) ); } @@ -327,7 +327,7 @@ or just add DEBUG to the root logger var results = makeRequest( resource=thisResource, method='post' ); // error - if( results.error ){ + if( results.response.error ){ throw( "Something went wrong tracking this download.", 'forgebox', arrayToList( results.response.messages ) ); } @@ -345,7 +345,7 @@ or just add DEBUG to the root logger var results = makeRequest( resource=thisResource, method='get', parameters={ typeSlug : arguments.typeSlug } ); // error - if( results.error ){ + if( results.response.error ){ throw( "Error searching for slugs", 'forgebox', arrayToList( results.response.messages ) ); } From 6f47941b51da6c1596e565614df504022b155e24 Mon Sep 17 00:00:00 2001 From: Jon Clausen Date: Tue, 26 Jul 2016 20:59:45 -0400 Subject: [PATCH 14/91] add SHA256 generation for all files & change hombrew stable sums to use integration server --- build/build.xml | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/build/build.xml b/build/build.xml index 5948f5474..50ecdd646 100644 --- a/build/build.xml +++ b/build/build.xml @@ -266,6 +266,7 @@ External Dependencies: + @@ -324,6 +325,7 @@ External Dependencies: + - + - - - - - - - - - + + + + + + + + + + + + + + + @@ -480,6 +488,7 @@ External Dependencies: + @@ -513,8 +522,10 @@ External Dependencies: + + @@ -556,6 +567,7 @@ External Dependencies: + @@ -602,6 +614,11 @@ External Dependencies: + + + + + @@ -647,6 +664,7 @@ External Dependencies: + Date: Tue, 26 Jul 2016 22:36:28 -0500 Subject: [PATCH 15/91] Fix sha256 path --- build/build.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/build/build.xml b/build/build.xml index 50ecdd646..1e919777d 100644 --- a/build/build.xml +++ b/build/build.xml @@ -266,7 +266,7 @@ External Dependencies: - + @@ -325,7 +325,7 @@ External Dependencies: - + - + - + @@ -522,10 +522,10 @@ External Dependencies: - + - + @@ -567,7 +567,7 @@ External Dependencies: - + @@ -664,7 +664,7 @@ External Dependencies: - + Date: Tue, 26 Jul 2016 23:04:38 -0500 Subject: [PATCH 16/91] Testing failure status --- build/build-auto.properties | 2 +- build/build.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/build-auto.properties b/build/build-auto.properties index 3c5e845d6..6c1e2a316 100644 --- a/build/build-auto.properties +++ b/build/build-auto.properties @@ -1,5 +1,5 @@ #java build -java.pack200=true +java.pack200=false #build locations build.type=auto diff --git a/build/build.xml b/build/build.xml index 1e919777d..f7755d3c4 100644 --- a/build/build.xml +++ b/build/build.xml @@ -413,7 +413,7 @@ External Dependencies: - + From 90543375c1c1c40e46842abd7dfae3c57bc27eeb Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 26 Jul 2016 23:58:13 -0500 Subject: [PATCH 17/91] Turn back on pack200 after testing --- build/build-auto.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build-auto.properties b/build/build-auto.properties index 6c1e2a316..3c5e845d6 100644 --- a/build/build-auto.properties +++ b/build/build-auto.properties @@ -1,5 +1,5 @@ #java build -java.pack200=false +java.pack200=true #build locations build.type=auto From 271c8578911bdc4ae49788cb1b754b8fb3952652 Mon Sep 17 00:00:00 2001 From: Jon Clausen Date: Wed, 27 Jul 2016 07:48:13 -0400 Subject: [PATCH 18/91] change git commands to use sudo --- build/build.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/build.xml b/build/build.xml index f7755d3c4..ab6cd0f49 100644 --- a/build/build.xml +++ b/build/build.xml @@ -413,7 +413,8 @@ External Dependencies: - + + From c9305f295660afc996d789211a995ee3122f8a80 Mon Sep 17 00:00:00 2001 From: Jon Clausen Date: Wed, 27 Jul 2016 10:59:55 -0400 Subject: [PATCH 19/91] Homebrew build updates to use sudo and allow empty commit messages in case shasum is the same --- build/build.xml | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/build/build.xml b/build/build.xml index ab6cd0f49..3c9cf4363 100644 --- a/build/build.xml +++ b/build/build.xml @@ -427,13 +427,31 @@ External Dependencies: - + + + + + + + + + - + + + + + + + + - + @@ -441,6 +459,14 @@ External Dependencies: + + + + + + + + From 446888fa41567526a8202dcf1d3410b1f3def768 Mon Sep 17 00:00:00 2001 From: Jon Clausen Date: Wed, 27 Jul 2016 14:44:45 -0400 Subject: [PATCH 20/91] fix stable version placeholders in brew template --- build/brew-template.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/brew-template.rb b/build/brew-template.rb index 819b45575..43f7fd921 100644 --- a/build/brew-template.rb +++ b/build/brew-template.rb @@ -1,7 +1,7 @@ class Commandbox < Formula desc "CFML embedded server, package manager, and app scaffolding tools" homepage "https://www.ortussolutions.com/products/commandbox" - url "@repoPRDURL@/ortussolutions/commandbox/@version@/commandbox-bin-@stable-version@.zip" + url "@repoPRDURL@/ortussolutions/commandbox/@stable-version@/commandbox-bin-@stable-version@.zip" sha256 "@stable-sha256@" version "@stable-version@" @@ -16,7 +16,7 @@ class Commandbox < Formula depends_on :java => "1.7+" resource "apidocs" do - url "@repoPRDURL@/ortussolutions/commandbox/@version@/commandbox-apidocs-@stable-version@.zip" + url "@repoPRDURL@/ortussolutions/commandbox/@stable-version@./commandbox-apidocs-@stable-version@.zip" sha256 "@apidocs.stable-sha256@" end From 5abf9ff4f573bc3043230e65a3d76e26dc0b48ba Mon Sep 17 00:00:00 2001 From: Jon Clausen Date: Wed, 27 Jul 2016 15:41:09 -0400 Subject: [PATCH 21/91] Homebrew: fix typo in URL --- build/brew-template.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/brew-template.rb b/build/brew-template.rb index 43f7fd921..ae47caaec 100644 --- a/build/brew-template.rb +++ b/build/brew-template.rb @@ -16,7 +16,7 @@ class Commandbox < Formula depends_on :java => "1.7+" resource "apidocs" do - url "@repoPRDURL@/ortussolutions/commandbox/@stable-version@./commandbox-apidocs-@stable-version@.zip" + url "@repoPRDURL@/ortussolutions/commandbox/@stable-version@/commandbox-apidocs-@stable-version@.zip" sha256 "@apidocs.stable-sha256@" end From cea09af2fe60f2c3048ec2ba66cf2dcb20243196 Mon Sep 17 00:00:00 2001 From: Jon Clausen Date: Wed, 27 Jul 2016 16:40:26 -0400 Subject: [PATCH 22/91] strip line breaks from sha file read - trim does not seem to be catching them --- build/build.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/build.xml b/build/build.xml index 3c9cf4363..30dd2fcaf 100644 --- a/build/build.xml +++ b/build/build.xml @@ -364,6 +364,7 @@ External Dependencies: + @@ -371,6 +372,7 @@ External Dependencies: + From 94515aa0638c2b175532775e0a5d1782cc052211 Mon Sep 17 00:00:00 2001 From: Jon Clausen Date: Wed, 27 Jul 2016 16:43:13 -0400 Subject: [PATCH 23/91] append query string devel url --- build/brew-template.rb | 2 +- build/build.xml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/build/brew-template.rb b/build/brew-template.rb index ae47caaec..ddcea9bbe 100644 --- a/build/brew-template.rb +++ b/build/brew-template.rb @@ -6,7 +6,7 @@ class Commandbox < Formula version "@stable-version@" devel do - url "@repoURL@/ortussolutions/commandbox/@version@/commandbox-bin-@version@.zip" + url "@repoURL@/ortussolutions/commandbox/@version@/commandbox-bin-@version@.zip?build=@buildnumber@" sha256 "@sha256@" version "@version@" end diff --git a/build/build.xml b/build/build.xml index 30dd2fcaf..47f0bb168 100644 --- a/build/build.xml +++ b/build/build.xml @@ -407,6 +407,9 @@ External Dependencies: @apidocs.stable-sha256@ + + @buildnumber@ + From fe63809109ed1758d0a3aea673379fe5f0062e54 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 3 Aug 2016 02:00:47 -0500 Subject: [PATCH 24/91] COMMANDBOX-424 --- src/cfml/system/util/Formatter.cfc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/cfml/system/util/Formatter.cfc b/src/cfml/system/util/Formatter.cfc index 0bfbeb6b2..bb11b4d09 100644 --- a/src/cfml/system/util/Formatter.cfc +++ b/src/cfml/system/util/Formatter.cfc @@ -88,7 +88,7 @@ component singleton { arguments.json = serializeJSON( arguments.json ); } - var retval = ''; + var retval = createObject("java","java.lang.StringBuilder").init(''); var str = json; var pos = 0; var strLen = str.length(); @@ -103,13 +103,13 @@ component singleton { if( isEscaped ) { isEscaped = false; - retval &= char; + retval.append( char ); continue; } if( char == '\' ) { isEscaped = true; - retval &= char; + retval.append( char ); continue; } @@ -119,34 +119,34 @@ component singleton { } else { inQuote = true; } - retval &= char; + retval.append( char ); continue; } if( inQuote ) { - retval &= char; + retval.append( char ); continue; } if (char == '}' || char == ']') { - retval &= newLine; + retval.append( newLine ); pos = pos - 1; for (var j=0; j Date: Wed, 3 Aug 2016 02:02:15 -0500 Subject: [PATCH 25/91] COMMANDBOX-425 --- src/cfml/system/services/ModuleService.cfc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/cfml/system/services/ModuleService.cfc b/src/cfml/system/services/ModuleService.cfc index ac16e1a53..ef3de18b5 100644 --- a/src/cfml/system/services/ModuleService.cfc +++ b/src/cfml/system/services/ModuleService.cfc @@ -21,6 +21,7 @@ + @@ -255,8 +256,14 @@ }; - // Load Module configuration from cfc and store it in module Config Cache - var oConfig = loadModuleConfiguration( mConfig, arguments.moduleName ); + try { + // Load Module configuration from cfc and store it in module Config Cache + var oConfig = loadModuleConfiguration( mConfig, arguments.moduleName ); + } catch( any var e ) { + consoleLogger.error( 'There was an error loading module [#arguments.moduleName#]' ); + consoleLogger.error( '#e.message##chr( 10 )##e.detail#' ); + return false; + } // Verify if module has been disabled if( mConfig.disabled ){ if( instance.logger.canDebug() ){ From 4e1024448d856468e5281af28c1b058d0116ff6a Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 3 Aug 2016 02:04:15 -0500 Subject: [PATCH 26/91] COMMANDBOX-425 --- .../modules/server-commands/commands/server/open.cfc | 8 ++++++++ 1 file changed, 8 insertions(+) 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 1266d65eb..3ed9ca379 100644 --- a/src/cfml/system/modules/server-commands/commands/server/open.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/open.cfc @@ -44,4 +44,12 @@ component { } } + + /** + * Complete server names + */ + function serverNameComplete() { + return serverService.getServerNames(); + } + } \ No newline at end of file From 30a4a50a7b2bce0ed9de1c65e61a3fd34e589d90 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 3 Aug 2016 02:05:27 -0500 Subject: [PATCH 27/91] COMMANDBOX-427 --- src/cfml/system/services/ServerService.cfc | 24 +++++++++++++--------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index e251ad803..9c254e5bd 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -341,9 +341,7 @@ component accessors="true" singleton { if( serverInfo.cfengine.endsWith( '@' ) ) { serverInfo.cfengine = left( serverInfo.cfengine, len( serverInfo.cfengine ) - 1 ); } - - interceptorService.announceInterception( 'onServerStart', { serverInfo=serverInfo } ); - + var launchUtil = java.LaunchUtil; // Setup lib directory, add more if defined by server info @@ -373,9 +371,10 @@ component accessors="true" singleton { // 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. + // This interception point can be used for additional configuration of the engine before it actually starts. interceptorService.announceInterception( 'onServerInstall', { serverInfo=serverInfo, installDetails=installDetails } ); thisVersion = ' ' & installDetails.version; + serverInfo.serverHome = installDetails.installDir; serverInfo.logdir = installDetails.installDir & "/logs"; // If external Lucee server, set the java agent @@ -418,7 +417,10 @@ component accessors="true" singleton { } } - + + // This is a WAR + } else { + serverInfo.serverHome = getDirectoryFromPath( serverInfo.WARPath ); } // Default tray icon @@ -437,8 +439,9 @@ component accessors="true" singleton { // This is due to a bug in RunWar not creating the right directory for the logs directoryCreate( serverInfo.logDir, true, true ); - - + + interceptorService.announceInterception( 'onServerStart', { serverInfo=serverInfo } ); + // 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#""" @@ -484,9 +487,6 @@ component accessors="true" singleton { args &= " --urlrewrite-file ""#serverInfo.rewritesConfig#"""; } - // Persist server information - setServerInfo( serverInfo ); - // change status to starting + persist serverInfo.status = "starting"; setServerInfo( serverInfo ); @@ -495,6 +495,7 @@ component accessors="true" singleton { var cleanedArgs = cr & ' ' & trim( replaceNoCase( args, ' -', cr & ' -', 'all' ) ); consoleLogger.debug("Server start command: #javaCommand# #cleanedArgs#"); } + // thread the execution var threadName = 'server#hash( serverInfo.webroot )##createUUID()#'; thread name="#threadName#" serverInfo=serverInfo args=args { @@ -802,6 +803,7 @@ component accessors="true" singleton { * @serverInfo.hint struct of server info (ports, etc.) **/ function setServerInfo( required struct serverInfo ){ + var servers = getServers(); var webrootHash = hash( arguments.serverInfo.webroot & ucase( arguments.serverInfo.name ) ); arguments.serverInfo.id = webrootHash; @@ -811,7 +813,9 @@ component accessors="true" singleton { } servers[ webrootHash ] = serverInfo; // persist back safely + setServers( servers ); + } /** From b38551b9ca36e8cc180427ed2401c2671e3b14fd Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Sat, 6 Aug 2016 23:13:05 -0500 Subject: [PATCH 28/91] COMMANDBOX-433 --- .../interceptors/packageScripts.cfc | 1 + src/cfml/system/services/InterceptorService.cfc | 2 +- src/cfml/system/services/PackageService.cfc | 16 +++++++++++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc b/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc index c1d6ac44d..c0e949277 100644 --- a/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc +++ b/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc @@ -25,6 +25,7 @@ component { function onServerStop() { processScripts( 'onServerStop', interceptData.serverinfo.webroot ); } function onException() { processScripts( 'onException' ); } function preInstall() { processScripts( 'preInstall' ); } + function onInstall() { processScripts( 'onInstall' ); } function postInstall() { processScripts( 'postInstall' ); } function preUninstall() { processScripts( 'preUninstall' ); } function postUninstall() { processScripts( 'postUninstall' ); } diff --git a/src/cfml/system/services/InterceptorService.cfc b/src/cfml/system/services/InterceptorService.cfc index a9f3ace05..69d811999 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','preVersion','postVersion','prePublish','postPublish','preUnpublish','postUnpublish','onRelease' + 'preInstall','onInstall','postInstall','preUninstall','postUninstall','preVersion','postVersion','prePublish','postPublish','preUnpublish','postUnpublish','onRelease' ] ); return this; diff --git a/src/cfml/system/services/PackageService.cfc b/src/cfml/system/services/PackageService.cfc index 5ebdcffc5..1652acd9c 100644 --- a/src/cfml/system/services/PackageService.cfc +++ b/src/cfml/system/services/PackageService.cfc @@ -150,7 +150,7 @@ component accessors="true" singleton { } /******************************************************************************************************************/ - // Now that we have resolved the directory where our packge lives, read the box.json out of it. + // Now that we have resolved the directory where our package lives, read the box.json out of it. var artifactDescriptor = readPackageDescriptor( tmpPath ); var ignorePatterns = ( isArray( artifactDescriptor.ignore ) ? artifactDescriptor.ignore : [] ); @@ -234,6 +234,20 @@ component accessors="true" singleton { } installDirectory = arguments.currentWorkingDirectory & '/' & artifactDescriptor.directory; } + + // Gather all the interesting things this interceptor might need to know. + var interceptData = { + installArgs = arguments, + installDirectory = installDirectory, + containerBoxJSON = containerBoxJSON, + artifactDescriptor = artifactDescriptor, + ignorePatterns = ignorePatterns, + endpointData = endpointData + }; + interceptorService.announceInterception( 'onInstall', interceptData ); + // Make sure these get set back into their original variables in case the interceptor changed them. + installDirectory = interceptData.installDirectory; + ignorePatterns = interceptData.ignorePatterns; // Else, use package type convention if( !len( installDirectory ) && len( packageType ) ) { From 850e8296e4d45ce90aeccebd5f2e2260a2d05a8a Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 8 Aug 2016 22:13:26 -0500 Subject: [PATCH 29/91] COMMANDBOX-436 #resolve Incorrect custom model path in the unit test --- .../modules/coldbox-commands/commands/coldbox/create/model.cfc | 3 +++ .../coldbox-commands/templates/testing/ModelBDDContent.txt | 2 +- .../templates/testing/ModelBDDContentScript.txt | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) 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 fdf4aa389..37819cfcb 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 @@ -53,6 +53,8 @@ component { boolean accessors=true, properties="" ) { + // store incoming relative path for testing purposes + var modelTestPath = arguments.directory; // This will make each directory canonical and absolute arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); arguments.testsDirectory = fileSystemUtil.resolvePath( arguments.testsDirectory ); @@ -93,6 +95,7 @@ component { modelContent = replaceNoCase( modelContent, '|modelName|', listLast( arguments.name, '/\' ), 'all' ); modelContent = replaceNoCase( modelContent, '|modelDescription|', arguments.description, 'all' ); modelTestContent = replaceNoCase( modelTestContent, '|modelName|', listChangeDelims( arguments.name, '.', '/\' ), 'all' ); + modelTestContent = replaceNoCase( modelTestContent, '|modelPath|', listChangeDelims( modelTestPath, '.', '/\' ) & "." & listChangeDelims( arguments.name, '.', '/\' ), 'all' ); // Persistence switch ( Persistence ) { 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 bbf7ff447..474eada2c 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 278fdba2a..0629d40db 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="models.|modelName|"{ +component extends="coldbox.system.testing.BaseModelTest" model="|modelPath|"{ /*********************************** LIFE CYCLE Methods ***********************************/ From 808a313796dc11a047d72d203d65ac7ec965f8ef Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 8 Aug 2016 22:15:08 -0500 Subject: [PATCH 30/91] removed non-used files, this will have to become tickets, but are just confusing users. --- .../coldbox-commands/commands/coldbox/compile.cfc | 13 ------------- .../commands/coldbox/integrate/ant.cfc | 13 ------------- .../commands/coldbox/integrate/cfuilder.cfc | 13 ------------- .../commands/coldbox/integrate/eclipse.cfc | 13 ------------- .../commands/coldbox/integrate/grunt.cfc | 13 ------------- .../commands/coldbox/integrate/help.cfc | 12 ------------ .../coldbox-commands/commands/coldbox/notes.cfc | 13 ------------- .../coldbox-commands/commands/coldbox/report/di.cfc | 13 ------------- .../commands/coldbox/report/handlers.cfc | 13 ------------- .../commands/coldbox/report/help.cfc | 12 ------------ .../commands/coldbox/report/routes.cfc | 13 ------------- .../coldbox-commands/commands/coldbox/stats.cfc | 13 ------------- .../commands/coldbox/test-directory.cfc | 13 ------------- .../commands/coldbox/test-watch.cfc | 13 ------------- .../coldbox-commands/commands/coldbox/test.cfc | 13 ------------- .../coldbox-commands/commands/coldbox/war.cfc | 13 ------------- 16 files changed, 206 deletions(-) delete mode 100644 src/cfml/system/modules/coldbox-commands/commands/coldbox/compile.cfc delete mode 100644 src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/ant.cfc delete mode 100644 src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/cfuilder.cfc delete mode 100644 src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/eclipse.cfc delete mode 100644 src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/grunt.cfc delete mode 100644 src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/help.cfc delete mode 100644 src/cfml/system/modules/coldbox-commands/commands/coldbox/notes.cfc delete mode 100644 src/cfml/system/modules/coldbox-commands/commands/coldbox/report/di.cfc delete mode 100644 src/cfml/system/modules/coldbox-commands/commands/coldbox/report/handlers.cfc delete mode 100644 src/cfml/system/modules/coldbox-commands/commands/coldbox/report/help.cfc delete mode 100644 src/cfml/system/modules/coldbox-commands/commands/coldbox/report/routes.cfc delete mode 100644 src/cfml/system/modules/coldbox-commands/commands/coldbox/stats.cfc delete mode 100644 src/cfml/system/modules/coldbox-commands/commands/coldbox/test-directory.cfc delete mode 100644 src/cfml/system/modules/coldbox-commands/commands/coldbox/test-watch.cfc delete mode 100644 src/cfml/system/modules/coldbox-commands/commands/coldbox/test.cfc delete mode 100644 src/cfml/system/modules/coldbox-commands/commands/coldbox/war.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/compile.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/compile.cfc deleted file mode 100644 index dce2a8c4e..000000000 --- a/src/cfml/system/modules/coldbox-commands/commands/coldbox/compile.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/coldbox-commands/commands/coldbox/integrate/ant.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/ant.cfc deleted file mode 100644 index dce2a8c4e..000000000 --- a/src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/ant.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/coldbox-commands/commands/coldbox/integrate/cfuilder.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/cfuilder.cfc deleted file mode 100644 index dce2a8c4e..000000000 --- a/src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/cfuilder.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/coldbox-commands/commands/coldbox/integrate/eclipse.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/eclipse.cfc deleted file mode 100644 index dce2a8c4e..000000000 --- a/src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/eclipse.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/coldbox-commands/commands/coldbox/integrate/grunt.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/grunt.cfc deleted file mode 100644 index dce2a8c4e..000000000 --- a/src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/grunt.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/coldbox-commands/commands/coldbox/integrate/help.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/help.cfc deleted file mode 100644 index 1b461a80c..000000000 --- a/src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/help.cfc +++ /dev/null @@ -1,12 +0,0 @@ -component excludeFromHelp=true { - - function run() { - - print.line(); - print.yellowLine( 'General help and description of how to use coldbox integrate' ); - print.line(); - print.line(); - - - } -} \ No newline at end of file diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/notes.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/notes.cfc deleted file mode 100644 index dce2a8c4e..000000000 --- a/src/cfml/system/modules/coldbox-commands/commands/coldbox/notes.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/coldbox-commands/commands/coldbox/report/di.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/report/di.cfc deleted file mode 100644 index dce2a8c4e..000000000 --- a/src/cfml/system/modules/coldbox-commands/commands/coldbox/report/di.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/coldbox-commands/commands/coldbox/report/handlers.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/report/handlers.cfc deleted file mode 100644 index dce2a8c4e..000000000 --- a/src/cfml/system/modules/coldbox-commands/commands/coldbox/report/handlers.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/coldbox-commands/commands/coldbox/report/help.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/report/help.cfc deleted file mode 100644 index f94e73aaa..000000000 --- a/src/cfml/system/modules/coldbox-commands/commands/coldbox/report/help.cfc +++ /dev/null @@ -1,12 +0,0 @@ -component excludeFromHelp=true { - - function run() { - - print.line(); - print.yellowLine( 'General help and description of how to use coldbox report' ); - print.line(); - print.line(); - - - } -} \ No newline at end of file diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/report/routes.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/report/routes.cfc deleted file mode 100644 index dce2a8c4e..000000000 --- a/src/cfml/system/modules/coldbox-commands/commands/coldbox/report/routes.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/coldbox-commands/commands/coldbox/stats.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/stats.cfc deleted file mode 100644 index dce2a8c4e..000000000 --- a/src/cfml/system/modules/coldbox-commands/commands/coldbox/stats.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/coldbox-commands/commands/coldbox/test-directory.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/test-directory.cfc deleted file mode 100644 index dce2a8c4e..000000000 --- a/src/cfml/system/modules/coldbox-commands/commands/coldbox/test-directory.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/coldbox-commands/commands/coldbox/test-watch.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/test-watch.cfc deleted file mode 100644 index dce2a8c4e..000000000 --- a/src/cfml/system/modules/coldbox-commands/commands/coldbox/test-watch.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/coldbox-commands/commands/coldbox/test.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/test.cfc deleted file mode 100644 index dce2a8c4e..000000000 --- a/src/cfml/system/modules/coldbox-commands/commands/coldbox/test.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/coldbox-commands/commands/coldbox/war.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/war.cfc deleted file mode 100644 index dce2a8c4e..000000000 --- a/src/cfml/system/modules/coldbox-commands/commands/coldbox/war.cfc +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Description of command - **/ -component { - - /** - * - **/ - function run( ) { - print.line( "Command not implemented!" ); - } - -} \ No newline at end of file From cf81326c7bd04464a5f7818739bd173198f05a2e Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 8 Aug 2016 22:17:27 -0500 Subject: [PATCH 31/91] COMMANDBOX-437 #resolve appSkeleton in the coldbox create app wizard needs to comply to IDs instead of local disk --- .../commands/coldbox/create/app-wizard.cfc | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/app-wizard.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/app-wizard.cfc index 366f18a1c..5eccd8808 100644 --- a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/app-wizard.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/app-wizard.cfc @@ -22,17 +22,9 @@ component extends="app" { ) { var skeletons = skeletonComplete(); // turn off wizard - arguments.wizard = false; - arguments.initWizard = true; - arguments.directory=getCWD(); - - // Validate skeletons - while( !arrayFindNoCase( skeletons, arguments.skeleton ) ){ - print.boldRedLine( "The skeleton you chose: '#arguments.skeleton#' is not valid." ) - .boldRedLine( " Valid Choices are (#arrayToList( skeletons, ", " )#)" ) - .toConsole(); - arguments.skeleton = ask( "Choose Skeleton: " ); - } + arguments.wizard = false; + arguments.initWizard = true; + arguments.directory = getCWD(); super.run( argumentCollection=arguments ); } From c89c57f77f96c22f734dd20f327fe46076e84918 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 8 Aug 2016 22:19:29 -0500 Subject: [PATCH 32/91] typo fixes --- .../coldbox-commands/commands/coldbox/create/app.cfc | 7 ++++--- 1 file changed, 4 insertions(+), 3 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 6152b8235..f6fd6d04b 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,12 +1,13 @@ /** -* Create a blank ColdBox app from one of our app skeletons. By default it will create -* in your current directory. +* Create a blank ColdBox app from one of our app skeletons or a skeleton using a valid Endpoint ID which can come from . +* ForgeBox, HTTP/S, git, github, etc. +* By default it will create the application in your current directory. * . * {code:bash} * coldbox create app myApp * {code} * . -* Here are the basic skeltons that are available for you. +* Here are the basic skeletons that are available for you that come from ForgeBox * - Advanced * - AdvancedScript (default) * - elixir From 9cc720fc26468707b1d2a39d8af18606cac46bd0 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 10 Aug 2016 15:16:15 -0500 Subject: [PATCH 33/91] COMMANDBOX-435 --- src/cfml/system/services/ArtifactService.cfc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/cfml/system/services/ArtifactService.cfc b/src/cfml/system/services/ArtifactService.cfc index 177aa3af9..715b190b7 100644 --- a/src/cfml/system/services/ArtifactService.cfc +++ b/src/cfml/system/services/ArtifactService.cfc @@ -67,13 +67,17 @@ component accessors="true" singleton { * Removes all artifacts from the cache and returns the number of wiped out directories */ numeric function cleanArtifacts() { - var dirList = directoryList( path=variables.artifactDir, recurse=false ); + var qryDir = directoryList( path=variables.artifactDir, recurse=false, listInfo='query' ); + var numRemoved = 0; - for( var dir in dirList ) { - directoryDelete( dir, true ); + for( var path in qryDir ) { + if( path.type == 'Dir' ) { + numRemoved++; + directoryDelete( path.directory & '/' & path.name, true ); + } } - return dirList.len(); + return numRemoved; } /** From 9f51f2af601b372c2a1ce71418df21965158f9c8 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Sat, 13 Aug 2016 23:28:16 -0500 Subject: [PATCH 34/91] Variables weren't always defined. --- src/cfml/system/services/ServerService.cfc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 9c254e5bd..dd1e16134 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -514,6 +514,9 @@ component accessors="true" singleton { serverInfo.statusInfo.result &= e.message & ' ' & e.detail; serverInfo.status="unknown"; } finally { + // make sure these don't come back as nulls + param name='local.executeResult' default=''; + param name='local.executeError' default=''; serverInfo.statusInfo.result = serverInfo.statusInfo.result & executeResult & ' ' & executeError; setServerInfo( serverInfo ); } From 8b9678e19ad989674c8df738929aea718cee251f Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 16 Aug 2016 14:39:50 -0500 Subject: [PATCH 35/91] COMMANDBOX-440 --- src/cfml/system/modules/system-commands/commands/repl.cfc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cfml/system/modules/system-commands/commands/repl.cfc b/src/cfml/system/modules/system-commands/commands/repl.cfc index aabe863e5..8c657b4f1 100644 --- a/src/cfml/system/modules/system-commands/commands/repl.cfc +++ b/src/cfml/system/modules/system-commands/commands/repl.cfc @@ -67,12 +67,12 @@ component { do { // ask repl if ( arrayLen( REPLParser.getCommandLines() ) == 0 ) { - var command = ask( ( arguments.script ? "CFSCRIPT" : "CFML" ) & "-REPL: " ); + var command = ask( ( arguments.script ? 'CFSCRIPT' : 'CFML' ) & '-REPL: ' ); } else { var command = ask( "..." ); // allow ability to break out of adding additional lines - if ( trim(command) == "exit" ) { + if ( trim(command) == 'exit' || trim(command) == '' ) { break; } } From 4820888b3e84fc52064e1a5b857cdd6a171403e2 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 16 Aug 2016 22:10:57 -0500 Subject: [PATCH 36/91] COMMANDBOX-442 --- src/cfml/system/services/ServerService.cfc | 35 ++++++++++++++-------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index dd1e16134..2300ab014 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -128,6 +128,7 @@ component accessors="true" singleton { host : d.web.host ?: '127.0.0.1', directoryBrowsing : d.web.directoryBrowsing ?: true, webroot : d.web.webroot ?: '', + aliases : d.web.aliases ?: {}, http : { port : d.web.http.port ?: 0, enable : d.web.http.enable ?: true @@ -300,6 +301,15 @@ component accessors="true" singleton { 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 ); + + // Double check that the port in the user params or server.json isn't in use + if( !isPortAvailable( serverInfo.host, serverInfo.port ) ) { + consoleLogger.error( "." ); + consoleLogger.error( "You asked for port [#( serverProps.port ?: serverJSON.web.http.port ?: '?' )#] in your #( serverProps.keyExists( 'port' ) ? 'start params' : 'server.json' )# but it's already in use so I'm ignoring it and choosing a random one for you." ); + consoleLogger.error( "." ); + 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; @@ -443,17 +453,18 @@ component accessors="true" singleton { interceptorService.announceInterception( 'onServerStart', { serverInfo=serverInfo } ); // 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 " & ( 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#""" - & " --directoryindex ""#serverInfo.directoryBrowsing#"" --cfml-web-config ""#serverInfo.webConfigDir#""" - & " --cfml-server-config ""#serverInfo.serverConfigDir#"" #serverInfo.runwarArgs# --timeout 120"; + 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 ' & ( 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#"' + & ' --directoryindex "#serverInfo.directoryBrowsing#" --cfml-web-config "#serverInfo.webConfigDir#"' +// & ' --dirs "/foo=C:\"' + & ' --cfml-server-config "#serverInfo.serverConfigDir#" #serverInfo.runwarArgs# --timeout 120'; // Starting a WAR if (serverInfo.WARPath != "" ) { @@ -491,7 +502,7 @@ component accessors="true" singleton { serverInfo.status = "starting"; setServerInfo( serverInfo ); - if(serverInfo.debug) { + if( serverInfo.debug ) { var cleanedArgs = cr & ' ' & trim( replaceNoCase( args, ' -', cr & ' -', 'all' ) ); consoleLogger.debug("Server start command: #javaCommand# #cleanedArgs#"); } From 25e362d954c104b7a161d5d6089dc34da114973c Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 16 Aug 2016 22:12:03 -0500 Subject: [PATCH 37/91] COMMANDBOX-443 --- src/cfml/system/services/ServerService.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 2300ab014..a47268e6d 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -539,7 +539,7 @@ component accessors="true" singleton { // If this is a one off command, wait for the thread to finish, otherwise the JVM will shutdown before // the server is started and the json files get updated. - if( shell.getShellType() == 'command' ) { + if( shell.getShellType() == 'command' || serverInfo.debug ) { thread action="join" name="#threadName#"; // Pull latest info that was saved in the thread and output it. Since we made the From 92499aed50a3b65fb99a9eaebf9e67190dce6ffa Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 16 Aug 2016 23:29:48 -0500 Subject: [PATCH 38/91] COMMANDBOX-444 --- src/cfml/system/services/ServerService.cfc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index a47268e6d..7187367d1 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -326,8 +326,13 @@ component accessors="true" singleton { serverInfo.rewritesConfig = serverProps.rewritesConfig ?: serverJSON.web.rewrites.config ?: defaults.web.rewrites.config; serverInfo.heapSize = serverProps.heapSize ?: serverJSON.JVM.heapSize ?: defaults.JVM.heapSize; 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; + + // Global defauls are always added on top of whatever is specified by the user or server.json + serverInfo.JVMargs = ( serverProps.JVMargs ?: serverJSON.JVM.args ?: '' ) & ' ' & defaults.JVM.args; + + serverInfo.runwarArgs = ( serverProps.runwarArgs ?: serverJSON.runwar.args ?: '' ) & ' ' & defaults.runwar.args; + // Global defauls are always added on top of whatever is specified by the user or server.json + serverInfo.cfengine = serverProps.cfengine ?: serverJSON.app.cfengine ?: defaults.app.cfengine; serverInfo.WARPath = serverProps.WARPath ?: serverJSON.app.WARPath ?: defaults.app.WARPath; @@ -451,7 +456,7 @@ component accessors="true" singleton { directoryCreate( serverInfo.logDir, true, true ); interceptorService.announceInterception( 'onServerStart', { serverInfo=serverInfo } ); - + // 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#"' From c56a7ff24fadbf7b5228d7b703e1cc6c42ef10e0 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 17 Aug 2016 00:10:32 -0500 Subject: [PATCH 39/91] COMMANDBOX-445 --- build/build.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/build.properties b/build/build.properties index f5e479b87..3e5feb0e6 100644 --- a/build/build.properties +++ b/build/build.properties @@ -12,12 +12,12 @@ java.pack200=false #dependencies dependencies.dir=${basedir}/lib cfml.version=4.5.2.018 -cfml.loader.version=1.3.3 +cfml.loader.version=1.3.4 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.5 +runwar.version=3.4.8 #build locations build.type=localdev From b3a2760b0347fd65b5963d6bd2c038a2dbbac136 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 17 Aug 2016 12:48:48 -0500 Subject: [PATCH 40/91] COMMANDBOX-445 --- src/cfml/system/services/ServerService.cfc | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 7187367d1..3e4e2a85f 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -327,6 +327,11 @@ component accessors="true" singleton { serverInfo.heapSize = serverProps.heapSize ?: serverJSON.JVM.heapSize ?: defaults.JVM.heapSize; serverInfo.directoryBrowsing = serverProps.directoryBrowsing ?: serverJSON.web.directoryBrowsing ?: defaults.web.directoryBrowsing; + // Global defaults are always added on top of server.json (but don't overwrite) + // Aliases aren't accepted via command params due to no cleam way to provide them + serverInfo.aliases = defaults.web.aliases; + serverInfo.aliases.append( serverJSON.web.aliases ?: {} ); + // Global defauls are always added on top of whatever is specified by the user or server.json serverInfo.JVMargs = ( serverProps.JVMargs ?: serverJSON.JVM.args ?: '' ) & ' ' & defaults.JVM.args; @@ -456,7 +461,14 @@ component accessors="true" singleton { directoryCreate( serverInfo.logDir, true, true ); interceptorService.announceInterception( 'onServerStart', { serverInfo=serverInfo } ); - + + // Turn struct of aliases into a comma-delimited list, plus resolve relative paths. + // "/foo=C:\path,/bar=C:\another/path" + var CLIAliases = ''; + for( var thisAlias in serverInfo.aliases ) { + CLIAliases = CLIAliases.listAppend( thisAlias & '=' & fileSystemUtil.resolvePath( serverInfo.aliases[ thisAlias ], serverInfo.webroot ) ); + } + // 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#"' @@ -468,7 +480,7 @@ component accessors="true" singleton { & ' --server-name "#serverInfo.name#"' & ' --tray-icon "#serverInfo.trayIcon#" --tray-config "#trayConfigJSON#"' & ' --directoryindex "#serverInfo.directoryBrowsing#" --cfml-web-config "#serverInfo.webConfigDir#"' -// & ' --dirs "/foo=C:\"' + & ( len( CLIAliases ) ? ' --dirs "#CLIAliases#"' : '' ) & ' --cfml-server-config "#serverInfo.serverConfigDir#" #serverInfo.runwarArgs# --timeout 120'; // Starting a WAR @@ -502,7 +514,6 @@ component accessors="true" singleton { } args &= " --urlrewrite-file ""#serverInfo.rewritesConfig#"""; } - // change status to starting + persist serverInfo.status = "starting"; setServerInfo( serverInfo ); From 7e35e42a20dc8348abee247d8dd1192c0cb75638 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 22 Aug 2016 11:45:13 -0500 Subject: [PATCH 41/91] COMMANDBOX-448 --- src/cfml/system/services/ServerEngineService.cfc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cfml/system/services/ServerEngineService.cfc b/src/cfml/system/services/ServerEngineService.cfc index 7917051eb..e69ba42c4 100644 --- a/src/cfml/system/services/ServerEngineService.cfc +++ b/src/cfml/system/services/ServerEngineService.cfc @@ -182,6 +182,7 @@ component accessors="true" singleton="true" { for( var thisFile in directoryList( thisTempDir ) ) { if( listFindNoCase( 'war,zip', listLast( thisFile, '.' ) ) ) { theArchive = thisFile; + break; } } @@ -191,7 +192,7 @@ component accessors="true" singleton="true" { } consoleLogger.info( "Exploding WAR/zip archive..."); - zip action="unzip" file="#thisFile#" destination="#installDetails.installDir#" overwrite="true"; + zip action="unzip" file="#theArchive#" destination="#installDetails.installDir#" overwrite="true"; // Catch this to gracefully handle where the OS or another program // has the folder locked. From 4374db40580ac725b7af89322250a17727a92d57 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 22 Aug 2016 18:26:12 -0500 Subject: [PATCH 42/91] COMMANDBOX-428 --- src/cfml/system/services/ArtifactService.cfc | 11 +++- src/cfml/system/services/ServerService.cfc | 59 ++++++++++++++++---- 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/src/cfml/system/services/ArtifactService.cfc b/src/cfml/system/services/ArtifactService.cfc index 715b190b7..bfdb4badd 100644 --- a/src/cfml/system/services/ArtifactService.cfc +++ b/src/cfml/system/services/ArtifactService.cfc @@ -234,8 +234,15 @@ component accessors="true" singleton { * @version Version range to satisfy */ function findSatisfyingVersion( required string slug, required string version ) { + var artifacts = listArtifacts( slug ); + + // Check to see if we even have any versions for this artifact + if( !artifacts.keyExists( slug ) ) { + return ''; + } + // Get the locally-stored versions - var arrVersions = listArtifacts( slug )[ slug ]; + var arrVersions = artifacts[ slug ]; // Sort them arrVersions.sort( function( a, b ) { return semanticVersion.compare( b.version, a.version ) } ); @@ -251,7 +258,7 @@ component accessors="true" singleton { if( arguments.version == 'stable' && arrayLen( arrVersions ) ) { return arrVersions[ 1 ]; } else { - return ''; + return ''; } } diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 3e4e2a85f..3906f3b95 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -120,6 +120,7 @@ component accessors="true" singleton { stopsocket : d.stopsocket ?: 0, debug : d.debug ?: false, trayicon : d.trayicon ?: '', + trayOptions : d.trayOptions ?: [], jvm : { heapSize : d.jvm.heapSize ?: 512, args : d.jvm.args ?: '' @@ -327,16 +328,21 @@ component accessors="true" singleton { serverInfo.heapSize = serverProps.heapSize ?: serverJSON.JVM.heapSize ?: defaults.JVM.heapSize; serverInfo.directoryBrowsing = serverProps.directoryBrowsing ?: serverJSON.web.directoryBrowsing ?: defaults.web.directoryBrowsing; - // Global defaults are always added on top of server.json (but don't overwrite) - // Aliases aren't accepted via command params due to no cleam way to provide them + // Global aliases are always added on top of server.json (but don't overwrite) + // Aliases aren't accepted via command params due to no clean way to provide them serverInfo.aliases = defaults.web.aliases; serverInfo.aliases.append( serverJSON.web.aliases ?: {} ); + + // Global trayOptions are always added on top of server.json (but don't overwrite) + // trayOptions aren't accepted via command params due to no clean way to provide them + serverInfo.trayOptions = defaults.trayOptions; + serverInfo.trayOptions.append( serverJSON.trayOptions ?: [], true ); // Global defauls are always added on top of whatever is specified by the user or server.json serverInfo.JVMargs = ( serverProps.JVMargs ?: serverJSON.JVM.args ?: '' ) & ' ' & defaults.JVM.args; - serverInfo.runwarArgs = ( serverProps.runwarArgs ?: serverJSON.runwar.args ?: '' ) & ' ' & defaults.runwar.args; // Global defauls are always added on top of whatever is specified by the user or server.json + 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; @@ -447,16 +453,41 @@ component accessors="true" singleton { 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'; + // Set default options for all servers + // TODO: Don't overwrite existing options with the same label. + serverInfo.trayOptions.append( + [ + { 'label':'Stop Server (${runwar.processName})', 'action':'stopserver' }, + { 'label':'Open Browser', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/' } + ], + true + ); + 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'; + serverInfo.trayOptions.append( + [ + { 'label':'Open Server Admin', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/lucee/admin/server.cfm' }, + { 'label':'Open Web Admin', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/lucee/admin/web.cfm' } + ], + true + ); + } else if( serverInfo.cfengine contains "railo" ) { + serverInfo.trayOptions.append( + [ + { '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' } + ], + true + ); + } else if( serverInfo.cfengine contains "adobe" ) { + serverInfo.trayOptions.append( + [ + { 'label':'Open Server Admin', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/CFIDE/administrator/enter.cfm' } + ], + true + ); } - + // This is due to a bug in RunWar not creating the right directory for the logs directoryCreate( serverInfo.logDir, true, true ); @@ -468,6 +499,10 @@ component accessors="true" singleton { for( var thisAlias in serverInfo.aliases ) { CLIAliases = CLIAliases.listAppend( thisAlias & '=' & fileSystemUtil.resolvePath( serverInfo.aliases[ thisAlias ], serverInfo.webroot ) ); } + + // Serialize tray options and write to temp file + var trayOptionsPath = serverInfo.serverHome & '/trayOptions.json'; + fileWrite( trayOptionsPath, serializeJSON( serverInfo.trayOptions ) ); // The java arguments to execute: Shared server, custom web configs var args = ' #serverInfo.JVMargs# -Xmx#serverInfo.heapSize#m -Xms#serverInfo.heapSize#m' @@ -478,7 +513,7 @@ component accessors="true" singleton { & ' --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#"' + & ' --tray-icon "#serverInfo.trayIcon#" --tray-config "#trayOptionsPath#"' & ' --directoryindex "#serverInfo.directoryBrowsing#" --cfml-web-config "#serverInfo.webConfigDir#"' & ( len( CLIAliases ) ? ' --dirs "#CLIAliases#"' : '' ) & ' --cfml-server-config "#serverInfo.serverConfigDir#" #serverInfo.runwarArgs# --timeout 120'; From 89e86c53f21381dfc4796621e21c53d8355e5ce7 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 22 Aug 2016 18:34:50 -0500 Subject: [PATCH 43/91] COMMANDBOX-428 --- src/cfml/system/services/ServerService.cfc | 41 ++++++---------------- 1 file changed, 11 insertions(+), 30 deletions(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 3906f3b95..faaef81db 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -455,39 +455,20 @@ component accessors="true" singleton { // Set default options for all servers // TODO: Don't overwrite existing options with the same label. - serverInfo.trayOptions.append( - [ - { 'label':'Stop Server (${runwar.processName})', 'action':'stopserver' }, - { 'label':'Open Browser', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/' } - ], - true - ); - if( serverInfo.cfengine contains "lucee" ) { - serverInfo.trayOptions.append( - [ - { 'label':'Open Server Admin', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/lucee/admin/server.cfm' }, - { 'label':'Open Web Admin', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/lucee/admin/web.cfm' } - ], - true - ); - } else if( serverInfo.cfengine contains "railo" ) { - serverInfo.trayOptions.append( - [ - { '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' } - ], - true - ); - } else if( serverInfo.cfengine contains "adobe" ) { - serverInfo.trayOptions.append( - [ - { 'label':'Open Server Admin', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/CFIDE/administrator/enter.cfm' } - ], - true - ); + if( serverInfo.cfengine contains "lucee" ) { + serverInfo.trayOptions.prepend( { 'label':'Open Web Admin', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/lucee/admin/web.cfm' } ); + serverInfo.trayOptions.prepend( { 'label':'Open Server Admin', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/lucee/admin/server.cfm' } ); + } else if( serverInfo.cfengine contains "railo" ) { + serverInfo.trayOptions.prepend( { 'label':'Open Web Admin', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/railo-context/admin/web.cfm' } ); + serverInfo.trayOptions.prepend( { 'label':'Open Server Admin', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/railo-context/admin/server.cfm' } ); + } else if( serverInfo.cfengine contains "adobe" ) { + serverInfo.trayOptions.prepend( { 'label':'Open Server Admin', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/CFIDE/administrator/enter.cfm' } ); } + serverInfo.trayOptions.prepend( { 'label':'Open Browser', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/' } ); + serverInfo.trayOptions.prepend( { 'label':'Stop Server (${runwar.processName})', 'action':'stopserver' } ); + // This is due to a bug in RunWar not creating the right directory for the logs directoryCreate( serverInfo.logDir, true, true ); From b9a2bf42890053169bde35b4f9d5c21ad72eae97 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 23 Aug 2016 01:07:26 -0500 Subject: [PATCH 44/91] COMMANDBOX-428 --- src/cfml/system/services/ServerService.cfc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index faaef81db..97decf3c9 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -120,7 +120,8 @@ component accessors="true" singleton { stopsocket : d.stopsocket ?: 0, debug : d.debug ?: false, trayicon : d.trayicon ?: '', - trayOptions : d.trayOptions ?: [], + // Duplicate so onServerStart interceptors don't actually change config settings via refernce. + trayOptions : duplicate( d.trayOptions ?: [] ), jvm : { heapSize : d.jvm.heapSize ?: 512, args : d.jvm.args ?: '' @@ -129,7 +130,8 @@ component accessors="true" singleton { host : d.web.host ?: '127.0.0.1', directoryBrowsing : d.web.directoryBrowsing ?: true, webroot : d.web.webroot ?: '', - aliases : d.web.aliases ?: {}, + // Duplicate so onServerStart interceptors don't actually change config settings via refernce. + aliases : duplicate( d.web.aliases ?: {} ), http : { port : d.web.http.port ?: 0, enable : d.web.http.enable ?: true From f8881ac1c1c84481c326151ad09a43a2cb248b74 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 23 Aug 2016 12:51:14 -0500 Subject: [PATCH 45/91] Reverting this until 3.4.9 is ready. --- build/build.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/build.properties b/build/build.properties index 3e5feb0e6..86a2a7976 100644 --- a/build/build.properties +++ b/build/build.properties @@ -12,12 +12,12 @@ java.pack200=false #dependencies dependencies.dir=${basedir}/lib cfml.version=4.5.2.018 -cfml.loader.version=1.3.4 +cfml.loader.version=1.3.5 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.8 +runwar.version=3.4.5 #build locations build.type=localdev From 6200562d8cdee56b074e27081145ff59956cba1a Mon Sep 17 00:00:00 2001 From: Ben Bluemel Date: Thu, 25 Aug 2016 16:20:07 +0100 Subject: [PATCH 46/91] server open should use host specified in server.json --- .../system/modules/server-commands/commands/server/open.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 3ed9ca379..9ada1eab6 100644 --- a/src/cfml/system/modules/server-commands/commands/server/open.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/open.cfc @@ -36,7 +36,7 @@ component { 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#"; + var thisURL = "#serverInfo.host#:#serverInfo.port##arguments.URI#"; print.greenLine( "Opening...#thisURL#" ); openURL( thisURL ); From 13161ea0e6a41ed80c372c15a6565c8b0253ea96 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 1 Sep 2016 18:48:50 -0500 Subject: [PATCH 47/91] COMMANDBOX-451 --- .../server-commands/commands/server/start.cfc | 22 ++++---- src/cfml/system/services/ServerService.cfc | 51 ++++++++++++++----- 2 files changed, 47 insertions(+), 26 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 68a17c68f..e2d195286 100644 --- a/src/cfml/system/modules/server-commands/commands/server/start.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/start.cfc @@ -58,7 +58,7 @@ component aliases="start" { * @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 + * @trayIconFile path to .png file for tray icon * @webXML path to web.xml file used to configure the server * @HTTPEnable enable HTTP * @SSLEnable enable SSL @@ -91,7 +91,7 @@ component aliases="start" { String webConfigDir, String serverConfigDir, String libDirs, - String trayIcon, + String trayIconFile, String webXML, Boolean HTTPEnable, Boolean SSLEnable, @@ -110,16 +110,6 @@ component aliases="start" { String WARPath, 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 ); - } // This is a common mis spelling if( structKeyExists( arguments, 'rewritesEnabled' ) ) { @@ -128,7 +118,13 @@ component aliases="start" { arguments.rewritesEnable = arguments.rewritesEnabled; structDelete( arguments, 'rewritesEnabled' ); } - + + // changed trayIcon to trayIconFile, but let's keep them both working for backwards compat + if( structKeyExists( arguments, 'trayIconFile' ) ) { + arguments.trayIcon = arguments.trayIconFile; + structDelete( arguments, 'trayIconFile' ); + } + try { // startup the server diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 97decf3c9..336c0cbeb 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -179,6 +179,7 @@ component accessors="true" singleton { var defaultName = serverDetails.defaultName; var defaultwebroot = serverDetails.defaultwebroot; var defaultServerConfigFile = serverDetails.defaultServerConfigFile; + var defaultServerConfigFileDirectory = getDirectoryFromPath( defaultServerConfigFile ); var serverJSON = serverDetails.serverJSON; var serverInfo = serverDetails.serverinfo; @@ -186,7 +187,7 @@ component accessors="true" singleton { // Backwards compat for default port in box.json. Remove this eventually... // * // * // Get package descriptor // * - var boxJSON = packageService.readPackageDescriptor( serverInfo.webroot ); // * + var boxJSON = packageService.readPackageDescriptor( defaultwebroot ); // * // Get defaults // * var defaults = getDefaultServerJSON(); // * // * @@ -200,11 +201,25 @@ component accessors="true" singleton { // * // Update box.json to remove defaultPort from disk // * boxJSON.delete( 'defaultPort' ); // * - packageService.writePackageDescriptor( boxJSON, serverInfo.webroot ); // * + packageService.writePackageDescriptor( boxJSON, defaultwebroot ); // * } // * // * // End backwards compat for default port in box.json. // * // ************************************************************************************* + + // Resolve path as used locally + if( !isNull( serverProps.directory ) ) { + serverProps.directory = fileSystemUtil.resolvePath( serverProps.directory ); + } + if( !isNull( serverProps.serverConfigFile ) ) { + serverProps.serverConfigFile = fileSystemUtil.resolvePath( serverProps.serverConfigFile ); + } + if( !isNull( serverProps.WARPath ) ) { + serverProps.WARPath = fileSystemUtil.resolvePath( serverProps.WARPath ); + } + if( !isNull( serverProps.trayIcon ) ) { + serverProps.trayIcon = fileSystemUtil.resolvePath( serverProps.trayIcon ); + } // Save hand-entered properties in our server.json for next time for( var prop in serverProps ) { @@ -222,14 +237,24 @@ component accessors="true" singleton { break; case "directory": // Both of these are canonical already. - var thisDirectory = replace( serverProps[ prop ], '\', '/', 'all' ) & '/'; - var configPath = replace( fileSystemUtil.resolvePath( getDirectoryFromPath( defaultServerConfigFile ) ), '\', '/', 'all' ) & '/'; + var thisDirectory = replace( serverProps[ 'directory' ], '\', '/', 'all' ) & '/'; + var configPath = replace( fileSystemUtil.resolvePath( defaultServerConfigFileDirectory ), '\', '/', '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 "trayIcon": + // Both of these are canonical already. + var thisDirectory = replace( serverProps[ 'trayIcon' ], '\', '/', 'all' ) & '/'; + var configPath = replace( fileSystemUtil.resolvePath( defaultServerConfigFileDirectory ), '\', '/', 'all' ) & '/'; + // If the trayIcon is south of the server's JSON, make it relative for better portability. + if( thisDirectory contains configPath ) { + thisDirectory = replaceNoCase( thisDirectory, configPath, '' ); + } + serverJSON[ 'trayIcon' ] = thisDirectory; + break; case "stopPort": serverJSON[ 'stopsocket' ] = serverProps[ prop ]; break; @@ -292,8 +317,7 @@ component accessors="true" singleton { if( !serverJSON.isEmpty() && serverProps.saveSettings ) { 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 @@ -317,6 +341,8 @@ component accessors="true" singleton { serverInfo.webConfigDir = serverProps.webConfigDir ?: serverJSON.app.webConfigDir ?: getCustomServerFolder( serverInfo ); serverInfo.serverConfigDir = serverProps.serverConfigDir ?: serverJSON.app.serverConfigDir ?: defaults.app.serverConfigDir; serverInfo.libDirs = serverProps.libDirs ?: serverJSON.app.libDirs ?: defaults.app.libDirs; + if( serverJSON.keyExists( 'trayIcon' ) ) { serverJSON.trayIcon = fileSystemUtil.resolvePath( serverJSON.trayIcon, defaultServerConfigFileDirectory ); } + if( defaults.keyExists( 'trayIcon' ) ) { defaults.trayIcon = fileSystemUtil.resolvePath( defaults.trayIcon, defaultwebroot ); } serverInfo.trayIcon = serverProps.trayIcon ?: serverJSON.trayIcon ?: defaults.trayIcon; serverInfo.webXML = serverProps.webXML ?: serverJSON.app.webXML ?: defaults.app.webXML; serverInfo.SSLEnable = serverProps.SSLEnable ?: serverJSON.web.SSL.enable ?: defaults.web.SSL.enable; @@ -345,6 +371,9 @@ component accessors="true" singleton { // Global defauls are always added on top of whatever is specified by the user or server.json serverInfo.runwarArgs = ( serverProps.runwarArgs ?: serverJSON.runwar.args ?: '' ) & ' ' & defaults.runwar.args; + + // Global defauls are always added on top of whatever is specified by the user or server.json + serverInfo.libDirs = ( serverProps.libDirs ?: serverJSON.app.libDirs ?: '' ).listAppend( defaults.app.libDirs ); serverInfo.cfengine = serverProps.cfengine ?: serverJSON.app.cfengine ?: defaults.app.cfengine; serverInfo.WARPath = serverProps.WARPath ?: serverJSON.app.WARPath ?: defaults.app.WARPath; @@ -371,12 +400,6 @@ component accessors="true" singleton { } var launchUtil = java.LaunchUtil; - - // Setup lib directory, add more if defined by server info - var libDirs = variables.libDir; - if ( Len( Trim( serverInfo.libDirs ?: "" ) ) ) { - libDirs = ListAppend( libDirs, serverInfo.libDirs ); - } // log directory location if( !directoryExists( serverInfo.logDir ) ){ directoryCreate( serverInfo.logDir ); } @@ -509,7 +532,9 @@ component accessors="true" singleton { 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#"""; + // The internal server borrows the CommandBox lib directory + serverInfo.libDirs = serverInfo.libDirs.listAppend( variables.libDir ); + args &= " -war ""#serverInfo.webroot#"" --lib-dirs ""#serverInfo.libDirs#"""; } // Incorporate SSL to command if( serverInfo.SSLEnable ){ From a736130029bd277e9d9853fb9d1f62e76e8601cf Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 1 Sep 2016 18:55:20 -0500 Subject: [PATCH 48/91] COMMANDBOX-454 --- build/build.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/build.properties b/build/build.properties index 86a2a7976..b21c05c6b 100644 --- a/build/build.properties +++ b/build/build.properties @@ -12,12 +12,12 @@ java.pack200=false #dependencies dependencies.dir=${basedir}/lib cfml.version=4.5.2.018 -cfml.loader.version=1.3.5 +cfml.loader.version=1.3.6 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.5 +runwar.version=3.4.9 #build locations build.type=localdev From dcccf22ce3faa9793acb37cfb1470dcbd256fe1b Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 1 Sep 2016 19:00:45 -0500 Subject: [PATCH 49/91] COMMANDBOX-454 --- build/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build.properties b/build/build.properties index b21c05c6b..8b6d12a62 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.9 +runwar.version=3.4.9-SNAPSHOT #build locations build.type=localdev From a27f400b399f4e289e06c349b24c7aa33da95dc4 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 1 Sep 2016 19:53:29 -0500 Subject: [PATCH 50/91] breaks headless servers --- build/build.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/build.properties b/build/build.properties index 8b6d12a62..73907da3a 100644 --- a/build/build.properties +++ b/build/build.properties @@ -17,7 +17,8 @@ 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.9-SNAPSHOT +runwar.version=3.4.5 +#runwar.version=3.4.9-SNAPSHOT #build locations build.type=localdev From 6a81ff2eedf502378d32476734fce9830bbf31c6 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 1 Sep 2016 22:23:48 -0500 Subject: [PATCH 51/91] Trying 3.4.9 again --- build/build.properties | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build/build.properties b/build/build.properties index 73907da3a..8b6d12a62 100644 --- a/build/build.properties +++ b/build/build.properties @@ -17,8 +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.5 -#runwar.version=3.4.9-SNAPSHOT +runwar.version=3.4.9-SNAPSHOT #build locations build.type=localdev From 693c72d0006a14200511964e0a660010473b7acc Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 1 Sep 2016 23:55:22 -0500 Subject: [PATCH 52/91] Default icon messed up --- src/cfml/system/services/ServerService.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 336c0cbeb..0f020367e 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -342,7 +342,7 @@ component accessors="true" singleton { serverInfo.serverConfigDir = serverProps.serverConfigDir ?: serverJSON.app.serverConfigDir ?: defaults.app.serverConfigDir; serverInfo.libDirs = serverProps.libDirs ?: serverJSON.app.libDirs ?: defaults.app.libDirs; if( serverJSON.keyExists( 'trayIcon' ) ) { serverJSON.trayIcon = fileSystemUtil.resolvePath( serverJSON.trayIcon, defaultServerConfigFileDirectory ); } - if( defaults.keyExists( 'trayIcon' ) ) { defaults.trayIcon = fileSystemUtil.resolvePath( defaults.trayIcon, defaultwebroot ); } + if( defaults.keyExists( 'trayIcon' ) && len( defaults.trayIcon ) ) { defaults.trayIcon = fileSystemUtil.resolvePath( defaults.trayIcon, defaultwebroot ); } serverInfo.trayIcon = serverProps.trayIcon ?: serverJSON.trayIcon ?: defaults.trayIcon; serverInfo.webXML = serverProps.webXML ?: serverJSON.app.webXML ?: defaults.app.webXML; serverInfo.SSLEnable = serverProps.SSLEnable ?: serverJSON.web.SSL.enable ?: defaults.web.SSL.enable; From 661297d07b9db2efba084abcd70a2dd6d935ab42 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Fri, 2 Sep 2016 16:39:22 -0500 Subject: [PATCH 53/91] COMMANDBOX-455 --- src/cfml/system/services/ArtifactService.cfc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cfml/system/services/ArtifactService.cfc b/src/cfml/system/services/ArtifactService.cfc index bfdb4badd..7689f1872 100644 --- a/src/cfml/system/services/ArtifactService.cfc +++ b/src/cfml/system/services/ArtifactService.cfc @@ -243,9 +243,8 @@ component accessors="true" singleton { // Get the locally-stored versions var arrVersions = artifacts[ slug ]; - // Sort them - arrVersions.sort( function( a, b ) { return semanticVersion.compare( b.version, a.version ) } ); + arrVersions.sort( function( a, b ) { return semanticVersion.compare( b, a ) } ); var found = false; for( var thisVersion in arrVersions ) { From 815591a67d4836bf046f4d029c7943966e95f4c1 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Fri, 9 Sep 2016 13:22:46 -0500 Subject: [PATCH 54/91] forgebox registration blurb --- .../commands/forgebox/login.cfc | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/login.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/login.cfc index 5021796cc..78aa72636 100644 --- a/src/cfml/system/modules/forgebox-commands/commands/forgebox/login.cfc +++ b/src/cfml/system/modules/forgebox-commands/commands/forgebox/login.cfc @@ -12,12 +12,29 @@ component { * @password.hint Password for this user **/ function run( - required string username, - required string password ) { - + string username, + string password + ){ + // Default the endpointName arguments.endpointName = 'forgebox'; - + + // Info for ForgeBox + print.line( "Login with your ForgeBox ID to publish and manage packages in Forgebox.io. ") + .line( "If you don't have a ForgeBox ID, head over to https://www.forgebox.io to create one or just use the" ) + .boldRed( " forgebox register ") + .line( "command to register a new account.") + .line() + .toConsole(); + + // Ask for username/password if not passed + if( !len( arguments.username ) ) { + arguments.username = ask( 'Enter your username: ' ); + } + if( !len( arguments.password ) ) { + arguments.password = ask( 'Enter your password: ', '*' ); + } + // Defer to the generic command command( 'endpoint login' ) .params( argumentCollection=arguments ) From 25d9f76e1ab923001e407cdb4a8c90eeb320daf1 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Fri, 9 Sep 2016 13:37:37 -0500 Subject: [PATCH 55/91] Tweaked registration blurb --- .../commands/forgebox/login.cfc | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/login.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/login.cfc index 78aa72636..56a37f45a 100644 --- a/src/cfml/system/modules/forgebox-commands/commands/forgebox/login.cfc +++ b/src/cfml/system/modules/forgebox-commands/commands/forgebox/login.cfc @@ -12,28 +12,37 @@ component { * @password.hint Password for this user **/ function run( - string username, - string password + string username='', + string password='' ){ // Default the endpointName arguments.endpointName = 'forgebox'; - // Info for ForgeBox - print.line( "Login with your ForgeBox ID to publish and manage packages in Forgebox.io. ") - .line( "If you don't have a ForgeBox ID, head over to https://www.forgebox.io to create one or just use the" ) - .boldRed( " forgebox register ") - .line( "command to register a new account.") - .line() - .toConsole(); - - // Ask for username/password if not passed + // Ask for username if not passed if( !len( arguments.username ) ) { + + // Info for ForgeBox + print.line() + .line( "Login with your ForgeBox ID to publish and manage packages in Forgebox.io. ") + .line( "If you don't have a ForgeBox ID, head over to https://www.forgebox.io to create one or just use the" ) + .boldRed( " forgebox register ") + .line( "command to register a new account.") + .line() + .toConsole(); + arguments.username = ask( 'Enter your username: ' ); } + + // Ask for password if not passed if( !len( arguments.password ) ) { arguments.password = ask( 'Enter your password: ', '*' ); } + + // Message user since there can be a couple-second delay here + print.line() + .yellowLine( 'Contacting ForgeBox...' ) + .toConsole(); // Defer to the generic command command( 'endpoint login' ) From a732af365aa9ddd5fdf390f22ad49a044a2dbaef Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 12 Sep 2016 18:49:15 -0700 Subject: [PATCH 56/91] Better detect running servers --- .../server-commands/commands/server/forget.cfc | 17 ++++++++++++++++- .../server-commands/commands/server/list.cfc | 5 ++--- .../server-commands/commands/server/status.cfc | 2 +- src/cfml/system/services/ServerService.cfc | 9 +++++++++ 4 files changed, 28 insertions(+), 5 deletions(-) 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 33ec34465..2a4891e49 100644 --- a/src/cfml/system/modules/server-commands/commands/server/forget.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/forget.cfc @@ -38,8 +38,15 @@ component { } var serverInfo = serverService.resolveServerDetails( arguments ).serverinfo; + if( arguments.all ) { + var servers = serverService.getServers(); + servers.each( function( ID ){ runningServerCheck( servers[ arguments.ID ] ); } ); + } else { + runningServerCheck( serverInfo ); + } + // Confirm deletion - var askMessage = arguments.all ? "Really forget & delete all servers (servers=#arrayToList( serverService.getServerNames() )#) forever [y/n]?" : + var askMessage = arguments.all ? "Really forget & delete all servers (#arrayToList( serverService.getServerNames() )#) forever [y/n]?" : "Really forget & delete server '#serverinfo.name#' forever [y/n]?"; if( arguments.force || confirm( askMessage ) ){ @@ -50,6 +57,14 @@ component { } + private function runningServerCheck( required struct serverInfo ) { + if( serverService.isServerRunning( serverInfo ) ) { + print.redBoldLine( 'Server "#serverInfo.name#" (#serverInfo.webroot#) appears to still be running!' ) + .yellowLine( 'Forgetting it now may leave the server in a currupt state. Please stop it first.' ) + .line(); + } + } + function serverNameComplete() { return serverService.getServerNames(); } 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 c34e89956..bd712dbb4 100644 --- a/src/cfml/system/modules/server-commands/commands/server/list.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/list.cfc @@ -66,17 +66,16 @@ component { for( var thisKey in servers ){ var thisServerInfo = servers[ thisKey ]; + var status = serverService.isServerRunning( thisServerInfo ) ? 'running' : 'stopped'; // Check name and status filters. By default, everything shows if( ( !len( arguments.name ) || listFindNoCase( arguments.name, thisServerInfo.name ) ) - && ( !len( statusList ) || listFindNoCase( statusList, thisServerInfo.status ) ) ) { + && ( !len( statusList ) || listFindNoCase( statusList, status ) ) ) { // Null Checks, to guarnatee correct struct. structAppend( thisServerInfo, serverService.newServerInfoStruct(), false ); print.line().boldText( thisServerInfo.name ); - - var status = thisServerInfo.status; print.boldtext( ' (' ) .bold( status, statusColors.keyExists( status ) ? statusColors[ status ] : 'yellow' ) .bold( ')' ) 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 c39fbe2c8..a03836c2d 100644 --- a/src/cfml/system/modules/server-commands/commands/server/status.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/status.cfc @@ -100,7 +100,7 @@ component aliases='status,server info' { print.line().boldText( thisServerInfo.name ); - var status = thisServerInfo.status; + var status = serverService.isServerRunning( thisServerInfo ) ? 'running' : 'stopped';; print.boldtext( ' (' ) .bold( status, statusColors.keyExists( status ) ? statusColors[ status ] : 'yellow' ) .bold( ')' ); diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 0f020367e..1248c7665 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -871,6 +871,15 @@ component accessors="true" singleton { } } + + /** + * Logic to tell if a server is running + * @serverInfo.hint Struct of server information + **/ + function isServerRunning( required struct serverInfo ){ + return !isPortAvailable( serverInfo.host, serverInfo.stopSocket ); + } + /** * persist server info * @serverInfo.hint struct of server info (ports, etc.) From e93d8b2367f4b9280e97e2caaea591cf1d9e6e90 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 12 Sep 2016 21:42:01 -0700 Subject: [PATCH 57/91] More detection of running servers --- .../server-commands/commands/server/start.cfc | 2 +- .../server-commands/commands/server/stop.cfc | 4 ++-- src/cfml/system/services/ServerService.cfc | 19 ++++++++++++++++++- 3 files changed, 21 insertions(+), 4 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 e2d195286..93d4f7527 100644 --- a/src/cfml/system/modules/server-commands/commands/server/start.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/start.cfc @@ -86,7 +86,7 @@ component aliases="start" { Boolean openbrowser, String directory, Numeric stopPort, - Boolean force, + Boolean force=false, Boolean debug, String webConfigDir, String serverConfigDir, 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 686d0d1fd..18c8664ae 100644 --- a/src/cfml/system/modules/server-commands/commands/server/stop.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/stop.cfc @@ -49,9 +49,9 @@ component aliases="stop" { for( var id in servers ) { var serverInfo = servers[ id ]; - if( serverInfo.status == 'stopped' ) { + if( !serverService.isServerRunning( serverInfo ) ) { if( structCount( servers ) == 1 ) { - print.yellowLine( serverInfo.name & ' already stopped..' ).toConsole(); + print.yellowLine( serverInfo.name & ' already stopped.' ).toConsole(); } continue; } diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 1248c7665..e920e3aab 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -183,6 +183,23 @@ component accessors="true" singleton { var serverJSON = serverDetails.serverJSON; var serverInfo = serverDetails.serverinfo; + // If the server is already running, make sure the user really wants to do this. + if( isServerRunning( serverInfo ) && !serverProps.force ) { + consoleLogger.error( '.' ); + consoleLogger.error( 'Server "#serverInfo.name#" (#serverInfo.webroot#) is already running!' ); + consoleLogger.error( 'Overwriting a running server means you won''t be able to use the "stop" command to stop the original one.' ); + consoleLogger.warn( 'Use the --force parameter to skip this check.' ); + consoleLogger.error( '.' ); + // Collect a new name + var newName = shell.ask( 'Provide a unique "name" for this server (leave blank to keep starting as-is): ' ); + // If a name is provided, start over. Otherwise, just keep starting. + // The recursive call here will subject their answer to the same check until they provide a name that hasn't been used for this folder. + if( len( newName ) ) { + serverProps.name = newName; + return start( serverProps ); + } + } + // ************************************************************************************* // Backwards compat for default port in box.json. Remove this eventually... // * // * @@ -224,7 +241,7 @@ component accessors="true" singleton { // Save hand-entered properties in our server.json for next time for( var prop in serverProps ) { // Ignore null props or ones that shouldn't be saved - if( isNull( serverProps[ prop ] ) || listFindNoCase( 'saveSettings,serverConfigFile,debug', prop ) ) { + if( isNull( serverProps[ prop ] ) || listFindNoCase( 'saveSettings,serverConfigFile,debug,force', prop ) ) { continue; } // Only need switch cases for properties that are nested or use different name From bdf03d8b07877e0eb929812bafd695e52f38b9db Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 13 Sep 2016 12:05:18 -0700 Subject: [PATCH 58/91] COMMANDBOX-412 --- build/build.xml | 5 + src/cfml/system/box.json | 15 ++ src/cfml/system/modules/.gitignore | 4 + .../artifacts-commands/ModuleConfig.cfc | 0 .../commands/artifacts/clean.cfc | 0 .../commands/artifacts/help.cfc | 0 .../commands/artifacts/list.cfc | 0 .../commands/artifacts/remove.cfc | 0 .../cachebox-commands/ModuleConfig.cfc | 0 .../commands/cachebox/create/config.cfc | 0 .../commands/cachebox/create/help.cfc | 0 .../commands/cachebox/help.cfc | 0 .../templates/cachebox/CacheBox.txt | 0 .../coldbox-commands/ModuleConfig.cfc | 0 .../commands/coldbox/create/app-wizard.cfc | 0 .../commands/coldbox/create/app.cfc | 0 .../commands/coldbox/create/bdd.cfc | 0 .../commands/coldbox/create/handler.cfc | 0 .../coldbox/create/handlers/Users.cfc | 0 .../commands/coldbox/create/help.cfc | 0 .../coldbox/create/integration-test.cfc | 0 .../coldbox/create/interceptor-test.cfc | 0 .../commands/coldbox/create/interceptor.cfc | 0 .../commands/coldbox/create/layout.cfc | 0 .../commands/coldbox/create/model-test.cfc | 0 .../commands/coldbox/create/model.cfc | 0 .../commands/coldbox/create/module.cfc | 0 .../commands/coldbox/create/orm-crud.cfc | 0 .../commands/coldbox/create/orm-entity.cfc | 0 .../coldbox/create/orm-event-handler.cfc | 0 .../commands/coldbox/create/orm-service.cfc | 0 .../coldbox/create/orm-virtual-service.cfc | 0 .../commands/coldbox/create/unit.cfc | 0 .../commands/coldbox/create/view.cfc | 0 .../coldbox/create/views/Users/edit.cfm | 0 .../coldbox/create/views/Users/editor.cfm | 0 .../coldbox/create/views/Users/index.cfm | 0 .../coldbox/create/views/Users/new.cfm | 0 .../commands/coldbox/help.cfc | 0 .../commands/coldbox/interceptor/help.cfc | 0 .../commands/coldbox/interceptor/install.cfc | 0 .../commands/coldbox/interceptor/remove.cfc | 0 .../commands/coldbox/module/help.cfc | 0 .../commands/coldbox/module/install.cfc | 0 .../commands/coldbox/module/list.cfc | 0 .../commands/coldbox/module/remove.cfc | 0 .../commands/coldbox/reinit.cfc | 0 .../coldbox-commands/skeletons/Advanced.zip | Bin .../skeletons/AdvancedScript.zip | Bin .../skeletons/AdvancedScriptv3.zip | Bin .../coldbox-commands/skeletons/Advancedv3.zip | Bin .../coldbox-commands/skeletons/Simple.zip | Bin .../coldbox-commands/skeletons/Simplev3.zip | Bin .../skeletons/SuperSimple.zip | Bin .../skeletons/SuperSimplev3.zip | Bin .../coldbox-commands/skeletons/rest.zip | Bin .../templates/ActionContent.txt | 0 .../templates/ActionContentScript.txt | 0 .../templates/HandlerContent.txt | 0 .../templates/HandlerContentScript.txt | 0 .../templates/InterceptorContent.txt | 0 .../templates/InterceptorContentScript.txt | 0 .../templates/InterceptorMethod.txt | 0 .../templates/InterceptorMethodScript.txt | 0 .../templates/ModelContent.txt | 0 .../templates/ModelContentScript.txt | 0 .../templates/ModelMethodContent.txt | 0 .../templates/ModelMethodContentScript.txt | 0 .../templates/crud/HandlerContent.txt | 0 .../coldbox-commands/templates/crud/edit.txt | 0 .../templates/crud/editor.txt | 0 .../coldbox-commands/templates/crud/index.txt | 0 .../coldbox-commands/templates/crud/new.txt | 0 .../coldbox-commands/templates/crud/table.cfm | 0 .../templates/modules/ModuleConfig.cfc | 0 .../templates/modules/ModuleConfigScript.cfc | 0 .../templates/modules/handlers/Home.cfc | 0 .../templates/modules/handlers/HomeScript.cfc | 0 .../templates/modules/models/models_here.txt | 0 .../templates/modules/views/home/index.cfm | 0 .../coldbox-commands/templates/orm/Entity.txt | 0 .../templates/orm/EntityScript.txt | 0 .../templates/orm/ORMEventHandler.txt | 0 .../templates/orm/TemplatedEntityService.txt | 0 .../templates/orm/VirtualEntityService.txt | 0 .../testing/HandlerBDDCaseContent.txt | 0 .../testing/HandlerBDDCaseContentScript.txt | 0 .../templates/testing/HandlerBDDContent.txt | 0 .../testing/HandlerBDDContentScript.txt | 0 .../testing/HandlerTestCaseContent.txt | 0 .../testing/HandlerTestCaseContentScript.txt | 0 .../templates/testing/HandlerTestContent.txt | 0 .../testing/HandlerTestContentScript.txt | 0 .../InterceptorBDDCaseContentScript.txt | 0 .../testing/InterceptorBDDContentScript.txt | 0 .../testing/InterceptorTestCaseContent.txt | 0 .../InterceptorTestCaseContentScript.txt | 0 .../testing/InterceptorTestContent.txt | 0 .../testing/InterceptorTestContentScript.txt | 0 .../templates/testing/ModelBDDContent.txt | 0 .../testing/ModelBDDContentScript.txt | 0 .../testing/ModelBDDMethodContent.txt | 0 .../testing/ModelBDDMethodContentScript.txt | 0 .../templates/testing/ModelTestContent.txt | 0 .../testing/ModelTestContentScript.txt | 0 .../templates/testing/ORMEntityBDDContent.txt | 0 .../testing/ORMEntityBDDContentScript.txt | 0 .../contentbox-commands/ModuleConfig.cfc | 0 .../commands/contentbox/create/app-wizard.cfc | 0 .../commands/contentbox/create/app.cfc | 0 .../commands/contentbox/create/bdd.cfc | 0 .../commands/contentbox/create/handler.cfc | 0 .../contentbox/create/handlers/Users.cfc | 0 .../commands/contentbox/create/help.cfc | 0 .../contentbox/create/integration-test.cfc | 0 .../contentbox/create/interceptor-test.cfc | 0 .../contentbox/create/interceptor.cfc | 0 .../commands/contentbox/create/layout.cfc | 0 .../commands/contentbox/create/model-test.cfc | 0 .../commands/contentbox/create/model.cfc | 0 .../commands/contentbox/create/module.cfc | 0 .../commands/contentbox/create/orm-crud.cfc | 0 .../commands/contentbox/create/orm-entity.cfc | 0 .../contentbox/create/orm-event-handler.cfc | 0 .../contentbox/create/orm-service.cfc | 0 .../contentbox/create/orm-virtual-service.cfc | 0 .../commands/contentbox/create/unit.cfc | 0 .../commands/contentbox/create/view.cfc | 0 .../contentbox/create/views/Users/edit.cfm | 0 .../contentbox/create/views/Users/editor.cfm | 0 .../contentbox/create/views/Users/index.cfm | 0 .../contentbox/create/views/Users/new.cfm | 0 .../commands/contentbox/help.cfc | 0 .../commands/contentbox/module/create.cfc | 0 .../commands/contentbox/module/help.cfc | 0 .../commands/contentbox/module/install.cfc | 0 .../commands/contentbox/module/list.cfc | 0 .../commands/contentbox/module/remove.cfc | 0 .../commands/contentbox/theme/create.cfc | 0 .../commands/contentbox/theme/help.cfc | 0 .../commands/contentbox/theme/install.cfc | 0 .../commands/contentbox/theme/list.cfc | 0 .../commands/contentbox/theme/remove.cfc | 0 .../commands/contentbox/widget/create.cfc | 0 .../commands/contentbox/widget/help.cfc | 0 .../commands/contentbox/widget/install.cfc | 0 .../commands/contentbox/widget/list.cfc | 0 .../commands/contentbox/widget/remove.cfc | 0 .../templates/ActionContent.txt | 0 .../templates/ActionContentScript.txt | 0 .../templates/HandlerContent.txt | 0 .../templates/HandlerContentScript.txt | 0 .../templates/InterceptorContent.txt | 0 .../templates/InterceptorContentScript.txt | 0 .../templates/InterceptorMethod.txt | 0 .../templates/InterceptorMethodScript.txt | 0 .../templates/ModelContent.txt | 0 .../templates/ModelContentScript.txt | 0 .../templates/ModelMethodContent.txt | 0 .../templates/ModelMethodContentScript.txt | 0 .../templates/modules/ModuleConfig.cfc | 0 .../templates/modules/ModuleConfigScript.cfc | 0 .../templates/modules/handlers/Home.cfc | 0 .../templates/modules/handlers/HomeScript.cfc | 0 .../templates/modules/models/models_here.txt | 0 .../templates/modules/views/home/index.cfm | 0 .../forgebox-commands/ModuleConfig.cfc | 0 .../commands/forgebox/disable.cfc | 0 .../commands/forgebox/enable.cfc | 0 .../commands/forgebox/help.cfc | 0 .../commands/forgebox/login.cfc | 0 .../commands/forgebox/my-contributions.cfc | 0 .../commands/forgebox/publish.cfc | 0 .../commands/forgebox/register.cfc | 0 .../commands/forgebox/search.cfc | 0 .../commands/forgebox/show.cfc | 0 .../commands/forgebox/slugcheck.cfc | 0 .../commands/forgebox/types.cfc | 0 .../commands/forgebox/unpublish.cfc | 0 .../games-commands/ModuleConfig.cfc | 0 .../games-commands/commands/game/snake.cfc | 0 .../logbox-commands/ModuleConfig.cfc | 0 .../commands/logbox/create/appender.cfc | 0 .../commands/logbox/create/config.cfc | 0 .../commands/logbox/create/help.cfc | 0 .../logbox-commands/commands/logbox/help.cfc | 0 .../templates/logbox/LogBox.txt | 0 .../package-commands/ModuleConfig.cfc | 0 .../commands/endpoint/login.cfc | 0 .../commands/endpoint/publish.cfc | 0 .../commands/endpoint/register.cfc | 0 .../commands/endpoint/unpublish.cfc | 0 .../commands/package/bugs.cfc | 0 .../commands/package/clear.cfc | 0 .../commands/package/documentation.cfc | 0 .../commands/package/help.cfc | 0 .../commands/package/homepage.cfc | 0 .../commands/package/init-wizard.cfc | 0 .../commands/package/init.cfc | 0 .../commands/package/install.cfc | 0 .../commands/package/list.cfc | 0 .../commands/package/outdated.cfc | 0 .../commands/package/run-script.cfc | 0 .../package-commands/commands/package/set.cfc | 0 .../commands/package/show.cfc | 0 .../commands/package/uninstall.cfc | 0 .../commands/package/update.cfc | 0 .../commands/package/version.cfc | 0 .../interceptors/packageScripts.cfc | 0 .../server-commands/ModuleConfig.cfc | 0 .../server-commands/commands/server/cd.cfc | 0 .../server-commands/commands/server/clear.cfc | 0 .../commands/server/forget.cfc | 0 .../server-commands/commands/server/help.cfc | 0 .../server-commands/commands/server/list.cfc | 0 .../server-commands/commands/server/log.cfc | 0 .../server-commands/commands/server/open.cfc | 0 .../commands/server/restart.cfc | 0 .../server-commands/commands/server/set.cfc | 0 .../server-commands/commands/server/show.cfc | 0 .../server-commands/commands/server/start.cfc | 0 .../commands/server/status.cfc | 0 .../server-commands/commands/server/stop.cfc | 0 .../system-commands/ModuleConfig.cfc | 0 .../system-commands/commands/browse.cfc | 0 .../system-commands/commands/cat.cfc | 0 .../system-commands/commands/cd.cfc | 0 .../system-commands/commands/cfml.cfc | 0 .../system-commands/commands/clear.cfc | 0 .../system-commands/commands/config/clear.cfc | 0 .../system-commands/commands/config/set.cfc | 0 .../system-commands/commands/config/show.cfc | 0 .../system-commands/commands/cp.cfc | 0 .../system-commands/commands/delete.cfc | 0 .../system-commands/commands/dir.cfc | 0 .../system-commands/commands/echo.cfc | 0 .../system-commands/commands/edit.cfc | 0 .../system-commands/commands/execute.cfc | 0 .../system-commands/commands/fileAppend.cfc | 0 .../system-commands/commands/fileWrite.cfc | 0 .../system-commands/commands/grep.cfc | 0 .../system-commands/commands/help.cfc | 0 .../system-commands/commands/history.cfc | 0 .../system-commands/commands/info.cfc | 0 .../system-commands/commands/mkdir.cfc | 0 .../system-commands/commands/more.cfc | 0 .../system-commands/commands/mv.cfc | 0 .../system-commands/commands/pause.cfc | 0 .../system-commands/commands/prompt.cfc | 0 .../system-commands/commands/pwd.cfc | 0 .../system-commands/commands/quit.cfc | 0 .../system-commands/commands/recipe.cfc | 0 .../system-commands/commands/reload.cfc | 0 .../system-commands/commands/repl.cfc | 0 .../system-commands/commands/run.cfc | 0 .../system-commands/commands/sed.cfc | 0 .../system-commands/commands/system-log.cfc | 0 .../system-commands/commands/tail.cfc | 0 .../system-commands/commands/touch.cfc | 0 .../system-commands/commands/upgrade.cfc | 0 .../system-commands/commands/version.cfc | 0 .../task-commands/ModuleConfig.cfc | 0 .../task-commands/commands/task/create.cfc | 0 .../task-commands/commands/task/help.cfc | 0 .../task-commands/commands/task/kill-all.cfc | 0 .../task-commands/commands/task/list.cfc | 0 .../task-commands/commands/task/remove.cfc | 0 .../testbox-commands/ModuleConfig.cfc | 0 .../commands/testbox/create/bdd.cfc | 0 .../commands/testbox/create/help.cfc | 0 .../commands/testbox/create/unit.cfc | 0 .../commands/testbox/generate/browser | 0 .../commands/testbox/generate/harness.cfc | 0 .../commands/testbox/generate/help.cfc | 0 .../commands/testbox/help.cfc | 0 .../commands/testbox/open/bundle.cfc | 0 .../commands/testbox/open/directory.cfc | 0 .../commands/testbox/open/help.cfc | 0 .../commands/testbox/open/runner.cfc | 0 .../testbox-commands/commands/testbox/run.cfc | 0 .../commands/testbox/watch.cfc | 0 .../templates/testbox/bdd.txt | 0 .../testbox/test-browser/Application.cfc | 0 .../testbox/test-browser/TestBoxLogo125.png | Bin .../templates/testbox/test-browser/index.cfm | 0 .../testbox/test-harness/Application.cfc | 0 .../test-harness/results/TEST.properties | 0 .../test-harness/results/results_go_here.txt | 0 .../templates/testbox/test-harness/runner.cfm | 0 .../testbox/test-harness/specs/BDDTest.cfc | 0 .../specs/put_test_bundles_here.txt | 0 .../templates/testbox/test-harness/test.xml | 0 .../templates/testbox/unit.txt | 0 .../wirebox-commands/ModuleConfig.cfc | 0 .../commands/wirebox/create/aspects.cfc | 0 .../commands/wirebox/create/binder.cfc | 0 .../commands/wirebox/create/dsl.cfc | 0 .../commands/wirebox/create/help.cfc | 0 .../commands/wirebox/create/scope.cfc | 0 .../commands/wirebox/help.cfc | 0 .../templates/wirebox/Aspect.txt | 0 .../templates/wirebox/AspectScript.txt | 0 .../templates/wirebox/WireBox.txt | 0 src/cfml/system/services/CommandService.cfc | 4 +- src/cfml/system/services/ModuleService.cfc | 7 +- src/cfml/system/util/StringDistance.cfc | 192 ------------------ 306 files changed, 32 insertions(+), 195 deletions(-) create mode 100644 src/cfml/system/box.json create mode 100644 src/cfml/system/modules/.gitignore rename src/cfml/system/{modules => modules_app}/artifacts-commands/ModuleConfig.cfc (100%) rename src/cfml/system/{modules => modules_app}/artifacts-commands/commands/artifacts/clean.cfc (100%) rename src/cfml/system/{modules => modules_app}/artifacts-commands/commands/artifacts/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/artifacts-commands/commands/artifacts/list.cfc (100%) rename src/cfml/system/{modules => modules_app}/artifacts-commands/commands/artifacts/remove.cfc (100%) rename src/cfml/system/{modules => modules_app}/cachebox-commands/ModuleConfig.cfc (100%) rename src/cfml/system/{modules => modules_app}/cachebox-commands/commands/cachebox/create/config.cfc (100%) rename src/cfml/system/{modules => modules_app}/cachebox-commands/commands/cachebox/create/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/cachebox-commands/commands/cachebox/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/cachebox-commands/templates/cachebox/CacheBox.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/ModuleConfig.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/app-wizard.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/app.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/bdd.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/handler.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/handlers/Users.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/integration-test.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/interceptor-test.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/interceptor.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/layout.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/model-test.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/model.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/module.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/orm-crud.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/orm-entity.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/orm-event-handler.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/orm-service.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/orm-virtual-service.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/unit.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/view.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/views/Users/edit.cfm (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/views/Users/editor.cfm (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/views/Users/index.cfm (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/create/views/Users/new.cfm (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/interceptor/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/interceptor/install.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/interceptor/remove.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/module/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/module/install.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/module/list.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/module/remove.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/commands/coldbox/reinit.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/skeletons/Advanced.zip (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/skeletons/AdvancedScript.zip (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/skeletons/AdvancedScriptv3.zip (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/skeletons/Advancedv3.zip (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/skeletons/Simple.zip (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/skeletons/Simplev3.zip (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/skeletons/SuperSimple.zip (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/skeletons/SuperSimplev3.zip (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/skeletons/rest.zip (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/ActionContent.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/ActionContentScript.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/HandlerContent.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/HandlerContentScript.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/InterceptorContent.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/InterceptorContentScript.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/InterceptorMethod.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/InterceptorMethodScript.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/ModelContent.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/ModelContentScript.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/ModelMethodContent.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/ModelMethodContentScript.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/crud/HandlerContent.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/crud/edit.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/crud/editor.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/crud/index.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/crud/new.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/crud/table.cfm (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/modules/ModuleConfig.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/modules/ModuleConfigScript.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/modules/handlers/Home.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/modules/handlers/HomeScript.cfc (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/modules/models/models_here.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/modules/views/home/index.cfm (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/orm/Entity.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/orm/EntityScript.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/orm/ORMEventHandler.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/orm/TemplatedEntityService.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/orm/VirtualEntityService.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/testing/HandlerBDDCaseContent.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/testing/HandlerBDDCaseContentScript.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/testing/HandlerBDDContent.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/testing/HandlerBDDContentScript.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/testing/HandlerTestCaseContent.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/testing/HandlerTestCaseContentScript.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/testing/HandlerTestContent.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/testing/HandlerTestContentScript.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/testing/InterceptorBDDCaseContentScript.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/testing/InterceptorBDDContentScript.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/testing/InterceptorTestCaseContent.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/testing/InterceptorTestCaseContentScript.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/testing/InterceptorTestContent.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/testing/InterceptorTestContentScript.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/testing/ModelBDDContent.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/testing/ModelBDDContentScript.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/testing/ModelBDDMethodContent.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/testing/ModelBDDMethodContentScript.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/testing/ModelTestContent.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/testing/ModelTestContentScript.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/testing/ORMEntityBDDContent.txt (100%) rename src/cfml/system/{modules => modules_app}/coldbox-commands/templates/testing/ORMEntityBDDContentScript.txt (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/ModuleConfig.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/app-wizard.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/app.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/bdd.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/handler.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/handlers/Users.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/integration-test.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/interceptor-test.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/interceptor.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/layout.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/model-test.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/model.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/module.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/orm-crud.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/orm-entity.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/orm-event-handler.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/orm-service.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/orm-virtual-service.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/unit.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/view.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/views/Users/edit.cfm (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/views/Users/editor.cfm (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/views/Users/index.cfm (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/create/views/Users/new.cfm (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/module/create.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/module/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/module/install.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/module/list.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/module/remove.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/theme/create.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/theme/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/theme/install.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/theme/list.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/theme/remove.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/widget/create.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/widget/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/widget/install.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/widget/list.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/commands/contentbox/widget/remove.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/templates/ActionContent.txt (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/templates/ActionContentScript.txt (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/templates/HandlerContent.txt (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/templates/HandlerContentScript.txt (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/templates/InterceptorContent.txt (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/templates/InterceptorContentScript.txt (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/templates/InterceptorMethod.txt (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/templates/InterceptorMethodScript.txt (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/templates/ModelContent.txt (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/templates/ModelContentScript.txt (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/templates/ModelMethodContent.txt (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/templates/ModelMethodContentScript.txt (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/templates/modules/ModuleConfig.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/templates/modules/ModuleConfigScript.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/templates/modules/handlers/Home.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/templates/modules/handlers/HomeScript.cfc (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/templates/modules/models/models_here.txt (100%) rename src/cfml/system/{modules => modules_app}/contentbox-commands/templates/modules/views/home/index.cfm (100%) rename src/cfml/system/{modules => modules_app}/forgebox-commands/ModuleConfig.cfc (100%) rename src/cfml/system/{modules => modules_app}/forgebox-commands/commands/forgebox/disable.cfc (100%) rename src/cfml/system/{modules => modules_app}/forgebox-commands/commands/forgebox/enable.cfc (100%) rename src/cfml/system/{modules => modules_app}/forgebox-commands/commands/forgebox/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/forgebox-commands/commands/forgebox/login.cfc (100%) rename src/cfml/system/{modules => modules_app}/forgebox-commands/commands/forgebox/my-contributions.cfc (100%) rename src/cfml/system/{modules => modules_app}/forgebox-commands/commands/forgebox/publish.cfc (100%) rename src/cfml/system/{modules => modules_app}/forgebox-commands/commands/forgebox/register.cfc (100%) rename src/cfml/system/{modules => modules_app}/forgebox-commands/commands/forgebox/search.cfc (100%) rename src/cfml/system/{modules => modules_app}/forgebox-commands/commands/forgebox/show.cfc (100%) rename src/cfml/system/{modules => modules_app}/forgebox-commands/commands/forgebox/slugcheck.cfc (100%) rename src/cfml/system/{modules => modules_app}/forgebox-commands/commands/forgebox/types.cfc (100%) rename src/cfml/system/{modules => modules_app}/forgebox-commands/commands/forgebox/unpublish.cfc (100%) rename src/cfml/system/{modules => modules_app}/games-commands/ModuleConfig.cfc (100%) rename src/cfml/system/{modules => modules_app}/games-commands/commands/game/snake.cfc (100%) rename src/cfml/system/{modules => modules_app}/logbox-commands/ModuleConfig.cfc (100%) rename src/cfml/system/{modules => modules_app}/logbox-commands/commands/logbox/create/appender.cfc (100%) rename src/cfml/system/{modules => modules_app}/logbox-commands/commands/logbox/create/config.cfc (100%) rename src/cfml/system/{modules => modules_app}/logbox-commands/commands/logbox/create/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/logbox-commands/commands/logbox/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/logbox-commands/templates/logbox/LogBox.txt (100%) rename src/cfml/system/{modules => modules_app}/package-commands/ModuleConfig.cfc (100%) rename src/cfml/system/{modules => modules_app}/package-commands/commands/endpoint/login.cfc (100%) rename src/cfml/system/{modules => modules_app}/package-commands/commands/endpoint/publish.cfc (100%) rename src/cfml/system/{modules => modules_app}/package-commands/commands/endpoint/register.cfc (100%) rename src/cfml/system/{modules => modules_app}/package-commands/commands/endpoint/unpublish.cfc (100%) rename src/cfml/system/{modules => modules_app}/package-commands/commands/package/bugs.cfc (100%) rename src/cfml/system/{modules => modules_app}/package-commands/commands/package/clear.cfc (100%) rename src/cfml/system/{modules => modules_app}/package-commands/commands/package/documentation.cfc (100%) rename src/cfml/system/{modules => modules_app}/package-commands/commands/package/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/package-commands/commands/package/homepage.cfc (100%) rename src/cfml/system/{modules => modules_app}/package-commands/commands/package/init-wizard.cfc (100%) rename src/cfml/system/{modules => modules_app}/package-commands/commands/package/init.cfc (100%) rename src/cfml/system/{modules => modules_app}/package-commands/commands/package/install.cfc (100%) rename src/cfml/system/{modules => modules_app}/package-commands/commands/package/list.cfc (100%) rename src/cfml/system/{modules => modules_app}/package-commands/commands/package/outdated.cfc (100%) rename src/cfml/system/{modules => modules_app}/package-commands/commands/package/run-script.cfc (100%) rename src/cfml/system/{modules => modules_app}/package-commands/commands/package/set.cfc (100%) rename src/cfml/system/{modules => modules_app}/package-commands/commands/package/show.cfc (100%) rename src/cfml/system/{modules => modules_app}/package-commands/commands/package/uninstall.cfc (100%) rename src/cfml/system/{modules => modules_app}/package-commands/commands/package/update.cfc (100%) rename src/cfml/system/{modules => modules_app}/package-commands/commands/package/version.cfc (100%) rename src/cfml/system/{modules => modules_app}/package-commands/interceptors/packageScripts.cfc (100%) rename src/cfml/system/{modules => modules_app}/server-commands/ModuleConfig.cfc (100%) rename src/cfml/system/{modules => modules_app}/server-commands/commands/server/cd.cfc (100%) rename src/cfml/system/{modules => modules_app}/server-commands/commands/server/clear.cfc (100%) rename src/cfml/system/{modules => modules_app}/server-commands/commands/server/forget.cfc (100%) rename src/cfml/system/{modules => modules_app}/server-commands/commands/server/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/server-commands/commands/server/list.cfc (100%) rename src/cfml/system/{modules => modules_app}/server-commands/commands/server/log.cfc (100%) rename src/cfml/system/{modules => modules_app}/server-commands/commands/server/open.cfc (100%) rename src/cfml/system/{modules => modules_app}/server-commands/commands/server/restart.cfc (100%) rename src/cfml/system/{modules => modules_app}/server-commands/commands/server/set.cfc (100%) rename src/cfml/system/{modules => modules_app}/server-commands/commands/server/show.cfc (100%) rename src/cfml/system/{modules => modules_app}/server-commands/commands/server/start.cfc (100%) rename src/cfml/system/{modules => modules_app}/server-commands/commands/server/status.cfc (100%) rename src/cfml/system/{modules => modules_app}/server-commands/commands/server/stop.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/ModuleConfig.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/browse.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/cat.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/cd.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/cfml.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/clear.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/config/clear.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/config/set.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/config/show.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/cp.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/delete.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/dir.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/echo.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/edit.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/execute.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/fileAppend.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/fileWrite.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/grep.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/history.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/info.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/mkdir.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/more.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/mv.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/pause.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/prompt.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/pwd.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/quit.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/recipe.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/reload.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/repl.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/run.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/sed.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/system-log.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/tail.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/touch.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/upgrade.cfc (100%) rename src/cfml/system/{modules => modules_app}/system-commands/commands/version.cfc (100%) rename src/cfml/system/{modules => modules_app}/task-commands/ModuleConfig.cfc (100%) rename src/cfml/system/{modules => modules_app}/task-commands/commands/task/create.cfc (100%) rename src/cfml/system/{modules => modules_app}/task-commands/commands/task/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/task-commands/commands/task/kill-all.cfc (100%) rename src/cfml/system/{modules => modules_app}/task-commands/commands/task/list.cfc (100%) rename src/cfml/system/{modules => modules_app}/task-commands/commands/task/remove.cfc (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/ModuleConfig.cfc (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/commands/testbox/create/bdd.cfc (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/commands/testbox/create/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/commands/testbox/create/unit.cfc (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/commands/testbox/generate/browser (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/commands/testbox/generate/harness.cfc (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/commands/testbox/generate/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/commands/testbox/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/commands/testbox/open/bundle.cfc (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/commands/testbox/open/directory.cfc (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/commands/testbox/open/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/commands/testbox/open/runner.cfc (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/commands/testbox/run.cfc (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/commands/testbox/watch.cfc (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/templates/testbox/bdd.txt (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/templates/testbox/test-browser/Application.cfc (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/templates/testbox/test-browser/TestBoxLogo125.png (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/templates/testbox/test-browser/index.cfm (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/templates/testbox/test-harness/Application.cfc (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/templates/testbox/test-harness/results/TEST.properties (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/templates/testbox/test-harness/results/results_go_here.txt (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/templates/testbox/test-harness/runner.cfm (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/templates/testbox/test-harness/specs/BDDTest.cfc (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/templates/testbox/test-harness/specs/put_test_bundles_here.txt (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/templates/testbox/test-harness/test.xml (100%) rename src/cfml/system/{modules => modules_app}/testbox-commands/templates/testbox/unit.txt (100%) rename src/cfml/system/{modules => modules_app}/wirebox-commands/ModuleConfig.cfc (100%) rename src/cfml/system/{modules => modules_app}/wirebox-commands/commands/wirebox/create/aspects.cfc (100%) rename src/cfml/system/{modules => modules_app}/wirebox-commands/commands/wirebox/create/binder.cfc (100%) rename src/cfml/system/{modules => modules_app}/wirebox-commands/commands/wirebox/create/dsl.cfc (100%) rename src/cfml/system/{modules => modules_app}/wirebox-commands/commands/wirebox/create/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/wirebox-commands/commands/wirebox/create/scope.cfc (100%) rename src/cfml/system/{modules => modules_app}/wirebox-commands/commands/wirebox/help.cfc (100%) rename src/cfml/system/{modules => modules_app}/wirebox-commands/templates/wirebox/Aspect.txt (100%) rename src/cfml/system/{modules => modules_app}/wirebox-commands/templates/wirebox/AspectScript.txt (100%) rename src/cfml/system/{modules => modules_app}/wirebox-commands/templates/wirebox/WireBox.txt (100%) delete mode 100644 src/cfml/system/util/StringDistance.cfc diff --git a/build/build.xml b/build/build.xml index 47f0bb168..a40639505 100644 --- a/build/build.xml +++ b/build/build.xml @@ -255,6 +255,11 @@ External Dependencies: + + + + + diff --git a/src/cfml/system/box.json b/src/cfml/system/box.json new file mode 100644 index 000000000..6930b3700 --- /dev/null +++ b/src/cfml/system/box.json @@ -0,0 +1,15 @@ +{ + "name":"CommandBox System Core", + "version":"@build.version@+@build.number@", + "author":"Brad Wood", + "shortDescription":"This tracks the CommandBox core dependencies", + "dependencies":{ + "string-similarity":"^1.0.0" + }, + "devDependencies":{ + + }, + "installPaths":{ + "string-similarity":"modules\\string-similarity" + } +} \ No newline at end of file diff --git a/src/cfml/system/modules/.gitignore b/src/cfml/system/modules/.gitignore new file mode 100644 index 000000000..86d0cb272 --- /dev/null +++ b/src/cfml/system/modules/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore \ No newline at end of file diff --git a/src/cfml/system/modules/artifacts-commands/ModuleConfig.cfc b/src/cfml/system/modules_app/artifacts-commands/ModuleConfig.cfc similarity index 100% rename from src/cfml/system/modules/artifacts-commands/ModuleConfig.cfc rename to src/cfml/system/modules_app/artifacts-commands/ModuleConfig.cfc diff --git a/src/cfml/system/modules/artifacts-commands/commands/artifacts/clean.cfc b/src/cfml/system/modules_app/artifacts-commands/commands/artifacts/clean.cfc similarity index 100% rename from src/cfml/system/modules/artifacts-commands/commands/artifacts/clean.cfc rename to src/cfml/system/modules_app/artifacts-commands/commands/artifacts/clean.cfc diff --git a/src/cfml/system/modules/artifacts-commands/commands/artifacts/help.cfc b/src/cfml/system/modules_app/artifacts-commands/commands/artifacts/help.cfc similarity index 100% rename from src/cfml/system/modules/artifacts-commands/commands/artifacts/help.cfc rename to src/cfml/system/modules_app/artifacts-commands/commands/artifacts/help.cfc diff --git a/src/cfml/system/modules/artifacts-commands/commands/artifacts/list.cfc b/src/cfml/system/modules_app/artifacts-commands/commands/artifacts/list.cfc similarity index 100% rename from src/cfml/system/modules/artifacts-commands/commands/artifacts/list.cfc rename to src/cfml/system/modules_app/artifacts-commands/commands/artifacts/list.cfc diff --git a/src/cfml/system/modules/artifacts-commands/commands/artifacts/remove.cfc b/src/cfml/system/modules_app/artifacts-commands/commands/artifacts/remove.cfc similarity index 100% rename from src/cfml/system/modules/artifacts-commands/commands/artifacts/remove.cfc rename to src/cfml/system/modules_app/artifacts-commands/commands/artifacts/remove.cfc diff --git a/src/cfml/system/modules/cachebox-commands/ModuleConfig.cfc b/src/cfml/system/modules_app/cachebox-commands/ModuleConfig.cfc similarity index 100% rename from src/cfml/system/modules/cachebox-commands/ModuleConfig.cfc rename to src/cfml/system/modules_app/cachebox-commands/ModuleConfig.cfc diff --git a/src/cfml/system/modules/cachebox-commands/commands/cachebox/create/config.cfc b/src/cfml/system/modules_app/cachebox-commands/commands/cachebox/create/config.cfc similarity index 100% rename from src/cfml/system/modules/cachebox-commands/commands/cachebox/create/config.cfc rename to src/cfml/system/modules_app/cachebox-commands/commands/cachebox/create/config.cfc diff --git a/src/cfml/system/modules/cachebox-commands/commands/cachebox/create/help.cfc b/src/cfml/system/modules_app/cachebox-commands/commands/cachebox/create/help.cfc similarity index 100% rename from src/cfml/system/modules/cachebox-commands/commands/cachebox/create/help.cfc rename to src/cfml/system/modules_app/cachebox-commands/commands/cachebox/create/help.cfc diff --git a/src/cfml/system/modules/cachebox-commands/commands/cachebox/help.cfc b/src/cfml/system/modules_app/cachebox-commands/commands/cachebox/help.cfc similarity index 100% rename from src/cfml/system/modules/cachebox-commands/commands/cachebox/help.cfc rename to src/cfml/system/modules_app/cachebox-commands/commands/cachebox/help.cfc diff --git a/src/cfml/system/modules/cachebox-commands/templates/cachebox/CacheBox.txt b/src/cfml/system/modules_app/cachebox-commands/templates/cachebox/CacheBox.txt similarity index 100% rename from src/cfml/system/modules/cachebox-commands/templates/cachebox/CacheBox.txt rename to src/cfml/system/modules_app/cachebox-commands/templates/cachebox/CacheBox.txt diff --git a/src/cfml/system/modules/coldbox-commands/ModuleConfig.cfc b/src/cfml/system/modules_app/coldbox-commands/ModuleConfig.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/ModuleConfig.cfc rename to src/cfml/system/modules_app/coldbox-commands/ModuleConfig.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/app-wizard.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/app-wizard.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/app-wizard.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/app-wizard.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/app.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/app.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/app.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/app.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/bdd.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/bdd.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/bdd.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/bdd.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/handler.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/handler.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/handler.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/handler.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/handlers/Users.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/handlers/Users.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/handlers/Users.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/handlers/Users.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/help.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/help.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/help.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/help.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/integration-test.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/integration-test.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/integration-test.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/integration-test.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/interceptor-test.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/interceptor-test.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/interceptor-test.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/interceptor-test.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/interceptor.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/interceptor.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/interceptor.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/interceptor.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/layout.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/layout.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/layout.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/layout.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/model-test.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/model-test.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/model-test.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/model-test.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/model.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/model.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/model.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/model.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/module.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/module.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/module.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/module.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-crud.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-crud.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-crud.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-crud.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-entity.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-entity.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-entity.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-entity.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-event-handler.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-event-handler.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-event-handler.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-event-handler.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-service.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-service.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-service.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-service.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-virtual-service.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-virtual-service.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-virtual-service.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-virtual-service.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/unit.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/unit.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/unit.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/unit.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/view.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/view.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/view.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/view.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/views/Users/edit.cfm b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/edit.cfm similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/views/Users/edit.cfm rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/edit.cfm diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/views/Users/editor.cfm b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/editor.cfm similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/views/Users/editor.cfm rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/editor.cfm diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/views/Users/index.cfm b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/index.cfm similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/views/Users/index.cfm rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/index.cfm diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/views/Users/new.cfm b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/new.cfm similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/create/views/Users/new.cfm rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/new.cfm diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/help.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/help.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/help.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/help.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/interceptor/help.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/interceptor/help.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/interceptor/help.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/interceptor/help.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/interceptor/install.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/interceptor/install.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/interceptor/install.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/interceptor/install.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/interceptor/remove.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/interceptor/remove.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/interceptor/remove.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/interceptor/remove.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/module/help.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/module/help.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/module/help.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/module/help.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/module/install.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/module/install.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/module/install.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/module/install.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/module/list.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/module/list.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/module/list.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/module/list.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/module/remove.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/module/remove.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/module/remove.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/module/remove.cfc diff --git a/src/cfml/system/modules/coldbox-commands/commands/coldbox/reinit.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/reinit.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/commands/coldbox/reinit.cfc rename to src/cfml/system/modules_app/coldbox-commands/commands/coldbox/reinit.cfc diff --git a/src/cfml/system/modules/coldbox-commands/skeletons/Advanced.zip b/src/cfml/system/modules_app/coldbox-commands/skeletons/Advanced.zip similarity index 100% rename from src/cfml/system/modules/coldbox-commands/skeletons/Advanced.zip rename to src/cfml/system/modules_app/coldbox-commands/skeletons/Advanced.zip diff --git a/src/cfml/system/modules/coldbox-commands/skeletons/AdvancedScript.zip b/src/cfml/system/modules_app/coldbox-commands/skeletons/AdvancedScript.zip similarity index 100% rename from src/cfml/system/modules/coldbox-commands/skeletons/AdvancedScript.zip rename to src/cfml/system/modules_app/coldbox-commands/skeletons/AdvancedScript.zip diff --git a/src/cfml/system/modules/coldbox-commands/skeletons/AdvancedScriptv3.zip b/src/cfml/system/modules_app/coldbox-commands/skeletons/AdvancedScriptv3.zip similarity index 100% rename from src/cfml/system/modules/coldbox-commands/skeletons/AdvancedScriptv3.zip rename to src/cfml/system/modules_app/coldbox-commands/skeletons/AdvancedScriptv3.zip diff --git a/src/cfml/system/modules/coldbox-commands/skeletons/Advancedv3.zip b/src/cfml/system/modules_app/coldbox-commands/skeletons/Advancedv3.zip similarity index 100% rename from src/cfml/system/modules/coldbox-commands/skeletons/Advancedv3.zip rename to src/cfml/system/modules_app/coldbox-commands/skeletons/Advancedv3.zip diff --git a/src/cfml/system/modules/coldbox-commands/skeletons/Simple.zip b/src/cfml/system/modules_app/coldbox-commands/skeletons/Simple.zip similarity index 100% rename from src/cfml/system/modules/coldbox-commands/skeletons/Simple.zip rename to src/cfml/system/modules_app/coldbox-commands/skeletons/Simple.zip diff --git a/src/cfml/system/modules/coldbox-commands/skeletons/Simplev3.zip b/src/cfml/system/modules_app/coldbox-commands/skeletons/Simplev3.zip similarity index 100% rename from src/cfml/system/modules/coldbox-commands/skeletons/Simplev3.zip rename to src/cfml/system/modules_app/coldbox-commands/skeletons/Simplev3.zip diff --git a/src/cfml/system/modules/coldbox-commands/skeletons/SuperSimple.zip b/src/cfml/system/modules_app/coldbox-commands/skeletons/SuperSimple.zip similarity index 100% rename from src/cfml/system/modules/coldbox-commands/skeletons/SuperSimple.zip rename to src/cfml/system/modules_app/coldbox-commands/skeletons/SuperSimple.zip diff --git a/src/cfml/system/modules/coldbox-commands/skeletons/SuperSimplev3.zip b/src/cfml/system/modules_app/coldbox-commands/skeletons/SuperSimplev3.zip similarity index 100% rename from src/cfml/system/modules/coldbox-commands/skeletons/SuperSimplev3.zip rename to src/cfml/system/modules_app/coldbox-commands/skeletons/SuperSimplev3.zip diff --git a/src/cfml/system/modules/coldbox-commands/skeletons/rest.zip b/src/cfml/system/modules_app/coldbox-commands/skeletons/rest.zip similarity index 100% rename from src/cfml/system/modules/coldbox-commands/skeletons/rest.zip rename to src/cfml/system/modules_app/coldbox-commands/skeletons/rest.zip diff --git a/src/cfml/system/modules/coldbox-commands/templates/ActionContent.txt b/src/cfml/system/modules_app/coldbox-commands/templates/ActionContent.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/ActionContent.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/ActionContent.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/ActionContentScript.txt b/src/cfml/system/modules_app/coldbox-commands/templates/ActionContentScript.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/ActionContentScript.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/ActionContentScript.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/HandlerContent.txt b/src/cfml/system/modules_app/coldbox-commands/templates/HandlerContent.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/HandlerContent.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/HandlerContent.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/HandlerContentScript.txt b/src/cfml/system/modules_app/coldbox-commands/templates/HandlerContentScript.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/HandlerContentScript.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/HandlerContentScript.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/InterceptorContent.txt b/src/cfml/system/modules_app/coldbox-commands/templates/InterceptorContent.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/InterceptorContent.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/InterceptorContent.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/InterceptorContentScript.txt b/src/cfml/system/modules_app/coldbox-commands/templates/InterceptorContentScript.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/InterceptorContentScript.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/InterceptorContentScript.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/InterceptorMethod.txt b/src/cfml/system/modules_app/coldbox-commands/templates/InterceptorMethod.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/InterceptorMethod.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/InterceptorMethod.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/InterceptorMethodScript.txt b/src/cfml/system/modules_app/coldbox-commands/templates/InterceptorMethodScript.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/InterceptorMethodScript.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/InterceptorMethodScript.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/ModelContent.txt b/src/cfml/system/modules_app/coldbox-commands/templates/ModelContent.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/ModelContent.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/ModelContent.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/ModelContentScript.txt b/src/cfml/system/modules_app/coldbox-commands/templates/ModelContentScript.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/ModelContentScript.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/ModelContentScript.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/ModelMethodContent.txt b/src/cfml/system/modules_app/coldbox-commands/templates/ModelMethodContent.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/ModelMethodContent.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/ModelMethodContent.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/ModelMethodContentScript.txt b/src/cfml/system/modules_app/coldbox-commands/templates/ModelMethodContentScript.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/ModelMethodContentScript.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/ModelMethodContentScript.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/crud/HandlerContent.txt b/src/cfml/system/modules_app/coldbox-commands/templates/crud/HandlerContent.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/crud/HandlerContent.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/crud/HandlerContent.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/crud/edit.txt b/src/cfml/system/modules_app/coldbox-commands/templates/crud/edit.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/crud/edit.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/crud/edit.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/crud/editor.txt b/src/cfml/system/modules_app/coldbox-commands/templates/crud/editor.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/crud/editor.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/crud/editor.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/crud/index.txt b/src/cfml/system/modules_app/coldbox-commands/templates/crud/index.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/crud/index.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/crud/index.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/crud/new.txt b/src/cfml/system/modules_app/coldbox-commands/templates/crud/new.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/crud/new.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/crud/new.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/crud/table.cfm b/src/cfml/system/modules_app/coldbox-commands/templates/crud/table.cfm similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/crud/table.cfm rename to src/cfml/system/modules_app/coldbox-commands/templates/crud/table.cfm diff --git a/src/cfml/system/modules/coldbox-commands/templates/modules/ModuleConfig.cfc b/src/cfml/system/modules_app/coldbox-commands/templates/modules/ModuleConfig.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/modules/ModuleConfig.cfc rename to src/cfml/system/modules_app/coldbox-commands/templates/modules/ModuleConfig.cfc diff --git a/src/cfml/system/modules/coldbox-commands/templates/modules/ModuleConfigScript.cfc b/src/cfml/system/modules_app/coldbox-commands/templates/modules/ModuleConfigScript.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/modules/ModuleConfigScript.cfc rename to src/cfml/system/modules_app/coldbox-commands/templates/modules/ModuleConfigScript.cfc diff --git a/src/cfml/system/modules/coldbox-commands/templates/modules/handlers/Home.cfc b/src/cfml/system/modules_app/coldbox-commands/templates/modules/handlers/Home.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/modules/handlers/Home.cfc rename to src/cfml/system/modules_app/coldbox-commands/templates/modules/handlers/Home.cfc diff --git a/src/cfml/system/modules/coldbox-commands/templates/modules/handlers/HomeScript.cfc b/src/cfml/system/modules_app/coldbox-commands/templates/modules/handlers/HomeScript.cfc similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/modules/handlers/HomeScript.cfc rename to src/cfml/system/modules_app/coldbox-commands/templates/modules/handlers/HomeScript.cfc diff --git a/src/cfml/system/modules/coldbox-commands/templates/modules/models/models_here.txt b/src/cfml/system/modules_app/coldbox-commands/templates/modules/models/models_here.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/modules/models/models_here.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/modules/models/models_here.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/modules/views/home/index.cfm b/src/cfml/system/modules_app/coldbox-commands/templates/modules/views/home/index.cfm similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/modules/views/home/index.cfm rename to src/cfml/system/modules_app/coldbox-commands/templates/modules/views/home/index.cfm diff --git a/src/cfml/system/modules/coldbox-commands/templates/orm/Entity.txt b/src/cfml/system/modules_app/coldbox-commands/templates/orm/Entity.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/orm/Entity.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/orm/Entity.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/orm/EntityScript.txt b/src/cfml/system/modules_app/coldbox-commands/templates/orm/EntityScript.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/orm/EntityScript.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/orm/EntityScript.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/orm/ORMEventHandler.txt b/src/cfml/system/modules_app/coldbox-commands/templates/orm/ORMEventHandler.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/orm/ORMEventHandler.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/orm/ORMEventHandler.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/orm/TemplatedEntityService.txt b/src/cfml/system/modules_app/coldbox-commands/templates/orm/TemplatedEntityService.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/orm/TemplatedEntityService.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/orm/TemplatedEntityService.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/orm/VirtualEntityService.txt b/src/cfml/system/modules_app/coldbox-commands/templates/orm/VirtualEntityService.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/orm/VirtualEntityService.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/orm/VirtualEntityService.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/HandlerBDDCaseContent.txt b/src/cfml/system/modules_app/coldbox-commands/templates/testing/HandlerBDDCaseContent.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/testing/HandlerBDDCaseContent.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/testing/HandlerBDDCaseContent.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/HandlerBDDCaseContentScript.txt b/src/cfml/system/modules_app/coldbox-commands/templates/testing/HandlerBDDCaseContentScript.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/testing/HandlerBDDCaseContentScript.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/testing/HandlerBDDCaseContentScript.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/HandlerBDDContent.txt b/src/cfml/system/modules_app/coldbox-commands/templates/testing/HandlerBDDContent.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/testing/HandlerBDDContent.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/testing/HandlerBDDContent.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/HandlerBDDContentScript.txt b/src/cfml/system/modules_app/coldbox-commands/templates/testing/HandlerBDDContentScript.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/testing/HandlerBDDContentScript.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/testing/HandlerBDDContentScript.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/HandlerTestCaseContent.txt b/src/cfml/system/modules_app/coldbox-commands/templates/testing/HandlerTestCaseContent.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/testing/HandlerTestCaseContent.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/testing/HandlerTestCaseContent.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/HandlerTestCaseContentScript.txt b/src/cfml/system/modules_app/coldbox-commands/templates/testing/HandlerTestCaseContentScript.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/testing/HandlerTestCaseContentScript.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/testing/HandlerTestCaseContentScript.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/HandlerTestContent.txt b/src/cfml/system/modules_app/coldbox-commands/templates/testing/HandlerTestContent.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/testing/HandlerTestContent.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/testing/HandlerTestContent.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/HandlerTestContentScript.txt b/src/cfml/system/modules_app/coldbox-commands/templates/testing/HandlerTestContentScript.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/testing/HandlerTestContentScript.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/testing/HandlerTestContentScript.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorBDDCaseContentScript.txt b/src/cfml/system/modules_app/coldbox-commands/templates/testing/InterceptorBDDCaseContentScript.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorBDDCaseContentScript.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/testing/InterceptorBDDCaseContentScript.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorBDDContentScript.txt b/src/cfml/system/modules_app/coldbox-commands/templates/testing/InterceptorBDDContentScript.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorBDDContentScript.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/testing/InterceptorBDDContentScript.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorTestCaseContent.txt b/src/cfml/system/modules_app/coldbox-commands/templates/testing/InterceptorTestCaseContent.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorTestCaseContent.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/testing/InterceptorTestCaseContent.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorTestCaseContentScript.txt b/src/cfml/system/modules_app/coldbox-commands/templates/testing/InterceptorTestCaseContentScript.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorTestCaseContentScript.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/testing/InterceptorTestCaseContentScript.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorTestContent.txt b/src/cfml/system/modules_app/coldbox-commands/templates/testing/InterceptorTestContent.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorTestContent.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/testing/InterceptorTestContent.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorTestContentScript.txt b/src/cfml/system/modules_app/coldbox-commands/templates/testing/InterceptorTestContentScript.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorTestContentScript.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/testing/InterceptorTestContentScript.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDContent.txt b/src/cfml/system/modules_app/coldbox-commands/templates/testing/ModelBDDContent.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDContent.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/testing/ModelBDDContent.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDContentScript.txt b/src/cfml/system/modules_app/coldbox-commands/templates/testing/ModelBDDContentScript.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDContentScript.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/testing/ModelBDDContentScript.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDMethodContent.txt b/src/cfml/system/modules_app/coldbox-commands/templates/testing/ModelBDDMethodContent.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDMethodContent.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/testing/ModelBDDMethodContent.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDMethodContentScript.txt b/src/cfml/system/modules_app/coldbox-commands/templates/testing/ModelBDDMethodContentScript.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDMethodContentScript.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/testing/ModelBDDMethodContentScript.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/ModelTestContent.txt b/src/cfml/system/modules_app/coldbox-commands/templates/testing/ModelTestContent.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/testing/ModelTestContent.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/testing/ModelTestContent.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/ModelTestContentScript.txt b/src/cfml/system/modules_app/coldbox-commands/templates/testing/ModelTestContentScript.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/testing/ModelTestContentScript.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/testing/ModelTestContentScript.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/ORMEntityBDDContent.txt b/src/cfml/system/modules_app/coldbox-commands/templates/testing/ORMEntityBDDContent.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/testing/ORMEntityBDDContent.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/testing/ORMEntityBDDContent.txt diff --git a/src/cfml/system/modules/coldbox-commands/templates/testing/ORMEntityBDDContentScript.txt b/src/cfml/system/modules_app/coldbox-commands/templates/testing/ORMEntityBDDContentScript.txt similarity index 100% rename from src/cfml/system/modules/coldbox-commands/templates/testing/ORMEntityBDDContentScript.txt rename to src/cfml/system/modules_app/coldbox-commands/templates/testing/ORMEntityBDDContentScript.txt diff --git a/src/cfml/system/modules/contentbox-commands/ModuleConfig.cfc b/src/cfml/system/modules_app/contentbox-commands/ModuleConfig.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/ModuleConfig.cfc rename to src/cfml/system/modules_app/contentbox-commands/ModuleConfig.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/app-wizard.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/app-wizard.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/app-wizard.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/app-wizard.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/app.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/app.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/app.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/app.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/bdd.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/bdd.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/bdd.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/bdd.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/handler.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/handler.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/handler.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/handler.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/handlers/Users.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/handlers/Users.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/handlers/Users.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/handlers/Users.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/help.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/help.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/help.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/help.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/integration-test.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/integration-test.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/integration-test.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/integration-test.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/interceptor-test.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/interceptor-test.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/interceptor-test.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/interceptor-test.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/interceptor.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/interceptor.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/interceptor.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/interceptor.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/layout.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/layout.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/layout.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/layout.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/model-test.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/model-test.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/model-test.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/model-test.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/model.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/model.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/model.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/model.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/module.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/module.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/module.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/module.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/orm-crud.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/orm-crud.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/orm-crud.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/orm-crud.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/orm-entity.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/orm-entity.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/orm-entity.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/orm-entity.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/orm-event-handler.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/orm-event-handler.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/orm-event-handler.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/orm-event-handler.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/orm-service.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/orm-service.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/orm-service.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/orm-service.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/orm-virtual-service.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/orm-virtual-service.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/orm-virtual-service.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/orm-virtual-service.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/unit.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/unit.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/unit.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/unit.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/view.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/view.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/view.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/view.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/views/Users/edit.cfm b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/views/Users/edit.cfm similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/views/Users/edit.cfm rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/views/Users/edit.cfm diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/views/Users/editor.cfm b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/views/Users/editor.cfm similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/views/Users/editor.cfm rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/views/Users/editor.cfm diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/views/Users/index.cfm b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/views/Users/index.cfm similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/views/Users/index.cfm rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/views/Users/index.cfm diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/create/views/Users/new.cfm b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/views/Users/new.cfm similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/create/views/Users/new.cfm rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/create/views/Users/new.cfm diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/help.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/help.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/help.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/help.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/module/create.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/module/create.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/module/create.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/module/create.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/module/help.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/module/help.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/module/help.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/module/help.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/module/install.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/module/install.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/module/install.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/module/install.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/module/list.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/module/list.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/module/list.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/module/list.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/module/remove.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/module/remove.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/module/remove.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/module/remove.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/create.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/theme/create.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/create.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/theme/create.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/help.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/theme/help.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/help.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/theme/help.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/install.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/theme/install.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/install.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/theme/install.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/list.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/theme/list.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/list.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/theme/list.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/remove.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/theme/remove.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/remove.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/theme/remove.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/create.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/widget/create.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/create.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/widget/create.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/help.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/widget/help.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/help.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/widget/help.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/install.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/widget/install.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/install.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/widget/install.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/list.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/widget/list.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/list.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/widget/list.cfc diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/remove.cfc b/src/cfml/system/modules_app/contentbox-commands/commands/contentbox/widget/remove.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/remove.cfc rename to src/cfml/system/modules_app/contentbox-commands/commands/contentbox/widget/remove.cfc diff --git a/src/cfml/system/modules/contentbox-commands/templates/ActionContent.txt b/src/cfml/system/modules_app/contentbox-commands/templates/ActionContent.txt similarity index 100% rename from src/cfml/system/modules/contentbox-commands/templates/ActionContent.txt rename to src/cfml/system/modules_app/contentbox-commands/templates/ActionContent.txt diff --git a/src/cfml/system/modules/contentbox-commands/templates/ActionContentScript.txt b/src/cfml/system/modules_app/contentbox-commands/templates/ActionContentScript.txt similarity index 100% rename from src/cfml/system/modules/contentbox-commands/templates/ActionContentScript.txt rename to src/cfml/system/modules_app/contentbox-commands/templates/ActionContentScript.txt diff --git a/src/cfml/system/modules/contentbox-commands/templates/HandlerContent.txt b/src/cfml/system/modules_app/contentbox-commands/templates/HandlerContent.txt similarity index 100% rename from src/cfml/system/modules/contentbox-commands/templates/HandlerContent.txt rename to src/cfml/system/modules_app/contentbox-commands/templates/HandlerContent.txt diff --git a/src/cfml/system/modules/contentbox-commands/templates/HandlerContentScript.txt b/src/cfml/system/modules_app/contentbox-commands/templates/HandlerContentScript.txt similarity index 100% rename from src/cfml/system/modules/contentbox-commands/templates/HandlerContentScript.txt rename to src/cfml/system/modules_app/contentbox-commands/templates/HandlerContentScript.txt diff --git a/src/cfml/system/modules/contentbox-commands/templates/InterceptorContent.txt b/src/cfml/system/modules_app/contentbox-commands/templates/InterceptorContent.txt similarity index 100% rename from src/cfml/system/modules/contentbox-commands/templates/InterceptorContent.txt rename to src/cfml/system/modules_app/contentbox-commands/templates/InterceptorContent.txt diff --git a/src/cfml/system/modules/contentbox-commands/templates/InterceptorContentScript.txt b/src/cfml/system/modules_app/contentbox-commands/templates/InterceptorContentScript.txt similarity index 100% rename from src/cfml/system/modules/contentbox-commands/templates/InterceptorContentScript.txt rename to src/cfml/system/modules_app/contentbox-commands/templates/InterceptorContentScript.txt diff --git a/src/cfml/system/modules/contentbox-commands/templates/InterceptorMethod.txt b/src/cfml/system/modules_app/contentbox-commands/templates/InterceptorMethod.txt similarity index 100% rename from src/cfml/system/modules/contentbox-commands/templates/InterceptorMethod.txt rename to src/cfml/system/modules_app/contentbox-commands/templates/InterceptorMethod.txt diff --git a/src/cfml/system/modules/contentbox-commands/templates/InterceptorMethodScript.txt b/src/cfml/system/modules_app/contentbox-commands/templates/InterceptorMethodScript.txt similarity index 100% rename from src/cfml/system/modules/contentbox-commands/templates/InterceptorMethodScript.txt rename to src/cfml/system/modules_app/contentbox-commands/templates/InterceptorMethodScript.txt diff --git a/src/cfml/system/modules/contentbox-commands/templates/ModelContent.txt b/src/cfml/system/modules_app/contentbox-commands/templates/ModelContent.txt similarity index 100% rename from src/cfml/system/modules/contentbox-commands/templates/ModelContent.txt rename to src/cfml/system/modules_app/contentbox-commands/templates/ModelContent.txt diff --git a/src/cfml/system/modules/contentbox-commands/templates/ModelContentScript.txt b/src/cfml/system/modules_app/contentbox-commands/templates/ModelContentScript.txt similarity index 100% rename from src/cfml/system/modules/contentbox-commands/templates/ModelContentScript.txt rename to src/cfml/system/modules_app/contentbox-commands/templates/ModelContentScript.txt diff --git a/src/cfml/system/modules/contentbox-commands/templates/ModelMethodContent.txt b/src/cfml/system/modules_app/contentbox-commands/templates/ModelMethodContent.txt similarity index 100% rename from src/cfml/system/modules/contentbox-commands/templates/ModelMethodContent.txt rename to src/cfml/system/modules_app/contentbox-commands/templates/ModelMethodContent.txt diff --git a/src/cfml/system/modules/contentbox-commands/templates/ModelMethodContentScript.txt b/src/cfml/system/modules_app/contentbox-commands/templates/ModelMethodContentScript.txt similarity index 100% rename from src/cfml/system/modules/contentbox-commands/templates/ModelMethodContentScript.txt rename to src/cfml/system/modules_app/contentbox-commands/templates/ModelMethodContentScript.txt diff --git a/src/cfml/system/modules/contentbox-commands/templates/modules/ModuleConfig.cfc b/src/cfml/system/modules_app/contentbox-commands/templates/modules/ModuleConfig.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/templates/modules/ModuleConfig.cfc rename to src/cfml/system/modules_app/contentbox-commands/templates/modules/ModuleConfig.cfc diff --git a/src/cfml/system/modules/contentbox-commands/templates/modules/ModuleConfigScript.cfc b/src/cfml/system/modules_app/contentbox-commands/templates/modules/ModuleConfigScript.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/templates/modules/ModuleConfigScript.cfc rename to src/cfml/system/modules_app/contentbox-commands/templates/modules/ModuleConfigScript.cfc diff --git a/src/cfml/system/modules/contentbox-commands/templates/modules/handlers/Home.cfc b/src/cfml/system/modules_app/contentbox-commands/templates/modules/handlers/Home.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/templates/modules/handlers/Home.cfc rename to src/cfml/system/modules_app/contentbox-commands/templates/modules/handlers/Home.cfc diff --git a/src/cfml/system/modules/contentbox-commands/templates/modules/handlers/HomeScript.cfc b/src/cfml/system/modules_app/contentbox-commands/templates/modules/handlers/HomeScript.cfc similarity index 100% rename from src/cfml/system/modules/contentbox-commands/templates/modules/handlers/HomeScript.cfc rename to src/cfml/system/modules_app/contentbox-commands/templates/modules/handlers/HomeScript.cfc diff --git a/src/cfml/system/modules/contentbox-commands/templates/modules/models/models_here.txt b/src/cfml/system/modules_app/contentbox-commands/templates/modules/models/models_here.txt similarity index 100% rename from src/cfml/system/modules/contentbox-commands/templates/modules/models/models_here.txt rename to src/cfml/system/modules_app/contentbox-commands/templates/modules/models/models_here.txt diff --git a/src/cfml/system/modules/contentbox-commands/templates/modules/views/home/index.cfm b/src/cfml/system/modules_app/contentbox-commands/templates/modules/views/home/index.cfm similarity index 100% rename from src/cfml/system/modules/contentbox-commands/templates/modules/views/home/index.cfm rename to src/cfml/system/modules_app/contentbox-commands/templates/modules/views/home/index.cfm diff --git a/src/cfml/system/modules/forgebox-commands/ModuleConfig.cfc b/src/cfml/system/modules_app/forgebox-commands/ModuleConfig.cfc similarity index 100% rename from src/cfml/system/modules/forgebox-commands/ModuleConfig.cfc rename to src/cfml/system/modules_app/forgebox-commands/ModuleConfig.cfc diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/disable.cfc b/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/disable.cfc similarity index 100% rename from src/cfml/system/modules/forgebox-commands/commands/forgebox/disable.cfc rename to src/cfml/system/modules_app/forgebox-commands/commands/forgebox/disable.cfc diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/enable.cfc b/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/enable.cfc similarity index 100% rename from src/cfml/system/modules/forgebox-commands/commands/forgebox/enable.cfc rename to src/cfml/system/modules_app/forgebox-commands/commands/forgebox/enable.cfc diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/help.cfc b/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/help.cfc similarity index 100% rename from src/cfml/system/modules/forgebox-commands/commands/forgebox/help.cfc rename to src/cfml/system/modules_app/forgebox-commands/commands/forgebox/help.cfc diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/login.cfc b/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/login.cfc similarity index 100% rename from src/cfml/system/modules/forgebox-commands/commands/forgebox/login.cfc rename to src/cfml/system/modules_app/forgebox-commands/commands/forgebox/login.cfc diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/my-contributions.cfc b/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/my-contributions.cfc similarity index 100% rename from src/cfml/system/modules/forgebox-commands/commands/forgebox/my-contributions.cfc rename to src/cfml/system/modules_app/forgebox-commands/commands/forgebox/my-contributions.cfc diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/publish.cfc b/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/publish.cfc similarity index 100% rename from src/cfml/system/modules/forgebox-commands/commands/forgebox/publish.cfc rename to src/cfml/system/modules_app/forgebox-commands/commands/forgebox/publish.cfc diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/register.cfc b/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/register.cfc similarity index 100% rename from src/cfml/system/modules/forgebox-commands/commands/forgebox/register.cfc rename to src/cfml/system/modules_app/forgebox-commands/commands/forgebox/register.cfc diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/search.cfc b/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/search.cfc similarity index 100% rename from src/cfml/system/modules/forgebox-commands/commands/forgebox/search.cfc rename to src/cfml/system/modules_app/forgebox-commands/commands/forgebox/search.cfc diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/show.cfc b/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/show.cfc similarity index 100% rename from src/cfml/system/modules/forgebox-commands/commands/forgebox/show.cfc rename to src/cfml/system/modules_app/forgebox-commands/commands/forgebox/show.cfc diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/slugcheck.cfc b/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/slugcheck.cfc similarity index 100% rename from src/cfml/system/modules/forgebox-commands/commands/forgebox/slugcheck.cfc rename to src/cfml/system/modules_app/forgebox-commands/commands/forgebox/slugcheck.cfc diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/types.cfc b/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/types.cfc similarity index 100% rename from src/cfml/system/modules/forgebox-commands/commands/forgebox/types.cfc rename to src/cfml/system/modules_app/forgebox-commands/commands/forgebox/types.cfc diff --git a/src/cfml/system/modules/forgebox-commands/commands/forgebox/unpublish.cfc b/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/unpublish.cfc similarity index 100% rename from src/cfml/system/modules/forgebox-commands/commands/forgebox/unpublish.cfc rename to src/cfml/system/modules_app/forgebox-commands/commands/forgebox/unpublish.cfc diff --git a/src/cfml/system/modules/games-commands/ModuleConfig.cfc b/src/cfml/system/modules_app/games-commands/ModuleConfig.cfc similarity index 100% rename from src/cfml/system/modules/games-commands/ModuleConfig.cfc rename to src/cfml/system/modules_app/games-commands/ModuleConfig.cfc diff --git a/src/cfml/system/modules/games-commands/commands/game/snake.cfc b/src/cfml/system/modules_app/games-commands/commands/game/snake.cfc similarity index 100% rename from src/cfml/system/modules/games-commands/commands/game/snake.cfc rename to src/cfml/system/modules_app/games-commands/commands/game/snake.cfc diff --git a/src/cfml/system/modules/logbox-commands/ModuleConfig.cfc b/src/cfml/system/modules_app/logbox-commands/ModuleConfig.cfc similarity index 100% rename from src/cfml/system/modules/logbox-commands/ModuleConfig.cfc rename to src/cfml/system/modules_app/logbox-commands/ModuleConfig.cfc diff --git a/src/cfml/system/modules/logbox-commands/commands/logbox/create/appender.cfc b/src/cfml/system/modules_app/logbox-commands/commands/logbox/create/appender.cfc similarity index 100% rename from src/cfml/system/modules/logbox-commands/commands/logbox/create/appender.cfc rename to src/cfml/system/modules_app/logbox-commands/commands/logbox/create/appender.cfc diff --git a/src/cfml/system/modules/logbox-commands/commands/logbox/create/config.cfc b/src/cfml/system/modules_app/logbox-commands/commands/logbox/create/config.cfc similarity index 100% rename from src/cfml/system/modules/logbox-commands/commands/logbox/create/config.cfc rename to src/cfml/system/modules_app/logbox-commands/commands/logbox/create/config.cfc diff --git a/src/cfml/system/modules/logbox-commands/commands/logbox/create/help.cfc b/src/cfml/system/modules_app/logbox-commands/commands/logbox/create/help.cfc similarity index 100% rename from src/cfml/system/modules/logbox-commands/commands/logbox/create/help.cfc rename to src/cfml/system/modules_app/logbox-commands/commands/logbox/create/help.cfc diff --git a/src/cfml/system/modules/logbox-commands/commands/logbox/help.cfc b/src/cfml/system/modules_app/logbox-commands/commands/logbox/help.cfc similarity index 100% rename from src/cfml/system/modules/logbox-commands/commands/logbox/help.cfc rename to src/cfml/system/modules_app/logbox-commands/commands/logbox/help.cfc diff --git a/src/cfml/system/modules/logbox-commands/templates/logbox/LogBox.txt b/src/cfml/system/modules_app/logbox-commands/templates/logbox/LogBox.txt similarity index 100% rename from src/cfml/system/modules/logbox-commands/templates/logbox/LogBox.txt rename to src/cfml/system/modules_app/logbox-commands/templates/logbox/LogBox.txt diff --git a/src/cfml/system/modules/package-commands/ModuleConfig.cfc b/src/cfml/system/modules_app/package-commands/ModuleConfig.cfc similarity index 100% rename from src/cfml/system/modules/package-commands/ModuleConfig.cfc rename to src/cfml/system/modules_app/package-commands/ModuleConfig.cfc diff --git a/src/cfml/system/modules/package-commands/commands/endpoint/login.cfc b/src/cfml/system/modules_app/package-commands/commands/endpoint/login.cfc similarity index 100% rename from src/cfml/system/modules/package-commands/commands/endpoint/login.cfc rename to src/cfml/system/modules_app/package-commands/commands/endpoint/login.cfc diff --git a/src/cfml/system/modules/package-commands/commands/endpoint/publish.cfc b/src/cfml/system/modules_app/package-commands/commands/endpoint/publish.cfc similarity index 100% rename from src/cfml/system/modules/package-commands/commands/endpoint/publish.cfc rename to src/cfml/system/modules_app/package-commands/commands/endpoint/publish.cfc diff --git a/src/cfml/system/modules/package-commands/commands/endpoint/register.cfc b/src/cfml/system/modules_app/package-commands/commands/endpoint/register.cfc similarity index 100% rename from src/cfml/system/modules/package-commands/commands/endpoint/register.cfc rename to src/cfml/system/modules_app/package-commands/commands/endpoint/register.cfc diff --git a/src/cfml/system/modules/package-commands/commands/endpoint/unpublish.cfc b/src/cfml/system/modules_app/package-commands/commands/endpoint/unpublish.cfc similarity index 100% rename from src/cfml/system/modules/package-commands/commands/endpoint/unpublish.cfc rename to src/cfml/system/modules_app/package-commands/commands/endpoint/unpublish.cfc diff --git a/src/cfml/system/modules/package-commands/commands/package/bugs.cfc b/src/cfml/system/modules_app/package-commands/commands/package/bugs.cfc similarity index 100% rename from src/cfml/system/modules/package-commands/commands/package/bugs.cfc rename to src/cfml/system/modules_app/package-commands/commands/package/bugs.cfc diff --git a/src/cfml/system/modules/package-commands/commands/package/clear.cfc b/src/cfml/system/modules_app/package-commands/commands/package/clear.cfc similarity index 100% rename from src/cfml/system/modules/package-commands/commands/package/clear.cfc rename to src/cfml/system/modules_app/package-commands/commands/package/clear.cfc diff --git a/src/cfml/system/modules/package-commands/commands/package/documentation.cfc b/src/cfml/system/modules_app/package-commands/commands/package/documentation.cfc similarity index 100% rename from src/cfml/system/modules/package-commands/commands/package/documentation.cfc rename to src/cfml/system/modules_app/package-commands/commands/package/documentation.cfc diff --git a/src/cfml/system/modules/package-commands/commands/package/help.cfc b/src/cfml/system/modules_app/package-commands/commands/package/help.cfc similarity index 100% rename from src/cfml/system/modules/package-commands/commands/package/help.cfc rename to src/cfml/system/modules_app/package-commands/commands/package/help.cfc diff --git a/src/cfml/system/modules/package-commands/commands/package/homepage.cfc b/src/cfml/system/modules_app/package-commands/commands/package/homepage.cfc similarity index 100% rename from src/cfml/system/modules/package-commands/commands/package/homepage.cfc rename to src/cfml/system/modules_app/package-commands/commands/package/homepage.cfc diff --git a/src/cfml/system/modules/package-commands/commands/package/init-wizard.cfc b/src/cfml/system/modules_app/package-commands/commands/package/init-wizard.cfc similarity index 100% rename from src/cfml/system/modules/package-commands/commands/package/init-wizard.cfc rename to src/cfml/system/modules_app/package-commands/commands/package/init-wizard.cfc diff --git a/src/cfml/system/modules/package-commands/commands/package/init.cfc b/src/cfml/system/modules_app/package-commands/commands/package/init.cfc similarity index 100% rename from src/cfml/system/modules/package-commands/commands/package/init.cfc rename to src/cfml/system/modules_app/package-commands/commands/package/init.cfc diff --git a/src/cfml/system/modules/package-commands/commands/package/install.cfc b/src/cfml/system/modules_app/package-commands/commands/package/install.cfc similarity index 100% rename from src/cfml/system/modules/package-commands/commands/package/install.cfc rename to src/cfml/system/modules_app/package-commands/commands/package/install.cfc diff --git a/src/cfml/system/modules/package-commands/commands/package/list.cfc b/src/cfml/system/modules_app/package-commands/commands/package/list.cfc similarity index 100% rename from src/cfml/system/modules/package-commands/commands/package/list.cfc rename to src/cfml/system/modules_app/package-commands/commands/package/list.cfc diff --git a/src/cfml/system/modules/package-commands/commands/package/outdated.cfc b/src/cfml/system/modules_app/package-commands/commands/package/outdated.cfc similarity index 100% rename from src/cfml/system/modules/package-commands/commands/package/outdated.cfc rename to src/cfml/system/modules_app/package-commands/commands/package/outdated.cfc diff --git a/src/cfml/system/modules/package-commands/commands/package/run-script.cfc b/src/cfml/system/modules_app/package-commands/commands/package/run-script.cfc similarity index 100% rename from src/cfml/system/modules/package-commands/commands/package/run-script.cfc rename to src/cfml/system/modules_app/package-commands/commands/package/run-script.cfc diff --git a/src/cfml/system/modules/package-commands/commands/package/set.cfc b/src/cfml/system/modules_app/package-commands/commands/package/set.cfc similarity index 100% rename from src/cfml/system/modules/package-commands/commands/package/set.cfc rename to src/cfml/system/modules_app/package-commands/commands/package/set.cfc diff --git a/src/cfml/system/modules/package-commands/commands/package/show.cfc b/src/cfml/system/modules_app/package-commands/commands/package/show.cfc similarity index 100% rename from src/cfml/system/modules/package-commands/commands/package/show.cfc rename to src/cfml/system/modules_app/package-commands/commands/package/show.cfc diff --git a/src/cfml/system/modules/package-commands/commands/package/uninstall.cfc b/src/cfml/system/modules_app/package-commands/commands/package/uninstall.cfc similarity index 100% rename from src/cfml/system/modules/package-commands/commands/package/uninstall.cfc rename to src/cfml/system/modules_app/package-commands/commands/package/uninstall.cfc diff --git a/src/cfml/system/modules/package-commands/commands/package/update.cfc b/src/cfml/system/modules_app/package-commands/commands/package/update.cfc similarity index 100% rename from src/cfml/system/modules/package-commands/commands/package/update.cfc rename to src/cfml/system/modules_app/package-commands/commands/package/update.cfc diff --git a/src/cfml/system/modules/package-commands/commands/package/version.cfc b/src/cfml/system/modules_app/package-commands/commands/package/version.cfc similarity index 100% rename from src/cfml/system/modules/package-commands/commands/package/version.cfc rename to src/cfml/system/modules_app/package-commands/commands/package/version.cfc diff --git a/src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc b/src/cfml/system/modules_app/package-commands/interceptors/packageScripts.cfc similarity index 100% rename from src/cfml/system/modules/package-commands/interceptors/packageScripts.cfc rename to src/cfml/system/modules_app/package-commands/interceptors/packageScripts.cfc diff --git a/src/cfml/system/modules/server-commands/ModuleConfig.cfc b/src/cfml/system/modules_app/server-commands/ModuleConfig.cfc similarity index 100% rename from src/cfml/system/modules/server-commands/ModuleConfig.cfc rename to src/cfml/system/modules_app/server-commands/ModuleConfig.cfc diff --git a/src/cfml/system/modules/server-commands/commands/server/cd.cfc b/src/cfml/system/modules_app/server-commands/commands/server/cd.cfc similarity index 100% rename from src/cfml/system/modules/server-commands/commands/server/cd.cfc rename to src/cfml/system/modules_app/server-commands/commands/server/cd.cfc diff --git a/src/cfml/system/modules/server-commands/commands/server/clear.cfc b/src/cfml/system/modules_app/server-commands/commands/server/clear.cfc similarity index 100% rename from src/cfml/system/modules/server-commands/commands/server/clear.cfc rename to src/cfml/system/modules_app/server-commands/commands/server/clear.cfc diff --git a/src/cfml/system/modules/server-commands/commands/server/forget.cfc b/src/cfml/system/modules_app/server-commands/commands/server/forget.cfc similarity index 100% rename from src/cfml/system/modules/server-commands/commands/server/forget.cfc rename to src/cfml/system/modules_app/server-commands/commands/server/forget.cfc diff --git a/src/cfml/system/modules/server-commands/commands/server/help.cfc b/src/cfml/system/modules_app/server-commands/commands/server/help.cfc similarity index 100% rename from src/cfml/system/modules/server-commands/commands/server/help.cfc rename to src/cfml/system/modules_app/server-commands/commands/server/help.cfc diff --git a/src/cfml/system/modules/server-commands/commands/server/list.cfc b/src/cfml/system/modules_app/server-commands/commands/server/list.cfc similarity index 100% rename from src/cfml/system/modules/server-commands/commands/server/list.cfc rename to src/cfml/system/modules_app/server-commands/commands/server/list.cfc diff --git a/src/cfml/system/modules/server-commands/commands/server/log.cfc b/src/cfml/system/modules_app/server-commands/commands/server/log.cfc similarity index 100% rename from src/cfml/system/modules/server-commands/commands/server/log.cfc rename to src/cfml/system/modules_app/server-commands/commands/server/log.cfc diff --git a/src/cfml/system/modules/server-commands/commands/server/open.cfc b/src/cfml/system/modules_app/server-commands/commands/server/open.cfc similarity index 100% rename from src/cfml/system/modules/server-commands/commands/server/open.cfc rename to src/cfml/system/modules_app/server-commands/commands/server/open.cfc diff --git a/src/cfml/system/modules/server-commands/commands/server/restart.cfc b/src/cfml/system/modules_app/server-commands/commands/server/restart.cfc similarity index 100% rename from src/cfml/system/modules/server-commands/commands/server/restart.cfc rename to src/cfml/system/modules_app/server-commands/commands/server/restart.cfc diff --git a/src/cfml/system/modules/server-commands/commands/server/set.cfc b/src/cfml/system/modules_app/server-commands/commands/server/set.cfc similarity index 100% rename from src/cfml/system/modules/server-commands/commands/server/set.cfc rename to src/cfml/system/modules_app/server-commands/commands/server/set.cfc diff --git a/src/cfml/system/modules/server-commands/commands/server/show.cfc b/src/cfml/system/modules_app/server-commands/commands/server/show.cfc similarity index 100% rename from src/cfml/system/modules/server-commands/commands/server/show.cfc rename to src/cfml/system/modules_app/server-commands/commands/server/show.cfc diff --git a/src/cfml/system/modules/server-commands/commands/server/start.cfc b/src/cfml/system/modules_app/server-commands/commands/server/start.cfc similarity index 100% rename from src/cfml/system/modules/server-commands/commands/server/start.cfc rename to src/cfml/system/modules_app/server-commands/commands/server/start.cfc diff --git a/src/cfml/system/modules/server-commands/commands/server/status.cfc b/src/cfml/system/modules_app/server-commands/commands/server/status.cfc similarity index 100% rename from src/cfml/system/modules/server-commands/commands/server/status.cfc rename to src/cfml/system/modules_app/server-commands/commands/server/status.cfc diff --git a/src/cfml/system/modules/server-commands/commands/server/stop.cfc b/src/cfml/system/modules_app/server-commands/commands/server/stop.cfc similarity index 100% rename from src/cfml/system/modules/server-commands/commands/server/stop.cfc rename to src/cfml/system/modules_app/server-commands/commands/server/stop.cfc diff --git a/src/cfml/system/modules/system-commands/ModuleConfig.cfc b/src/cfml/system/modules_app/system-commands/ModuleConfig.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/ModuleConfig.cfc rename to src/cfml/system/modules_app/system-commands/ModuleConfig.cfc diff --git a/src/cfml/system/modules/system-commands/commands/browse.cfc b/src/cfml/system/modules_app/system-commands/commands/browse.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/browse.cfc rename to src/cfml/system/modules_app/system-commands/commands/browse.cfc diff --git a/src/cfml/system/modules/system-commands/commands/cat.cfc b/src/cfml/system/modules_app/system-commands/commands/cat.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/cat.cfc rename to src/cfml/system/modules_app/system-commands/commands/cat.cfc diff --git a/src/cfml/system/modules/system-commands/commands/cd.cfc b/src/cfml/system/modules_app/system-commands/commands/cd.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/cd.cfc rename to src/cfml/system/modules_app/system-commands/commands/cd.cfc diff --git a/src/cfml/system/modules/system-commands/commands/cfml.cfc b/src/cfml/system/modules_app/system-commands/commands/cfml.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/cfml.cfc rename to src/cfml/system/modules_app/system-commands/commands/cfml.cfc diff --git a/src/cfml/system/modules/system-commands/commands/clear.cfc b/src/cfml/system/modules_app/system-commands/commands/clear.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/clear.cfc rename to src/cfml/system/modules_app/system-commands/commands/clear.cfc diff --git a/src/cfml/system/modules/system-commands/commands/config/clear.cfc b/src/cfml/system/modules_app/system-commands/commands/config/clear.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/config/clear.cfc rename to src/cfml/system/modules_app/system-commands/commands/config/clear.cfc diff --git a/src/cfml/system/modules/system-commands/commands/config/set.cfc b/src/cfml/system/modules_app/system-commands/commands/config/set.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/config/set.cfc rename to src/cfml/system/modules_app/system-commands/commands/config/set.cfc diff --git a/src/cfml/system/modules/system-commands/commands/config/show.cfc b/src/cfml/system/modules_app/system-commands/commands/config/show.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/config/show.cfc rename to src/cfml/system/modules_app/system-commands/commands/config/show.cfc diff --git a/src/cfml/system/modules/system-commands/commands/cp.cfc b/src/cfml/system/modules_app/system-commands/commands/cp.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/cp.cfc rename to src/cfml/system/modules_app/system-commands/commands/cp.cfc diff --git a/src/cfml/system/modules/system-commands/commands/delete.cfc b/src/cfml/system/modules_app/system-commands/commands/delete.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/delete.cfc rename to src/cfml/system/modules_app/system-commands/commands/delete.cfc diff --git a/src/cfml/system/modules/system-commands/commands/dir.cfc b/src/cfml/system/modules_app/system-commands/commands/dir.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/dir.cfc rename to src/cfml/system/modules_app/system-commands/commands/dir.cfc diff --git a/src/cfml/system/modules/system-commands/commands/echo.cfc b/src/cfml/system/modules_app/system-commands/commands/echo.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/echo.cfc rename to src/cfml/system/modules_app/system-commands/commands/echo.cfc diff --git a/src/cfml/system/modules/system-commands/commands/edit.cfc b/src/cfml/system/modules_app/system-commands/commands/edit.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/edit.cfc rename to src/cfml/system/modules_app/system-commands/commands/edit.cfc diff --git a/src/cfml/system/modules/system-commands/commands/execute.cfc b/src/cfml/system/modules_app/system-commands/commands/execute.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/execute.cfc rename to src/cfml/system/modules_app/system-commands/commands/execute.cfc diff --git a/src/cfml/system/modules/system-commands/commands/fileAppend.cfc b/src/cfml/system/modules_app/system-commands/commands/fileAppend.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/fileAppend.cfc rename to src/cfml/system/modules_app/system-commands/commands/fileAppend.cfc diff --git a/src/cfml/system/modules/system-commands/commands/fileWrite.cfc b/src/cfml/system/modules_app/system-commands/commands/fileWrite.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/fileWrite.cfc rename to src/cfml/system/modules_app/system-commands/commands/fileWrite.cfc diff --git a/src/cfml/system/modules/system-commands/commands/grep.cfc b/src/cfml/system/modules_app/system-commands/commands/grep.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/grep.cfc rename to src/cfml/system/modules_app/system-commands/commands/grep.cfc diff --git a/src/cfml/system/modules/system-commands/commands/help.cfc b/src/cfml/system/modules_app/system-commands/commands/help.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/help.cfc rename to src/cfml/system/modules_app/system-commands/commands/help.cfc diff --git a/src/cfml/system/modules/system-commands/commands/history.cfc b/src/cfml/system/modules_app/system-commands/commands/history.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/history.cfc rename to src/cfml/system/modules_app/system-commands/commands/history.cfc diff --git a/src/cfml/system/modules/system-commands/commands/info.cfc b/src/cfml/system/modules_app/system-commands/commands/info.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/info.cfc rename to src/cfml/system/modules_app/system-commands/commands/info.cfc diff --git a/src/cfml/system/modules/system-commands/commands/mkdir.cfc b/src/cfml/system/modules_app/system-commands/commands/mkdir.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/mkdir.cfc rename to src/cfml/system/modules_app/system-commands/commands/mkdir.cfc diff --git a/src/cfml/system/modules/system-commands/commands/more.cfc b/src/cfml/system/modules_app/system-commands/commands/more.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/more.cfc rename to src/cfml/system/modules_app/system-commands/commands/more.cfc diff --git a/src/cfml/system/modules/system-commands/commands/mv.cfc b/src/cfml/system/modules_app/system-commands/commands/mv.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/mv.cfc rename to src/cfml/system/modules_app/system-commands/commands/mv.cfc diff --git a/src/cfml/system/modules/system-commands/commands/pause.cfc b/src/cfml/system/modules_app/system-commands/commands/pause.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/pause.cfc rename to src/cfml/system/modules_app/system-commands/commands/pause.cfc diff --git a/src/cfml/system/modules/system-commands/commands/prompt.cfc b/src/cfml/system/modules_app/system-commands/commands/prompt.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/prompt.cfc rename to src/cfml/system/modules_app/system-commands/commands/prompt.cfc diff --git a/src/cfml/system/modules/system-commands/commands/pwd.cfc b/src/cfml/system/modules_app/system-commands/commands/pwd.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/pwd.cfc rename to src/cfml/system/modules_app/system-commands/commands/pwd.cfc diff --git a/src/cfml/system/modules/system-commands/commands/quit.cfc b/src/cfml/system/modules_app/system-commands/commands/quit.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/quit.cfc rename to src/cfml/system/modules_app/system-commands/commands/quit.cfc diff --git a/src/cfml/system/modules/system-commands/commands/recipe.cfc b/src/cfml/system/modules_app/system-commands/commands/recipe.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/recipe.cfc rename to src/cfml/system/modules_app/system-commands/commands/recipe.cfc diff --git a/src/cfml/system/modules/system-commands/commands/reload.cfc b/src/cfml/system/modules_app/system-commands/commands/reload.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/reload.cfc rename to src/cfml/system/modules_app/system-commands/commands/reload.cfc diff --git a/src/cfml/system/modules/system-commands/commands/repl.cfc b/src/cfml/system/modules_app/system-commands/commands/repl.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/repl.cfc rename to src/cfml/system/modules_app/system-commands/commands/repl.cfc diff --git a/src/cfml/system/modules/system-commands/commands/run.cfc b/src/cfml/system/modules_app/system-commands/commands/run.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/run.cfc rename to src/cfml/system/modules_app/system-commands/commands/run.cfc diff --git a/src/cfml/system/modules/system-commands/commands/sed.cfc b/src/cfml/system/modules_app/system-commands/commands/sed.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/sed.cfc rename to src/cfml/system/modules_app/system-commands/commands/sed.cfc diff --git a/src/cfml/system/modules/system-commands/commands/system-log.cfc b/src/cfml/system/modules_app/system-commands/commands/system-log.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/system-log.cfc rename to src/cfml/system/modules_app/system-commands/commands/system-log.cfc diff --git a/src/cfml/system/modules/system-commands/commands/tail.cfc b/src/cfml/system/modules_app/system-commands/commands/tail.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/tail.cfc rename to src/cfml/system/modules_app/system-commands/commands/tail.cfc diff --git a/src/cfml/system/modules/system-commands/commands/touch.cfc b/src/cfml/system/modules_app/system-commands/commands/touch.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/touch.cfc rename to src/cfml/system/modules_app/system-commands/commands/touch.cfc diff --git a/src/cfml/system/modules/system-commands/commands/upgrade.cfc b/src/cfml/system/modules_app/system-commands/commands/upgrade.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/upgrade.cfc rename to src/cfml/system/modules_app/system-commands/commands/upgrade.cfc diff --git a/src/cfml/system/modules/system-commands/commands/version.cfc b/src/cfml/system/modules_app/system-commands/commands/version.cfc similarity index 100% rename from src/cfml/system/modules/system-commands/commands/version.cfc rename to src/cfml/system/modules_app/system-commands/commands/version.cfc diff --git a/src/cfml/system/modules/task-commands/ModuleConfig.cfc b/src/cfml/system/modules_app/task-commands/ModuleConfig.cfc similarity index 100% rename from src/cfml/system/modules/task-commands/ModuleConfig.cfc rename to src/cfml/system/modules_app/task-commands/ModuleConfig.cfc diff --git a/src/cfml/system/modules/task-commands/commands/task/create.cfc b/src/cfml/system/modules_app/task-commands/commands/task/create.cfc similarity index 100% rename from src/cfml/system/modules/task-commands/commands/task/create.cfc rename to src/cfml/system/modules_app/task-commands/commands/task/create.cfc diff --git a/src/cfml/system/modules/task-commands/commands/task/help.cfc b/src/cfml/system/modules_app/task-commands/commands/task/help.cfc similarity index 100% rename from src/cfml/system/modules/task-commands/commands/task/help.cfc rename to src/cfml/system/modules_app/task-commands/commands/task/help.cfc diff --git a/src/cfml/system/modules/task-commands/commands/task/kill-all.cfc b/src/cfml/system/modules_app/task-commands/commands/task/kill-all.cfc similarity index 100% rename from src/cfml/system/modules/task-commands/commands/task/kill-all.cfc rename to src/cfml/system/modules_app/task-commands/commands/task/kill-all.cfc diff --git a/src/cfml/system/modules/task-commands/commands/task/list.cfc b/src/cfml/system/modules_app/task-commands/commands/task/list.cfc similarity index 100% rename from src/cfml/system/modules/task-commands/commands/task/list.cfc rename to src/cfml/system/modules_app/task-commands/commands/task/list.cfc diff --git a/src/cfml/system/modules/task-commands/commands/task/remove.cfc b/src/cfml/system/modules_app/task-commands/commands/task/remove.cfc similarity index 100% rename from src/cfml/system/modules/task-commands/commands/task/remove.cfc rename to src/cfml/system/modules_app/task-commands/commands/task/remove.cfc diff --git a/src/cfml/system/modules/testbox-commands/ModuleConfig.cfc b/src/cfml/system/modules_app/testbox-commands/ModuleConfig.cfc similarity index 100% rename from src/cfml/system/modules/testbox-commands/ModuleConfig.cfc rename to src/cfml/system/modules_app/testbox-commands/ModuleConfig.cfc diff --git a/src/cfml/system/modules/testbox-commands/commands/testbox/create/bdd.cfc b/src/cfml/system/modules_app/testbox-commands/commands/testbox/create/bdd.cfc similarity index 100% rename from src/cfml/system/modules/testbox-commands/commands/testbox/create/bdd.cfc rename to src/cfml/system/modules_app/testbox-commands/commands/testbox/create/bdd.cfc diff --git a/src/cfml/system/modules/testbox-commands/commands/testbox/create/help.cfc b/src/cfml/system/modules_app/testbox-commands/commands/testbox/create/help.cfc similarity index 100% rename from src/cfml/system/modules/testbox-commands/commands/testbox/create/help.cfc rename to src/cfml/system/modules_app/testbox-commands/commands/testbox/create/help.cfc diff --git a/src/cfml/system/modules/testbox-commands/commands/testbox/create/unit.cfc b/src/cfml/system/modules_app/testbox-commands/commands/testbox/create/unit.cfc similarity index 100% rename from src/cfml/system/modules/testbox-commands/commands/testbox/create/unit.cfc rename to src/cfml/system/modules_app/testbox-commands/commands/testbox/create/unit.cfc diff --git a/src/cfml/system/modules/testbox-commands/commands/testbox/generate/browser b/src/cfml/system/modules_app/testbox-commands/commands/testbox/generate/browser similarity index 100% rename from src/cfml/system/modules/testbox-commands/commands/testbox/generate/browser rename to src/cfml/system/modules_app/testbox-commands/commands/testbox/generate/browser diff --git a/src/cfml/system/modules/testbox-commands/commands/testbox/generate/harness.cfc b/src/cfml/system/modules_app/testbox-commands/commands/testbox/generate/harness.cfc similarity index 100% rename from src/cfml/system/modules/testbox-commands/commands/testbox/generate/harness.cfc rename to src/cfml/system/modules_app/testbox-commands/commands/testbox/generate/harness.cfc diff --git a/src/cfml/system/modules/testbox-commands/commands/testbox/generate/help.cfc b/src/cfml/system/modules_app/testbox-commands/commands/testbox/generate/help.cfc similarity index 100% rename from src/cfml/system/modules/testbox-commands/commands/testbox/generate/help.cfc rename to src/cfml/system/modules_app/testbox-commands/commands/testbox/generate/help.cfc diff --git a/src/cfml/system/modules/testbox-commands/commands/testbox/help.cfc b/src/cfml/system/modules_app/testbox-commands/commands/testbox/help.cfc similarity index 100% rename from src/cfml/system/modules/testbox-commands/commands/testbox/help.cfc rename to src/cfml/system/modules_app/testbox-commands/commands/testbox/help.cfc diff --git a/src/cfml/system/modules/testbox-commands/commands/testbox/open/bundle.cfc b/src/cfml/system/modules_app/testbox-commands/commands/testbox/open/bundle.cfc similarity index 100% rename from src/cfml/system/modules/testbox-commands/commands/testbox/open/bundle.cfc rename to src/cfml/system/modules_app/testbox-commands/commands/testbox/open/bundle.cfc diff --git a/src/cfml/system/modules/testbox-commands/commands/testbox/open/directory.cfc b/src/cfml/system/modules_app/testbox-commands/commands/testbox/open/directory.cfc similarity index 100% rename from src/cfml/system/modules/testbox-commands/commands/testbox/open/directory.cfc rename to src/cfml/system/modules_app/testbox-commands/commands/testbox/open/directory.cfc diff --git a/src/cfml/system/modules/testbox-commands/commands/testbox/open/help.cfc b/src/cfml/system/modules_app/testbox-commands/commands/testbox/open/help.cfc similarity index 100% rename from src/cfml/system/modules/testbox-commands/commands/testbox/open/help.cfc rename to src/cfml/system/modules_app/testbox-commands/commands/testbox/open/help.cfc diff --git a/src/cfml/system/modules/testbox-commands/commands/testbox/open/runner.cfc b/src/cfml/system/modules_app/testbox-commands/commands/testbox/open/runner.cfc similarity index 100% rename from src/cfml/system/modules/testbox-commands/commands/testbox/open/runner.cfc rename to src/cfml/system/modules_app/testbox-commands/commands/testbox/open/runner.cfc diff --git a/src/cfml/system/modules/testbox-commands/commands/testbox/run.cfc b/src/cfml/system/modules_app/testbox-commands/commands/testbox/run.cfc similarity index 100% rename from src/cfml/system/modules/testbox-commands/commands/testbox/run.cfc rename to src/cfml/system/modules_app/testbox-commands/commands/testbox/run.cfc diff --git a/src/cfml/system/modules/testbox-commands/commands/testbox/watch.cfc b/src/cfml/system/modules_app/testbox-commands/commands/testbox/watch.cfc similarity index 100% rename from src/cfml/system/modules/testbox-commands/commands/testbox/watch.cfc rename to src/cfml/system/modules_app/testbox-commands/commands/testbox/watch.cfc diff --git a/src/cfml/system/modules/testbox-commands/templates/testbox/bdd.txt b/src/cfml/system/modules_app/testbox-commands/templates/testbox/bdd.txt similarity index 100% rename from src/cfml/system/modules/testbox-commands/templates/testbox/bdd.txt rename to src/cfml/system/modules_app/testbox-commands/templates/testbox/bdd.txt diff --git a/src/cfml/system/modules/testbox-commands/templates/testbox/test-browser/Application.cfc b/src/cfml/system/modules_app/testbox-commands/templates/testbox/test-browser/Application.cfc similarity index 100% rename from src/cfml/system/modules/testbox-commands/templates/testbox/test-browser/Application.cfc rename to src/cfml/system/modules_app/testbox-commands/templates/testbox/test-browser/Application.cfc diff --git a/src/cfml/system/modules/testbox-commands/templates/testbox/test-browser/TestBoxLogo125.png b/src/cfml/system/modules_app/testbox-commands/templates/testbox/test-browser/TestBoxLogo125.png similarity index 100% rename from src/cfml/system/modules/testbox-commands/templates/testbox/test-browser/TestBoxLogo125.png rename to src/cfml/system/modules_app/testbox-commands/templates/testbox/test-browser/TestBoxLogo125.png diff --git a/src/cfml/system/modules/testbox-commands/templates/testbox/test-browser/index.cfm b/src/cfml/system/modules_app/testbox-commands/templates/testbox/test-browser/index.cfm similarity index 100% rename from src/cfml/system/modules/testbox-commands/templates/testbox/test-browser/index.cfm rename to src/cfml/system/modules_app/testbox-commands/templates/testbox/test-browser/index.cfm diff --git a/src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/Application.cfc b/src/cfml/system/modules_app/testbox-commands/templates/testbox/test-harness/Application.cfc similarity index 100% rename from src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/Application.cfc rename to src/cfml/system/modules_app/testbox-commands/templates/testbox/test-harness/Application.cfc diff --git a/src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/results/TEST.properties b/src/cfml/system/modules_app/testbox-commands/templates/testbox/test-harness/results/TEST.properties similarity index 100% rename from src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/results/TEST.properties rename to src/cfml/system/modules_app/testbox-commands/templates/testbox/test-harness/results/TEST.properties diff --git a/src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/results/results_go_here.txt b/src/cfml/system/modules_app/testbox-commands/templates/testbox/test-harness/results/results_go_here.txt similarity index 100% rename from src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/results/results_go_here.txt rename to src/cfml/system/modules_app/testbox-commands/templates/testbox/test-harness/results/results_go_here.txt diff --git a/src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/runner.cfm b/src/cfml/system/modules_app/testbox-commands/templates/testbox/test-harness/runner.cfm similarity index 100% rename from src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/runner.cfm rename to src/cfml/system/modules_app/testbox-commands/templates/testbox/test-harness/runner.cfm diff --git a/src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/specs/BDDTest.cfc b/src/cfml/system/modules_app/testbox-commands/templates/testbox/test-harness/specs/BDDTest.cfc similarity index 100% rename from src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/specs/BDDTest.cfc rename to src/cfml/system/modules_app/testbox-commands/templates/testbox/test-harness/specs/BDDTest.cfc diff --git a/src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/specs/put_test_bundles_here.txt b/src/cfml/system/modules_app/testbox-commands/templates/testbox/test-harness/specs/put_test_bundles_here.txt similarity index 100% rename from src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/specs/put_test_bundles_here.txt rename to src/cfml/system/modules_app/testbox-commands/templates/testbox/test-harness/specs/put_test_bundles_here.txt diff --git a/src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/test.xml b/src/cfml/system/modules_app/testbox-commands/templates/testbox/test-harness/test.xml similarity index 100% rename from src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/test.xml rename to src/cfml/system/modules_app/testbox-commands/templates/testbox/test-harness/test.xml diff --git a/src/cfml/system/modules/testbox-commands/templates/testbox/unit.txt b/src/cfml/system/modules_app/testbox-commands/templates/testbox/unit.txt similarity index 100% rename from src/cfml/system/modules/testbox-commands/templates/testbox/unit.txt rename to src/cfml/system/modules_app/testbox-commands/templates/testbox/unit.txt diff --git a/src/cfml/system/modules/wirebox-commands/ModuleConfig.cfc b/src/cfml/system/modules_app/wirebox-commands/ModuleConfig.cfc similarity index 100% rename from src/cfml/system/modules/wirebox-commands/ModuleConfig.cfc rename to src/cfml/system/modules_app/wirebox-commands/ModuleConfig.cfc diff --git a/src/cfml/system/modules/wirebox-commands/commands/wirebox/create/aspects.cfc b/src/cfml/system/modules_app/wirebox-commands/commands/wirebox/create/aspects.cfc similarity index 100% rename from src/cfml/system/modules/wirebox-commands/commands/wirebox/create/aspects.cfc rename to src/cfml/system/modules_app/wirebox-commands/commands/wirebox/create/aspects.cfc diff --git a/src/cfml/system/modules/wirebox-commands/commands/wirebox/create/binder.cfc b/src/cfml/system/modules_app/wirebox-commands/commands/wirebox/create/binder.cfc similarity index 100% rename from src/cfml/system/modules/wirebox-commands/commands/wirebox/create/binder.cfc rename to src/cfml/system/modules_app/wirebox-commands/commands/wirebox/create/binder.cfc diff --git a/src/cfml/system/modules/wirebox-commands/commands/wirebox/create/dsl.cfc b/src/cfml/system/modules_app/wirebox-commands/commands/wirebox/create/dsl.cfc similarity index 100% rename from src/cfml/system/modules/wirebox-commands/commands/wirebox/create/dsl.cfc rename to src/cfml/system/modules_app/wirebox-commands/commands/wirebox/create/dsl.cfc diff --git a/src/cfml/system/modules/wirebox-commands/commands/wirebox/create/help.cfc b/src/cfml/system/modules_app/wirebox-commands/commands/wirebox/create/help.cfc similarity index 100% rename from src/cfml/system/modules/wirebox-commands/commands/wirebox/create/help.cfc rename to src/cfml/system/modules_app/wirebox-commands/commands/wirebox/create/help.cfc diff --git a/src/cfml/system/modules/wirebox-commands/commands/wirebox/create/scope.cfc b/src/cfml/system/modules_app/wirebox-commands/commands/wirebox/create/scope.cfc similarity index 100% rename from src/cfml/system/modules/wirebox-commands/commands/wirebox/create/scope.cfc rename to src/cfml/system/modules_app/wirebox-commands/commands/wirebox/create/scope.cfc diff --git a/src/cfml/system/modules/wirebox-commands/commands/wirebox/help.cfc b/src/cfml/system/modules_app/wirebox-commands/commands/wirebox/help.cfc similarity index 100% rename from src/cfml/system/modules/wirebox-commands/commands/wirebox/help.cfc rename to src/cfml/system/modules_app/wirebox-commands/commands/wirebox/help.cfc diff --git a/src/cfml/system/modules/wirebox-commands/templates/wirebox/Aspect.txt b/src/cfml/system/modules_app/wirebox-commands/templates/wirebox/Aspect.txt similarity index 100% rename from src/cfml/system/modules/wirebox-commands/templates/wirebox/Aspect.txt rename to src/cfml/system/modules_app/wirebox-commands/templates/wirebox/Aspect.txt diff --git a/src/cfml/system/modules/wirebox-commands/templates/wirebox/AspectScript.txt b/src/cfml/system/modules_app/wirebox-commands/templates/wirebox/AspectScript.txt similarity index 100% rename from src/cfml/system/modules/wirebox-commands/templates/wirebox/AspectScript.txt rename to src/cfml/system/modules_app/wirebox-commands/templates/wirebox/AspectScript.txt diff --git a/src/cfml/system/modules/wirebox-commands/templates/wirebox/WireBox.txt b/src/cfml/system/modules_app/wirebox-commands/templates/wirebox/WireBox.txt similarity index 100% rename from src/cfml/system/modules/wirebox-commands/templates/wirebox/WireBox.txt rename to src/cfml/system/modules_app/wirebox-commands/templates/wirebox/WireBox.txt diff --git a/src/cfml/system/services/CommandService.cfc b/src/cfml/system/services/CommandService.cfc index 597f8513f..774496c6a 100644 --- a/src/cfml/system/services/CommandService.cfc +++ b/src/cfml/system/services/CommandService.cfc @@ -19,7 +19,8 @@ component accessors="true" singleton { property name='wirebox' inject='wirebox'; property name='commandLocations' inject='commandLocations@constants'; property name='interceptorService' inject='interceptorService'; - property name='stringDistance' inject='StringDistance'; + // Using provider since CommandService is created before modules are loaded + property name='stringDistance' inject='provider:StringSimilarity@string-similarity'; property name='configured' default="false" type="boolean"; @@ -45,7 +46,6 @@ component accessors="true" singleton { * Configure the service */ CommandService function configure(){ - // Check if handler mapped? if( NOT wirebox.getBinder().mappingExists( 'commandbox.system.BaseCommand' ) ){ // feed the base class diff --git a/src/cfml/system/services/ModuleService.cfc b/src/cfml/system/services/ModuleService.cfc index ef3de18b5..21cca08d4 100644 --- a/src/cfml/system/services/ModuleService.cfc +++ b/src/cfml/system/services/ModuleService.cfc @@ -85,7 +85,7 @@ // Add the application's module's location and the system core modules - var modLocations = [ '/commandbox/system/modules', '/commandbox/modules' ]; + var modLocations = [ '/commandbox/system/modules','/commandbox/system/modules_app', '/commandbox/modules' ]; // Add the application's external locations array. modLocations.addAll( ConfigService.getSetting( "ModulesExternalLocation", [] ) ); // iterate through locations and build the module registry in order @@ -415,12 +415,17 @@ if( directoryExists( mconfig.modelsPhysicalPath ) and mConfig.autoMapModels ){ // Add as a mapped directory with module name as the namespace with correct mapping path var packagePath = ( len( mConfig.cfmapping ) ? mConfig.cfmapping & ".#mConfig.conventions.modelsLocation#" : mConfig.modelsInvocationPath ); + systemOutput(mConfig.modelNamespace, true); + systemOutput(packagePath, true); + systemOutput('', true); if( len( mConfig.modelNamespace ) ){ wirebox.getBinder().mapDirectory( packagePath=packagePath, namespace="@#mConfig.modelNamespace#" ); } else { // just register with no namespace wirebox.getBinder().mapDirectory( packagePath=packagePath ); } + wirebox.getBinder().processMappings(); + wirebox.getBinder().getMappings().keyArray().sort('text').each( function(i){ systemOutput(i,true); } ); } // Register commands if they exist diff --git a/src/cfml/system/util/StringDistance.cfc b/src/cfml/system/util/StringDistance.cfc deleted file mode 100644 index 03f977b6f..000000000 --- a/src/cfml/system/util/StringDistance.cfc +++ /dev/null @@ -1,192 +0,0 @@ -/** -* -* 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 65aa2c53c381522f11798d92497e06e325e835df Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 13 Sep 2016 12:08:23 -0700 Subject: [PATCH 59/91] COMMANDBOX-412 --- build/build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build.xml b/build/build.xml index a40639505..844e6bb07 100644 --- a/build/build.xml +++ b/build/build.xml @@ -257,7 +257,7 @@ External Dependencies: - + From 309302260980c6cfde1ec70267854b8005d79f9e Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 13 Sep 2016 12:26:25 -0700 Subject: [PATCH 60/91] remove debugging --- src/cfml/system/services/ModuleService.cfc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/cfml/system/services/ModuleService.cfc b/src/cfml/system/services/ModuleService.cfc index 21cca08d4..8b3cd6c11 100644 --- a/src/cfml/system/services/ModuleService.cfc +++ b/src/cfml/system/services/ModuleService.cfc @@ -415,9 +415,6 @@ if( directoryExists( mconfig.modelsPhysicalPath ) and mConfig.autoMapModels ){ // Add as a mapped directory with module name as the namespace with correct mapping path var packagePath = ( len( mConfig.cfmapping ) ? mConfig.cfmapping & ".#mConfig.conventions.modelsLocation#" : mConfig.modelsInvocationPath ); - systemOutput(mConfig.modelNamespace, true); - systemOutput(packagePath, true); - systemOutput('', true); if( len( mConfig.modelNamespace ) ){ wirebox.getBinder().mapDirectory( packagePath=packagePath, namespace="@#mConfig.modelNamespace#" ); } else { @@ -425,7 +422,6 @@ wirebox.getBinder().mapDirectory( packagePath=packagePath ); } wirebox.getBinder().processMappings(); - wirebox.getBinder().getMappings().keyArray().sort('text').each( function(i){ systemOutput(i,true); } ); } // Register commands if they exist From 8945dc4fca29011d877298247e09dcb6c4c3ba3e Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 13 Sep 2016 14:42:25 -0700 Subject: [PATCH 61/91] COMMANDBOX-413 --- apidocs/index.cfm | 2 +- apidocs/internal.cfm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apidocs/index.cfm b/apidocs/index.cfm index bd0a5a154..242044038 100644 --- a/apidocs/index.cfm +++ b/apidocs/index.cfm @@ -11,7 +11,7 @@ try{ } ); baseDir = expandPath( '/commandbox' ); - commandDirs = directoryList(path='/commandbox/system/modules', recurse=true, filter=function(path){ return reFindNoCase( '.*[/\\]commands$', arguments.path ); } ); + commandDirs = directoryList(path='/commandbox/system/modules_app', recurse=true, filter=function(path){ return reFindNoCase( '.*[/\\]commands$', arguments.path ); } ); source = [ ]; for( dir in commandDirs ) { diff --git a/apidocs/internal.cfm b/apidocs/internal.cfm index 9a675e25f..664b712bc 100644 --- a/apidocs/internal.cfm +++ b/apidocs/internal.cfm @@ -15,7 +15,7 @@ try{ docbox.generate( source = expandPath( "/commandbox/system" ), mapping = "commandbox.system", - excludes = "system\/(modules)" + excludes = "system\/(modules),system\/(modules_app)" ); } catch ( Any e ){ writeOutput( e.message & e.detail ); From f1e45dbee8303cd7c2f9ac8cfe74449248ffb9f1 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 13 Sep 2016 16:00:09 -0700 Subject: [PATCH 62/91] COMMANDBOX-413 --- src/cfml/system/box.json | 6 ++++-- .../package-commands/commands/package/version.cfc | 2 +- src/cfml/system/services/PackageService.cfc | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/cfml/system/box.json b/src/cfml/system/box.json index 6930b3700..59897c779 100644 --- a/src/cfml/system/box.json +++ b/src/cfml/system/box.json @@ -4,12 +4,14 @@ "author":"Brad Wood", "shortDescription":"This tracks the CommandBox core dependencies", "dependencies":{ - "string-similarity":"^1.0.0" + "string-similarity":"^1.0.0", + "semver":"^1.0.0" }, "devDependencies":{ }, "installPaths":{ - "string-similarity":"modules\\string-similarity" + "string-similarity":"modules\\string-similarity", + "semver":"modules\\semver" } } \ No newline at end of file diff --git a/src/cfml/system/modules_app/package-commands/commands/package/version.cfc b/src/cfml/system/modules_app/package-commands/commands/package/version.cfc index 4c446ac44..9a7133cc7 100644 --- a/src/cfml/system/modules_app/package-commands/commands/package/version.cfc +++ b/src/cfml/system/modules_app/package-commands/commands/package/version.cfc @@ -45,7 +45,7 @@ component aliases="bump" { property name='packageService' inject='PackageService'; property name='configService' inject='ConfigService'; - property name='semanticVersion' inject='semanticVersion'; + property name='semanticVersion' inject='provider:semanticVersion@semver'; property name='interceptorService' inject='interceptorService'; /** diff --git a/src/cfml/system/services/PackageService.cfc b/src/cfml/system/services/PackageService.cfc index 1652acd9c..b01514bc9 100644 --- a/src/cfml/system/services/PackageService.cfc +++ b/src/cfml/system/services/PackageService.cfc @@ -17,7 +17,7 @@ component accessors="true" singleton { property name='pathPatternMatcher' inject='pathPatternMatcher'; property name='shell' inject='Shell'; property name='logger' inject='logbox:logger:{this}'; - property name='semanticVersion' inject='semanticVersion'; + property name='semanticVersion' inject='provider:semanticVersion@semver'; property name='endpointService' inject='EndpointService'; property name='consoleLogger' inject='logbox:logger:console'; property name='interceptorService' inject='interceptorService'; From 3e9b78b736fef25487e1754c79a4857e73f82e1f Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 13 Sep 2016 16:50:58 -0700 Subject: [PATCH 63/91] COMMANDBOX-414 --- src/cfml/system/box.json | 6 +- src/cfml/system/services/PackageService.cfc | 2 +- src/cfml/system/util/PathPatternMatcher.cfc | 91 --------------------- 3 files changed, 5 insertions(+), 94 deletions(-) delete mode 100644 src/cfml/system/util/PathPatternMatcher.cfc diff --git a/src/cfml/system/box.json b/src/cfml/system/box.json index 59897c779..b2a67b8b7 100644 --- a/src/cfml/system/box.json +++ b/src/cfml/system/box.json @@ -5,13 +5,15 @@ "shortDescription":"This tracks the CommandBox core dependencies", "dependencies":{ "string-similarity":"^1.0.0", - "semver":"^1.0.0" + "semver":"^1.0.0", + "globber":"^1.0.0" }, "devDependencies":{ }, "installPaths":{ "string-similarity":"modules\\string-similarity", - "semver":"modules\\semver" + "semver":"modules\\semver", + "globber":"modules\\globber" } } \ No newline at end of file diff --git a/src/cfml/system/services/PackageService.cfc b/src/cfml/system/services/PackageService.cfc index b01514bc9..eaf1f19cb 100644 --- a/src/cfml/system/services/PackageService.cfc +++ b/src/cfml/system/services/PackageService.cfc @@ -14,7 +14,7 @@ component accessors="true" singleton { property name='formatterUtil' inject='formatter'; property name='artifactService' inject='ArtifactService'; property name='fileSystemUtil' inject='FileSystem'; - property name='pathPatternMatcher' inject='pathPatternMatcher'; + property name='pathPatternMatcher' inject='provider:pathPatternMatcher@globber'; property name='shell' inject='Shell'; property name='logger' inject='logbox:logger:{this}'; property name='semanticVersion' inject='provider:semanticVersion@semver'; diff --git a/src/cfml/system/util/PathPatternMatcher.cfc b/src/cfml/system/util/PathPatternMatcher.cfc deleted file mode 100644 index 414f400a7..000000000 --- a/src/cfml/system/util/PathPatternMatcher.cfc +++ /dev/null @@ -1,91 +0,0 @@ -/** -********************************************************************************* -* Copyright Since 2014 CommandBox by Ortus Solutions, Corp -* www.coldbox.org | www.ortussolutions.com -******************************************************************************** -* @author Brad Wood, Luis Majano, Denny Valliant -* -* I am a utility to match file system path patterns -* -* End a pattern with a slash to only match a directory. Start a pattern with a slash to start in the root. Ex: -* - foo will match any file or folder in the directory tree -* - /foo will only match a file or folder in the root -* - foo/ will only match a directory anywhere in the directory tree -* - /foo/ will only match a folder in the root -* -* Use a single * to match zero or more characters INSIDE a file or folder name (won't match a slash) Ex: -* - foo* will match any file or folder starting with "foo" -* - foo*.txt will match any file or folder starting with "foo" and ending with .txt -* - *foo will match any file or folder ending with "foo" -* - a/* /z will match a/b/z but not a/b/c/z -* -* Use a double ** to match zero or more characters including slashes. This allows a pattern to span directories Ex: -* - a/** /z will match a/z and a/b/z and a/b/c/z -* -*/ -component accessors="true" singleton { - - function init() { - return this; - } - - /** - * Match a single path to a single pattern. Returns true if the path matches the pattern, otherwise false. - * @pattern.hint The pattern to match against the path - * @path.hint The file system path to test. Can be a file or directory. Direcories MUST end with a trailing slash - */ - boolean function matchPattern( required string pattern, required string path ) { - // Normalize slashes - arguments.pattern = replace( arguments.pattern, '\', '/', 'all' ); - arguments.path = replace( arguments.path, '\', '/', 'all' ); - - // Start all paths with / - arguments.path = ( arguments.path.startsWith( '/' ) ? arguments.path : '/' & arguments.path ); - - // build a regex based on the pattern - var regex = arguments.pattern; - - // Escape any periods in the pattern - regex = replace( regex, '.', '\.', 'all' ); - - // /**/ matches zero or more directories (at least one /) - regex = replace( regex, '/**/', '__zeroOrMoreDirs_', 'all' ); - // Double ** matches anything - regex = replace( regex, '**', '__anything_', 'all' ); - // Single * matches anything BUT slash - regex = replace( regex, '*', '__anythingButSlash__', 'all' ); - // Switch placeholders for actual regex - regex = replace( regex, '__zeroOrMoreDirs_', '/.*', 'all' ); - regex = replace( regex, '__anything_', '.*', 'all' ); - regex = replace( regex, '__anythingButSlash__', '[^/]*', 'all' ); - - // If pattern starts with slash - if( regex.startsWith( '/' )) { - // add a ^ to match start of string - regex = '^' & regex; - } else { - // Otherwise, anything can precede this pattern - regex = '.*' & regex; - } - // Anything can follow this pattern - regex &= '.*'; - - //writeDump(regex);abort; - return ( reFindNoCase( regex, arguments.path ) > 0 ); - } - - /** - * Match an array of patterns against a single path. Returns true if at least one pattern matches, otherwise false. - * @patterns.hint An array of patterns to match against the path - * @path.hint The file system path to test. Can be a file or directory. Direcories MUST end with a trailing slash - */ - boolean function matchPatterns( required array patterns, required string path ){ - for( var pattern in arguments.patterns ) { - if( matchPattern( pattern, arguments.path ) ) { - return true; - } - } - return false; - } - -} \ No newline at end of file From b32ceb29178a98d1bf29eab6a9ec03551a1e35d4 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 13 Sep 2016 17:13:22 -0700 Subject: [PATCH 64/91] COMMANDBOX-420 --- src/cfml/system/services/PackageService.cfc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/cfml/system/services/PackageService.cfc b/src/cfml/system/services/PackageService.cfc index eaf1f19cb..80a710375 100644 --- a/src/cfml/system/services/PackageService.cfc +++ b/src/cfml/system/services/PackageService.cfc @@ -1033,7 +1033,10 @@ component accessors="true" singleton { 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 ) ) { - + + // Run preXXX package script + runScript( 'pre#arguments.scriptName#', arguments.directory, true ); + var thisScript = boxJSON.scripts[ arguments.scriptName ]; consoleLogger.debug( '.' ); consoleLogger.warn( 'Running package script [#arguments.scriptName#].' ); @@ -1044,6 +1047,10 @@ component accessors="true" singleton { shell.cd( arguments.directory ); shell.callCommand( thisScript ); shell.cd( previousCWD ); + + // Run postXXX package script + runScript( 'post#arguments.scriptName#', arguments.directory, true ); + } else if( !arguments.ignoreMissing ) { consoleLogger.error( 'The script [#arguments.scriptName#] does not exist in this package.' ); } From 90c32bb899982e3e9c067792c39350a672ba7d26 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 19 Sep 2016 12:03:25 -0500 Subject: [PATCH 65/91] COMMANDBOX-460 --- .../modules_app/system-commands/commands/execute.cfc | 2 +- src/cfml/system/util/Formatter.cfc | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/cfml/system/modules_app/system-commands/commands/execute.cfc b/src/cfml/system/modules_app/system-commands/commands/execute.cfc index 5b2d6d0e4..3b4b7badd 100644 --- a/src/cfml/system/modules_app/system-commands/commands/execute.cfc +++ b/src/cfml/system/modules_app/system-commands/commands/execute.cfc @@ -47,7 +47,7 @@ component aliases="exec"{ var out = wirebox.getInstance( "Executor" ).runFile( arguments.file, vars ); } catch( any e ){ print.boldGreen( "Error executing #arguments.file#: " ); - return error( '#e.message##CR##e.detail##CR##e.stackTrace#' ); + rethrow; } return ( out ?: "The file '#arguments.file#' executed succesfully!" ); diff --git a/src/cfml/system/util/Formatter.cfc b/src/cfml/system/util/Formatter.cfc index bb11b4d09..5099acdd2 100644 --- a/src/cfml/system/util/Formatter.cfc +++ b/src/cfml/system/util/Formatter.cfc @@ -38,10 +38,13 @@ component singleton { if( len( trim( text ) ) == 0 ) { return ""; - } + } text = ansifyHTML( text, "b", "bold" ); text = ansifyHTML( text, "strong", "bold" ); text = ansifyHTML( text, "em", "underline" ); + + // Remove inherent line breaks + text = reReplaceNoCase( text , CR, '', 'all' ); text = reReplaceNoCase( text , "]*>", CR, 'all' ); var t='div'; @@ -68,7 +71,7 @@ component singleton { **/ function ansifyHTML(text,tag,ansiCode) { var t=tag; - var matches = REMatch('(?i)<#t#[^>]*>(.+?)', text); + var matches = REMatch('(?i)<#t#[ ^>]*>(.+?)', text); for(var match in matches) { // This doesn't really work inside of a larger string that you are applying formatting to // The end of the boldText clears all formatting, and the rest of the string is just plain. From 391ac46ec45a05d27b7e93b39179ba19fac020c0 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 19 Sep 2016 19:00:42 -0500 Subject: [PATCH 66/91] // Replace remainingbr tags followed by whitespace with a CR --- src/cfml/system/util/Formatter.cfc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/cfml/system/util/Formatter.cfc b/src/cfml/system/util/Formatter.cfc index 5099acdd2..853768e6a 100644 --- a/src/cfml/system/util/Formatter.cfc +++ b/src/cfml/system/util/Formatter.cfc @@ -43,9 +43,8 @@ component singleton { text = ansifyHTML( text, "strong", "bold" ); text = ansifyHTML( text, "em", "underline" ); - // Remove inherent line breaks - text = reReplaceNoCase( text , CR, '', 'all' ); - text = reReplaceNoCase( text , "]*>", CR, 'all' ); + // Replace br tags (and any whitespace/line breaks after them) with a CR + text = reReplaceNoCase( text , "]*>\s*", CR, 'all' ); var t='div'; var matches = REMatch('(?i)<#t#[^>]*>(.*?)', text); From 04460f3b1b7feff1c9813da453c1d17d354e72b7 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 20 Sep 2016 12:49:26 -0500 Subject: [PATCH 67/91] COMMANDBOX-461 --- .../server-commands/commands/server/start.cfc | 2 +- src/cfml/system/util/ForgeBox.cfc | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/cfml/system/modules_app/server-commands/commands/server/start.cfc b/src/cfml/system/modules_app/server-commands/commands/server/start.cfc index 93d4f7527..6b82fed58 100644 --- a/src/cfml/system/modules_app/server-commands/commands/server/start.cfc +++ b/src/cfml/system/modules_app/server-commands/commands/server/start.cfc @@ -151,7 +151,7 @@ component aliases="start" { try { // Get auto-complete options - return forgebox.slugSearch( arguments.paramSoFar, 'cf-engines' ); + return forgebox.slugSearch( arguments.paramSoFar, 'cf-engines' ); } catch( forgebox var e ) { // Gracefully handle ForgeBox issues print diff --git a/src/cfml/system/util/ForgeBox.cfc b/src/cfml/system/util/ForgeBox.cfc index 576d07b95..3502433f1 100644 --- a/src/cfml/system/util/ForgeBox.cfc +++ b/src/cfml/system/util/ForgeBox.cfc @@ -349,7 +349,16 @@ or just add DEBUG to the root logger throw( "Error searching for slugs", 'forgebox', arrayToList( results.response.messages ) ); } - return results.response.data; + var opts = results.response.data; + + // If there's only one suggestion and it doesn't have an @ in it, add another suggestion with the @ at the end. + // This is to prevent the tab completion from adding a space after the suggestion since it thinks it's the only possible option + // Hitting tab will still populate the line, but won't add the space which makes it easier if the user intends to continue for a specific version. + if( opts.len() == 1 && !( opts[1] contains '@' ) ) { + opts.append( opts[1] & '@' ); + } + + return opts; } From 80f8edd19fbe91ae151531b231050752dbcd9e7c Mon Sep 17 00:00:00 2001 From: Jon Clausen Date: Wed, 28 Sep 2016 11:19:28 -0400 Subject: [PATCH 68/91] bump our server startup timeout for Adobe engines --- src/cfml/system/services/ServerService.cfc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index e920e3aab..8b5fa84de 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -526,6 +526,11 @@ component accessors="true" singleton { // Serialize tray options and write to temp file var trayOptionsPath = serverInfo.serverHome & '/trayOptions.json'; fileWrite( trayOptionsPath, serializeJSON( serverInfo.trayOptions ) ); + + + var startupTimeout = 120; + // Increase our startup allowance for Adobe engines, since a number of files are generated on the first request + if( CFEngineName == 'adobe' ) startupTimeout=240; // The java arguments to execute: Shared server, custom web configs var args = ' #serverInfo.JVMargs# -Xmx#serverInfo.heapSize#m -Xms#serverInfo.heapSize#m' @@ -539,7 +544,7 @@ component accessors="true" singleton { & ' --tray-icon "#serverInfo.trayIcon#" --tray-config "#trayOptionsPath#"' & ' --directoryindex "#serverInfo.directoryBrowsing#" --cfml-web-config "#serverInfo.webConfigDir#"' & ( len( CLIAliases ) ? ' --dirs "#CLIAliases#"' : '' ) - & ' --cfml-server-config "#serverInfo.serverConfigDir#" #serverInfo.runwarArgs# --timeout 120'; + & ' --cfml-server-config "#serverInfo.serverConfigDir#" #serverInfo.runwarArgs# --timeout #startupTimeout#'; // Starting a WAR if (serverInfo.WARPath != "" ) { From 8fbc70950e0b70e30187330eb190fe490ce55d81 Mon Sep 17 00:00:00 2001 From: Jon Clausen Date: Wed, 28 Sep 2016 11:46:25 -0400 Subject: [PATCH 69/91] conditional needs brackets per syntax guidelines --- src/cfml/system/services/ServerService.cfc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 8b5fa84de..7bef4afa2 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -530,7 +530,9 @@ component accessors="true" singleton { var startupTimeout = 120; // Increase our startup allowance for Adobe engines, since a number of files are generated on the first request - if( CFEngineName == 'adobe' ) startupTimeout=240; + if( CFEngineName == 'adobe' ) { + startupTimeout=240; + } // The java arguments to execute: Shared server, custom web configs var args = ' #serverInfo.JVMargs# -Xmx#serverInfo.heapSize#m -Xms#serverInfo.heapSize#m' From bd99ded2c1f470517b975bbe5719e836d1ff413a Mon Sep 17 00:00:00 2001 From: Jon Clausen Date: Wed, 28 Sep 2016 11:46:42 -0400 Subject: [PATCH 70/91] conditional needs brackets per syntax guidelines --- src/cfml/system/services/ServerService.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 7bef4afa2..b2a1a8fe5 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -530,7 +530,7 @@ component accessors="true" singleton { var startupTimeout = 120; // Increase our startup allowance for Adobe engines, since a number of files are generated on the first request - if( CFEngineName == 'adobe' ) { + if( CFEngineName == 'adobe' ){ startupTimeout=240; } From 11bcd600a8d30a821e7353e407f794108ae7fc42 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Fri, 30 Sep 2016 14:34:10 -0500 Subject: [PATCH 71/91] COMMANDBOX-464 --- .../package-commands/commands/package/update.cfc | 10 ++++++++-- src/cfml/system/services/PackageService.cfc | 13 +++++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/cfml/system/modules_app/package-commands/commands/package/update.cfc b/src/cfml/system/modules_app/package-commands/commands/package/update.cfc index c2e07c72d..1517551be 100644 --- a/src/cfml/system/modules_app/package-commands/commands/package/update.cfc +++ b/src/cfml/system/modules_app/package-commands/commands/package/update.cfc @@ -59,7 +59,7 @@ component aliases="update" { verbose=arguments.verbose, includeSlugs=arguments.slug ); - + // Advice initial notice if( dependenciesToUpdate.len() ){ print.green( 'Found ' ) @@ -90,7 +90,13 @@ component aliases="update" { print.magentaLine( "Starting update of #oldID# ").toConsole(); // install it - runCommand( "install ID='#parser.escapeArg( newID )#' verbose=#arguments.verbose# --force --!save" ); + command( 'install' ) + .params( + ID=newID, + verbose=arguments.verbose, + directory=dependency.directory ) + .flags( 'force', '!save' ) + .run( echo=arguments.verbose ) } } diff --git a/src/cfml/system/services/PackageService.cfc b/src/cfml/system/services/PackageService.cfc index 80a710375..d637c9544 100644 --- a/src/cfml/system/services/PackageService.cfc +++ b/src/cfml/system/services/PackageService.cfc @@ -916,6 +916,7 @@ component accessors="true" singleton { if( updateData.isOutdated ){ aOutdatedDependencies.append({ slug : arguments.slug, + directory : value.directory, version : value.version, packageVersion : value.packageVersion, newVersion : updateData.version, @@ -958,7 +959,8 @@ component accessors="true" singleton { 'shortDescription' : boxJSON.shortDescription, 'version': boxJSON.version, 'packageVersion': boxJSON.version, - 'isInstalled': true + 'isInstalled': true, + 'directory': arguments.directory }; buildChildren( boxJSON, tree, arguments.directory); return tree; @@ -979,7 +981,8 @@ component accessors="true" singleton { 'name' : '', 'shortDescription' : '', 'packageVersion' : '', - 'isInstalled': false + 'isInstalled': false, + 'directory': '' }; if( structKeyExists( arguments.installPaths, dependency ) ) { @@ -990,6 +993,12 @@ component accessors="true" singleton { thisDeps[ dependency ][ 'shortDescription' ] = boxJSON.shortDescription; thisDeps[ dependency ][ 'packageVersion' ] = boxJSON.version; thisDeps[ dependency ][ 'isInstalled' ] = true; + if( boxJSON.createPackageDirectory ) { + // Back up to the "container" folder. The packge directory will be added back on installation + thisDeps[ dependency ][ 'directory' ] = listDeleteAt( fullPackageInstallPath, listLen( fullPackageInstallPath, '/\' ), '/\' ); + } else { + thisDeps[ dependency ][ 'directory' ] = fullPackageInstallPath; + } // Down the rabbit hole buildChildren( boxJSON, thisDeps[ dependency ], fullPackageInstallPath ); From 159308c15821259617a54fed6737e8a5cc955e51 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Sun, 2 Oct 2016 00:38:30 -0500 Subject: [PATCH 72/91] COMMANDBOX-430 --- .../commands/forgebox/whoami.cfc | 33 +++++++++++++++++++ src/cfml/system/util/ForgeBox.cfc | 15 +++++++++ 2 files changed, 48 insertions(+) create mode 100644 src/cfml/system/modules_app/forgebox-commands/commands/forgebox/whoami.cfc diff --git a/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/whoami.cfc b/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/whoami.cfc new file mode 100644 index 000000000..094f5dd73 --- /dev/null +++ b/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/whoami.cfc @@ -0,0 +1,33 @@ + /** + * Looks up the user associated with your current ForgeBox API Token + * . + * {code:bash} + * forgebox whoami + * {code} + **/ +component { + + property name="forgeBox" inject="ForgeBox"; + property name="configService" inject="ConfigService"; + + /** + * + **/ + function run(){ + try { + var APIToken = configService.getSetting( 'endpoints.forgebox.APIToken', '' ); + if( !len( APIToken) ) { + error( 'You don''t have a Forgebox API token set.', 'Use "forgebox login" to authenticate as a user.' ); + } + userData = forgebox.whoami( APIToken ); + + print.boldLine( '#userData.fname# #userData.lname# (#userData.username#)' ) + .line( userData.email ); + + } catch( forgebox var e ) { + // This can include "expected" errors such as "Email already in use" + error( e.message, e.detail ); + } + } + +} \ No newline at end of file diff --git a/src/cfml/system/util/ForgeBox.cfc b/src/cfml/system/util/ForgeBox.cfc index 3502433f1..637d538c7 100644 --- a/src/cfml/system/util/ForgeBox.cfc +++ b/src/cfml/system/util/ForgeBox.cfc @@ -203,6 +203,21 @@ or just add DEBUG to the root logger return results.response.data; } + /** + * Look up user based on API Token + */ + function whoami( required string APIToken ) { + + var results = makeRequest( resource="users/whoami/#APIToken#", method='get' ); + + // error + if( results.response.error ){ + throw( arrayToList( results.response.messages ), 'forgebox' ); + } + + return results.response.data; + } + /** * Authenticates a user in ForgeBox */ From 4c2b8d26750be413456bf17c90f62b1c4fad0e28 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Sun, 2 Oct 2016 00:52:20 -0500 Subject: [PATCH 73/91] COMMANDBOX-431 --- src/cfml/system/services/EndpointService.cfc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cfml/system/services/EndpointService.cfc b/src/cfml/system/services/EndpointService.cfc index ee1a1b9fb..818962f4d 100644 --- a/src/cfml/system/services/EndpointService.cfc +++ b/src/cfml/system/services/EndpointService.cfc @@ -180,6 +180,7 @@ component accessors="true" singleton { // Store the APIToken configService.setSetting( 'endpoints.#endpointName#.APIToken', APIToken ); + configService.setSetting( 'endpoints.#endpointName#.tokens.#arguments.username#', APIToken ); } @@ -214,6 +215,7 @@ component accessors="true" singleton { // Store the APIToken configService.setSetting( 'endpoints.#endpointName#.APIToken', APIToken ); + configService.setSetting( 'endpoints.#endpointName#.tokens.#arguments.username#', APIToken ); } From 20d54d1cf419f99d855b5d11412a20666cea268f Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Sun, 2 Oct 2016 01:06:26 -0500 Subject: [PATCH 74/91] COMMANDBOX-432 --- .../commands/forgebox/use.cfc | 44 +++++++++++++++++++ .../commands/forgebox/whoami.cfc | 2 +- 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 src/cfml/system/modules_app/forgebox-commands/commands/forgebox/use.cfc diff --git a/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/use.cfc b/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/use.cfc new file mode 100644 index 000000000..3f2f1005f --- /dev/null +++ b/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/use.cfc @@ -0,0 +1,44 @@ + /** + * Switch APIKey in use based on username. If no API Key is stored, prompt to authenticate + * . + * {code:bash} + * forgebox use username + * {code} + * . + * To skip interactivity, use the skipLogin flag and you won't be asked to log if the username provided isn't authenticated + * {code:bash} + * forgebox use username --skipLogin + * {code} + **/ +component { + + property name="forgeBox" inject="ForgeBox"; + property name="configService" inject="ConfigService"; + + /** + * @username The ForgeBox username to switch to. + * @skipLogin If username isn't authenticated, retuen an error instead of prompting with login + **/ + function run( required string username, boolean skipLogin=false ){ + + var tokens = configService.getSetting( 'endpoints.forgebox.tokens', {} ); + if( !len( arguments.username ) ) { + error( 'Please provide a ForgeBox username to use.' ); + } + + // If this username exists + if( tokens.keyExists( arguments.username ) ) { + // Set the active token + configService.setSetting( 'endpoints.forgebox.APIToken', tokens[ arguments.username ] ); + print.greenLine( 'Active Forgebox user set to [#arguments.username#]' ); + } else if( !skipLogin ) { + // Otherwise, prompt them to login + command( 'forgebox login' ) + .params( arguments.username ) + .run(); + } else { + error( 'Username [#arguments.username#] isn''t authentcated. Please use "forgebox login".' ); + } + } + +} \ No newline at end of file diff --git a/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/whoami.cfc b/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/whoami.cfc index 094f5dd73..1aa76c2f4 100644 --- a/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/whoami.cfc +++ b/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/whoami.cfc @@ -16,7 +16,7 @@ component { function run(){ try { var APIToken = configService.getSetting( 'endpoints.forgebox.APIToken', '' ); - if( !len( APIToken) ) { + if( !len( APIToken ) ) { error( 'You don''t have a Forgebox API token set.', 'Use "forgebox login" to authenticate as a user.' ); } userData = forgebox.whoami( APIToken ); From 448e625fa98731ae0abac4eb1eb02f33395eee1a Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Sun, 2 Oct 2016 22:37:12 -0500 Subject: [PATCH 75/91] COMMANDBOX-458 --- src/cfml/system/services/ServerService.cfc | 41 ++++++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index e920e3aab..4e1510fe4 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -130,8 +130,10 @@ component accessors="true" singleton { host : d.web.host ?: '127.0.0.1', directoryBrowsing : d.web.directoryBrowsing ?: true, webroot : d.web.webroot ?: '', - // Duplicate so onServerStart interceptors don't actually change config settings via refernce. + // Duplicate so onServerStart interceptors don't actually change config settings via refernce. aliases : duplicate( d.web.aliases ?: {} ), + // Duplicate so onServerStart interceptors don't actually change config settings via refernce. + errorPages : duplicate( d.web.errorPages ?: {} ), http : { port : d.web.http.port ?: 0, enable : d.web.http.enable ?: true @@ -378,6 +380,12 @@ component accessors="true" singleton { serverInfo.aliases = defaults.web.aliases; serverInfo.aliases.append( serverJSON.web.aliases ?: {} ); + // Global errorPages are always added on top of server.json (but don't overwrite the full struct) + // Aliases aren't accepted via command params + serverInfo.errorPages = defaults.web.errorPages; + serverInfo.errorPages.append( serverJSON.web.errorPages ?: {} ); + + // Global trayOptions are always added on top of server.json (but don't overwrite) // trayOptions aren't accepted via command params due to no clean way to provide them serverInfo.trayOptions = defaults.trayOptions; @@ -523,6 +531,23 @@ component accessors="true" singleton { CLIAliases = CLIAliases.listAppend( thisAlias & '=' & fileSystemUtil.resolvePath( serverInfo.aliases[ thisAlias ], serverInfo.webroot ) ); } + // Turn struct of errorPages into a comma-delimited list. + // --error-pages="404=/path/to/404.html,500=/path/to/500.html,1=/path/to/default.html" + var errorPages = ''; + for( var thisErrorPage in serverInfo.errorPages ) { + // "default" turns into "1" + var tmp = thisErrorPage == 'default' ? 1 : thisErrorPage; + tmp &= '='; + // normalize slashes + var thisPath = replace( serverInfo.errorPages[ thisErrorPage ], '\', '/', 'all' ); + // Add leading slash if it doesn't exist. + tmp &= thisPath.startsWith( '/' ) ? thisPath : '/' & thisPath; + errorPages = errorPages.listAppend( tmp ); + } + if( len( errorPages ) ) { + errorPages = '--error-pages="#errorPages#"'; + } + // Serialize tray options and write to temp file var trayOptionsPath = serverInfo.serverHome & '/trayOptions.json'; fileWrite( trayOptionsPath, serializeJSON( serverInfo.trayOptions ) ); @@ -535,7 +560,7 @@ component accessors="true" singleton { & ' --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#"' + & ' --server-name "#serverInfo.name#" #errorPages#' & ' --tray-icon "#serverInfo.trayIcon#" --tray-config "#trayOptionsPath#"' & ' --directoryindex "#serverInfo.directoryBrowsing#" --cfml-web-config "#serverInfo.webConfigDir#"' & ( len( CLIAliases ) ? ' --dirs "#CLIAliases#"' : '' ) @@ -1147,8 +1172,18 @@ component accessors="true" singleton { // If we want all possible options... if( arguments.all ) { - // ... Then add them in + // ... Then add them in props = JSONService.addProp( props, '', '', getDefaultServerJSON() ); + // Suggest a couple optional web error pages + props = JSONService.addProp( props, '', '', { + web : { + errorPages : { + 404 : '', + 500 : '', + default : '' + } + } + } ); } return props; From e2fcbc5d8373778ae028fec7baa9a167a9c1902a Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Mon, 3 Oct 2016 12:12:39 -0500 Subject: [PATCH 76/91] Added comments --- src/cfml/system/services/ServerService.cfc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 4e1510fe4..a28231a4e 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -544,6 +544,8 @@ component accessors="true" singleton { tmp &= thisPath.startsWith( '/' ) ? thisPath : '/' & thisPath; errorPages = errorPages.listAppend( tmp ); } + // Bug in runwar requires me to completley omit this param unless it's populated + // https://github.com/cfmlprojects/runwar/issues/33 if( len( errorPages ) ) { errorPages = '--error-pages="#errorPages#"'; } From 777f3dc73d786491150c07e38be13e564df64eed Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 4 Oct 2016 10:12:46 -0500 Subject: [PATCH 77/91] COMMANDBOX-466 --- .../coldbox-commands/commands/coldbox/create/orm-crud.cfc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-crud.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-crud.cfc index 913fe32f2..80a5ac50d 100644 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-crud.cfc +++ b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-crud.cfc @@ -33,8 +33,9 @@ component { // entity defaults var entityName = listLast( arguments.entity, "." ); - var entityCFC = fileSystemUtil.resolvePath( replace( arguments.entity, ".", "/", "all" ) ); + var entityCFC = fileSystemUtil.makePathRelative( fileSystemUtil.resolvePath( replace( arguments.entity, ".", "/", "all" ) ) ); var entityPath = entityCFC & ".cfc"; + // verify it if( !fileExists( entityPath ) ){ return error( "The entity #entityPath# does not exist, cannot continue, ciao!" ); From 1df96eeacdf9df791f7f7d7ea58f36ec97e87f3d Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Tue, 4 Oct 2016 11:05:40 -0500 Subject: [PATCH 78/91] COMMANDBOX-465 --- src/cfml/system/services/ServerService.cfc | 30 ++++++++++++++++------ 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index a28231a4e..61e7c2329 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -238,7 +238,10 @@ component accessors="true" singleton { } if( !isNull( serverProps.trayIcon ) ) { serverProps.trayIcon = fileSystemUtil.resolvePath( serverProps.trayIcon ); - } + } + if( !isNull( serverProps.rewritesConfig ) ) { + serverProps.rewritesConfig = fileSystemUtil.resolvePath( serverProps.rewritesConfig ); + } // Save hand-entered properties in our server.json for next time for( var prop in serverProps ) { @@ -266,13 +269,13 @@ component accessors="true" singleton { break; case "trayIcon": // Both of these are canonical already. - var thisDirectory = replace( serverProps[ 'trayIcon' ], '\', '/', 'all' ) & '/'; + var thisFile = replace( serverProps[ 'trayIcon' ], '\', '/', 'all' ); var configPath = replace( fileSystemUtil.resolvePath( defaultServerConfigFileDirectory ), '\', '/', 'all' ) & '/'; // If the trayIcon is south of the server's JSON, make it relative for better portability. - if( thisDirectory contains configPath ) { - thisDirectory = replaceNoCase( thisDirectory, configPath, '' ); + if( thisFile contains configPath ) { + thisFile = replaceNoCase( thisFile, configPath, '' ); } - serverJSON[ 'trayIcon' ] = thisDirectory; + serverJSON[ 'trayIcon' ] = thisFile; break; case "stopPort": serverJSON[ 'stopsocket' ] = serverProps[ prop ]; @@ -317,7 +320,14 @@ component accessors="true" singleton { serverJSON[ 'web' ][ 'rewrites' ][ 'enable' ] = serverProps[ prop ]; break; case "rewritesConfig": - serverJSON[ 'web' ][ 'rewrites' ][ 'config' ] = serverProps[ prop ]; + // Both of these are canonical already. + var thisFile = replace( serverProps[ 'rewritesConfig' ], '\', '/', 'all' ); + var configPath = replace( fileSystemUtil.resolvePath( defaultServerConfigFileDirectory ), '\', '/', 'all' ) & '/'; + // If the trayIcon is south of the server's JSON, make it relative for better portability. + if( thisFile contains configPath ) { + thisFile = replaceNoCase( thisFile, configPath, '' ); + } + serverJSON[ 'web' ][ 'rewrites' ][ 'config' ] = thisFile; break; case "heapSize": serverJSON[ 'JVM' ][ 'heapSize' ] = serverProps[ prop ]; @@ -371,6 +381,8 @@ component accessors="true" singleton { serverInfo.SSLKey = serverProps.SSLKey ?: serverJSON.web.SSL.key ?: defaults.web.SSL.key; serverInfo.SSLKeyPass = serverProps.SSLKeyPass ?: serverJSON.web.SSL.keyPass ?: defaults.web.SSL.keyPass; serverInfo.rewritesEnable = serverProps.rewritesEnable ?: serverJSON.web.rewrites.enable ?: defaults.web.rewrites.enable; + if( isDefined( 'serverJSON.web.rewrites.config' ) ) { serverJSON.web.rewrites.config = fileSystemUtil.resolvePath( serverJSON.web.rewrites.config, defaultServerConfigFileDirectory ); } + if( isDefined( 'defaults.web.rewrites.config' ) ) { defaults.web.rewrites.config = fileSystemUtil.resolvePath( defaults.web.rewrites.config, defaultwebroot ); } serverInfo.rewritesConfig = serverProps.rewritesConfig ?: serverJSON.web.rewrites.config ?: defaults.web.rewrites.config; serverInfo.heapSize = serverProps.heapSize ?: serverJSON.JVM.heapSize ?: defaults.JVM.heapSize; serverInfo.directoryBrowsing = serverProps.directoryBrowsing ?: serverJSON.web.directoryBrowsing ?: defaults.web.directoryBrowsing; @@ -595,9 +607,11 @@ component accessors="true" singleton { 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#"; + consoleLogger.error( '.' ); + consoleLogger.error( 'URL rewrite config not found [#serverInfo.rewritesConfig#]' ); + consoleLogger.error( '.' ); + return; } args &= " --urlrewrite-file ""#serverInfo.rewritesConfig#"""; } From 38f66a83dd2f22ba3065e8053d348388b9b9cb89 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 5 Oct 2016 10:20:24 -0500 Subject: [PATCH 79/91] Bumping to stable Runwar version --- build/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build.properties b/build/build.properties index 8b6d12a62..b21c05c6b 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.9-SNAPSHOT +runwar.version=3.4.9 #build locations build.type=localdev From 66fd586e6bc4c2f0eb9cb0de41d62e46e6c09e21 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 5 Oct 2016 12:06:29 -0500 Subject: [PATCH 80/91] Bump for rc 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 b21c05c6b..9d40bf4f8 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.6 +cfml.loader.version=1.3.7 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 844e6bb07..9ce8c4d68 100644 --- a/build/build.xml +++ b/build/build.xml @@ -15,7 +15,7 @@ External Dependencies: - + From 61a2e3028e61af88796a470bcf2d850df8bf5b3b Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Thu, 6 Oct 2016 17:06:32 -0500 Subject: [PATCH 81/91] The server name is now redundant. --- src/cfml/system/services/ServerService.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index 61e7c2329..d44c1ae07 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -529,7 +529,7 @@ component accessors="true" singleton { } serverInfo.trayOptions.prepend( { 'label':'Open Browser', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/' } ); - serverInfo.trayOptions.prepend( { 'label':'Stop Server (${runwar.processName})', 'action':'stopserver' } ); + serverInfo.trayOptions.prepend( { 'label':'Stop Server', 'action':'stopserver' } ); // This is due to a bug in RunWar not creating the right directory for the logs directoryCreate( serverInfo.logDir, true, true ); From 2f265711bbcb25cea548e31a213e714996963c3b Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Fri, 7 Oct 2016 21:38:57 -0700 Subject: [PATCH 82/91] Update runwar to fix server process not existing --- build/build.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/build.properties b/build/build.properties index 9d40bf4f8..858096ffd 100644 --- a/build/build.properties +++ b/build/build.properties @@ -12,12 +12,12 @@ java.pack200=false #dependencies dependencies.dir=${basedir}/lib cfml.version=4.5.2.018 -cfml.loader.version=1.3.7 +cfml.loader.version=1.3.8 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.9 +runwar.version=3.4.10 #build locations build.type=localdev From dc2187da182a0e0a8db804831712bb9ff795ab29 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Fri, 7 Oct 2016 22:46:13 -0700 Subject: [PATCH 83/91] COMMANDBOX-467 --- src/cfml/system/config/server-icons/home.png | Bin 0 -> 21991 bytes src/cfml/system/config/server-icons/info.png | Bin 0 -> 8475 bytes .../config/server-icons/server_settings.png | Bin 0 -> 7911 bytes src/cfml/system/config/server-icons/stop.png | Bin 0 -> 23350 bytes .../config/server-icons/web_settings.png | Bin 0 -> 5451 bytes src/cfml/system/services/ServerService.cfc | 22 +++++++++++------- 6 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 src/cfml/system/config/server-icons/home.png create mode 100644 src/cfml/system/config/server-icons/info.png create mode 100644 src/cfml/system/config/server-icons/server_settings.png create mode 100644 src/cfml/system/config/server-icons/stop.png create mode 100644 src/cfml/system/config/server-icons/web_settings.png diff --git a/src/cfml/system/config/server-icons/home.png b/src/cfml/system/config/server-icons/home.png new file mode 100644 index 0000000000000000000000000000000000000000..7ba349aadee0c1c91e3c3ff5e34f479b29ce9c2e GIT binary patch literal 21991 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 literal 0 HcmV?d00001 diff --git a/src/cfml/system/config/server-icons/info.png b/src/cfml/system/config/server-icons/info.png new file mode 100644 index 0000000000000000000000000000000000000000..3fa750a11aaa355e41eb25dbd2ec58b92098e4f0 GIT binary patch literal 8475 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 B?(6^n literal 0 HcmV?d00001 diff --git a/src/cfml/system/config/server-icons/server_settings.png b/src/cfml/system/config/server-icons/server_settings.png new file mode 100644 index 0000000000000000000000000000000000000000..e9fc520e711c0e84560c587f104f71e81792fc5f GIT binary patch literal 7911 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 XbHYj8zJ0)qYaDG21N9nJ`*;5XW&TUG literal 0 HcmV?d00001 diff --git a/src/cfml/system/config/server-icons/web_settings.png b/src/cfml/system/config/server-icons/web_settings.png new file mode 100644 index 0000000000000000000000000000000000000000..1eac22f29682632469c323de455c652533448921 GIT binary patch literal 5451 zcmV-R6}0M!P)cWF~+fjYZKy%mm>&sNJtuWw+;}xki{i#aTo+TW02hYzMgLJX4EtD zUia&sZZuu>71E&j`t|#L{f_VbzV8bJ?y;-5Sj{PVHTqB}A}!`c`6oe9t_%vwM?pcZ z3r3{wpdj_5e{TgN$`}`sCP3h4?KAX$ydZUHe+%D1-{m9H3!K;#3Pzg$7IX))SN!$p zqmRr$l7q<%H}x$oZGIpm%BzE-QWX>>8G$&A09EgbY$A#!;UmgWP;8WuVN~&v=<1?y z-2-kvuiN_4-7GgzoYwc9;@Ui}Oy&S^1jvb$pos`g**5@NJx+43dE*O%+?_&9z4`1BKbT%>UkC(3*2!9qi{5S=QP=Y3}SszXB4zdW>cOODh1XGb5&&EN)e zFv+vo_(^?Bmi!=}Tfgr~^wzZ71FHcO7T`0~7p`v)uG_cj+pE4imv#Ty)tByOV7buf zd`#f?9J~6yy?j{#w{Fk!V7RW`UgtJI2V>HpdRJfF5%kPUS@a(ZJVd)-)7@A zeZl|v!#9Gj)E?A2#on6*or;NX^i}g^^1@8wL3*=!m=xFqzu?h-UH4_aWZ!0Pecia$ zAy&6%@ICl`DJK5YcLx@_q2kuL#Qnzz50W`%E_TED`oDI-pU1!ar^kcqYtIHt55+pf zPUmW!dI%H$>f;3I6f6|e^`DNze7krU7^hocY)_G96q*?hFdeUvm)rnWhGSITi9S1F*H= z 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 Bq2T}k literal 0 HcmV?d00001 diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index aacbdf1c2..345a315af 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -519,17 +519,18 @@ component accessors="true" singleton { // TODO: Don't overwrite existing options with the same label. if( serverInfo.cfengine contains "lucee" ) { - serverInfo.trayOptions.prepend( { 'label':'Open Web Admin', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/lucee/admin/web.cfm' } ); - serverInfo.trayOptions.prepend( { 'label':'Open Server Admin', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/lucee/admin/server.cfm' } ); + serverInfo.trayOptions.prepend( { 'label':'Open Web Admin', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/lucee/admin/web.cfm', 'image' : expandPath('/commandbox/system/config/server-icons/web_settings.png' ) } ); + serverInfo.trayOptions.prepend( { 'label':'Open Server Admin', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/lucee/admin/server.cfm', 'image' : expandPath('/commandbox/system/config/server-icons/server_settings.png' ) } ); } else if( serverInfo.cfengine contains "railo" ) { - serverInfo.trayOptions.prepend( { 'label':'Open Web Admin', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/railo-context/admin/web.cfm' } ); - serverInfo.trayOptions.prepend( { 'label':'Open Server Admin', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/railo-context/admin/server.cfm' } ); + serverInfo.trayOptions.prepend( { 'label':'Open Web Admin', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/railo-context/admin/web.cfm', 'image' : expandPath('/commandbox/system/config/server-icons/web_settings.png' ) } ); + serverInfo.trayOptions.prepend( { 'label':'Open Server Admin', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/railo-context/admin/server.cfm', 'image' : expandPath('/commandbox/system/config/server-icons/server_settings.png' ) } ); } else if( serverInfo.cfengine contains "adobe" ) { - serverInfo.trayOptions.prepend( { 'label':'Open Server Admin', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/CFIDE/administrator/enter.cfm' } ); + serverInfo.trayOptions.prepend( { 'label':'Open Server Admin', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/CFIDE/administrator/enter.cfm', 'image' : expandPath('/commandbox/system/config/server-icons/server_settings.png' ) } ); } - serverInfo.trayOptions.prepend( { 'label':'Open Browser', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/' } ); - serverInfo.trayOptions.prepend( { 'label':'Stop Server', 'action':'stopserver' } ); + serverInfo.trayOptions.prepend( { 'label':'Open Browser', 'action':'openbrowser', 'url':'http://${runwar.host}:${runwar.port}/', 'image' : expandPath('/commandbox/system/config/server-icons/home.png' ) } ); + serverInfo.trayOptions.prepend( { 'label':'Stop Server', 'action':'stopserver', 'image' : expandPath('/commandbox/system/config/server-icons/stop.png' ) } ); + serverInfo.trayOptions.prepend( { 'label': processName, 'disabled':true, 'image' : expandPath('/commandbox/system/config/server-icons/info.png' ) } ); // This is due to a bug in RunWar not creating the right directory for the logs directoryCreate( serverInfo.logDir, true, true ); @@ -564,7 +565,12 @@ component accessors="true" singleton { // Serialize tray options and write to temp file var trayOptionsPath = serverInfo.serverHome & '/trayOptions.json'; - fileWrite( trayOptionsPath, serializeJSON( serverInfo.trayOptions ) ); + var trayJSON = { + 'title' : processName, + 'tooltip' : processName, + 'items' : serverInfo.trayOptions + }; + fileWrite( trayOptionsPath, serializeJSON( trayJSON ) ); var startupTimeout = 120; From 1d78a86755f11217d8f3995c8031a6fce9ba925f Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Sat, 8 Oct 2016 14:26:32 -0700 Subject: [PATCH 84/91] COMMANDBOX-468 #resolve Add overwrite confirmations to all coldbox create commands --- .../commands/coldbox/create/handler.cfc | 7 ++ .../coldbox/create/handlers/Users.cfc | 118 ------------------ .../coldbox/create/integration-test.cfc | 7 ++ .../coldbox/create/interceptor-test.cfc | 7 ++ .../commands/coldbox/create/interceptor.cfc | 7 ++ .../commands/coldbox/create/layout.cfc | 7 ++ .../commands/coldbox/create/model-test.cfc | 7 ++ .../commands/coldbox/create/model.cfc | 8 +- .../commands/coldbox/create/module.cfc | 7 ++ .../commands/coldbox/create/orm-entity.cfc | 7 ++ .../commands/coldbox/create/orm-service.cfc | 7 ++ .../coldbox/create/orm-virtual-service.cfc | 7 ++ .../commands/coldbox/create/view.cfc | 7 ++ .../coldbox/create/views/Users/edit.cfm | 1 - .../coldbox/create/views/Users/editor.cfm | 39 ------ .../coldbox/create/views/Users/index.cfm | 49 -------- .../coldbox/create/views/Users/new.cfm | 3 - .../commands/coldbox/interceptor/help.cfc | 12 -- .../commands/coldbox/interceptor/install.cfc | 13 -- .../commands/coldbox/interceptor/remove.cfc | 13 -- .../commands/coldbox/module/help.cfc | 12 -- .../commands/coldbox/module/install.cfc | 13 -- .../commands/coldbox/module/list.cfc | 13 -- .../commands/coldbox/module/remove.cfc | 13 -- 24 files changed, 84 insertions(+), 300 deletions(-) delete mode 100644 src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/handlers/Users.cfc delete mode 100644 src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/edit.cfm delete mode 100644 src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/editor.cfm delete mode 100644 src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/index.cfm delete mode 100644 src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/new.cfm delete mode 100644 src/cfml/system/modules_app/coldbox-commands/commands/coldbox/interceptor/help.cfc delete mode 100644 src/cfml/system/modules_app/coldbox-commands/commands/coldbox/interceptor/install.cfc delete mode 100644 src/cfml/system/modules_app/coldbox-commands/commands/coldbox/interceptor/remove.cfc delete mode 100644 src/cfml/system/modules_app/coldbox-commands/commands/coldbox/module/help.cfc delete mode 100644 src/cfml/system/modules_app/coldbox-commands/commands/coldbox/module/install.cfc delete mode 100644 src/cfml/system/modules_app/coldbox-commands/commands/coldbox/module/list.cfc delete mode 100644 src/cfml/system/modules_app/coldbox-commands/commands/coldbox/module/remove.cfc diff --git a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/handler.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/handler.cfc index 7cc71e197..9f4c986a0 100644 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/handler.cfc +++ b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/handler.cfc @@ -112,6 +112,13 @@ component aliases='coldbox create controller' { var handlerPath = '#arguments.directory#/#arguments.name#.cfc'; // Create dir if it doesn't exist directorycreate( getDirectoryFromPath( handlerPath ), true, true ); + + // Confirm it + if( fileExists( handlerPath ) && !confirm( "The file '#getFileFromPath( handlerPath )#' already exists, overwrite it (y/n)?" ) ){ + print.redLine( "Exiting..." ); + return; + } + // Write out the files file action='write' file='#handlerPath#' mode ='777' output='#handlerContent#'; print.greenLine( 'Created #handlerPath#' ); diff --git a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/handlers/Users.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/handlers/Users.cfc deleted file mode 100644 index 86d91af5e..000000000 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/handlers/Users.cfc +++ /dev/null @@ -1,118 +0,0 @@ -/** -* Manage Users -* It will be your responsibility to fine tune this template, add validations, try/catch blocks, logging, etc. -*/ -component{ - - // DI Virtual Entity Service - property name="ormService" inject="entityService:User"; - - // HTTP Method Security - this.allowedMethods = { - index = "GET", new = "GET", edit = "GET", delete = "POST,DELETE", save = "POST,PUT" - }; - - /** - * preHandler() - */ - function preHandler( event, rc, prc ){ - event.paramValue( "format", "html" ); - } - - /** - * Listing - */ - function index( event, rc, prc ){ - // Get all Users - prc.Users = ormService.getAll(); - // Multi-format rendering - event.renderData( data=prc.Users, formats="xml,json,html,pdf" ); - } - - /** - * New Form - */ - function new( event, rc, prc ){ - // get new User - prc.User = ormService.new(); - - event.setView( "Users/new" ); - } - - /** - * Edit Form - */ - function edit( event, rc, prc ){ - // get persisted User - prc.User = ormService.get( rc.user_id ); - - event.setView( "Users/edit" ); - } - - /** - * View User mostly used for RESTful services only. - */ - function show( event, rc, prc ){ - // Default rendering. - event.paramValue( "format", "json" ); - // Get requested entity by id - prc.User = ormService.get( rc.user_id ); - // Multi-format rendering - event.renderData( data=prc.User, formats="xml,json" ); - } - - /** - * Save and Update - */ - function save( event, rc, prc ){ - // get User to persist or update and populate it with incoming form - prc.User = populateModel( model=ormService.get( rc.user_id ), exclude="user_id", composeRelationships=true ); - - // Do your validations here - - // Save it - ormService.save( prc.User ); - - // RESTful Handler - switch(rc.format){ - // xml,json,jsont are by default. Add your own or remove - case "xml" : case "json" : case "jsont" :{ - event.renderData( data=prc.User, type=rc.format, location="/Users/show/#prc.User.getuser_id()#" ); - break; - } - // HTML - default:{ - // Show a nice notice - flash.put( "notice", { message="User Created", type="success" } ); - // Redirect to listing - setNextEvent( 'Users' ); - } - } - } - - /** - * Delete - */ - function delete( event, rc, prc ){ - // Delete record by ID - var removed = ormService.delete( ormService.get( rc.user_id ) ); - - // RESTful Handler - switch( rc.format ){ - // xml,json,jsont are by default. Add your own or remove - case "xml" : case "json" : case "jsont" :{ - var restData = { "deleted" = removed }; - event.renderData( data=restData, type=rc.format ); - break; - } - // HTML - default:{ - // Show a nice notice - flash.put( "notice", { message="User Poofed!", type="success" } ); - // Redirect to listing - setNextEvent( 'Users' ); - } - } - } - -} diff --git a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/integration-test.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/integration-test.cfc index b496451d6..8a406ef2b 100644 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/integration-test.cfc +++ b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/integration-test.cfc @@ -108,6 +108,13 @@ component { var integrationTestPath = '#arguments.directory#/#arguments.handler#Test.cfc'; // Create dir if it doesn't exist directorycreate( getDirectoryFromPath( integrationTestPath ), true, true ); + + // Confirm it + if( fileExists( integrationTestPath ) && !confirm( "The file '#getFileFromPath( integrationTestPath )#' already exists, overwrite it (y/n)?" ) ){ + print.redLine( "Exiting..." ); + return; + } + // Write out the files file action='write' file='#integrationTestPath#' mode ='777' output='#handlerTestContent#'; print.greenLine( 'Created #integrationTestPath#' ); diff --git a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/interceptor-test.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/interceptor-test.cfc index 57a9b496a..2bd3be000 100644 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/interceptor-test.cfc +++ b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/interceptor-test.cfc @@ -57,6 +57,13 @@ component { var testPath = '#arguments.testsDirectory#/#listLast( arguments.path, "." )#Test.cfc'; // Create dir if it doesn't exist directorycreate( getDirectoryFromPath( testPath ), true, true ); + + // Confirm it + if( fileExists( testPath ) && !confirm( "The file '#getFileFromPath( testPath )#' already exists, overwrite it (y/n)?" ) ){ + print.redLine( "Exiting..." ); + return; + } + // Create the tests file action='write' file='#testPath#' mode ='777' output='#interceptorTestContent#'; print.greenLine( 'Created #testPath#' ); diff --git a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/interceptor.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/interceptor.cfc index c45a6cfe0..c3d824512 100644 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/interceptor.cfc +++ b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/interceptor.cfc @@ -89,6 +89,13 @@ component { // Write it out. var interceptorPath = '#arguments.directory#/#arguments.name#.cfc'; + + // Confirm it + if( fileExists( interceptorPath ) && !confirm( "The file '#getFileFromPath( interceptorPath )#' already exists, overwrite it (y/n)?" ) ){ + print.redLine( "Exiting..." ); + return; + } + file action='write' file='#interceptorPath#' mode ='777' output='#interceptorContent#'; print.greenLine( '#interceptorPath#' ); diff --git a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/layout.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/layout.cfc index b7fdcaefc..fc1eecc94 100644 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/layout.cfc +++ b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/layout.cfc @@ -36,6 +36,13 @@ component { // Write out layout var layoutPath = '#arguments.directory#/#arguments.name#.cfm'; + + // Confirm it + if( fileExists( layoutPath ) && !confirm( "The file '#getFileFromPath( layoutPath )#' already exists, overwrite it (y/n)?" ) ){ + print.redLine( "Exiting..." ); + return; + } + file action='write' file='#layoutPath#' mode ='777' output='#layoutContent#'; print.greenLine( 'Created #layoutPath#' ); diff --git a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/model-test.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/model-test.cfc index 817197dfe..866212a5e 100644 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/model-test.cfc +++ b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/model-test.cfc @@ -72,6 +72,13 @@ component { var testPath = '#arguments.TestsDirectory#/#listLast( arguments.path, "." )#Test.cfc'; // Create dir if it doesn't exist directorycreate( getDirectoryFromPath( testPath ), true, true ); + + // Confirm it + if( fileExists( testPath ) && !confirm( "The file '#getFileFromPath( testPath )#' already exists, overwrite it (y/n)?" ) ){ + print.redLine( "Exiting..." ); + return; + } + // Create the tests file action='write' file='#testPath#' mode ='777' output='#modelTestContent#'; // open file diff --git a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/model.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/model.cfc index 37819cfcb..1310f1977 100644 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/model.cfc +++ b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/model.cfc @@ -163,7 +163,13 @@ component { var modelPath = '#directory#/#arguments.name#.cfc'; // Create dir if it doesn't exist directorycreate( getDirectoryFromPath( modelPath ), true, true ); - file action='write' file='#modelPath#' mode ='777' output='#trim( modelContent )#'; + // Prompt for override + if( fileExists( modelPath ) && !confirm( "The file '#getFileFromPath( modelPath )#' already exists, overwrite it (y/n)?" ) ){ + print.redLine( "Exiting..." ); + return; + } + // Write out file + fileWrite( modelPath, trim( modelContent ) ); print.greenLine( 'Created #modelPath#' ); if( arguments.tests ) { diff --git a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/module.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/module.cfc index 3209d123b..92795742b 100644 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/module.cfc +++ b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/module.cfc @@ -63,6 +63,13 @@ component { moduleConfig = replaceNoCase( moduleConfig, '@modelNamespace@', arguments.modelNamespace, 'all'); moduleConfig = replaceNoCase( moduleConfig, '@dependencies@', serializeJSON( listToArray( arguments.dependencies ) ), 'all'); + // Confirm it + if( directoryExists( arguments.directory & '/#arguments.name#' ) && + !confirm( "The module already exists, overwrite it (y/n)?" ) ){ + print.redLine( "Exiting..." ); + return; + } + // Copy module template directoryCopy( '/coldbox-commands/templates/modules/', arguments.directory & '/#arguments.name#', true ); diff --git a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-entity.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-entity.cfc index 5cfa1f09c..f8d1c3c2e 100644 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-entity.cfc +++ b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-entity.cfc @@ -122,6 +122,13 @@ component { var modelPath = '#arguments.directory#/#arguments.entityName#.cfc'; // Create dir if it doesn't exist directorycreate( getDirectoryFromPath( modelPath ), true, true ); + + // Confirm it + if( fileExists( modelPath ) && !confirm( "The file '#getFileFromPath( modelPath )#' already exists, overwrite it (y/n)?" ) ){ + print.redLine( "Exiting..." ); + return; + } + file action='write' file='#modelPath#' mode ='777' output='#modelContent#'; print.greenLine( 'Created #modelPath#' ); diff --git a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-service.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-service.cfc index 6ecbbd994..2ea1749d1 100644 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-service.cfc +++ b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-service.cfc @@ -61,6 +61,13 @@ component { var modelPath = '#arguments.directory#/#arguments.serviceName#Service.cfc'; // Create dir if it doesn't exist directorycreate( getDirectoryFromPath( modelPath ), true, true ); + + // Confirm it + if( fileExists( modelPath ) && !confirm( "The file '#getFileFromPath( modelPath )#' already exists, overwrite it (y/n)?" ) ){ + print.redLine( "Exiting..." ); + return; + } + file action='write' file='#modelPath#' mode ='777' output='#modelContent#'; print.greenLine( 'Created #modelPath#' ); diff --git a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-virtual-service.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-virtual-service.cfc index b399f6616..38a29c083 100644 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-virtual-service.cfc +++ b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/orm-virtual-service.cfc @@ -61,6 +61,13 @@ component { var modelPath = '#arguments.directory#/#arguments.entityName#Service.cfc'; // Create dir if it doesn't exist directorycreate( getDirectoryFromPath( modelPath ), true, true ); + + // Confirm it + if( fileExists( modelPath ) && !confirm( "The file '#getFileFromPath( modelPath )#' already exists, overwrite it (y/n)?" ) ){ + print.redLine( "Exiting..." ); + return; + } + file action='write' file='#modelPath#' mode ='777' output='#modelContent#'; print.greenLine( 'Created #modelPath#' ); diff --git a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/view.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/view.cfc index 2e78898c9..77fcae2d3 100644 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/view.cfc +++ b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/view.cfc @@ -49,6 +49,13 @@ component { // Write out view var viewPath = '#arguments.directory#/#arguments.name#.cfm'; + + // Confirm it + if( fileExists( viewPath ) && !confirm( "The file '#getFileFromPath( viewPath )#' already exists, overwrite it (y/n)?" ) ){ + print.redLine( "Exiting..." ); + return; + } + file action='write' file='#viewPath#' mode ='777' output='#viewContent#'; print.greenLine( 'Created #viewPath#' ); diff --git a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/edit.cfm b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/edit.cfm deleted file mode 100644 index c3b2ef025..000000000 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/edit.cfm +++ /dev/null @@ -1 +0,0 @@ - #renderView(view="Users/editor", args={title="Update User"})# \ No newline at end of file diff --git a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/editor.cfm b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/editor.cfm deleted file mode 100644 index c7a418461..000000000 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/editor.cfm +++ /dev/null @@ -1,39 +0,0 @@ - - - -

#args.title#

- - -#html.startForm( action='Users.save' )# - - - #html.entityFields( entity=prc.User, - groupWrapper="div class='form-group'", - class="form-control", - fieldWrapper="", - labelWrapper="", - textAreas="", - booleanSelect=true, - manyToOne={}, - manyToMany={}, - showRelations=true)# - - -
- #html.href( href="Users", text="Cancel", class="btn btn-default" )# - #html.submitButton(value="Save", class="btn btn-primary")# -
- -#html.endForm()# -
\ No newline at end of file diff --git a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/index.cfm b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/index.cfm deleted file mode 100644 index 5ebffb1bb..000000000 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/index.cfm +++ /dev/null @@ -1,49 +0,0 @@ - -

Users

- - - -
- #flash.get( "notice" ).message# -
-
- - -#html.href( href="Users.new", text="Create User", class="btn btn-primary")# -#html.br(2)# - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#thisProp.name#Actions
##thisRecord.get#thisProp.name#()## - ##html.startForm(action="#inputStruct.pluralname#.delete")## - ##html.hiddenField(name="#metadata.pk#", bind=thisRecord)## - ##html.submitButton(value="Delete", onclick="return confirm('Really Delete Record?')", class="btn btn-danger")## - ##html.href(href="#inputStruct.pluralName#.edit", queryString="#metadata.pk#=##thisRecord.get#metadata.pk#()##", text="Edit", class="btn btn-info")## - ##html.endForm()## -
-
-
\ No newline at end of file diff --git a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/new.cfm b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/new.cfm deleted file mode 100644 index 5d6de5784..000000000 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/create/views/Users/new.cfm +++ /dev/null @@ -1,3 +0,0 @@ - -#renderView(view="Users/editor", args={title="Create User"})# - \ No newline at end of file diff --git a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/interceptor/help.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/interceptor/help.cfc deleted file mode 100644 index ff4e313c7..000000000 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/interceptor/help.cfc +++ /dev/null @@ -1,12 +0,0 @@ -component excludeFromHelp=true { - - function run() { - - print.line(); - print.yellowLine( 'General help and description of how to use coldbox interceptor' ); - print.line(); - print.line(); - - - } -} \ No newline at end of file diff --git a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/interceptor/install.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/interceptor/install.cfc deleted file mode 100644 index dce2a8c4e..000000000 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/interceptor/install.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_app/coldbox-commands/commands/coldbox/interceptor/remove.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/interceptor/remove.cfc deleted file mode 100644 index dce2a8c4e..000000000 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/interceptor/remove.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_app/coldbox-commands/commands/coldbox/module/help.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/module/help.cfc deleted file mode 100644 index becafab71..000000000 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/module/help.cfc +++ /dev/null @@ -1,12 +0,0 @@ -component excludeFromHelp=true { - - function run() { - - print.line(); - print.yellowLine( 'General help and description of how to use coldbox modules' ); - print.line(); - print.line(); - - - } -} \ No newline at end of file diff --git a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/module/install.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/module/install.cfc deleted file mode 100644 index dce2a8c4e..000000000 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/module/install.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_app/coldbox-commands/commands/coldbox/module/list.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/module/list.cfc deleted file mode 100644 index dce2a8c4e..000000000 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/module/list.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_app/coldbox-commands/commands/coldbox/module/remove.cfc b/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/module/remove.cfc deleted file mode 100644 index dce2a8c4e..000000000 --- a/src/cfml/system/modules_app/coldbox-commands/commands/coldbox/module/remove.cfc +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Description of command - **/ -component { - - /** - * - **/ - function run( ) { - print.line( "Command not implemented!" ); - } - -} \ No newline at end of file From a09b577c79b1f296051369adbedcaff8fd56d295 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Sat, 8 Oct 2016 22:52:53 -0700 Subject: [PATCH 85/91] OMMANDBOX-469 --- .../commands/forgebox/show.cfc | 36 +++++++++++++++++-- src/cfml/system/services/PackageService.cfc | 4 ++- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/show.cfc b/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/show.cfc index 3d3fd94fb..e187cf1c8 100644 --- a/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/show.cfc +++ b/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/show.cfc @@ -136,9 +136,39 @@ component aliases="show" { .line() .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( 'Summary: #entryData.summary#' ) + .text( 'Versions: ' ); + + var prevMajor = val( entryData.versions[ 1 ].version.listGetAt( 1, '.' ) ); + var majorCount = 0; + var versionLine = ''; + var lines = 0; + var versionsSkipped = 0; + for( var ver in entryData.versions ) { + var major = val( ver.version.listGetAt( 1, '.' ) ); + if( major != prevMajor ) { + if( lines > 0 ) { print.text( ' ' ); } + print.line( versionLine & ( versionsSkipped > 0 ? ' ( #versionsSkipped# more...)' : '' ) ); + majorCount = 0; + versionLine = ''; + versionsSkipped = 0; + lines++; + } + majorCount++; + if( majorCount <= 5 ) { + versionLine = versionLine.listAppend( ' ' & ver.version ); + } else { + versionsSkipped++; + } + prevMajor = major; + } + if( len( versionLine ) ) { + if( lines > 0 ) { print.text( ' ' ); } + print.line( versionLine & ( versionsSkipped > 0 ? ' ( #versionsSkipped# more...)' : '' ) ); + } + + + print.line( 'Created On: #dateFormat( entryData.createdDate )#' ) .line( 'Updated On: #dateFormat( entryData.updatedDate )#' ) .line( 'ForgeBox Views: #numberFormat( entryData.hits )#' ) .line( 'Downloads: #numberFormat( entryData.downloads )#' ) diff --git a/src/cfml/system/services/PackageService.cfc b/src/cfml/system/services/PackageService.cfc index d637c9544..d06dde3d0 100644 --- a/src/cfml/system/services/PackageService.cfc +++ b/src/cfml/system/services/PackageService.cfc @@ -242,12 +242,14 @@ component accessors="true" singleton { containerBoxJSON = containerBoxJSON, artifactDescriptor = artifactDescriptor, ignorePatterns = ignorePatterns, - endpointData = endpointData + endpointData = endpointData, + artifactPath = tmpPath }; interceptorService.announceInterception( 'onInstall', interceptData ); // Make sure these get set back into their original variables in case the interceptor changed them. installDirectory = interceptData.installDirectory; ignorePatterns = interceptData.ignorePatterns; + tmpPath = interceptData.artifactPath; // Else, use package type convention if( !len( installDirectory ) && len( packageType ) ) { From b2d9e0a98a65fdbc60c269638fc94104d4a10cce Mon Sep 17 00:00:00 2001 From: denuno Date: Sun, 9 Oct 2016 12:42:38 -0600 Subject: [PATCH 86/91] bump JRE and Lucee versions --- build/build.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/build.properties b/build/build.properties index 858096ffd..57f0dda95 100644 --- a/build/build.properties +++ b/build/build.properties @@ -14,8 +14,8 @@ dependencies.dir=${basedir}/lib cfml.version=4.5.2.018 cfml.loader.version=1.3.8 cfml.cli.version=${cfml.loader.version}.${cfml.version} -lucee.version=4.5.2.018 -jre.version=1.8.0_77 +lucee.version=4.5.3.020 +jre.version=1.8.0_102 launch4j.version=3.4 runwar.version=3.4.10 From e7cbb659d6471dca2b4ed84da62ff2e39a77a357 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Sun, 9 Oct 2016 15:19:02 -0700 Subject: [PATCH 87/91] Fix to work on Lucee 4.5.3.020 --- build/build.properties | 4 ++-- src/cfml/system/endpoints/ForgeBox.cfc | 2 +- .../modules_app/forgebox-commands/commands/forgebox/show.cfc | 5 ++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/build/build.properties b/build/build.properties index 57f0dda95..8c1f5c23e 100644 --- a/build/build.properties +++ b/build/build.properties @@ -11,10 +11,10 @@ java.pack200=false #dependencies dependencies.dir=${basedir}/lib -cfml.version=4.5.2.018 +cfml.version=4.5.3.020 cfml.loader.version=1.3.8 cfml.cli.version=${cfml.loader.version}.${cfml.version} -lucee.version=4.5.3.020 +lucee.version=${cfml.version} jre.version=1.8.0_102 launch4j.version=3.4 runwar.version=3.4.10 diff --git a/src/cfml/system/endpoints/ForgeBox.cfc b/src/cfml/system/endpoints/ForgeBox.cfc index 35ea7eb62..e6158a6f3 100644 --- a/src/cfml/system/endpoints/ForgeBox.cfc +++ b/src/cfml/system/endpoints/ForgeBox.cfc @@ -343,7 +343,7 @@ component accessors="true" implements="IEndpointInteractive" singleton { // 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 - if( !val( entryData.isActive ) ) { + if( !entryData.isActive ) { throw( 'The ForgeBox entry [#entryData.title#] is inactive.', 'endpointException' ); } diff --git a/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/show.cfc b/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/show.cfc index e187cf1c8..55f8a0e8d 100644 --- a/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/show.cfc +++ b/src/cfml/system/modules_app/forgebox-commands/commands/forgebox/show.cfc @@ -121,8 +121,7 @@ component aliases="show" { var entryData = entryData ?: forgebox.getEntry( slug ); // 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 ) ) { + if( !entryData.isActive ) { error( 'The ForgeBox entry [#entryData.title#] is inactive, we highly recommed NOT installing it or contact the author about it' ); } @@ -192,7 +191,7 @@ component aliases="show" { print.line(); var activeCount = 0; for( var entry in entries.results ) { - if( val( entry.isactive ) ) { + if( entry.isactive ) { activeCount++; print.blackOnWhite( ' #entry.title# ' ); print.boldText( ' ( #entry.user.fname# #entry.user.lname# )' ); From febea6b5bed0a926660f25b34a91c3817a6a5b6a Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Sun, 9 Oct 2016 16:40:23 -0700 Subject: [PATCH 88/91] Adding dependencies --- src/cfml/system/modules/.gitignore | 4 - .../system/modules/globber/.gitattributes | 17 + src/cfml/system/modules/globber/.gitignore | 216 +++++++ .../system/modules/globber/ModuleConfig.cfc | 7 + src/cfml/system/modules/globber/box.json | 16 + .../globber/models/PathPatternMatcher.cfc | 91 +++ src/cfml/system/modules/globber/readme.md | 26 + src/cfml/system/modules/semver/.gitattributes | 17 + src/cfml/system/modules/semver/.gitignore | 216 +++++++ .../system/modules/semver/ModuleConfig.cfc | 7 + src/cfml/system/modules/semver/box.json | 16 + .../modules/semver/models/SemanticVersion.cfc | 599 ++++++++++++++++++ src/cfml/system/modules/semver/readme.md | 13 + .../string-similarity/ModuleConfig.cfc | 7 + .../system/modules/string-similarity/box.json | 21 + .../models/StringSimilarity.cfc | 185 ++++++ .../modules/string-similarity/readme.md | 42 ++ 17 files changed, 1496 insertions(+), 4 deletions(-) delete mode 100644 src/cfml/system/modules/.gitignore create mode 100644 src/cfml/system/modules/globber/.gitattributes create mode 100644 src/cfml/system/modules/globber/.gitignore create mode 100644 src/cfml/system/modules/globber/ModuleConfig.cfc create mode 100644 src/cfml/system/modules/globber/box.json create mode 100644 src/cfml/system/modules/globber/models/PathPatternMatcher.cfc create mode 100644 src/cfml/system/modules/globber/readme.md create mode 100644 src/cfml/system/modules/semver/.gitattributes create mode 100644 src/cfml/system/modules/semver/.gitignore create mode 100644 src/cfml/system/modules/semver/ModuleConfig.cfc create mode 100644 src/cfml/system/modules/semver/box.json create mode 100644 src/cfml/system/modules/semver/models/SemanticVersion.cfc create mode 100644 src/cfml/system/modules/semver/readme.md create mode 100644 src/cfml/system/modules/string-similarity/ModuleConfig.cfc create mode 100644 src/cfml/system/modules/string-similarity/box.json create mode 100644 src/cfml/system/modules/string-similarity/models/StringSimilarity.cfc create mode 100644 src/cfml/system/modules/string-similarity/readme.md diff --git a/src/cfml/system/modules/.gitignore b/src/cfml/system/modules/.gitignore deleted file mode 100644 index 86d0cb272..000000000 --- a/src/cfml/system/modules/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# Ignore everything in this directory -* -# Except this file -!.gitignore \ No newline at end of file diff --git a/src/cfml/system/modules/globber/.gitattributes b/src/cfml/system/modules/globber/.gitattributes new file mode 100644 index 000000000..bdb0cabc8 --- /dev/null +++ b/src/cfml/system/modules/globber/.gitattributes @@ -0,0 +1,17 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/src/cfml/system/modules/globber/.gitignore b/src/cfml/system/modules/globber/.gitignore new file mode 100644 index 000000000..f91ff2b91 --- /dev/null +++ b/src/cfml/system/modules/globber/.gitignore @@ -0,0 +1,216 @@ +################# +## Eclipse +################# + +*.pydevproject +.project +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.classpath +.settings/ +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# PDT-specific +.buildpath + + +################# +## Visual Studio +################# + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results + +[Dd]ebug/ +[Rr]elease/ +x64/ +build/ +[Bb]in/ +[Oo]bj/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.log +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.Publish.xml +*.pubxml +*.publishproj + +# NuGet Packages Directory +## TODO: If you have NuGet Package Restore enabled, uncomment the next line +#packages/ + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.[Pp]ublish.xml +*.pfx +*.publishsettings + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +App_Data/*.mdf +App_Data/*.ldf + +############# +## Windows detritus +############# + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Mac crap +.DS_Store + + +############# +## Python +############# + +*.py[cod] + +# Packages +*.egg +*.egg-info +dist/ +build/ +eggs/ +parts/ +var/ +sdist/ +develop-eggs/ +.installed.cfg + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox + +#Translations +*.mo + +#Mr Developer +.mr.developer.cfg diff --git a/src/cfml/system/modules/globber/ModuleConfig.cfc b/src/cfml/system/modules/globber/ModuleConfig.cfc new file mode 100644 index 000000000..b402a68d0 --- /dev/null +++ b/src/cfml/system/modules/globber/ModuleConfig.cfc @@ -0,0 +1,7 @@ +component { + + function configure() { + + } + +} \ No newline at end of file diff --git a/src/cfml/system/modules/globber/box.json b/src/cfml/system/modules/globber/box.json new file mode 100644 index 000000000..f652c9815 --- /dev/null +++ b/src/cfml/system/modules/globber/box.json @@ -0,0 +1,16 @@ +{ + "name":"Globber", + "version":"1.0.0", + "author":"Brad Wood", + "location":"Ortus-Solutions/globber#v1.0.0", + "homepage":"https://github.com/Ortus-Solutions/globber/", + "documentation":"https://github.com/Ortus-Solutions/globber/", + "repository":{ + "type":"Git", + "URL":"git@github.com:Ortus-Solutions/globber.git" + }, + "bugs":"https://github.com/Ortus-Solutions/globber/issues", + "slug":"globber", + "shortDescription":"I am a utility to match file system path patterns.", + "type":"modules" +} \ No newline at end of file diff --git a/src/cfml/system/modules/globber/models/PathPatternMatcher.cfc b/src/cfml/system/modules/globber/models/PathPatternMatcher.cfc new file mode 100644 index 000000000..414f400a7 --- /dev/null +++ b/src/cfml/system/modules/globber/models/PathPatternMatcher.cfc @@ -0,0 +1,91 @@ +/** +********************************************************************************* +* Copyright Since 2014 CommandBox by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood, Luis Majano, Denny Valliant +* +* I am a utility to match file system path patterns +* +* End a pattern with a slash to only match a directory. Start a pattern with a slash to start in the root. Ex: +* - foo will match any file or folder in the directory tree +* - /foo will only match a file or folder in the root +* - foo/ will only match a directory anywhere in the directory tree +* - /foo/ will only match a folder in the root +* +* Use a single * to match zero or more characters INSIDE a file or folder name (won't match a slash) Ex: +* - foo* will match any file or folder starting with "foo" +* - foo*.txt will match any file or folder starting with "foo" and ending with .txt +* - *foo will match any file or folder ending with "foo" +* - a/* /z will match a/b/z but not a/b/c/z +* +* Use a double ** to match zero or more characters including slashes. This allows a pattern to span directories Ex: +* - a/** /z will match a/z and a/b/z and a/b/c/z +* +*/ +component accessors="true" singleton { + + function init() { + return this; + } + + /** + * Match a single path to a single pattern. Returns true if the path matches the pattern, otherwise false. + * @pattern.hint The pattern to match against the path + * @path.hint The file system path to test. Can be a file or directory. Direcories MUST end with a trailing slash + */ + boolean function matchPattern( required string pattern, required string path ) { + // Normalize slashes + arguments.pattern = replace( arguments.pattern, '\', '/', 'all' ); + arguments.path = replace( arguments.path, '\', '/', 'all' ); + + // Start all paths with / + arguments.path = ( arguments.path.startsWith( '/' ) ? arguments.path : '/' & arguments.path ); + + // build a regex based on the pattern + var regex = arguments.pattern; + + // Escape any periods in the pattern + regex = replace( regex, '.', '\.', 'all' ); + + // /**/ matches zero or more directories (at least one /) + regex = replace( regex, '/**/', '__zeroOrMoreDirs_', 'all' ); + // Double ** matches anything + regex = replace( regex, '**', '__anything_', 'all' ); + // Single * matches anything BUT slash + regex = replace( regex, '*', '__anythingButSlash__', 'all' ); + // Switch placeholders for actual regex + regex = replace( regex, '__zeroOrMoreDirs_', '/.*', 'all' ); + regex = replace( regex, '__anything_', '.*', 'all' ); + regex = replace( regex, '__anythingButSlash__', '[^/]*', 'all' ); + + // If pattern starts with slash + if( regex.startsWith( '/' )) { + // add a ^ to match start of string + regex = '^' & regex; + } else { + // Otherwise, anything can precede this pattern + regex = '.*' & regex; + } + // Anything can follow this pattern + regex &= '.*'; + + //writeDump(regex);abort; + return ( reFindNoCase( regex, arguments.path ) > 0 ); + } + + /** + * Match an array of patterns against a single path. Returns true if at least one pattern matches, otherwise false. + * @patterns.hint An array of patterns to match against the path + * @path.hint The file system path to test. Can be a file or directory. Direcories MUST end with a trailing slash + */ + boolean function matchPatterns( required array patterns, required string path ){ + for( var pattern in arguments.patterns ) { + if( matchPattern( pattern, arguments.path ) ) { + return true; + } + } + return false; + } + +} \ No newline at end of file diff --git a/src/cfml/system/modules/globber/readme.md b/src/cfml/system/modules/globber/readme.md new file mode 100644 index 000000000..b8bb459f7 --- /dev/null +++ b/src/cfml/system/modules/globber/readme.md @@ -0,0 +1,26 @@ +# Globber + +I am a utility to match file system path patterns (globbing) in the same manner as Unix file systems. + +End a pattern with a slash to only match a directory. Start a pattern with a slash to start in the root. Ex: +* `foo` wil match any file or folder in the directory tree +* `/foo` will only match a file or folder in the root +* `foo/` will only match a directory anywhere in the directory tree +* `/foo/` will only match a folder in the root + +Use a single * to match zero or more characters INSIDE a file or folder name (won't match a slash) Ex: +* `foo*` will match any file or folder starting with "foo" +* `foo*.txt` will match any file or folder starting with "foo" and ending with .txt +* `*foo` will match any file or folder ending with "foo" +* `a/*/z` will match `a/b/z` but not `a/b/c/z` + +Use a double ** to match zero or more characters including slashes. This allows a pattern to span directories Ex: +* `a/**/z` will match `a/z` and `a/b/z` and `a/b/c/z` + +## Usage + +``` +var globber = wirebox.getInstance( 'PathPatternMatcher@globber' ); +globber.matchPattern( '/foo/*', '/foo/bar' ); +globber.matchPatterns( [ '/foo/*', '**.txt' ], '/foo/bar' ); +``` \ No newline at end of file diff --git a/src/cfml/system/modules/semver/.gitattributes b/src/cfml/system/modules/semver/.gitattributes new file mode 100644 index 000000000..bdb0cabc8 --- /dev/null +++ b/src/cfml/system/modules/semver/.gitattributes @@ -0,0 +1,17 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/src/cfml/system/modules/semver/.gitignore b/src/cfml/system/modules/semver/.gitignore new file mode 100644 index 000000000..f91ff2b91 --- /dev/null +++ b/src/cfml/system/modules/semver/.gitignore @@ -0,0 +1,216 @@ +################# +## Eclipse +################# + +*.pydevproject +.project +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.classpath +.settings/ +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# PDT-specific +.buildpath + + +################# +## Visual Studio +################# + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results + +[Dd]ebug/ +[Rr]elease/ +x64/ +build/ +[Bb]in/ +[Oo]bj/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.log +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.Publish.xml +*.pubxml +*.publishproj + +# NuGet Packages Directory +## TODO: If you have NuGet Package Restore enabled, uncomment the next line +#packages/ + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.[Pp]ublish.xml +*.pfx +*.publishsettings + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +App_Data/*.mdf +App_Data/*.ldf + +############# +## Windows detritus +############# + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Mac crap +.DS_Store + + +############# +## Python +############# + +*.py[cod] + +# Packages +*.egg +*.egg-info +dist/ +build/ +eggs/ +parts/ +var/ +sdist/ +develop-eggs/ +.installed.cfg + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox + +#Translations +*.mo + +#Mr Developer +.mr.developer.cfg diff --git a/src/cfml/system/modules/semver/ModuleConfig.cfc b/src/cfml/system/modules/semver/ModuleConfig.cfc new file mode 100644 index 000000000..b402a68d0 --- /dev/null +++ b/src/cfml/system/modules/semver/ModuleConfig.cfc @@ -0,0 +1,7 @@ +component { + + function configure() { + + } + +} \ No newline at end of file diff --git a/src/cfml/system/modules/semver/box.json b/src/cfml/system/modules/semver/box.json new file mode 100644 index 000000000..119d090fb --- /dev/null +++ b/src/cfml/system/modules/semver/box.json @@ -0,0 +1,16 @@ +{ + "name":"Semantic Version", + "version":"1.0.0", + "author":"Brad Wood", + "location":"Ortus-Solutions/semanticVersion#v1.0.0", + "homepage":"https://github.com/Ortus-Solutions/semanticVersion/", + "documentation":"https://github.com/Ortus-Solutions/semanticVersion/", + "repository":{ + "type":"Git", + "URL":"git@github.com:Ortus-Solutions/semanticVersion.git" + }, + "bugs":"https://github.com/Ortus-Solutions/semanticVersion/issues", + "slug":"semver", + "shortDescription":"This is a library that implements npm-style semantic versioning for CFML.", + "type":"modules" +} \ No newline at end of file diff --git a/src/cfml/system/modules/semver/models/SemanticVersion.cfc b/src/cfml/system/modules/semver/models/SemanticVersion.cfc new file mode 100644 index 000000000..0e03075c4 --- /dev/null +++ b/src/cfml/system/modules/semver/models/SemanticVersion.cfc @@ -0,0 +1,599 @@ +/** +******************************************************************************** +Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp +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-preReleaseID+build +* http://semver.org/ +* https://github.com/npm/node-semver +*/ +component singleton{ + + /** + * Constructor + */ + function init(){ + return this; + } + + function getDefaultsVersion() { + 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, checkBuildID ) ) { + return 0; + } + + // first is 'smaller' than the second + if( isNew( arguments.current, arguments.target, checkBuildID ) ) { + 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(). + * @current The current version of the system + * @target The newer version received + * @checkBuildID If true it will check build equality, else it will ignore it + * + */ + boolean function isNew( + required string current, + required string target, + boolean checkBuildID=true + ){ + /** + Semantic version: major.minor.revision-alpha.1+build + **/ + + var current = parseVersion( arguments.current ); + var target = parseVersion( arguments.target ); + + // Major check + if( target.major gt current.major ){ + return true; + } + + // Minor Check + if( target.major eq current.major AND target.minor gt current.minor ){ + return true; + } + + // Revision Check + if( target.major eq current.major AND + target.minor eq current.minor AND + target.revision gt current.revision ){ + 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 ) { + 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.preReleaseID eq current.preReleaseID AND + target.buildID gt current.buildID ){ + return true; + } + + return false; + } + + /** + * Clean a version string from leading = or v + */ + string function clean( required version ){ + version = trim( version ); + return reReplaceNoCase( arguments.version, "^[=v]*", "" ); + } + + /** + * Decides whether a version satisfies a range + * + */ + boolean function satisfies( required string version, required string range ){ + + arguments.version = clean( arguments.version ); + + if( range == 'be' ) { + return true; + } + + 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 + // 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, false ); + } + + private function evaluateComparator( required struct comparator, version ) { + switch( comparator.operator ) { + case "<": + return isNew( arguments.version, comparator.version, false ); + break; + case "<=": + return isNew( arguments.version, comparator.version, false ) || isEq( comparator.version, arguments.version, false ); + break; + case ">": + return isNew( comparator.version, arguments.version, false ); + break; + case ">=": + return isNew( comparator.version, arguments.version, false ) || isEq( comparator.version, arguments.version, false ); + break; + case "=": + return isEq( comparator.version, arguments.version, false ); + 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=val( sComparator.sVersion.major )+1; + 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=val( sComparator.sVersion.minor )+1; + 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=val( sComparator.sVersion.major )+1; + 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=val(sComparator.sVersion.minor)+1; + 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=val( sComparator.sVersion.major )+1; + 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=val( sComparator.sVersion.minor )+1; + 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=val( sComparator.sVersion.minor )+1; + 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=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=val( sComparator.sVersion.minor )+1; + sComparator.sVersion.revision = 0; + } else { + sComparator.sVersion.revision=val( sComparator.sVersion.revision )+1; + } + + 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, missingValuePlaceholder ){ + arguments.version = clean( arguments.version ); + var results = getDefaultsVersion(); + + // Get build ID first + results.buildID = find( "+", arguments.version ) ? listLast( arguments.version, "+" ) : '0'; + // Remove build ID + arguments.version = reReplace( arguments.version, "\+([^\+]*).$", "" ); + // 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, "." ); + if( results.revision == "" ){ results.revision = missingValuePlaceholder ?: 0; } + + // Get Minor + Major + results.minor = getToken( arguments.version, 2, "." ); + if( results.minor == "" ){ results.minor = missingValuePlaceholder ?: 0; } + results.major = getToken( arguments.version, 1, "." ); + + return results; + } + + /** + * Parse the incoming version string and conform it to semantic version. + * If preReleaseID is not found it is omitted. + * @return string:{major.minor.revision[-preReleaseID]+buildid} + */ + string function parseVersionAsString( required string version, boolean includeBuildID=true ){ + var sVersion = parseVersion( arguments.version ); + return getVersionAsString( sVersion, includeBuildID ); + } + + + /** + * Parse the incoming version struct and output it as a string + * @return string:{major.minor.revision[-preReleaseID]+buildid} + */ + string function getVersionAsString( required struct sVersion, boolean includeBuildID=true ){ + var defaultsVersion = getDefaultsVersion(); + arguments.sVersion = defaultsVersion.append( arguments.sVersion ); + 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 : '' ) ); + } + } + + /** + * Verifies if the passed version string is in a pre-release state + * Pre-release is defined by the existance of a preRelease ID + */ + boolean function isPreRelease( required string version ){ + var pVersion = parseVersion( arguments.version ); + + return ( len( pVersion.preReleaseID ) ) ? true : false; + } + + /** + * Checks if the versions are equal + * 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 checkBuildID=true ){ + /** + Semantic version: major.minor.revision-alpha.1+build + **/ + + var current = parseVersionAsString( arguments.current, checkBuildID ); + var target = parseVersionAsString( arguments.target, checkBuildID ); + + return ( current == target ); + } + + /** + * 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 ) { + // Default any missing pieces to "x" so "3" becomes "3.x.x". + arguments.version = getVersionAsString (parseVersion( clean( arguments.version ), 'x' ) ); + + 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; + } + +} \ No newline at end of file diff --git a/src/cfml/system/modules/semver/readme.md b/src/cfml/system/modules/semver/readme.md new file mode 100644 index 000000000..c72df5f23 --- /dev/null +++ b/src/cfml/system/modules/semver/readme.md @@ -0,0 +1,13 @@ +# Semantic Version + +This is a library that implements npm-style semantic versioning for CFML. + +* Semantic version: major.minor.revision-preReleaseID+build +* http://semver.org/ +* https://github.com/npm/node-semver + +Usage +``` +var semver = wirebox.getInstance( 'semanticVersion@semver' ); +semver.satisfies( '1.0.0', '1.0.x' ); +``` \ No newline at end of file diff --git a/src/cfml/system/modules/string-similarity/ModuleConfig.cfc b/src/cfml/system/modules/string-similarity/ModuleConfig.cfc new file mode 100644 index 000000000..b402a68d0 --- /dev/null +++ b/src/cfml/system/modules/string-similarity/ModuleConfig.cfc @@ -0,0 +1,7 @@ +component { + + function configure() { + + } + +} \ No newline at end of file diff --git a/src/cfml/system/modules/string-similarity/box.json b/src/cfml/system/modules/string-similarity/box.json new file mode 100644 index 000000000..99c5f1d03 --- /dev/null +++ b/src/cfml/system/modules/string-similarity/box.json @@ -0,0 +1,21 @@ +{ + "name":"String Similarity", + "version":"1.0.0", + "author":"Brad Wood", + "location":"bdw429s/string-similarity#v1.0.0", + "homepage":"https://github.com/bdw429s/string-similarity/", + "documentation":"https://github.com/bdw429s/string-similarity/", + "repository":{ + "type":"Git", + "URL":"git@github.com:bdw429s/string-similarity.git" + }, + "bugs":"https://github.com/bdw429s/string-similarity/issues", + "slug":"string-similarity", + "shortDescription":"A small string comparison library to highlight differences between to strings ", + "type":"modules", + "ignore":[ + "**/.*", + "test", + "tests" + ] +} \ No newline at end of file diff --git a/src/cfml/system/modules/string-similarity/models/StringSimilarity.cfc b/src/cfml/system/modules/string-similarity/models/StringSimilarity.cfc new file mode 100644 index 000000000..83faabe7f --- /dev/null +++ b/src/cfml/system/modules/string-similarity/models/StringSimilarity.cfc @@ -0,0 +1,185 @@ +component { + + /** + * StringSimilarity + * Brad Wood + * brad@bradwood.com + * May 2007 + * http://www.codersrevolution.com/blog/ColdFusion-Levenshtein-Distance-String-comparison-and-highlighting + * Code adopted from Siderite Zackwehdex's Blog + * http://siderite.blogspot.com/2007/04/super-fast-and-accurate-string-distance.html + * Parameters: + * 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 piece of inserted text. Play with it to suit. + * + * 2016-50-20 James Moberg SunStarMedia.com + * - Added VAR scope to 15 variables. (Increased performance from 15-32 to 0-15ms.) + * - Added generateHTML flag (optional). If disabled, will return empty s1 & s2 strings. + */ + function stringSimilarity(s1, s2, maxOffset){ + var c = 0; + var offset1 = 0; var offset2 = 0; + var lcs = 0; + var _s1 = ""; var _s2 = ""; + var h1 = ""; var h2 = ""; + // default response = empty strings + var return_struct = {lcs = 0, similarity = 1, distance = len(trim(s1)), s1 = "", s2 = ""}; + /* 15 params VARed */ + var next_s1 = 0; var next_s2 = 0; + var old_offset1 = 0; var old_offset2 = 0; + var _s1_deviation = 0; var _s2_deviation = 0; + var len_next_s1 = 0; var len_next_s2 = 0; + var bookmarked_s1 = 0; var bookmarked_s2 = 0; + var added_offset1 = 0; var added_offset2 = 0; + var distance = 0; + var similarity = 0; + // Add option to toggle HTML generation. If disabled, will return empty s1 & s2 strings. + var generateHTML = 1; + if (arraylen(arguments) gte 4 AND isValid("boolean", arguments[4])){ + generateHTML = yesNoFormat(arguments[4]); + } + if (generateHTML){ + // These two strings will contain the "highlighted" version + _s1 = createObject("java","java.lang.StringBuffer").init(javacast("int",len(s1)*3)); + _s2 = createObject("java","java.lang.StringBuffer").init(javacast("int",len(s2)*3)); + // These characters will surround differences in the strings + // (Inserted into _s1 and _s2) + h1 = ""; + h2 = ""; + } + // If both strings are empty + if (not len(trim(s1)) and not len(trim(s2))){ + return return_struct; + } + // If s2 is empty, but s1 isn't + else if (len(trim(s1)) and not len(trim(s2))){ + return_struct.similarity = 0; + return_struct.distance = len(s1); + return_struct.s1 = h1 & s1 & h2; + return return_struct; + } + // If s1 is empty, but s2 isn't + else if (len(trim(s2)) and not len(trim(s1))){ + return_struct.similarity = 0; + return_struct.distance = len(s2); + 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 + if (generateHTML){ + _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 (generateHTML){ + 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 (generateHTML){ + 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 diff --git a/src/cfml/system/modules/string-similarity/readme.md b/src/cfml/system/modules/string-similarity/readme.md new file mode 100644 index 000000000..cd62c6cde --- /dev/null +++ b/src/cfml/system/modules/string-similarity/readme.md @@ -0,0 +1,42 @@ +# String Similarity + + This is a small library based on the Levenshtein Distance Algorithm tha compares small strings to look for the number of characters that's different between them. It returns the longest common string (LCS), a percentage of similarity, and can also wrap the differences in HTML tags of your choice to highlight the differnces. + +Read more about how it works here: + +http://www.codersrevolution.com/blog/ColdFusion-Levenshtein-Distance-String-comparison-and-highlighting + +``` html + + + + + + + +Roughly #comparison_result.distance# characters are different between the two strings.
+The strings are a #numberformat(comparison_result.similarity*100)#% match.
+The Longest Common String is #comparison_result.lcs#.
+
+ + + + + +
+ #replacenocase(comparison_result.s1,chr(10),"
","all")# +
+ #replacenocase(comparison_result.s2,chr(10),"
","all")# +
+
+``` From a0e82b59c0f9134cacb5cff8e9027841a7431cd6 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Sun, 9 Oct 2016 16:41:27 -0700 Subject: [PATCH 89/91] No longer needed --- build/build.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/build/build.xml b/build/build.xml index 9ce8c4d68..85e036d91 100644 --- a/build/build.xml +++ b/build/build.xml @@ -255,11 +255,6 @@ External Dependencies: - - - - - From 65f13a7cdd45bf1c4f873db775065cdcce739bd2 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Sun, 9 Oct 2016 22:58:05 -0700 Subject: [PATCH 90/91] Updated icons and offline start fix --- src/cfml/system/config/server-icons/home.png | Bin 21991 -> 52335 bytes .../config/server-icons/server_settings.png | Bin 7911 -> 54415 bytes src/cfml/system/config/server-icons/stop.png | Bin 23350 -> 51164 bytes .../config/server-icons/web_settings.png | Bin 5451 -> 55605 bytes .../system/services/ServerEngineService.cfc | 1 + 5 files changed, 1 insertion(+) diff --git a/src/cfml/system/config/server-icons/home.png b/src/cfml/system/config/server-icons/home.png index 7ba349aadee0c1c91e3c3ff5e34f479b29ce9c2e..d99c9877b43fe920f82d891cd0dd09883167c26f 100644 GIT binary patch literal 52335 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
r*>C`kT=t0}ZeQ5uR#R9w?3&-Lcli*1`#Fthi4I zd%OPoDZ29&F-QF9yuUd|0otq1VY6Vi#c{PC5eGwcYbOF63&KF2ERh%Ck8EDy)zGcl znU>bmnPr|4fyEf=D*IpsR zs4%TDDLui&C_}G+zm2>dgf|sC-XjpEQiOP73!(&2hjx^!AB1B^ycf3?>>-DDn#fK1fSGpTqC!N#mKd)La{5hwnz`%=uex^&9 z`Q{ukYYz67Q0l69y9EcRph<;o(IGFs1jFNJ5^r_Tf7xUv0-W~ovjxGb-)gyN0m6Ic z>Jsgq>7t!;0KVz{`*tqB5>$Oq<&_YZecBxmO~=YHh%bL2bD9htpTJ(Al{Ap1Z|Q$+ zd^}&#YSSK_EFX^%ee%Z|#a?qv6ogP# z#Lv^D7u_`f_m=mU$AW7w@-u=AjCtg(G*-PebnDl@z#5p)383fG=zGmeD0_7^ZKv*F zZ5%yfAase|rzApOhZZo!f*Qo%Q~XK?cZjC!g;X96hlPx0to72LH)R8erwCro+2q0PmO;HNQVrw|nv_ zgk9+)Smp#*v*^+W$G3?#f!vDE&xCZENQ7z{l1|rL4!d-~GtSOJzlAbOAZjEbW;(yt9`l z8l~8YN|1PbxPj2m`Xxc~Rm^D-jX}a^gtBxk?Z*2-!p~Z5evvIJuUnchhs@o8r=&D~ zbO0w|E@V^*Rs>y$U_5w2k&wINkL$f$mg51U?)rvNoCCK8(mf6|tS-lI_*><5IdtMg zVCz*6JTEo|R&HCC~!QMJ!n#(?1G~1QLN1scs06lD32?4=Q8|GUmH(J zOUnz+0ss3Uym<<_JlvIR;*q=x0#C()jGTfz+=4tc-2*+r7oaGwpeQS^B&(odC$FZd tqO2*eCM&O^DKDRl-Fo}~4E%3;_;`i>Z-Zl``Cou5U}j`tSgr3${6DW{X9NHM diff --git a/src/cfml/system/config/server-icons/server_settings.png b/src/cfml/system/config/server-icons/server_settings.png index e9fc520e711c0e84560c587f104f71e81792fc5f..e24e1beae80aae0ad94f40ca77e8e61dec5f06bf 100644 GIT binary patch literal 54415 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 literal 7911 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 aF{vFNR2&;L27h1uboKHz?E=l4!T$o39GIT~ literal 23350 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 XbHYj8zJ0)qYaDG21N9nJ`*;5XW&TUG diff --git a/src/cfml/system/config/server-icons/web_settings.png b/src/cfml/system/config/server-icons/web_settings.png index 1eac22f29682632469c323de455c652533448921..4661852161610a671728ce1a90d61d0780a53178 100644 GIT binary patch literal 55605 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

4t3eA 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 literal 5451 zcmV-R6}0M!P)cWF~+fjYZKy%mm>&sNJtuWw+;}xki{i#aTo+TW02hYzMgLJX4EtD zUia&sZZuu>71E&j`t|#L{f_VbzV8bJ?y;-5Sj{PVHTqB}A}!`c`6oe9t_%vwM?pcZ z3r3{wpdj_5e{TgN$`}`sCP3h4?KAX$ydZUHe+%D1-{m9H3!K;#3Pzg$7IX))SN!$p zqmRr$l7q<%H}x$oZGIpm%BzE-QWX>>8G$&A09EgbY$A#!;UmgWP;8WuVN~&v=<1?y z-2-kvuiN_4-7GgzoYwc9;@Ui}Oy&S^1jvb$pos`g**5@NJx+43dE*O%+?_&9z4`1BKbT%>UkC(3*2!9qi{5S=QP=Y3}SszXB4zdW>cOODh1XGb5&&EN)e zFv+vo_(^?Bmi!=}Tfgr~^wzZ71FHcO7T`0~7p`v)uG_cj+pE4imv#Ty)tByOV7buf zd`#f?9J~6yy?j{#w{Fk!V7RW`UgtJI2V>HpdRJfF5%kPUS@a(ZJVd)-)7@A zeZl|v!#9Gj)E?A2#on6*or;NX^i}g^^1@8wL3*=!m=xFqzu?h-UH4_aWZ!0Pecia$ zAy&6%@ICl`DJK5YcLx@_q2kuL#Qnzz50W`%E_TED`oDI-pU1!ar^kcqYtIHt55+pf zPUmW!dI%H$>f;3I6f6|e^`DNze7krU7^hocY)_G96q*?hFdeUvm)rnWhGSITi9S1F*H= z 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 Bq2T}k diff --git a/src/cfml/system/services/ServerEngineService.cfc b/src/cfml/system/services/ServerEngineService.cfc index e69ba42c4..30c659094 100644 --- a/src/cfml/system/services/ServerEngineService.cfc +++ b/src/cfml/system/services/ServerEngineService.cfc @@ -141,6 +141,7 @@ component accessors="true" singleton="true" { // See if there's something usable in the artifacts cache. If so, we'll use that version. var satisfyingVersion = artifactService.findSatisfyingVersion( endpoint.parseSlug( arguments.ID ), version ); if( len( satisfyingVersion ) ) { + arguments.ID = endpoint.parseSlug( arguments.ID ) & '@' & satisfyingVersion; consoleLogger.info( "."); consoleLogger.info( "Sweet! We found a local version of [#satisfyingVersion#] that we can use in your artifacts."); consoleLogger.info( "."); From 18993ab47693e2cab1f30f0cb27bea58f5ad5371 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Sun, 9 Oct 2016 23:20:06 -0700 Subject: [PATCH 91/91] Final 3.3.0 build --- build/build.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/build.xml b/build/build.xml index 85e036d91..37ead1361 100644 --- a/build/build.xml +++ b/build/build.xml @@ -15,8 +15,8 @@ External Dependencies: - - + +