@wpmoo/toolkit 0.9.22 → 0.9.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +6 -17
- package/dist/cockpit/command-registry.js +23 -24
- package/dist/cockpit/menu.js +16 -4
- package/dist/prompts/index.js +4 -1
- package/dist/status.js +16 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -38,7 +38,7 @@ import { confirmPrompt, introPrompt, isPromptCancel, notePrompt, outroPrompt, se
|
|
|
38
38
|
import { renderBanner } from './templates.js';
|
|
39
39
|
import { checkForUpdate, isUpdateCheckSkipped, restartCli } from './update-check.js';
|
|
40
40
|
import { packageName, packageVersion, renderVersion, renderVersionTag } from './version.js';
|
|
41
|
-
import { environmentStatusJson, getEnvironmentStatus,
|
|
41
|
+
import { environmentStatusJson, getEnvironmentStatus, environmentBannerSummaryLine, renderEnvironmentStatusForTarget, } from './status.js';
|
|
42
42
|
import { getGitHubAccounts, getGitHubRepositoryStatus, githubRepositoryUrl, realGitHub, createGitHubRepository, } from './github.js';
|
|
43
43
|
import { environmentGitHubOwner } from './environment-context.js';
|
|
44
44
|
import { handlePromptCancel, handleUnavailableMenuChoice, installPromptCancelKeyTracker, isMenuBackSignal, MenuBackSignal, menuIntroTitle, menuPromptMessage, } from './menu-navigation.js';
|
|
@@ -184,27 +184,16 @@ function validateRepoName(value) {
|
|
|
184
184
|
function startupVersionLine(latestVersion) {
|
|
185
185
|
return `v${packageVersion()}${latestVersion ? ` -> v${latestVersion} available` : ''}`;
|
|
186
186
|
}
|
|
187
|
-
function pluralize(count, singular, plural) {
|
|
188
|
-
return `${count} ${count === 1 ? singular : plural}`;
|
|
189
|
-
}
|
|
190
|
-
function renderStartupEnvironmentLine(status) {
|
|
191
|
-
if (status.kind !== 'environment') {
|
|
192
|
-
return `Environment: ${renderEnvironmentStatusSummary(status)}`;
|
|
193
|
-
}
|
|
194
|
-
const issueCount = status.composeErrors.length + status.invalidSourceRepoPaths.length + status.missingCoreFiles.length;
|
|
195
|
-
const issueSuffix = issueCount > 0 ? ` · ${pluralize(issueCount, 'issue', 'issues')}` : '';
|
|
196
|
-
return [
|
|
197
|
-
`Environment: Odoo ${status.odooVersion}`,
|
|
198
|
-
pluralize(status.sourceRepoCount, 'repo', 'repos'),
|
|
199
|
-
pluralize(status.moduleCandidateCount, 'module', 'modules'),
|
|
200
|
-
].join(' · ') + issueSuffix;
|
|
201
|
-
}
|
|
202
187
|
function renderStartupBanner(details, latestVersion) {
|
|
203
188
|
const versionLine = startupVersionLine(latestVersion);
|
|
204
189
|
return renderBanner(details?.(versionLine), details ? { version: versionLine } : undefined);
|
|
205
190
|
}
|
|
206
191
|
function renderCockpitStatusLines(status, serviceStatus, lastStatus) {
|
|
207
|
-
return [
|
|
192
|
+
return [
|
|
193
|
+
environmentBannerSummaryLine(status),
|
|
194
|
+
renderServiceRuntimeStatusLine(serviceStatus),
|
|
195
|
+
lastStatus,
|
|
196
|
+
];
|
|
208
197
|
}
|
|
209
198
|
function renderLastCommandStatus(command) {
|
|
210
199
|
return `Last: ${command.label} ✓ completed`;
|
|
@@ -29,41 +29,40 @@ function internalCommand(id, category, label, description, aliases = []) {
|
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
31
|
export const cockpitCommands = [
|
|
32
|
-
dailyCommand('start', 'services', 'Start services', 'Start
|
|
33
|
-
dailyCommand('stop', 'services', 'Stop services', 'Stop
|
|
34
|
-
dailyCommand('restart', 'services', 'Restart services', 'Restart
|
|
35
|
-
dailyCommand('logs', 'services', 'View logs', '
|
|
36
|
-
dailyCommand('shell', 'services', 'Open shell', 'Open a
|
|
32
|
+
dailyCommand('start', 'services', 'Start services', 'Start Odoo services.', ['up', 'compose up']),
|
|
33
|
+
dailyCommand('stop', 'services', 'Stop services', 'Stop Odoo services.', ['down', 'compose down']),
|
|
34
|
+
dailyCommand('restart', 'services', 'Restart services', 'Restart Odoo services.', ['reload']),
|
|
35
|
+
dailyCommand('logs', 'services', 'View logs', 'Tail service logs.', ['log', 'tail']),
|
|
36
|
+
dailyCommand('shell', 'services', 'Open shell', 'Open a service shell.', ['bash', 'terminal']),
|
|
37
37
|
internalCommand('list-modules', 'modules', 'List modules', 'Browse detected Odoo modules by source category.', [
|
|
38
38
|
'modules list',
|
|
39
39
|
'browse modules',
|
|
40
|
+
'/module',
|
|
41
|
+
'module',
|
|
40
42
|
]),
|
|
41
|
-
dailyCommand('install', 'modules', 'Install module', 'Install
|
|
42
|
-
dailyCommand('update', 'modules', 'Update module', 'Update
|
|
43
|
-
dailyCommand('test', 'modules', 'Run tests', 'Run
|
|
44
|
-
dailyCommand('lint', 'modules', 'Run environment lint', 'Run
|
|
45
|
-
dailyCommand('pot', 'modules', 'Generate POT', 'Generate translation
|
|
46
|
-
dailyCommand('psql', 'database', 'Open psql', 'Open
|
|
47
|
-
dailyCommand('snapshot', 'database', 'Create snapshot', 'Create a database snapshot.', ['backup', 'dump']),
|
|
48
|
-
dailyCommand('restore-snapshot', 'database', 'Restore snapshot', 'Restore a
|
|
49
|
-
dailyCommand('resetdb', 'database', 'Reset database', 'Reset
|
|
43
|
+
dailyCommand('install', 'modules', 'Install module', 'Install modules in the database.', ['install module', 'module']),
|
|
44
|
+
dailyCommand('update', 'modules', 'Update module', 'Update modules in the database.', ['upgrade', 'module']),
|
|
45
|
+
dailyCommand('test', 'modules', 'Run tests', 'Run tests for selected modules.', ['tests', 'pytest', 'module']),
|
|
46
|
+
dailyCommand('lint', 'modules', 'Run environment lint', 'Run environment lint checks.', ['check', 'quality']),
|
|
47
|
+
dailyCommand('pot', 'modules', 'Generate POT', 'Generate module translation templates.', ['translation', 'i18n']),
|
|
48
|
+
dailyCommand('psql', 'database', 'Open psql', 'Open PostgreSQL prompt.', ['postgres', 'sql', '/db']),
|
|
49
|
+
dailyCommand('snapshot', 'database', 'Create snapshot', 'Create a database snapshot.', ['backup', 'dump', '/snapshot']),
|
|
50
|
+
dailyCommand('restore-snapshot', 'database', 'Restore snapshot', 'Restore a named snapshot.', ['restore', 'snapshot restore']),
|
|
51
|
+
dailyCommand('resetdb', 'database', 'Reset database', 'Reset the environment database.', ['reset db', 'database reset']),
|
|
50
52
|
internalCommand('status', 'diagnostics', 'Environment status', 'Show a summary of the current environment state.', [
|
|
51
53
|
'state',
|
|
52
54
|
'summary',
|
|
53
55
|
]),
|
|
54
|
-
internalCommand('doctor', 'diagnostics', 'Run doctor', 'Run environment diagnostics
|
|
55
|
-
|
|
56
|
-
'health',
|
|
57
|
-
]),
|
|
58
|
-
internalCommand('add-repo', 'repositories', 'Add source repo', 'Add a source repository as an environment submodule.', [
|
|
56
|
+
internalCommand('doctor', 'diagnostics', 'Run doctor', 'Run environment diagnostics.', ['diagnose', 'health']),
|
|
57
|
+
internalCommand('add-repo', 'repositories', 'Add source repo', 'Add a source repository.', [
|
|
59
58
|
'repository add',
|
|
60
59
|
'source add',
|
|
61
60
|
]),
|
|
62
|
-
internalCommand('remove-repo', 'repositories', 'Remove source repo', 'Remove a source repository
|
|
63
|
-
internalCommand('add-module', 'modules', 'Add module', 'Add a module
|
|
64
|
-
internalCommand('remove-module', 'modules', 'Remove module', 'Remove a module
|
|
65
|
-
internalCommand('safe-reset', 'maintenance', 'Safe reset environment', 'Refresh generated
|
|
66
|
-
internalCommand('exit', 'maintenance', 'Exit', '
|
|
61
|
+
internalCommand('remove-repo', 'repositories', 'Remove source repo', 'Remove a source repository.', ['repository remove', 'source remove']),
|
|
62
|
+
internalCommand('add-module', 'modules', 'Add module', 'Add a module to a source repository.', ['module add']),
|
|
63
|
+
internalCommand('remove-module', 'modules', 'Remove module', 'Remove a module from a source repository.', ['module remove']),
|
|
64
|
+
internalCommand('safe-reset', 'maintenance', 'Safe reset environment', 'Refresh generated files only.', ['reset', 'refresh', '/safe']),
|
|
65
|
+
internalCommand('exit', 'maintenance', 'Exit', 'Close the command palette.', ['quit', 'back']),
|
|
67
66
|
];
|
|
68
67
|
const defaultCommandIds = new Set(['start', 'logs', 'test', 'status', 'doctor', 'exit']);
|
|
69
68
|
export function normalizeCockpitSearchTerm(term) {
|
package/dist/cockpit/menu.js
CHANGED
|
@@ -33,6 +33,21 @@ function categoryHeading(category) {
|
|
|
33
33
|
function commandName(command) {
|
|
34
34
|
return `${rgb(226, 184, 96, ` ${command.label.padEnd(topLevelCommandLabelWidth)}`)}${dim(` ${command.description}`)}`;
|
|
35
35
|
}
|
|
36
|
+
const disabledReasonNextStep = {
|
|
37
|
+
'No modules found.': 'Next: choose "Add module" first.',
|
|
38
|
+
'Services stopped.': 'Next: choose "Start services" first.',
|
|
39
|
+
'Already running.': 'Next: choose "Stop services" or "Restart services".',
|
|
40
|
+
'Docker not running.': 'Next: start Docker, then choose "Start services".',
|
|
41
|
+
'No source repos found.': 'Next: choose "Add source repo" first.',
|
|
42
|
+
};
|
|
43
|
+
function disabledError(reason) {
|
|
44
|
+
const base = 'This option is disabled and cannot be selected.';
|
|
45
|
+
if (!reason) {
|
|
46
|
+
return base;
|
|
47
|
+
}
|
|
48
|
+
const nextStep = disabledReasonNextStep[reason];
|
|
49
|
+
return nextStep ? `${base}\nReason: ${reason}\n${nextStep}` : `${base}\nReason: ${reason}`;
|
|
50
|
+
}
|
|
36
51
|
function serviceDisabledReason(command, serviceStatus) {
|
|
37
52
|
if (command.category !== 'services' || !serviceStatus)
|
|
38
53
|
return undefined;
|
|
@@ -56,9 +71,6 @@ function disabledReason(command, serviceStatus, moduleCount, sourceRepoCount) {
|
|
|
56
71
|
moduleDisabledReason(command, moduleCount) ??
|
|
57
72
|
sourceRepoDisabledReason(command, sourceRepoCount));
|
|
58
73
|
}
|
|
59
|
-
function disabledError() {
|
|
60
|
-
return 'This option is disabled and cannot be selected.';
|
|
61
|
-
}
|
|
62
74
|
function commandDisabledValue(reason) {
|
|
63
75
|
if (!reason) {
|
|
64
76
|
return undefined;
|
|
@@ -131,7 +143,7 @@ export async function selectCockpitTopLevelMenu(options = {}) {
|
|
|
131
143
|
pageSize: topLevelPageSize(choices.length),
|
|
132
144
|
loop: false,
|
|
133
145
|
hideMessage: true,
|
|
134
|
-
disabledError
|
|
146
|
+
disabledError,
|
|
135
147
|
navigationWarning: options.navigationWarning,
|
|
136
148
|
escapeBehavior: 'ignore',
|
|
137
149
|
});
|
package/dist/prompts/index.js
CHANGED
|
@@ -171,10 +171,13 @@ function hiddenSelectTheme(disabledError, navigationHelp = 'exit', navigationWar
|
|
|
171
171
|
};
|
|
172
172
|
}
|
|
173
173
|
function disabledErrorI18n(disabledError, activeReason) {
|
|
174
|
-
const i18n = { disabledError };
|
|
174
|
+
const i18n = typeof disabledError === 'string' ? { disabledError } : { disabledError: disabledError(undefined) };
|
|
175
175
|
Object.defineProperty(i18n, 'disabledError', {
|
|
176
176
|
get: () => {
|
|
177
177
|
const reason = activeReason();
|
|
178
|
+
if (typeof disabledError === 'function') {
|
|
179
|
+
return disabledError(reason);
|
|
180
|
+
}
|
|
178
181
|
return reason ? `${disabledError}\nReason: ${reason}` : disabledError;
|
|
179
182
|
},
|
|
180
183
|
});
|
package/dist/status.js
CHANGED
|
@@ -5,6 +5,10 @@ import { defaultOdooVersion, markerPath } from './environment.js';
|
|
|
5
5
|
import { emptyModuleQualitySummary, mergeModuleQualitySummaries, scanModuleQuality, } from './module-quality.js';
|
|
6
6
|
import { isValidPathSegment, validateRepoPath } from './path-validation.js';
|
|
7
7
|
const validSourceTypes = ['private', 'oca', 'external'];
|
|
8
|
+
const summarySeparator = ' \u00B7 ';
|
|
9
|
+
function pluralize(count, singular, plural) {
|
|
10
|
+
return `${count} ${count === 1 ? singular : plural}`;
|
|
11
|
+
}
|
|
8
12
|
function normalizeSourceType(sourceType) {
|
|
9
13
|
if (typeof sourceType === 'string' && validSourceTypes.includes(sourceType)) {
|
|
10
14
|
return sourceType;
|
|
@@ -85,6 +89,18 @@ async function missingCoreFiles(target, odooVersion) {
|
|
|
85
89
|
missing.push(...composeLayout.missingFiles);
|
|
86
90
|
return { missing, composeFiles: composeLayout.files, composeErrors: composeLayout.errors };
|
|
87
91
|
}
|
|
92
|
+
export function environmentBannerSummaryLine(status) {
|
|
93
|
+
if (status.kind !== 'environment') {
|
|
94
|
+
return `Environment: ${summaryText(status)}`;
|
|
95
|
+
}
|
|
96
|
+
const issueCount = status.composeErrors.length + status.invalidSourceRepoPaths.length + status.missingCoreFiles.length;
|
|
97
|
+
const issueSuffix = issueCount > 0 ? `${summarySeparator}${pluralize(issueCount, 'issue', 'issues')}` : '';
|
|
98
|
+
return [
|
|
99
|
+
`Environment: Odoo ${status.odooVersion}`,
|
|
100
|
+
pluralize(status.sourceRepoCount, 'repo', 'repos'),
|
|
101
|
+
pluralize(status.moduleCandidateCount, 'module', 'modules'),
|
|
102
|
+
].join(summarySeparator) + issueSuffix;
|
|
103
|
+
}
|
|
88
104
|
function summaryText(status) {
|
|
89
105
|
if (status.kind === 'no_environment')
|
|
90
106
|
return 'No WPMoo environment detected.';
|