github.com/drud/ddev@v1.21.5-alpha1.0.20230226034409-94fcc4b94453/pkg/ddevapp/list.go (about)

     1  package ddevapp
     2  
     3  import (
     4  	"bytes"
     5  	"github.com/drud/ddev/pkg/globalconfig"
     6  	"github.com/drud/ddev/pkg/nodeps"
     7  	"github.com/drud/ddev/pkg/output"
     8  	"github.com/drud/ddev/pkg/styles"
     9  	"github.com/drud/ddev/pkg/util"
    10  	"github.com/drud/ddev/pkg/versionconstants"
    11  	"github.com/jedib0t/go-pretty/v6/table"
    12  	"github.com/jedib0t/go-pretty/v6/text"
    13  	"strings"
    14  	"time"
    15  )
    16  
    17  // List provides the functionality for `ddev list`
    18  // activeOnly if true only shows projects that are currently docker containers
    19  // continuous if true keeps requesting and outputting continuously
    20  // wrapTableText if true the text is wrapped instead of truncated to fit the row length
    21  // continuousSleepTime is the time between reports
    22  func List(activeOnly bool, continuous bool, wrapTableText bool, continuousSleepTime int) {
    23  	runTime := util.TimeTrack(time.Now(), "ddev list")
    24  	defer runTime()
    25  
    26  	var out bytes.Buffer
    27  
    28  	for {
    29  		apps, err := GetProjects(activeOnly)
    30  		if err != nil {
    31  			util.Failed("failed getting GetProjects: %v", err)
    32  		}
    33  		appDescs := make([]map[string]interface{}, 0)
    34  
    35  		if len(apps) < 1 {
    36  			output.UserOut.WithField("raw", appDescs).Println("No ddev projects were found.")
    37  		} else {
    38  			t := CreateAppTable(&out, wrapTableText)
    39  			for _, app := range apps {
    40  				desc, err := app.Describe(true)
    41  				if err != nil {
    42  					util.Error("Failed to describe project %s: %v", app.GetName(), err)
    43  				}
    44  				appDescs = append(appDescs, desc)
    45  				RenderAppRow(t, desc)
    46  			}
    47  
    48  			routerStatus, _ := GetRouterStatus()
    49  			var extendedRouterStatus = RenderRouterStatus()
    50  			if nodeps.ArrayContainsString(globalconfig.DdevGlobalConfig.OmitContainersGlobal, globalconfig.DdevRouterContainer) {
    51  				extendedRouterStatus = "disabled"
    52  			}
    53  			routerImage := versionconstants.GetRouterImage()
    54  			routerImage = strings.Replace(routerImage, ":", ": ", 1)
    55  			routerImage = strings.Replace(routerImage, "drud/ddev-router", "original", 1)
    56  			t.AppendFooter(table.Row{
    57  				"Router", routerStatus, "~/.ddev", globalconfig.GetRouterURL(), routerImage},
    58  			)
    59  			t.Render()
    60  			output.UserOut.WithField("raw", appDescs).Print(out.String())
    61  			if routerStatus != "healthy" {
    62  				rawResult := map[string]string{
    63  					"routerStatus":         routerStatus,
    64  					"extendedRouterStatus": extendedRouterStatus,
    65  				}
    66  				rawResult["routerStatus"] = routerStatus
    67  				rawResult["extendedStatus"] = extendedRouterStatus
    68  				output.UserOut.WithField("raw", rawResult)
    69  			}
    70  		}
    71  
    72  		if !continuous {
    73  			break
    74  		}
    75  
    76  		time.Sleep(time.Duration(continuousSleepTime) * time.Second)
    77  	}
    78  }
    79  
    80  // CreateAppTable will create a new app table for describe and list output
    81  func CreateAppTable(out *bytes.Buffer, wrapTableText bool) table.Writer {
    82  	t := table.NewWriter()
    83  	t.AppendHeader(table.Row{"Name", "Status", "Location", "URL", "Type"})
    84  	termWidth, _ := nodeps.GetTerminalWidthHeight()
    85  	usableWidth := termWidth - 15
    86  	statusWidth := 7 // Maybe just "running"
    87  	nameWidth := 10
    88  	typeWidth := 9 // drupal7, magento2 or wordpress
    89  	locationWidth := 20
    90  	urlWidth := 20
    91  	if termWidth > 80 {
    92  		urlWidth = urlWidth + (termWidth-80)/2
    93  		locationWidth = locationWidth + (termWidth-80)/2
    94  		statusWidth = statusWidth + (termWidth-80)/3
    95  	}
    96  	totUsedWidth := nameWidth + statusWidth + locationWidth + urlWidth + typeWidth
    97  	if !wrapTableText {
    98  		t.SetAllowedRowLength(termWidth)
    99  	}
   100  
   101  	util.Debug("detected terminal width=%v usableWidth=%d statusWidth=%d nameWidth=%d locationWidth=%d urlWidth=%d typeWidth=%d totUsedWidth=%d", termWidth, usableWidth, statusWidth, nameWidth, locationWidth, urlWidth, typeWidth, totUsedWidth)
   102  	t.SortBy([]table.SortBy{{Name: "Name"}})
   103  
   104  	if !globalconfig.DdevGlobalConfig.SimpleFormatting {
   105  
   106  		t.SetColumnConfigs([]table.ColumnConfig{
   107  			{
   108  				Name: "Name",
   109  				//WidthMax: nameWidth,
   110  			},
   111  			{
   112  				Name:     "Status",
   113  				WidthMax: statusWidth,
   114  			},
   115  			{
   116  				Name: "Location",
   117  				//WidthMax: locationWidth,
   118  			},
   119  			{
   120  				Name: "URL",
   121  				//WidthMax: urlWidth,
   122  			},
   123  			{
   124  				Name:             "Type",
   125  				WidthMax:         int(typeWidth),
   126  				WidthMaxEnforcer: text.WrapText,
   127  			},
   128  		})
   129  	}
   130  	styles.SetGlobalTableStyle(t)
   131  	t.SetOutputMirror(out)
   132  	return t
   133  }