44
55use crate :: cargo:: manifest_analyzer:: DepKind ;
66use crate :: cargo:: manifest_ops;
7- use crate :: cargo:: unify_analyzer:: UnifiedDep ;
7+ use crate :: cargo:: unify_analyzer:: { TransitivePin , UnifiedDep } ;
88use crate :: error:: { RailResult , ResultExt } ;
99use crate :: toml:: format:: TomlFormatter ;
1010use std:: path:: Path ;
@@ -137,22 +137,22 @@ impl ManifestWriter {
137137 }
138138
139139 /// Add transitive dependencies for pinning (workspace-hack replacement)
140- pub fn add_transitive_pins (
141- & self ,
142- host_toml_path : & Path ,
143- transitives : & [ ( String , Vec < String > ) ] , // (dep_name, features)
144- ) -> RailResult < ( ) > {
140+ ///
141+ /// This adds entries with `workspace = true` to the host's dev-dependencies.
142+ /// IMPORTANT: The caller must ensure these deps are already in [workspace.dependencies]
143+ /// before calling this function. Use `write_transitive_workspace_deps` first.
144+ pub fn add_transitive_pins ( & self , host_toml_path : & Path , transitives : & [ TransitivePin ] ) -> RailResult < ( ) > {
145145 // Read host Cargo.toml (usually workspace root)
146146 let mut doc = manifest_ops:: read_toml_file ( host_toml_path) ?;
147147
148148 // Ensure [dev-dependencies] exists
149149 let dev_deps =
150150 manifest_ops:: get_or_create_table ( & mut doc, "dev-dependencies" ) . context ( "Failed to create [dev-dependencies]" ) ?;
151151
152- // Add each transitive as a dev dependency
153- for ( dep_name , features ) in transitives {
154- let entry = manifest_ops:: build_transitive_entry ( features) ;
155- manifest_ops:: insert_dependency ( dev_deps, dep_name , entry) . context ( "Failed to insert transitive dependency" ) ?;
152+ // Add each transitive as a dev dependency with workspace = true
153+ for pin in transitives {
154+ let entry = manifest_ops:: build_transitive_entry ( & pin . features ) ;
155+ manifest_ops:: insert_dependency ( dev_deps, & pin . name , entry) . context ( "Failed to insert transitive dependency" ) ?;
156156 }
157157
158158 // Format and write
@@ -162,6 +162,37 @@ impl ManifestWriter {
162162 Ok ( ( ) )
163163 }
164164
165+ /// Write transitive dependencies to [workspace.dependencies]
166+ ///
167+ /// This must be called BEFORE `add_transitive_pins` so that the deps exist
168+ /// in workspace.dependencies when referenced with `workspace = true`.
169+ pub fn write_transitive_workspace_deps (
170+ & self ,
171+ workspace_toml_path : & Path ,
172+ transitives : & [ TransitivePin ] ,
173+ ) -> RailResult < ( ) > {
174+ // Read workspace Cargo.toml
175+ let mut doc = manifest_ops:: read_toml_file ( workspace_toml_path) ?;
176+
177+ // Ensure [workspace.dependencies] exists
178+ manifest_ops:: ensure_section ( & mut doc, "workspace" ) . context ( "Failed to create [workspace] section" ) ?;
179+ let deps_table = manifest_ops:: get_or_create_table ( & mut doc, "workspace.dependencies" )
180+ . context ( "Failed to create [workspace.dependencies]" ) ?;
181+
182+ // Add each transitive dependency with version and features
183+ for pin in transitives {
184+ let entry = manifest_ops:: build_versioned_dep_entry ( & pin. version , & pin. features ) ;
185+ manifest_ops:: insert_dependency ( deps_table, & pin. name , entry)
186+ . context ( "Failed to insert transitive to workspace.dependencies" ) ?;
187+ }
188+
189+ // Format and write
190+ self . formatter . format_manifest ( & mut doc) ?;
191+ manifest_ops:: write_toml_file ( workspace_toml_path, & doc) ?;
192+
193+ Ok ( ( ) )
194+ }
195+
165196 /// Convert DepKind to Cargo.toml section name
166197 fn dep_kind_to_section ( & self , dep_kind : DepKind ) -> & ' static str {
167198 manifest_ops:: dep_kind_to_section ( dep_kind)
0 commit comments