10
10
11
11
12
12
def lint_for_dev_import_violations (codebase : Codebase , event : PullRequestLabeledEvent ):
13
+ # Next.js codemod to detect imports of the react-dev-overlay module in production code
14
+
13
15
patch , commit_shas , modified_symbols = codebase .get_modified_symbols_in_pr (event .pull_request .number )
14
16
modified_files = set (commit_shas .keys ())
17
+ from codegen .sdk .core .statements .if_block_statement import IfBlockStatement
15
18
16
- DIR_NAME = " packages/next/src/client/components/react-dev-overlay"
19
+ DIR_NAME = ' packages/next/src/client/components/react-dev-overlay'
17
20
directory = codebase .get_directory (DIR_NAME )
18
21
19
- # Initialize a list to store all violations
20
22
violations = []
21
23
22
- print ("modified_files" , modified_files )
23
-
24
- # Check if directory exists before proceeding
25
- if directory is not None and hasattr (directory , "files" ):
26
- for file in directory .files :
27
- print ("checking file" , file .filepath )
28
- for imp in file .inbound_imports :
29
- print ("file" , imp .file .filepath )
30
- print ("checking import" , imp .import_statement )
31
- # Check if the import is from outside the directory and is in the modified files
32
- if imp .file not in directory and imp .file .filepath in modified_files :
33
- # Skip require statements
34
- if "require" in imp .import_statement :
35
- continue
36
- violation = f"- Violation in `{ file .filepath } `: Importing from `{ imp .file .filepath } ` ([link]({ imp .github_url } ))"
37
- violations .append (violation )
38
- logger .info (f"Found violation: { violation } " )
39
-
40
- # Only create a PR comment if violations are found
41
- if violations :
42
- review_attention_message = "## Dev Import Violations Found\n \n "
43
- review_attention_message += "The following files have imports that violate development overlay rules:\n \n "
44
- review_attention_message += "\n " .join (violations )
45
- review_attention_message += "\n \n Please ensure that development imports are not imported in production code."
46
-
47
- # Create PR comment with the formatted message
48
- codebase ._op .create_pr_comment (event .pull_request .number , review_attention_message )
49
-
50
-
51
- def review_with_codegen_agent (codebase : Codebase , event : PullRequestLabeledEvent ):
52
- review_initial_message = "CodegenBot is starting to review the PR please wait..."
53
- comment = codebase ._op .create_pr_comment (event .number , review_initial_message )
54
- # Define tools first
55
- pr_tools = [
56
- GithubViewPRTool (codebase ),
57
- GithubCreatePRCommentTool (codebase ),
58
- GithubCreatePRReviewCommentTool (codebase ),
59
- ]
60
-
61
- # Create agent with the defined tools
62
- agent = CodeAgent (codebase = codebase , tools = pr_tools )
63
-
64
- # Using a prompt from SWE Bench
65
- prompt = f"""
66
- Hey CodegenBot!
67
-
68
- Here's a SWE task for you. Please Review this pull request!
69
- { event .pull_request .url }
70
- Do not terminate until have reviewed the pull request and are satisfied with your review.
71
-
72
- Review this Pull request like the señor ingenier you are
73
- be explicit about the changes, produce a short summary, and point out possible improvements where pressent dont be self congratulatory stick to the facts
74
- use the tools at your disposal to create propper pr reviews include code snippets if needed, and suggest improvements if feel its necesary
75
- """
76
- # Run the agent
77
- agent .run (prompt )
78
- comment .delete ()
24
+
25
+ false_operators = ["!=" , "!==" ]
26
+ true_operators = ["===" , "==" ]
27
+
28
+
29
+
30
+ def is_valid_block_expression (if_block : IfBlockStatement ) -> bool :
31
+ """Check if the if block has a valid environment check condition.
32
+
33
+ Valid conditions are:
34
+ - process.env.NODE_ENV !== 'production'
35
+ - process.env.NODE_ENV != 'production'
36
+ - process.env.NODE_ENV === 'development'
37
+ - process.env.NODE_ENV == 'development'
38
+ """
39
+ if not if_block .is_if_statement :
40
+ return False
41
+
42
+ condition = if_block .condition
43
+ # Get the operator without any whitespace
44
+ operator = condition .operator [- 1 ].source
45
+
46
+ # Check for non-production conditions
47
+ if operator in false_operators and condition .source == f"process.env.NODE_ENV { operator } 'production'" :
48
+ return True
49
+
50
+ # Check for explicit development conditions
51
+ if operator in true_operators and condition .source == f"process.env.NODE_ENV { operator } 'development'" :
52
+ return True
53
+
54
+ return False
55
+
56
+
57
+ def process_else_block_expression (else_block : IfBlockStatement ) -> bool :
58
+ """Check if the else block is valid by checking its parent if block.
59
+
60
+ Valid when the parent if block checks for production environment:
61
+ - if (process.env.NODE_ENV === 'production') { ... } else { <our import> }
62
+ - if (process.env.NODE_ENV == 'production') { ... } else { <our import> }
63
+ """
64
+ if not else_block .is_else_statement :
65
+ return False
66
+
67
+ main_if = else_block ._main_if_block
68
+ if not main_if or not main_if .condition :
69
+ return False
70
+
71
+ condition = main_if .condition
72
+ operator = condition .operator [- 1 ].source
73
+
74
+ # Valid if the main if block checks for production
75
+ return operator in true_operators and condition .source == f"process.env.NODE_ENV { operator } 'production'"
76
+
77
+
78
+ for file in directory .files (recursive = True ):
79
+ for imp in file .inbound_imports :
80
+
81
+ if imp .file .filepath not in modified_files :
82
+ # skip if the import is not in the pull request's modified files
83
+ continue
84
+ # Skip if the import is from within the target directory
85
+ if directory .dirpath in imp .file .filepath :
86
+ # "✅ Valid import" if the import is within the target directory
87
+ continue
88
+
89
+ parent_if_block = imp .parent_of_type (IfBlockStatement )
90
+
91
+ # Check if import is in a valid environment check block
92
+ if_block_valid = parent_if_block and is_valid_block_expression (parent_if_block )
93
+ else_block_valid = parent_if_block and process_else_block_expression (parent_if_block )
94
+
95
+ # Skip if the import is properly guarded by environment checks
96
+ if if_block_valid or else_block_valid :
97
+ # "✅ Valid import" these are guarded by non prod checks
98
+ continue
99
+
100
+ # Report invalid imports that aren't properly guarded
101
+ violation = f"- Violation in `{ file .filepath } `: Importing from `{ imp .file .filepath } ` ([link]({ imp .github_url } ))"
102
+ violations .append (violation )
103
+ logger .info (f"Found violation: { violation } " )
104
+
105
+
106
+ if violations :
107
+ # Comment on PR with violations
108
+ review_attention_message = "## Dev Import Violations Found\n \n "
109
+ review_attention_message += "The following files have imports that violate development overlay rules:\n \n "
110
+ review_attention_message += "\n " .join (violations )
111
+ review_attention_message += "\n \n Please ensure that development imports are not imported in production code."
112
+
113
+ # Create PR comment with the formatted message
114
+ codebase ._op .create_pr_comment (event .pull_request .number , review_attention_message )
0 commit comments