@wpmoo/odoo 0.8.37 → 0.8.38

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.
Files changed (2) hide show
  1. package/dist/doctor.js +75 -0
  2. package/package.json +1 -1
package/dist/doctor.js CHANGED
@@ -19,6 +19,18 @@ async function exists(path) {
19
19
  function errorMessage(error) {
20
20
  return error instanceof Error ? error.message : String(error);
21
21
  }
22
+ function commandErrorText(error) {
23
+ const parts = [errorMessage(error)];
24
+ if (isRecord(error)) {
25
+ for (const key of ['stderr', 'stdout']) {
26
+ const value = error[key];
27
+ if (typeof value === 'string' && value.trim()) {
28
+ parts.push(value.trim());
29
+ }
30
+ }
31
+ }
32
+ return parts.join('\n');
33
+ }
22
34
  function isRecord(value) {
23
35
  return typeof value === 'object' && value !== null && !Array.isArray(value);
24
36
  }
@@ -95,9 +107,39 @@ function validatePort(name, env, errors) {
95
107
  function renderFailure(errors) {
96
108
  return ['WPMoo doctor failed:', ...errors.map((error) => `- ${error}`)].join('\n');
97
109
  }
110
+ function isNotGitCheckoutError(error) {
111
+ return commandErrorText(error).toLowerCase().includes('not a git repository');
112
+ }
113
+ function isSourceRepoSubmodule(path, sourceRepos) {
114
+ return sourceRepos.some((repo) => {
115
+ const sourcePath = `odoo/custom/src/private/${repo.path}`;
116
+ return path === sourcePath || path.startsWith(`${sourcePath}/`);
117
+ });
118
+ }
119
+ function sourceSubmoduleStatusErrors(output, sourceRepos) {
120
+ const errors = [];
121
+ for (const rawLine of output.split(/\r?\n/)) {
122
+ const line = rawLine.trimEnd();
123
+ if (!line)
124
+ continue;
125
+ const status = line[0];
126
+ const parts = line.slice(1).trim().split(/\s+/);
127
+ const path = parts[1];
128
+ if (!path || !isSourceRepoSubmodule(path, sourceRepos))
129
+ continue;
130
+ if (status === '-') {
131
+ errors.push(`Uninitialized Git submodule: ${path}`);
132
+ }
133
+ else if (status === 'U') {
134
+ errors.push(`Conflicted Git submodule: ${path}`);
135
+ }
136
+ }
137
+ return errors;
138
+ }
98
139
  export async function runDoctor(target = process.cwd(), runner = realCommandRunner) {
99
140
  const lines = ['WPMoo doctor'];
100
141
  const errors = [];
142
+ const warnings = [];
101
143
  const metadata = await readMetadata(target);
102
144
  lines.push(`OK metadata ${markerPath}`);
103
145
  const engine = metadataString(metadata, 'engine') ?? 'compose';
@@ -160,9 +202,42 @@ export async function runDoctor(target = process.cwd(), runner = realCommandRunn
160
202
  catch (error) {
161
203
  errors.push(`Docker CLI check failed: ${errorMessage(error)}`);
162
204
  }
205
+ try {
206
+ await runner('docker', ['compose', 'version'], { cwd: target });
207
+ lines.push('OK docker compose');
208
+ }
209
+ catch (error) {
210
+ errors.push(`Docker Compose check failed: ${errorMessage(error)}`);
211
+ }
212
+ if (sourceRepos.length > 0) {
213
+ try {
214
+ const result = await runner('git', ['submodule', 'status', '--recursive'], { cwd: target });
215
+ const submoduleErrors = sourceSubmoduleStatusErrors(result.stdout, sourceRepos);
216
+ errors.push(...submoduleErrors);
217
+ if (submoduleErrors.length === 0) {
218
+ lines.push(`OK git submodules ${sourceRepos.length} checked`);
219
+ }
220
+ }
221
+ catch (error) {
222
+ if (isNotGitCheckoutError(error)) {
223
+ lines.push('OK git submodules skipped (not a git checkout)');
224
+ }
225
+ else {
226
+ errors.push(`Git submodule status check failed: ${errorMessage(error)}`);
227
+ }
228
+ }
229
+ }
230
+ try {
231
+ await runner('gh', ['auth', 'status'], { cwd: target });
232
+ lines.push('OK GitHub CLI auth');
233
+ }
234
+ catch (error) {
235
+ warnings.push(`WARN GitHub CLI auth: ${errorMessage(error)}`);
236
+ }
163
237
  if (errors.length > 0) {
164
238
  throw new Error(renderFailure(errors));
165
239
  }
240
+ lines.push(...warnings);
166
241
  lines.push('Doctor checks passed.');
167
242
  return lines.join('\n');
168
243
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wpmoo/odoo",
3
- "version": "0.8.37",
3
+ "version": "0.8.38",
4
4
  "description": "WPMoo Odoo lifecycle tooling for development, staging, and production workflows.",
5
5
  "type": "module",
6
6
  "repository": {