Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented option to include empty directory #180

Merged
merged 4 commits into from
Nov 24, 2024

Conversation

iNerdStack
Copy link
Contributor

@iNerdStack iNerdStack commented Nov 24, 2024

Added the option to include empty directory, also with the config flag output.includeEmptyDirectories
I also updated test cases to cover existing changes and added new test for checking flag option

Checklist

  • Run npm run test
  • Run npm run lint

Related: #161

Copy link

stackblitz bot commented Nov 24, 2024

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

Copy link
Contributor

coderabbitai bot commented Nov 24, 2024

📝 Walkthrough

Walkthrough

The pull request introduces modifications to the configuration and functionality of the project. A new property, includeEmptyDirectories, is added to the repomix.config.json file, allowing the inclusion of empty directories in the output. Corresponding updates are made to the configuration schemas and various core functionalities, including file searching and tree generation, to accommodate this new feature. Additionally, the tests are enhanced to validate the new behavior regarding empty directories.

Changes

File Path Change Summary
repomix.config.json Added property: "includeEmptyDirectories": true in the output section. Modified formatting of showLineNumbers.
src/config/configSchema.ts Added optional property: includeEmptyDirectories: z.boolean().optional() in output object of both repomixConfigBaseSchema and repomixConfigDefaultSchema.
src/core/file/fileSearch.ts Introduced FileSearchResult interface. Updated searchFiles method to return an object containing filePaths and emptyDirPaths. Added findEmptyDirectories function for checking empty directories.
src/core/file/fileTreeGenerate.ts Updated generateFileTree and generateTreeString methods to accept emptyDirPaths parameter. Introduced addPathToTree helper function for managing file and directory additions to the tree structure.
src/core/output/outputGenerate.ts Updated buildOutputGeneratorContext to use searchFiles for retrieving empty directory paths. Modified generateTreeString function signature to include emptyDirPaths.
src/core/packager.ts Updated pack function to destructure filePaths from the result of deps.searchFiles, which now returns an object instead of an array.
tests/core/file/fileSearch.test.ts Added tests for handling empty directories when enabled and disabled. Updated existing tests to reflect the new structure of results from searchFiles.
tests/core/packager.test.ts Modified mock implementation of searchFiles to return an object with filePaths and emptyDirPaths. Updated tests to ensure correct behavior with the new structure.

Possibly related PRs


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 540a0ce and be993d8.

📒 Files selected for processing (1)
  • src/core/output/outputGenerate.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/core/output/outputGenerate.ts

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 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 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.

Copy link
Contributor

@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: 5

🧹 Outside diff range and nitpick comments (10)
repomix.config.json (1)

10-11: Configuration changes look good, consider adding documentation

The new includeEmptyDirectories option is well-placed in the output section and its default value of true makes sense for backward compatibility.

Consider updating the header text or README to document this new feature. Here's a suggested addition to the "Key Features" section:

 Key Features:
 - Configurable ignore patterns
 - Custom header text support
 - Efficient file processing and packing
+- Support for including empty directories
src/core/file/fileTreeGenerate.ts (1)

26-41: Consider adding path validation and conflict handling

While the implementation is functional, consider these improvements for robustness:

  1. Add validation for empty or invalid paths
  2. Handle path normalization (e.g., for different path separators)
  3. Add conflict detection when a path is treated as both file and directory

Example implementation:

 const addPathToTree = (root: TreeNode, path: string, isDirectory: boolean): void => {
+  if (!path) {
+    throw new Error('Path cannot be empty');
+  }
+  // Normalize path separators
+  const normalizedPath = path.replace(/[\\/]+/g, nodepath.sep);
   const parts = path.split(nodepath.sep);
   let currentNode = root;

   for (let i = 0; i < parts.length; i++) {
     const part = parts[i];
     const isLastPart = i === parts.length - 1;
     let child = currentNode.children.find((c) => c.name === part);

     if (!child) {
       child = createTreeNode(part, !isLastPart || isDirectory);
       currentNode.children.push(child);
+    } else if (isLastPart && child.isDirectory !== isDirectory) {
+      throw new Error(`Path conflict: ${path} cannot be both file and directory`);
     }

     currentNode = child;
   }
 };
src/core/output/outputGenerate.ts (1)

82-86: Consider architectural improvements for the empty directory feature

