@@ -8,12 +8,12 @@ import (
88 "errors"
99 "fmt"
1010 "log"
11+ "maps"
1112 "math"
1213 "net"
1314 "os"
1415 "os/exec"
1516 "os/signal"
16- "slices"
1717 "strconv"
1818 "strings"
1919 "syscall"
@@ -360,15 +360,15 @@ func assignPorts(
360360 ports := svclib.Ports {}
361361
362362 for label , spec := range serviceSpecs {
363- namedPorts := slices .Clone (spec .NamedPorts )
363+ namedPorts := maps .Clone (spec .NamedPorts )
364364 if spec .AutoassignPort {
365- namedPorts = append ( namedPorts , "" )
365+ namedPorts [ "" ] = spec . Port
366366 }
367367
368368 // Note, this can cause collisions. So be careful!
369369 // To avoid port collisions, set the `so_reuseport_aware` option on the service definition
370370 // and use the SO_REUSEPORT socket option in your services.
371- for _ , portName := range namedPorts {
371+ for portName , port := range namedPorts {
372372 // We do a bit of a dance here to set SO_LINGER to 0. For details, see
373373 // https://stackoverflow.com/questions/71975992/what-really-is-the-linger-time-that-can-be-set-with-so-linger-on-sockets
374374 lc := net.ListenConfig {
@@ -387,18 +387,18 @@ func assignPorts(
387387 },
388388 }
389389
390- listener , err := lc .Listen (context .Background (), "tcp" , "127.0.0.1:0" )
390+ listener , err := lc .Listen (context .Background (), "tcp" , "127.0.0.1:" + port )
391391 if err != nil {
392392 return nil , err
393393 }
394- _ , port , err : = net .SplitHostPort (listener .Addr ().String ())
394+ _ , port , err = net .SplitHostPort (listener .Addr ().String ())
395395 if err != nil {
396396 return nil , err
397397 }
398398
399399 qualifiedPortName := label
400400 if portName != "" {
401- qualifiedPortName += ": " + portName
401+ qualifiedPortName += ". " + portName
402402 }
403403
404404 if ! terseOutput {
@@ -407,6 +407,20 @@ func assignPorts(
407407
408408 ports .Set (qualifiedPortName , port )
409409
410+ {
411+ // TODO(zbarsky): Clean this up after April 2026
412+ qualifiedPortName := label
413+ if portName != "" {
414+ qualifiedPortName += ":" + portName
415+ }
416+
417+ if ! terseOutput {
418+ log .Printf ("Assigning port %s to %s\n " , port , qualifiedPortName )
419+ }
420+
421+ ports .Set (qualifiedPortName , port )
422+ }
423+
410424 if ! spec .SoReuseportAware {
411425 toClose = append (toClose , listener )
412426 }
@@ -424,10 +438,20 @@ func assignPorts(
424438 for portName , aliasedTo := range spec .PortAliases {
425439 qualifiedPortName := label
426440 if portName != "" {
427- qualifiedPortName += ": " + portName
441+ qualifiedPortName += ". " + portName
428442 }
429443
430444 ports .Set (qualifiedPortName , ports [aliasedTo ])
445+
446+ {
447+ // TODO(zbarsky): Clean this up after April 2026
448+ qualifiedPortName := label
449+ if portName != "" {
450+ qualifiedPortName += ":" + portName
451+ }
452+
453+ ports .Set (qualifiedPortName , ports [aliasedTo ])
454+ }
431455 }
432456 }
433457
@@ -516,6 +540,7 @@ func augmentServiceSpecs(
516540 Replacement {Old : "$${TMPDIR}" , New : tmpDir },
517541 Replacement {Old : "$${SOCKET_DIR}" , New : socketDir },
518542 )
543+
519544 for label , port := range ports {
520545 replacements = append (replacements , Replacement {
521546 Old : "$${" + label + "}" ,
0 commit comments