Skip to content

refactor: Add dynamic task support for generators and adapt Typescript file writer to a dynamic task - #484

Merged
kingston merged 3 commits into
mainfrom
kingston/eng-602-introduce-dynamic-providers
Apr 3, 2025
Merged

refactor: Add dynamic task support for generators and adapt Typescript file writer to a dynamic task#484
kingston merged 3 commits into
mainfrom
kingston/eng-602-introduce-dynamic-providers

Conversation

@kingston

@kingston kingston commented Apr 3, 2025

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • Enhanced generator functionality with dynamic task execution and phase-based processing for more flexible workflows.
  • Refactor

    • Streamlined task and metadata structures to improve dependency resolution and overall execution robustness.
  • Tests

    • Expanded test coverage to ensure reliable dynamic task handling and configuration in generator operations.

@changeset-bot

changeset-bot Bot commented Apr 3, 2025

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 55d4dff

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 11 packages
Name Type
@halfdomelabs/fastify-generators Minor
@halfdomelabs/core-generators Minor
@halfdomelabs/sync Minor
@halfdomelabs/project-builder-server Patch
@halfdomelabs/baseplate-plugin-storage Major
@halfdomelabs/react-generators Patch
@halfdomelabs/project-builder-common Patch
@halfdomelabs/project-builder-lib Patch
@halfdomelabs/project-builder-test Patch
@halfdomelabs/project-builder-cli Patch
@halfdomelabs/project-builder-web Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Apr 3, 2025

Copy link
Copy Markdown

Walkthrough

This pull request introduces dynamic task support and a restructuring of generator metadata. The changes update references from direct base directory properties to a consolidated generatorInfo object across various modules. New functions such as createTypescriptFileTask and createSetupTaskWithInfo are added, and the logger service now adds dynamic tasks using these utilities. Dependency mapping, task sorting, and runner execution logic are modified to handle dynamic tasks and the updated data structure. Several tests and utilities are updated to reflect these changes while maintaining task phase organization.

Changes

File(s) Change Summary
packages/core-generators/src/actions/copy-typescript-file-action.ts
packages/sync/src/actions/copy-directory-action.ts
packages/sync/src/actions/copy-file-action.ts
packages/sync/src/actions/write-template-action.ts
Replaced builder.generatorBaseDirectory with builder.generatorInfo.baseDirectory to access the base directory from a consolidated object.
packages/core-generators/src/generators/node/typescript/index.ts Added GeneratorTask support with new functions (createTypescriptFileTask, createSetupTaskWithInfo) and a new task phase (typescriptFileTaskPhase). Removed batch processing in favor of individual task handling.
packages/fastify-generators/src/generators/core/logger-service/index.ts Removed the direct dependency on typescriptFile and replaced it with builder.addDynamicTask(createTypescriptFileTask(...)) to incorporate dynamic task creation.
packages/sync/src/generators/build-generator-entry.ts
packages/sync/src/generators/build-generator-entry.unit.test.ts
packages/sync/src/runner/tests/factories.test-helper.ts
Restructured generator task entries to encapsulate generator metadata into a new generatorInfo object, removing flat properties such as generatorBaseDirectory and generatorName.
packages/sync/src/runner/dependency-map.ts
packages/sync/src/runner/dependency-map.unit.test.ts
packages/sync/src/runner/dependency-sort.ts
packages/sync/src/runner/dependency-sort.unit.test.ts
Updated dependency resolution and sorting functions to accept dynamic tasks and use the new generatorInfo for error messages and mapping.
packages/sync/src/runner/generator-runner.ts
packages/sync/src/runner/generator-runner.unit.test.ts
Modified generator entry execution flow to use sorted task phases and process dynamic tasks; updated error handling and test assertions accordingly.
packages/sync/src/output/generator-task-output.ts Replaced properties generatorBaseDirectory and generatorName with generatorInfo and generatorId, added a dynamicTasks array, and implemented an addDynamicTask method with validations.
packages/sync/src/runner/utils.ts
packages/sync/src/utils/create-generator.ts
packages/sync/src/utils/create-setup-task-with-info.ts
packages/sync/src/utils/index.ts
Renamed and enhanced task flattening to flattenGeneratorTaskEntriesAndPhases, introduced support for pre-registered phases in generator config, and added a new utility for creating setup tasks with descriptor information.

Sequence Diagram(s)

sequenceDiagram
    participant G as Generator
    participant B as Builder
    participant DT as DynamicTaskCreator
    participant O as OutputBuilder
    participant R as Runner

    G->>B: Initialize with generatorInfo
    B->>DT: Invoke createTypescriptFileTask / createSetupTaskWithInfo
    DT-->>B: Return dynamic task details
    B->>B: Add task via addDynamicTask(dynamicTask)
    R->>B: Retrieve sorted task phases and dynamicTasks
    R->>O: Execute tasks using updated generator metadata
Loading

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (7)
packages/fastify-generators/src/generators/core/logger-service/index.ts (1)

129-146: Good encapsulation with createTypescriptFileTask
Wrapping file creation in a dynamic task promotes modularity and keeps file concerns isolated. Consider adding additional parameters to handle edge cases, such as conflicting file names.

packages/sync/src/runner/generator-runner.ts (1)

128-128: Use of non-null assertion
Although convenient, it may hide potential runtime errors if provider is unexpectedly undefined. Consider safer null checks.

packages/core-generators/src/generators/node/typescript/index.ts (2)

149-170: Enhanced setup with descriptor-driven info.
Using createSetupTaskWithInfo to derive includeMetadata from the descriptor is a clean way to extend configuration seamlessly.

Consider adding a unit test to ensure that includeMetadata remains consistent with future descriptor changes and that no unexpected overrides break generation.


182-231: New createTypescriptFileTask logic for dynamic TypeScript file generation.

  • The structure properly delegates to the typescriptFileTaskPhase.
  • Dependencies on typescriptConfigProvider allow for easy retrieval of the compilerOptions and additional metadata.
  • The renderTsCodeFileTemplate usage is well-structured, ensuring resolution of modules and sorting of imports.

To improve error handling, you might catch or gracefully handle cases where the template might fail to render or the file cannot be written. This would provide clearer feedback without halting the entire generator.

packages/sync/src/generators/build-generator-entry.ts (1)

9-22: New GeneratorInfo interface.
It consolidates fields (name, baseDirectory, and optional instanceName) into a coherent unit for identifying generators.

Add a brief note on how instanceName is formulated or chosen, to guide implementers about the naming strategy.

packages/sync/src/utils/create-setup-task-with-info.ts (2)

18-47: CreateSetupTaskWithInfoOptions interface for descriptor-driven setup.

  • The prefix and taskName fields are flexible for naming convention control.
  • infoFromDescriptor is a strong pattern to extract dynamic config from generator definitions.

If you anticipate complex logic in infoFromDescriptor, you may want to expand JSDoc or create additional utility methods for that transformation. Let me know if you’d like help creating a specialized helper.


62-111: Implementation of createSetupTaskWithInfo.

  • Dynamically merges the schema-derived fields and custom descriptor-based info into config and output providers.
  • Cleanly returns a function that, given a descriptor, creates a generator task for the “setup” phase.

Consider supporting partial descriptors or advanced validation (e.g., advanced Zod checks) to handle large or nested descriptor objects gracefully.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Lite

📥 Commits

Reviewing files that changed from the base of the PR and between 80b9a21 and 55d4dff.

📒 Files selected for processing (23)
  • .changeset/funny-trains-arrive.md (1 hunks)
  • packages/core-generators/src/actions/copy-typescript-file-action.ts (1 hunks)
  • packages/core-generators/src/generators/node/typescript/index.ts (5 hunks)
  • packages/fastify-generators/src/generators/core/logger-service/index.ts (3 hunks)
  • packages/sync/src/actions/copy-directory-action.ts (1 hunks)
  • packages/sync/src/actions/copy-directory-action.unit.test.ts (4 hunks)
  • packages/sync/src/actions/copy-file-action.ts (1 hunks)
  • packages/sync/src/actions/write-template-action.ts (1 hunks)
  • packages/sync/src/generators/build-generator-entry.ts (5 hunks)
  • packages/sync/src/generators/build-generator-entry.unit.test.ts (2 hunks)
  • packages/sync/src/generators/generators.ts (1 hunks)
  • packages/sync/src/output/generator-task-output.ts (6 hunks)
  • packages/sync/src/runner/dependency-map.ts (8 hunks)
  • packages/sync/src/runner/dependency-map.unit.test.ts (9 hunks)
  • packages/sync/src/runner/dependency-sort.ts (1 hunks)
  • packages/sync/src/runner/dependency-sort.unit.test.ts (4 hunks)
  • packages/sync/src/runner/generator-runner.ts (6 hunks)
  • packages/sync/src/runner/generator-runner.unit.test.ts (5 hunks)
  • packages/sync/src/runner/tests/factories.test-helper.ts (1 hunks)
  • packages/sync/src/runner/utils.ts (1 hunks)
  • packages/sync/src/utils/create-generator.ts (3 hunks)
  • packages/sync/src/utils/create-setup-task-with-info.ts (1 hunks)
  • packages/sync/src/utils/index.ts (1 hunks)
🧰 Additional context used
🧬 Code Definitions (11)
packages/sync/src/generators/build-generator-entry.unit.test.ts (1)
packages/sync/src/generators/generators.ts (1)
  • ProviderExportMap (33-35)
packages/sync/src/utils/create-setup-task-with-info.ts (1)
packages/sync/src/generators/generators.ts (2)
  • GeneratorTask (132-185)
  • createGeneratorTask (187-195)
packages/sync/src/runner/utils.ts (2)
packages/sync/src/generators/build-generator-entry.ts (2)
  • GeneratorEntry (49-75)
  • GeneratorTaskEntry (27-44)
packages/sync/src/phases/types.ts (1)
  • TaskPhase (18-21)
packages/sync/src/generators/generators.ts (1)
packages/sync/src/phases/types.ts (1)
  • TaskPhase (18-21)
packages/sync/src/runner/generator-runner.ts (6)
packages/sync/src/generators/build-generator-entry.ts (2)
  • GeneratorEntry (49-75)
  • GeneratorTaskEntry (27-44)
packages/sync/src/output/generator-task-output.ts (1)
  • GeneratorOutput (96-98)
packages/sync/src/runner/utils.ts (1)
  • flattenGeneratorTaskEntriesAndPhases (26-37)
packages/sync/src/phases/sort-task-phases.ts (1)
  • sortTaskPhases (5-63)
packages/sync/src/runner/dependency-map.ts (1)
  • resolveTaskDependenciesForPhase (278-293)
packages/sync/src/runner/dependency-sort.ts (1)
  • getSortedRunSteps (20-90)
packages/sync/src/runner/dependency-map.unit.test.ts (3)
packages/sync/src/generators/build-generator-entry.ts (1)
  • GeneratorTaskEntry (27-44)
packages/sync/src/runner/dependency-map.ts (2)
  • EntryDependencyMap (194-197)
  • resolveTaskDependenciesForPhase (278-293)
packages/sync/src/runner/tests/factories.test-helper.ts (2)
  • buildTestGeneratorTaskEntry (29-50)
  • buildTestGeneratorEntry (52-86)
packages/sync/src/runner/dependency-sort.unit.test.ts (1)
packages/sync/src/runner/tests/factories.test-helper.ts (1)
  • buildTestGeneratorTaskEntry (29-50)
packages/sync/src/runner/tests/factories.test-helper.ts (2)
packages/sync/src/generators/build-generator-entry.ts (1)
  • GeneratorEntry (49-75)
packages/sync/src/generators/generators.ts (1)
  • GeneratorTask (132-185)
packages/core-generators/src/generators/node/typescript/index.ts (6)
packages/sync/src/utils/create-setup-task-with-info.ts (1)
  • createSetupTaskWithInfo (69-110)
packages/core-generators/src/renderers/typescript/templates/types.ts (1)
  • TsCodeTemplateVariableMap (7-7)
packages/sync/src/generators/generators.ts (2)
  • GeneratorTask (132-185)
  • createGeneratorTask (187-195)
