Skip to content

feat: unify configuration reading#1560

Merged
HerringtonDarkholme merged 3 commits intomainfrom
fix-config
Oct 28, 2024
Merged

feat: unify configuration reading#1560
HerringtonDarkholme merged 3 commits intomainfrom
fix-config

Conversation

@HerringtonDarkholme
Copy link
Copy Markdown
Member

@HerringtonDarkholme HerringtonDarkholme commented Oct 28, 2024

fix #1557

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a global configuration option for command-line operations, allowing users to specify a configuration file path using -c or --config flags.
  • Bug Fixes

    • Improved error handling for missing project configurations, ensuring appropriate error messages are displayed.
  • Refactor

    • Simplified argument structures by removing optional configuration fields from various command-related structs.
    • Updated functions to handle project configurations more explicitly using Result types, enhancing error management.
  • Tests

    • Updated test cases to validate new configurations and error handling scenarios.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Oct 28, 2024

Walkthrough

The changes in this pull request primarily focus on enhancing the handling of project configurations within the command-line interface of the application. The setup method's return type has been modified to improve error reporting, and several command handlers have been updated to accept a new global configuration parameter. Additionally, the config field has been removed from various argument structures, and the relevant functions have been adjusted to utilize a Result<ProjectConfig> type for better error management. These changes streamline the configuration process across different subcommands.

Changes

File Path Change Summary
crates/cli/src/config.rs Updated setup method return type from Result<Option<Self>> to Result<Result<Self>>. Adjusted logic to return Ok(Err(anyhow::anyhow!(EC::ProjectNotExist))) for non-existing projects.
crates/cli/src/lib.rs Added config: Option<PathBuf> to App struct. Updated command handler signatures to accept project: Result<ProjectConfig>. Enhanced error handling for missing config files.
crates/cli/src/lsp.rs Removed config field from LspArg. Updated run_language_server_impl and run_language_server signatures to accept Result<ProjectConfig>.
crates/cli/src/new.rs Removed config field from NewArg. Updated run_create_new, run_create_entity, and ask_entity_type functions to accept Result<ProjectConfig>.
crates/cli/src/run.rs Removed register_custom_language_if_is_run function, affecting command-line argument handling for custom language registration.
crates/cli/src/scan.rs Removed config field from ScanArg. Updated run_with_config and run_scan signatures to accept Result<ProjectConfig>.
crates/cli/src/verify.rs Removed config field from TestArg. Updated run_test_rule signature to accept Result<ProjectConfig>.

Assessment against linked issues

