yeoman-environment 4.0.0-alpha.5 → 4.0.0-alpha.7
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/bin/bin.cjs +4 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +18 -15
- package/dist/cli/utils.d.ts +8 -0
- package/dist/cli/utils.js +6 -7
- package/dist/commands.d.ts +23 -0
- package/dist/commands.js +45 -0
- package/dist/commit.d.ts +17 -0
- package/dist/commit.js +22 -0
- package/dist/composed-store.d.ts +26 -0
- package/dist/composed-store.js +68 -0
- package/dist/constants.d.ts +3 -0
- package/dist/constants.js +17 -0
- package/dist/environment-base.d.ts +259 -0
- package/dist/environment-base.js +641 -0
- package/dist/environment-full.d.ts +115 -0
- package/dist/environment-full.js +321 -0
- package/dist/generator-lookup.d.ts +56 -0
- package/dist/generator-lookup.js +97 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +9 -5
- package/dist/module-lookup.d.ts +59 -0
- package/dist/module-lookup.js +227 -0
- package/dist/package-manager.d.ts +18 -0
- package/dist/package-manager.js +52 -69
- package/dist/store.d.ts +66 -0
- package/dist/store.js +76 -47
- package/dist/util/command.d.ts +34 -0
- package/dist/util/command.js +32 -17
- package/dist/util/namespace.d.ts +26 -0
- package/dist/util/namespace.js +56 -190
- package/dist/util/resolve.d.ts +6 -0
- package/dist/util/resolve.js +40 -0
- package/dist/util/util.d.ts +7 -0
- package/dist/util/util.js +24 -23
- package/package.json +20 -33
- package/readme.md +2 -3
- package/dist/adapter.js +0 -97
- package/dist/adapter.js.map +0 -1
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/utils.js.map +0 -1
- package/dist/command.js +0 -74
- package/dist/command.js.map +0 -1
- package/dist/composability.js +0 -78
- package/dist/composability.js.map +0 -1
- package/dist/environment.js +0 -1221
- package/dist/environment.js.map +0 -1
- package/dist/generator-features.js +0 -69
- package/dist/generator-features.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/namespace-composability.js +0 -340
- package/dist/namespace-composability.js.map +0 -1
- package/dist/package-manager.js.map +0 -1
- package/dist/resolver.js +0 -421
- package/dist/resolver.js.map +0 -1
- package/dist/spawn-command.js +0 -30
- package/dist/spawn-command.js.map +0 -1
- package/dist/store.js.map +0 -1
- package/dist/util/binary-diff.js +0 -36
- package/dist/util/binary-diff.js.map +0 -1
- package/dist/util/command.js.map +0 -1
- package/dist/util/conflicter.js +0 -346
- package/dist/util/conflicter.js.map +0 -1
- package/dist/util/esm.js +0 -22
- package/dist/util/esm.js.map +0 -1
- package/dist/util/log.js +0 -165
- package/dist/util/log.js.map +0 -1
- package/dist/util/namespace.js.map +0 -1
- package/dist/util/repository.js +0 -223
- package/dist/util/repository.js.map +0 -1
- package/dist/util/transform.js +0 -149
- package/dist/util/transform.js.map +0 -1
- package/dist/util/util.js.map +0 -1
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { existsSync, lstatSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { delimiter, dirname, join, resolve, sep } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import process from 'node:process';
|
|
5
|
+
import arrify from 'arrify';
|
|
6
|
+
import { uniq, compact } from 'lodash-es';
|
|
7
|
+
import { globbySync } from 'globby';
|
|
8
|
+
import slash from 'slash';
|
|
9
|
+
import createdLogger from 'debug';
|
|
10
|
+
import { execaOutput } from './util/util.js';
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = dirname(__filename);
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
14
|
+
const PROJECT_ROOT = join(__dirname, '..');
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
16
|
+
const PACKAGE_NAME_PATTERN = [JSON.parse(readFileSync(join(PROJECT_ROOT, 'package.json')).toString()).name];
|
|
17
|
+
const win32 = process.platform === 'win32';
|
|
18
|
+
const nvm = process.env.NVM_HOME;
|
|
19
|
+
const debug = createdLogger('yeoman:environment');
|
|
20
|
+
/**
|
|
21
|
+
* Search for npm packages.
|
|
22
|
+
*/
|
|
23
|
+
export function moduleLookupSync(options, find) {
|
|
24
|
+
debug('Running lookup with options: %o', options);
|
|
25
|
+
options = { ...options };
|
|
26
|
+
options.filePatterns = arrify(options.filePatterns ?? 'package.json').map(filePattern => slash(filePattern));
|
|
27
|
+
if (options.packagePaths) {
|
|
28
|
+
options.packagePaths = arrify(options.packagePaths);
|
|
29
|
+
if (options.reverse) {
|
|
30
|
+
options.packagePaths = options.packagePaths.reverse();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
options.npmPaths = options.npmPaths ?? getNpmPaths(options);
|
|
35
|
+
if (options.reverse && Array.isArray(options.npmPaths)) {
|
|
36
|
+
options.npmPaths = options.npmPaths.reverse();
|
|
37
|
+
}
|
|
38
|
+
options.packagePatterns = arrify(options.packagePatterns ?? PACKAGE_NAME_PATTERN).map(packagePattern => slash(packagePattern));
|
|
39
|
+
options.packagePaths = findPackagesIn(options.npmPaths, options.packagePatterns);
|
|
40
|
+
}
|
|
41
|
+
debug('Lookup calculated options: %o', options);
|
|
42
|
+
const modules = [];
|
|
43
|
+
for (const packagePath of options.packagePaths) {
|
|
44
|
+
if (!existsSync(packagePath) || (!lstatSync(packagePath).isDirectory() && !lstatSync(packagePath).isSymbolicLink())) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const files = globbySync(options.filePatterns, {
|
|
48
|
+
cwd: packagePath,
|
|
49
|
+
absolute: true,
|
|
50
|
+
...options.globbyOptions,
|
|
51
|
+
});
|
|
52
|
+
const filePath = find({ files, packagePath });
|
|
53
|
+
if (filePath) {
|
|
54
|
+
return [{ filePath, packagePath }];
|
|
55
|
+
}
|
|
56
|
+
for (const filePath of files) {
|
|
57
|
+
modules.push({ filePath, packagePath });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return modules;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Search npm for every available generators.
|
|
64
|
+
* Generators are npm packages who's name start with `generator-` and who're placed in the
|
|
65
|
+
* top level `node_module` path. They can be installed globally or locally.
|
|
66
|
+
*
|
|
67
|
+
* @method
|
|
68
|
+
*
|
|
69
|
+
* @param searchPaths List of search paths
|
|
70
|
+
* @param packagePatterns Pattern of the packages
|
|
71
|
+
* @param globbyOptions
|
|
72
|
+
* @return List of the generator modules path
|
|
73
|
+
*/
|
|
74
|
+
export function findPackagesIn(searchPaths, packagePatterns, globbyOptions) {
|
|
75
|
+
searchPaths = arrify(searchPaths)
|
|
76
|
+
.filter(Boolean)
|
|
77
|
+
.map(npmPath => resolve(npmPath));
|
|
78
|
+
let modules = [];
|
|
79
|
+
for (const root of searchPaths) {
|
|
80
|
+
if (!existsSync(root) || (!lstatSync(root).isDirectory() && !lstatSync(root).isSymbolicLink())) {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
// Some folders might not be readable to the current user. For those, we add a try
|
|
84
|
+
// catch to handle the error gracefully as globby doesn't have an option to skip
|
|
85
|
+
// restricted folders.
|
|
86
|
+
try {
|
|
87
|
+
modules = modules.concat(globbySync(packagePatterns, {
|
|
88
|
+
cwd: root,
|
|
89
|
+
onlyDirectories: true,
|
|
90
|
+
expandDirectories: false,
|
|
91
|
+
absolute: true,
|
|
92
|
+
deep: 0,
|
|
93
|
+
...globbyOptions,
|
|
94
|
+
}));
|
|
95
|
+
// To limit recursive lookups into non-namespace folders within globby,
|
|
96
|
+
// fetch all namespaces in root, then search each namespace separately
|
|
97
|
+
// for generator modules
|
|
98
|
+
const scopes = globbySync(['@*'], {
|
|
99
|
+
cwd: root,
|
|
100
|
+
onlyDirectories: true,
|
|
101
|
+
expandDirectories: false,
|
|
102
|
+
absolute: true,
|
|
103
|
+
deep: 0,
|
|
104
|
+
...globbyOptions,
|
|
105
|
+
});
|
|
106
|
+
for (const scope of scopes) {
|
|
107
|
+
modules = modules.concat(globbySync(packagePatterns, {
|
|
108
|
+
cwd: scope,
|
|
109
|
+
onlyDirectories: true,
|
|
110
|
+
expandDirectories: false,
|
|
111
|
+
absolute: true,
|
|
112
|
+
deep: 0,
|
|
113
|
+
...globbyOptions,
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
debug('Could not access %s (%s)', root, error);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return modules;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get the npm lookup directories (`node_modules/`)
|
|
125
|
+
*
|
|
126
|
+
* @method
|
|
127
|
+
*
|
|
128
|
+
* @param {boolean|Object} [options]
|
|
129
|
+
* @param {boolean} [options.localOnly = false] - Set true to skip lookups of
|
|
130
|
+
* globally-installed generators.
|
|
131
|
+
* @param {boolean} [options.filterPaths = false] - Remove paths that don't ends
|
|
132
|
+
* with a supported path (don't touch at NODE_PATH paths).
|
|
133
|
+
* @return {Array} lookup paths
|
|
134
|
+
*/
|
|
135
|
+
export function getNpmPaths(options = {}) {
|
|
136
|
+
// Resolve signature where options is boolean (localOnly).
|
|
137
|
+
if (typeof options === 'boolean') {
|
|
138
|
+
options = { localOnly: options };
|
|
139
|
+
}
|
|
140
|
+
// Start with the local paths.
|
|
141
|
+
let paths = getLocalNpmPaths();
|
|
142
|
+
// Append global paths, unless they should be excluded.
|
|
143
|
+
if (!options.localOnly) {
|
|
144
|
+
paths = paths.concat(getGlobalNpmPaths(options.filterPaths));
|
|
145
|
+
}
|
|
146
|
+
return uniq(paths);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Get the local npm lookup directories
|
|
150
|
+
* @private
|
|
151
|
+
* @return {Array} lookup paths
|
|
152
|
+
*/
|
|
153
|
+
function getLocalNpmPaths() {
|
|
154
|
+
const paths = [];
|
|
155
|
+
// Walk up the CWD and add `node_modules/` folder lookup on each level
|
|
156
|
+
process
|
|
157
|
+
.cwd()
|
|
158
|
+
.split(sep)
|
|
159
|
+
.forEach((part, i, parts) => {
|
|
160
|
+
let lookup = join(...parts.slice(0, i + 1), 'node_modules');
|
|
161
|
+
if (!win32) {
|
|
162
|
+
lookup = `/${lookup}`;
|
|
163
|
+
}
|
|
164
|
+
paths.push(lookup);
|
|
165
|
+
});
|
|
166
|
+
return uniq(paths.reverse());
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Get the global npm lookup directories
|
|
170
|
+
* Reference: https://nodejs.org/api/modules.html
|
|
171
|
+
* @private
|
|
172
|
+
* @return {Array} lookup paths
|
|
173
|
+
*/
|
|
174
|
+
function getGlobalNpmPaths(filterPaths = true) {
|
|
175
|
+
let paths = [];
|
|
176
|
+
// Node.js will search in the following list of GLOBAL_FOLDERS:
|
|
177
|
+
// 1: $HOME/.node_modules
|
|
178
|
+
// 2: $HOME/.node_libraries
|
|
179
|
+
// 3: $PREFIX/lib/node
|
|
180
|
+
const filterValidNpmPath = function (path, ignore = false) {
|
|
181
|
+
return ignore ? [path] : ['/node_modules', '/.node_modules', '/.node_libraries', '/node'].some(dir => path.endsWith(dir)) ? [path] : [];
|
|
182
|
+
};
|
|
183
|
+
// Default paths for each system
|
|
184
|
+
if (nvm && process.env.NVM_HOME) {
|
|
185
|
+
paths.push(join(process.env.NVM_HOME, process.version, 'node_modules'));
|
|
186
|
+
}
|
|
187
|
+
else if (win32 && process.env.APPDATA) {
|
|
188
|
+
paths.push(join(process.env.APPDATA, 'npm/node_modules'));
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
paths.push('/usr/lib/node_modules', '/usr/local/lib/node_modules');
|
|
192
|
+
}
|
|
193
|
+
// Add NVM prefix directory
|
|
194
|
+
if (process.env.NVM_PATH) {
|
|
195
|
+
paths.push(join(dirname(process.env.NVM_PATH), 'node_modules'));
|
|
196
|
+
}
|
|
197
|
+
// Adding global npm directories
|
|
198
|
+
// We tried using npm to get the global modules path, but it haven't work out
|
|
199
|
+
// because of bugs in the parseable implementation of `ls` command and mostly
|
|
200
|
+
// performance issues. So, we go with our best bet for now.
|
|
201
|
+
if (process.env.NODE_PATH) {
|
|
202
|
+
paths = compact(process.env.NODE_PATH.split(delimiter)).concat(paths);
|
|
203
|
+
}
|
|
204
|
+
// Global node_modules should be 4 or 2 directory up this one (most of the time)
|
|
205
|
+
// Ex: /usr/another_global/node_modules/yeoman-denerator/node_modules/yeoman-environment/lib (1 level dependency)
|
|
206
|
+
paths.push(...filterValidNpmPath(join(PROJECT_ROOT, '../../..'), !filterPaths));
|
|
207
|
+
// Ex: /usr/another_global/node_modules/yeoman-environment/lib (installed directly)
|
|
208
|
+
paths.push(join(PROJECT_ROOT, '..'));
|
|
209
|
+
// Get yarn global directory and infer the module paths from there
|
|
210
|
+
const yarnBase = execaOutput('yarn', ['global', 'dir'], { encoding: 'utf8' });
|
|
211
|
+
if (yarnBase) {
|
|
212
|
+
paths.push(resolve(yarnBase, 'node_modules'));
|
|
213
|
+
paths.push(resolve(yarnBase, '../link/'));
|
|
214
|
+
}
|
|
215
|
+
// Get npm global prefix and infer the module paths from there
|
|
216
|
+
const globalInstall = execaOutput('npm', ['root', '-g'], {
|
|
217
|
+
encoding: 'utf8',
|
|
218
|
+
});
|
|
219
|
+
if (globalInstall) {
|
|
220
|
+
paths.push(resolve(globalInstall));
|
|
221
|
+
}
|
|
222
|
+
// Adds support for generator resolving when yeoman-generator has been linked
|
|
223
|
+
if (process.argv[1]) {
|
|
224
|
+
paths.push(...filterValidNpmPath(join(dirname(process.argv[1]), '../..'), !filterPaths));
|
|
225
|
+
}
|
|
226
|
+
return uniq(paths.filter(Boolean).reverse());
|
|
227
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { MemFsEditorFile } from 'mem-fs-editor';
|
|
2
|
+
import { type InputOutputAdapter } from '@yeoman/types';
|
|
3
|
+
import { type Store } from 'mem-fs';
|
|
4
|
+
export type PackageManagerInstallTaskOptions = {
|
|
5
|
+
memFs: Store<MemFsEditorFile>;
|
|
6
|
+
packageJsonLocation: string;
|
|
7
|
+
adapter: InputOutputAdapter;
|
|
8
|
+
nodePackageManager?: string;
|
|
9
|
+
customInstallTask?: boolean | ((nodePackageManager: string | undefined, defaultTask: () => Promise<boolean>) => void | Promise<void>);
|
|
10
|
+
skipInstall?: boolean;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Executes package manager install.
|
|
14
|
+
* - checks if package.json was committed.
|
|
15
|
+
* - uses a preferred package manager or try to detect.
|
|
16
|
+
* @return {Promise<boolean>} Promise true if the install execution suceeded.
|
|
17
|
+
*/
|
|
18
|
+
export declare function packageManagerInstallTask({ memFs, packageJsonLocation, customInstallTask, adapter, nodePackageManager, skipInstall, }: PackageManagerInstallTaskOptions): Promise<boolean | void>;
|
package/dist/package-manager.js
CHANGED
|
@@ -1,92 +1,75 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { join, resolve } from 'node:path';
|
|
2
2
|
import createdLogger from 'debug';
|
|
3
3
|
import preferredPm from 'preferred-pm';
|
|
4
|
+
import { execa } from 'execa';
|
|
4
5
|
const debug = createdLogger('yeoman:environment:package-manager');
|
|
5
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Executes package manager install.
|
|
8
|
+
* - checks if package.json was committed.
|
|
9
|
+
* - uses a preferred package manager or try to detect.
|
|
10
|
+
* @return {Promise<boolean>} Promise true if the install execution suceeded.
|
|
11
|
+
*/
|
|
12
|
+
/*
|
|
13
|
+
const { customInstallTask } = this.composedStore;
|
|
14
|
+
packageJsonFile: join(this.cwd, 'package.json');
|
|
15
|
+
|
|
16
|
+
*/
|
|
17
|
+
export async function packageManagerInstallTask({ memFs, packageJsonLocation, customInstallTask, adapter, nodePackageManager, skipInstall, }) {
|
|
18
|
+
packageJsonLocation = resolve(packageJsonLocation);
|
|
6
19
|
/**
|
|
7
20
|
* @private
|
|
8
21
|
* Get the destination package.json file.
|
|
9
22
|
* @return {Vinyl | undefined} a Vinyl file.
|
|
10
23
|
*/
|
|
11
|
-
getDestinationPackageJson() {
|
|
12
|
-
return
|
|
24
|
+
function getDestinationPackageJson() {
|
|
25
|
+
return memFs.get(join(packageJsonLocation, 'package.json'));
|
|
13
26
|
}
|
|
14
27
|
/**
|
|
15
28
|
* @private
|
|
16
29
|
* Get the destination package.json commit status.
|
|
17
30
|
* @return {boolean} package.json commit status.
|
|
18
31
|
*/
|
|
19
|
-
isDestinationPackageJsonCommitted() {
|
|
20
|
-
const file =
|
|
21
|
-
return file
|
|
32
|
+
function isDestinationPackageJsonCommitted() {
|
|
33
|
+
const file = getDestinationPackageJson();
|
|
34
|
+
return file.committed;
|
|
22
35
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
* Detect the package manager based on files or use the passed one.
|
|
26
|
-
* @return {string} package manager.
|
|
27
|
-
*/
|
|
28
|
-
async detectPackageManager() {
|
|
29
|
-
if (this.options.nodePackageManager) {
|
|
30
|
-
return this.options.nodePackageManager;
|
|
31
|
-
}
|
|
32
|
-
const pm = await preferredPm(this.cwd);
|
|
33
|
-
return pm && pm.name;
|
|
36
|
+
if (!getDestinationPackageJson()) {
|
|
37
|
+
return false;
|
|
34
38
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
async packageManagerInstallTask() {
|
|
42
|
-
if (!this.getDestinationPackageJson()) {
|
|
43
|
-
return false;
|
|
44
|
-
}
|
|
45
|
-
if (this.compatibilityMode === 'v4') {
|
|
46
|
-
debug('Running in generator < 5 compatibility. Package manager install is done by the generator.');
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
49
|
-
const customInstallTask = this.findGeneratorCustomInstallTask();
|
|
50
|
-
if (customInstallTask && typeof customInstallTask !== 'function') {
|
|
51
|
-
debug('Install disabled by customInstallTask');
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
if (!this.isDestinationPackageJsonCommitted()) {
|
|
55
|
-
this.adapter.log(`
|
|
39
|
+
if (customInstallTask && typeof customInstallTask !== 'function') {
|
|
40
|
+
debug('Install disabled by customInstallTask');
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
if (!isDestinationPackageJsonCommitted()) {
|
|
44
|
+
adapter.log(`
|
|
56
45
|
No change to package.json was detected. No package manager install will be executed.`);
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
adapter.log(`
|
|
60
49
|
Changes to package.json were detected.`);
|
|
61
|
-
|
|
62
|
-
|
|
50
|
+
if (skipInstall) {
|
|
51
|
+
adapter.log(`Skipping package manager install.
|
|
63
52
|
`);
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
// eslint-disable-next-line unicorn/no-await-expression-member
|
|
56
|
+
let packageManagerName = nodePackageManager ?? (await preferredPm(packageJsonLocation))?.name;
|
|
57
|
+
const execPackageManager = async () => {
|
|
58
|
+
if (!packageManagerName) {
|
|
59
|
+
packageManagerName = 'npm';
|
|
60
|
+
adapter.log('Error detecting the package manager. Falling back to npm.');
|
|
61
|
+
}
|
|
62
|
+
if (!['npm', 'yarn', 'pnpm'].includes(packageManagerName)) {
|
|
63
|
+
adapter.log(`${packageManagerName} is not a supported package manager. Run it by yourself.`);
|
|
64
64
|
return false;
|
|
65
65
|
}
|
|
66
|
-
|
|
67
|
-
const execPackageManager = async () => {
|
|
68
|
-
if (!packageManagerName) {
|
|
69
|
-
packageManagerName = 'npm';
|
|
70
|
-
this.adapter.log('Error detecting the package manager. Falling back to npm.');
|
|
71
|
-
}
|
|
72
|
-
if (!['npm', 'yarn', 'pnpm'].includes(packageManagerName)) {
|
|
73
|
-
this.adapter.log(`${packageManagerName} is not a supported package manager. Run it by yourself.`);
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
this.adapter.log(`
|
|
66
|
+
adapter.log(`
|
|
77
67
|
Running ${packageManagerName} install for you to install the required dependencies.`);
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if (!result || !result.then) {
|
|
84
|
-
return true;
|
|
85
|
-
}
|
|
86
|
-
return result;
|
|
87
|
-
}
|
|
88
|
-
return execPackageManager();
|
|
68
|
+
await execa(packageManagerName, ['install'], { stdio: 'inherit', cwd: packageJsonLocation });
|
|
69
|
+
return true;
|
|
70
|
+
};
|
|
71
|
+
if (customInstallTask) {
|
|
72
|
+
return customInstallTask(packageManagerName, execPackageManager);
|
|
89
73
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
//# sourceMappingURL=package-manager.js.map
|
|
74
|
+
return execPackageManager();
|
|
75
|
+
}
|
package/dist/store.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { BaseEnvironment, GetGeneratorConstructor, GeneratorMeta, BaseGeneratorMeta } from '@yeoman/types';
|
|
2
|
+
/**
|
|
3
|
+
* The Generator store
|
|
4
|
+
* This is used to store generator (npm packages) reference and instantiate them when
|
|
5
|
+
* requested.
|
|
6
|
+
* @constructor
|
|
7
|
+
* @private
|
|
8
|
+
*/
|
|
9
|
+
export default class Store {
|
|
10
|
+
private readonly env;
|
|
11
|
+
private readonly _meta;
|
|
12
|
+
private readonly _packagesPaths;
|
|
13
|
+
private readonly _packagesNS;
|
|
14
|
+
constructor(env: BaseEnvironment);
|
|
15
|
+
/**
|
|
16
|
+
* Store a module under the namespace key
|
|
17
|
+
* @param meta
|
|
18
|
+
* @param generator - A generator module or a module path
|
|
19
|
+
*/
|
|
20
|
+
add(meta: BaseGeneratorMeta, Generator?: unknown): GeneratorMeta;
|
|
21
|
+
/**
|
|
22
|
+
* Get the module registered under the given namespace
|
|
23
|
+
* @param {String} namespace
|
|
24
|
+
* @return {Module}
|
|
25
|
+
*/
|
|
26
|
+
get(namespace: string): Promise<GetGeneratorConstructor>;
|
|
27
|
+
/**
|
|
28
|
+
* Get the module registered under the given namespace
|
|
29
|
+
* @param {String} namespace
|
|
30
|
+
* @return {Module}
|
|
31
|
+
*/
|
|
32
|
+
getMeta(namespace: string): GeneratorMeta;
|
|
33
|
+
/**
|
|
34
|
+
* Returns the list of registered namespace.
|
|
35
|
+
* @return {Array} Namespaces array
|
|
36
|
+
*/
|
|
37
|
+
namespaces(): string[];
|
|
38
|
+
/**
|
|
39
|
+
* Get the stored generators meta data
|
|
40
|
+
* @return {Object} Generators metadata
|
|
41
|
+
*/
|
|
42
|
+
getGeneratorsMeta(): Record<string, GeneratorMeta>;
|
|
43
|
+
/**
|
|
44
|
+
* Store a package under the namespace key
|
|
45
|
+
* @param {String} packageNS - The key under which the generator can be retrieved
|
|
46
|
+
* @param {String} packagePath - The package path
|
|
47
|
+
*/
|
|
48
|
+
addPackage(packageNS: string, packagePath: string): void;
|
|
49
|
+
/**
|
|
50
|
+
* Get the stored packages namespaces with paths.
|
|
51
|
+
* @return {Object} Stored packages namespaces with paths.
|
|
52
|
+
*/
|
|
53
|
+
getPackagesPaths(): Record<string, string[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Store a package ns
|
|
56
|
+
* @param {String} packageNS - The key under which the generator can be retrieved
|
|
57
|
+
*/
|
|
58
|
+
addPackageNamespace(packageNS: string): void;
|
|
59
|
+
/**
|
|
60
|
+
* Get the stored packages namespaces.
|
|
61
|
+
* @return {Array} Stored packages namespaces.
|
|
62
|
+
*/
|
|
63
|
+
getPackagesNS(): string[];
|
|
64
|
+
private getFactory;
|
|
65
|
+
private _getGenerator;
|
|
66
|
+
}
|
package/dist/store.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { pathToFileURL } from 'node:url';
|
|
2
|
+
import { extname, join } from 'node:path';
|
|
3
|
+
import { toNamespace } from '@yeoman/namespace';
|
|
1
4
|
import createDebug from 'debug';
|
|
2
|
-
import { requireOrImport } from './util/esm.js';
|
|
3
5
|
const debug = createDebug('yeoman:environment:store');
|
|
4
6
|
/**
|
|
5
7
|
* The Generator store
|
|
@@ -8,45 +10,71 @@ const debug = createDebug('yeoman:environment:store');
|
|
|
8
10
|
* @constructor
|
|
9
11
|
* @private
|
|
10
12
|
*/
|
|
11
|
-
class Store {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
export default class Store {
|
|
14
|
+
env;
|
|
15
|
+
_meta = {};
|
|
16
|
+
// Store packages paths by ns
|
|
17
|
+
_packagesPaths = {};
|
|
18
|
+
// Store packages ns
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
20
|
+
_packagesNS = [];
|
|
21
|
+
constructor(env) {
|
|
22
|
+
this.env = env;
|
|
18
23
|
}
|
|
19
24
|
/**
|
|
20
25
|
* Store a module under the namespace key
|
|
21
|
-
* @param
|
|
22
|
-
* @param
|
|
23
|
-
* @param {String} packagePath - PackagePath to the generator npm package (optional)
|
|
24
|
-
* @param {String} [resolved] - The file path to the generator (used only if generator is a module)
|
|
26
|
+
* @param meta
|
|
27
|
+
* @param generator - A generator module or a module path
|
|
25
28
|
*/
|
|
26
|
-
add(
|
|
27
|
-
if (typeof
|
|
28
|
-
|
|
29
|
-
return;
|
|
29
|
+
add(meta, Generator) {
|
|
30
|
+
if (typeof meta.resolved === 'string') {
|
|
31
|
+
meta.resolved = extname(meta.resolved) ? join(meta.resolved) : join(meta.resolved, 'index.js');
|
|
30
32
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
resolved
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
if (meta.packagePath) {
|
|
34
|
+
meta.packagePath = join(meta.packagePath);
|
|
35
|
+
}
|
|
36
|
+
let importModule;
|
|
37
|
+
if (!Generator) {
|
|
38
|
+
if (!meta.resolved) {
|
|
39
|
+
throw new Error(`Generator Stub or resolved path is required for ${meta.namespace}`);
|
|
40
|
+
}
|
|
41
|
+
importModule = async () => import(pathToFileURL(meta.resolved).href);
|
|
42
|
+
}
|
|
43
|
+
let importPromise;
|
|
44
|
+
const importGenerator = async () => {
|
|
45
|
+
if (importPromise) {
|
|
46
|
+
Generator = await importPromise;
|
|
47
|
+
}
|
|
48
|
+
if (importModule && !Generator) {
|
|
49
|
+
importPromise = importModule();
|
|
50
|
+
Generator = await importPromise;
|
|
51
|
+
}
|
|
52
|
+
const factory = this.getFactory(Generator);
|
|
53
|
+
if (typeof factory === 'function') {
|
|
54
|
+
importPromise = factory(this.env);
|
|
55
|
+
Generator = await importPromise;
|
|
56
|
+
}
|
|
57
|
+
return this._getGenerator(Generator, meta);
|
|
40
58
|
};
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
namespace,
|
|
47
|
-
packagePath,
|
|
59
|
+
const instantiate = async (args = [], options = {}) => this.env.instantiate(await importGenerator(), { generatorArgs: args, generatorOptions: options });
|
|
60
|
+
const instantiateHelp = async () => instantiate([], { help: true });
|
|
61
|
+
const { packageNamespace } = toNamespace(meta.namespace) ?? {};
|
|
62
|
+
const generatorMeta = {
|
|
63
|
+
...meta,
|
|
48
64
|
importGenerator,
|
|
65
|
+
importModule,
|
|
66
|
+
instantiate,
|
|
67
|
+
instantiateHelp,
|
|
68
|
+
packageNamespace,
|
|
49
69
|
};
|
|
70
|
+
this._meta[meta.namespace] = generatorMeta;
|
|
71
|
+
if (packageNamespace) {
|
|
72
|
+
this.addPackageNamespace(packageNamespace);
|
|
73
|
+
if (meta.packagePath) {
|
|
74
|
+
this.addPackage(packageNamespace, meta.packagePath);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return generatorMeta;
|
|
50
78
|
}
|
|
51
79
|
/**
|
|
52
80
|
* Get the module registered under the given namespace
|
|
@@ -54,18 +82,7 @@ class Store {
|
|
|
54
82
|
* @return {Module}
|
|
55
83
|
*/
|
|
56
84
|
async get(namespace) {
|
|
57
|
-
|
|
58
|
-
if (!meta) {
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
const { importGenerator, ...additionalMeta } = meta;
|
|
62
|
-
const maybeGenerator = importGenerator();
|
|
63
|
-
if (maybeGenerator.then) {
|
|
64
|
-
const esmGenerator = await maybeGenerator;
|
|
65
|
-
return [esmGenerator, additionalMeta];
|
|
66
|
-
}
|
|
67
|
-
Object.assign(maybeGenerator, additionalMeta);
|
|
68
|
-
return maybeGenerator;
|
|
85
|
+
return this.getMeta(namespace)?.importGenerator();
|
|
69
86
|
}
|
|
70
87
|
/**
|
|
71
88
|
* Get the module registered under the given namespace
|
|
@@ -123,7 +140,7 @@ class Store {
|
|
|
123
140
|
* Store a package ns
|
|
124
141
|
* @param {String} packageNS - The key under which the generator can be retrieved
|
|
125
142
|
*/
|
|
126
|
-
|
|
143
|
+
addPackageNamespace(packageNS) {
|
|
127
144
|
if (!this._packagesNS.includes(packageNS)) {
|
|
128
145
|
this._packagesNS.push(packageNS);
|
|
129
146
|
}
|
|
@@ -132,9 +149,21 @@ class Store {
|
|
|
132
149
|
* Get the stored packages namespaces.
|
|
133
150
|
* @return {Array} Stored packages namespaces.
|
|
134
151
|
*/
|
|
152
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
135
153
|
getPackagesNS() {
|
|
136
154
|
return this._packagesNS;
|
|
137
155
|
}
|
|
156
|
+
getFactory(module) {
|
|
157
|
+
// CJS is imported in default, for backward compatibility we support a Generator exported as `module.exports = { default }`
|
|
158
|
+
return module.createGenerator ?? module.default?.createGenerator ?? module.default?.default?.createGenerator;
|
|
159
|
+
}
|
|
160
|
+
_getGenerator(module, meta) {
|
|
161
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
162
|
+
const Generator = module.default?.default ?? module.default ?? module;
|
|
163
|
+
if (typeof Generator !== 'function') {
|
|
164
|
+
throw new TypeError("The generator doesn't provides a constructor.");
|
|
165
|
+
}
|
|
166
|
+
Object.assign(Generator, meta);
|
|
167
|
+
return Generator;
|
|
168
|
+
}
|
|
138
169
|
}
|
|
139
|
-
export default Store;
|
|
140
|
-
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Command, Option } from 'commander';
|
|
2
|
+
import type BaseEnvironment from '../environment-base.js';
|
|
3
|
+
export default class YeomanCommand extends Command {
|
|
4
|
+
env?: BaseEnvironment;
|
|
5
|
+
createCommand(name?: string): YeomanCommand;
|
|
6
|
+
/**
|
|
7
|
+
* Override addOption to register a negative alternative for every option.
|
|
8
|
+
* @param {Option} option
|
|
9
|
+
* @return {YeomanCommand} this;
|
|
10
|
+
*/
|
|
11
|
+
addOption(option: Option): this;
|
|
12
|
+
/**
|
|
13
|
+
* Load Generator options into a commander instance.
|
|
14
|
+
*
|
|
15
|
+
* @param {Generator} generator - Generator
|
|
16
|
+
* @return {Command} return command
|
|
17
|
+
*/
|
|
18
|
+
registerGenerator(generator: any): this;
|
|
19
|
+
/**
|
|
20
|
+
* Register arguments using generator._arguments structure.
|
|
21
|
+
* @param {object[]} generatorArgs
|
|
22
|
+
* @return {YeomanCommand} this;
|
|
23
|
+
*/
|
|
24
|
+
addGeneratorArguments(generatorArgs?: any[]): this;
|
|
25
|
+
/**
|
|
26
|
+
* Register options using generator._options structure.
|
|
27
|
+
* @param {object} options
|
|
28
|
+
* @param {string} blueprintOptionDescription - description of the blueprint that adds the option
|
|
29
|
+
* @return {YeomanCommand} this;
|
|
30
|
+
*/
|
|
31
|
+
addGeneratorOptions(options: Record<string, any>): this;
|
|
32
|
+
_addGeneratorOption(optionName: string, optionDefinition: any, additionalDescription?: string): any;
|
|
33
|
+
}
|
|
34
|
+
export declare const addEnvironmentOptions: (command?: YeomanCommand) => YeomanCommand;
|