Skip to content

Commit

Permalink
add meta to the generator instance (#515)
Browse files Browse the repository at this point in the history
* add meta to the generator instance

* fix type
  • Loading branch information
mshima committed Jan 29, 2024
1 parent 658b4de commit a48ee47
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 23 deletions.
54 changes: 33 additions & 21 deletions src/environment-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,18 +245,10 @@ export default class EnvironmentBase extends EventEmitter implements BaseEnviron
}

/**
* Get a single generator from the registered list of generators. The lookup is
* based on generator's namespace, "walking up" the namespaces until a matching
* is found. Eg. if an `angular:common` namespace is registered, and we try to
* get `angular:common:all` then we get `angular:common` as a fallback (unless
* an `angular:common:all` generator is registered).
*
* @param namespaceOrPath
* @return the generator registered under the namespace
* @return the generator meta registered under the namespace
*/
async get<C extends BaseGeneratorConstructor = BaseGeneratorConstructor>(
namespaceOrPath: string | YeomanNamespace,
): Promise<C | undefined> {
async findMeta(namespaceOrPath: string | YeomanNamespace): Promise<GeneratorMeta | undefined> {
// Stop the recursive search if nothing is left
if (!namespaceOrPath) {
return;
Expand All @@ -265,27 +257,41 @@ export default class EnvironmentBase extends EventEmitter implements BaseEnviron
const parsed = toNamespace(namespaceOrPath);
if (typeof namespaceOrPath !== 'string' || parsed) {
const ns = parsed!.namespace;
const maybeGenerator = (await this.store.get(ns)) ?? this.store.get(this.alias(ns));
return maybeGenerator as C;
return this.store.getMeta(ns) ?? this.store.getMeta(this.alias(ns));
}

const maybeGenerator = (await this.store.get(namespaceOrPath)) ?? (await this.store.get(this.alias(namespaceOrPath)));
if (maybeGenerator) {
return maybeGenerator as C;
const maybeMeta = this.store.getMeta(namespaceOrPath) ?? this.store.getMeta(this.alias(namespaceOrPath));
if (maybeMeta) {
return maybeMeta;
}

try {
const resolved = await resolveModulePath(namespaceOrPath);
if (resolved) {
const namespace = this.namespace(resolved);
this.store.add({ resolved, namespace });
return (await this.store.get(namespace)) as C;
return this.store.add({ resolved, namespace: this.namespace(resolved) });
}
} catch {}

return undefined;
}

/**
* Get a single generator from the registered list of generators. The lookup is
* based on generator's namespace, "walking up" the namespaces until a matching
* is found. Eg. if an `angular:common` namespace is registered, and we try to
* get `angular:common:all` then we get `angular:common` as a fallback (unless
* an `angular:common:all` generator is registered).
*
* @param namespaceOrPath
* @return the generator registered under the namespace
*/
async get<C extends BaseGeneratorConstructor = BaseGeneratorConstructor>(
namespaceOrPath: string | YeomanNamespace,
): Promise<C | undefined> {
const meta = await this.findMeta(namespaceOrPath);
return meta?.importGenerator() as Promise<C>;
}

/**
* Create is the Generator factory. It takes a namespace to lookup and optional
* hash of options, that lets you define `arguments` and `options` to
Expand Down Expand Up @@ -351,11 +357,16 @@ export default class EnvironmentBase extends EventEmitter implements BaseEnviron
}

if (typeof namespaceOrPath === 'string') {
constructor = await this.get(namespaceOrPath);
const meta = await this.findMeta(namespaceOrPath);
constructor = await meta?.importGenerator();
if (namespace && !constructor) {
// Await this.lookupLocalNamespaces(namespace);
// constructor = await this.get(namespace);
}

if (constructor) {
(constructor as any)._meta = meta;
}
} else {
constructor = namespaceOrPath;
}
Expand All @@ -376,14 +387,15 @@ export default class EnvironmentBase extends EventEmitter implements BaseEnviron
): Promise<G>;
async instantiate<G extends BaseGenerator = BaseGenerator>(constructor: GetGeneratorConstructor<G>, ...args: any[]): Promise<G> {
const composeOptions = args.length > 0 ? (getInstantiateOptions(...args) as InstantiateOptions<G>) : {};
const { namespace = UNKNOWN_NAMESPACE, resolved = UNKNOWN_RESOLVED } = constructor as any;
const { namespace = UNKNOWN_NAMESPACE, resolved = UNKNOWN_RESOLVED, _meta } = constructor as any;
const environmentOptions = { env: this, resolved, namespace };
const generator = new constructor(composeOptions.generatorArgs ?? [], {
...this.sharedOptions,
...composeOptions.generatorOptions,
...environmentOptions,
} as unknown as GetGeneratorOptions<G>);

(generator as any)._meta = _meta;
(generator as any)._environmentOptions = {
...this.options,
...this.sharedOptions,
Expand Down Expand Up @@ -689,7 +701,7 @@ export default class EnvironmentBase extends EventEmitter implements BaseEnviron
* @param namespace
*/
getGeneratorMeta(namespace: string): GeneratorMeta | undefined {
const meta: GeneratorMeta = this.store.getMeta(namespace) ?? this.store.getMeta(this.alias(namespace));
const meta = this.store.getMeta(namespace) ?? this.store.getMeta(this.alias(namespace));
if (!meta) {
return;
}
Expand Down
4 changes: 2 additions & 2 deletions src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export default class Store {
* @param {String} namespace
* @return {Module}
*/
async get(namespace: string): Promise<GetGeneratorConstructor> {
async get(namespace: string): Promise<GetGeneratorConstructor | undefined> {
return this.getMeta(namespace)?.importGenerator();
}

Expand All @@ -117,7 +117,7 @@ export default class Store {
* @param {String} namespace
* @return {Module}
*/
getMeta(namespace: string): GeneratorMeta {
getMeta(namespace: string): GeneratorMeta | undefined {
return this._meta[namespace];
}

Expand Down
4 changes: 4 additions & 0 deletions test/environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,10 @@ for (const generatorVersion of allVersions) {
assert.ok((await this.env.composeWith('stub')) instanceof this.Generator);
});

it('should instantiate a genarator and set _meta', async function () {
assert.ok((await this.env.composeWith('stub'))._meta);
});

it('should schedule generator queue', async function () {
this.env.queueTask = sinon.spy();
await this.env.composeWith('stub');
Expand Down

0 comments on commit a48ee47

Please sign in to comment.