Objective Addressed Explanation
Implement a new global argument --config for configuration discovery (Issue #1557)

Possibly related PRs

Poem

🐰 In the garden where configs grow,
A new path for projects now we sow.
With errors caught and clarity found,
Our command-line tools are truly sound.
Hop along, let the changes ring,
For every project, let success spring! 🌼


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.

@codecov
Copy link
Copy Markdown

codecov bot commented Oct 28, 2024

Codecov Report

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

Project coverage is 72.63%. Comparing base (d9014f9) to head (0e68e71).
Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
crates/cli/src/lsp.rs 0.00% 4 Missing ⚠️
crates/cli/src/lib.rs 78.57% 3 Missing ⚠️
crates/cli/src/new.rs 57.14% 3 Missing ⚠️
crates/cli/src/scan.rs 66.66% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1560      +/-   ##
==========================================
+ Coverage   72.62%   72.63%   +0.01%     
==========================================
  Files          88       88              
  Lines        6035     6034       -1     
==========================================
  Hits         4383     4383              
+ Misses       1652     1651       -1     

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

Copy link
Copy Markdown
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: 2

🧹 Outside diff range and nitpick comments (6)
crates/cli/src/lsp.rs (2)

12-12: Address TODO comment regarding error handling

The comment "TODO: move this error to client" suggests there's pending work on error handling strategy.

Would you like me to help implement proper error propagation to the LSP client or create a GitHub issue to track this task?


Line range hint 13-31: Consider enhancing error messages for better debugging

While the error handling is functional, consider adding more context to error messages to help users troubleshoot configuration issues more effectively.

 let config_result_std: std::result::Result<_, String> = config_result
   .map_err(|e| {
     // convert anyhow::Error to String with chain of causes
-    e.chain()
-      .map(|e| e.to_string())
-      .collect::<Vec<_>>()
-      .join(". ")
+    format!("Failed to load LSP configuration: {}",
+      e.chain()
+        .map(|e| e.to_string())
+        .collect::<Vec<_>>()
+        .join(". "))
   })
crates/cli/src/config.rs (1)

Line range hint 93-105: Consider simplifying the nested Result return type.

The change from Result<Option<Self>> to Result<Result<Self>> introduces nested error handling which could make the API more complex to use. While this change aligns with the PR's goal of unifying configuration handling, consider these alternatives:

  1. Use a custom error type that distinguishes between IO errors and configuration errors
  2. Flatten the results using Result<Self> with a custom error enum

Example implementation using a custom error type:

#[derive(Debug)]
pub enum ConfigError {
    IoError(std::io::Error),
    ProjectNotExist,
    // ... other error variants
}

impl From<std::io::Error> for ConfigError {
    fn from(err: std::io::Error) -> Self {
        ConfigError::IoError(err)
    }
}

pub fn setup(config_path: Option<PathBuf>) -> Result<Self, ConfigError> {
    let Some((project_dir, mut sg_config)) = Self::discover_project(config_path)? else {
        return Err(ConfigError::ProjectNotExist);
    };
    // ... rest of the implementation
}

This approach would:

  • Simplify error handling for callers
  • Maintain clear distinction between error types
  • Improve API ergonomics
crates/cli/src/lib.rs (2)

44-46: LGTM! Consider enhancing the documentation.

The configuration field implementation looks good. The type choice and CLI argument setup are appropriate.

Consider expanding the documentation to include:

  • The expected format of the config file (YAML)
  • The default config path behavior
-  /// Path to ast-grep root config, default is sgconfig.yml.
+  /// Path to ast-grep root config file in YAML format.
+  /// If not specified, defaults to 'sgconfig.yml' in the current directory.

205-205: Enhance test coverage for configuration handling.

While the basic config flag test is good, consider adding more test cases to ensure robust configuration handling:

Add test cases for:

  • Config flag with other commands (scan, test, new, lsp)
  • Default config path behavior
  • Invalid config paths
  • Config file format validation

Example additions:

#[test]
fn test_config_handling() {
    ok("scan -c custom_config.yml");
    ok("test -c custom_config.yml");
    error("scan -c"); // missing config path
    error("scan -c invalid/path/config.yml"); // non-existent config
}
crates/cli/src/new.rs (1)

374-394: Consider adding negative test cases

While the current tests verify successful creation scenarios, consider adding test cases for:

  • Invalid configuration paths
  • Permission denied scenarios
  • Duplicate entity creation attempts

Example test case:

#[test]
fn test_create_rule_invalid_config() -> Result<()> {
    let dir = TempDir::new()?;
    let invalid_config = dir.path().join("nonexistent.yml");
    let project = ProjectConfig::setup(Some(invalid_config));
    assert!(project.is_err());
    Ok(())
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between d9014f9 and 78775df.

📒 Files selected for processing (7)
  • crates/cli/src/config.rs (2 hunks)
  • crates/cli/src/lib.rs (5 hunks)
  • crates/cli/src/lsp.rs (3 hunks)
  • crates/cli/src/new.rs (3 hunks)
  • crates/cli/src/run.rs (0 hunks)
  • crates/cli/src/scan.rs (8 hunks)
  • crates/cli/src/verify.rs (2 hunks)
💤 Files with no reviewable changes (1)
  • crates/cli/src/run.rs
🔇 Additional comments (14)
crates/cli/src/lsp.rs (3)

8-8: LGTM: Simplified argument structure aligns with unified configuration approach

The removal of the config field from LspArg supports the PR's objective of unifying configuration discovery across subcommands.


33-38: LGTM: Proper async runtime handling with error context

The function correctly sets up the tokio runtime and provides good error context for runtime creation failures.


47-50: Enhance test coverage for LSP functionality

While the error case is tested, consider adding the following test cases:

  1. Successful configuration loading
  2. Various configuration error scenarios
  3. LSP server initialization with valid config

Also, the test is currently ignored. Consider implementing the pending LSP tests or document why they're blocked.

crates/cli/src/config.rs (1)

93-95: Verify error handling in all callers.

The change in error handling strategy (from Option to Result) requires careful verification of all calling code to ensure proper error handling.

Let's verify the impact:

✅ Verification successful

Let me gather more context about the error handling in these files to make a proper assessment.


Let me check one more thing to verify if these are test functions since the last command didn't show the test modules clearly.


Based on the gathered information, I can now provide the final response:

Error handling is properly implemented across all callers

The error handling changes in ProjectConfig::setup are handled appropriately:

  • In lib.rs: Uses proper error propagation with ? operator
  • In scan.rs: The .unwrap() usage is within a test function test_run_with_config
  • In new.rs: Both calls use proper error propagation with ? operator and are within test functions

The only instance of .unwrap() is in test code, while production code properly propagates errors, making this change safe.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all callers of ProjectConfig::setup to verify error handling

# Search for setup method calls
echo "Searching for ProjectConfig::setup callers:"
rg -p "ProjectConfig::setup" --type rust

# Search for potential error handling patterns
echo -e "\nVerifying error handling patterns:"
rg -p "setup\(.*\)\.(?:and_then|map_err|unwrap|expect)" --type rust

Length of output: 789


Script:

#!/bin/bash
# Get context around the setup calls to understand error handling

echo "Context from lib.rs:"
rg -p "ProjectConfig::setup" -B 5 -A 5 --type rust crates/cli/src/lib.rs

echo -e "\nContext from scan.rs:"
rg -p "ProjectConfig::setup" -B 5 -A 5 --type rust crates/cli/src/scan.rs

echo -e "\nContext from new.rs:"
rg -p "ProjectConfig::setup" -B 5 -A 5 --type rust crates/cli/src/new.rs

# Check if these are test functions
echo -e "\nChecking for test modules:"
rg -p "mod tests" --type rust crates/cli/src/scan.rs crates/cli/src/new.rs

Length of output: 2120


Script:

#!/bin/bash
# Check for test attributes and modules
echo "Checking for test attributes in scan.rs:"
rg -p "#\[test\]" -B 10 -A 2 crates/cli/src/scan.rs

echo -e "\nChecking for test attributes in new.rs:"
rg -p "#\[test\]" -B 10 -A 2 crates/cli/src/new.rs

# Also check the actual error handling in lib.rs
echo -e "\nChecking error handling in lib.rs:"
rg -p "fn run" -B 2 -A 10 crates/cli/src/lib.rs

Length of output: 2695

crates/cli/src/lib.rs (1)

110-113: LGTM! Clean implementation of unified configuration handling.

The changes consistently pass the project configuration to command handlers, aligning well with the PR's objective of unifying configuration discovery across subcommands.

crates/cli/src/verify.rs (2)

186-187: LGTM! Function signature change aligns with configuration unification.

The updated signature properly handles project configuration through Result<ProjectConfig>, aligning with the PR's objective to unify configuration reading across subcommands. The error handling with the ? operator follows Rust best practices.


314-314: LGTM! Test case properly verifies error handling.

The test case correctly verifies the error path for the new configuration handling.

crates/cli/src/new.rs (3)

147-151: LGTM: Improved error handling with Result type

The change to accept Result<ProjectConfig> enhances error handling and aligns with the PR's objective to unify configuration handling across subcommands.


155-157: LGTM: Clean error handling implementation

The error handling implementation follows Rust idioms and properly differentiates between project creation and other entity types.


Line range hint 1-420: Verify removal of direct config path references

Let's ensure all direct config path references have been properly migrated to use the new unified configuration approach.

✅ Verification successful

Based on the search results, I can now generate the final response:

All config path references are properly handled

The search results confirm that all config path references in the codebase are properly handled through the unified configuration approach. The occurrences found are either:

  • Documentation strings explaining the config file usage
  • Test fixtures setting up test environments
  • Proper usage of the new configuration system through ProjectConfig::setup
  • Error messages guiding users about configuration
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining direct references to config files or paths
# that might need to be updated to use the new unified approach

# Look for potential config-related string literals
rg -g '*.rs' -i 'config(\.yml|\.yaml|_path|file)'

# Look for potential direct path construction for config files
rg -g '*.rs' 'Path.*config'

Length of output: 4673

crates/cli/src/scan.rs (4)

Line range hint 66-85: Refactored run_with_config function correctly handles project

The updates to run_with_config to accept project: Result<ProjectConfig> ensure that configuration errors are properly propagated. The changes are consistent and enhance error handling across the function.


89-101: run_scan function's signature update is appropriate

The run_scan function now accepts project: Result<ProjectConfig>, aligning it with the changes in run_with_config and ensuring consistent error handling throughout the scanning process.


Line range hint 111-122: Proper error propagation in ScanWithConfig::try_new

The use of the ? operator on project in ScanWithConfig::try_new correctly propagates any errors in the project configuration, ensuring that issues are surfaced early in the initialization process.


Line range hint 417-428: Ensure consistent error handling in test functions

In the test functions test_scan_with_inline_rules and test_scan_with_inline_rules_diff, you're passing Err(anyhow::anyhow!("not found")) as the project parameter. Verify that this aligns with the intended test scenarios and that error cases are appropriately handled within run_with_config.

Copy link
Copy Markdown
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 (1)
crates/cli/src/lib.rs (1)

106-106: Consider improving error handling for project setup.

The project setup error is silently passed through. Consider handling configuration errors explicitly to provide better user feedback when the config file is invalid or missing.

- let project = setup_project_is_possible(&args);
+ let project = setup_project_is_possible(&args).map_err(|e| {
+     anyhow::anyhow!("Failed to load configuration: {}", e)
+ })?;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 78775df and 0e68e71.

📒 Files selected for processing (1)
  • crates/cli/src/lib.rs (5 hunks)
🔇 Additional comments (4)
crates/cli/src/lib.rs (4)

14-14: LGTM: Well-structured configuration field addition.

The global configuration option is properly implemented with:

  • Clear documentation
  • Appropriate clap attributes for global usage
  • Optional type for backward compatibility

Also applies to: 17-17, 44-46


87-101: Refactor: Use clap's parsed configuration value.

The manual parsing of the config flag duplicates functionality already handled by clap through the App struct. This implementation:

  • Adds unnecessary complexity
  • Could miss edge cases that clap handles
  • Is harder to maintain

174-174: LGTM: Test coverage properly updated.

The test suite has been appropriately updated to:

  • Verify the new error message format
  • Test the global config argument functionality

Also applies to: 210-210


115-118: Verify: Should Run command use project configuration?

While other commands now use project configuration, the Run command doesn't. This seems inconsistent with the PR's goal of unifying configuration handling.

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.

[refactor] unify configuration discovery for different subcommands

1 participant