Skip to content

Coldbox Watch-Reinit Doesn't Recognize Webroot Setting in server.json #76

Description

@homestar9

Similar to: #9

What are the steps to reproduce this issue?

  1. Create a new app using the Ortus Module Template
  2. Add a server.json file to the project root and make sure the web.webroot value is set to test-harness.
// example server.json
{
    "name":"myapp",
    "app":{
        "serverHomeDirectory":".engine/lucee5",
        "cfengine":"lucee@5"
    },
    "web":{
        "http":{
            "port":"60301"
        },
        "rewrites":{
            "enable":"true"
        },
        "webroot":"test-harness",
        "aliases":{
            "/moduleroot/myapp":"./",
            "/modules/myapp":"./"
        }
    },
    "openBrowser":"false",
    "cfconfig":{
        "file":".cfconfig.json"
    }
}
  1. Start the server from the root
  2. Enter coldbox watch-reinit in Commandbox

What happens?

Console will display:

Server Status: Stopped
Would you like to start it [y/n]? :

What were you expecting to happen?

The Coldbox-CLI should identify that the server is running in the webroot and watch the specified folder for changes.

Any other comments?

Discovered this when building a Coldbox module where the webroot lives in "test-harness", but I want to monitor the project root (the module's code) for changes so I can reinit the test-harness.

Activity

  1. homestar9 commented on May 27, 2026

    @homestar9
    ContributorAuthor

    Possible solution? Note that I added getDefaultServerName() which also exists in the fwreinit command. Might want to pull that out as a UDF or base class method to avoid duplicated code.

    // commands/coldbox/watch-reinit.cfc		
      function run(
      	string paths,
      	number delay,
      	string password = "1",
      	string directory,
      	name = getDefaultServerName( getCWD() ) <-- new argument
      ){
      	// Get watch options from package descriptor
      	var boxOptions   = packageService.readPackageDescriptor( getCWD() );
      	var initPassword = arguments.password;
      
      	var getOptionsWatchers = function(){
      		// Return to List
      		if ( boxOptions.keyExists( "reinitWatchPaths" ) && boxOptions.reinitWatchPaths.len() ) {
      			return (
      				isArray( boxOptions.reinitWatchPaths ) ? boxOptions.reinitWatchPaths.toList() : boxOptions.reinitWatchPaths
      			);
      		}
      		// should return null if not found
      		return;
      	}
      
      	// Determine watching patterns, either from arguments or boxoptions or defaults
      	var globbingPaths = arguments.paths ?: getOptionsWatchers() ?: variables.PATHS;
      	var globArray     = globbingPaths.listToArray();
      	var theDirectory  = arguments.directory ?: boxOptions.reinitWatchDirectory ?: getCWD();
      	theDirectory      = resolvePath( theDirectory );
      
      	// handle non numeric config
      	var delayMs = max(
      		val( arguments.delay ?: boxOptions.reinitWatchDelay ?: variables.WATCH_DELAY ),
      		variables.WATCH_DELAY
      	);
      	var statusColors = {
      		"added"   : "green",
      		"removed" : "red",
      		"changed" : "yellow"
      	}
      
      	// New: Use the new way to resolve server details
            var serverDetails = serverService.resolveServerDetails( {
      		name      : arguments.name,
      		directory : getCWD()
      	} );
      	var serverStatus  = serverService.isServerRunning( serverDetails.serverInfo );
      
      	// Tabula rasa
      	command( "cls" ).run();
      
      
      	// Check if the server is up, prompt if not to start it
      	if ( !serverStatus ) {
      		print
      			.redBoldText( "Server Status: Stopped" )
      			.line()
      			.toConsole();
      		var startServer = confirm( "Would you like to start it [y/n]?" );
      		if ( startServer ) {
      			command( "start" ).run();
      		} else {
      			return;
      		}
      	}
      
      	// General Message about the globbing paths and its purpose
      	print
      		.greenLine( "---------------------------------------------------" )
      		.greenLine( "Watching the following files for a framework reinit" )
      		.greenLine( "---------------------------------------------------" )
      		.line();
      	globArray.each( ( p ) => print.greenLine( " " & p ) );
      	print
      		.line()
      		.greenLine( " in directory: #theDirectory#" )
      		.greenLine( " Press Ctrl-C to exit " )
      		.greenLine( "---------------------------------------------------" )
      		.toConsole();
      
      	// Start watcher
      	watch()
      		.paths( globArray )
      		.inDirectory( theDirectory )
      		.withDelay( delayMs )
      		.onChange( function( changeData ){
      			// output file changes
      			var changetime = "[" & timeFormat( now(), "HH:mm:ss" ) & "] ";
      			for ( status in changeData ) {
      				changeData[ status ].map( function( filePath ){
      					print
      						.text( changetime, statusColors[ status ] )
      						.text(
      							filePath,
      							statusColors[ status ] & "Bold"
      						)
      						.text(
      							" " & status & " ",
      							statusColors[ status ]
      						)
      						.toConsole();
      				} )
      			}
      
      			// reinit the framework
      			command( "coldbox reinit password=""#initPassword#"" showUrl=""false""" ).run();
      		} )
      		.start();
      		
      		
      }
      
      /**
       * Tries to find the default server name from the server.json file in the current directory
       * note: This method is duplicated in fwreinit command... might want to pull out as shared UDF.
       * @directory The directory to look for the server.json file, defaults to the current working directory
       *
       * @return The server name if found, otherwise an empty string
       */
      private function getDefaultServerName( directory = getCwd() ){
      	var serverInfo = serverService.getServerInfoByDiscovery( serverConfigFile = "server.json" )
      	return serverInfo.keyExists( "name" ) ? serverInfo.name : ""
      }
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions