Skip to content

Conversation

@Kartikayy007
Copy link
Contributor

@Kartikayy007 Kartikayy007 commented Nov 29, 2025

Description

Add generateOnly filtering on final output paths for all template writes/copies, with negated globs supported and copy paths filtered.

  • Added centralized filtering helpers (writeFileWithFiltering/copyFileWithFiltering) applying generateOnly (with negation) and noOverwriteGlobs on final output paths for all template writes and copies.
  • React rendering now filters after metadata.fileName renames via the shared helper; Nunjucks writes use the helper, copy path is filtered.

Known

Hooks/conditional dirs remain ungated by generateOnly (extra files like asyncapi.yaml still appear) needs to be worked

Test are failing and needs to be fixed

Summary by CodeRabbit

Release Notes

  • New Features
    • Added --generate-only CLI option (short form -g) to selectively generate files matching glob patterns
    • Supports negation patterns (prefixed with !) for excluding specific files
    • Integrates with existing file protection options for combined filtering control
    • Displays warning when specified patterns match no files

✏️ Tip: You can customize this high-level summary in your review settings.

@changeset-bot
Copy link

changeset-bot bot commented Nov 29, 2025

⚠️ No Changeset found

Latest commit: e4d9a09

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@coderabbitai
Copy link

coderabbitai bot commented Nov 29, 2025

Walkthrough

This PR introduces a --generate-only CLI option that accepts glob patterns to limit code generation to specific files. It adds filtering utilities, updates the generator constructor to accept and process generateOnly patterns, modifies file writing operations to respect the filter, and includes logging messages and test coverage for the new feature.

Changes

Cohort / File(s) Summary
CLI Interface
apps/generator/cli.js
Added --generate-only (alias -g) CLI option that accepts glob patterns; creates accumulator and parser to collect patterns into an array passed to Generator configuration.
Core Generator Logic
apps/generator/lib/generator.js
Updated constructor to accept generateOnly parameter; added generatedFilesCount property to track file generation; replaced direct file writes with filtered equivalents; added warnIfNoGenerateOnlyMatches() method to alert when no files match patterns.
Logging Messages
apps/generator/lib/logMessages.js
Added two new log message helpers: skipGenerateOnly(filePath) for skipped files and generateOnlyNoMatches(patterns) for unmatched patterns.
File Filtering Utilities
apps/generator/lib/utils.js
Added minimatch dependency; introduced isAllowedByGenerateOnly() helper supporting negation patterns; added shouldSkipOverwrite() helper; created writeFileWithFiltering() and copyFileWithFiltering() public functions that gate operations by generateOnly whitelist then noOverwriteGlobs blacklist.
React Renderer
apps/generator/lib/renderer/react.js
Updated saveRenderedReactContent() and saveContentToFile() signatures to accept generateOnly and targetDir parameters; replaced direct file writes with writeFileWithFiltering() calls; changed return value to numeric count of written files.
Unit & Integration Tests
apps/generator/test/generator.test.js, apps/generator/test/integration.test.js, apps/generator/test/renderer.test.js, apps/generator/test/utils.test.js
Added tests for generateOnly property and warnIfNoGenerateOnlyMatches() method; added integration tests for exact file matching, glob patterns, and combined generateOnly/noOverwriteGlobs scenarios; updated renderer tests to mock writeFileWithFiltering; added comprehensive filtering utility tests.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Filtering logic in apps/generator/lib/utils.js: Verify negation pattern handling (patterns prefixed with !), minimatch integration, and correct precedence (generateOnly applied before noOverwriteGlobs).
  • Integration across layers: Confirm parameter propagation from CLI → Generator → utilities → renderer and that relative path calculations are consistent.
  • File writing flow changes: Review all writeFileWithFiltering() and copyFileWithFiltering() call sites to ensure proper targetDir context and option passing.
  • Test coverage completeness: Validate that new integration tests cover edge cases like empty generateOnly arrays, conflicting patterns, and interaction with existing noOverwriteGlobs.

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding generateOnly filtering on final paths with support for a new test template feature.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@asyncapi-bot
Copy link
Contributor

What reviewer looks at during PR review

