Skip to content

Commit 22e05a1

Browse files
authored
fix(view): show <rootversion>-dev and detect non-repo CLI installs on homepage (#2272)
Resolves #2255. When $readFrameworkVersion() detects an unreplaced @build.version@ placeholder, it now peeks at the enclosing repo's root box.json. If that box.json identifies the wheels-dev/wheels monorepo (slug "wheels" or name "Wheels.fw"), the helper returns "<rootversion>-dev" so the homepage surfaces the upcoming version. Vendored installs and any other hosting context still fall back to "0.0.0-dev". Resolves #2259. congratulations.cfm's CLI detection no longer relies solely on the monorepo-only path /cli/lucli/Module.cfc. It additionally probes ~/.CommandBox/cfml/modules/wheels-cli/ModuleConfig.cfc, ~/.lucli/lucli, and ~/.lucli/bin/lucli so CommandBox and LuCLI installs are recognized too. FileExists-only; no cfexecute. frameworkVersionSpec extended with four new cases covering the monorepo-detection branch, the vendored-install fallback, the both-placeholder fallback, and the missing-enclosing-box.json fallback. Full core suite: 3306 pass, 0 fail, 0 error, 16 skip.
1 parent c50d87a commit 22e05a1

3 files changed

Lines changed: 94 additions & 2 deletions

File tree

vendor/wheels/Global.cfc

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2753,7 +2753,7 @@ return local.$wheels;
27532753
return local.rv;
27542754
}
27552755

2756-
public string function $readFrameworkVersion(string boxJsonPath = "") {
2756+
public string function $readFrameworkVersion(string boxJsonPath = "", string rootBoxJsonPath = "") {
27572757
local.path = Len(arguments.boxJsonPath)
27582758
? arguments.boxJsonPath
27592759
: GetDirectoryFromPath(GetCurrentTemplatePath()) & "box.json";
@@ -2782,6 +2782,33 @@ return local.$wheels;
27822782
);
27832783
}
27842784
if (local.box.version == "@build.version@") {
2785+
// Dev checkout. Try to synthesize a more useful version by reading the
2786+
// enclosing repo's root box.json — when that box.json identifies itself as
2787+
// the wheels-dev/wheels monorepo, report "<rootversion>-dev" so the
2788+
// homepage shows the upcoming version rather than a blank placeholder.
2789+
local.rootPath = Len(arguments.rootBoxJsonPath)
2790+
? arguments.rootBoxJsonPath
2791+
: GetDirectoryFromPath(GetCurrentTemplatePath()) & "../box.json";
2792+
try {
2793+
if (FileExists(local.rootPath)) {
2794+
local.rootBox = DeserializeJSON(FileRead(local.rootPath));
2795+
local.isWheelsRepo = IsStruct(local.rootBox)
2796+
&& (
2797+
(StructKeyExists(local.rootBox, "slug") && local.rootBox.slug == "wheels")
2798+
|| (StructKeyExists(local.rootBox, "name") && local.rootBox.name == "Wheels.fw")
2799+
);
2800+
if (
2801+
local.isWheelsRepo
2802+
&& StructKeyExists(local.rootBox, "version")
2803+
&& Len(local.rootBox.version)
2804+
&& local.rootBox.version != "@build.version@"
2805+
) {
2806+
return local.rootBox.version & "-dev";
2807+
}
2808+
}
2809+
} catch (any e) {
2810+
// fall through to the plain dev sentinel
2811+
}
27852812
return "0.0.0-dev";
27862813
}
27872814
return local.box.version;

