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

breaking: upgrade chokidar v4 #237

Merged
merged 2 commits into from
Oct 11, 2024
Merged

breaking: upgrade chokidar v4 #237

merged 2 commits into from
Oct 11, 2024

Conversation

zce
Copy link
Owner

@zce zce commented Oct 11, 2024

Summary by Sourcery

Upgrade chokidar to version 4, refactor pattern matching logic using a new utility function, and update timestamp handling to default to the current date when git log does not provide a date. Update dependencies and documentation to reflect these changes.

New Features:

  • Introduce a new utility function matchPatterns in src/utils.ts to handle pattern matching with support for negated patterns.

Enhancements:

  • Refactor the file watching logic in src/build.ts to use the new matchPatterns utility for improved pattern matching.
  • Update the timestamp logic in multiple files to handle cases where git log does not return a date, defaulting to the current date.

Build:

  • Upgrade chokidar to version 4.0.1, which requires Node.js version 14.16.0 or higher.
  • Replace micromatch with picomatch for pattern matching, updating dependencies accordingly.

Documentation:

  • Update documentation in docs/guide/last-modified.md and docs/other/snippets.md to reflect changes in timestamp handling.

Summary by CodeRabbit

  • New Features

    • Introduced a new utility function for pattern matching, enhancing file handling capabilities.
    • Updated timestamp retrieval logic to ensure valid date returns even when Git commands yield no results.
  • Bug Fixes

    • Improved robustness of timestamp handling by adding fallback to the current date if necessary.
  • Chores

    • Updated project dependencies for improved performance and compatibility.

Copy link

sourcery-ai bot commented Oct 11, 2024

Reviewer's Guide by Sourcery

This pull request upgrades the chokidar dependency to version 4, replaces micromatch with picomatch, and updates the file watching logic in the build process. It also includes minor changes to timestamp handling and adds a new utility function for pattern matching.

No diagrams generated as the changes look simple and do not need a visual representation.

File-Level Changes

Change Details Files
Upgrade chokidar to version 4 and replace micromatch with picomatch
  • Update chokidar from v3.6.0 to v4.0.1
  • Remove @types/micromatch dependency
  • Add @types/picomatch dependency
  • Replace micromatch with picomatch in dependencies
  • Update related package versions in pnpm-lock.yaml
pnpm-lock.yaml
Refactor file watching logic in build process
  • Update watch patterns to include '.' and configImports
  • Remove directory change handling
  • Implement new matchPatterns function for file matching
  • Update file change detection logic
src/build.ts
Add new utility function for pattern matching
  • Create matchPatterns function using picomatch
  • Handle both normal and negated patterns
  • Normalize input paths for consistent matching
src/utils.ts
Update timestamp handling in various files
  • Add fallback to current timestamp when git log command returns empty
  • Update timestamp function in multiple configuration files
docs/guide/last-modified.md
docs/other/snippets.md
examples/basic/velite.config.js
examples/nextjs/velite.config.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time. You can also use
    this command to specify where the summary should be inserted.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

coderabbitai bot commented Oct 11, 2024

Walkthrough

The pull request introduces several modifications focused on enhancing the handling of timestamps in the project. Key changes include updates to the timestamp schema to ensure valid date returns, adjustments in the package.json to replace dependencies, and the introduction of a new utility function for pattern matching. The changes also include a test suite for the new utility function, ensuring its functionality through various scenarios.

Changes

File Change Summary
docs/guide/last-modified.md Updated timestamp schema return logic to fallback to current date if stdout is empty.
docs/other/snippets.md Modified timestamp schema return logic to fallback to current date if stdout is empty.
examples/basic/velite.config.js Altered timestamp function return logic to include a fallback to current date if stdout is empty.
examples/nextjs/velite.config.ts Changed timestamp function return logic to fallback to current date if stdout is empty.
package.json Removed @types/micromatch, added @types/picomatch, updated chokidar version, removed micromatch, and added picomatch.
src/build.ts Removed micromatch import, replaced with matchPatterns, updated logic for file handling and pattern matching in resolve and watch functions.
src/utils.ts Introduced matchPatterns function to categorize input strings against normal and negated patterns using picomatch.
test/utils.ts Added a test suite for the matchPatterns function to validate its functionality through various scenarios.

