Skip to content

Commit 181cb6d

Browse files
bpamiriPeter Amiriclaude
authored
fix: anchor app-template rootPath to GetCurrentTemplatePath for subfolder stability (#3244)
The application template set `this.wheels.rootPath` from `GetDirectoryFromPath(GetBaseTemplatePath())` — the directory of whatever file was originally requested. When a request bootstraps under a subfolder (e.g. the web test runner), the base template is not the public front controller, so rootPath mis-anchors. Because rootPath seeds `this.name` via `Hash(rootPath)` (the issue-359 shared-app-name pattern), an unstable value silently splits one app across two application scopes — a contributor to the "reload=true fixes it" symptom in #3025/#2887. Anchor to `GetCurrentTemplatePath()` instead — always this Application.cfc's own path (the public dir), stable regardless of the requested base template. The value is identical for a normal front-controller request, so existing apps that uncommented `Hash(rootPath)` keep the same app name. (Deliberately not the reporter's `dir & "../"` form, which would shift the value to the app root and change that hash for every existing user — stability, not level, is the fix.) Same idiom already used two lines down in rocketunit_tests/Application.cfc for `this.webrootDir`. Applied to the `wheels new` scaffold, the demo app, both examples, and the legacy test app. Validated: demo app reload/boot clean; onboarding harness (wheels new -> start -> migrate -> generate -> test) green (45/0). Refs #3025, #2887 Signed-off-by: Peter Amiri <petera@pai.com> Co-authored-by: Peter Amiri <petera@pai.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 944f458 commit 181cb6d

6 files changed

Lines changed: 30 additions & 5 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- The application template's `this.wheels.rootPath` now anchors to `GetCurrentTemplatePath()` (the `public/` front-controller directory) instead of `GetBaseTemplatePath()` (whatever file was originally requested). When a request bootstrapped under a subfolder — e.g. the test runner — the old base-template anchor produced an unstable path, and because `rootPath` seeds `this.name` via `Hash(rootPath)`, that silently split one app across two application scopes (the "reload=true fixes it" symptom). The value is identical for a normal front-controller request, so existing apps are unaffected (#3025, refs #2887)

‎cli/lucli/templates/app/public/Application.cfc‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@ component output="false" {
22

33
// Put variables we just need internally inside a wheels struct.
44
this.wheels = {};
5-
this.wheels.rootPath = GetDirectoryFromPath(GetBaseTemplatePath());
5+
// Anchor to THIS file's directory (the public front-controller dir), not the
6+
// base template's. GetBaseTemplatePath() returns whatever file was originally
7+
// requested, so when a request bootstraps under a subfolder (e.g. the test
8+
// runner) rootPath would mis-anchor — and since it seeds `this.name` via
9+
// Hash(rootPath) below, an unstable value silently splits one app across two
10+
// application scopes (the "reload=true fixes it" symptom in issue #3025/#2887).
11+
// GetCurrentTemplatePath() is always this Application.cfc's path, so rootPath
12+
// stays stable regardless of the requested base template — and is identical to
13+
// the old value for a normal front-controller request.
14+
this.wheels.rootPath = GetDirectoryFromPath(GetCurrentTemplatePath());
615

716
this.name = createUUID();
817

‎examples/starter-app/public/Application.cfc‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ component output="false" {
22

33
// Put variables we just need internally inside a wheels struct.
44
this.wheels = {};
5-
this.wheels.rootPath = GetDirectoryFromPath(GetBaseTemplatePath());
5+
// Anchor to this file's directory, not the requested base template's, so
6+
// rootPath stays stable when a request bootstraps under a subfolder (e.g.
7+
// the test runner) — Hash(rootPath) below seeds this.name, and an unstable
8+
// value splits one app across two application scopes (issue #3025/#2887).
9+
this.wheels.rootPath = GetDirectoryFromPath(GetCurrentTemplatePath());
610

711
this.name = createUUID();
812
// Give this application a unique name by taking the path to the root and hashing it.

‎examples/tweet/public/Application.cfc‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ component output="false" {
22

33
// Put variables we just need internally inside a wheels struct.
44
this.wheels = {};
5-
this.wheels.rootPath = GetDirectoryFromPath(GetBaseTemplatePath());
5+
// Anchor to this file's directory, not the requested base template's, so
6+
// rootPath stays stable when a request bootstraps under a subfolder (e.g.
7+
// the test runner) — Hash(rootPath) below seeds this.name, and an unstable
8+
// value splits one app across two application scopes (issue #3025/#2887).
9+
this.wheels.rootPath = GetDirectoryFromPath(GetCurrentTemplatePath());
610

711
this.name = createUUID();
812
// Give this application a unique name by taking the path to the root and hashing it.

‎public/Application.cfc‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ component output="false" {
22

33
// Put variables we just need internally inside a wheels struct.
44
this.wheels = {};
5-
this.wheels.rootPath = GetDirectoryFromPath(GetBaseTemplatePath());
5+
// Anchor to this file's directory, not the requested base template's, so
6+
// rootPath stays stable when a request bootstraps under a subfolder (e.g.
7+
// the test runner) — Hash(rootPath) below seeds this.name, and an unstable
8+
// value splits one app across two application scopes (issue #3025/#2887).
9+
this.wheels.rootPath = GetDirectoryFromPath(GetCurrentTemplatePath());
610

711
this.name = createUUID();
812
// Give this application a unique name by taking the path to the root and hashing it.

‎vendor/wheels/rocketunit_tests/Application.cfc‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ component {
1010

1111
// Put variables we just need internally inside a wheels struct.
1212
this.wheels = {};
13-
this.wheels.rootPath = GetDirectoryFromPath(GetBaseTemplatePath());
13+
// Anchor to this file's directory (matches this.webrootDir below), not the
14+
// requested base template's, so rootPath stays stable under subfolder
15+
// bootstrap (issue #3025/#2887).
16+
this.wheels.rootPath = GetDirectoryFromPath(GetCurrentTemplatePath());
1417

1518
this.webrootDir = getDirectoryFromPath( getCurrentTemplatePath() );
1619
this.appDir = getCanonicalPath("_assets");

0 commit comments

Comments
 (0)