@@ -22,12 +22,79 @@ pub use dependencies::{
2222} ;
2323pub ( crate ) use move_file:: { MoveError , move_file} ;
2424use pixi_record:: PinnedSourceSpec ;
25+ use serde:: { Deserialize , Serialize } ;
2526use url:: Url ;
2627pub use work_dir_key:: { SourceRecordOrCheckout , WorkDirKey } ;
2728use xxhash_rust:: xxh3:: Xxh3 ;
2829
2930const KNOWN_SUFFIXES : [ & str ; 3 ] = [ ".git" , ".tar.gz" , ".zip" ] ;
3031
32+ /// Stores the two possible locations for the source code,
33+ /// in the case of an out-of-tree source build.
34+ ///
35+ /// Something which looks like:
36+ /// ```toml
37+ /// [package.build]
38+ /// source = { path = "some-path" }
39+ /// ```
40+ ///
41+ /// We want to prefer that location for our cache checks
42+ #[ derive( Debug , Clone , Eq , PartialEq , Hash , Serialize , Deserialize ) ]
43+ pub struct SourceCodeLocation {
44+ /// The location of the manifest and the possible source code
45+ manifest_source : PinnedSourceSpec ,
46+ /// The location of the source code that should be queried and build
47+ build_source : Option < PinnedSourceSpec > ,
48+ }
49+
50+ impl SourceCodeLocation {
51+ pub fn new ( manifest_source : PinnedSourceSpec , build_source : Option < PinnedSourceSpec > ) -> Self {
52+ Self {
53+ manifest_source,
54+ build_source,
55+ }
56+ }
57+
58+ /// Get the reference to the manifest source
59+ pub fn manifest_source ( & self ) -> & PinnedSourceSpec {
60+ & self . manifest_source
61+ }
62+
63+ /// Get the pinned source spec to the actual source code
64+ /// This is the normally the path to the manifest_source
65+ /// but when set is the path to the build_source
66+ pub fn source_code ( & self ) -> & PinnedSourceSpec {
67+ self . build_source . as_ref ( ) . unwrap_or ( & self . manifest_source )
68+ }
69+
70+ /// Get the optional explicit build source override.
71+ pub fn build_source ( & self ) -> Option < & PinnedSourceSpec > {
72+ self . build_source . as_ref ( )
73+ }
74+
75+ pub fn as_source_and_alternative_root ( & self ) -> ( & PinnedSourceSpec , Option < & PinnedSourceSpec > ) {
76+ if let Some ( build_source) = & self . build_source {
77+ ( build_source, Some ( & self . manifest_source ) )
78+ } else {
79+ ( & self . manifest_source , None )
80+ }
81+ }
82+ }
83+
84+ impl std:: fmt:: Display for SourceCodeLocation {
85+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
86+ write ! (
87+ f,
88+ "(manifest-src: {}, build-src: {})" ,
89+ self . manifest_source( ) ,
90+ self . build_source
91+ . as_ref( )
92+ . map( |build| format!( "{build}" ) )
93+ . unwrap_or( "undefined" . to_string( ) )
94+ )
95+ }
96+ }
97+
3198/// Try to deduce a name from a url.
3299fn pretty_url_name ( url : & Url ) -> String {
33100 if let Some ( last_segment) = url
0 commit comments