working on a dream... 😏
This commit is contained in:
parent
5330eac174
commit
64f7f4c131
@ -12,14 +12,6 @@ import (
|
|||||||
"gitea.thegux.fr/hmdeploy/models"
|
"gitea.thegux.fr/hmdeploy/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
appPartsLength = 2
|
|
||||||
imagePartsLength = 2
|
|
||||||
portPartsLength = 2
|
|
||||||
portOutPartsLength = 2
|
|
||||||
replicasPartLength = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrDockerClientSave = errors.New("unable to save image into tar")
|
ErrDockerClientSave = errors.New("unable to save image into tar")
|
||||||
|
|
||||||
|
|||||||
@ -131,7 +131,7 @@ func (s *Service) UnmarshalJSON(data []byte) error {
|
|||||||
Tag string
|
Tag string
|
||||||
}{
|
}{
|
||||||
Name: imageName,
|
Name: imageName,
|
||||||
Tag: ci.Details[0].Spec.Labels.Tag,
|
Tag: imageNameParts[1],
|
||||||
},
|
},
|
||||||
Ports: ci.Details[0].Endpoint.Ports,
|
Ports: ci.Details[0].Endpoint.Ports,
|
||||||
Replicas: replicas,
|
Replicas: replicas,
|
||||||
|
|||||||
58
main.go
58
main.go
@ -9,6 +9,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path"
|
"path"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"gitea.thegux.fr/hmdeploy/deployers"
|
"gitea.thegux.fr/hmdeploy/deployers"
|
||||||
@ -255,7 +256,62 @@ func getSwarmServicesDetails(hm *models.HMMap) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(services)
|
tb := utils.NewTable(
|
||||||
|
utils.WithColSeparator(" | "),
|
||||||
|
utils.WithHeaderBorderStyle("*"),
|
||||||
|
utils.WithRowSeparator("-"),
|
||||||
|
utils.WithHeader("App", 20),
|
||||||
|
utils.WithHeader("Name", 20),
|
||||||
|
utils.WithHeader("Image", 20),
|
||||||
|
utils.WithHeader("Tag", 20),
|
||||||
|
utils.WithHeader("Target-Published", 40),
|
||||||
|
utils.WithHeader("Replicas", 2),
|
||||||
|
utils.WithHeader("Status", 10),
|
||||||
|
)
|
||||||
|
|
||||||
|
for idx := range services {
|
||||||
|
columns := []utils.Column{}
|
||||||
|
columns = append(
|
||||||
|
columns,
|
||||||
|
utils.Column{
|
||||||
|
Name: "app",
|
||||||
|
Value: services[idx].App,
|
||||||
|
},
|
||||||
|
utils.Column{
|
||||||
|
Name: "name",
|
||||||
|
Value: services[idx].Name,
|
||||||
|
},
|
||||||
|
utils.Column{
|
||||||
|
Name: "image",
|
||||||
|
Value: services[idx].Image.Name,
|
||||||
|
},
|
||||||
|
utils.Column{
|
||||||
|
Name: "tag",
|
||||||
|
Value: services[idx].Image.Tag,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
ports := []string{}
|
||||||
|
for idy := range services[idx].Ports {
|
||||||
|
ports = append(
|
||||||
|
ports,
|
||||||
|
fmt.Sprintf(
|
||||||
|
"%d-%d",
|
||||||
|
services[idx].Ports[idy].Target,
|
||||||
|
services[idx].Ports[idy].Published,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
columns = append(columns, utils.Column{
|
||||||
|
Name: "target-published",
|
||||||
|
Value: strings.Join(ports, ","),
|
||||||
|
})
|
||||||
|
|
||||||
|
tb.AddRow(columns...)
|
||||||
|
}
|
||||||
|
tb.Render()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
150
utils/utils.go
150
utils/utils.go
@ -120,3 +120,153 @@ func CatchAndConvertNumber(value string) (int, error) {
|
|||||||
|
|
||||||
return strconv.Atoi(string(buf))
|
return strconv.Atoi(string(buf))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type HeaderColumn struct {
|
||||||
|
Name string
|
||||||
|
Length int
|
||||||
|
pos int
|
||||||
|
}
|
||||||
|
|
||||||
|
type Header struct {
|
||||||
|
BorderStyle string
|
||||||
|
headerMeta map[string]*HeaderColumn
|
||||||
|
Columns []HeaderColumn
|
||||||
|
}
|
||||||
|
|
||||||
|
type TableOption func(*Table)
|
||||||
|
|
||||||
|
func WithHeaderBorderStyle(style string) TableOption {
|
||||||
|
return func(t *Table) {
|
||||||
|
t.Header.BorderStyle = style
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithRowSeparator(separator string) TableOption {
|
||||||
|
return func(t *Table) {
|
||||||
|
t.RowSeparator = separator
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithColSeparator(separator string) TableOption {
|
||||||
|
return func(t *Table) {
|
||||||
|
t.ColSeparator = separator
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithHeader(name string, length int) TableOption {
|
||||||
|
return func(t *Table) {
|
||||||
|
if t.Header.Columns == nil {
|
||||||
|
t.Header.Columns = []HeaderColumn{}
|
||||||
|
}
|
||||||
|
pos := len(t.Header.Columns)
|
||||||
|
t.Header.Columns = append(
|
||||||
|
t.Header.Columns,
|
||||||
|
HeaderColumn{Name: name, Length: length, pos: pos},
|
||||||
|
)
|
||||||
|
|
||||||
|
if t.Header.headerMeta == nil {
|
||||||
|
t.Header.headerMeta = map[string]*HeaderColumn{}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Header.headerMeta[strings.ToLower(name)] = &t.Header.Columns[pos]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Column struct {
|
||||||
|
Name string
|
||||||
|
Value string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Table struct {
|
||||||
|
RowSeparator string
|
||||||
|
ColSeparator string
|
||||||
|
data [][]string
|
||||||
|
Header Header
|
||||||
|
cursor int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTable(options ...TableOption) Table {
|
||||||
|
table := Table{}
|
||||||
|
for _, o := range options {
|
||||||
|
o(&table)
|
||||||
|
}
|
||||||
|
|
||||||
|
table.data = [][]string{}
|
||||||
|
|
||||||
|
return table
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Table) AddRow(columns ...Column) error {
|
||||||
|
maxNbCols := len(t.Header.Columns)
|
||||||
|
if len(columns) > maxNbCols {
|
||||||
|
return fmt.Errorf("invalid column number, should be %d", maxNbCols)
|
||||||
|
}
|
||||||
|
|
||||||
|
rowData := make([]string, maxNbCols)
|
||||||
|
t.data = append(t.data, rowData)
|
||||||
|
|
||||||
|
for idx := range columns {
|
||||||
|
header, ok := t.Header.headerMeta[strings.ToLower(columns[idx].Name)]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("no corresponding %s column exist", columns[idx].Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
value := columns[idx].Value
|
||||||
|
if len(value) > header.Length {
|
||||||
|
log.Debug().
|
||||||
|
Str("column", columns[idx].Name).
|
||||||
|
Str("value", value).
|
||||||
|
Msg("col value too long, trimming...")
|
||||||
|
value = value[:header.Length-3] + "..."
|
||||||
|
}
|
||||||
|
|
||||||
|
t.data[t.cursor][header.pos] = value
|
||||||
|
}
|
||||||
|
t.cursor++
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Table) Render() {
|
||||||
|
table := []string{}
|
||||||
|
|
||||||
|
// header
|
||||||
|
headerParts := []string{}
|
||||||
|
for idx := range t.Header.Columns {
|
||||||
|
headerParts = append(
|
||||||
|
headerParts,
|
||||||
|
fmt.Sprintf("%-*s", t.Header.Columns[idx].Length, t.Header.Columns[idx].Name),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
header := strings.Join(headerParts, t.ColSeparator)
|
||||||
|
border := ""
|
||||||
|
for i := 0; i < len(header); i++ {
|
||||||
|
border += t.Header.BorderStyle
|
||||||
|
}
|
||||||
|
|
||||||
|
rowHr := ""
|
||||||
|
for i := 0; i < len(header); i++ {
|
||||||
|
rowHr += t.RowSeparator
|
||||||
|
}
|
||||||
|
|
||||||
|
table = append(table, border, header, border)
|
||||||
|
|
||||||
|
// data
|
||||||
|
for idx := range t.data {
|
||||||
|
lineParts := []string{}
|
||||||
|
for idy := range t.data[idx] {
|
||||||
|
lineParts = append(lineParts, fmt.Sprintf(
|
||||||
|
"%-*s",
|
||||||
|
t.Header.Columns[idy].Length,
|
||||||
|
t.data[idx][idy]),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if idx+1 < len(t.data) {
|
||||||
|
table = append(table, strings.Join(lineParts, t.ColSeparator), rowHr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(strings.Join(table, "\n"))
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user