add output format option

This commit is contained in:
Simon Vieille 2024-07-22 13:32:47 +02:00
commit 234fb37b82
Signed by: deblan
GPG key ID: 579388D585F70417
4 changed files with 84 additions and 22 deletions

View file

@ -25,3 +25,12 @@ $ expiration-check certificates -d example.com -d other-example.com -d mail.exam
| mail.example.com | XXX | YYYY-MM-DD HH:MM:SS | | mail.example.com | XXX | YYYY-MM-DD HH:MM:SS |
+-------------------+------+---------------------+ +-------------------+------+---------------------+
``` ```
You can specify an ouput format using `--format` or `-f`:
- `table` (default)
- `json`
- `csv`
- `tsv`
- `html`
- `markdown`

32
app.go
View file

@ -6,12 +6,32 @@ import (
"gitnet.fr/deblan/expiration-check/render" "gitnet.fr/deblan/expiration-check/render"
) )
func NormalizeFormat(format string) string {
formats := []string{"json", "table", "csv", "tsv", "html", "markdown"}
for _, f := range formats {
if f == format {
return f
}
}
return "table"
}
func App() *cli.App { func App() *cli.App {
flags := []cli.Flag{ flags := []cli.Flag{
&cli.StringSliceFlag{ &cli.StringSliceFlag{
Name: "domain", Name: "domain",
Aliases: []string{"d"}, Aliases: []string{"d"},
Required: true, Required: true,
Usage: "list of domains",
},
&cli.StringFlag{
Name: "format",
Aliases: []string{"f"},
Required: false,
Value: "table",
Usage: "output format: table, csv, tsv, html, json, markdown",
}, },
} }
@ -23,7 +43,11 @@ func App() *cli.App {
Usage: "Checks certificate", Usage: "Checks certificate",
Flags: flags, Flags: flags,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
render.Render(checker.CheckCertificates(c.StringSlice("domain")), 30, 14) render.Render(
checker.CheckCertificates(c.StringSlice("domain")),
30, 14,
NormalizeFormat(c.String("format")),
)
return nil return nil
}, },
@ -34,7 +58,11 @@ func App() *cli.App {
Aliases: []string{"d", "domains"}, Aliases: []string{"d", "domains"},
Flags: flags, Flags: flags,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
render.Render(checker.CheckDomains(c.StringSlice("domain")), 30, 14) render.Render(
checker.CheckDomains(c.StringSlice("domain")),
30, 14,
NormalizeFormat(c.String("format")),
)
return nil return nil
}, },

View file

@ -1,8 +1,8 @@
package checker package checker
type Domain struct { type Domain struct {
Name string Name string `json:"name"`
DaysLeft float64 DaysLeft float64 `json:"days"`
Date string Date string `json:"date"`
Failed bool Failed bool `json:"failed"`
} }

View file

@ -1,6 +1,8 @@
package render package render
import ( import (
"encoding/json"
"fmt"
"os" "os"
"sort" "sort"
@ -9,7 +11,15 @@ import (
"gitnet.fr/deblan/expiration-check/checker" "gitnet.fr/deblan/expiration-check/checker"
) )
func Render(values []checker.Domain, warning, danger float64) { func RenderColor(value string, c text.Colors, format string) string {
if format != "table" {
return value
}
return c.Sprint(value)
}
func Render(values []checker.Domain, warning, danger float64, format string) {
sort.SliceStable(values, func(i, j int) bool { sort.SliceStable(values, func(i, j int) bool {
if values[i].Failed && values[j].Failed { if values[i].Failed && values[j].Failed {
return values[i].Name < values[j].Name return values[i].Name < values[j].Name
@ -26,12 +36,19 @@ func Render(values []checker.Domain, warning, danger float64) {
return values[i].DaysLeft < values[j].DaysLeft return values[i].DaysLeft < values[j].DaysLeft
}) })
if format == "json" {
data, _ := json.Marshal(&values)
os.Stdout.Write(data)
return
}
t := table.NewWriter() t := table.NewWriter()
t.SetOutputMirror(os.Stdout) t.SetOutputMirror(os.Stdout)
t.AppendHeader(table.Row{ t.AppendHeader(table.Row{
text.Colors{0, text.FgCyan}.Sprint("Domain"), RenderColor("Domain", text.Colors{0, text.FgCyan}, format),
text.Colors{0, text.FgCyan}.Sprint("Days"), RenderColor("Days", text.Colors{0, text.FgCyan}, format),
text.Colors{0, text.FgCyan}.Sprint("Date"), RenderColor("Date", text.Colors{0, text.FgCyan}, format),
}) })
t.SetColumnConfigs([]table.ColumnConfig{ t.SetColumnConfigs([]table.ColumnConfig{
{Number: 2, Align: text.AlignRight}, {Number: 2, Align: text.AlignRight},
@ -39,25 +56,23 @@ func Render(values []checker.Domain, warning, danger float64) {
}) })
for _, value := range values { for _, value := range values {
failed := RenderColor("FAIL", text.Colors{0, text.FgRed}, format)
if value.Failed { if value.Failed {
t.AppendRow(table.Row{ t.AppendRow(table.Row{value.Name, failed, failed}, table.RowConfig{})
value.Name,
text.Colors{0, text.FgRed}.Sprint("FAIL"),
text.Colors{0, text.FgRed}.Sprint("FAIL"),
}, table.RowConfig{})
} else { } else {
var days string var days string
var date string var date string
if value.DaysLeft <= danger { if value.DaysLeft <= danger {
days = text.Colors{0, text.FgRed}.Sprint("FAIL") days = failed
date = text.Colors{0, text.FgRed}.Sprint("FAIL") date = failed
} else if value.DaysLeft <= warning { } else if value.DaysLeft <= warning {
days = text.Colors{0, text.FgYellow}.Sprint(value.DaysLeft) days = RenderColor(fmt.Sprintf("%.0f", value.DaysLeft), text.Colors{0, text.FgYellow}, format)
date = text.Colors{0, text.FgYellow}.Sprint(value.Date) date = RenderColor(value.Date, text.Colors{0, text.FgYellow}, format)
} else { } else {
days = text.Colors{0, text.FgGreen}.Sprint(value.DaysLeft) days = RenderColor(fmt.Sprintf("%.0f", value.DaysLeft), text.Colors{0, text.FgGreen}, format)
date = text.Colors{0, text.FgGreen}.Sprint(value.Date) date = RenderColor(value.Date, text.Colors{0, text.FgGreen}, format)
} }
t.AppendRow(table.Row{ t.AppendRow(table.Row{
@ -68,5 +83,15 @@ func Render(values []checker.Domain, warning, danger float64) {
} }
} }
if format == "table" {
t.Render() t.Render()
} else if format == "csv" {
t.RenderCSV()
} else if format == "html" {
t.RenderHTML()
} else if format == "tsv" {
t.RenderTSV()
} else if format == "markdown" {
t.RenderMarkdown()
}
} }