packages/core-generators/src/renderers/typescript/imports/ts-path-maps.ts (2)
  • generatePathMapEntries (12-27)
  • pathMapEntriesToRegexes (46-54)
packages/core-generators/src/renderers/typescript/renderers/file.ts (1)
  • renderTsCodeFileTemplate (99-137)
packages/sync/src/utils/create-generator.ts (1)
  • createGenerator (90-116)
packages/sync/src/output/generator-task-output.ts (2)
packages/sync/src/generators/build-generator-entry.ts (2)
  • GeneratorInfo (9-22)
  • GeneratorTaskEntry (27-44)
packages/sync/src/generators/generators.ts (1)
  • GeneratorTask (132-185)
packages/sync/src/runner/dependency-map.ts (2)
packages/sync/src/generators/build-generator-entry.ts (2)
  • GeneratorEntry (49-75)
  • GeneratorTaskEntry (27-44)
packages/sync/src/phases/types.ts (1)
  • TaskPhase (18-21)
🔇 Additional comments (87)
packages/sync/src/utils/index.ts (1)

3-3: New utility export looks good

The addition of the create-setup-task-with-info.js export aligns with the PR objective of adding dynamic task support for generators. This export makes the new utilities accessible to other modules.

packages/core-generators/src/actions/copy-typescript-file-action.ts (1)

49-49: Correctly updated to use generatorInfo structure

The change from builder.generatorBaseDirectory to builder.generatorInfo.baseDirectory aligns with the refactoring to use a consolidated generatorInfo object. This ensures consistency with other changes in the PR.

.changeset/funny-trains-arrive.md (1)

1-8: Changeset correctly describes the changes

The changeset provides clear information about the scope of changes (minor versions for three packages) and accurately describes the feature addition of dynamic task support for generators and adaptation of the TypeScript file writer.

packages/sync/src/actions/write-template-action.ts (1)

20-20: Consistently updated to use generatorInfo structure

The change from builder.generatorBaseDirectory to builder.generatorInfo.baseDirectory maintains consistency with the refactoring pattern applied throughout the codebase. This change aligns with the overall objective of consolidating generator metadata.

packages/sync/src/actions/copy-file-action.ts (1)

36-36: Structural change to access base directory through generatorInfo.

This change adapts the code to access the base directory via builder.generatorInfo.baseDirectory instead of directly from builder.generatorBaseDirectory. This is consistent with the PR's objective to consolidate generator metadata.

packages/sync/src/actions/copy-directory-action.ts (1)

19-19: Structural change to access base directory through generatorInfo.

This change follows the same pattern as in copy-file-action.ts, updating the access to the base directory via the consolidated generatorInfo object instead of accessing it directly. This maintains consistency across the codebase.

packages/sync/src/generators/generators.ts (1)

232-236: Well-documented addition of preRegisteredPhases to support dynamic tasks.

The addition of the preRegisteredPhases property to the GeneratorBundle interface enhances the framework's ability to handle phases that might only contain dynamic tasks. The property is well-documented, clearly explaining its purpose.

This change aligns with the PR's objective of adding dynamic task support for generators, allowing phases to be pre-registered when they only contain dynamic tasks.

packages/sync/src/utils/create-generator.ts (4)

11-11: Added import for TaskPhase to support new preRegisteredPhases property.

The import of TaskPhase from @src/phases/types.js is necessary to support the new preRegisteredPhases property being added to the CreateGeneratorConfig interface.


33-34: Improved clarity in documentation.

The comment for the scopes property has been updated from "The scopes to export" to "The scopes that the generator encompasses," providing a clearer description of the property's purpose.


36-40: Added preRegisteredPhases property with clear documentation.

This addition of the preRegisteredPhases property to the CreateGeneratorConfig interface is well-documented, explaining that it's for phases that should be pre-registered because they only contain dynamic tasks. This aligns with the PR's objective of supporting dynamic tasks.


113-113: Correctly implemented preRegisteredPhases in the generator bundle creation.

The implementation properly passes the preRegisteredPhases from the configuration to the generated bundle, with a fallback to an empty array if none are provided. This ensures consistent behavior between the configuration and the actual generator bundle.

