@@ -19,17 +19,19 @@ const LOCAL_DEPENDENCIES_FOLDER: &str = "local_dependencies";
19
19
/// This method is rather frail, but unfortunately I don't know a better solution.
20
20
fn rewrite_cargo_toml (
21
21
manifest_path : impl AsRef < Path > ,
22
+ workspace_manifest : & toml_edit:: Document ,
22
23
known_path_deps : & HashMap < String , PathBuf > ,
23
24
local_deps_folder : String ,
24
25
root_crate : bool ,
25
26
) -> Result < String > {
27
+ let manifest_path = manifest_path. as_ref ( ) ;
26
28
let text = fs:: read_to_string ( & manifest_path) . context ( format ! (
27
29
"Can't read Cargo.toml at {}" ,
28
- manifest_path. as_ref ( ) . display( ) ,
30
+ manifest_path. display( ) ,
29
31
) ) ?;
30
32
let mut data = text. parse :: < toml_edit:: Document > ( ) . context ( format ! (
31
33
"Failed to parse Cargo.toml at {}" ,
32
- manifest_path. as_ref ( ) . display( )
34
+ manifest_path. display( )
33
35
) ) ?;
34
36
let mut rewritten = false ;
35
37
// ˇˇˇˇˇˇˇˇˇˇˇˇ dep_category
@@ -39,6 +41,10 @@ fn rewrite_cargo_toml(
39
41
// ^^^^^^^^^^^^^ dep_name
40
42
for dep_category in & [ "dependencies" , "dev-dependencies" , "build-dependencies" ] {
41
43
if let Some ( table) = data. get_mut ( * dep_category) . and_then ( |x| x. as_table_mut ( ) ) {
44
+ let workspace_deps = workspace_manifest
45
+ . get ( "workspace" )
46
+ . and_then ( |x| x. get ( dep_category) )
47
+ . and_then ( |x| x. as_table ( ) ) ;
42
48
let dep_names: Vec < _ > = table. iter ( ) . map ( |( key, _) | key. to_string ( ) ) . collect ( ) ;
43
49
for dep_name in dep_names {
44
50
let workspace_inherit = table
@@ -55,19 +61,63 @@ fn rewrite_cargo_toml(
55
61
if !table[ & dep_name] [ "path" ] . is_str ( ) {
56
62
bail ! (
57
63
"In {}, {} {} has a path value that is not a string" ,
58
- manifest_path. as_ref ( ) . display( ) ,
64
+ manifest_path. display( ) ,
59
65
dep_category,
60
66
dep_name
61
67
)
62
68
}
69
+ } else {
70
+ // If a workspace inherited dependency isn't a path dep,
71
+ // we need to replace `workspace = true` with its full requirement spec.
72
+ if !known_path_deps. contains_key ( & dep_name) {
73
+ if let Some ( workspace_dep) = workspace_deps. and_then ( |x| x. get ( & dep_name) ) {
74
+ let mut workspace_dep = workspace_dep. clone ( ) ;
75
+ // Merge optional and features from the current Cargo.toml
76
+ if table[ & dep_name] . get ( "optional" ) . is_some ( ) {
77
+ workspace_dep[ "optional" ] = table[ & dep_name] [ "optional" ] . clone ( ) ;
78
+ }
79
+ if let Some ( features) =
80
+ table[ & dep_name] . get ( "features" ) . and_then ( |x| x. as_array ( ) )
81
+ {
82
+ let existing_features = workspace_dep
83
+ . as_table_like_mut ( )
84
+ . unwrap ( )
85
+ . entry ( "features" )
86
+ . or_insert_with ( || {
87
+ toml_edit:: Item :: Value ( toml_edit:: Array :: new ( ) . into ( ) )
88
+ } )
89
+ . as_array_mut ( )
90
+ . with_context ( || {
91
+ format ! (
92
+ "In {}, {} {} has a features value that is not an array" ,
93
+ manifest_path. display( ) ,
94
+ dep_category,
95
+ dep_name
96
+ )
97
+ } ) ?;
98
+ existing_features. extend ( features) ;
99
+ }
100
+ table[ & dep_name] = workspace_dep;
101
+ rewritten = true ;
102
+ } else {
103
+ bail ! (
104
+ "In {}, {} {} is marked as `workspace = true`, but it is found neither in \
105
+ the workspace manifest nor in the known path dependencies",
106
+ manifest_path. display( ) ,
107
+ dep_category,
108
+ dep_name
109
+ )
110
+ }
111
+ continue ;
112
+ }
63
113
}
64
114
if !known_path_deps. contains_key ( & dep_name) {
65
115
bail ! (
66
116
"cargo metadata does not know about the path for {}.{} present in {}, \
67
117
which should never happen ಠ_ಠ",
68
118
dep_category,
69
119
dep_name,
70
- manifest_path. as_ref ( ) . display( )
120
+ manifest_path. display( )
71
121
) ;
72
122
}
73
123
// This is the location of the targeted crate in the source distribution
@@ -136,6 +186,7 @@ fn add_crate_to_source_distribution(
136
186
writer : & mut SDistWriter ,
137
187
pyproject_toml_path : impl AsRef < Path > ,
138
188
manifest_path : impl AsRef < Path > ,
189
+ workspace_manifest : & toml_edit:: Document ,
139
190
prefix : impl AsRef < Path > ,
140
191
known_path_deps : & HashMap < String , PathBuf > ,
141
192
root_crate : bool ,
@@ -230,6 +281,7 @@ fn add_crate_to_source_distribution(
230
281
} ;
231
282
let rewritten_cargo_toml = rewrite_cargo_toml (
232
283
& manifest_path,
284
+ workspace_manifest,
233
285
known_path_deps,
234
286
local_deps_folder,
235
287
root_crate,
@@ -296,6 +348,12 @@ pub fn source_distribution(
296
348
let metadata21 = & build_context. metadata21 ;
297
349
let manifest_path = & build_context. manifest_path ;
298
350
let pyproject_toml_path = fs:: canonicalize ( & build_context. pyproject_toml_path ) ?;
351
+ let workspace_manifest_path = build_context
352
+ . cargo_metadata
353
+ . workspace_root
354
+ . join ( "Cargo.toml" ) ;
355
+ let workspace_manifest: toml_edit:: Document =
356
+ fs:: read_to_string ( & workspace_manifest_path) ?. parse ( ) ?;
299
357
300
358
let known_path_deps = find_path_deps ( & build_context. cargo_metadata ) ?;
301
359
@@ -312,6 +370,7 @@ pub fn source_distribution(
312
370
& mut writer,
313
371
& pyproject_toml_path,
314
372
& path_dep,
373
+ & workspace_manifest,
315
374
& root_dir. join ( LOCAL_DEPENDENCIES_FOLDER ) . join ( name) ,
316
375
& known_path_deps,
317
376
false ,
@@ -328,6 +387,7 @@ pub fn source_distribution(
328
387
& mut writer,
329
388
& pyproject_toml_path,
330
389
& manifest_path,
390
+ & workspace_manifest,
331
391
& root_dir,
332
392
& known_path_deps,
333
393
true ,
0 commit comments