While the implementation works, consider these architectural improvements:

  1. Move the empty directory logic to a separate function for better maintainability
  2. Consider caching the search results to avoid duplicate filesystem operations
  3. Add logging for debugging purposes, especially for empty directory handling

Example structure:

async function getEmptyDirectories(rootDir: string, config: RepomixConfigMerged): Promise<string[]> {
  if (!config.output.includeEmptyDirectories) {
    return [];
  }
  
  try {
    const searchResult = await searchFiles(rootDir, config);
    return searchResult.emptyDirPaths;
  } catch (error) {
    throw new RepomixError(`Failed to search for empty directories: ${error.message}`);
  }
}
src/core/packager.ts (1)

41-41: Consider updating progress callback messages

Since we're now handling empty directories, the progress messages should reflect this.

-  progressCallback('Searching for files...');
+  progressCallback('Searching for files and directories...');
tests/core/packager.test.ts (1)

Line range hint 1-190: Consider adding specific test cases for empty directories.

While the mock implementation supports empty directories, there are no explicit test cases verifying the behavior when emptyDirPaths contains entries. Consider adding test cases to verify:

  1. Handling of empty directories when included
  2. Proper counting of empty directories in results
  3. Output generation with empty directories

Would you like me to help draft these additional test cases?

tests/core/file/fileSearch.test.ts (3)

60-65: Enhance mock implementation with stricter options checking

The current mock implementation could be more robust by validating all relevant globby options.

Consider enhancing the mock implementation:

 vi.mocked(globby).mockImplementation(async (_, options) => {
   if (options?.onlyDirectories) {
+    expect(options).toMatchObject({
+      onlyDirectories: true,
+      onlyFiles: false,
+      dot: true,
+      followSymbolicLinks: false
+    });
     return mockEmptyDirs;
   }
+  expect(options).toMatchObject({
+    onlyDirectories: false,
+    onlyFiles: true,
+    dot: true,
+    followSymbolicLinks: false
+  });
   return mockFilePaths;
 });

86-86: Improve error message clarity

The error message could be more descriptive to help developers understand the test failure.

-throw new Error('Should not search for directories when disabled');
+throw new Error('globby was called with onlyDirectories=true when includeEmptyDirectories is disabled');

49-49: Consider adding test cases for edge scenarios

The current test suite could benefit from additional coverage for:

  • Empty directories with special characters or spaces
  • Nested empty directories
  • Error handling scenarios (e.g., permission issues)

Would you like me to help generate these additional test cases?

src/core/file/fileSearch.ts (2)

38-39: Consider elevating error logging level for directory read errors

Errors encountered while reading directories are currently logged at the debug level. If a directory cannot be read due to permission issues or other errors, consider logging at a higher level (e.g., warn or error) to make users aware of potential issues during file search.

Apply this change to adjust the logging level:

-      logger.debug(`Error checking directory ${dir}:`, error);
+      logger.warn(`Error checking directory ${dir}:`, error);

87-100: Standardize error handling for directory and file searches

In the file search, permission errors are explicitly caught and re-thrown as PermissionError, providing clear feedback to the user. For consistency and better error reporting, consider applying similar error handling in the directory search when accessing directories.

Update the findEmptyDirectories function to handle permission errors:

      try {
        const entries = await fs.readdir(fullPath);
        const hasVisibleContents = entries.some((entry) => !entry.startsWith('.'));

        if (!hasVisibleContents) {
          // Existing logic...
        }
      } catch (error) {
        // Handle permission errors specifically
+       if (error.code === 'EPERM' || error.code === 'EACCES') {
+         throw new PermissionError(
+           `Permission denied while accessing directory: ${fullPath}`,
+           fullPath,
+         );
+       }
        logger.debug(`Error checking directory ${dir}:`, error);
      }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between f0401c7 and 53bb500.

📒 Files selected for processing (8)
  • repomix.config.json (1 hunks)
  • src/config/configSchema.ts (2 hunks)
  • src/core/file/fileSearch.ts (2 hunks)
  • src/core/file/fileTreeGenerate.ts (3 hunks)
  • src/core/output/outputGenerate.ts (2 hunks)
  • src/core/packager.ts (1 hunks)
  • tests/core/file/fileSearch.test.ts (3 hunks)
  • tests/core/packager.test.ts (2 hunks)
