@@ -21,7 +21,9 @@ def _create_requires_assignment(self) -> cst.Assign:
2121 """Create a `requires` assignment statement."""
2222 return cst .Assign (
2323 targets = [cst .AssignTarget (cst .Name ('requires' ))],
24- value = cst .List ([cst .Element (cst .SimpleString (f'"{ dep .requires ()} "' )) for dep in self .dependencies ]),
24+ value = cst .List ([
25+ cst .Element (cst .SimpleString (f'"{ dependency .requires ()} "' )) for dependency in self .dependencies
26+ ]),
2527 )
2628
2729 def leave_ClassDef (self , original_node : cst .ClassDef , updated_node : cst .ClassDef ) -> cst .BaseStatement :
@@ -46,51 +48,70 @@ def _is_conanfile_class(class_node: cst.ClassDef) -> bool:
4648
4749 Returns: True if the class inherits from ConanFile, False otherwise.
4850 """
49- return any (
50- (isinstance (base , cst .Name ) and base .value == 'ConanFile' )
51- or (isinstance (base , cst .Attribute ) and base .attr .value == 'ConanFile' )
52- for base in class_node .bases
53- )
51+ return any ((isinstance (base .value , cst .Name ) and base .value .value == 'ConanFile' ) for base in class_node .bases )
5452
5553 def _update_requires (self , updated_node : cst .ClassDef ) -> cst .ClassDef :
56- """Update or add the 'requires' attribute in the class definition.
54+ """Update or add a 'requires' assignment in a ConanFile class definition."""
55+ # Check if 'requires' is already defined
56+ for body_statement_line in updated_node .body .body :
57+ if not isinstance (body_statement_line , cst .SimpleStatementLine ):
58+ continue
59+
60+ assignment_statement = body_statement_line .body [0 ]
61+ if not isinstance (assignment_statement , cst .Assign ):
62+ continue
63+
64+ for target in assignment_statement .targets :
65+ if not isinstance (target .target , cst .Name ) or target .target .value != 'requires' :
66+ continue
67+
68+ return self ._replace_requires (updated_node , body_statement_line , assignment_statement )
69+
70+ # Find the last attribute assignment before methods
71+ last_attribute = None
72+ for body_statement_line in updated_node .body .body :
73+ if not isinstance (body_statement_line , cst .SimpleStatementLine ):
74+ break
75+ assignment_statement = body_statement_line .body [0 ]
76+ if not isinstance (assignment_statement , cst .Assign ):
77+ break
78+ last_attribute = body_statement_line
79+
80+ # Construct a new statement for the 'requires' attribute
81+ new_statement = cst .SimpleStatementLine (
82+ body = [self ._create_requires_assignment ()],
83+ )
5784
58- Args:
59- updated_node: The class definition to update.
85+ # Insert the new statement after the last attribute assignment
86+ if last_attribute is not None :
87+ new_body = list (updated_node .body .body )
88+ index = new_body .index (last_attribute )
89+ new_body .insert (index + 1 , new_statement )
90+ else :
91+ new_body = [new_statement ] + list (updated_node .body .body )
6092
61- Returns: The updated class definition.
62- """
63- for body_item in updated_node .body .body :
64- if isinstance (body_item , cst .SimpleStatementLine ):
65- stmt = body_item .body [0 ]
66- if isinstance (stmt , cst .Assign ):
67- for target in stmt .targets :
68- if isinstance (target .target , cst .Name ) and target .target .value == 'requires' :
69- return self ._replace_requires (updated_node , body_item , stmt )
70-
71- new_stmt = self ._create_requires_assignment ()
72- return updated_node .with_changes (
73- body = updated_node .body .with_changes (body = [new_stmt ] + list (updated_node .body .body ))
74- )
93+ return updated_node .with_changes (body = updated_node .body .with_changes (body = new_body ))
7594
7695 def _replace_requires (
77- self , updated_node : cst .ClassDef , body_item : cst .SimpleStatementLine , stmt : cst .Assign
96+ self , updated_node : cst .ClassDef , body_statement_line : cst .SimpleStatementLine , assignment_statement : cst .Assign
7897 ) -> cst .ClassDef :
7998 """Replace the existing 'requires' assignment with a new one.
8099
81100 Args:
82101 updated_node (cst.ClassDef): The class definition to update.
83- body_item (cst.SimpleStatementLine): The body item containing the assignment.
84- stmt (cst.Assign): The existing assignment statement.
102+ body_statement_line (cst.SimpleStatementLine): The body item containing the assignment.
103+ assignment_statement (cst.Assign): The existing assignment statement.
85104
86105 Returns:
87106 cst.ClassDef: The updated class definition.
88107 """
89- new_value = cst .List ([cst .Element (cst .SimpleString (f'"{ dep .requires ()} "' )) for dep in self .dependencies ])
90- new_stmt = stmt .with_changes (value = new_value )
108+ new_value = cst .List ([
109+ cst .Element (cst .SimpleString (f'"{ dependency .requires ()} "' )) for dependency in self .dependencies
110+ ])
111+ new_assignment = assignment_statement .with_changes (value = new_value )
91112 return updated_node .with_changes (
92113 body = updated_node .body .with_changes (
93- body = [new_stmt if item is body_item else item for item in updated_node .body .body ]
114+ body = [new_assignment if item is body_statement_line else item for item in updated_node .body .body ]
94115 )
95116 )
96117
0 commit comments