packages/sync/src/runner/dependency-sort.ts (1)

30-33: Property access structure updated to use generatorInfo object

The modification correctly updates the property access pattern to get generator metadata from the new generatorInfo object instead of accessing these properties directly from the entry object. This change is consistent with the PR's objective of restructuring generator metadata.

packages/sync/src/actions/copy-directory-action.unit.test.ts (3)

5-5: New import added for test helper function

The import of buildTestGeneratorTaskEntry is appropriate for the refactoring being done to standardize test setup.


16-25: Good refactoring of test setup with reusable generator task entry

Creating a reusable test generator task entry helps centralize the test setup and reduces duplication across test cases. This is a good practice that will make future maintenance easier.


32-34: Updated GeneratorTaskOutputBuilder instantiation to use new structure

The builder instantiation has been correctly updated to use the new generatorInfo object and generatorId properties from the test generator task entry, which aligns with the overall restructuring of generator metadata.

Also applies to: 52-54, 79-81

packages/sync/src/runner/dependency-sort.unit.test.ts (2)

68-70: Task properties properly moved to task object

The test entries have been correctly updated to nest properties like outputs, exports, and dependencies under a task object. This change aligns with the restructuring of the GeneratorTaskEntry interface to better support dynamic tasks.

Also applies to: 104-106, 158-159, 193-195, 215-217


74-76: Multiple task dependency structures updated consistently

All the different dependency scenarios (output providers, normal producers, read-only providers, and complex chains) have been updated with a consistent structure. This thorough refactoring ensures all test cases properly validate the functionality with the new data structure.

Also applies to: 110-112, 116-121, 163-165, 199-211

packages/sync/src/generators/build-generator-entry.unit.test.ts (2)

63-78: Generator metadata structure improved with generatorInfo object

The test expectations have been properly updated to verify the new structure where generator metadata is encapsulated in a generatorInfo object. The task structure has also been updated to include the task properties within a task object, consistent with the broader refactoring.


129-146: Nested generator entries correctly refactored

The nested generator structure with parent-child relationships has been properly updated to use the new generatorInfo object consistently across all levels of nesting. This ensures the refactored structure works correctly for complex generator hierarchies.

Also applies to: 155-170

packages/fastify-generators/src/generators/core/logger-service/index.ts (2)

8-8: Nice addition of createTypescriptFileTask import
Importing this utility aligns well with the shift to dynamic tasks for TypeScript file generation and removes unnecessary direct references.


70-70:

Details

✅ Verification successful

Removed typescriptFile parameter
Confirm all references to typescriptFile were removed or replaced properly.


🏁 Script executed:

#!/bin/bash
# Searching for any leftover references to "typescriptFile"
rg -A 3 "typescriptFile"

Length of output: 1747


Parameter Removal Verified for Logger-Service Generator
The typescriptFile parameter has been successfully removed from the logger-service generator (see packages/fastify-generators/src/generators/core/logger-service/index.ts, line 70). A global search still reveals several occurrences of "typescriptFile" in the node TypeScript generator (in packages/core-generators/src/generators/node/typescript/index.ts); however, these references are part of provider and task naming and appear to be intentional.

  • Confirmed removal in logger-service: No residual typescriptFile parameter in the run({ node, fastify }) { ... } function.
  • Node TypeScript generator: Existing typescriptFile references (e.g., typescriptFileProvider, typescriptFileTaskPhase, createTypescriptFileTask) are used for their specific purposes and do not indicate a leftover parameter issue.
packages/sync/src/runner/utils.ts (3)

26-29: Enhanced return type
Exposing both task entries and phases in one function streamlines subsequent processing.


31-35: Potential phase duplication risk
Since phases can be collected from both preRegisteredPhases and task definitions, consider deduplicating them to prevent unexpected collisions or repeated phase names.


36-36: Straightforward object return
Returning { taskEntries, phases } in a single payload is readable and extensible.

packages/sync/src/runner/generator-runner.ts (23)

1-1: New import for mapGroupBy
This import supports grouping dynamic tasks by phase below.


