@@ -554,6 +554,7 @@ public struct Parser {
554554    /// Parse --publish-port arguments into PublishPort objects
555555    /// The format of each argument is `[host-ip:]host-port:container-port[/protocol]`
556556    /// (e.g., "127.0.0.1:8080:80/tcp")
557+     /// host-port and container-port can be ranges (e.g., "127.0.0.1:3456-4567:3456-4567/tcp`
557558    ///
558559    /// - Parameter rawPublishPorts: Array of port arguments
559560    /// - Returns: Array of PublishPort objects
@@ -563,14 +564,14 @@ public struct Parser {
563564
564565        // Process each raw port string
565566        for  socket  in  rawPublishPorts { 
566-             let  parsedSocket  =  try   Parser . publishPort ( socket) 
567-             sockets. append ( parsedSocket ) 
567+             let  parsedSockets  =  try   Parser . publishPort ( socket) 
568+             sockets. append ( contentsOf :  parsedSockets ) 
568569        } 
569570        return  sockets
570571    } 
571572
572-     // Parse a single `--publish-port` argument into a `PublishPort`.
573-     public  static  func  publishPort( _ portText:  String )  throws  ->  PublishPort  { 
573+     // Parse a single `--publish-port` argument into a `[ PublishPort] `.
574+     public  static  func  publishPort( _ portText:  String )  throws  ->  [ PublishPort ]  { 
574575        let  protoSplit  =  portText. split ( separator:  " / " ) 
575576        let  proto :  PublishProtocol 
576577        let  addressAndPortText :  String 
@@ -607,19 +608,98 @@ public struct Parser {
607608        } 
608609
609610        guard  let  hostPort =  Int ( hostPortText)  else  { 
610-             throw  ContainerizationError ( . invalidArgument,  message:  " invalid publish host port:  \( hostPortText) " ) 
611+             let  hostPortRangeStart :  Int 
612+             let  hostPortRangeEnd :  Int 
613+             let  containerPortRangeStart :  Int 
614+             let  containerPortRangeEnd :  Int 
615+ 
616+             let  hostPortParts  =  hostPortText. split ( separator:  " - " ) 
617+             switch  hostPortParts. count { 
618+             case  2 : 
619+                 guard  let  start =  Int ( hostPortParts [ 0 ] )  else  { 
620+                     throw  ContainerizationError ( . invalidArgument,  message:  " invalid publish host port  \( hostPortText) " ) 
621+                 } 
622+ 
623+                 guard  let  end =  Int ( hostPortParts [ 1 ] )  else  { 
624+                     throw  ContainerizationError ( . invalidArgument,  message:  " invalid publish host port  \( hostPortText) " ) 
625+                 } 
626+ 
627+                 hostPortRangeStart =  start
628+                 hostPortRangeEnd =  end
629+             default : 
630+                 throw  ContainerizationError ( . invalidArgument,  message:  " invalid publish host port  \( hostPortText) " ) 
631+             } 
632+ 
633+             let  containerPortParts  =  containerPortText. split ( separator:  " - " ) 
634+             switch  containerPortParts. count { 
635+             case  2 : 
636+                 guard  let  start =  Int ( containerPortParts [ 0 ] )  else  { 
637+                     throw  ContainerizationError ( . invalidArgument,  message:  " invalid publish container port  \( containerPortText) " ) 
638+                 } 
639+ 
640+                 guard  let  end =  Int ( containerPortParts [ 1 ] )  else  { 
641+                     throw  ContainerizationError ( . invalidArgument,  message:  " invalid publish container port  \( containerPortText) " ) 
642+                 } 
643+ 
644+                 containerPortRangeStart =  start
645+                 containerPortRangeEnd =  end
646+             default : 
647+                 throw  ContainerizationError ( . invalidArgument,  message:  " invalid publish container port  \( containerPortText) " ) 
648+             } 
649+ 
650+             guard  hostPortRangeStart >  1 , 
651+                 hostPortRangeEnd >  1 , 
652+                 hostPortRangeStart <  hostPortRangeEnd, 
653+                 hostPortRangeEnd >  hostPortRangeStart
654+             else  { 
655+                 throw  ContainerizationError ( . invalidArgument,  message:  " invalid publish host port range  \( hostPortText) " ) 
656+             } 
657+ 
658+             guard  containerPortRangeStart >  1 , 
659+                 containerPortRangeEnd >  1 , 
660+                 containerPortRangeStart <  containerPortRangeEnd, 
661+                 containerPortRangeEnd >  containerPortRangeStart
662+             else  { 
663+                 throw  ContainerizationError ( . invalidArgument,  message:  " invalid publish container port range  \( containerPortText) " ) 
664+             } 
665+ 
666+             let  hostRange  =  hostPortRangeEnd -  hostPortRangeStart
667+             let  containerRange  =  containerPortRangeEnd -  containerPortRangeStart
668+ 
669+             guard  hostRange ==  containerRange else  { 
670+                 throw  ContainerizationError ( . invalidArgument,  message:  " publish host and container port range are not equal  \( addressAndPortText) " ) 
671+             } 
672+ 
673+             var  publishPorts  =  [ PublishPort] ( ) 
674+             for  i  in  0 ..< hostPortRangeEnd -  hostPortRangeStart +  1  { 
675+                 let  hostPort  =  hostPortRangeStart +  i
676+                 let  containerPort  =  containerPortRangeStart +  i
677+ 
678+                 publishPorts. append ( 
679+                     PublishPort ( 
680+                         hostAddress:  hostAddress, 
681+                         hostPort:  hostPort, 
682+                         containerPort:  containerPort, 
683+                         proto:  proto
684+                     ) 
685+                 ) 
686+             } 
687+ 
688+             return  publishPorts
611689        } 
612690
613691        guard  let  containerPort =  Int ( containerPortText)  else  { 
614692            throw  ContainerizationError ( . invalidArgument,  message:  " invalid publish container port:  \( containerPortText) " ) 
615693        } 
616694
617-         return  PublishPort ( 
618-             hostAddress:  hostAddress, 
619-             hostPort:  hostPort, 
620-             containerPort:  containerPort, 
621-             proto:  proto
622-         ) 
695+         return  [ 
696+             PublishPort ( 
697+                 hostAddress:  hostAddress, 
698+                 hostPort:  hostPort, 
699+                 containerPort:  containerPort, 
700+                 proto:  proto
701+             ) 
702+         ] 
623703    } 
624704
625705    /// Parse --publish-socket arguments into PublishSocket objects
0 commit comments