9
9
10
10
from _types import AllPatches , Patch , ResourcePatches
11
11
12
+ from cfnlint .schema .resolver import RefResolver
13
+
12
14
skip = [
13
15
"account" ,
14
16
"chime" ,
@@ -90,12 +92,63 @@ def get_last_date(service_dir: Path) -> str:
90
92
return last_date
91
93
92
94
95
+ def _nested_objects (
96
+ resolver : RefResolver ,
97
+ schema_data : dict [str , Any ],
98
+ boto_data : dict [str , Any ],
99
+ shape_data : dict [str , Any ],
100
+ start_path : str ,
101
+ source : list [str ],
102
+ ):
103
+ results = {}
104
+ for member , member_data in shape_data .get ("members" , {}).items ():
105
+ for p_name , p_data in schema_data .get ("properties" , {}).items ():
106
+ if p_name in skip_property_names :
107
+ continue
108
+ if p_name .lower () == member .lower ():
109
+
110
+ path = f"{ start_path } /properties/{ p_name } "
111
+
112
+ while True :
113
+ if "$ref" not in p_data :
114
+ break
115
+ path = p_data ["$ref" ][1 :]
116
+ p_data = resolver .resolve_from_url (p_data ["$ref" ])
117
+
118
+ # skip if we already have an enum or pattern
119
+ if any ([p_data .get (field ) for field in _fields ]):
120
+ continue
121
+
122
+ member_shape_name = member_data .get ("shape" )
123
+ member_shape = boto_data .get ("shapes" , {}).get (member_shape_name , {})
124
+
125
+ if member_shape .get ("type" ) == "structure" :
126
+ if p_data .get ("type" ) == "object" :
127
+ results .update (
128
+ _nested_objects (
129
+ resolver , p_data , boto_data , member_shape , path , source
130
+ )
131
+ )
132
+
133
+ if not any ([member_shape .get (field ) for field in _fields ]):
134
+ continue
135
+
136
+ results [path ] = Patch (
137
+ source = source ,
138
+ shape = member_shape_name ,
139
+ )
140
+
141
+ return results
142
+
143
+
93
144
def _per_resource_patch (
94
145
schema_data : dict [str , Any ], boto_data : dict [str , Any ], source : list [str ]
95
146
) -> ResourcePatches :
96
147
results : ResourcePatches = {}
97
148
create_operations = get_schema_create_operations (schema_data )
98
149
shapes = {}
150
+
151
+ resolver = RefResolver .from_schema (schema_data )
99
152
for create_operation in create_operations :
100
153
shapes .update (get_shapes (boto_data , create_operation ))
101
154
create_shape = (
@@ -105,39 +158,16 @@ def _per_resource_patch(
105
158
.get ("shape" )
106
159
)
107
160
108
- for member , member_data in (
109
- boto_data .get ("shapes" , {}).get (create_shape , {}).get ("members" , {}).items ()
110
- ):
111
- for p_name , p_data in schema_data .get ("properties" , {}).items ():
112
- if p_name in skip_property_names :
113
- continue
114
- if p_name .lower () == member .lower ():
115
-
116
- path = f"/properties/{ p_name } "
117
-
118
- if "$ref" in p_data :
119
- pointer = p_data ["$ref" ].split ("/" )
120
- p_data = schema_data .get (pointer [1 ], {}).get (pointer [2 ], {})
121
- if not p_data :
122
- continue
123
- path = f"/{ '/' .join (pointer [1 :])} "
124
-
125
- # skip if we already have an enum or pattern
126
- if any ([p_data .get (field ) for field in _fields ]):
127
- continue
128
-
129
- member_shape_name = member_data .get ("shape" )
130
- member_shape = boto_data .get ("shapes" , {}).get (
131
- member_shape_name , {}
132
- )
133
-
134
- if not any ([member_shape .get (field ) for field in _fields ]):
135
- continue
136
-
137
- results [path ] = Patch (
138
- source = source ,
139
- shape = member_shape_name ,
140
- )
161
+ results .update (
162
+ _nested_objects (
163
+ resolver ,
164
+ schema_data ,
165
+ boto_data ,
166
+ boto_data .get ("shapes" , {}).get (create_shape , {}),
167
+ "" ,
168
+ source ,
169
+ )
170
+ )
141
171
142
172
return results
143
173
0 commit comments