6-6: Added import for sortTaskPhases
Sorting is essential for handling phased execution in a predictable manner.


12-12: Updated import for GeneratorTaskEntry
Using the correct type reference clarifies the contract for generator tasks.


28-28: Importing new utility
flattenGeneratorTaskEntriesAndPhases centralizes the logic of collecting tasks and phases.


34-35: Refactored to use flattened tasks and phases
Using flattenGeneratorTaskEntriesAndPhases simplifies the code by gathering all tasks and phases at once.


36-36: Sorting the phases
Ensures that tasks within these phases are executed in the correct order.


48-51: Introducing dynamicTaskEntriesByPhase map
Maintains a clear structure for tasks registered during runtime, grouped by phase.


53-57: Iterating over [undefined, ...sortedPhases]
Captures unphased tasks first and then phases in sorted order. Verify no tasks remain stuck without an assigned phase in production code.


62-62: Passing currentDynamicTaskEntries to dependency resolution
Allows the dependency logic to account for tasks introduced dynamically.


66-66: Filtering tasks by current phase
Restricts the handling to those tasks assigned to the active phase, promoting correctness in phase-based logic.


69-74: Merging static and dynamic tasks
Combining the two sets ensures all tasks for the phase are processed consistently.


81-82: Refined destructuring
Grabbing dependencies, exports, and outputs upfront clarifies how each part of task is used.


104-104: Phase mismatch check
Prevents tasks in different phases from inadvertently connecting unless explicitly allowed.


110-110: Phase existence check
Confirms that a dependent task actually defines a phase before referencing it.


112-112: Verifying phase membership
Checking whether dependencyTask.task.phase is included in consumesOutputFrom avoids silent acceptance of cross-phase data.


116-116: Detailed error message
Explicitly referencing the phase name in the error improves diagnostic clarity.


132-133: Explicit task context
Passing taskId when running the task helps track logs and errors precisely.


166-167: Enhanced GeneratorTaskOutputBuilder context
Providing generatorInfo and generatorId ensures more accurate metadata in the resulting outputs.


199-200: Initiating dynamic task validation
This block enforces strong constraints on dynamically added tasks before they join the main pipeline.


201-225: Comprehensive checks on dynamic tasks
Rejecting duplicate IDs and requiring explicit phase relationships strengthens overall generator stability.


227-241: Grouping dynamic tasks by phase
Aggregating tasks into dynamicTaskEntriesByPhase ensures correctness in subsequent runs.


248-248: Fetching generatorInfo from tasks
Provides the correct generator context for use in error reporting and logging.


250-250: More descriptive error logging
Including generatorInfo.name in the message helps pinpoint which generator failed.

packages/core-generators/src/generators/node/typescript/index.ts (3)

3-3: Import for GeneratorTask appears correct.
This addition aligns with the new dynamic task architecture.


13-14: New imports for createSetupTaskWithInfo and createTaskPhase.
These additions seem consistent with the strategy of introducing dynamic tasks and phases.


237-239: Registering the new phase for dynamic tasks.
preRegisteredPhases: [typescriptFileTaskPhase] ensures that dynamic TypeScript tasks can be properly inserted.

packages/sync/src/generators/build-generator-entry.ts (7)

5-5: Importing GeneratorBundle and GeneratorTask.
This import is coherent with the new dynamic task usage.


24-45: Refined GeneratorTaskEntry interface.

  • The new generatorId and generatorInfo fields help track the provenance of tasks more clearly.
  • This could facilitate debugging by linking each task entry to its generator context.

66-75: generatorInfo and preRegisteredPhases added to GeneratorEntry.
Decoupling generator metadata from tasks themselves offers flexibility for future expansions.


87-95: Destructuring bundle to retrieve additional properties.
Inclusion of preRegisteredPhases here is crucial for the new dynamic task approach.


104-109: Constructing generatorInfo with prefixedName.
This approach helps ensure uniqueness by combining package name and generator name.


114-115: Assigning generatorId and generatorInfo to each task entry.
Properly links tasks to their parent generator, promoting better traceability.


167-168: Returning generatorInfo and preRegisteredPhases in the final GeneratorEntry.
This finalizes the new structure, making the entry fully dynamic-task capable.