The following are ideal points maintainers look for during review. Reviewing these points yourself beforehand can help streamline the review process and reduce time to merge.

  1. PR Title: Use a concise title that follows our Conventional Commits guidelines and clearly summarizes the change using imperative mood (it means spoken or written as if giving a command or instruction, like "add new helper for listing operations")

    Note - In Generator, prepend feat: or fix: in PR title only when PATCH/MINOR release must be triggered.

  2. PR Description: Clearly explain the issue being solved, summarize the changes made, and mention the related issue.

    Note - In Generator, we use Maintainers Work board to track progress. Ensure the PR Description includes Resolves #<issue-number> or Fixes #<issue-number> this will automatically close the linked issue when the PR is merged and helps automate the maintainers workflow.

  3. Documentation: Update the relevant Generator documentation to accurately reflect the changes introduced in the PR, ensuring users and contributors have up-to-date guidance.

  4. Comments and JSDoc: Write clear and consistent JSDoc comments for functions, including parameter types, return values, and error conditions, so others can easily understand and use the code.

  5. DRY Code: Ensure the code follows the Don't Repeat Yourself principle. Look out for duplicate logic that can be reused.

  6. Test Coverage: Ensure the new code is well-tested with meaningful test cases that pass consistently and cover all relevant edge cases.

  7. Commit History: Contributors should avoid force-pushing as much as possible. It makes it harder to track incremental changes and review the latest updates.

  8. Template Design Principles Alignment: While reviewing template-related changes in the packages/ directory, ensure they align with the Assumptions and Principles. If any principle feels outdated or no longer applicable, start a discussion these principles are meant to evolve with the project.

  9. Reduce Scope When Needed: If an issue or PR feels too large or complex, consider splitting it and creating follow-up issues. Smaller, focused PRs are easier to review and merge.

  10. Bot Comments: As reviewers, check that contributors have appropriately addressed comments or suggestions made by automated bots. If there are bot comments the reviewer disagrees with, react to them or mark them as resolved, so the review history remains clear and accurate.

@Kartikayy007 Kartikayy007 changed the title Add generateOnly filtering on final paths and new test template feat: add generateOnly filtering on final paths and new test template Nov 29, 2025
@sonarqubecloud
Copy link

@Kartikayy007 Kartikayy007 marked this pull request as ready for review December 2, 2025 10:08
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0dc9f60 and e4d9a09.

