1
1
//! Crate specific information embedded into [crate::context::Context] objects.
2
2
3
3
use std:: collections:: { BTreeMap , BTreeSet } ;
4
- use std:: path:: PathBuf ;
4
+ use std:: path:: { Path , PathBuf } ;
5
5
6
- use cargo_metadata:: { Node , Package , PackageId } ;
6
+ use cargo_metadata:: { Node , Package , PackageId , Target } ;
7
7
use serde:: { Deserialize , Serialize } ;
8
8
9
9
use crate :: config:: { CrateId , GenBinaries } ;
@@ -12,7 +12,9 @@ use crate::metadata::{
12
12
} ;
13
13
use crate :: splicing:: WorkspaceMetadata ;
14
14
use crate :: utils:: sanitize_module_name;
15
- use crate :: utils:: starlark:: { Glob , SelectList , SelectMap , SelectStringDict , SelectStringList } ;
15
+ use crate :: utils:: starlark:: {
16
+ Glob , GlobOrLabels , Label , SelectList , SelectMap , SelectStringDict , SelectStringList ,
17
+ } ;
16
18
17
19
#[ derive( Debug , PartialEq , Eq , PartialOrd , Ord , Serialize , Deserialize , Clone ) ]
18
20
pub struct CrateDependency {
@@ -43,8 +45,12 @@ pub struct TargetAttributes {
43
45
/// The path to the crate's root source file, relative to the manifest.
44
46
pub crate_root : Option < String > ,
45
47
46
- /// A glob pattern of all source files required by the target
47
- pub srcs : Glob ,
48
+ /// A glob pattern of all source files required by the target or a label
49
+ /// pointing to a filegroup containing said glob (used for patching)
50
+ pub srcs : GlobOrLabels ,
51
+
52
+ /// A label for overriding compile_data, used for patching
53
+ pub compile_data : Option < GlobOrLabels > ,
48
54
}
49
55
50
56
#[ derive( Debug , PartialEq , Eq , PartialOrd , Ord , Serialize , Deserialize , Clone ) ]
@@ -656,95 +662,100 @@ impl CrateContext {
656
662
. targets
657
663
. iter ( )
658
664
. flat_map ( |target| {
665
+ let attrs = get_attributes ( target, package, workspace, package_root) ;
659
666
target. kind . iter ( ) . filter_map ( move |kind| {
660
- // Unfortunately, The package graph and resolve graph of cargo metadata have different representations
661
- // for the crate names (resolve graph sanitizes names to match module names) so to get the rest of this
662
- // content to align when rendering, the package target names are always sanitized.
663
- let crate_name = sanitize_module_name ( & target. name ) ;
664
-
665
- // Locate the crate's root source file relative to the package root normalized for unix
666
- let crate_root = pathdiff:: diff_paths ( & target. src_path , package_root) . map (
667
- // Normalize the path so that it always renders the same regardless of platform
668
- |root| root. to_string_lossy ( ) . replace ( '\\' , "/" ) ,
669
- ) ;
670
- println ! ( "{}" , package. id) ;
671
- if package. id . repr . contains ( "(path+file://" ) {
672
- println ! ( "" ) ;
673
- println ! ( "{crate_name} {kind} {:?}" , & crate_root) ;
674
- println ! ( "src: {:?}" , & target. src_path) ;
675
- println ! ( "pkg: {:?}" , package_root) ;
676
- println ! ( "root: {:?}" , & crate_root) ;
677
- println ! ( "workspace: {:?}" , workspace. workspace_prefix) ;
678
- let temp_components = std:: env:: temp_dir ( ) . components ( ) . count ( ) + 1 ;
679
- println ! ( "temp dir components to drop: {temp_components}" ) ;
680
- let real_root: PathBuf =
681
- package_root. components ( ) . skip ( temp_components) . collect ( ) ;
682
- println ! ( "ACTUAL FOR REAL ROOT: {}" , real_root. to_string_lossy( ) ) ;
683
- println ! ( "" ) ;
684
- }
685
- let crate_root = crate_root. map ( |r| {
686
- if package. id . repr . contains ( "(path+file://" ) {
687
- let temp_components = std:: env:: temp_dir ( ) . components ( ) . count ( ) + 1 ;
688
- package_root
689
- . components ( )
690
- . skip ( temp_components)
691
- . collect :: < PathBuf > ( )
692
- . join ( r)
693
- . to_string_lossy ( )
694
- . to_string ( )
695
- } else {
696
- r
697
- }
698
- } ) ;
699
-
700
- // Conditionally check to see if the dependencies is a build-script target
701
- if include_build_scripts && kind == "custom-build" {
702
- return Some ( Rule :: BuildScript ( TargetAttributes {
703
- crate_name,
704
- crate_root,
705
- srcs : Glob :: new_rust_srcs ( ) ,
706
- } ) ) ;
707
- }
708
-
709
- // Check to see if the dependencies is a proc-macro target
667
+ let attrs = attrs. clone ( ) ;
710
668
if kind == "proc-macro" {
711
- return Some ( Rule :: ProcMacro ( TargetAttributes {
712
- crate_name,
713
- crate_root,
714
- srcs : Glob :: new_rust_srcs ( ) ,
715
- } ) ) ;
716
- }
717
-
718
- // Check to see if the dependencies is a library target
719
- if [ "lib" , "rlib" ] . contains ( & kind. as_str ( ) ) {
720
- return Some ( Rule :: Library ( TargetAttributes {
721
- crate_name,
722
- crate_root,
723
- srcs : Glob :: new_rust_srcs ( ) ,
724
- } ) ) ;
725
- }
726
-
727
- // Check if the target kind is binary and is one of the ones included in gen_binaries
728
- if kind == "bin"
729
- && match gen_binaries {
669
+ Some ( Rule :: ProcMacro ( attrs) )
670
+ } else if [ "lib" , "rlib" ] . contains ( & kind. as_str ( ) ) {
671
+ Some ( Rule :: Library ( attrs) )
672
+ } else if include_build_scripts && kind == "custom-build" {
673
+ let build_script_crate_root = attrs
674
+ . crate_root
675
+ . map ( |s| s. replace ( ":crate_root" , ":build_script_crate_root" ) ) ;
676
+ Some ( Rule :: BuildScript ( TargetAttributes {
677
+ crate_root : build_script_crate_root,
678
+ ..attrs
679
+ } ) )
680
+ } else if kind == "bin" {
681
+ match gen_binaries {
730
682
GenBinaries :: All => true ,
731
683
GenBinaries :: Some ( set) => set. contains ( & target. name ) ,
732
684
}
733
- {
734
- return Some ( Rule :: Binary ( TargetAttributes {
735
- crate_name : target. name . clone ( ) ,
736
- crate_root,
737
- srcs : Glob :: new_rust_srcs ( ) ,
738
- } ) ) ;
685
+ . then ( || {
686
+ Rule :: Binary ( TargetAttributes {
687
+ crate_name : target. name . clone ( ) ,
688
+ ..attrs
689
+ } )
690
+ } )
691
+ } else {
692
+ None
739
693
}
740
-
741
- None
742
694
} )
743
695
} )
744
696
. collect ( )
745
697
}
746
698
}
747
699
700
+ fn get_attributes (
701
+ target : & Target ,
702
+ package : & Package ,
703
+ workspace : & WorkspaceMetadata ,
704
+ package_root : & Path ,
705
+ ) -> TargetAttributes {
706
+ // Unfortunately, The package graph and resolve graph of cargo metadata have
707
+ // different representations for the crate names (resolve graph sanitizes
708
+ // names to match module names) so to get the rest of this content to align
709
+ // when rendering, the package target names are always sanitized.
710
+ let crate_name = sanitize_module_name ( & target. name ) ;
711
+
712
+ // Locate the crate's root source file relative to the package root normalized
713
+ // for unix
714
+ let crate_root = pathdiff:: diff_paths ( & target. src_path , package_root) . map (
715
+ // Normalize the path so that it always renders the same regardless of platform
716
+ |root| root. to_string_lossy ( ) . replace ( '\\' , "/" ) ,
717
+ ) ;
718
+ let local_patch = package. id . repr . contains ( "(path+file://" ) ;
719
+ let temp_components = std:: env:: temp_dir ( ) . components ( ) . count ( ) + 1 ;
720
+ let real_root: PathBuf = package_root. components ( ) . skip ( temp_components) . collect ( ) ;
721
+ if !local_patch || real_root. as_os_str ( ) . is_empty ( ) {
722
+ TargetAttributes {
723
+ crate_name,
724
+ crate_root,
725
+ srcs : Glob :: new_rust_srcs ( ) . into ( ) ,
726
+ compile_data : None ,
727
+ }
728
+ } else {
729
+ let root = real_root. display ( ) ;
730
+ let pkg = if let Some ( workspace) = & workspace. workspace_prefix {
731
+ format ! ( "{workspace}/{}" , root)
732
+ } else {
733
+ root. to_string ( )
734
+ } ;
735
+ // TODO: remove once added to help-docs
736
+ println ! ( "\n There's a patch crate at '//{pkg}'." ) ;
737
+ println ! ( "Make sure that '//{pkg}/BUILD.bazel' exposes the following filegroups:" ) ;
738
+ println ! ( "'crate_root', 'srcs', 'compile_data', and (if necessary) 'build_script'" ) ;
739
+ let srcs = GlobOrLabels :: Labels ( vec ! [ Label {
740
+ repository: None ,
741
+ package: Some ( pkg. clone( ) ) ,
742
+ target: "srcs" . to_string( ) ,
743
+ } ] ) ;
744
+ let compile_data = Some ( GlobOrLabels :: Labels ( vec ! [ Label {
745
+ repository: None ,
746
+ package: Some ( pkg. clone( ) ) ,
747
+ target: "compile_data" . to_string( ) ,
748
+ } ] ) ) ;
749
+
750
+ TargetAttributes {
751
+ crate_name,
752
+ crate_root : Some ( format ! ( "//{pkg}:crate_root" ) ) ,
753
+ srcs,
754
+ compile_data,
755
+ }
756
+ }
757
+ }
758
+
748
759
#[ cfg( test) ]
749
760
mod test {
750
761
use super :: * ;
@@ -787,7 +798,8 @@ mod test {
787
798
BTreeSet :: from( [ Rule :: Library ( TargetAttributes {
788
799
crate_name: "common" . to_owned( ) ,
789
800
crate_root: Some ( "lib.rs" . to_owned( ) ) ,
790
- srcs: Glob :: new_rust_srcs( ) ,
801
+ srcs: Glob :: new_rust_srcs( ) . into( ) ,
802
+ compile_data: None ,
791
803
} ) ] ) ,
792
804
) ;
793
805
}
@@ -819,7 +831,7 @@ mod test {
819
831
let include_build_scripts = false ;
820
832
let context = CrateContext :: new (
821
833
crate_annotation,
822
- & annotations. metadata . packages ,
834
+ & annotations. metadata ,
823
835
& annotations. lockfile . crates ,
824
836
& pairred_extras,
825
837
& annotations. features ,
@@ -834,12 +846,14 @@ mod test {
834
846
Rule :: Library ( TargetAttributes {
835
847
crate_name: "common" . to_owned( ) ,
836
848
crate_root: Some ( "lib.rs" . to_owned( ) ) ,
837
- srcs: Glob :: new_rust_srcs( ) ,
849
+ srcs: Glob :: new_rust_srcs( ) . into( ) ,
850
+ compile_data: None ,
838
851
} ) ,
839
852
Rule :: Binary ( TargetAttributes {
840
853
crate_name: "common-bin" . to_owned( ) ,
841
854
crate_root: Some ( "main.rs" . to_owned( ) ) ,
842
- srcs: Glob :: new_rust_srcs( ) ,
855
+ srcs: Glob :: new_rust_srcs( ) . into( ) ,
856
+ compile_data: None ,
843
857
} ) ,
844
858
] ) ,
845
859
) ;
@@ -882,7 +896,7 @@ mod test {
882
896
let include_build_scripts = true ;
883
897
let context = CrateContext :: new (
884
898
crate_annotation,
885
- & annotations. metadata . packages ,
899
+ & annotations. metadata ,
886
900
& annotations. lockfile . crates ,
887
901
& annotations. pairred_extras ,
888
902
& annotations. features ,
@@ -898,12 +912,14 @@ mod test {
898
912
Rule :: Library ( TargetAttributes {
899
913
crate_name: "openssl_sys" . to_owned( ) ,
900
914
crate_root: Some ( "src/lib.rs" . to_owned( ) ) ,
901
- srcs: Glob :: new_rust_srcs( ) ,
915
+ srcs: Glob :: new_rust_srcs( ) . into( ) ,
916
+ compile_data: None ,
902
917
} ) ,
903
918
Rule :: BuildScript ( TargetAttributes {
904
919
crate_name: "build_script_main" . to_owned( ) ,
905
920
crate_root: Some ( "build/main.rs" . to_owned( ) ) ,
906
- srcs: Glob :: new_rust_srcs( ) ,
921
+ srcs: Glob :: new_rust_srcs( ) . into( ) ,
922
+ compile_data: None ,
907
923
} )
908
924
] ) ,
909
925
) ;
@@ -927,7 +943,7 @@ mod test {
927
943
let include_build_scripts = false ;
928
944
let context = CrateContext :: new (
929
945
crate_annotation,
930
- & annotations. metadata . packages ,
946
+ & annotations. metadata ,
931
947
& annotations. lockfile . crates ,
932
948
& annotations. pairred_extras ,
933
949
& annotations. features ,
@@ -942,7 +958,8 @@ mod test {
942
958
BTreeSet :: from( [ Rule :: Library ( TargetAttributes {
943
959
crate_name: "openssl_sys" . to_owned( ) ,
944
960
crate_root: Some ( "src/lib.rs" . to_owned( ) ) ,
945
- srcs: Glob :: new_rust_srcs( ) ,
961
+ srcs: Glob :: new_rust_srcs( ) . into( ) ,
962
+ compile_data: None ,
946
963
} ) ] ) ,
947
964
) ;
948
965
}
@@ -962,7 +979,7 @@ mod test {
962
979
let include_build_scripts = false ;
963
980
let context = CrateContext :: new (
964
981
crate_annotation,
965
- & annotations. metadata . packages ,
982
+ & annotations. metadata ,
966
983
& annotations. lockfile . crates ,
967
984
& annotations. pairred_extras ,
968
985
& annotations. features ,
@@ -977,7 +994,8 @@ mod test {
977
994
BTreeSet :: from( [ Rule :: Library ( TargetAttributes {
978
995
crate_name: "sysinfo" . to_owned( ) ,
979
996
crate_root: Some ( "src/lib.rs" . to_owned( ) ) ,
980
- srcs: Glob :: new_rust_srcs( ) ,
997
+ srcs: Glob :: new_rust_srcs( ) . into( ) ,
998
+ compile_data: None ,
981
999
} ) ] ) ,
982
1000
) ;
983
1001
}
0 commit comments