🧰 Additional context used
🪛 GitHub Check: Test (windows-latest, 22.x)
tests/core/file/fileSearch.test.ts

[failure] 72-72: tests/core/file/fileSearch.test.ts > fileSearch > getIgnoreFilePaths > should handle empty directories when enabled
AssertionError: expected [ 'empty-root', 'src/empty' ] to deeply equal [ 'src/empty', 'empty-root' ]

  • Expected
  • Received

    Array [

  • "src/empty",
    "empty-root",
  • "src/empty",
    ]

❯ tests/core/file/fileSearch.test.ts:72:36

🔇 Additional comments (14)
repomix.config.json (1)

10-11: Verify the unrelated showLineNumbers change

The addition of showLineNumbers wasn't mentioned in the PR objectives. Please confirm if this is an intentional change related to the empty directories feature.

✅ Verification successful

Let me gather more specific information about the relationship between these changes.


Based on the evidence from the shell scripts, I can now generate the final response:

The showLineNumbers change is a valid configuration update

The showLineNumbers option is a well-established feature in the codebase:

  • It's properly defined in the config schema with a default value of false
  • Has dedicated test coverage in fileProcess.test.ts for line number functionality
  • Is consistently used across test fixtures and integration tests
  • Setting it to false in the config file aligns with the default value in the schema

The change in repomix.config.json is simply making the default behavior explicit, likely for clarity, and is unrelated to the empty directories feature.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if showLineNumbers is related to includeEmptyDirectories
# Look for related changes in source files and tests

# Search for showLineNumbers usage
echo "Searching for showLineNumbers usage:"
rg -l 'showLineNumbers'

# Search for commits mentioning both features
echo -e "\nSearching for related commits:"
git log --grep="showLineNumbers\|empty.*director" --pretty=format:"%h %s"

Length of output: 851


Script:

#!/bin/bash
# Check the implementation and tests related to showLineNumbers
echo "Checking showLineNumbers implementation:"
ast-grep --pattern 'showLineNumbers' -f ts,js

# Check config schema definition
echo -e "\nChecking config schema definition:"
cat src/config/configSchema.ts

# Check test cases
echo -e "\nChecking test cases for showLineNumbers:"
rg -A 5 'showLineNumbers' tests/

Length of output: 11418

src/core/file/fileTreeGenerate.ts (4)

11-11: LGTM: Function signature properly updated

The addition of the optional emptyDirPaths parameter with a default empty array is well-typed and aligns with the feature requirements.


14-21: LGTM: Clean implementation of file and directory handling

The separate processing of files and empty directories provides clear separation of concerns and maintainable code structure.


71-74: LGTM: Clean update to generateTreeString

The function has been properly updated to support empty directories while maintaining existing behavior.


11-11: Verify updates to all callers

Since both generateFileTree and generateTreeString signatures have changed, we should verify that all callers are updated accordingly.

Also applies to: 71-71

✅ Verification successful

All callers are properly updated with the new parameter

The verification shows that both functions are called correctly with the new emptyDirPaths parameter:

  • generateFileTree is called in fileTreeGenerate.ts with both parameters: generateFileTree(files, emptyDirPaths)
  • generateTreeString is called in outputGenerate.ts with both parameters: generateTreeString(allFilePaths, emptyDirPaths)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for all calls to these functions to ensure they're updated with the new parameter
echo "Searching for generateFileTree calls:"
rg "generateFileTree\(" --type ts -A 1

echo -e "\nSearching for generateTreeString calls:"
rg "generateTreeString\(" --type ts -A 1

Length of output: 575

src/config/configSchema.ts (2)

27-27: LGTM! The schema addition is well-structured.

The new includeEmptyDirectories option is correctly implemented as an optional boolean property within the output configuration object, maintaining consistency with other similar options.


27-27: Verify configuration usage across the codebase.

Let's ensure the new configuration option is properly handled throughout the codebase.

Also applies to: 58-58

✅ Verification successful

Let me gather more specific information about how empty directories are handled in the codebase.


The new configuration option is properly implemented and handled throughout the codebase

The codebase already has complete implementation for handling empty directories:

  • fileSearch.ts collects empty directories when enabled
  • fileTreeGenerate.ts properly includes empty directories in tree generation
  • outputGenerate.ts correctly uses the configuration option
  • Test coverage exists for both enabled and disabled cases
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check usage of includeEmptyDirectories configuration option

