github.com/simonferquel/app@v0.6.1-0.20181012141724-68b7cccf26ac/internal/inspect/inspect.go (about) 1 package inspect 2 3 import ( 4 "fmt" 5 "io" 6 "sort" 7 "strings" 8 "text/tabwriter" 9 10 "github.com/docker/app/render" 11 "github.com/docker/app/types" 12 "github.com/docker/app/types/settings" 13 composetypes "github.com/docker/cli/cli/compose/types" 14 units "github.com/docker/go-units" 15 ) 16 17 // Inspect dumps the metadata of an app 18 func Inspect(out io.Writer, app *types.App, argSettings map[string]string) error { 19 // Render the compose file 20 config, err := render.Render(app, argSettings) 21 if err != nil { 22 return err 23 } 24 25 // Extract all the settings 26 settingsKeys, allSettings, err := extractSettings(app, argSettings) 27 if err != nil { 28 return err 29 } 30 31 // Add Meta data 32 printMetadata(out, app) 33 34 // Add Service section 35 printSection(out, len(config.Services), func(w io.Writer) { 36 for _, service := range config.Services { 37 fmt.Fprintf(w, "%s\t%d\t%s\t%s\n", service.Name, getReplicas(service), getPorts(service.Ports), service.Image) 38 } 39 }, "Service", "Replicas", "Ports", "Image") 40 41 // Add Network section 42 printSection(out, len(config.Networks), func(w io.Writer) { 43 for name := range config.Networks { 44 fmt.Fprintln(w, name) 45 } 46 }, "Network") 47 48 // Add Volume section 49 printSection(out, len(config.Volumes), func(w io.Writer) { 50 for name := range config.Volumes { 51 fmt.Fprintln(w, name) 52 } 53 }, "Volume") 54 55 // Add Secret section 56 printSection(out, len(config.Secrets), func(w io.Writer) { 57 for name := range config.Secrets { 58 fmt.Fprintln(w, name) 59 } 60 }, "Secret") 61 62 // Add Setting section 63 printSection(out, len(settingsKeys), func(w io.Writer) { 64 for _, k := range settingsKeys { 65 fmt.Fprintf(w, "%s\t%s\n", k, allSettings[k]) 66 } 67 }, "Setting", "Value") 68 69 // Add Attachments section 70 attachments := app.Attachments() 71 printSection(out, len(attachments), func(w io.Writer) { 72 for _, file := range attachments { 73 sizeString := units.HumanSize(float64(file.Size())) 74 fmt.Fprintf(w, "%s\t%s\n", file.Path(), sizeString) 75 } 76 }, "Attachment", "Size") 77 78 return nil 79 } 80 81 func printMetadata(out io.Writer, app *types.App) { 82 meta := app.Metadata() 83 fmt.Fprintln(out, meta.Name, meta.Version) 84 if maintainers := meta.Maintainers.String(); maintainers != "" { 85 fmt.Fprintln(out) 86 fmt.Fprintln(out, "Maintained by:", maintainers) 87 } 88 if meta.Description != "" { 89 fmt.Fprintln(out) 90 fmt.Fprintln(out, meta.Description) 91 } 92 } 93 94 func printSection(out io.Writer, len int, printer func(io.Writer), headers ...string) { 95 if len == 0 { 96 return 97 } 98 fmt.Fprintln(out) 99 w := tabwriter.NewWriter(out, 0, 0, 1, ' ', 0) 100 var plural string 101 if len > 1 { 102 plural = "s" 103 } 104 headers[0] = fmt.Sprintf("%s%s (%d)", headers[0], plural, len) 105 printHeaders(w, headers...) 106 printer(w) 107 w.Flush() 108 } 109 110 func printHeaders(w io.Writer, headers ...string) { 111 fmt.Fprintln(w, strings.Join(headers, "\t")) 112 dashes := make([]string, len(headers)) 113 for i, h := range headers { 114 dashes[i] = strings.Repeat("-", len(h)) 115 } 116 fmt.Fprintln(w, strings.Join(dashes, "\t")) 117 } 118 119 func getReplicas(service composetypes.ServiceConfig) int { 120 if service.Deploy.Replicas != nil { 121 return int(*service.Deploy.Replicas) 122 } 123 return 1 124 } 125 126 func extractSettings(app *types.App, argSettings map[string]string) ([]string, map[string]string, error) { 127 allSettings, err := mergeAndFlattenSettings(app, argSettings) 128 if err != nil { 129 return nil, nil, err 130 } 131 // sort the keys to get consistent output 132 var settingsKeys []string 133 for k := range allSettings { 134 settingsKeys = append(settingsKeys, k) 135 } 136 sort.Slice(settingsKeys, func(i, j int) bool { return settingsKeys[i] < settingsKeys[j] }) 137 return settingsKeys, allSettings, nil 138 } 139 140 func mergeAndFlattenSettings(app *types.App, argSettings map[string]string) (map[string]string, error) { 141 sArgs, err := settings.FromFlatten(argSettings) 142 if err != nil { 143 return nil, err 144 } 145 s, err := settings.Merge(app.Settings(), sArgs) 146 if err != nil { 147 return nil, err 148 } 149 return s.Flatten(), nil 150 }