1- use std:: collections:: BTreeMap ;
1+ use std:: { collections:: BTreeMap , str :: FromStr } ;
22
33use miette:: Diagnostic ;
44use pixi_build_discovery:: EnabledProtocols ;
55use pixi_build_types:: procedures:: conda_outputs:: { CondaOutput , CondaOutputDependencies } ;
66use pixi_record:: PinnedSourceSpec ;
7- use rattler_conda_types:: { ChannelConfig , ChannelUrl , PackageName } ;
7+ use pixi_spec:: { BinarySpec , PixiSpec } ;
8+ use pixi_spec_containers:: DependencyMap ;
9+ use rattler_conda_types:: { ChannelConfig , ChannelUrl , InvalidPackageNameError , PackageName } ;
810use thiserror:: Error ;
911use tracing:: instrument;
1012
1113use crate :: {
1214 BuildBackendMetadataError , BuildBackendMetadataSpec , BuildEnvironment , CommandDispatcher ,
1315 CommandDispatcherError , CommandDispatcherErrorResultExt ,
14- build:: source_metadata_cache:: MetadataKind ,
16+ build:: { conversion , source_metadata_cache:: MetadataKind } ,
1517} ;
1618
1719/// A specification for retrieving the dependencies of a specific output from a
@@ -48,15 +50,24 @@ pub struct GetOutputDependenciesSpec {
4850pub struct OutputDependencies {
4951 /// The build dependencies of the package. These refer to the packages that
5052 /// should be installed in the "build" environment.
51- pub build_dependencies : Option < CondaOutputDependencies > ,
53+ pub build_dependencies : Option < DependencyMap < PackageName , PixiSpec > > ,
54+
55+ /// Additional constraints for the build environment.
56+ pub build_constraints : Option < DependencyMap < PackageName , BinarySpec > > ,
5257
5358 /// The "host" dependencies of the package. These refer to the packages that
5459 /// should be installed to be able to refer to them from the build process
5560 /// but not run them.
56- pub host_dependencies : Option < CondaOutputDependencies > ,
61+ pub host_dependencies : Option < DependencyMap < PackageName , PixiSpec > > ,
62+
63+ /// Additional constraints for the host environment.
64+ pub host_constraints : Option < DependencyMap < PackageName , BinarySpec > > ,
5765
5866 /// The dependencies for the run environment of the package.
59- pub run_dependencies : CondaOutputDependencies ,
67+ pub run_dependencies : DependencyMap < PackageName , PixiSpec > ,
68+
69+ /// Additional constraints for the run environment.
70+ pub run_constraints : DependencyMap < PackageName , BinarySpec > ,
6071}
6172
6273impl GetOutputDependenciesSpec {
@@ -110,17 +121,76 @@ impl GetOutputDependenciesSpec {
110121 } ) ?;
111122
112123 // Extract and return the dependencies.
113- Ok ( extract_dependencies ( output) )
124+ extract_dependencies ( output) . map_err ( CommandDispatcherError :: Failed )
114125 }
115126}
116127
117- /// Extracts the dependencies from a CondaOutput.
118- fn extract_dependencies ( output : & CondaOutput ) -> OutputDependencies {
119- OutputDependencies {
120- build_dependencies : output. build_dependencies . clone ( ) ,
121- host_dependencies : output. host_dependencies . clone ( ) ,
122- run_dependencies : output. run_dependencies . clone ( ) ,
128+ /// Extracts the dependencies from a CondaOutput and converts them to PixiSpecs.
129+ fn extract_dependencies (
130+ output : & CondaOutput ,
131+ ) -> Result < OutputDependencies , GetOutputDependenciesError > {
132+ let ( build_deps, build_constraints) = output
133+ . build_dependencies
134+ . as_ref ( )
135+ . map ( convert_conda_dependencies)
136+ . transpose ( ) ?
137+ . map ( |( deps, constraints) | ( Some ( deps) , Some ( constraints) ) )
138+ . unwrap_or ( ( None , None ) ) ;
139+
140+ let ( host_deps, host_constraints) = output
141+ . host_dependencies
142+ . as_ref ( )
143+ . map ( convert_conda_dependencies)
144+ . transpose ( ) ?
145+ . map ( |( deps, constraints) | ( Some ( deps) , Some ( constraints) ) )
146+ . unwrap_or ( ( None , None ) ) ;
147+
148+ let ( run_deps, run_constraints) = convert_conda_dependencies ( & output. run_dependencies ) ?;
149+
150+ Ok ( OutputDependencies {
151+ build_dependencies : build_deps,
152+ build_constraints,
153+ host_dependencies : host_deps,
154+ host_constraints,
155+ run_dependencies : run_deps,
156+ run_constraints,
157+ } )
158+ }
159+
160+ /// Converts CondaOutputDependencies to DependencyMaps of PixiSpecs and BinarySpecs.
161+ fn convert_conda_dependencies (
162+ deps : & CondaOutputDependencies ,
163+ ) -> Result <
164+ (
165+ DependencyMap < PackageName , PixiSpec > ,
166+ DependencyMap < PackageName , BinarySpec > ,
167+ ) ,
168+ GetOutputDependenciesError ,
169+ > {
170+ let mut dependencies = DependencyMap :: default ( ) ;
171+ let mut constraints = DependencyMap :: default ( ) ;
172+
173+ // Convert depends
174+ for depend in & deps. depends {
175+ let name = PackageName :: from_str ( & depend. name ) . map_err ( |err| {
176+ GetOutputDependenciesError :: InvalidPackageName ( depend. name . clone ( ) , err)
177+ } ) ?;
178+
179+ let spec = conversion:: from_package_spec_v1 ( depend. spec . clone ( ) ) ;
180+ dependencies. insert ( name, spec) ;
123181 }
182+
183+ // Convert constraints
184+ for constraint in & deps. constraints {
185+ let name = PackageName :: from_str ( & constraint. name ) . map_err ( |err| {
186+ GetOutputDependenciesError :: InvalidPackageName ( constraint. name . clone ( ) , err)
187+ } ) ?;
188+
189+ let spec = conversion:: from_binary_spec_v1 ( constraint. spec . clone ( ) ) ;
190+ constraints. insert ( name, spec) ;
191+ }
192+
193+ Ok ( ( dependencies, constraints) )
124194}
125195
126196#[ derive( Debug , Error , Diagnostic ) ]
@@ -143,4 +213,7 @@ pub enum GetOutputDependenciesError {
143213 output_name : PackageName ,
144214 available_outputs : Vec < PackageName > ,
145215 } ,
216+
217+ #[ error( "backend returned a dependency on an invalid package name: {0}" ) ]
218+ InvalidPackageName ( String , #[ source] InvalidPackageNameError ) ,
146219}
0 commit comments