Possibly related PRs

  • docs: improvements #201: The changes in docs/guide/last-modified.md and docs/other/snippets.md regarding the timestamp function are directly related to the modifications made in the main PR, as both involve updates to the return statement of the timestamp schema to ensure a valid date is always returned.

🐰 In the code, I hop and play,
With timestamps bright as day.
If Git's stdout goes astray,
Current time will save the way!
Patterns matched, all neat and fine,
In this code, our joy will shine! 🌟


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

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey @zce - I've reviewed your changes and they look great!

Here's what I looked at during the review
  • 🟢 General issues: all looks good
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟡 Complexity: 1 issue found
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

import { relative } from 'node:path'
import pm from 'picomatch'

export const matchPatterns = (input: string, patterns: string | string[], base?: string) => {
Copy link

Choose a reason for hiding this comment

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

issue (complexity): Consider refactoring the matchPatterns function into smaller, focused functions to improve code organization and maintainability.

The matchPatterns function introduces unnecessary complexity by handling multiple concerns in a single function. Here's a suggestion to simplify and improve the code:

  1. Split the function into smaller, focused functions:
import { relative } from 'node:path'
import pm from 'picomatch'

const normalizeInput = (input: string, base?: string): string => {
  if (base != null) {
    input = relative(base, input).replace(/^\.[\\/]/, '')
  }
  return input.replaceAll('\\', '/')
}

const separatePatterns = (patterns: string | string[]): { normal: string[], negated: string[] } => {
  const list = Array.isArray(patterns) ? patterns : [patterns]
  return list.reduce((acc, p) => {
    acc[p.startsWith('!') ? 'negated' : 'normal'].push(p)
    return acc
  }, { normal: [] as string[], negated: [] as string[] })
}

export const matchPatterns = (input: string, patterns: string | string[], base?: string): boolean => {
  const normalizedInput = normalizeInput(input, base)
  const { normal, negated } = separatePatterns(patterns)
  return normal.some(i => pm(i)(normalizedInput)) && negated.every(i => pm(i)(normalizedInput))
}
  1. Consider using simpler array methods instead of reduce for pattern separation:
const separatePatterns = (patterns: string | string[]): { normal: string[], negated: string[] } => {
  const list = Array.isArray(patterns) ? patterns : [patterns]
  return {
    normal: list.filter(p => !p.startsWith('!')),
    negated: list.filter(p => p.startsWith('!')).map(p => p.slice(1))
  }
}
  1. For future extensions, consider creating separate utility functions instead of adding more complexity to matchPatterns. This will help maintain the single responsibility principle and prevent this file from becoming a catch-all for string matching utilities.

These changes improve readability, maintainability, and adhere better to the single responsibility principle while preserving the original functionality.

awaitWriteFinish: { stabilityThreshold: 50, pollInterval: 10 }
}).on('all', async (event, filename) => {
if (event === 'addDir' || event === 'unlinkDir') return // ignore dir changes
if (event === 'addDir' || event === 'unlinkDir') return
Copy link

Choose a reason for hiding this comment

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

suggestion (code-quality): Use block braces for ifs, whiles, etc. (use-braces)

Suggested change
if (event === 'addDir' || event === 'unlinkDir') return
if (event === 'addDir' || event === 'unlinkDir') {


ExplanationIt is recommended to always use braces and create explicit statement blocks.

Using the allowed syntax to just write a single statement can lead to very confusing
situations, especially where subsequently a developer might add another statement
while forgetting to add the braces (meaning that this wouldn't be included in the condition).

logger.info('velite config changed, restarting...')
watcher.close()
return build({ config: config.configPath, clean: false, watch: true })
}

// skip if filename not match any collection pattern
if (!matchPatterns(filename, patterns)) return
Copy link

Choose a reason for hiding this comment

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

suggestion (code-quality): Use block braces for ifs, whiles, etc. (use-braces)

Suggested change
if (!matchPatterns(filename, patterns)) return
if (!matchPatterns(filename, patterns)) {


ExplanationIt is recommended to always use braces and create explicit statement blocks.

Using the allowed syntax to just write a single statement can lead to very confusing
situations, especially where subsequently a developer might add another statement
while forgetting to add the braces (meaning that this wouldn't be included in the condition).


// remove changed file cache
for (const [key, value] of config.cache.entries()) {
if (value === fullpath) config.cache.delete(key)
Copy link

Choose a reason for hiding this comment

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

suggestion (code-quality): Use block braces for ifs, whiles, etc. (use-braces)

Suggested change
if (value === fullpath) config.cache.delete(key)
if (value === fullpath) {


ExplanationIt is recommended to always use braces and create explicit statement blocks.

Using the allowed syntax to just write a single statement can lead to very confusing
situations, especially where subsequently a developer might add another statement
while forgetting to add the braces (meaning that this wouldn't be included in the condition).

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: 3

🧹 Outside diff range and nitpick comments (9)
src/utils.ts (3)

5-7: LGTM: Good handling of input patterns. Consider creating an issue for the TODO.

The array initialization ensures uniform handling of both string and string[] inputs, which is a good practice. The TODO comment about using groupBy in the future is a good reminder for potential optimization.

Would you like me to create a GitHub issue to track the TODO for implementing groupBy in the future?


16-20: LGTM: Path handling looks good. Consider using optional chaining.

The path handling logic is correct and necessary for consistent matching across different systems. A minor suggestion would be to use optional chaining for a more concise check.

Consider updating the condition:

if (base != null) {
  input = relative(base, input).replace(/^\.[\\/]/, '')
}

to:

input = base ? relative(base, input).replace(/^\.[\\/]/, '') : input

This change eliminates the need for a separate if block, making the code slightly more concise.


22-23: LGTM: Efficient pattern matching logic. Consider adding a comment for clarity.

The pattern matching logic using picomatch is correct and efficient. The use of some and every is a good way to implement the matching logic.

For improved readability, especially for developers who might not be familiar with picomatch, consider adding a brief comment explaining the logic:

// Match if the input matches any normal pattern and doesn't match any negated pattern
return normal.some(i => pm(i)(input)) && negated.every(i => !pm(i)(input));

Also, note that the negated patterns should use !pm(i)(input) instead of pm(i)(input) to correctly implement the negation.

test/utils.ts (2)

6-6: Consider simplifying the describe function.

The describe function is currently defined as an async function with an unused parameter t. Since there are no async operations at this level, you can simplify it.

Consider changing the line to:

describe('matchPatterns function', () => {

7-20: Consider enhancing test case naming and coverage.

While the current test cases are good, consider the following improvements:

  1. Use more descriptive names for test cases. For example:

    it('matches a single pattern correctly', () => {...})
    it('handles multiple patterns as expected', () => {...})
    it('correctly applies negated patterns', () => {...})
  2. Add more edge cases to improve coverage:

    • Test with an empty pattern array
    • Test with conflicting patterns (e.g., ['**/*.js', '!**/*.js'])
    • Test with a file path containing special characters
  3. Consider using test.each for parameterized tests to reduce duplication.

Would you like me to provide examples for these additional test cases?

docs/guide/last-modified.md (1)

60-60: Approve change with suggestion for error logging

The modification to use Date.now() as a fallback is a good defensive programming practice. It ensures that a valid timestamp is always returned, even if the Git command fails to provide one.

However, to aid in debugging, consider adding some error logging when stdout is empty or falsy. This will help identify issues with Git command execution or file paths while still maintaining the robust behavior.

Consider modifying the code as follows:

- return new Date(stdout || Date.now()).toISOString()
+ if (!stdout) {
+   console.warn(`Git timestamp not available for ${meta.path}. Using current time.`);
+ }
+ return new Date(stdout || Date.now()).toISOString()

This change will log a warning when falling back to the current time, which can be helpful for identifying and addressing any underlying issues.

package.json (1)

52-62: Summary of dependency changes

The changes in this PR include:

  1. Replacing micromatch with picomatch (including type definitions)
  2. Upgrading chokidar to version 4

These updates align with the PR objectives and may improve the project's functionality. However, they also introduce potential breaking changes that need to be carefully managed.

To ensure a smooth transition:

  1. Review the changelogs for both picomatch and chokidar v4 for any breaking changes.
  2. Update all instances of micromatch usage to picomatch throughout the codebase.
  3. Test thoroughly, especially file watching functionality that relies on chokidar.
  4. Consider updating the project's documentation to reflect these dependency changes.
examples/nextjs/velite.config.ts (1)

33-33: Approve with suggestions: Improved robustness, but consider error handling

The change improves the robustness of the timestamp function by adding a fallback to Date.now() when the Git command fails or returns an empty string. This ensures that a valid date is always returned.

However, silently falling back to the current date might mask underlying issues with Git or file tracking. Consider the following improvements:

  1. Add a warning log when falling back to the current date:
const gitDate = stdout.trim();
if (!gitDate) {
  console.warn(`Unable to get Git timestamp for ${meta.path}. Falling back to current date.`);
}
return new Date(gitDate || Date.now()).toISOString();
  1. In development environments, consider throwing an error instead of silently falling back:
const gitDate = stdout.trim();
if (!gitDate) {
  if (process.env.NODE_ENV === 'development') {
    throw new Error(`Unable to get Git timestamp for ${meta.path}`);
  }
  console.warn(`Unable to get Git timestamp for ${meta.path}. Falling back to current date.`);
}
return new Date(gitDate || Date.now()).toISOString();

These suggestions will help with debugging and make it more apparent when the fallback is being used.

examples/basic/velite.config.js (1)

33-33: Approve change with suggestions for improvement

The modification to use Date.now() as a fallback is a good improvement in error handling, ensuring that a valid date is always returned. However, consider the following suggestions:

  1. Use file system metadata (e.g., last modified time) as a more accurate fallback instead of the current time. This would better represent the actual last update time of the file.

  2. Add a warning log when falling back to indicate that the Git command failed to produce a result.

Here's a suggested implementation incorporating these improvements:

const fs = require('fs').promises;

// ... (rest of the code)

const timestamp = () =>
  s
    .custom(i => i === undefined || typeof i === 'string')
    .transform(async (value, { meta, addIssue }) => {
      if (value != null) {
        addIssue({ fatal: false, code: 'custom', message: '`s.timestamp()` schema will resolve the value from `git log -1 --format=%cd`' })
      }
      try {
        const { stdout } = await execAsync(`git log -1 --format=%cd ${meta.path}`)
        return new Date(stdout.trim()).toISOString()
      } catch (error) {
        console.warn(`Failed to get Git timestamp for ${meta.path}. Falling back to file's last modified time.`)
        const stats = await fs.stat(meta.path)
        return new Date(stats.mtime).toISOString()
      }
    })

This implementation attempts to use the Git timestamp first, falls back to the file's last modified time if that fails, and logs a warning in the fallback case.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 02c4e2a and c72bda2.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (8)
  • docs/guide/last-modified.md (1 hunks)
  • docs/other/snippets.md (1 hunks)
  • examples/basic/velite.config.js (1 hunks)
  • examples/nextjs/velite.config.ts (1 hunks)
  • package.json (1 hunks)
  • src/build.ts (3 hunks)
  • src/utils.ts (1 hunks)
  • test/utils.ts (1 hunks)
🧰 Additional context used
🔇 Additional comments (15)
src/utils.ts (2)

1-4: LGTM: Imports and function signature are well-defined.

The imports are appropriate for the function's purpose, and the function signature is clear and well-typed. The use of an optional parameter for base is a good practice, allowing flexibility in function usage.


1-23: Overall, the implementation of matchPatterns is solid and efficient.

The function effectively handles pattern matching with support for negated patterns and relative paths. It makes good use of TypeScript features and efficient array methods. The suggestions provided in the review are minor and aimed at improving readability and conciseness.

Great job on implementing this utility function!

test/utils.ts (3)

1-4: LGTM: Imports are correct and follow good practices.

The imports are well-structured, using Node.js built-in modules for testing and assertions. The relative import for matchPatterns looks correct.


7-20: LGTM: Well-structured test cases with good coverage.

The test cases cover important scenarios for the matchPatterns function, including single patterns, multiple patterns, and negated patterns. The assertions are correct and test both positive and negative cases.


1-21: Overall, well-structured and effective test suite with room for minor enhancements.

This new test file for the matchPatterns function is well-organized and covers key scenarios. The use of Node.js built-in testing modules is commendable. To further improve:

  1. Simplify the describe function by removing the async keyword and unused parameter.
  2. Enhance test case naming for better clarity.
  3. Consider adding more edge cases to increase coverage.

These changes will make the test suite more robust and easier to maintain in the future.

package.json (3)

62-62: LGTM: Addition of picomatch

The addition of picomatch as a replacement for micromatch is a good update. This change aligns with the removal of micromatch mentioned in the AI summary.

Please ensure that all instances of micromatch usage in the codebase have been updated to use picomatch. You can use the following script to check for any remaining micromatch usage and find places where picomatch should be used:

✅ Verification successful

Verified: micromatch Successfully Replaced with picomatch

All instances of micromatch have been removed from the codebase, and picomatch has been correctly integrated as its replacement.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining micromatch usage and find potential picomatch usage

# Search for micromatch imports or usage
echo "Checking for remaining micromatch usage:"
rg --type typescript --type javascript 'micromatch'

# Search for potential places to use picomatch
echo "\nPotential places to use picomatch:"
rg --type typescript --type javascript '(glob|pattern|wildcard|match)'

Length of output: 368


Script:

#!/bin/bash
# Description: Check for any remaining micromatch usage and find potential places to use picomatch

# Search for micromatch imports or usage in JavaScript and TypeScript files
echo "Checking for remaining micromatch usage:"
rg 'micromatch' --glob '*.js' --glob '*.ts'

# Search for potential places to use picomatch in JavaScript and TypeScript files
echo -e "\nPotential places to use picomatch:"
rg '(glob|pattern|wildcard|match)' --glob '*.js' --glob '*.ts'

Length of output: 4807


52-52: LGTM: Addition of @types/picomatch

The addition of @types/picomatch aligns with the transition from micromatch to picomatch. This is a good update to maintain type safety with the new dependency.

Please verify that all instances of micromatch usage in the codebase have been updated to use picomatch. You can use the following script to check for any remaining micromatch usage:


54-54: LGTM: Upgrade of chokidar to v4

The upgrade of chokidar to version 4.0.1 aligns with the PR objective. This is a major version upgrade, which may introduce breaking changes.

Please review the chokidar changelog for any breaking changes and ensure that the codebase is compatible with the new version. You can use the following script to find chokidar usage in the codebase:

docs/other/snippets.md (1)

51-51: Improved robustness in timestamp handling

This change enhances the reliability of the timestamp schema by providing a fallback to the current timestamp when stdout is empty or falsy. This ensures that a valid date is always returned, preventing potential issues with invalid dates in the system.

src/build.ts (6)

12-12: LGTM: Updated import statement

The import statement has been correctly updated to import matchPatterns from ./utils.


179-179: LGTM: Collecting patterns from collections

The patterns are correctly collected from the collections for use in the watcher.


192-196: LGTM: Handling configuration changes

The code correctly handles configuration changes by restarting the build process when a config file changes.


198-200: Ensure consistent usage of matchPatterns function

This usage of matchPatterns is similar to the one noted earlier. Please refer to the previous comment to ensure consistency.


201-205: LGTM: Clearing cache entries for the changed file

The cache is properly updated by removing entries related to the changed file, ensuring that stale data is not used.


207-209: LGTM: Rebuilding upon file changes

The code successfully triggers a rebuild when a change is detected in watched files, maintaining up-to-date output.

Comment on lines +8 to +14
const { normal, negated } = list.reduce(
(acc, p) => {
acc[p.startsWith('!') ? 'negated' : 'normal'].push(p)
return acc
},
{ normal: [] as string[], negated: [] as string[] }
)
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider refactoring the reducer for improved readability.

While the current implementation using reduce is efficient for categorizing patterns, it could be made more readable by extracting the reducer logic into a separate function.

Here's a suggested refactor:

const categorizePatterns = (patterns: string[]) => {
  const categorizePattern = (acc: { normal: string[], negated: string[] }, pattern: string) => {
    const category = pattern.startsWith('!') ? 'negated' : 'normal';
    acc[category].push(pattern);
    return acc;
  };

  return patterns.reduce(categorizePattern, { normal: [], negated: [] });
};

const { normal, negated } = categorizePatterns(list);

This refactoring improves readability by giving clear names to the operations being performed and separating concerns.

Comment on lines +181 to 184
const watcher = watch(['.', ...configImports], {
cwd: root,
ignored: /(^|[\/\\])[\._]./, // ignore dot & underscore files
ignoreInitial: true, // ignore initial scan
ignoreInitial: true,
awaitWriteFinish: { stabilityThreshold: 50, pollInterval: 10 }
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider refining the watch paths to improve performance

Watching the entire root directory '.' may be unnecessary and could impact performance. Consider specifying only the necessary directories or patterns to watch, to avoid excessive file system events.

Comment on lines +101 to 103
if (changed != null && !matchPatterns(changed, pattern, root) && resolved.has(name)) {
// skip collection if changed file not match
logger.log(`skipped resolve '${name}', using previous resolved`)
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

⚠️ Potential issue

Inconsistent usage of matchPatterns function detected

The matchPatterns function is called with different numbers of arguments across the codebase:

  • In src/build.ts:

    • matchPatterns(changed, pattern, root)
    • matchPatterns(filename, patterns)
  • In test/utils.ts:

    • Various calls with two arguments, such as matchPatterns('foo/bar.js', '**/*.js')

Please ensure that the function is used consistently with the correct number and order of arguments.

🔗 Analysis chain

Verify consistent usage of matchPatterns function

The matchPatterns function is called with different numbers of arguments in lines 101 and 199. Please ensure that the function supports these usages and that the arguments are in the correct order.

Run the following script to verify the usage of matchPatterns across the codebase:


Re-run verification for consistent usage of matchPatterns

Please execute the following script to gather the necessary information:


Re-run verification for consistent usage of matchPatterns

Please execute the following corrected script to gather the necessary information:


Re-run verification for consistent usage of matchPatterns using rg

Please execute the following script to gather the necessary information:


Re-run verification for consistent usage of matchPatterns using rg with file extensions

Please execute the following corrected script to gather the necessary information:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all calls to 'matchPatterns' and display their arguments.

# Test: Ensure 'matchPatterns' is consistently used with the correct number of arguments.
ast-grep --lang typescript --pattern 'matchPatterns($$ARGS)'

Length of output: 62


Script:

#!/bin/bash
# Description: Find all calls to 'matchPatterns' and display their arguments.

# Test: Ensure 'matchPatterns' is consistently used with the correct number of arguments.
ast-grep --lang typescript --pattern 'matchPatterns($$ARGS)'

Length of output: 62


Script:

#!/bin/bash
# Description: Find all calls to 'matchPatterns' and display their arguments.

# Test: Ensure 'matchPatterns' is consistently used with the correct number of arguments.
ast-grep --lang typescript --pattern 'matchPatterns($$*)'

Length of output: 59


Script:

#!/bin/bash
# Description: Find all calls to 'matchPatterns' and display their arguments using ripgrep.

# Test: Ensure 'matchPatterns' is consistently used with the correct number of arguments.
rg 'matchPatterns\(([^)]*)\)' --type typescript | grep 'matchPatterns'

Length of output: 105


Script:

#!/bin/bash
# Description: Find all calls to 'matchPatterns' and display their arguments using ripgrep.

# Test: Ensure 'matchPatterns' is consistently used with the correct number of arguments.
rg 'matchPatterns\(([^)]*)\)' -g '*.ts' -g '*.tsx'

Length of output: 773

@zce zce merged commit d25ecd9 into main Oct 11, 2024
2 checks passed
@zce zce deleted the upgrade-chokidar branch October 11, 2024 13:46
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