# Find files that might need to handle the new option
echo "Files potentially needing updates for the new option:"
rg -l "output\." --type ts

# Check for potential configuration parsing
echo -e "\nConfiguration parsing implementations:"
rg "repomixConfig\w+Schema\.parse" --type ts

# Look for file operations that might need to handle empty directories
echo -e "\nFile operation implementations that might need updates:"
rg "readdir|mkdir|rmdir|Directory" --type ts

Length of output: 11221


Script:

#!/bin/bash
# Check implementation details in key files

# Check fileSearch implementation
echo "=== File Search Implementation ==="
rg -A 10 "const searchFiles" src/core/file/fileSearch.ts

# Check if empty directories are already handled
echo -e "\n=== Empty Directory Handling ==="
rg "emptyDir|empty.*director" --type ts

# Check the file tree generation logic
echo -e "\n=== File Tree Generation ==="
rg -A 10 "addPathToTree" src/core/file/fileTreeGenerate.ts

# Check test coverage for empty directories
echo -e "\n=== Test Coverage for Directory Handling ==="
rg "empty.*director|directory.*empty" tests/ --type ts

Length of output: 3704

src/core/output/outputGenerate.ts (2)

6-6: LGTM: Import added for new functionality

The import is correctly placed and necessary for the empty directory feature.


86-86: Verify tree generation with empty directories

The parameter addition looks correct, but let's verify the integration with the tree generation logic.

✅ Verification successful

Let me gather more information about the implementation and test coverage.


Let me check the implementation of the file tree generation to verify how empty directories are handled.


Tree generation with empty directories is properly implemented

The implementation correctly handles empty directories:

  • The generateTreeString function signature matches the usage, accepting files and emptyDirPaths arrays
  • Empty directories are properly added to the tree structure via addPathToTree with isDirectory=true
  • The tree generation preserves directory markers with trailing slashes
  • Test coverage confirms the feature works with both enabled and disabled empty directory configurations
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the generateTreeString implementation handles empty directories correctly

# Check the implementation of generateTreeString
ast-grep --pattern 'function generateTreeString($_: $_[], $_: $_[]) {
  $$$
}'

# Check for any test cases covering empty directory scenarios
rg -l "test.*empty.*director" --type=ts

Length of output: 157


Script:

#!/bin/bash
# Check the actual implementation of generateTreeString
rg "generateTreeString" -A 10 --type=ts

# Check the test file content for empty directory handling
cat tests/core/file/fileSearch.test.ts

Length of output: 10038


Script:

#!/bin/bash
# Check the implementation of file tree generation
cat src/core/file/fileTreeGenerate.ts

Length of output: 1937

src/core/packager.ts (1)

41-41: Verify empty directory handling in output generation

The generateOutput function needs to be checked to ensure it properly handles empty directories.

✅ Verification successful

Let me gather more information about the empty directory handling implementation.


Let me check one final piece about the file search implementation to ensure complete verification.


Empty directory handling is properly implemented

The codebase has comprehensive empty directory handling through:

  • Optional configuration via includeEmptyDirectories in the config schema
  • Implementation in fileSearch.ts using globby with onlyDirectories option
  • Dedicated findEmptyDirectories function
  • Integration in output generation that conditionally includes empty directories in the tree structure
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if generateOutput function handles empty directories

# Search for generateOutput implementation
ast-grep --pattern 'function generateOutput($$$) {
  $$$
}'

# Search for any directory-related handling in the output generation
rg -A 5 'emptyDir|directory' src/core/output/

Length of output: 773


Script:

#!/bin/bash
# Check the generateTreeString implementation and config interface
ast-grep --pattern 'function generateTreeString($$$) {
  $$$
}'

# Check the config interface for empty directory option
rg -A 3 'includeEmptyDirectories' src/

Length of output: 1168


Script:

#!/bin/bash
# Check the file search implementation for empty directories
rg -A 10 'const directories = await globby' src/core/file/fileSearch.ts

# Also check if there are any tests related to empty directory handling
rg -l 'empty.*director' test/

Length of output: 524

tests/core/packager.test.ts (1)

117-120: LGTM! Consistent mock implementation across test cases.

The mock maintains consistency with the new interface structure while preserving the security check test functionality.

tests/core/file/fileSearch.test.ts (1)

