@@ -706,3 +706,256 @@ impl Package {
706
706
}
707
707
}
708
708
}
709
+
710
+ fn get_unallowed_dependents (
711
+ packages : & AHashMap < String , Package > ,
712
+ package_name : & String ,
713
+ dependencies : & Vec < String > ,
714
+ ) -> Option < String > {
715
+ for deps_package_name in dependencies {
716
+ if let Some ( deps_package) = packages. get ( deps_package_name) {
717
+ let deps_allowed_dependents = deps_package. bsconfig . allowed_dependents . to_owned ( ) ;
718
+ if let Some ( allowed_dependents) = deps_allowed_dependents {
719
+ if !allowed_dependents. contains ( package_name) {
720
+ return Some ( deps_package_name. to_string ( ) ) ;
721
+ }
722
+ }
723
+ }
724
+ }
725
+ return None ;
726
+ }
727
+ #[ derive( Debug , Clone ) ]
728
+ struct UnallowedDependency {
729
+ bs_deps : Vec < String > ,
730
+ pinned_deps : Vec < String > ,
731
+ bs_dev_deps : Vec < String > ,
732
+ }
733
+
734
+ pub fn validate_packages_dependencies ( packages : & AHashMap < String , Package > ) -> bool {
735
+ let mut detected_unallowed_dependencies: AHashMap < String , UnallowedDependency > = AHashMap :: new ( ) ;
736
+
737
+ for ( package_name, package) in packages {
738
+ let bs_dependencies = & package. bsconfig . bs_dependencies . to_owned ( ) . unwrap_or ( vec ! [ ] ) ;
739
+ let pinned_dependencies = & package. bsconfig . pinned_dependencies . to_owned ( ) . unwrap_or ( vec ! [ ] ) ;
740
+ let dev_dependencies = & package. bsconfig . bs_dev_dependencies . to_owned ( ) . unwrap_or ( vec ! [ ] ) ;
741
+
742
+ vec ! [
743
+ ( "bs-dependencies" , bs_dependencies) ,
744
+ ( "pinned-dependencies" , pinned_dependencies) ,
745
+ ( "bs-dev-dependencies" , dev_dependencies) ,
746
+ ]
747
+ . iter ( )
748
+ . for_each ( |( dependency_type, dependencies) | {
749
+ if let Some ( unallowed_dependency_name) = get_unallowed_dependents ( packages, package_name, dependencies) {
750
+ let empty_unallowed_deps = UnallowedDependency {
751
+ bs_deps : vec ! [ ] ,
752
+ pinned_deps : vec ! [ ] ,
753
+ bs_dev_deps : vec ! [ ] ,
754
+ } ;
755
+
756
+ let unallowed_dependency = detected_unallowed_dependencies. entry ( String :: from ( package_name) ) ;
757
+ let value = unallowed_dependency
758
+ . or_insert_with ( ||empty_unallowed_deps) ;
759
+ match dependency_type {
760
+ & "bs-dependencies" => value. bs_deps . push ( String :: from ( unallowed_dependency_name) ) ,
761
+ & "pinned-dependencies" => value. pinned_deps . push ( String :: from ( unallowed_dependency_name) ) ,
762
+ & "bs-dev-dependencies" => value. bs_dev_deps . push ( String :: from ( unallowed_dependency_name) ) ,
763
+ _ => ( ) ,
764
+ }
765
+
766
+ }
767
+ } ) ;
768
+ }
769
+ for ( package_name, unallowed_deps) in detected_unallowed_dependencies. iter ( ) {
770
+ println ! (
771
+ "\n {}: {} has the following unallowed dependencies:" ,
772
+ console:: style( "Error" ) . red( ) ,
773
+ console:: style( package_name) . bold( )
774
+ ) ;
775
+
776
+ vec ! [
777
+ ( "bs-dependencies" , unallowed_deps. bs_deps. to_owned( ) ) ,
778
+ ( "pinned-dependencies" , unallowed_deps. pinned_deps. to_owned( ) ) ,
779
+ ( "bs-dev-dependencies" , unallowed_deps. bs_dev_deps. to_owned( ) ) ,
780
+ ]
781
+ . iter ( )
782
+ . for_each ( |( deps_type, map) | {
783
+ if map. len ( ) > 0 {
784
+ println ! (
785
+ "{} dependencies: {}" ,
786
+ console:: style( deps_type) . bold( ) . dim( ) ,
787
+ console:: style( map. join( " \n -" ) ) . bold( ) . dim( )
788
+ ) ;
789
+ }
790
+ } ) ;
791
+ }
792
+ let has_any_unallowed_dependent = detected_unallowed_dependencies. len ( ) > 0 ;
793
+
794
+ if has_any_unallowed_dependent {
795
+ println ! ( "\n Update the {} value in the {} of the unallowed dependencies to solve the issue!" ,
796
+ console:: style( "unallowed_dependents" ) . bold( ) . dim( ) ,
797
+ console:: style( "bsconfig.json" ) . bold( ) . dim( )
798
+ )
799
+ }
800
+ return !has_any_unallowed_dependent;
801
+ }
802
+
803
+ #[ cfg( test) ]
804
+ mod test {
805
+ use crate :: bsconfig:: Source ;
806
+ use ahash:: { AHashMap , AHashSet } ;
807
+
808
+ use super :: { Package , Namespace } ;
809
+
810
+ fn create_package (
811
+ name : String ,
812
+ bs_deps : Vec < String > ,
813
+ pinned_deps : Vec < String > ,
814
+ dev_deps : Vec < String > ,
815
+ allowed_dependents : Option < Vec < String > > ,
816
+ ) -> Package {
817
+ return Package {
818
+ name : name. clone ( ) ,
819
+ bsconfig : crate :: bsconfig:: T {
820
+ name : name. clone ( ) ,
821
+ sources : crate :: bsconfig:: OneOrMore :: Single ( Source :: Shorthand ( String :: from ( "Source" ) ) ) ,
822
+ package_specs : None ,
823
+ warnings : None ,
824
+ suffix : None ,
825
+ pinned_dependencies : Some ( pinned_deps) ,
826
+ bs_dependencies : Some ( bs_deps) ,
827
+ bs_dev_dependencies : Some ( dev_deps) ,
828
+ ppx_flags : None ,
829
+ bsc_flags : None ,
830
+ reason : None ,
831
+ namespace : None ,
832
+ jsx : None ,
833
+ uncurried : None ,
834
+ namespace_entry : None ,
835
+ allowed_dependents,
836
+ } ,
837
+ source_folders : AHashSet :: new ( ) ,
838
+ source_files : None ,
839
+ namespace : Namespace :: Namespace ( String :: from ( "Package1" ) ) ,
840
+ modules : None ,
841
+ package_dir : String :: from ( "./something" ) ,
842
+ dirs : None ,
843
+ is_pinned_dep : false ,
844
+ is_root : false ,
845
+ } ;
846
+ }
847
+ #[ test]
848
+ fn test_validate_packages_dependencies_unallowed_dependents_should_return_false_with_invalid_parents_as_bs_dependencies (
849
+ ) {
850
+ let mut packages: AHashMap < String , Package > = AHashMap :: new ( ) ;
851
+ packages. insert (
852
+ String :: from ( "Package1" ) ,
853
+ create_package (
854
+ String :: from ( "Package1" ) ,
855
+ vec ! [ String :: from( "Package2" ) ] ,
856
+ vec ! [ ] ,
857
+ vec ! [ ] ,
858
+ None ,
859
+ ) ,
860
+ ) ;
861
+ packages. insert (
862
+ String :: from ( "Package2" ) ,
863
+ create_package (
864
+ String :: from ( "Package2" ) ,
865
+ vec ! [ ] ,
866
+ vec ! [ ] ,
867
+ vec ! [ ] ,
868
+ Some ( vec ! [ String :: from( "Package3" ) ] ) ,
869
+ ) ,
870
+ ) ;
871
+
872
+ let is_valid = super :: validate_packages_dependencies ( & packages) ;
873
+ assert_eq ! ( is_valid, false )
874
+ }
875
+
876
+ #[ test]
877
+ fn test_validate_packages_dependencies_unallowed_dependents_should_return_false_with_invalid_parents_as_pinned_dependencies (
878
+ ) {
879
+ let mut packages: AHashMap < String , Package > = AHashMap :: new ( ) ;
880
+ packages. insert (
881
+ String :: from ( "Package1" ) ,
882
+ create_package (
883
+ String :: from ( "Package1" ) ,
884
+ vec ! [ ] ,
885
+ vec ! [ String :: from( "Package2" ) ] ,
886
+ vec ! [ ] ,
887
+ None ,
888
+ ) ,
889
+ ) ;
890
+ packages. insert (
891
+ String :: from ( "Package2" ) ,
892
+ create_package (
893
+ String :: from ( "Package2" ) ,
894
+ vec ! [ ] ,
895
+ vec ! [ ] ,
896
+ vec ! [ ] ,
897
+ Some ( vec ! [ String :: from( "Package3" ) ] ) ,
898
+ ) ,
899
+ ) ;
900
+
901
+ let is_valid = super :: validate_packages_dependencies ( & packages) ;
902
+ assert_eq ! ( is_valid, false )
903
+ }
904
+
905
+ #[ test]
906
+ fn test_validate_packages_dependencies_unallowed_dependents_should_return_false_with_invalid_parents_as_dev_dependencies (
907
+ ) {
908
+ let mut packages: AHashMap < String , Package > = AHashMap :: new ( ) ;
909
+ packages. insert (
910
+ String :: from ( "Package1" ) ,
911
+ create_package (
912
+ String :: from ( "Package1" ) ,
913
+ vec ! [ ] ,
914
+ vec ! [ ] ,
915
+ vec ! [ String :: from( "Package2" ) ] ,
916
+ None ,
917
+ ) ,
918
+ ) ;
919
+ packages. insert (
920
+ String :: from ( "Package2" ) ,
921
+ create_package (
922
+ String :: from ( "Package2" ) ,
923
+ vec ! [ ] ,
924
+ vec ! [ ] ,
925
+ vec ! [ ] ,
926
+ Some ( vec ! [ String :: from( "Package3" ) ] ) ,
927
+ ) ,
928
+ ) ;
929
+
930
+ let is_valid = super :: validate_packages_dependencies ( & packages) ;
931
+ assert_eq ! ( is_valid, false )
932
+ }
933
+
934
+ #[ test]
935
+ fn test_validate_packages_dependencies_unallowed_dependents_should_return_true_with_no_invalid_parent ( ) {
936
+ let mut packages: AHashMap < String , Package > = AHashMap :: new ( ) ;
937
+ packages. insert (
938
+ String :: from ( "Package1" ) ,
939
+ create_package (
940
+ String :: from ( "Package1" ) ,
941
+ vec ! [ String :: from( "Package2" ) ] ,
942
+ vec ! [ ] ,
943
+ vec ! [ ] ,
944
+ None ,
945
+ ) ,
946
+ ) ;
947
+ packages. insert (
948
+ String :: from ( "Package2" ) ,
949
+ create_package (
950
+ String :: from ( "Package2" ) ,
951
+ vec ! [ ] ,
952
+ vec ! [ ] ,
953
+ vec ! [ ] ,
954
+ Some ( vec ! [ String :: from( "Package1" ) ] ) ,
955
+ ) ,
956
+ ) ;
957
+
958
+ let is_valid = super :: validate_packages_dependencies ( & packages) ;
959
+ assert_eq ! ( is_valid, true )
960
+ }
961
+ }
0 commit comments