Skip to content

Commit

Permalink
add inheritTasks to features (#1523)
Browse files Browse the repository at this point in the history
  • Loading branch information
mshima authored Jun 17, 2024
1 parent 9f7b1bd commit 8b1605a
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 17 deletions.
30 changes: 25 additions & 5 deletions src/actions/lifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,26 @@ export abstract class TasksMixin {
}
}

/**
* Get task sources property descriptors.
*/
getTaskSourcesPropertyDescriptors(this: BaseGeneratorImpl): any {
if (this.features.inheritTasks) {
const queueNames = Object.keys(this._queues);
let currentPrototype = Object.getPrototypeOf(this);
let propertyDescriptors = [];
while (currentPrototype) {
propertyDescriptors.unshift(...Object.entries(Object.getOwnPropertyDescriptors(currentPrototype)));
currentPrototype = Object.getPrototypeOf(currentPrototype);
}

propertyDescriptors = propertyDescriptors.filter(([name]) => queueNames.includes(name));
return Object.fromEntries(propertyDescriptors);
}

return Object.getOwnPropertyDescriptors(Object.getPrototypeOf(this));
}

/**
* Extract tasks from a priority.
*
Expand All @@ -161,10 +181,10 @@ export abstract class TasksMixin {

const { taskPrefix = this.features.taskPrefix ?? '' } = taskOptions;
const propertyName = `${taskPrefix}${name}`;
const property = Object.getOwnPropertyDescriptor(
taskOptions.taskOrigin || Object.getPrototypeOf(this),
propertyName,
);
const property = taskOptions.taskOrigin
? Object.getOwnPropertyDescriptor(taskOptions.taskOrigin, propertyName)
: this.getTaskSourcesPropertyDescriptors()[propertyName];

if (!property) return [];

const item: Task['method'] = property.value ?? property.get?.call(this);
Expand Down Expand Up @@ -218,7 +238,7 @@ export abstract class TasksMixin {
* Get task names.
*/
getTaskNames(this: BaseGeneratorImpl): string[] {
const methods = Object.getOwnPropertyNames(Object.getPrototypeOf(this));
const methods = Object.keys(this.getTaskSourcesPropertyDescriptors());
let validMethods = methods.filter(method => methodIsValid(method));
const { taskPrefix } = this.features;

Expand Down
3 changes: 3 additions & 0 deletions src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ export type BaseFeatures = FeaturesApi & {

/** Custom priorities for more fine tuned workflows. */
customPriorities?: Priority[];

/** Inherit tasks from parent prototypes, implies tasksMatchingPriority */
inheritTasks?: boolean;
};

export type BaseOptions = OptionsApi & {
Expand Down
63 changes: 51 additions & 12 deletions test/base.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1889,18 +1889,21 @@ describe('Base', () => {
describe('getTaskNames', () => {
class TestGen extends Base {
constructor(args, options, features) {
const customPriorities = [{ priorityName: 'customPriority', before: 'prompting' }];
super(
args,
{
...options,
customPriorities: [
{
priorityName: 'customPriority',
before: 'prompting',
Array.isArray(args)
? options
: {
...options,
customPriorities,
},
],
},
features,
Array.isArray(args)
? {
...features,
customPriorities,
}
: features,
);
}

Expand All @@ -1920,12 +1923,48 @@ describe('Base', () => {
assert.deepStrictEqual(gen.getTaskNames(), ['anyMethod', 'default', 'customPriority']);
});

it('should return any public member when tasksMatchingPriority is true', async function () {
const Gen = helpers.createDummyGenerator(TestGen, {
it('should return any public member when tasksMatchingPriority is false', async function () {
const Gen = helpers.createDummyGenerator(class extends TestGen {}, {
default() {},
customPriority() {},
otherMethod() {},
});
assert.deepStrictEqual(new Gen({ env }).getTaskNames(), ['default', 'customPriority']);
assert.deepStrictEqual(new Gen({ env }).getTaskNames(), ['default', 'customPriority', 'otherMethod']);
});

it('should return only priorities tasks when tasksMatchingPriority is true', async function () {
const Gen = class extends TestGen {
constructor(args, options, features) {
super(args, options, { ...features, tasksMatchingPriority: true });
}

default() {}

customPriority() {}

otherMethod() {}
};

assert.deepStrictEqual(new Gen([], { env }).getTaskNames(), ['default', 'customPriority']);
});

it('should return only inherited tasks when inheritTasks is true', async function () {
const Gen = class extends TestGen {
constructor(args, options, features) {
super(args, options, { ...features, inheritTasks: true });
}

default() {}

initializing() {}
};

const gen = new Gen([], { env });
assert.deepStrictEqual(gen.getTaskNames(), ['default', 'customPriority', 'initializing']);
assert.strictEqual(
gen.getTaskSourcesPropertyDescriptors().default.value,
Object.getOwnPropertyDescriptor(Object.getPrototypeOf(gen), 'default')!.value,
);
});
});
});

0 comments on commit 8b1605a

Please sign in to comment.