245-247: LGTM: Assertions properly handle the new FileSearchResult structure

The modifications to existing test cases correctly verify the new behavior by asserting both filePaths and emptyDirPaths.

Also applies to: 271-273

src/core/file/fileSearch.ts (2)

11-14: ⚠️ Potential issue

Confirm the impact of the new FileSearchResult interface on existing code

The introduction of the FileSearchResult interface changes the return type of searchFiles, which previously returned string[]. Please verify that all usages of searchFiles in the codebase have been updated to handle the new return type to prevent any runtime errors.

Run the following script to find all invocations of searchFiles:

✅ Verification successful

The new FileSearchResult interface changes have been properly handled

The codebase analysis shows that all usages of searchFiles have been correctly updated to handle the new return type:

  • In src/core/packager.ts: Uses destructuring to get filePaths from the result: const { filePaths } = await deps.searchFiles(rootDir, config)
  • In src/core/output/outputGenerate.ts: Correctly accesses emptyDirPaths from the result
  • In tests/core/packager.test.ts: Mock implementations and assertions are updated to use the new interface structure
  • In tests/core/file/fileSearch.test.ts: All test cases properly verify both filePaths and emptyDirPaths properties
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all function calls to 'searchFiles' to ensure they handle the new return type.

# Use 'ast-grep' to find calls to 'searchFiles' excluding its own definition
ast-grep --pattern '$CALL(searchFiles($_, $_))' --lang ts --ignore src/core/file/fileSearch.ts

Length of output: 358


Script:

#!/bin/bash
# Let's try a different approach using ripgrep to find all occurrences of 'searchFiles'
rg "searchFiles" -t ts -A 3 -B 3

Length of output: 8901


16-43: Verify handling of directories containing only hidden files

The findEmptyDirectories function considers directories containing only hidden files (e.g., files starting with .) as empty. Ensure that this behavior aligns with the intended functionality, as some users might expect such directories to be treated as non-empty.

Run the following script to list directories containing only hidden files:

src/config/configSchema.ts Show resolved Hide resolved
src/core/output/outputGenerate.ts Outdated Show resolved Hide resolved
src/core/packager.ts Show resolved Hide resolved
tests/core/packager.test.ts Show resolved Hide resolved
tests/core/file/fileSearch.test.ts Outdated Show resolved Hide resolved
Copy link

codecov bot commented Nov 24, 2024

Codecov Report

Attention: Patch coverage is 83.75000% with 13 lines in your changes missing coverage. Please review.

Project coverage is 91.63%. Comparing base (f0401c7) to head (be993d8).
Report is 5 commits behind head on main.

Files with missing lines Patch % Lines
src/core/output/outputGenerate.ts 25.00% 9 Missing ⚠️
src/core/file/fileSearch.ts 95.23% 2 Missing ⚠️
src/core/file/fileTreeGenerate.ts 91.30% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #180      +/-   ##
==========================================
- Coverage   92.07%   91.63%   -0.44%     
==========================================
  Files          35       35              
  Lines        1892     1949      +57     
  Branches      429      439      +10     
==========================================
+ Hits         1742     1786      +44     
- Misses        150      163      +13     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.


🚨 Try these New Features:

Copy link
Contributor

@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: 0

🧹 Outside diff range and nitpick comments (2)
src/core/output/outputGenerate.ts (1)

82-82: Remove commented code.

The old implementation is commented out and should be removed since it's no longer needed and is tracked in version control.

-  // const emptyDirPaths = config.output.includeEmptyDirectories ? (await searchFiles(rootDir, config)).emptyDirPaths : [];
tests/core/file/fileSearch.test.ts (1)

245-247: LGTM! Consider adding test coverage for combined scenarios.

The assertions for empty directory paths have been appropriately added to existing test cases. However, consider adding a test case that verifies the interaction between .gitignore rules and empty directory handling, such as:

  • Empty directories within ignored paths
  • Empty directories containing only ignored files

Example test case:

