@@ -3204,7 +3204,28 @@ async def compose_up(compose: PodmanCompose, args: argparse.Namespace) -> int |
32043204
32053205    max_service_length  =  0 
32063206    for  cnt  in  compose .containers :
3207-         curr_length  =  len (cnt ["_service" ])
3207+         # Saltar contenedores excluidos 
3208+         if  cnt ["_service" ] in  excluded :
3209+             continue 
3210+ 
3211+         service_name  =  cnt ["_service" ]
3212+         container_name  =  cnt ["name" ]
3213+ 
3214+         if  getattr (args , 'names' , False ):
3215+             # Con -n: mostrar solo servicio_numero (sin prefijo de proyecto) 
3216+             expected_name  =  compose .format_name (service_name , str (cnt ["num" ]))
3217+ 
3218+             if  container_name  ==  expected_name :
3219+                 # Es un nombre generado automáticamente, mostrar solo servicio_numero 
3220+                 display_name  =  compose .join_name_parts (service_name , str (cnt ["num" ]))
3221+             else :
3222+                 # Es un container_name personalizado, usarlo tal como está 
3223+                 display_name  =  container_name 
3224+         else :
3225+             # Sin -n: mostrar nombre completo del contenedor (comportamiento por defecto) 
3226+             display_name  =  container_name 
3227+ 
3228+         curr_length  =  len (display_name )
32083229        max_service_length  =  curr_length  if  curr_length  >  max_service_length  else  max_service_length 
32093230
32103231    tasks : set [asyncio .Task ] =  set ()
@@ -3226,11 +3247,33 @@ async def handle_sigint() -> None:
32263247        loop .add_signal_handler (signal .SIGINT , lambda : asyncio .create_task (handle_sigint ()))
32273248
32283249    for  i , cnt  in  enumerate (compose .containers ):
3229-         # Add colored service prefix to output by piping output through sed  
3250+         # Add colored service prefix to output like docker-compose  
32303251        color_idx  =  i  %  len (compose .console_colors )
32313252        color  =  compose .console_colors [color_idx ]
3232-         space_suffix  =  " "  *  (max_service_length  -  len (cnt ["_service" ]) +  1 )
3233-         log_formatter  =  "{}[{}]{}|\x1b [0m" .format (color , cnt ["_service" ], space_suffix )
3253+ 
3254+         # Determinar el nombre a mostrar 
3255+         service_name  =  cnt ["_service" ]
3256+         container_name  =  cnt ["name" ]
3257+ 
3258+         if  getattr (args , 'names' , False ):
3259+             # Con -n: mostrar solo servicio_numero (sin prefijo de proyecto) 
3260+             expected_name  =  compose .format_name (service_name , str (cnt ["num" ]))
3261+ 
3262+             if  container_name  ==  expected_name :
3263+                 # Es un nombre generado automáticamente, mostrar solo servicio_numero 
3264+                 display_name  =  compose .join_name_parts (service_name , str (cnt ["num" ]))
3265+             else :
3266+                 # Es un container_name personalizado, usarlo tal como está 
3267+                 display_name  =  container_name 
3268+         else :
3269+             # Sin -n: mostrar nombre completo del contenedor (comportamiento por defecto) 
3270+             display_name  =  container_name 
3271+ 
3272+         # Calcular espacios para alinear el | exactamente 
3273+         # max_service_length + 1 espacio, menos la longitud del display_name actual 
3274+         space_suffix  =  " "  *  (max_service_length  +  1  -  len (display_name ))
3275+         log_formatter  =  "{}{}{}|\x1b [0m" .format (color , display_name , space_suffix )
3276+ 
32343277        if  cnt ["_service" ] in  excluded :
32353278            log .debug ("** skipping: %s" , cnt ["name" ])
32363279            continue 
@@ -3585,29 +3628,149 @@ async def compose_logs(compose: PodmanCompose, args: argparse.Namespace) -> None
35853628    if  not  args .services  and  not  args .latest :
35863629        args .services  =  container_names_by_service .keys ()
35873630    compose .assert_services (args .services )
3631+ 
35883632    targets  =  []
3633+     service_by_container  =  {}
3634+ 
35893635    for  service  in  args .services :
3590-         targets .extend (container_names_by_service [service ])
3591-     podman_args  =  []
3592-     if  args .follow :
3593-         podman_args .append ("-f" )
3594-     if  args .latest :
3595-         podman_args .append ("-l" )
3596-     if  args .names :
3597-         podman_args .append ("-n" )
3598-     if  args .since :
3599-         podman_args .extend (["--since" , args .since ])
3600-     # the default value is to print all logs which is in podman = 0 and not 
3601-     # needed to be passed 
3602-     if  args .tail  and  args .tail  !=  "all" :
3603-         podman_args .extend (["--tail" , args .tail ])
3604-     if  args .timestamps :
3605-         podman_args .append ("-t" )
3606-     if  args .until :
3607-         podman_args .extend (["--until" , args .until ])
3608-     for  target  in  targets :
3609-         podman_args .append (target )
3610-     await  compose .podman .run ([], "logs" , podman_args )
3636+         containers  =  container_names_by_service [service ]
3637+         targets .extend (containers )
3638+         for  container  in  containers :
3639+             service_by_container [container ] =  service 
3640+ 
3641+     should_use_colors  =  (
3642+         (len (args .services ) >  1  or  args .names )
3643+         and  not  args .latest 
3644+         and  sys .stdout .isatty ()
3645+         and  not  getattr (args , "no_color" , False )
3646+     )
3647+ 
3648+     if  should_use_colors :
3649+         # Calcular la longitud máxima para alineación, igual que en compose_up 
3650+         max_service_length  =  0 
3651+         for  target  in  targets :
3652+             cnt  =  compose .container_by_name [target ]
3653+             service_name  =  cnt ["_service" ]
3654+             container_name  =  cnt ["name" ]
3655+ 
3656+             if  getattr (args , 'names' , False ):
3657+                 # Con -n: mostrar solo servicio_numero (sin prefijo de proyecto) 
3658+                 expected_name  =  compose .format_name (service_name , str (cnt ["num" ]))
3659+ 
3660+                 if  container_name  ==  expected_name :
3661+                     # Es un nombre generado automáticamente, mostrar solo servicio_numero 
3662+                     display_name  =  compose .join_name_parts (service_name , str (cnt ["num" ]))
3663+                 else :
3664+                     # Es un container_name personalizado, usarlo tal como está 
3665+                     display_name  =  container_name 
3666+             else :
3667+                 # Sin -n: mostrar nombre completo del contenedor (comportamiento por defecto) 
3668+                 display_name  =  container_name 
3669+ 
3670+             curr_length  =  len (display_name )
3671+             max_service_length  =  (
3672+                 curr_length  if  curr_length  >  max_service_length  else  max_service_length 
3673+             )
3674+ 
3675+         tasks  =  []
3676+         service_colors  =  {}
3677+ 
3678+         for  target  in  targets :
3679+             cnt  =  compose .container_by_name [target ]
3680+             service_name  =  cnt ["_service" ]
3681+             container_name  =  cnt ["name" ]
3682+ 
3683+             # Aplicar la misma lógica de display_name que en compose_up 
3684+             if  getattr (args , 'names' , False ):
3685+                 # Con -n: mostrar solo servicio_numero (sin prefijo de proyecto) 
3686+                 expected_name  =  compose .format_name (service_name , str (cnt ["num" ]))
3687+ 
3688+                 if  container_name  ==  expected_name :
3689+                     # Es un nombre generado automáticamente, mostrar solo servicio_numero 
3690+                     display_name  =  compose .join_name_parts (service_name , str (cnt ["num" ]))
3691+                 else :
3692+                     # Es un container_name personalizado, usarlo tal como está 
3693+                     display_name  =  container_name 
3694+             else :
3695+                 # Sin -n: mostrar nombre completo del contenedor (comportamiento por defecto) 
3696+                 display_name  =  container_name 
3697+ 
3698+             # Asignar color por servicio (no por contenedor individual) 
3699+             if  service_name  not  in   service_colors :
3700+                 color_idx  =  len (service_colors ) %  len (compose .console_colors )
3701+                 service_colors [service_name ] =  compose .console_colors [color_idx ]
3702+ 
3703+             color  =  service_colors [service_name ]
3704+ 
3705+             # Calcular espacios para alinear el | exactamente, igual que en compose_up 
3706+             # max_service_length + 1 espacio, menos la longitud del display_name actual 
3707+             space_suffix  =  " "  *  (max_service_length  +  1  -  len (display_name ))
3708+             log_formatter  =  "{}{}{}|\x1b [0m" .format (color , display_name , space_suffix )
3709+ 
3710+             podman_args  =  []
3711+             if  args .follow :
3712+                 podman_args .append ("-f" )
3713+             if  args .names :
3714+                 podman_args .append ("-n" )
3715+             if  args .since :
3716+                 podman_args .extend (["--since" , args .since ])
3717+             if  args .tail  and  args .tail  !=  "all" :
3718+                 podman_args .extend (["--tail" , args .tail ])
3719+             if  args .timestamps :
3720+                 podman_args .append ("-t" )
3721+             if  args .until :
3722+                 podman_args .extend (["--until" , args .until ])
3723+             podman_args .append (target )
3724+ 
3725+             task  =  asyncio .create_task (
3726+                 compose .podman .run ([], "logs" , podman_args , log_formatter = log_formatter ),
3727+                 name = f"logs-{ service_name }  -{ target }  " ,
3728+             )
3729+             tasks .append (task )
3730+ 
3731+         async  def  handle_sigint () ->  None :
3732+             log .info ("Caught SIGINT or Ctrl+C, stopping log streaming..." )
3733+             for  task  in  tasks :
3734+                 if  not  task .done ():
3735+                     task .cancel ()
3736+ 
3737+         if  sys .platform  !=  'win32' :
3738+             loop  =  asyncio .get_event_loop ()
3739+             loop .add_signal_handler (signal .SIGINT , lambda : asyncio .create_task (handle_sigint ()))
3740+ 
3741+         try :
3742+             await  asyncio .gather (* tasks )
3743+         except  KeyboardInterrupt :
3744+             for  task  in  tasks :
3745+                 if  not  task .done ():
3746+                     task .cancel ()
3747+             await  asyncio .gather (* tasks , return_exceptions = True )
3748+         except  Exception  as  e :
3749+             log .error ("Error in logs command: %s" , e )
3750+             for  task  in  tasks :
3751+                 if  not  task .done ():
3752+                     task .cancel ()
3753+             await  asyncio .gather (* tasks , return_exceptions = True )
3754+             raise 
3755+     else :
3756+         podman_args  =  []
3757+         if  args .follow :
3758+             podman_args .append ("-f" )
3759+         if  args .latest :
3760+             podman_args .append ("-l" )
3761+         if  args .names :
3762+             podman_args .append ("-n" )
3763+         if  args .since :
3764+             podman_args .extend (["--since" , args .since ])
3765+         if  args .tail  and  args .tail  !=  "all" :
3766+             podman_args .extend (["--tail" , args .tail ])
3767+         if  args .timestamps :
3768+             podman_args .append ("-t" )
3769+         if  args .until :
3770+             podman_args .extend (["--until" , args .until ])
3771+         for  target  in  targets :
3772+             podman_args .append (target )
3773+         await  compose .podman .run ([], "logs" , podman_args )
36113774
36123775
36133776@cmd_run (podman_compose , "config" , "displays the compose file" ) 
@@ -3866,6 +4029,12 @@ def compose_up_parse(parser: argparse.ArgumentParser) -> None:
38664029        help = "Return the exit code of the selected service container. " 
38674030        "Implies --abort-on-container-exit." ,
38684031    )
4032+     parser .add_argument (
4033+         "-n" ,
4034+         "--names" ,
4035+         action = "store_true" ,
4036+         help = "Show short service names instead of full container names in logs" ,
4037+     )
38694038
38704039
38714040@cmd_parse (podman_compose , "down" ) 
0 commit comments