@wpmoo/odoo 0.8.63 → 0.8.64
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 +8 -4
- package/dist/cli.js +40 -18
- package/dist/cockpit/daily-prompts.js +6 -2
- package/dist/help.js +8 -4
- package/dist/module-actions.js +20 -13
- package/dist/status.js +21 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -142,8 +142,8 @@ npx @wpmoo/odoo doctor
|
|
|
142
142
|
npx @wpmoo/odoo doctor --fix
|
|
143
143
|
npx @wpmoo/odoo add-repo --repo-url https://github.com/example-org/odoo_sample_module_reports.git
|
|
144
144
|
npx @wpmoo/odoo remove-repo --repo odoo_sample_module_reports
|
|
145
|
-
npx @wpmoo/odoo add-module --repo odoo_sample_module --module odoo_sample_module_base
|
|
146
|
-
npx @wpmoo/odoo remove-module --repo odoo_sample_module --module odoo_sample_module_base
|
|
145
|
+
npx @wpmoo/odoo add-module --repo odoo_sample_module --module odoo_sample_module_base --source-type private
|
|
146
|
+
npx @wpmoo/odoo remove-module --repo odoo_sample_module --module odoo_sample_module_base --source-type private
|
|
147
147
|
npx @wpmoo/odoo reset --dry-run
|
|
148
148
|
npx @wpmoo/odoo reset
|
|
149
149
|
|
|
@@ -275,10 +275,13 @@ GitHub CLI is optional for repository setup. When it is available and authentica
|
|
|
275
275
|
|
|
276
276
|
Add a minimal Odoo module skeleton to a source repository:
|
|
277
277
|
|
|
278
|
+
For module actions, `--source-type` selects the source directory (`private`, `oca`, or `external`). Default is `private`.
|
|
279
|
+
|
|
278
280
|
```bash
|
|
279
281
|
npx @wpmoo/odoo add-module \
|
|
280
282
|
--repo odoo_sample_module \
|
|
281
|
-
--module odoo_sample_module_base
|
|
283
|
+
--module odoo_sample_module_base \
|
|
284
|
+
--source-type oca
|
|
282
285
|
```
|
|
283
286
|
|
|
284
287
|
Remove a module registration while keeping files:
|
|
@@ -286,7 +289,8 @@ Remove a module registration while keeping files:
|
|
|
286
289
|
```bash
|
|
287
290
|
npx @wpmoo/odoo remove-module \
|
|
288
291
|
--repo odoo_sample_module \
|
|
289
|
-
--module odoo_sample_module_base
|
|
292
|
+
--module odoo_sample_module_base \
|
|
293
|
+
--source-type oca
|
|
290
294
|
```
|
|
291
295
|
|
|
292
296
|
Delete module files as well:
|
package/dist/cli.js
CHANGED
|
@@ -399,21 +399,39 @@ async function ensureAddRepoGitHubRepository(options, cancelAction = 'exit') {
|
|
|
399
399
|
await createGitHubRepository(realGitHub, options.repoUrl, visibility);
|
|
400
400
|
}
|
|
401
401
|
async function selectSourceRepo(target, cancelAction = 'exit') {
|
|
402
|
-
const repos = await
|
|
403
|
-
|
|
402
|
+
const repos = await listSources(target);
|
|
403
|
+
const repoOptions = repos.length > 0
|
|
404
|
+
? repos.map((repo) => ({
|
|
405
|
+
value: { repoPath: repo.path, sourceType: repo.type },
|
|
406
|
+
label: `${repo.type}/${repo.path}`,
|
|
407
|
+
}))
|
|
408
|
+
: (await listModuleRepos(target)).map((repoPath) => ({
|
|
409
|
+
value: { repoPath, sourceType: 'private' },
|
|
410
|
+
label: `private/${repoPath}`,
|
|
411
|
+
}));
|
|
412
|
+
if (repoOptions.length === 0) {
|
|
404
413
|
if (cancelAction === 'back') {
|
|
405
|
-
note(`No source repos found under ${target}/odoo/custom/src
|
|
414
|
+
note(`No source repos found under ${target}/odoo/custom/src.\nNext: choose "Add source repo" first.`, 'Nothing to select');
|
|
406
415
|
handleUnavailableMenuChoice(cancelAction);
|
|
407
416
|
}
|
|
408
|
-
throw new Error(`No source repos found under ${target}/odoo/custom/src
|
|
417
|
+
throw new Error(`No source repos found under ${target}/odoo/custom/src`);
|
|
409
418
|
}
|
|
410
|
-
const
|
|
419
|
+
const selected = await select({
|
|
411
420
|
message: menuPromptMessage('Source repo', cancelAction),
|
|
412
|
-
options:
|
|
413
|
-
initialValue:
|
|
421
|
+
options: repoOptions,
|
|
422
|
+
initialValue: repoOptions[0].value,
|
|
414
423
|
});
|
|
415
|
-
handleCancel(
|
|
416
|
-
|
|
424
|
+
handleCancel(selected, cancelAction);
|
|
425
|
+
if (typeof selected === 'string') {
|
|
426
|
+
return { repoPath: selected, sourceType: 'private' };
|
|
427
|
+
}
|
|
428
|
+
if (typeof selected === 'object' && selected !== null && 'repoPath' in selected && 'sourceType' in selected) {
|
|
429
|
+
return { repoPath: selected.repoPath, sourceType: selected.sourceType };
|
|
430
|
+
}
|
|
431
|
+
return { repoPath: String(selected), sourceType: 'private' };
|
|
432
|
+
}
|
|
433
|
+
function formatSourceRepoPromptPath(target, selected) {
|
|
434
|
+
return renderedSourceRepoPath(target, selected.sourceType, selected.repoPath);
|
|
417
435
|
}
|
|
418
436
|
function suggestedModuleName(repoPath) {
|
|
419
437
|
return 'odoo_sample_module';
|
|
@@ -430,6 +448,7 @@ async function addModuleOptionsFromArgs(argv) {
|
|
|
430
448
|
target,
|
|
431
449
|
repoPath,
|
|
432
450
|
moduleName,
|
|
451
|
+
sourceType: optionalSourceTypeValue(values),
|
|
433
452
|
odooVersion: await commandOdooVersion(target, stringOption(values, 'odooVersion')),
|
|
434
453
|
stage: booleanOption(values, 'stage', true),
|
|
435
454
|
};
|
|
@@ -437,15 +456,16 @@ async function addModuleOptionsFromArgs(argv) {
|
|
|
437
456
|
async function addModuleOptionsFromPrompts(showIntro = true, cancelAction = 'exit') {
|
|
438
457
|
showSubmenuIntro('Add module to source repo', showIntro, cancelAction);
|
|
439
458
|
const target = process.cwd();
|
|
440
|
-
const
|
|
459
|
+
const sourceRepo = await selectSourceRepo(target, cancelAction);
|
|
441
460
|
const moduleName = asString(await text({
|
|
442
461
|
message: menuPromptMessage('Module name', cancelAction),
|
|
443
|
-
placeholder: suggestedModuleName(repoPath),
|
|
462
|
+
placeholder: suggestedModuleName(sourceRepo.repoPath),
|
|
444
463
|
validate: (value) => (value.trim() ? undefined : 'Enter the module technical name.'),
|
|
445
|
-
}), suggestedModuleName(repoPath), cancelAction);
|
|
464
|
+
}), suggestedModuleName(sourceRepo.repoPath), cancelAction);
|
|
446
465
|
return {
|
|
447
466
|
target,
|
|
448
|
-
repoPath,
|
|
467
|
+
repoPath: sourceRepo.repoPath,
|
|
468
|
+
sourceType: sourceRepo.sourceType,
|
|
449
469
|
moduleName,
|
|
450
470
|
odooVersion: await commandOdooVersion(target),
|
|
451
471
|
stage: true,
|
|
@@ -587,6 +607,7 @@ function removeModuleOptionsFromArgs(argv) {
|
|
|
587
607
|
target: resolve(stringOption(values, 'target') ?? process.cwd()),
|
|
588
608
|
repoPath,
|
|
589
609
|
moduleName,
|
|
610
|
+
sourceType: optionalSourceTypeValue(values),
|
|
590
611
|
deleteFiles: booleanOption(values, 'deleteFiles', false),
|
|
591
612
|
stage: booleanOption(values, 'stage', true),
|
|
592
613
|
};
|
|
@@ -594,14 +615,14 @@ function removeModuleOptionsFromArgs(argv) {
|
|
|
594
615
|
async function removeModuleOptionsFromPrompts(showIntro = true, cancelAction = 'exit') {
|
|
595
616
|
showSubmenuIntro('Remove module from source repo', showIntro, cancelAction);
|
|
596
617
|
const target = process.cwd();
|
|
597
|
-
const
|
|
598
|
-
const modules = await listModulesInSourceRepo(target, repoPath);
|
|
618
|
+
const sourceRepo = await selectSourceRepo(target, cancelAction);
|
|
619
|
+
const modules = await listModulesInSourceRepo(target, sourceRepo.repoPath, sourceRepo.sourceType);
|
|
599
620
|
if (modules.length === 0) {
|
|
600
621
|
if (cancelAction === 'back') {
|
|
601
|
-
note(`No Odoo modules found under ${target}
|
|
622
|
+
note(`No Odoo modules found under ${formatSourceRepoPromptPath(target, sourceRepo)}.\nNext: choose "Add module to source repo" first.`, 'Nothing to remove');
|
|
602
623
|
handleUnavailableMenuChoice(cancelAction);
|
|
603
624
|
}
|
|
604
|
-
throw new Error(`No Odoo modules found under ${target}
|
|
625
|
+
throw new Error(`No Odoo modules found under ${formatSourceRepoPromptPath(target, sourceRepo)}`);
|
|
605
626
|
}
|
|
606
627
|
const moduleName = await select({
|
|
607
628
|
message: menuPromptMessage('Module to remove', cancelAction),
|
|
@@ -618,7 +639,8 @@ async function removeModuleOptionsFromPrompts(showIntro = true, cancelAction = '
|
|
|
618
639
|
handleCancel(deleteFiles, cancelAction);
|
|
619
640
|
return {
|
|
620
641
|
target,
|
|
621
|
-
repoPath,
|
|
642
|
+
repoPath: sourceRepo.repoPath,
|
|
643
|
+
sourceType: sourceRepo.sourceType,
|
|
622
644
|
moduleName: String(moduleName),
|
|
623
645
|
deleteFiles: Boolean(deleteFiles),
|
|
624
646
|
stage: true,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isCancel, select, text } from '@clack/prompts';
|
|
2
2
|
import { listModulesInSourceRepo } from '../module-actions.js';
|
|
3
3
|
import { listModuleRepos } from '../repo-actions.js';
|
|
4
|
+
import { listSources } from '../source-actions.js';
|
|
4
5
|
import { handlePromptCancel, menuPromptMessage, } from '../menu-navigation.js';
|
|
5
6
|
const manualModuleValue = '__wpmoo_manual_module_entry__';
|
|
6
7
|
function defaultCancelHandler(value, action) {
|
|
@@ -27,10 +28,13 @@ function requiredString(value, message, deps) {
|
|
|
27
28
|
}
|
|
28
29
|
async function detectedModules(cwd) {
|
|
29
30
|
try {
|
|
30
|
-
const
|
|
31
|
+
const sources = await listSources(cwd);
|
|
32
|
+
const repos = sources.length > 0
|
|
33
|
+
? sources.map((source) => ({ path: source.path, sourceType: source.type }))
|
|
34
|
+
: (await listModuleRepos(cwd)).map((path) => ({ path, sourceType: 'private' }));
|
|
31
35
|
const modules = await Promise.all(repos.map(async (repo) => {
|
|
32
36
|
try {
|
|
33
|
-
return await listModulesInSourceRepo(cwd, repo);
|
|
37
|
+
return await listModulesInSourceRepo(cwd, repo.path, repo.sourceType);
|
|
34
38
|
}
|
|
35
39
|
catch {
|
|
36
40
|
return [];
|
package/dist/help.js
CHANGED
|
@@ -13,8 +13,8 @@ Usage:
|
|
|
13
13
|
npx @wpmoo/odoo source sync
|
|
14
14
|
npx @wpmoo/odoo source add --repo-url <url> [--source-type private|oca|external]
|
|
15
15
|
npx @wpmoo/odoo source remove --repo <name> [--source-type private|oca|external]
|
|
16
|
-
npx @wpmoo/odoo add-module --repo <source-repo> --module <module-name>
|
|
17
|
-
npx @wpmoo/odoo remove-module --repo <source-repo> --module <module-name>
|
|
16
|
+
npx @wpmoo/odoo add-module --repo <source-repo> --module <module-name> [--source-type <category>]
|
|
17
|
+
npx @wpmoo/odoo remove-module --repo <source-repo> --module <module-name> [--source-type <category>]
|
|
18
18
|
npx @wpmoo/odoo reset [--dry-run]
|
|
19
19
|
npx @wpmoo/odoo doctor [--fix]
|
|
20
20
|
npx @wpmoo/odoo start
|
|
@@ -49,7 +49,7 @@ Options:
|
|
|
49
49
|
--http-port <port> Host HTTP port written to .env.example.
|
|
50
50
|
--gevent-port <port> Host gevent/live chat port written to .env.example.
|
|
51
51
|
--repo-url <url> Source repo URL for add-repo.
|
|
52
|
-
--source-type <category> Source repo category for add-repo/remove-repo. One of private, oca, external. Default: private.
|
|
52
|
+
--source-type <category> Source repo category for add-repo/remove-repo/add-module/remove-module. One of private, oca, external. Default: private.
|
|
53
53
|
--repo <name> Source repo folder name for repo/module actions.
|
|
54
54
|
--module <name> Odoo module technical name for module actions.
|
|
55
55
|
--delete-files Also delete module files in remove-module. Default: false.
|
|
@@ -101,7 +101,11 @@ Task recipes:
|
|
|
101
101
|
npx @wpmoo/odoo source list
|
|
102
102
|
npx @wpmoo/odoo source sync
|
|
103
103
|
Add module:
|
|
104
|
-
npx @wpmoo/odoo add-module --repo <source-repo> --module <module-name>
|
|
104
|
+
npx @wpmoo/odoo add-module --repo <source-repo> --module <module-name> --source-type private|oca|external
|
|
105
|
+
Remove module:
|
|
106
|
+
npx @wpmoo/odoo remove-module --repo <source-repo> --module <module-name> --source-type private|oca|external
|
|
107
|
+
Add OCA module:
|
|
108
|
+
npx @wpmoo/odoo add-module --repo sale-workflow --module sale_order_line_no_discount --source-type oca
|
|
105
109
|
Run tests:
|
|
106
110
|
npx @wpmoo/odoo test <module[,module]> [--db <db>] [--mode init|update] [--tags <tags>]
|
|
107
111
|
Safe reset and recover:
|
package/dist/module-actions.js
CHANGED
|
@@ -5,11 +5,15 @@ import { readEnvironmentMetadata } from './environment.js';
|
|
|
5
5
|
import { realGit, stageAll } from './git.js';
|
|
6
6
|
import { pathUnderBase, validateModuleName, validateRepoPath } from './path-validation.js';
|
|
7
7
|
import { readAddonsYaml, writeAddonsYaml } from './repo-actions.js';
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
const validSourceTypes = ['private', 'oca', 'external'];
|
|
9
|
+
function normalizeSourceType(value) {
|
|
10
|
+
return validSourceTypes.includes(value) ? value : 'private';
|
|
10
11
|
}
|
|
11
|
-
function
|
|
12
|
-
return pathUnderBase(
|
|
12
|
+
function sourceRepoPath(target, sourceType, repoPath) {
|
|
13
|
+
return pathUnderBase(join(target, `odoo/custom/src/${sourceType}`), repoPath, 'repo path');
|
|
14
|
+
}
|
|
15
|
+
function modulePath(target, sourceType, repoPath, moduleName) {
|
|
16
|
+
return pathUnderBase(sourceRepoPath(target, sourceType, repoPath), moduleName, 'module name');
|
|
13
17
|
}
|
|
14
18
|
function titleizeModule(moduleName) {
|
|
15
19
|
return moduleName
|
|
@@ -49,7 +53,8 @@ async function usesAddonsYaml(target) {
|
|
|
49
53
|
export async function addModuleToSourceRepo(options, git = realGit) {
|
|
50
54
|
const repoPath = validateRepoPath(options.repoPath);
|
|
51
55
|
const moduleName = validateModuleName(options.moduleName);
|
|
52
|
-
const
|
|
56
|
+
const sourceType = normalizeSourceType(options.sourceType);
|
|
57
|
+
const destination = modulePath(options.target, sourceType, repoPath, moduleName);
|
|
53
58
|
await mkdir(join(destination, 'models'), { recursive: true });
|
|
54
59
|
await mkdir(join(destination, 'security'), { recursive: true });
|
|
55
60
|
await mkdir(join(destination, 'views'), { recursive: true });
|
|
@@ -58,24 +63,25 @@ export async function addModuleToSourceRepo(options, git = realGit) {
|
|
|
58
63
|
await writeIfMissing(join(destination, 'models/__init__.py'), '');
|
|
59
64
|
await writeIfMissing(join(destination, 'security/ir.model.access.csv'), 'id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink\n');
|
|
60
65
|
await writeIfMissing(join(destination, 'views/.gitkeep'), '');
|
|
61
|
-
if (await usesAddonsYaml(options.target)) {
|
|
66
|
+
if (sourceType === 'private' && (await usesAddonsYaml(options.target))) {
|
|
62
67
|
const addonsYaml = await readAddonsYaml(options.target);
|
|
63
68
|
await writeAddonsYaml(options.target, addModuleToSourceRepoInAddonsYaml(addonsYaml, repoPath, moduleName));
|
|
64
69
|
}
|
|
65
70
|
if (options.stage) {
|
|
66
|
-
await stageAll(git, sourceRepoPath(options.target, repoPath));
|
|
71
|
+
await stageAll(git, sourceRepoPath(options.target, sourceType, repoPath));
|
|
67
72
|
await stageAll(git, options.target);
|
|
68
73
|
}
|
|
69
74
|
}
|
|
70
|
-
export async function listModulesInSourceRepo(target, repoPath) {
|
|
75
|
+
export async function listModulesInSourceRepo(target, repoPath, sourceType) {
|
|
71
76
|
const safeRepoPath = validateRepoPath(repoPath);
|
|
77
|
+
const resolvedSourceType = normalizeSourceType(sourceType);
|
|
72
78
|
try {
|
|
73
|
-
const entries = await readdir(sourceRepoPath(target, safeRepoPath), { withFileTypes: true });
|
|
79
|
+
const entries = await readdir(sourceRepoPath(target, resolvedSourceType, safeRepoPath), { withFileTypes: true });
|
|
74
80
|
const modules = await Promise.all(entries
|
|
75
81
|
.filter((entry) => entry.isDirectory())
|
|
76
82
|
.map(async (entry) => {
|
|
77
83
|
try {
|
|
78
|
-
await readFile(join(sourceRepoPath(target, safeRepoPath), entry.name, '__manifest__.py'), 'utf8');
|
|
84
|
+
await readFile(join(sourceRepoPath(target, resolvedSourceType, safeRepoPath), entry.name, '__manifest__.py'), 'utf8');
|
|
79
85
|
return entry.name;
|
|
80
86
|
}
|
|
81
87
|
catch {
|
|
@@ -91,16 +97,17 @@ export async function listModulesInSourceRepo(target, repoPath) {
|
|
|
91
97
|
export async function removeModuleFromSourceRepo(options, git = realGit) {
|
|
92
98
|
const repoPath = validateRepoPath(options.repoPath);
|
|
93
99
|
const moduleName = validateModuleName(options.moduleName);
|
|
94
|
-
|
|
100
|
+
const sourceType = normalizeSourceType(options.sourceType);
|
|
101
|
+
if (sourceType === 'private' && (await usesAddonsYaml(options.target))) {
|
|
95
102
|
const addonsYaml = await readAddonsYaml(options.target);
|
|
96
103
|
await writeAddonsYaml(options.target, removeModuleFromSourceRepoInAddonsYaml(addonsYaml, repoPath, moduleName));
|
|
97
104
|
}
|
|
98
105
|
if (options.deleteFiles) {
|
|
99
|
-
await rm(modulePath(options.target, repoPath, moduleName), { recursive: true, force: true });
|
|
106
|
+
await rm(modulePath(options.target, sourceType, repoPath, moduleName), { recursive: true, force: true });
|
|
100
107
|
}
|
|
101
108
|
if (options.stage) {
|
|
102
109
|
if (options.deleteFiles) {
|
|
103
|
-
await stageAll(git, sourceRepoPath(options.target, repoPath));
|
|
110
|
+
await stageAll(git, sourceRepoPath(options.target, sourceType, repoPath));
|
|
104
111
|
}
|
|
105
112
|
await stageAll(git, options.target);
|
|
106
113
|
}
|
package/dist/status.js
CHANGED
|
@@ -3,6 +3,16 @@ import { join } from 'node:path';
|
|
|
3
3
|
import { detectComposeLayout, readEnvFile, selectedComposeEnvironment } from './compose-layout.js';
|
|
4
4
|
import { defaultOdooVersion, markerPath } from './environment.js';
|
|
5
5
|
import { isValidPathSegment, validateRepoPath } from './path-validation.js';
|
|
6
|
+
const validSourceTypes = ['private', 'oca', 'external'];
|
|
7
|
+
function normalizeSourceType(sourceType) {
|
|
8
|
+
if (typeof sourceType === 'string' && validSourceTypes.includes(sourceType)) {
|
|
9
|
+
return sourceType;
|
|
10
|
+
}
|
|
11
|
+
return 'private';
|
|
12
|
+
}
|
|
13
|
+
function sourceRepoPath(target, sourceType, path) {
|
|
14
|
+
return join(target, 'odoo/custom/src', sourceType, path);
|
|
15
|
+
}
|
|
6
16
|
async function pathExists(path) {
|
|
7
17
|
try {
|
|
8
18
|
await access(path);
|
|
@@ -27,9 +37,11 @@ function parseMetadata(content) {
|
|
|
27
37
|
}
|
|
28
38
|
function sourceRepoPathsFromMetadata(metadata) {
|
|
29
39
|
const sourceRepoPaths = [];
|
|
40
|
+
const sourceRepoLocations = [];
|
|
30
41
|
const invalidSourceRepoPaths = [];
|
|
31
|
-
if (!Array.isArray(metadata.sourceRepos))
|
|
32
|
-
return { sourceRepoPaths, invalidSourceRepoPaths };
|
|
42
|
+
if (!Array.isArray(metadata.sourceRepos)) {
|
|
43
|
+
return { sourceRepoPaths, sourceRepoLocations, invalidSourceRepoPaths };
|
|
44
|
+
}
|
|
33
45
|
for (const repo of metadata.sourceRepos) {
|
|
34
46
|
const path = repo && typeof repo.path === 'string' ? repo.path.trim() : '';
|
|
35
47
|
if (!path)
|
|
@@ -38,9 +50,12 @@ function sourceRepoPathsFromMetadata(metadata) {
|
|
|
38
50
|
invalidSourceRepoPaths.push(path);
|
|
39
51
|
continue;
|
|
40
52
|
}
|
|
41
|
-
|
|
53
|
+
const sourceType = normalizeSourceType(typeof repo.sourceType === 'string' ? repo.sourceType : undefined);
|
|
54
|
+
const normalizedPath = validateRepoPath(path);
|
|
55
|
+
sourceRepoPaths.push(normalizedPath);
|
|
56
|
+
sourceRepoLocations.push({ sourceType, path: normalizedPath });
|
|
42
57
|
}
|
|
43
|
-
return { sourceRepoPaths, invalidSourceRepoPaths };
|
|
58
|
+
return { sourceRepoPaths, sourceRepoLocations, invalidSourceRepoPaths };
|
|
44
59
|
}
|
|
45
60
|
async function missingCoreFiles(target, odooVersion) {
|
|
46
61
|
const missing = [];
|
|
@@ -135,8 +150,8 @@ export async function getEnvironmentStatus(target) {
|
|
|
135
150
|
const odooVersion = typeof metadata.odooVersion === 'string' && metadata.odooVersion.trim()
|
|
136
151
|
? metadata.odooVersion.trim()
|
|
137
152
|
: defaultOdooVersion;
|
|
138
|
-
const { sourceRepoPaths, invalidSourceRepoPaths } = sourceRepoPathsFromMetadata(metadata);
|
|
139
|
-
const repoRoots =
|
|
153
|
+
const { sourceRepoPaths, sourceRepoLocations, invalidSourceRepoPaths } = sourceRepoPathsFromMetadata(metadata);
|
|
154
|
+
const repoRoots = sourceRepoLocations.map(({ sourceType, path }) => sourceRepoPath(target, sourceType, path));
|
|
140
155
|
let moduleCandidateCount = 0;
|
|
141
156
|
for (const repoRoot of repoRoots) {
|
|
142
157
|
moduleCandidateCount += await countModuleCandidatesInRepoPath(repoRoot);
|