@@ -47,7 +47,129 @@ def logger_debug(*args):
47
47
return logger .debug (" " .join (isinstance (a , str ) and a or repr (a ) for a in args ))
48
48
49
49
50
- class SwiftShowDependenciesDepLockHandler (models .DatafileHandler ):
50
+ class BaseSwiftDatafileHandler (models .DatafileHandler ):
51
+ @classmethod
52
+ def assemble (cls , package_data , resource , codebase , package_adder ):
53
+ swift_manifest_resource = None
54
+ swift_show_dependencies_resource = None
55
+ swift_resolved_package_resource = None
56
+ processed_package = None
57
+ add_datafile_paths = []
58
+ add_datasource_ids = []
59
+ processed_dependencies = []
60
+
61
+ for r in resource .siblings (codebase ):
62
+ if r .name in ("Package.swift.json" , "Package.swift.deplock" ):
63
+ swift_manifest_resource = r
64
+ elif r .name in ("Package.resolved" , ".package.resolved" ):
65
+ swift_resolved_package_resource = r
66
+ elif r .name == "swift-show-dependencies.deplock" :
67
+ swift_show_dependencies_resource = r
68
+
69
+ # If only Package.resolved is available then yield all dependency as package.
70
+ if (
71
+ not swift_manifest_resource
72
+ and not swift_show_dependencies_resource
73
+ and resource .name in ("Package.resolved" , ".package.resolved" )
74
+ ):
75
+ processed_package = package_data
76
+ processed_dependencies = package_data .dependencies
77
+ # If no manifest but have dependency graph from `deplock` then use it construct top-level package.
78
+ elif (
79
+ not swift_manifest_resource
80
+ and resource .name == "swift-show-dependencies.deplock"
81
+ ):
82
+ processed_package = package_data
83
+ processed_dependencies = package_data .dependencies
84
+ # If manifest is available then use the manifest to construct top-level package.
85
+ elif swift_manifest_resource and resource .name in (
86
+ "Package.swift.json" ,
87
+ "Package.swift.deplock" ,
88
+ ):
89
+ processed_dependencies = package_data .dependencies
90
+ # Dependencies from `swift-show-dependencies.deplock` supersedes dependencies from other datafiles.
91
+ if swift_show_dependencies_resource :
92
+ swift_show_dependencies_package_data = models .PackageData .from_dict (
93
+ swift_show_dependencies_resource .package_data [0 ]
94
+ )
95
+ processed_dependencies = (
96
+ swift_show_dependencies_package_data .dependencies
97
+ )
98
+ # Use dependencies from `Package.resolved` when `swift-show-dependencies.deplock` is not present.
99
+ elif swift_resolved_package_resource :
100
+ swift_resolved_package_data = (
101
+ swift_resolved_package_resource .package_data
102
+ )
103
+
104
+ resolved_dependencies = []
105
+ for package in swift_resolved_package_data :
106
+ version = package .get ("version" )
107
+ name = package .get ("name" )
108
+
109
+ purl = PackageURL (
110
+ type = cls .default_package_type , name = name , version = version
111
+ )
112
+ resolved_dependencies .append (
113
+ models .DependentPackage (
114
+ purl = purl .to_string (),
115
+ scope = "dependencies" ,
116
+ is_runtime = True ,
117
+ is_optional = False ,
118
+ is_resolved = True ,
119
+ extracted_requirement = version ,
120
+ )
121
+ )
122
+
123
+ for dependency in processed_dependencies [:]:
124
+ dependency_purl = PackageURL .from_string (dependency .purl )
125
+
126
+ if dependency_purl .name == name :
127
+ processed_dependencies .remove (dependency )
128
+
129
+ processed_dependencies .extend (resolved_dependencies )
130
+
131
+ processed_package = package_data
132
+ if swift_show_dependencies_resource :
133
+ add_datafile_paths .append (swift_show_dependencies_resource .path )
134
+ add_datasource_ids .append (
135
+ SwiftShowDependenciesDepLockHandler .datasource_id
136
+ )
137
+ elif swift_resolved_package_resource :
138
+ add_datafile_paths .append (swift_resolved_package_resource .path )
139
+ add_datasource_ids .append (SwiftPackageResolvedHandler .datasource_id )
140
+
141
+ if processed_package and processed_package .purl :
142
+ package = models .Package .from_package_data (
143
+ package_data = processed_package ,
144
+ datafile_path = resource .path ,
145
+ )
146
+
147
+ package .datafile_paths .extend (add_datafile_paths )
148
+ package .datasource_ids .extend (add_datasource_ids )
149
+
150
+ package .populate_license_fields ()
151
+ yield package
152
+
153
+ parent = resource .parent (codebase )
154
+ cls .assign_package_to_resources (
155
+ package = package ,
156
+ resource = parent ,
157
+ codebase = codebase ,
158
+ package_adder = package_adder ,
159
+ )
160
+
161
+ if processed_dependencies :
162
+ yield from models .Dependency .from_dependent_packages (
163
+ dependent_packages = processed_dependencies ,
164
+ datafile_path = resource .path ,
165
+ datasource_id = processed_package .datasource_id ,
166
+ package_uid = package .package_uid ,
167
+ )
168
+
169
+ yield resource
170
+
171
+
172
+ class SwiftShowDependenciesDepLockHandler (BaseSwiftDatafileHandler ):
51
173
datasource_id = "swift_package_show_dependencies"
52
174
path_patterns = ("*/swift-show-dependencies.deplock" ,)
53
175
default_package_type = "swift"
@@ -86,32 +208,8 @@ def parse(cls, location, package_only=False):
86
208
87
209
yield cls ._parse (swift_dependency_relation , package_only )
88
210
89
- @classmethod
90
- def assemble (
91
- cls , package_data , resource , codebase , package_adder = models .add_to_package
92
- ):
93
- siblings = resource .siblings (codebase )
94
- swift_manifest_resource = [
95
- r
96
- for r in siblings
97
- if r .name in ("Package.swift.json" , "Package.swift.deplock" )
98
- ]
99
-
100
- # Skip the assembly if the Swift manifest is present.
101
- # SwiftManifestJsonHandler's assembly will take care of the
102
- # dependencies from swift-show-dependencies.deplock file.
103
- if swift_manifest_resource :
104
- return []
105
-
106
- yield from super (SwiftShowDependenciesDepLockHandler , cls ).assemble (
107
- package_data = package_data ,
108
- resource = resource ,
109
- codebase = codebase ,
110
- package_adder = package_adder ,
111
- )
112
211
113
-
114
- class SwiftManifestJsonHandler (models .DatafileHandler ):
212
+ class SwiftManifestJsonHandler (BaseSwiftDatafileHandler ):
115
213
datasource_id = "swift_package_manifest_json"
116
214
path_patterns = ("*/Package.swift.json" , "*/Package.swift.deplock" )
117
215
default_package_type = "swift"
@@ -149,116 +247,8 @@ def parse(cls, location, package_only=False):
149
247
150
248
yield cls ._parse (swift_manifest , package_only )
151
249
152
- @classmethod
153
- def assemble (
154
- cls ,
155
- package_data ,
156
- resource ,
157
- codebase ,
158
- package_adder = models .add_to_package ,
159
- ):
160
- """
161
- Use the dependencies from `Package.resolved` to create the
162
- top-level package with resolved dependencies.
163
- """
164
- siblings = resource .siblings (codebase )
165
- processed_dependencies = []
166
- swift_resolved_package_resource = [
167
- r for r in siblings if r .name == "Package.resolved"
168
- ]
169
-
170
- swift_show_dependencies_resources = [
171
- r for r in siblings if r .name == "swift-show-dependencies.deplock"
172
- ]
173
-
174
- if swift_show_dependencies_resources :
175
- swift_show_dependencies_resource = swift_show_dependencies_resources [0 ]
176
- swift_show_dependencies_package_data = (
177
- swift_show_dependencies_resource .package_data
178
- )
179
-
180
- # Dependencies from `swift-show-dependencies.deplock` supersede dependencies from other datafiles.
181
- processed_dependencies = swift_show_dependencies_package_data [0 ][
182
- "dependencies"
183
- ]
184
- processed_dependencies = [
185
- models .DependentPackage .from_dict (i ) for i in processed_dependencies
186
- ]
187
-
188
- # Use dependencies from `Package.resolved` when `swift-show-dependencies.deplock` is not present.
189
- else :
190
- dependencies_from_manifest = package_data .dependencies
191
-
192
- if swift_resolved_package_resource :
193
- swift_resolved_package_resource = swift_resolved_package_resource [0 ]
194
- swift_resolved_package_data = (
195
- swift_resolved_package_resource .package_data
196
- )
197
-
198
- for package in swift_resolved_package_data :
199
- version = package .get ("version" )
200
- name = package .get ("name" )
201
-
202
- purl = PackageURL (
203
- type = cls .default_package_type , name = name , version = version
204
- )
205
- processed_dependencies .append (
206
- models .DependentPackage (
207
- purl = purl .to_string (),
208
- scope = "dependencies" ,
209
- is_runtime = True ,
210
- is_optional = False ,
211
- is_resolved = True ,
212
- extracted_requirement = version ,
213
- )
214
- )
215
-
216
- for dependency in dependencies_from_manifest [:]:
217
- dependency_purl = PackageURL .from_string (dependency .purl )
218
-
219
- if dependency_purl .name == name :
220
- dependencies_from_manifest .remove (dependency )
221
250
222
- processed_dependencies .extend (dependencies_from_manifest )
223
-
224
- datafile_path = resource .path
225
- if package_data .purl :
226
- package = models .Package .from_package_data (
227
- package_data = package_data ,
228
- datafile_path = datafile_path ,
229
- )
230
-
231
- if swift_show_dependencies_resources :
232
- package .datafile_paths .append (swift_show_dependencies_resource .path )
233
- package .datasource_ids .append (
234
- SwiftShowDependenciesDepLockHandler .datasource_id
235
- )
236
- elif swift_resolved_package_resource :
237
- package .datafile_paths .append (swift_resolved_package_resource .path )
238
- package .datasource_ids .append (SwiftPackageResolvedHandler .datasource_id )
239
-
240
- package .populate_license_fields ()
241
- yield package
242
-
243
- parent = resource .parent (codebase )
244
- cls .assign_package_to_resources (
245
- package = package ,
246
- resource = parent ,
247
- codebase = codebase ,
248
- package_adder = package_adder ,
249
- )
250
-
251
- if processed_dependencies :
252
- yield from models .Dependency .from_dependent_packages (
253
- dependent_packages = processed_dependencies ,
254
- datafile_path = datafile_path ,
255
- datasource_id = package_data .datasource_id ,
256
- package_uid = package .package_uid ,
257
- )
258
- yield resource
259
-
260
-
261
- class SwiftPackageResolvedHandler (models .DatafileHandler ):
251
+ class SwiftPackageResolvedHandler (BaseSwiftDatafileHandler ):
262
252
datasource_id = "swift_package_resolved"
263
253
path_patterns = ("*/Package.resolved" , "*/.package.resolved" )
264
254
default_package_type = "swift"
@@ -282,30 +272,6 @@ def parse(cls, location, package_only=False):
282
272
if resolved_doc_version == 1 :
283
273
yield from packages_from_resolved_v1 (package_resolved )
284
274
285
- @classmethod
286
- def assemble (
287
- cls , package_data , resource , codebase , package_adder = models .add_to_package
288
- ):
289
- siblings = resource .siblings (codebase )
290
- swift_manifest_resource = [
291
- r
292
- for r in siblings
293
- if r .name in ("Package.swift.json" , "Package.swift.deplock" )
294
- ]
295
-
296
- # Skip the assembly if the ``Package.swift.json`` manifest is present.
297
- # SwiftManifestJsonHandler's assembly will take care of the resolved
298
- # dependencies from Package.resolved file.
299
- if swift_manifest_resource :
300
- return []
301
-
302
- yield from super (SwiftPackageResolvedHandler , cls ).assemble (
303
- package_data = package_data ,
304
- resource = resource ,
305
- codebase = codebase ,
306
- package_adder = package_adder ,
307
- )
308
-
309
275
310
276
def packages_from_resolved_v2_and_v3 (package_resolved ):
311
277
pinned = package_resolved .get ("pins" , [])
0 commit comments