vendor/wheels/public/views/congratulations.cfm

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,23 @@
1111
local.dbName = application.wheels.dataSourceName;
1212
local.environment = get("environment");
1313
14-
// CLI detection
14+
// CLI detection — best-effort across install vectors:
15+
// 1. Monorepo dev checkout (CLI source is in-tree)
16+
// 2. CommandBox module install (`box install wheels-cli`)
17+
// 3. LuCLI install (Homebrew, Chocolatey, or direct download)
1518
local.hasCLI = FileExists(ExpandPath("/cli/lucli/Module.cfc"));
19+
if (!local.hasCLI) {
20+
try {
21+
local.userHome = CreateObject("java", "java.lang.System").getProperty("user.home");
22+
local.hasCLI = Len(local.userHome) && (
23+
FileExists(local.userHome & "/.CommandBox/cfml/modules/wheels-cli/ModuleConfig.cfc")
24+
|| FileExists(local.userHome & "/.lucli/lucli")
25+
|| FileExists(local.userHome & "/.lucli/bin/lucli")
26+
);
27+
} catch (any e) {
28+
// best-effort — if home dir is unavailable, fall back to "not detected"
29+
}
30+
}
1631
1732
// OS detection for install tab pre-selection
1833
local.osName = server.os.name;

vendor/wheels/tests/specs/events/frameworkVersionSpec.cfc

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,56 @@ component extends="wheels.WheelsTest" {
3535
}
3636
});
3737

38+
it("$readFrameworkVersion synthesizes <rootversion>-dev when placeholder is detected inside the wheels monorepo", () => {
39+
var fwTmp = getTempDirectory() & "wheels-version-fw-#CreateUUID()#.json";
40+
var rootTmp = getTempDirectory() & "wheels-version-root-#CreateUUID()#.json";
41+
fileWrite(fwTmp, '{"version":"@build.version@"}');
42+
fileWrite(rootTmp, '{"name":"Wheels.fw","slug":"wheels","version":"4.0.0"}');
43+
try {
44+
expect(g.$readFrameworkVersion(fwTmp, rootTmp)).toBe("4.0.0-dev");
45+
} finally {
46+
fileDelete(fwTmp);
47+
fileDelete(rootTmp);
48+
}
49+
});
50+
51+
it("$readFrameworkVersion falls back to 0.0.0-dev when the enclosing box.json is not the wheels monorepo (vendored install)", () => {
52+
var fwTmp = getTempDirectory() & "wheels-version-fw-#CreateUUID()#.json";
53+
var rootTmp = getTempDirectory() & "wheels-version-root-#CreateUUID()#.json";
54+
fileWrite(fwTmp, '{"version":"@build.version@"}');
55+
fileWrite(rootTmp, '{"name":"SomeUserApp","slug":"user-app","version":"2.1.0"}');
56+
try {
57+
expect(g.$readFrameworkVersion(fwTmp, rootTmp)).toBe("0.0.0-dev");
58+
} finally {
59+
fileDelete(fwTmp);
60+
fileDelete(rootTmp);
61+
}
62+
});
63+
64+
it("$readFrameworkVersion falls back to 0.0.0-dev when the enclosing box.json is also unreplaced", () => {
65+
var fwTmp = getTempDirectory() & "wheels-version-fw-#CreateUUID()#.json";
66+
var rootTmp = getTempDirectory() & "wheels-version-root-#CreateUUID()#.json";
67+
fileWrite(fwTmp, '{"version":"@build.version@"}');
68+
fileWrite(rootTmp, '{"name":"Wheels.fw","slug":"wheels","version":"@build.version@"}');
69+
try {
70+
expect(g.$readFrameworkVersion(fwTmp, rootTmp)).toBe("0.0.0-dev");
71+
} finally {
72+
fileDelete(fwTmp);
73+
fileDelete(rootTmp);
74+
}
75+
});
76+
77+
it("$readFrameworkVersion falls back to 0.0.0-dev when the enclosing box.json is missing", () => {
78+
var fwTmp = getTempDirectory() & "wheels-version-fw-#CreateUUID()#.json";
79+
var missingRoot = getTempDirectory() & "wheels-version-missing-#CreateUUID()#.json";
80+
fileWrite(fwTmp, '{"version":"@build.version@"}');
81+
try {
82+
expect(g.$readFrameworkVersion(fwTmp, missingRoot)).toBe("0.0.0-dev");
83+
} finally {
84+
fileDelete(fwTmp);
85+
}
86+
});
87+
3888
it("$readFrameworkVersion throws Wheels.VersionReadFailed when the file is missing", () => {
3989
var missing = getTempDirectory() & "wheels-version-missing-#CreateUUID()#.json";
4090
var threw = false;

0 commit comments

Comments
 (0)