21
21
"""
22
22
23
23
24
- class CargoTomlHandler (models .DatafileHandler ):
25
- datasource_id = 'cargo_toml'
26
- path_patterns = ('*/Cargo.toml' , '*/cargo.toml' ,)
27
- default_package_type = 'cargo'
28
- default_primary_language = 'Rust'
29
- description = 'Rust Cargo.toml package manifest'
30
- documentation_url = 'https://doc.rust-lang.org/cargo/reference/manifest.html'
31
-
32
- @classmethod
33
- def parse (cls , location ):
34
- package_data = toml .load (location , _dict = dict )
35
- core_package_data = package_data .get ('package' , {})
36
- workspace = package_data .get ('workspace' , {})
37
-
38
- name = core_package_data .get ('name' )
39
- version = core_package_data .get ('version' )
40
- description = core_package_data .get ('description' ) or ''
41
- description = description .strip ()
42
-
43
- authors = core_package_data .get ('authors' ) or []
44
- parties = list (get_parties (person_names = authors , party_role = 'author' ))
45
-
46
- extracted_license_statement = core_package_data .get ('license' )
47
- # TODO: load as a notice_text
48
- license_file = core_package_data .get ('license-file' )
49
-
50
- keywords = core_package_data .get ('keywords' ) or []
51
- categories = core_package_data .get ('categories' ) or []
52
- keywords .extend (categories )
53
-
54
- # cargo dependencies are complex and can be overriden at multiple levels
55
- dependencies = []
56
- for key , value in core_package_data .items ():
57
- if key .endswith ('dependencies' ):
58
- dependencies .extend (dependency_mapper (dependencies = value , scope = key ))
59
-
60
- # TODO: add file refs:
61
- # - readme, include and exclude
62
- # TODO: other URLs
63
- # - documentation
64
-
65
- vcs_url = core_package_data .get ('repository' )
66
- homepage_url = core_package_data .get ('homepage' )
67
- repository_homepage_url = name and f'https://crates.io/crates/{ name } '
68
- repository_download_url = name and version and f'https://crates.io/api/v1/crates/{ name } /{ version } /download'
69
- api_data_url = name and f'https://crates.io/api/v1/crates/{ name } '
70
- extra_data = {}
71
- if workspace :
72
- extra_data ["workspace" ] = workspace
73
-
74
- yield models .PackageData (
75
- datasource_id = cls .datasource_id ,
76
- type = cls .default_package_type ,
77
- name = name ,
78
- version = version ,
79
- primary_language = cls .default_primary_language ,
80
- description = description ,
81
- parties = parties ,
82
- extracted_license_statement = extracted_license_statement ,
83
- vcs_url = vcs_url ,
84
- homepage_url = homepage_url ,
85
- repository_homepage_url = repository_homepage_url ,
86
- repository_download_url = repository_download_url ,
87
- api_data_url = api_data_url ,
88
- dependencies = dependencies ,
89
- extra_data = extra_data ,
90
- )
91
-
24
+ class CargoBaseHandler (models .DatafileHandler ):
92
25
@classmethod
93
26
def assemble (cls , package_data , resource , codebase , package_adder ):
94
27
"""
@@ -161,6 +94,79 @@ def update_resource_package_data(cls, package_data, old_package_data, mapping=No
161
94
return old_package_data
162
95
163
96
97
+
98
+ class CargoTomlHandler (CargoBaseHandler ):
99
+ datasource_id = 'cargo_toml'
100
+ path_patterns = ('*/Cargo.toml' , '*/cargo.toml' ,)
101
+ default_package_type = 'cargo'
102
+ default_primary_language = 'Rust'
103
+ description = 'Rust Cargo.toml package manifest'
104
+ documentation_url = 'https://doc.rust-lang.org/cargo/reference/manifest.html'
105
+
106
+ @classmethod
107
+ def parse (cls , location ):
108
+ package_data = toml .load (location , _dict = dict )
109
+ core_package_data = package_data .get ('package' , {})
110
+ workspace = package_data .get ('workspace' , {})
111
+
112
+ name = core_package_data .get ('name' )
113
+ version = core_package_data .get ('version' )
114
+ if isinstance (version , dict ) and "workspace" in version :
115
+ version = "workspace"
116
+
117
+ description = core_package_data .get ('description' ) or ''
118
+ description = description .strip ()
119
+
120
+ authors = core_package_data .get ('authors' ) or []
121
+ parties = list (get_parties (person_names = authors , party_role = 'author' ))
122
+
123
+ extracted_license_statement = core_package_data .get ('license' )
124
+ # TODO: load as a notice_text
125
+ license_file = core_package_data .get ('license-file' )
126
+
127
+ keywords = core_package_data .get ('keywords' ) or []
128
+ categories = core_package_data .get ('categories' ) or []
129
+ keywords .extend (categories )
130
+
131
+ # cargo dependencies are complex and can be overriden at multiple levels
132
+ dependencies = []
133
+ for key , value in core_package_data .items ():
134
+ if key .endswith ('dependencies' ):
135
+ dependencies .extend (dependency_mapper (dependencies = value , scope = key ))
136
+
137
+ # TODO: add file refs:
138
+ # - readme, include and exclude
139
+ # TODO: other URLs
140
+ # - documentation
141
+
142
+ vcs_url = core_package_data .get ('repository' )
143
+ homepage_url = core_package_data .get ('homepage' )
144
+ repository_homepage_url = name and f'https://crates.io/crates/{ name } '
145
+ repository_download_url = name and version and f'https://crates.io/api/v1/crates/{ name } /{ version } /download'
146
+ api_data_url = name and f'https://crates.io/api/v1/crates/{ name } '
147
+ extra_data = {}
148
+ if workspace :
149
+ extra_data ["workspace" ] = workspace
150
+
151
+ yield models .PackageData (
152
+ datasource_id = cls .datasource_id ,
153
+ type = cls .default_package_type ,
154
+ name = name ,
155
+ version = version ,
156
+ primary_language = cls .default_primary_language ,
157
+ description = description ,
158
+ parties = parties ,
159
+ extracted_license_statement = extracted_license_statement ,
160
+ vcs_url = vcs_url ,
161
+ homepage_url = homepage_url ,
162
+ repository_homepage_url = repository_homepage_url ,
163
+ repository_download_url = repository_download_url ,
164
+ api_data_url = api_data_url ,
165
+ dependencies = dependencies ,
166
+ extra_data = extra_data ,
167
+ )
168
+
169
+
164
170
CARGO_ATTRIBUTE_MAPPING = {
165
171
# Fields in PackageData model: Fields in cargo
166
172
"homepage_url" : "homepage" ,
@@ -173,7 +179,8 @@ def update_resource_package_data(cls, package_data, old_package_data, mapping=No
173
179
"declared_license_expression_spdx" : "declared_license_expression_spdx" ,
174
180
}
175
181
176
- class CargoLockHandler (models .DatafileHandler ):
182
+
183
+ class CargoLockHandler (CargoBaseHandler ):
177
184
datasource_id = 'cargo_lock'
178
185
path_patterns = ('*/Cargo.lock' , '*/cargo.lock' ,)
179
186
default_package_type = 'cargo'
@@ -220,18 +227,6 @@ def parse(cls, location):
220
227
dependencies = dependencies ,
221
228
)
222
229
223
- @classmethod
224
- def assemble (cls , package_data , resource , codebase , package_adder ):
225
- """
226
- Assemble Cargo.toml and possible Cargo.lock datafiles
227
- """
228
- yield from cls .assemble_from_many_datafiles (
229
- datafile_name_patterns = ('Cargo.toml' , 'Cargo.lock' ,),
230
- directory = resource .parent (codebase ),
231
- codebase = codebase ,
232
- package_adder = package_adder ,
233
- )
234
-
235
230
236
231
def dependency_mapper (dependencies , scope = 'dependencies' ):
237
232
"""
@@ -261,13 +256,11 @@ def dependency_mapper(dependencies, scope='dependencies'):
261
256
)
262
257
263
258
264
- def get_parties (person_names , party_role , debug = False ):
259
+ def get_parties (person_names , party_role ):
265
260
"""
266
261
Yields Party of `party_role` given a list of ``person_names`` strings.
267
262
https://doc.rust-lang.org/cargo/reference/manifest.html#the-authors-field-optional
268
263
"""
269
- if debug :
270
- raise Exception (person_names )
271
264
for person_name in person_names :
272
265
name , email = parse_person (person_name )
273
266
yield models .Party (
0 commit comments