Skip to content

Commit 7d00f77

Browse files
authored
Merge pull request #1862 from wheels-dev/cli-fixes
Merge pull request #1860 from wheels-dev/fix/fixes-for-cli
2 parents 6ae0a25 + 042102b commit 7d00f77

File tree

7 files changed

+135
-10
lines changed

7 files changed

+135
-10
lines changed

cli/src/commands/wheels/plugins/list.cfc

Lines changed: 117 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* wheels plugins list --available
77
*/
88
component aliases="wheels plugin list" extends="../base" {
9-
9+
property name="forgebox" inject="ForgeBox";
1010
property name="pluginService" inject="PluginService@wheels-cli";
1111
property name="detailOutput" inject="DetailOutputService@wheels-cli";
1212

@@ -30,8 +30,120 @@ component aliases="wheels plugin list" extends="../base" {
3030
if (arguments.available) {
3131
// Show available plugins from ForgeBox
3232
detailOutput.header("Available Wheels Plugins on ForgeBox");
33+
detailOutput.output("Searching, please wait...");
3334
detailOutput.line();
34-
command('forgebox show').params(type="cfwheels-plugins").run();
35+
36+
// Get list of all cfwheels plugins slugs
37+
var forgeboxResult = command('forgebox show')
38+
.params(type='cfwheels-plugins')
39+
.run(returnOutput=true);
40+
41+
var results = [];
42+
43+
if (len(forgeboxResult)) {
44+
var lines = listToArray(forgeboxResult, chr(10) & chr(13));
45+
46+
for (var i = 1; i <= arrayLen(lines); i++) {
47+
var line = trim(lines[i]);
48+
49+
// Check if this is a slug line: Slug: "slug-name"
50+
if (findNoCase('Slug:', line)) {
51+
// Extract slug from quotes
52+
var slugMatch = reFind('Slug:\s*"([^"]+)"', line, 1, true);
53+
if (slugMatch.pos[1] > 0) {
54+
var slug = mid(line, slugMatch.pos[2], slugMatch.len[2]);
55+
56+
try {
57+
var pluginInfo = forgebox.getEntry(slug);
58+
59+
if (isStruct(pluginInfo) && structKeyExists(pluginInfo, "slug")) {
60+
// Extract version from latestVersion structure
61+
var version = "N/A";
62+
if (structKeyExists(pluginInfo, "latestVersion") &&
63+
isStruct(pluginInfo.latestVersion) &&
64+
structKeyExists(pluginInfo.latestVersion, "version")) {
65+
version = pluginInfo.latestVersion.version;
66+
}
67+
68+
// Extract author from user structure
69+
var author = "Unknown";
70+
if (structKeyExists(pluginInfo, "user") &&
71+
isStruct(pluginInfo.user) &&
72+
structKeyExists(pluginInfo.user, "username")) {
73+
author = pluginInfo.user.username;
74+
}
75+
76+
arrayAppend(results, {
77+
name: pluginInfo.title ?: slug,
78+
slug: slug,
79+
version: version,
80+
description: pluginInfo.summary ?: pluginInfo.description ?: "",
81+
author: author,
82+
downloads: pluginInfo.hits ?: 0,
83+
updateDate: pluginInfo.updatedDate ?: ""
84+
});
85+
}
86+
} catch (any e) {
87+
// Skip plugins that can't be retrieved
88+
}
89+
}
90+
}
91+
}
92+
}
93+
94+
results.sort(function(a, b) {
95+
return compareNoCase(a.name, b.name);
96+
});
97+
98+
if (arguments.format == "json") {
99+
var jsonOutput = {
100+
"plugins": results,
101+
"count": arrayLen(results)
102+
};
103+
print.line(jsonOutput).toConsole();
104+
} else {
105+
detailOutput.subHeader("Found #arrayLen(results)# plugin(s)");
106+
detailOutput.line();
107+
108+
// Create table for results
109+
var rows = [];
110+
111+
for (var plugin in results) {
112+
// use ordered struct so JSON keeps key order
113+
var row = structNew("ordered");
114+
115+
row["Name"] = plugin.name;
116+
row["Slug"] = plugin.slug;
117+
row["Version"] = plugin.version;
118+
row["Downloads"] = numberFormat(plugin.downloads ?: 0);
119+
row["Description"] = plugin.description ?: "No description";
120+
121+
// Truncate long descriptions
122+
if (len(row["Description"]) > 50) {
123+
row["Description"] = left(row["Description"], 47) & "...";
124+
}
125+
126+
arrayAppend(rows, row);
127+
}
128+
129+
// Display the table
130+
detailOutput.getPrint().table(rows).toConsole();
131+
132+
detailOutput.line();
133+
detailOutput.divider();
134+
detailOutput.line();
135+
136+
// Show summary
137+
detailOutput.metric("Total plugins found", "#arrayLen(results)#");
138+
detailOutput.line();
139+
140+
// Show commands
141+
detailOutput.subHeader("Commands");
142+
detailOutput.output("- Install: wheels plugin install <name>", true);
143+
detailOutput.output("- Details: wheels plugin info <name>", true);
144+
detailOutput.output("- Add --format=json for JSON output", true);
145+
detailOutput.line();
146+
}
35147
return;
36148
}
37149

@@ -58,17 +170,17 @@ component aliases="wheels plugin list" extends="../base" {
58170
"plugins": plugins,
59171
"count": arrayLen(plugins)
60172
};
61-
print.line(serializeJSON(jsonOutput, true));
173+
print.line(jsonOutput).toConsole();
62174
} else {
63175
// Table format output
64176
detailOutput.header("Installed Wheels Plugins (#arrayLen(plugins)#)");
65-
detailOutput.line();
66177

67178
// Create table rows
68179
var rows = [];
69180
for (var plugin in plugins) {
70181
var row = {
71182
"Plugin Name": plugin.name,
183+
"Slug" :plugin.slug,
72184
"Version": plugin.version
73185
};
74186

@@ -87,7 +199,7 @@ component aliases="wheels plugin list" extends="../base" {
87199
}
88200

89201
// Display the table
90-
detailOutput.getPrint().table(rows).toConsole();
202+
detailOutput.getPrint().table(rows);
91203

92204
detailOutput.line();
93205
detailOutput.divider("-", 60);

core/src/wheels/Global.cfc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1557,7 +1557,7 @@ component output="false" {
15571557
local.minimumMinor = "0";
15581558
local.minimumPatch = "0";
15591559
local.maximumMajor = "1";
1560-
local.maximumMinor = "9";
1560+
local.maximumMinor = "15";
15611561
local.maximumPatch = "999";
15621562

15631563
// Check minimum version

core/src/wheels/databaseAdapters/Base.cfc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ component output=false extends="wheels.Global"{
112112
);
113113

114114
if (structKeyExists(wheels,"id") && isStruct(wheels.id) && !structIsEmpty(wheels.id)) {
115+
// BoxLang-safe: ensure modifiable
116+
wheels.result = duplicate(wheels.result);
115117
structAppend(wheels.result, wheels.id);
116118
}
117119

core/src/wheels/tests_testbox/runner.cfm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@
206206
local.tableList = ValueList(local.tables.table_name)
207207
local.populate = StructKeyExists(url, "populate") ? url.populate : true
208208
if (local.populate || !FindNoCase("c_o_r_e_authors", local.tableList)) {
209-
include "populate.cfm"
209+
include "/wheels/tests_testbox/populate.cfm"
210210
}
211211
}
212212

templates/base/src/tests/runner.cfm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@
319319
320320
local.populate = StructKeyExists(url, "populate") ? url.populate : true
321321
if (local.populate) {
322-
include "populate.cfm"
322+
include "/tests/populate.cfm"
323323
}
324324
}
325325

tools/docker/boxlang/Dockerfile

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM ortussolutions/commandbox:boxlang
1+
FROM ortussolutions/commandbox:latest
22

33
LABEL maintainer "Wheels Core Team"
44

@@ -30,5 +30,16 @@ COPY tools/docker/boxlang/settings.cfm ${APP_DIR}/config/settings.cfm
3030
# Install dependencies
3131
RUN box install
3232

33+
# Start once to create BoxLang engine
34+
RUN box server start --background && sleep 10 && box server stop
35+
36+
# Move bx-* modules if engine modules dir exists
37+
RUN if [ -d ".engine/boxlang/WEB-INF/boxlang/modules" ]; then \
38+
echo "Moving bx-* modules"; \
39+
mv bx-* .engine/boxlang/WEB-INF/boxlang/modules/ 2>/dev/null || true; \
40+
else \
41+
echo "Engine modules directory missing"; \
42+
fi
43+
3344
# WARM UP THE SERVER
3445
RUN ${BUILD_DIR}/util/warmup-server.sh

tools/docker/boxlang/box.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "wheels-test-suite-boxlang",
33
"version": "1.0.0",
44
"dependencies": {
5-
"wirebox": "^7.0.0",
5+
"wirebox": "^8.0.0",
66
"testbox": "^6.0.0",
77
"bx-compat-cfml":"^1.27.0+35",
88
"bx-csrf":"^1.2.0+3",

0 commit comments

Comments
 (0)