packages/sync/src/utils/create-setup-task-with-info.ts (2)

1-17: Imports and field map definitions.
All references (createFieldMap, GeneratorTask, ProviderExportScope) are aligned with the functionality required for building a descriptor-driven setup task.


49-61: SetupTaskWithInfoResult type definition.
Returning the setup task plus the config and output providers as a tuple is a neat pattern, ensuring strong type safety for each part.

packages/sync/src/runner/tests/factories.test-helper.ts (5)

38-42: LGTM - Clean restructuring of generator metadata

The introduction of the generatorId and generatorInfo object properties makes the function more maintainable by encapsulating related metadata into a single object. This aligns with the rest of the codebase changes towards a more coherent structure for generator information.


54-57: Good type constraints for the task parameter

Using Pick with specific properties creates more precise type safety by explicitly defining which properties are expected. This helps prevent errors when calling the function and makes it clear what subset of properties is needed from GeneratorTask.


61-64: LGTM - Consistent default values

Providing default values for generatorInfo ensures the property is always defined, which reduces potential null/undefined errors when this test helper is used.


70-73: LGTM - Properly structured task ID creation

The task ID creation now includes the generator's ID and properly passes the generator info, creating a more consistent relationship between generators and their tasks.


83-83: Appropriate initialization of new preRegisteredPhases array

The addition of preRegisteredPhases as an empty array is necessary to support the dynamic task functionality introduced in this PR, as it will track phases that may only contain dynamic tasks.

packages/sync/src/runner/generator-runner.unit.test.ts (6)

76-79: LGTM - Consistent generatorInfo structure

Replacing the direct generator properties with the structured generatorInfo object keeps the code consistent with the changes in other files and improves the organization of related data.


87-90: Improved run function implementation

The updated run function now returns a more standardized object with providers and build properties, which makes the test more reflective of the actual implementation and expected behavior.


465-530: Excellent test coverage for basic dynamic tasks

This comprehensive test verifies that dynamic tasks are correctly registered, processed, and executed as part of the generator entry execution. The test provides good coverage for the happy path of dynamic task execution.


532-561: Good validation test for dynamic tasks without phases

This test correctly verifies that the system enforces the requirement for dynamic tasks to have a defined phase, which is an important constraint to ensure proper execution ordering.


563-621: LGTM - Proper duplicate name detection test

This test checks that duplicate dynamic task names are correctly identified and rejected, which is important for maintaining the consistency and predictability of the task execution pipeline.


623-698: Comprehensive test for dynamic tasks with dependencies

This test verifies the more complex case of dynamic tasks with dependencies, ensuring that dependencies are properly resolved and called. The test also includes assertions to confirm that the expected outputs are generated.

packages/sync/src/runner/dependency-map.unit.test.ts (5)

3-6: LGTM - Updated imports for GeneratorTaskEntry

Adding the GeneratorTaskEntry type import ensures proper typing for the new dynamic task functionality.


61-66: Proper function signature update for dynamic tasks

The addition of the optional dynamicTaskEntries parameter allows the function to process dynamic tasks during dependency resolution, which is key to supporting the dynamic task feature.


852-899: Good test coverage for basic dynamic task dependency resolution

This test verifies that dynamic tasks are correctly included in the dependency resolution process and that their dependencies are properly resolved from the available providers.


901-972: LGTM - Comprehensive multi-phase dynamic task testing

Testing dynamic tasks across multiple phases ensures that phased execution functions correctly with dynamic tasks, which is important for complex generator workflows.


974-1030: Excellent test for parent scope dependency resolution

This test verifies that dynamic tasks can correctly resolve dependencies from parent scopes, which is crucial for maintaining the expected inheritance behavior when using dynamic tasks.

packages/sync/src/output/generator-task-output.ts (6)

4-8: LGTM - Comprehensive type imports

Adding imports for GeneratorInfo, GeneratorTask, and GeneratorTaskEntry ensures proper typing for the new dynamic task functionality and improved code organization.


100-109: Good interface redesign for better data organization

