1
1
import { logger } from '../../../logger' ;
2
- import type { SkipReason } from '../../../types' ;
3
2
import { coerceArray } from '../../../util/array' ;
4
3
import { findLocalSiblingOrParent , readLocalFile } from '../../../util/fs' ;
5
- import { parse as parseToml } from '../../../util/toml' ;
6
- import { CrateDatasource } from '../../datasource/crate' ;
7
4
import { api as versioning } from '../../versioning/cargo' ;
8
5
import type {
9
6
ExtractConfig ,
10
7
PackageDependency ,
11
8
PackageFileContent ,
12
9
} from '../types' ;
13
10
import { extractLockFileVersions } from './locked-version' ;
11
+ import {
12
+ type CargoConfig ,
13
+ CargoConfigSchema ,
14
+ CargoManifestSchema ,
15
+ } from './schema' ;
14
16
import type {
15
- CargoConfig ,
16
- CargoManifest ,
17
+ CargoManagerData ,
17
18
CargoRegistries ,
18
19
CargoRegistryUrl ,
19
- CargoSection ,
20
20
} from './types' ;
21
21
import { DEFAULT_REGISTRY_URL } from './utils' ;
22
22
@@ -28,75 +28,32 @@ function getCargoIndexEnv(registryName: string): string | null {
28
28
}
29
29
30
30
function extractFromSection (
31
- parsedContent : CargoSection ,
32
- section : keyof CargoSection ,
31
+ dependencies : PackageDependency < CargoManagerData > [ ] | undefined ,
33
32
cargoRegistries : CargoRegistries ,
34
33
target ?: string ,
35
- depTypeOverride ?: string ,
36
34
) : PackageDependency [ ] {
37
- const deps : PackageDependency [ ] = [ ] ;
38
- const sectionContent = parsedContent [ section ] ;
39
- if ( ! sectionContent ) {
35
+ if ( ! dependencies ) {
40
36
return [ ] ;
41
37
}
42
- Object . keys ( sectionContent ) . forEach ( ( depName ) => {
43
- let skipReason : SkipReason | undefined ;
44
- let currentValue = sectionContent [ depName ] ;
45
- let nestedVersion = false ;
46
- let registryUrls : string [ ] | undefined ;
47
- let packageName : string | undefined ;
48
-
49
- if ( typeof currentValue !== 'string' ) {
50
- const version = currentValue . version ;
51
- const path = currentValue . path ;
52
- const git = currentValue . git ;
53
- const registryName = currentValue . registry ;
54
- const workspace = currentValue . workspace ;
55
38
56
- packageName = currentValue . package ;
39
+ const deps : PackageDependency < CargoManagerData > [ ] = [ ] ;
57
40
58
- if ( version ) {
59
- currentValue = version ;
60
- nestedVersion = true ;
61
- if ( registryName ) {
62
- const registryUrl =
63
- getCargoIndexEnv ( registryName ) ?? cargoRegistries [ registryName ] ;
41
+ for ( const dep of Object . values ( dependencies ) ) {
42
+ let registryUrls : string [ ] | undefined ;
64
43
65
- if ( registryUrl ) {
66
- if ( registryUrl !== DEFAULT_REGISTRY_URL ) {
67
- registryUrls = [ registryUrl ] ;
68
- }
69
- } else {
70
- skipReason = 'unknown-registry' ;
71
- }
72
- }
73
- if ( path ) {
74
- skipReason = 'path-dependency' ;
75
- }
76
- if ( git ) {
77
- skipReason = 'git-dependency' ;
44
+ if ( dep . managerData ?. registryName ) {
45
+ const registryUrl =
46
+ getCargoIndexEnv ( dep . managerData . registryName ) ??
47
+ cargoRegistries [ dep . managerData ?. registryName ] ;
48
+ if ( registryUrl ) {
49
+ if ( registryUrl !== DEFAULT_REGISTRY_URL ) {
50
+ registryUrls = [ registryUrl ] ;
78
51
}
79
- } else if ( path ) {
80
- currentValue = '' ;
81
- skipReason = 'path-dependency' ;
82
- } else if ( git ) {
83
- currentValue = '' ;
84
- skipReason = 'git-dependency' ;
85
- } else if ( workspace ) {
86
- currentValue = '' ;
87
- skipReason = 'inherited-dependency' ;
88
52
} else {
89
- currentValue = '' ;
90
- skipReason = 'invalid-dependency-specification' ;
53
+ dep . skipReason = 'unknown-registry' ;
91
54
}
92
55
}
93
- const dep : PackageDependency = {
94
- depName,
95
- depType : section ,
96
- currentValue : currentValue as any ,
97
- managerData : { nestedVersion } ,
98
- datasource : CrateDatasource . id ,
99
- } ;
56
+
100
57
if ( registryUrls ) {
101
58
dep . registryUrls = registryUrls ;
102
59
} else {
@@ -108,24 +65,16 @@ function extractFromSection(
108
65
} else {
109
66
// we always expect to have DEFAULT_REGISTRY_ID set, if it's not it means the config defines an alternative
110
67
// registry that we couldn't resolve.
111
- skipReason = 'unknown-registry' ;
68
+ dep . skipReason = 'unknown-registry' ;
112
69
}
113
70
}
114
71
115
- if ( skipReason ) {
116
- dep . skipReason = skipReason ;
117
- }
118
72
if ( target ) {
119
73
dep . target = target ;
120
74
}
121
- if ( packageName ) {
122
- dep . packageName = packageName ;
123
- }
124
- if ( depTypeOverride ) {
125
- dep . depType = depTypeOverride ;
126
- }
127
75
deps . push ( dep ) ;
128
- } ) ;
76
+ }
77
+
129
78
return deps ;
130
79
}
131
80
@@ -135,12 +84,15 @@ async function readCargoConfig(): Promise<CargoConfig | null> {
135
84
const path = `.cargo/${ configName } ` ;
136
85
const payload = await readLocalFile ( path , 'utf8' ) ;
137
86
if ( payload ) {
138
- try {
139
- return parseToml ( payload ) as CargoConfig ;
140
- } catch ( err ) {
141
- logger . debug ( { err } , `Error parsing ${ path } ` ) ;
87
+ const parsedCargoConfig = CargoConfigSchema . safeParse ( payload ) ;
88
+ if ( parsedCargoConfig . success ) {
89
+ return parsedCargoConfig . data ;
90
+ } else {
91
+ logger . debug (
92
+ { err : parsedCargoConfig . error , path } ,
93
+ `Error parsing cargo config` ,
94
+ ) ;
142
95
}
143
- break ;
144
96
}
145
97
}
146
98
@@ -217,19 +169,23 @@ export async function extractPackageFile(
217
169
content : string ,
218
170
packageFile : string ,
219
171
_config ?: ExtractConfig ,
220
- ) : Promise < PackageFileContent | null > {
172
+ ) : Promise < PackageFileContent < CargoManagerData > | null > {
221
173
logger . trace ( `cargo.extractPackageFile(${ packageFile } )` ) ;
222
174
223
175
const cargoConfig = ( await readCargoConfig ( ) ) ?? { } ;
224
176
const cargoRegistries = extractCargoRegistries ( cargoConfig ) ;
225
177
226
- let cargoManifest : CargoManifest ;
227
- try {
228
- cargoManifest = parseToml ( content ) as CargoManifest ;
229
- } catch ( err ) {
230
- logger . debug ( { err, packageFile } , 'Error parsing Cargo.toml file' ) ;
178
+ const parsedCargoManifest = CargoManifestSchema . safeParse ( content ) ;
179
+ if ( ! parsedCargoManifest . success ) {
180
+ logger . debug (
181
+ { err : parsedCargoManifest . error , packageFile } ,
182
+ 'Error parsing Cargo.toml file' ,
183
+ ) ;
231
184
return null ;
232
185
}
186
+
187
+ const cargoManifest = parsedCargoManifest . data ;
188
+
233
189
/*
234
190
There are the following sections in Cargo.toml:
235
191
[package]
@@ -249,20 +205,17 @@ export async function extractPackageFile(
249
205
// Dependencies for `${target}`
250
206
const deps = [
251
207
...extractFromSection (
252
- targetContent ,
253
- 'dependencies' ,
208
+ targetContent . dependencies ,
254
209
cargoRegistries ,
255
210
target ,
256
211
) ,
257
212
...extractFromSection (
258
- targetContent ,
259
- 'dev-dependencies' ,
213
+ targetContent [ 'dev-dependencies' ] ,
260
214
cargoRegistries ,
261
215
target ,
262
216
) ,
263
217
...extractFromSection (
264
- targetContent ,
265
- 'build-dependencies' ,
218
+ targetContent [ 'build-dependencies' ] ,
266
219
cargoRegistries ,
267
220
target ,
268
221
) ,
@@ -275,18 +228,16 @@ export async function extractPackageFile(
275
228
let workspaceDeps : PackageDependency [ ] = [ ] ;
276
229
if ( workspaceSection ) {
277
230
workspaceDeps = extractFromSection (
278
- workspaceSection ,
279
- 'dependencies' ,
231
+ workspaceSection . dependencies ,
280
232
cargoRegistries ,
281
233
undefined ,
282
- 'workspace.dependencies' ,
283
234
) ;
284
235
}
285
236
286
237
const deps = [
287
- ...extractFromSection ( cargoManifest , ' dependencies' , cargoRegistries ) ,
288
- ...extractFromSection ( cargoManifest , 'dev-dependencies' , cargoRegistries ) ,
289
- ...extractFromSection ( cargoManifest , 'build-dependencies' , cargoRegistries ) ,
238
+ ...extractFromSection ( cargoManifest . dependencies , cargoRegistries ) ,
239
+ ...extractFromSection ( cargoManifest [ 'dev-dependencies' ] , cargoRegistries ) ,
240
+ ...extractFromSection ( cargoManifest [ 'build-dependencies' ] , cargoRegistries ) ,
290
241
...targetDeps ,
291
242
...workspaceDeps ,
292
243
] ;
0 commit comments