-
Notifications
You must be signed in to change notification settings - Fork 8
Process local folder #35
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
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
Warning Rate limit exceeded@swilly22 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 4 minutes and 8 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. WalkthroughThe changes in this pull request involve updates to the Changes
Poem
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? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Outside diff range and nitpick comments (1)
api/analyzers/source_analyzer.py (1)
Line range hint
147-162
: Consider thread safety concerns with directory manipulationThe current implementation changes the working directory which could cause issues in a multi-threaded environment where multiple analyses are running concurrently.
Consider refactoring to avoid changing the working directory:
- # Save original working directory for later restore - original_dir = Path.cwd() - - # change working directory to path - os.chdir(path) - - # Initialize the graph and analyzer - self.graph = g - - # Analyze source files - self.analyze_sources(ignore) - - logging.info("Done analyzing path") - - # Restore original working dir - os.chdir(original_dir) + try: + # Initialize the graph + self.graph = g + + # Convert relative paths in ignore list to be relative to the target path + adjusted_ignore = [os.path.join(path, p) for p in ignore] + + # Use absolute paths in analyze_sources + with Path(path).absolute() as abs_path: + self.analyze_sources(adjusted_ignore, base_path=abs_path) + + logging.info("Done analyzing path") + except Exception as e: + logging.error(f"Error analyzing path {path}: {e}") + raiseThis approach:
- Eliminates the need to change working directory
- Adds proper error handling
- Maintains thread safety
- Uses absolute paths for reliability
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (23)
api/__pycache__/__init__.cpython-312.pyc
is excluded by!**/*.pyc
api/__pycache__/app.cpython-312.pyc
is excluded by!**/*.pyc
api/__pycache__/auto_complete.cpython-312.pyc
is excluded by!**/*.pyc
api/__pycache__/graph.cpython-312.pyc
is excluded by!**/*.pyc
api/__pycache__/info.cpython-312.pyc
is excluded by!**/*.pyc
api/__pycache__/llm.cpython-312.pyc
is excluded by!**/*.pyc
api/__pycache__/project.cpython-312.pyc
is excluded by!**/*.pyc
api/analyzers/__pycache__/__init__.cpython-312.pyc
is excluded by!**/*.pyc
api/analyzers/__pycache__/analyzer.cpython-312.pyc
is excluded by!**/*.pyc
api/analyzers/__pycache__/source_analyzer.cpython-312.pyc
is excluded by!**/*.pyc
api/analyzers/__pycache__/utils.cpython-312.pyc
is excluded by!**/*.pyc
api/analyzers/c/__pycache__/analyzer.cpython-312.pyc
is excluded by!**/*.pyc
api/analyzers/python/__pycache__/analyzer.cpython-312.pyc
is excluded by!**/*.pyc
api/code_coverage/__pycache__/__init__.cpython-312.pyc
is excluded by!**/*.pyc
api/code_coverage/lcov/__pycache__/__init__.cpython-312.pyc
is excluded by!**/*.pyc
api/code_coverage/lcov/__pycache__/lcov.cpython-312.pyc
is excluded by!**/*.pyc
api/entities/__pycache__/__init__.cpython-312.pyc
is excluded by!**/*.pyc
api/entities/__pycache__/argument.cpython-312.pyc
is excluded by!**/*.pyc
api/entities/__pycache__/cls.cpython-312.pyc
is excluded by!**/*.pyc
api/entities/__pycache__/entity_encoder.cpython-312.pyc
is excluded by!**/*.pyc
api/entities/__pycache__/file.cpython-312.pyc
is excluded by!**/*.pyc
api/entities/__pycache__/function.cpython-312.pyc
is excluded by!**/*.pyc
api/entities/__pycache__/struct.cpython-312.pyc
is excluded by!**/*.pyc
📒 Files selected for processing (3)
.gitignore
(1 hunks)api/analyzers/source_analyzer.py
(3 hunks)api/index.py
(2 hunks)
✅ Files skipped from review due to trivial changes (1)
- .gitignore
🧰 Additional context used
🪛 Ruff (0.8.0)
api/index.py
340-340: Graph
may be undefined, or defined from star imports
(F405)
343-343: SourceAnalyzer
may be undefined, or defined from star imports
(F405)
api/analyzers/source_analyzer.py
138-138: Do not use mutable data structures for argument defaults
Replace with None
; initialize within function
(B006)
@@ -135,7 +135,7 @@ def analyze_sources(self, ignore: List[str]) -> None: | |||
# Second pass analysis of the source code | |||
self.second_pass(ignore, executor) | |||
|
|||
def analyze(self, path: str, g: Graph, ignore: Optional[List[str]] = []) -> None: | |||
def analyze_local_folder(self, path: str, g: Graph, ignore: Optional[List[str]] = []) -> None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix mutable default argument
Using mutable default arguments in Python can lead to unexpected behavior. The empty list []
as a default argument is shared across function calls.
Replace with:
- def analyze_local_folder(self, path: str, g: Graph, ignore: Optional[List[str]] = []) -> None:
+ def analyze_local_folder(self, path: str, g: Graph, ignore: Optional[List[str]] = None) -> None:
And add at the beginning of the method:
if ignore is None:
ignore = []
🧰 Tools
🪛 Ruff (0.8.0)
138-138: Do not use mutable data structures for argument defaults
Replace with None
; initialize within function
(B006)
proj_name = Path(path).name | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add validation for project name
The project name is derived from the path without validation, which could lead to issues with special characters or empty names.
Add validation:
- proj_name = Path(path).name
+ proj_name = Path(path).name
+ if not proj_name or proj_name.startswith('.'):
+ logging.error(f"Invalid project name derived from path: {proj_name}")
+ return jsonify({"status": "Invalid path: cannot derive valid project name"}), 400
📝 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.
proj_name = Path(path).name | |
proj_name = Path(path).name | |
if not proj_name or proj_name.startswith('.'): | |
logging.error(f"Invalid project name derived from path: {proj_name}") | |
return jsonify({"status": "Invalid path: cannot derive valid project name"}), 400 |
from api import * | ||
from pathlib import Path |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Replace star import with explicit imports
Star imports (from api import *
) make it unclear which symbols are being imported and can lead to naming conflicts.
Replace with explicit imports:
-from api import *
+from api.analyzers.source_analyzer import SourceAnalyzer
+from api.graph import Graph
+from api.utils import graph_exists, get_repos, get_repo_info, ask
Committable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 Ruff (0.8.0)
3-3: from api import *
used; unable to detect undefined names
(F403)
api/index.py
Outdated
@app.route('/analyze_folder', methods=['POST']) | ||
@token_required # Apply token authentication decorator | ||
def analyze_folder(): | ||
""" | ||
Endpoint to analyze local source code | ||
Expects 'path' and optionaly an ignore list. | ||
|
||
Returns: | ||
Status code | ||
""" | ||
|
||
# Get JSON data from the request | ||
data = request.get_json() | ||
|
||
# Get query parameters | ||
path = data.get('path') | ||
ignore = data.get('ignore', []) | ||
|
||
# Validate 'path' parameter | ||
if not path: | ||
logging.error("'path' is missing from the request.") | ||
return jsonify({"status": "'path' is required."}), 400 | ||
|
||
proj_name = Path(path).name | ||
|
||
# Initialize the graph with the provided project name | ||
g = Graph(proj_name) | ||
|
||
# Analyze source code within given folder | ||
analyzer = SourceAnalyzer() | ||
analyzer.analyze_local_folder(path, g, ignore) | ||
|
||
# Return response | ||
response = { | ||
'status': 'success' | ||
} | ||
|
||
return jsonify(response), 200 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enhance error handling and input validation
The current implementation lacks comprehensive error handling for file system operations and input validation.
Consider the following improvements:
@app.route('/analyze_folder', methods=['POST'])
@token_required
def analyze_folder():
"""
Endpoint to analyze local source code
- Expects 'path' and optionaly an ignore list.
+ Expects 'path' and optionally an ignore list.
Returns:
- Status code
+ JSON response with status and error message if applicable
+ Status codes:
+ 200: Success
+ 400: Invalid input
+ 500: Internal server error
"""
# Get JSON data from the request
data = request.get_json()
# Get query parameters
path = data.get('path')
ignore = data.get('ignore', [])
- # Validate 'path' parameter
+ # Validate input parameters
if not path:
logging.error("'path' is missing from the request.")
return jsonify({"status": "'path' is required."}), 400
+ # Validate path exists and is a directory
+ if not os.path.isdir(path):
+ logging.error(f"Path '{path}' does not exist or is not a directory")
+ return jsonify({"status": "Invalid path: must be an existing directory"}), 400
+
+ # Validate ignore list contains valid paths
+ if not isinstance(ignore, list):
+ logging.error("'ignore' must be a list of paths")
+ return jsonify({"status": "'ignore' must be a list of paths"}), 400
+
proj_name = Path(path).name
- # Initialize the graph with the provided project name
- g = Graph(proj_name)
+ try:
+ # Initialize the graph with the provided project name
+ g = Graph(proj_name)
- # Analyze source code within given folder
- analyzer = SourceAnalyzer()
- analyzer.analyze_local_folder(path, g, ignore)
+ # Analyze source code within given folder
+ analyzer = SourceAnalyzer()
+ analyzer.analyze_local_folder(path, g, ignore)
- # Return response
- response = {
- 'status': 'success'
- }
+ # Return response
+ response = {
+ 'status': 'success',
+ 'project': proj_name
+ }
+ return jsonify(response), 200
- return jsonify(response), 200
+ except Exception as e:
+ logging.error(f"Error analyzing folder {path}: {e}")
+ return jsonify({
+ 'status': 'error',
+ 'message': str(e)
+ }), 500
📝 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.
@app.route('/analyze_folder', methods=['POST']) | |
@token_required # Apply token authentication decorator | |
def analyze_folder(): | |
""" | |
Endpoint to analyze local source code | |
Expects 'path' and optionaly an ignore list. | |
Returns: | |
Status code | |
""" | |
# Get JSON data from the request | |
data = request.get_json() | |
# Get query parameters | |
path = data.get('path') | |
ignore = data.get('ignore', []) | |
# Validate 'path' parameter | |
if not path: | |
logging.error("'path' is missing from the request.") | |
return jsonify({"status": "'path' is required."}), 400 | |
proj_name = Path(path).name | |
# Initialize the graph with the provided project name | |
g = Graph(proj_name) | |
# Analyze source code within given folder | |
analyzer = SourceAnalyzer() | |
analyzer.analyze_local_folder(path, g, ignore) | |
# Return response | |
response = { | |
'status': 'success' | |
} | |
return jsonify(response), 200 | |
@app.route('/analyze_folder', methods=['POST']) | |
@token_required | |
def analyze_folder(): | |
""" | |
Endpoint to analyze local source code | |
Expects 'path' and optionally an ignore list. | |
Returns: | |
JSON response with status and error message if applicable | |
Status codes: | |
200: Success | |
400: Invalid input | |
500: Internal server error | |
""" | |
# Get JSON data from the request | |
data = request.get_json() | |
# Get query parameters | |
path = data.get('path') | |
ignore = data.get('ignore', []) | |
# Validate input parameters | |
if not path: | |
logging.error("'path' is missing from the request.") | |
return jsonify({"status": "'path' is required."}), 400 | |
# Validate path exists and is a directory | |
if not os.path.isdir(path): | |
logging.error(f"Path '{path}' does not exist or is not a directory") | |
return jsonify({"status": "Invalid path: must be an existing directory"}), 400 | |
# Validate ignore list contains valid paths | |
if not isinstance(ignore, list): | |
logging.error("'ignore' must be a list of paths") | |
return jsonify({"status": "'ignore' must be a list of paths"}), 400 | |
proj_name = Path(path).name | |
try: | |
# Initialize the graph with the provided project name | |
g = Graph(proj_name) | |
# Analyze source code within given folder | |
analyzer = SourceAnalyzer() | |
analyzer.analyze_local_folder(path, g, ignore) | |
# Return response | |
response = { | |
'status': 'success', | |
'project': proj_name | |
} | |
return jsonify(response), 200 | |
except Exception as e: | |
logging.error(f"Error analyzing folder {path}: {e}") | |
return jsonify({ | |
'status': 'error', | |
'message': str(e) | |
}), 500 |
🧰 Tools
🪛 Ruff (0.8.0)
340-340: Graph
may be undefined, or defined from star imports
(F405)
343-343: SourceAnalyzer
may be undefined, or defined from star imports
(F405)
b8599c7
to
3de17bb
Compare
There was a problem hiding this 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)
api/index.py (2)
317-327
: Enhance endpoint documentationThe documentation should include:
- Request body schema
- Example request/response
- Description of the ignore list format and usage
""" Endpoint to analyze local source code - Expects 'path' and optionally an ignore list. + Analyzes source code in a local directory that is not part of a Git repository. + + Request Body: + { + "path": str, # Path to the local directory + "ignore": list # Optional list of paths to ignore during analysis + } + + Example: + { + "path": "/path/to/source", + "ignore": ["tests/", "*.pyc"] + } Returns: JSON response with status and error message if applicable
360-365
: Enhance success response with additional metadataInclude useful metadata in the success response to provide more context about the analysis.
# Return response response = { 'status': 'success', - 'project': proj_name + 'project': proj_name, + 'analyzed_at': datetime.datetime.now().isoformat(), + 'path': path, + 'ignored_patterns': ignore }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (1)
api/index.py
(2 hunks)
🧰 Additional context used
🪛 Ruff (0.8.0)
api/index.py
354-354: Graph
may be undefined, or defined from star imports
(F405)
357-357: SourceAnalyzer
may be undefined, or defined from star imports
(F405)
🔇 Additional comments (4)
api/index.py (4)
3-4
: Replace star import with explicit imports
The star import makes it unclear which symbols are being imported and can lead to naming conflicts. This affects the newly added Graph
and SourceAnalyzer
imports used in the new endpoint.
🧰 Tools
🪛 Ruff (0.8.0)
3-3: from api import *
used; unable to detect undefined names
(F403)
351-352
: Add validation for project name
The project name is derived from the path without validation, which could lead to issues with special characters or empty names.
353-359
:
Add error handling for analysis operations
The graph initialization and analysis operations should be wrapped in a try-catch block to handle potential errors gracefully.
- # Initialize the graph with the provided project name
- g = Graph(proj_name)
-
- # Analyze source code within given folder
- analyzer = SourceAnalyzer()
- analyzer.analyze_local_folder(path, g, ignore)
+ try:
+ # Initialize the graph with the provided project name
+ g = Graph(proj_name)
+
+ # Analyze source code within given folder
+ analyzer = SourceAnalyzer()
+ analyzer.analyze_local_folder(path, g, ignore)
+ except Exception as e:
+ logging.error(f"Error analyzing folder {path}: {str(e)}")
+ return jsonify({
+ "status": "error",
+ "message": "Failed to analyze folder",
+ "details": str(e)
+ }), 500
Likely invalid or redundant comment.
🧰 Tools
🪛 Ruff (0.8.0)
354-354: Graph
may be undefined, or defined from star imports
(F405)
357-357: SourceAnalyzer
may be undefined, or defined from star imports
(F405)
314-366
: Verify the impact on existing graphs
Since this endpoint creates a new graph for local folders, we should verify that it doesn't conflict with existing graphs from Git repositories.
✅ Verification successful
Let me analyze the Graph instantiation patterns to understand potential naming conflicts. I need to check how graph names are stored and managed in the database.
Let me check one final aspect about how graphs are managed in the database by looking at the graph selection and creation logic.
Based on the gathered information, I can now provide the final response:
No conflict risk between local and Git repository graphs
The Graph implementation uses simple name-based selection through FalkorDB's select_graph
method, which creates the graph if it doesn't exist. Since local folder analysis uses the folder name (Path(path).name
) as the graph name, while Git repository analysis uses the repository name, they naturally maintain separation through their distinct naming patterns. There's no mechanism that could cause conflicts between them.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for potential naming conflicts between local and Git repository graphs
# Search for Graph instantiations to understand naming patterns
rg -A 2 "Graph\(" --type py
# Search for project name derivation patterns
rg -A 2 "proj_name" --type py
Length of output: 2055
Script:
#!/bin/bash
# Check Graph class implementation for name handling
ast-grep --pattern 'class Graph {
$$$
__init__($$$) {
$$$
}
$$$
}'
# Search for any graph name uniqueness checks or conflict handling
rg -B2 -A2 "name.*=.*" api/graph.py
Length of output: 2791
Script:
#!/bin/bash
# Check graph selection and creation logic
rg -B2 -A4 "select_graph" api/graph.py
# Check if there's any graph deletion or cleanup logic
rg -B2 -A4 "delete.*graph" api/graph.py
Length of output: 358
🧰 Tools
🪛 Ruff (0.8.0)
354-354: Graph
may be undefined, or defined from star imports
(F405)
357-357: SourceAnalyzer
may be undefined, or defined from star imports
(F405)
f45d7a5
to
c830d08
Compare
c830d08
to
49c2f16
Compare
Add the ability to process a local none git folder.
Summary by CodeRabbit
New Features
/analyze_folder
for analyzing local source code.Bug Fixes
Chores
.gitignore
to exclude various temporary and environment files.