@@ -136,11 +136,10 @@ impl FromStr for Spec {
136
136
type Err = ( ) ;
137
137
138
138
fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
139
- let split = s. split ( ';' ) . collect :: < Vec < _ > > ( ) ; // c 1; if b 1..2
139
+ let ( spec , condition ) = s. split_once ( "; if" ) . unwrap ( ) ;
140
140
141
- if split. len ( ) == 1 {
142
- // c 1
143
- let split = s. split ( ' ' ) . collect :: < Vec < _ > > ( ) ;
141
+ if condition. is_empty ( ) {
142
+ let split = spec. split ( ' ' ) . collect :: < Vec < _ > > ( ) ;
144
143
let name = split
145
144
. first ( )
146
145
. expect ( "spec does not have a name" )
@@ -149,10 +148,9 @@ impl FromStr for Spec {
149
148
return Ok ( Spec :: new ( name, versions, None ) ) ;
150
149
}
151
150
152
- let binding = split. get ( 1 ) . unwrap ( ) . replace ( "if" , "" ) ;
153
- let condition = Spec :: parse_union ( & binding) . next ( ) . unwrap ( ) . unwrap ( ) ;
151
+ let condition = Spec :: parse_union ( condition) . next ( ) . unwrap ( ) . unwrap ( ) ;
154
152
155
- let spec = Spec :: from_str ( split . first ( ) . unwrap ( ) ) . unwrap ( ) ;
153
+ let spec = Spec :: from_str ( spec ) . unwrap ( ) ;
156
154
157
155
fn version_range ( s : Option < & & str > ) -> Ranges < Pack > {
158
156
if let Some ( s) = s {
@@ -1616,6 +1614,69 @@ fn test_circular_conditional_dependencies() {
1616
1614
"### ) ;
1617
1615
}
1618
1616
1617
+ #[ test]
1618
+ fn test_conditional_requirements_multiple_versions ( ) {
1619
+ let mut provider = BundleBoxProvider :: new ( ) ;
1620
+
1621
+ // Add multiple versions of package b
1622
+ provider. add_package ( "b" , 1 . into ( ) , & [ ] , & [ ] ) ;
1623
+ provider. add_package ( "b" , 2 . into ( ) , & [ ] , & [ ] ) ;
1624
+ provider. add_package ( "b" , 3 . into ( ) , & [ ] , & [ ] ) ;
1625
+ provider. add_package ( "b" , 4 . into ( ) , & [ ] , & [ ] ) ;
1626
+ provider. add_package ( "b" , 5 . into ( ) , & [ ] , & [ ] ) ;
1627
+
1628
+ provider. add_package ( "c" , 1 . into ( ) , & [ ] , & [ ] ) ; // Simple package c
1629
+ provider. add_package ( "a" , 1 . into ( ) , & [ "b 4..6" ] , & [ ] ) ; // a depends on b versions 4-5
1630
+
1631
+ // Create conditional requirement: if b=1..3 is installed, require c
1632
+ let requirements = provider. requirements ( & [
1633
+ "a" , // Require package a
1634
+ "c 1; if b 1..3" , // If b is version 1-2, require c
1635
+ ] ) ;
1636
+
1637
+ let mut solver = Solver :: new ( provider) ;
1638
+ let problem = Problem :: new ( ) . requirements ( requirements) ;
1639
+ let solved = solver. solve ( problem) . unwrap ( ) ;
1640
+ let result = transaction_to_string ( solver. provider ( ) , & solved) ;
1641
+ // Since b=4 is installed (not b 1..3), c should not be installed
1642
+ insta:: assert_snapshot!( result, @r###"
1643
+ a=1
1644
+ b=4
1645
+ "### ) ;
1646
+ }
1647
+
1648
+ #[ test]
1649
+ fn test_conditional_requirements_multiple_versions_met ( ) {
1650
+ let mut provider = BundleBoxProvider :: new ( ) ;
1651
+
1652
+ // Add multiple versions of package b
1653
+ provider. add_package ( "b" , 1 . into ( ) , & [ ] , & [ ] ) ;
1654
+ provider. add_package ( "b" , 2 . into ( ) , & [ ] , & [ ] ) ;
1655
+ provider. add_package ( "b" , 3 . into ( ) , & [ ] , & [ ] ) ;
1656
+ provider. add_package ( "b" , 4 . into ( ) , & [ ] , & [ ] ) ;
1657
+ provider. add_package ( "b" , 5 . into ( ) , & [ ] , & [ ] ) ;
1658
+
1659
+ provider. add_package ( "c" , 1 . into ( ) , & [ ] , & [ ] ) ; // Simple package c
1660
+ provider. add_package ( "a" , 1 . into ( ) , & [ "b 1..3" ] , & [ ] ) ; // a depends on b versions 1-2
1661
+
1662
+ // Create conditional requirement: if b=1..3 is installed, require c
1663
+ let requirements = provider. requirements ( & [
1664
+ "a" , // Require package a
1665
+ "c 1; if b 1..3" , // If b is version 1-2, require c
1666
+ ] ) ;
1667
+
1668
+ let mut solver = Solver :: new ( provider) ;
1669
+ let problem = Problem :: new ( ) . requirements ( requirements) ;
1670
+ let solved = solver. solve ( problem) . unwrap ( ) ;
1671
+ let result = transaction_to_string ( solver. provider ( ) , & solved) ;
1672
+ // Since b=2 is installed (within b 1..3), c should be installed
1673
+ insta:: assert_snapshot!( result, @r###"
1674
+ a=1
1675
+ b=2
1676
+ c=1
1677
+ "### ) ;
1678
+ }
1679
+
1619
1680
#[ cfg( feature = "serde" ) ]
1620
1681
fn serialize_snapshot ( snapshot : & DependencySnapshot , destination : impl AsRef < std:: path:: Path > ) {
1621
1682
let file = std:: io:: BufWriter :: new ( std:: fs:: File :: create ( destination. as_ref ( ) ) . unwrap ( ) ) ;
0 commit comments