⛔ Files ignored due to path filters (2)
  • .github/workflows/scripts/mailchimp/package-lock.json is excluded by !**/package-lock.json
  • apps/generator/test/test-templates/react-template/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (9)
  • apps/generator/cli.js (4 hunks)
  • apps/generator/lib/generator.js (11 hunks)
  • apps/generator/lib/logMessages.js (2 hunks)
  • apps/generator/lib/renderer/react.js (4 hunks)
  • apps/generator/lib/utils.js (2 hunks)
  • apps/generator/test/generator.test.js (4 hunks)
  • apps/generator/test/integration.test.js (1 hunks)
  • apps/generator/test/renderer.test.js (3 hunks)
  • apps/generator/test/utils.test.js (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
apps/generator/lib/generator.js (1)
apps/generator/lib/renderer/react.js (1)
  • written (86-93)
apps/generator/test/renderer.test.js (2)
apps/generator/lib/renderer/react.js (2)
  • written (86-93)
  • content (70-70)
apps/generator/lib/utils.js (1)
  • util (2-2)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Acceptance tests for generated templates
  • GitHub Check: Test generator as dependency with Node 20
  • GitHub Check: Test generator as dependency with Node 18
  • GitHub Check: Test NodeJS PR - ubuntu-latest
  • GitHub Check: Test NodeJS PR - windows-latest
  • GitHub Check: Test NodeJS PR - macos-latest
🔇 Additional comments (35)
apps/generator/lib/logMessages.js (2)

44-50: LGTM! New log message helpers are consistent with existing patterns.

The new skipGenerateOnly and generateOnlyNoMatches functions follow the established conventions in this file.


80-82: LGTM! Exports updated correctly.

The new message helpers are properly exported alongside existing functions.

apps/generator/lib/utils.js (5)

10-10: LGTM! Minimatch dependency added for glob pattern matching.


62-73: LGTM! Clean implementation of overwrite skip logic.

The function correctly checks file existence first and only applies glob matching when needed.


86-102: LGTM! Well-structured file writing with filtering.

The function properly:

  1. Calculates the relative path for glob matching
  2. Applies generateOnly filter first
  3. Then checks noOverwriteGlobs for existing files
  4. Returns a boolean indicating success

114-130: LGTM! Copy filtering mirrors write filtering correctly.

The implementation is consistent with writeFileWithFiltering and correctly uses targetPath for the relative path calculation.


42-60: Verify negation-only pattern behavior is documented.

The function requires at least one positive pattern for any file to be allowed; providing only negation patterns like ['!test*.js'] will exclude nothing because allowed never becomes true. If this whitelist semantic is intentional, ensure it's clearly documented in code comments or external documentation to prevent user confusion.

apps/generator/test/utils.test.js (4)

129-144: LGTM! Test setup is well-structured.

The test suite properly mocks dependencies and clears them after each test.


145-214: LGTM! Comprehensive generateOnly filtering tests.

Good coverage of:

  • Empty/unset generateOnly (allows all)
  • Single and multiple pattern matching
  • Negated patterns
  • Complex glob patterns
  • Proper logging verification

216-247: LGTM! noOverwriteGlobs tests cover key scenarios.

Tests correctly verify:

  • Skipping existing files that match
  • Allowing new files even when matching noOverwriteGlobs
  • Overwriting existing files that don't match

282-290: LGTM! File options passthrough test.

Verifies that file mode options are correctly forwarded to the underlying writeFile call.

apps/generator/test/renderer.test.js (3)

2-6: LGTM! Mock updated to use the new filtering utility.

The mock correctly simulates writeFileWithFiltering returning true for successful writes.


41-44: LGTM! Test correctly verifies single content writing.

The test validates that saveRenderedReactContent returns the count of written files (1 for single content).


62-65: LGTM! Test correctly verifies multiple content writing.

The test validates aggregation of written file counts (2 for two contents).

apps/generator/test/integration.test.js (3)

157-176: LGTM! Integration test for exact file matching.

The test correctly verifies that only package.json is generated when specified in generateOnly, and test-file.md is excluded.


178-197: LGTM! Integration test for glob pattern matching.

Good coverage of glob-based filtering with *.json pattern.


199-223: LGTM! Integration test for combined generateOnly and noOverwriteGlobs.

The test correctly validates that:

  1. Pre-existing package.json content is preserved (noOverwriteGlobs)
  2. test-file.md is not generated (generateOnly filters it out)
apps/generator/test/generator.test.js (3)

25-25: LGTM! Default value test for generateOnly.

Verifies that generateOnly defaults to an empty array when not provided.


38-38: LGTM! Constructor test for generateOnly option.

Verifies that generateOnly is correctly set from constructor options.

Also applies to: 52-52


112-134: LGTM! Tests for warnIfNoGenerateOnlyMatches method.

Good coverage of warning behavior:

  • Warns when generateOnly is set but no files were generated
  • Does not warn when files were successfully generated
apps/generator/lib/renderer/react.js (4)

5-7: LGTM! Import updated for new filtering utility.


86-95: LGTM! Properly delegates to filtering utility.

The implementation correctly:

  1. Uses writeFileWithFiltering with all necessary parameters
  2. Returns 1 for successful writes, 0 for skipped files

109-113: LGTM! Correct aggregation of write results.

The Promise.all with reduce correctly accumulates the count of successfully written files. The (val || 0) handles any potential undefined/falsy values defensively.


66-66: Verify that all callers of saveContentToFile explicitly pass targetDir.

The default value targetDir = process.cwd() may not match the actual generator target directory if callers do not explicitly provide this parameter. Review all invocations in generator.js to ensure they pass the correct targetDir value rather than relying on the default.

apps/generator/cli.js (4)

22-22: LGTM! Consistent accumulator pattern.

The generateOnly array follows the same pattern as noOverwriteGlobs, providing a clean way to accumulate multiple CLI arguments.


37-37: LGTM! Parser follows established pattern.

The parser implementation is consistent with noOverwriteParser and correctly accumulates glob patterns into the array.


92-92: LGTM! Well-documented CLI option.

The option declaration is clear, properly documented, and follows Commander.js conventions. The description effectively communicates the filtering behavior to users.


160-160: Verify negation pattern support works as expected.

The integration of generateOnly looks correct and follows the established pattern for passing options to the Generator. However, since the PR description mentions "supporting negated globs", please verify that negation patterns (e.g., !*.test.js) work correctly in practice.

apps/generator/lib/generator.js (7)

26-28: LGTM! Necessary imports for filtering functionality.

The new filtering-aware write and copy utilities are properly imported alongside their non-filtering counterparts.


51-51: LGTM! Good optimization with Set conversion.

Converting GENERATOR_OPTIONS to a Set improves lookup performance from O(n) to O(1), and generateOnly is correctly included in the valid options list.


83-83: LGTM! Well-documented constructor additions.

The generateOnly parameter is properly documented, integrated into the constructor signature with appropriate defaults, and initialized as a public property following the same pattern as noOverwriteGlobs.

Also applies to: 97-97, 115-116


133-134: LGTM! Well-integrated counter and validation logic.

The file counter tracking is properly initialized, reset at the start of each generation, and used to provide feedback via the warning method. The validation correctly uses the Set's has() method for option checking.

Also applies to: 163-163, 202-202, 210-210


889-896: LGTM! Filtering properly integrated into rendering.

Both React and non-React rendering paths correctly apply filtering and track generated files. The different counting approaches (count vs. boolean) appropriately reflect that React templates can generate multiple files from a single render.


963-969: LGTM! Copy operations now respect filtering.

Non-renderable files are now properly filtered using copyFileWithFiltering, and the counter is correctly incremented when files are actually copied. This ensures consistent filtering behavior across all file generation operations.


1039-1049: LGTM! Helpful user feedback when patterns don't match.

The warning method provides valuable feedback when generateOnly patterns are specified but no files are generated. The guard for output === 'fs' is correct, as string output mode doesn't involve file generation.

Comment on lines +271 to +279
it('writes file that matches generateOnly and does not match noOverwriteGlobs', async () => {
const jsonFilePath = path.join(targetDir, 'tsconfig.json');
utils.exists = jest.fn().mockResolvedValue(true);

const result = await utils.writeFileWithFiltering(jsonFilePath, testContent, {}, targetDir, ['package.json'], ['*.json']);

expect(result).toBe(true);
expect(utils.writeFile).toHaveBeenCalledWith(jsonFilePath, testContent, {});
});
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Test expectation appears incorrect.

The test expects tsconfig.json to be written when generateOnly: ['package.json'], but tsconfig.json doesn't match the pattern package.json. This should return false and skip writing.

Either the test expectation is wrong, or the generateOnly pattern should be ['*.json'] to match tsconfig.json.

-    it('writes file that matches generateOnly and does not match noOverwriteGlobs', async () => {
-      const jsonFilePath = path.join(targetDir, 'tsconfig.json');
+    it('writes file that matches generateOnly and does not match noOverwriteGlobs', async () => {
+      const jsonFilePath = path.join(targetDir, 'config.json');
       utils.exists = jest.fn().mockResolvedValue(true);

-      const result = await utils.writeFileWithFiltering(jsonFilePath, testContent, {}, targetDir, ['package.json'], ['*.json']);
+      const result = await utils.writeFileWithFiltering(jsonFilePath, testContent, {}, targetDir, ['*.json'], ['package.json']);

-      expect(result).toBe(true);
-      expect(utils.writeFile).toHaveBeenCalledWith(jsonFilePath, testContent, {});
+      expect(result).toBe(true);
+      expect(utils.writeFile).toHaveBeenCalledWith(jsonFilePath, testContent, {});
     });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
it('writes file that matches generateOnly and does not match noOverwriteGlobs', async () => {
const jsonFilePath = path.join(targetDir, 'tsconfig.json');
utils.exists = jest.fn().mockResolvedValue(true);
const result = await utils.writeFileWithFiltering(jsonFilePath, testContent, {}, targetDir, ['package.json'], ['*.json']);
expect(result).toBe(true);
expect(utils.writeFile).toHaveBeenCalledWith(jsonFilePath, testContent, {});
});
it('writes file that matches generateOnly and does not match noOverwriteGlobs', async () => {
const jsonFilePath = path.join(targetDir, 'config.json');
utils.exists = jest.fn().mockResolvedValue(true);
const result = await utils.writeFileWithFiltering(jsonFilePath, testContent, {}, targetDir, ['*.json'], ['package.json']);
expect(result).toBe(true);
expect(utils.writeFile).toHaveBeenCalledWith(jsonFilePath, testContent, {});
});
🤖 Prompt for AI Agents
In apps/generator/test/utils.test.js around lines 271-279, the test currently
asserts that tsconfig.json is written even though generateOnly is
['package.json'] which doesn't match tsconfig.json; update the test to reflect
correct behavior by keeping generateOnly as ['package.json'] and changing
assertions to expect the function to return false and that utils.writeFile was
NOT called (i.e., expect(result).toBe(false);
expect(utils.writeFile).not.toHaveBeenCalled()); ensure the utils.exists mock
remains as-is so the skip behavior is exercised.

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.

2 participants