test('should handle empty directories with gitignore rules', async () => {
  const mockConfig = createMockConfig({
    output: {
      includeEmptyDirectories: true,
    },
    ignore: {
      useGitignore: true,
      customPatterns: [],
    },
  });

  const mockFilePaths = ['src/file1.js'];
  const mockEmptyDirs = ['src/empty', 'ignored/empty'];
  const mockGitignore = 'ignored/**';

  vi.mocked(globby).mockImplementation(async (_, options) => {
    if (options?.onlyDirectories) {
      return mockEmptyDirs;
    }
    return mockFilePaths;
  });

  vi.mocked(fs.readdir).mockResolvedValue([]);
  vi.mocked(fs.readFile).mockResolvedValue(mockGitignore);

  const result = await searchFiles('/mock/root', mockConfig);

  expect(result.filePaths).toEqual(mockFilePaths);
  expect(result.emptyDirPaths).toEqual(['src/empty']); // ignored/empty should be excluded
});

Also applies to: 271-273

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 53bb500 and 540a0ce.

📒 Files selected for processing (2)
  • src/core/output/outputGenerate.ts (2 hunks)
  • tests/core/file/fileSearch.test.ts (3 hunks)
🧰 Additional context used
🪛 GitHub Check: codecov/patch
src/core/output/outputGenerate.ts

[warning] 85-93: src/core/output/outputGenerate.ts#L85-L93
Added lines #L85 - L93 were not covered by tests

🔇 Additional comments (4)
src/core/output/outputGenerate.ts (3)

6-6: LGTM!

The import of searchFiles is correctly added and follows project conventions.


96-96: Verify function signature updates.

The generateTreeString function signature has been updated to accept empty directory paths. Let's verify that all callers have been updated accordingly.

✅ Verification successful

Function signature is consistently used across the codebase

The verification shows that:

  • The generateTreeString function is defined in src/core/file/fileTreeGenerate.ts with the signature (files: string[], emptyDirPaths: string[] = [])
  • There is only one call site in src/core/output/outputGenerate.ts which correctly passes both parameters
  • No other usages were found in the codebase
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for all calls to generateTreeString
ast-grep --pattern 'generateTreeString($_)' 

# Look for the function definition to verify signature
ast-grep --pattern 'function generateTreeString($_) {
  $$$
}'

Length of output: 110


Script:

#!/bin/bash
# Search for all calls to generateTreeString with ripgrep
rg "generateTreeString" -A 2

# Search for function definition
rg "function generateTreeString" -A 2

Length of output: 861


83-93: Add test coverage and improve error handling.

The error handling block is currently not covered by tests. Additionally, the error type assertion could be more specific.

  1. Consider using a more specific error type:
-      if (error instanceof Error) {
+      if (error instanceof RepomixError) {
         throw new RepomixError(`Failed to search for empty directories: ${error.message}`);
+      } else if (error instanceof Error) {
+        throw new RepomixError(`Unexpected error while searching empty directories: ${error.message}`);
       }
  1. Add test coverage for error scenarios:
// Test error handling
test('buildOutputGeneratorContext handles searchFiles error', async () => {
  const config = { output: { includeEmptyDirectories: true } };
  // Mock searchFiles to throw an error
  jest.spyOn(fileSearch, 'searchFiles').mockRejectedValue(new Error('Mock error'));
  
  await expect(buildOutputGeneratorContext(rootDir, config, [], [])).rejects
    .toThrow('Failed to search for empty directories: Mock error');
});

Let's verify the current test coverage:

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 85-93: src/core/output/outputGenerate.ts#L85-L93
Added lines #L85 - L93 were not covered by tests

tests/core/file/fileSearch.test.ts (1)

50-96: LGTM! Well-structured test cases for empty directory handling.

The test cases thoroughly cover both scenarios (enabled/disabled) with proper mocking and assertions. The Windows compatibility issue has been addressed by sorting arrays before comparison.

@iNerdStack iNerdStack changed the title Implemented include empty directory option Implemented option to include empty directory Nov 24, 2024
@yamadashy
Copy link
Owner

@iNerdStack
Thank you so much for your contribution!

The implementation looks perfect to me - everything works great, and I appreciate you adding the test cases as well.
The separate use of globby is particularly important for maintaining backward compatibility, so I'm very satisfied with this approach.

I'll go ahead and merge this. Thanks again!

I'll handle the release tomorrow.

@yamadashy yamadashy merged commit 0f225e7 into yamadashy:main Nov 24, 2024
43 checks passed
@iNerdStack
Copy link
Contributor Author

@yamadashy
It is a pleasure, I forgot to add the option documentation to the readme file.
I will raise a new PR to add it

Thank you

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