@wpmoo/odoo 0.8.52 → 0.8.53
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/README.md +20 -10
- package/dist/cli.js +58 -14
- package/dist/help.js +12 -2
- package/dist/templates.js +69 -36
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -30,14 +30,14 @@ files without touching product source code.
|
|
|
30
30
|
- Node.js `>=20.17`
|
|
31
31
|
- Git
|
|
32
32
|
- Docker and Docker Compose for generated environment runtime commands
|
|
33
|
-
-
|
|
34
|
-
deeper diagnostics
|
|
33
|
+
- GitHub CLI (`gh`) is optional. Use it for repository discovery, repository
|
|
34
|
+
creation, and deeper diagnostics.
|
|
35
35
|
|
|
36
36
|
The wizard currently offers Odoo `19.0`, `18.0`, `17.0`, and `16.0`. The copied
|
|
37
37
|
Compose resource must include the matching `docker-compose_<version>.yml` file
|
|
38
38
|
for the selected branch.
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
Set up GitHub CLI only when you want WPMoo to discover your personal account and
|
|
41
41
|
organizations or create missing repositories from the interactive wizard:
|
|
42
42
|
|
|
43
43
|
```bash
|
|
@@ -54,11 +54,18 @@ npx @wpmoo/odoo
|
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
If the current directory is not already a WPMoo environment, the CLI opens the
|
|
57
|
-
create flow. It asks for the product slug, Odoo version,
|
|
58
|
-
|
|
59
|
-
empty repository initialization behavior.
|
|
57
|
+
create flow. It asks for the product slug, Odoo version, and environment folder.
|
|
58
|
+
Choose any environment folder; the default is `./<product>_dev`.
|
|
60
59
|
|
|
61
|
-
|
|
60
|
+
After folder selection, connect Git/GitHub to use repository URLs. Choose
|
|
61
|
+
local-only setup to skip Git/GitHub connection and source repo prompts. Add
|
|
62
|
+
source repositories later from the cockpit (`Repositories` -> `add-repo`) or
|
|
63
|
+
`npx @wpmoo/odoo add-repo`.
|
|
64
|
+
|
|
65
|
+
For non-interactive usage with repository URLs:
|
|
66
|
+
|
|
67
|
+
Direct `create` commands keep the existing repo URL options; use
|
|
68
|
+
`--target <path>` to choose a custom folder.
|
|
62
69
|
|
|
63
70
|
```bash
|
|
64
71
|
npx @wpmoo/odoo create \
|
|
@@ -183,7 +190,8 @@ not search parent directories or run arbitrary script names.
|
|
|
183
190
|
## Generated Environment Layout
|
|
184
191
|
|
|
185
192
|
A generated environment is a separate Git repository, usually named
|
|
186
|
-
`<product>_dev
|
|
193
|
+
`<product>_dev`, but the wizard and `--target` can use any folder. Product
|
|
194
|
+
source code stays in child source repositories.
|
|
187
195
|
|
|
188
196
|
```text
|
|
189
197
|
odoo_sample_module_dev/
|
|
@@ -244,7 +252,8 @@ Compose commands.
|
|
|
244
252
|
|
|
245
253
|
## Repository and Module Management
|
|
246
254
|
|
|
247
|
-
Add a source repository from the cockpit or direct
|
|
255
|
+
Add a source repository after local-only setup from the cockpit or direct
|
|
256
|
+
command:
|
|
248
257
|
|
|
249
258
|
```bash
|
|
250
259
|
npx @wpmoo/odoo add-repo \
|
|
@@ -252,7 +261,8 @@ npx @wpmoo/odoo add-repo \
|
|
|
252
261
|
--init-empty-repos
|
|
253
262
|
```
|
|
254
263
|
|
|
255
|
-
|
|
264
|
+
GitHub CLI is optional for repository setup. When it is available and
|
|
265
|
+
authenticated, the interactive flow can:
|
|
256
266
|
|
|
257
267
|
- detect the owner or organization from the current environment;
|
|
258
268
|
- suggest repository URLs;
|
package/dist/cli.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { confirm, intro, isCancel, note, outro, select, text } from '@clack/prompts';
|
|
3
3
|
import { realpathSync } from 'node:fs';
|
|
4
|
-
import { resolve } from 'node:path';
|
|
4
|
+
import { basename, resolve } from 'node:path';
|
|
5
5
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
6
|
-
import { commandFromArgs,
|
|
6
|
+
import { commandFromArgs, isHelpRequested, isVersionRequested, optionsFromArgs, parseArgs, stripInternalFlags, } from './args.js';
|
|
7
7
|
import { selectCockpitCommandFromPalette } from './cockpit/command-palette.js';
|
|
8
8
|
import { collectDailyActionArgs } from './cockpit/daily-prompts.js';
|
|
9
9
|
import { selectCockpitCategoryCommand, selectCockpitTopLevelMenu } from './cockpit/menu.js';
|
|
@@ -153,9 +153,27 @@ async function optionsFromPrompts(showIntro = true, cancelAction = 'exit') {
|
|
|
153
153
|
placeholder: 'odoo_sample_module',
|
|
154
154
|
validate: (value) => (value.trim() ? undefined : 'Enter a product/module slug.'),
|
|
155
155
|
}), 'odoo_sample_module', cancelAction);
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
156
|
+
const defaultTarget = `./${product}_dev`;
|
|
157
|
+
const target = resolve(asString(await text({
|
|
158
|
+
message: 'Environment folder',
|
|
159
|
+
placeholder: defaultTarget,
|
|
160
|
+
defaultValue: defaultTarget,
|
|
161
|
+
initialValue: defaultTarget,
|
|
162
|
+
}), defaultTarget, cancelAction));
|
|
163
|
+
const connectGitHub = await select({
|
|
164
|
+
message: 'Connect this environment to Git/GitHub now?',
|
|
165
|
+
options: [
|
|
166
|
+
{ value: true, label: 'Yes, connect Git/GitHub repositories' },
|
|
167
|
+
{ value: false, label: 'No, scaffold local-only' },
|
|
168
|
+
],
|
|
169
|
+
initialValue: true,
|
|
170
|
+
});
|
|
171
|
+
handleCancel(connectGitHub, cancelAction);
|
|
172
|
+
let selectedGitHubOwner;
|
|
173
|
+
if (connectGitHub) {
|
|
174
|
+
note(renderRepositorySetupNote(product), 'Repository setup');
|
|
175
|
+
selectedGitHubOwner = await selectDefaultGitHubOwner(cancelAction);
|
|
176
|
+
}
|
|
159
177
|
const selectedVersion = await select({
|
|
160
178
|
message: menuPromptMessage('Odoo version', cancelAction),
|
|
161
179
|
options: supportedOdooVersions.map((version) => ({ value: version, label: version })),
|
|
@@ -163,6 +181,37 @@ async function optionsFromPrompts(showIntro = true, cancelAction = 'exit') {
|
|
|
163
181
|
});
|
|
164
182
|
handleCancel(selectedVersion, cancelAction);
|
|
165
183
|
const odooVersion = String(selectedVersion);
|
|
184
|
+
async function promptInstallAgentSkills() {
|
|
185
|
+
const installAgentSkills = await select({
|
|
186
|
+
message: 'Install project-local Odoo Agent Skills?',
|
|
187
|
+
options: [
|
|
188
|
+
{ value: true, label: 'Yes, install latest default skills' },
|
|
189
|
+
{ value: false, label: 'No' },
|
|
190
|
+
],
|
|
191
|
+
initialValue: false,
|
|
192
|
+
});
|
|
193
|
+
handleCancel(installAgentSkills, cancelAction);
|
|
194
|
+
return Boolean(installAgentSkills);
|
|
195
|
+
}
|
|
196
|
+
if (!connectGitHub) {
|
|
197
|
+
const installAgentSkills = await promptInstallAgentSkills();
|
|
198
|
+
return {
|
|
199
|
+
product,
|
|
200
|
+
odooVersion,
|
|
201
|
+
engine: 'compose',
|
|
202
|
+
devRepo: basename(target),
|
|
203
|
+
devRepoUrl: target,
|
|
204
|
+
sourceRepos: [],
|
|
205
|
+
target,
|
|
206
|
+
dryRun: false,
|
|
207
|
+
initEmptyRepos: false,
|
|
208
|
+
stage: false,
|
|
209
|
+
agentSkillsTemplateUrl: installAgentSkills ? defaultAgentSkillsTemplateUrl : undefined,
|
|
210
|
+
createMissingRepos: false,
|
|
211
|
+
repoVisibility: 'private',
|
|
212
|
+
skipSubmodules: true,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
166
215
|
const detectedDevRepoUrl = await getOriginUrl(realGit, target);
|
|
167
216
|
const defaultDevRepoUrl = selectedGitHubOwner
|
|
168
217
|
? githubRepositoryUrl(selectedGitHubOwner, `${product}_dev`)
|
|
@@ -204,15 +253,7 @@ async function optionsFromPrompts(showIntro = true, cancelAction = 'exit') {
|
|
|
204
253
|
handleCancel(shouldAddAnother, cancelAction);
|
|
205
254
|
addAnother = Boolean(shouldAddAnother);
|
|
206
255
|
}
|
|
207
|
-
const installAgentSkills = await
|
|
208
|
-
message: 'Install project-local Odoo Agent Skills?',
|
|
209
|
-
options: [
|
|
210
|
-
{ value: true, label: 'Yes, install latest default skills' },
|
|
211
|
-
{ value: false, label: 'No' },
|
|
212
|
-
],
|
|
213
|
-
initialValue: false,
|
|
214
|
-
});
|
|
215
|
-
handleCancel(installAgentSkills, cancelAction);
|
|
256
|
+
const installAgentSkills = await promptInstallAgentSkills();
|
|
216
257
|
const initEmpty = await select({
|
|
217
258
|
message: 'Initialize repositories that exist but have no commits?',
|
|
218
259
|
options: [
|
|
@@ -477,6 +518,9 @@ async function ensureGitHubRepositories(options, interactive) {
|
|
|
477
518
|
if (options.dryRun) {
|
|
478
519
|
return;
|
|
479
520
|
}
|
|
521
|
+
if (options.skipSubmodules) {
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
480
524
|
if (!interactive && !options.createMissingRepos) {
|
|
481
525
|
return;
|
|
482
526
|
}
|
package/dist/help.js
CHANGED
|
@@ -5,7 +5,7 @@ WPMoo Odoo lifecycle tooling.
|
|
|
5
5
|
|
|
6
6
|
Usage:
|
|
7
7
|
npx @wpmoo/odoo
|
|
8
|
-
npx @wpmoo/odoo create --product <slug> --dev-repo-url <url> --source-repo-url <url>
|
|
8
|
+
npx @wpmoo/odoo create --product <slug> [--target <path>] --dev-repo-url <url> --source-repo-url <url>
|
|
9
9
|
npx @wpmoo/odoo status
|
|
10
10
|
npx @wpmoo/odoo add-repo --repo-url <url>
|
|
11
11
|
npx @wpmoo/odoo remove-repo --repo <name>
|
|
@@ -31,7 +31,7 @@ Usage:
|
|
|
31
31
|
Options:
|
|
32
32
|
--product <slug> Product slug, for example my_odoo_module.
|
|
33
33
|
--odoo-version <branch> Odoo branch to pin submodules to. Default: 19.0.
|
|
34
|
-
--dev-repo-url <url>
|
|
34
|
+
--dev-repo-url <url> Optional development environment repository URL for docs.
|
|
35
35
|
--target <path> Target dev repo directory. Default: ./<product>_dev.
|
|
36
36
|
--engine <value> Environment engine: compose. Default: compose.
|
|
37
37
|
--compose-template-url <url> Standalone compose resource source. Default: gh:wpmoo-org/odoo-docker-compose.
|
|
@@ -73,13 +73,22 @@ Cockpit:
|
|
|
73
73
|
diagnostics, repositories, and maintenance categories.
|
|
74
74
|
Direct commands such as npx @wpmoo/odoo status and npx @wpmoo/odoo test remain available.
|
|
75
75
|
|
|
76
|
+
Wizard local-only path:
|
|
77
|
+
Run npx @wpmoo/odoo from a workspace directory to open the create wizard.
|
|
78
|
+
Choose any environment folder; the default is ./<product>_dev.
|
|
79
|
+
Skip Git/GitHub connection to create a local-only environment.
|
|
80
|
+
Add source repos later from the cockpit or with add-repo.
|
|
81
|
+
|
|
76
82
|
Status and doctor:
|
|
77
83
|
status: fast and offline. Reads local environment metadata and files only.
|
|
78
84
|
doctor: deeper health check. May check Docker CLI access and GitHub workflows.
|
|
79
85
|
|
|
80
86
|
Task recipes:
|
|
81
87
|
Create environment:
|
|
88
|
+
npx @wpmoo/odoo
|
|
82
89
|
npx @wpmoo/odoo create --product <slug> --dev-repo-url <url> --source-repo-url <url>
|
|
90
|
+
Create local-only environment:
|
|
91
|
+
npx @wpmoo/odoo
|
|
83
92
|
Add source repo:
|
|
84
93
|
npx @wpmoo/odoo add-repo --repo-url <url>
|
|
85
94
|
Add module:
|
|
@@ -100,6 +109,7 @@ Example:
|
|
|
100
109
|
npx @wpmoo/odoo create \\
|
|
101
110
|
--product odoo_sample_module \\
|
|
102
111
|
--odoo-version 19.0 \\
|
|
112
|
+
--target ./custom_odoo_dev \\
|
|
103
113
|
--dev-repo-url https://github.com/example-org/odoo_sample_module_dev.git \\
|
|
104
114
|
--source-repo-url https://github.com/example-org/odoo_sample_module.git
|
|
105
115
|
|
package/dist/templates.js
CHANGED
|
@@ -17,7 +17,13 @@ function yamlList(items) {
|
|
|
17
17
|
function allAddons(options) {
|
|
18
18
|
return options.sourceRepos.flatMap((repo) => repo.addons);
|
|
19
19
|
}
|
|
20
|
+
function hasSourceRepos(options) {
|
|
21
|
+
return options.sourceRepos.length > 0;
|
|
22
|
+
}
|
|
20
23
|
function repositoryLayout(options) {
|
|
24
|
+
const sourceRepoRows = hasSourceRepos(options)
|
|
25
|
+
? options.sourceRepos.map((repo) => `│ ├── ${repo.path}/`).join('\n')
|
|
26
|
+
: '│ └── README.md';
|
|
21
27
|
return `${options.devRepo}/
|
|
22
28
|
├── docker-compose_17.0.yml
|
|
23
29
|
├── docker-compose_18.0.yml
|
|
@@ -29,12 +35,17 @@ function repositoryLayout(options) {
|
|
|
29
35
|
│ └── custom/
|
|
30
36
|
│ └── src/
|
|
31
37
|
│ └── private/
|
|
32
|
-
${
|
|
38
|
+
${sourceRepoRows}
|
|
33
39
|
├── docs/
|
|
34
40
|
├── README.md
|
|
35
41
|
└── AGENTS.md`;
|
|
36
42
|
}
|
|
37
43
|
function sourceRepoDocs(options) {
|
|
44
|
+
if (!hasSourceRepos(options)) {
|
|
45
|
+
return `This environment was scaffolded without source repository submodules.
|
|
46
|
+
Add source repositories later from the cockpit or with \`npx @wpmoo/odoo add-repo\`.
|
|
47
|
+
They will be added under \`odoo/custom/src/private\`.`;
|
|
48
|
+
}
|
|
38
49
|
return options.sourceRepos
|
|
39
50
|
.map((repo) => `### ${repo.path}
|
|
40
51
|
|
|
@@ -58,6 +69,35 @@ ${repo.addons.map((addon) => `├── ${addon}/`).join('\n')}
|
|
|
58
69
|
\`\`\``)
|
|
59
70
|
.join('\n\n');
|
|
60
71
|
}
|
|
72
|
+
function cloneDocs(options) {
|
|
73
|
+
if (!hasSourceRepos(options)) {
|
|
74
|
+
return `## Local Folder
|
|
75
|
+
|
|
76
|
+
This environment is ready in this folder:
|
|
77
|
+
|
|
78
|
+
\`\`\`bash
|
|
79
|
+
cd ${options.devRepo}
|
|
80
|
+
\`\`\`
|
|
81
|
+
|
|
82
|
+
If you later connect it to Git, commit the generated files after reviewing them.
|
|
83
|
+
`;
|
|
84
|
+
}
|
|
85
|
+
return `## Clone
|
|
86
|
+
|
|
87
|
+
Clone with submodules:
|
|
88
|
+
|
|
89
|
+
\`\`\`bash
|
|
90
|
+
git clone --recurse-submodules ${options.devRepoUrl}
|
|
91
|
+
cd ${options.devRepo}
|
|
92
|
+
\`\`\`
|
|
93
|
+
|
|
94
|
+
If already cloned:
|
|
95
|
+
|
|
96
|
+
\`\`\`bash
|
|
97
|
+
git submodule update --init --recursive
|
|
98
|
+
\`\`\`
|
|
99
|
+
`;
|
|
100
|
+
}
|
|
61
101
|
function optionalAgentSkillsReadme(options) {
|
|
62
102
|
if (!options.agentSkillsTemplateUrl)
|
|
63
103
|
return '';
|
|
@@ -118,9 +158,9 @@ docker-compose_19.0.yml
|
|
|
118
158
|
If copied from the standalone resource, additional compose documentation is kept
|
|
119
159
|
in \`docs/compose.md\`.
|
|
120
160
|
|
|
121
|
-
Source repositories stay under \`odoo/custom/src/private
|
|
122
|
-
\`entrypoint.sh\` scans those repositories for addons and
|
|
123
|
-
\`/mnt/wpmoo-addons\`.
|
|
161
|
+
Source repositories stay under \`odoo/custom/src/private\` when configured. At
|
|
162
|
+
container startup, \`entrypoint.sh\` scans those repositories for addons and
|
|
163
|
+
exposes them through \`/mnt/wpmoo-addons\`.
|
|
124
164
|
|
|
125
165
|
## Daily Command Hub (\`./moo\`)
|
|
126
166
|
|
|
@@ -487,8 +527,9 @@ export function renderReadme(options) {
|
|
|
487
527
|
|
|
488
528
|
Private ${environmentKind()} development environment for the ${title} product.
|
|
489
529
|
|
|
490
|
-
This
|
|
491
|
-
in source repository submodules under \`odoo/custom/src/private
|
|
530
|
+
This folder owns the development environment only. Product source code lives
|
|
531
|
+
in source repository submodules under \`odoo/custom/src/private\` when source
|
|
532
|
+
repositories are connected.
|
|
492
533
|
|
|
493
534
|
## Repository Layout
|
|
494
535
|
|
|
@@ -496,20 +537,7 @@ in source repository submodules under \`odoo/custom/src/private\`.
|
|
|
496
537
|
${repositoryLayout(options)}
|
|
497
538
|
\`\`\`
|
|
498
539
|
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
Clone with submodules:
|
|
502
|
-
|
|
503
|
-
\`\`\`bash
|
|
504
|
-
git clone --recurse-submodules ${options.devRepoUrl}
|
|
505
|
-
cd ${options.devRepo}
|
|
506
|
-
\`\`\`
|
|
507
|
-
|
|
508
|
-
If already cloned:
|
|
509
|
-
|
|
510
|
-
\`\`\`bash
|
|
511
|
-
git submodule update --init --recursive
|
|
512
|
-
\`\`\`
|
|
540
|
+
${cloneDocs(options)}
|
|
513
541
|
|
|
514
542
|
## WPMoo CLI Shortcut
|
|
515
543
|
|
|
@@ -535,23 +563,34 @@ ${sourceRepoDocs(options)}
|
|
|
535
563
|
${environmentUsageDocs(options)}
|
|
536
564
|
## Branching
|
|
537
565
|
|
|
538
|
-
Use Odoo major-version branches in source repositories:
|
|
566
|
+
Use Odoo major-version branches in source repositories when you add them:
|
|
539
567
|
|
|
540
568
|
\`\`\`text
|
|
541
569
|
${options.odooVersion}
|
|
542
570
|
\`\`\`
|
|
543
571
|
|
|
544
|
-
|
|
545
|
-
submodule references.
|
|
572
|
+
If this environment is connected to Git, the dev repository can stay on \`main\`
|
|
573
|
+
and pin exact source commits through submodule references.
|
|
546
574
|
`;
|
|
547
575
|
}
|
|
548
576
|
export function renderAgents(options) {
|
|
549
|
-
const repoList = options
|
|
550
|
-
.map((repo) => `- \`${repo.path}\`: \`${repo.url}\``)
|
|
551
|
-
.
|
|
552
|
-
const
|
|
553
|
-
|
|
554
|
-
|
|
577
|
+
const repoList = hasSourceRepos(options)
|
|
578
|
+
? options.sourceRepos.map((repo) => `- \`${repo.path}\`: \`${repo.url}\``).join('\n')
|
|
579
|
+
: '- No source repositories are configured yet.';
|
|
580
|
+
const sourceLayout = hasSourceRepos(options)
|
|
581
|
+
? `Product repositories are Git submodules:
|
|
582
|
+
|
|
583
|
+
\`\`\`text
|
|
584
|
+
${options.sourceRepos.map((repo) => `odoo/custom/src/private/${repo.path}`).join('\n')}
|
|
585
|
+
\`\`\`
|
|
586
|
+
|
|
587
|
+
${repoDuplicationNote()}`
|
|
588
|
+
: 'No source repositories are configured yet. Use `./moo add-repo` or the cockpit Repositories menu before module-specific work.';
|
|
589
|
+
const addonList = hasSourceRepos(options)
|
|
590
|
+
? options.sourceRepos
|
|
591
|
+
.map((repo) => `\`${repo.path}\` addons:\n${repo.addons.map((addon) => `- \`${addon}\``).join('\n')}`)
|
|
592
|
+
.join('\n\n')
|
|
593
|
+
: 'No addon boundaries are known yet. Add source repositories before module-specific implementation.';
|
|
555
594
|
return `# AGENTS.md
|
|
556
595
|
|
|
557
596
|
## Project
|
|
@@ -565,13 +604,7 @@ ${repoList}
|
|
|
565
604
|
|
|
566
605
|
## Source Layout
|
|
567
606
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
\`\`\`text
|
|
571
|
-
${options.sourceRepos.map((repo) => `odoo/custom/src/private/${repo.path}`).join('\n')}
|
|
572
|
-
\`\`\`
|
|
573
|
-
|
|
574
|
-
${repoDuplicationNote()}
|
|
607
|
+
${sourceLayout}
|
|
575
608
|
${optionalAgentSkillsAgentsSection(options)}
|
|
576
609
|
## Addon Boundaries
|
|
577
610
|
|