The interface now uses generatorInfo and generatorId properties which better encapsulate related data and improve the API's structure and clarity.


122-134: LGTM - Well-structured class properties

The class properties now match the updated interface, with the addition of the dynamicTasks array to store dynamic tasks. This provides a consistent and organized data structure.


142-143: Proper initialization of new properties

The constructor correctly initializes the new properties from the context, ensuring the class is ready to use.


154-154: Consistent usage of generatorInfo properties

The methods now access the base directory and name through the generatorInfo object, maintaining consistency with the new structure.

Also applies to: 191-191


252-270: Excellent implementation of addDynamicTask method

The addDynamicTask method is well-implemented with proper validation to ensure:

  1. No duplicate task names
  2. Each task must have a phase

The method then creates a properly structured task entry with all required properties. This is a key addition that enables dynamic task functionality.

packages/sync/src/runner/dependency-map.ts (6)

42-45: Improved task iteration with nullish coalescing

The code now uses taskEntry object structure with nullish coalescing for both exports and outputs. This enhances robustness by safely handling cases where these properties might be undefined.


51-54: Fixed error reporting and provider mapping

Error messages now reference taskEntry.id instead of task.id, and the providers map now uses taskEntry.id. This correctly identifies tasks in error messages and ensures proper provider mapping with the new data structure.

Also applies to: 61-64, 98-98


137-137: Added null safety for dependencies

The nullish coalescing operator ensures that dependencies default to an empty object when undefined, preventing potential runtime errors when accessing properties of an undefined object.


164-164: Updated error message to use generatorInfo

Error messages now reference entry.generatorInfo.name instead of the previous entry.generatorName, which aligns with the new structure for storing generator metadata.

Also applies to: 172-174


214-214:

Details

✅ Verification successful

Added support for dynamic tasks

The implementation now merges dynamic tasks with existing tasks, filtering them based on the task phase. This is a key part of supporting dynamic tasks in the dependency resolution system.

Also applies to: 219-222


🏁 Script executed:

#!/bin/bash
# Check for usages of dynamicTaskEntries throughout the codebase
echo "Checking usages of dynamicTaskEntries..."
rg "dynamicTaskEntries" --type ts

Length of output: 1721


Dynamic tasks merging and filtering is confirmed as working correctly.
I've verified that the new implementation for dynamic tasks—declaring and using the dynamicTaskEntries property—is consistently applied across the codebase (e.g., in dependency-map.ts and generator-runner.ts). The merging of dynamic tasks with existing tasks based on the task phase is evident, and the usage aligns with the feature support described in the review comment. No additional removals or replacements were required.


242-242:

Details

✅ Verification successful

Updated function signatures to support dynamic tasks

The signatures of buildEntryDependencyMapRecursive and resolveTaskDependenciesForPhase functions have been updated to include the dynamicTaskEntries parameter, allowing the dependency resolution system to handle dynamically created tasks.

Also applies to: 282-291


🏁 Script executed:

#!/bin/bash
# Check for calls to resolveTaskDependenciesForPhase with the new parameter
echo "Checking calls to resolveTaskDependenciesForPhase..."
rg "resolveTaskDependenciesForPhase\(" -A 5 --type ts

Length of output: 1563


Dynamic Task Parameter Update Verified

The updated function signatures correctly include the dynamicTaskEntries parameter. Our verification confirms:

  • packages/sync/src/runner/dependency-map.ts: The snippet at line 242 now shows the added dynamicTaskEntries, property, along with the updated signature for resolveTaskDependenciesForPhase (also reflected at lines 282-291).
  • packages/sync/src/runner/generator-runner.ts & packages/sync/src/runner/dependency-map.unit.test.ts: All calls to resolveTaskDependenciesForPhase are updated to pass the dynamic task entries parameter as required.

These changes ensure the dependency resolution system now supports dynamically created tasks, and the updates have been applied consistently across the codebase.

@kingston
kingston merged commit 014b140 into main Apr 3, 2025
@kingston
kingston deleted the kingston/eng-602-introduce-dynamic-providers branch April 3, 2025 22:19
@github-actions github-actions Bot mentioned this pull request Apr 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant