diff --git a/.goreleaser.yml b/.goreleaser.yml index 02578c7..9aaaf32 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -96,6 +96,16 @@ archives: checksum: name_template: "checksums.txt" + +release: + footer: >- + ## Docker Images + + - `docker pull docker.io/pgconfig/api:{{ .Version }}` + - `docker pull ghcr.io/pgconfig/api:{{ .Version }}` + - `docker pull docker.io/pgconfig/pgconfigctl:{{ .Version }}` + - `docker pull ghcr.io/pgconfig/pgconfigctl:{{ .Version }}` + snapshot: version_template: "{{ .Tag }}-next" @@ -117,9 +127,6 @@ dockers_v2: ids: - pgconfigctl dockerfile: cmd/pgconfigctl/Dockerfile - use: buildx - build_flag_templates: - - "--platform=linux/amd64,linux/arm64" images: - "docker.io/pgconfig/pgconfigctl" - "ghcr.io/pgconfig/pgconfigctl" @@ -134,14 +141,14 @@ dockers_v2: "org.opencontainers.image.website": "pgconfig.org" "org.opencontainers.image.revision": "{{.FullCommit}}" "org.opencontainers.image.version": "{{.Version}}" + platforms: + - linux/amd64 + - linux/arm64 - id: api ids: - api dockerfile: cmd/api/Dockerfile - use: buildx - build_flag_templates: - - "--platform=linux/amd64,linux/arm64" extra_files: - rules.yml - pg-docs.yml @@ -160,3 +167,7 @@ dockers_v2: "org.opencontainers.image.website": "pgconfig.org" "org.opencontainers.image.revision": "{{.FullCommit}}" "org.opencontainers.image.version": "{{.Version}}" + platforms: + - linux/amd64 + - linux/arm64 + diff --git a/cmd/api/handlers/v1/config.go b/cmd/api/handlers/v1/config.go index 9b2abbe..bb9da03 100644 --- a/cmd/api/handlers/v1/config.go +++ b/cmd/api/handlers/v1/config.go @@ -2,6 +2,7 @@ package v1 import ( "fmt" + "os" "strconv" "github.com/gofiber/fiber/v2" @@ -14,8 +15,48 @@ import ( "github.com/pgconfig/api/pkg/input/bytes" "github.com/pgconfig/api/pkg/input/profile" "github.com/pgconfig/api/pkg/rules" + "gopkg.in/yaml.v2" ) +type rulesFileContent struct { + Categories map[string]map[string]parameter `json:"categories"` +} + +type parameter struct { + Abstract string `json:"abstract"` + Recomendations map[string]string `json:"recomendations,omitempty"` + Formula string `json:"formula,omitempty"` +} + +var ( + allRules rulesFileContent + pgDocs docs.DocFile +) + +// LoadConfig loads the necessary files to the api server +func LoadConfig(rulesFile, docsFile string) error { + fileData, err := os.ReadFile(rulesFile) + if err != nil { + return err + } + + err = yaml.Unmarshal(fileData, &allRules) + if err != nil { + return err + } + docFile, err := os.ReadFile(docsFile) + if err != nil { + return err + } + + err = yaml.Unmarshal(docFile, &pgDocs) + if err != nil { + return err + } + + return nil +} + // GetConfig is a function to that computes the input and suggests a tuning configuration // @Summary Get Configuration // @Description computes the input and suggests a tuning configuration diff --git a/cmd/api/handlers/v1/prepare.go b/cmd/api/handlers/v1/prepare.go deleted file mode 100644 index 316317c..0000000 --- a/cmd/api/handlers/v1/prepare.go +++ /dev/null @@ -1,46 +0,0 @@ -package v1 - -import ( - "io/ioutil" - "log" - - "github.com/pgconfig/api/pkg/docs" - "gopkg.in/yaml.v2" -) - -type rulesFileContent struct { - Categories map[string]map[string]parameter `json:"categories"` -} - -type parameter struct { - Abstract string `json:"abstract"` - Recomendations map[string]string `json:"recomendations,omitempty"` - Formula string `json:"formula,omitempty"` -} - -var ( - allRules rulesFileContent - pgDocs docs.DocFile -) - -// Prepare loads the necessary files to the api server -func Prepare(rulesFile, docsFile string) { - fileData, err := ioutil.ReadFile(rulesFile) - if err != nil { - log.Fatalf("could not open rules config file: %v", err) - } - - err = yaml.Unmarshal(fileData, &allRules) - if err != nil { - log.Fatalf("could not parse rules config file: %v", err) - } - docFile, err := ioutil.ReadFile(docsFile) - if err != nil { - log.Fatalf("could not open pg docs file: %v", err) - } - - err = yaml.Unmarshal(docFile, &pgDocs) - if err != nil { - log.Fatalf("could not parse pg docs file: %v", err) - } -} diff --git a/cmd/api/main.go b/cmd/api/main.go index 0a7c8f7..7c72781 100644 --- a/cmd/api/main.go +++ b/cmd/api/main.go @@ -3,13 +3,13 @@ package main import ( "flag" "fmt" - "log" "os" "strconv" + "github.com/charmbracelet/log" + _ "github.com/pgconfig/api/cmd/api/docs" // docs is generated by Swag CLI, you have to import it. v1 "github.com/pgconfig/api/cmd/api/handlers/v1" - "github.com/pgconfig/api/cmd/api/routes" "github.com/pgconfig/api/pkg/version" ) @@ -32,22 +32,24 @@ func getDefaultPort(envName string) int { return out } -func initAPI() { +func setupArgs() { flag.IntVar(&port, "port", getDefaultPort("PORT"), "Listen port") flag.StringVar(&rulesFile, "rules-file", "./rules.yml", "Rules file") flag.StringVar(&docsFile, "docs-file", "./pg-docs.yml", "Rules file") flag.Parse() - - v1.Prepare(rulesFile, docsFile) } func main() { - initAPI() + setupArgs() + + if err := v1.LoadConfig(rulesFile, docsFile); err != nil { + log.Fatal("could not load configuration", "err", err) + } - log.Printf("PGConfig API - %s\n", version.Pretty()) + log.Info("PGConfig API", "ver", version.Pretty()) app := routes.New() if err := app.Listen(fmt.Sprintf(":%d", port)); err != nil { - log.Println("[ERR] not running API: ", err) + log.Errorf("not running API: %v", err) } } diff --git a/cmd/api/main_test.go b/cmd/api/main_test.go new file mode 100644 index 0000000..eecd00f --- /dev/null +++ b/cmd/api/main_test.go @@ -0,0 +1,19 @@ +package main + +import ( + "testing" + + v1 "github.com/pgconfig/api/cmd/api/handlers/v1" +) + +func TestLoadConfiguration(t *testing.T) { + // Paths relative to cmd/api + rulesPath := "../../rules.yml" + docsPath := "../../pg-docs.yml" + + // We still need to call LoadConfig because the API handlers depend on + // allRules and pgDocs global variables being initialized. + if err := v1.LoadConfig(rulesPath, docsPath); err != nil { + t.Fatalf("Failed to load configuration: %v", err) + } +} diff --git a/generators/pg-docs/main.go b/generators/pg-docs/main.go index 9f5d546..086409d 100644 --- a/generators/pg-docs/main.go +++ b/generators/pg-docs/main.go @@ -3,7 +3,7 @@ package main import ( "flag" "fmt" - "log" + "github.com/charmbracelet/log" "os" "sync" @@ -105,7 +105,7 @@ func main() { err := saveFile(file) if err != nil { - log.Printf("Could not save file: %v", err) + log.Errorf("Could not save file: %v", err) } } diff --git a/go.mod b/go.mod index 62a4cb3..1546e88 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.25.1 require ( github.com/PuerkitoBio/goquery v1.11.0 github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 + github.com/charmbracelet/log v0.4.2 github.com/gofiber/fiber/v2 v2.52.10 github.com/gofiber/swagger v1.1.1 github.com/mackerelio/go-osstat v0.2.6 @@ -21,10 +22,17 @@ require ( github.com/KyleBanks/depth v1.2.1 // indirect github.com/andybalholm/brotli v1.2.0 // indirect github.com/andybalholm/cascadia v1.3.3 // indirect + github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect + github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect + github.com/charmbracelet/lipgloss v1.1.0 // indirect + github.com/charmbracelet/x/ansi v0.8.0 // indirect + github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect + github.com/charmbracelet/x/term v0.2.1 // indirect github.com/clipperhouse/stringish v0.1.1 // indirect github.com/clipperhouse/uax29/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-openapi/jsonpointer v0.22.4 // indirect github.com/go-openapi/jsonreference v0.21.4 // indirect github.com/go-openapi/spec v0.22.2 // indirect @@ -41,11 +49,14 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jtolds/gls v4.20.0+incompatible // indirect github.com/klauspost/compress v1.18.2 // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.19 // indirect + github.com/muesli/termenv v0.16.0 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/sagikazarmark/locafero v0.12.0 // indirect github.com/sergi/go-diff v1.3.1 // indirect github.com/smarty/assertions v1.15.0 // indirect @@ -56,7 +67,9 @@ require ( github.com/swaggo/files/v2 v2.0.2 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.68.0 // indirect + github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect golang.org/x/mod v0.31.0 // indirect golang.org/x/net v0.48.0 // indirect golang.org/x/sync v0.19.0 // indirect diff --git a/go.sum b/go.sum index b391631..2a22adc 100644 --- a/go.sum +++ b/go.sum @@ -8,6 +8,20 @@ github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwTo github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY= github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM= github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA= +github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= +github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= +github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs= +github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk= +github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= +github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= +github.com/charmbracelet/log v0.4.2 h1:hYt8Qj6a8yLnvR+h7MwsJv/XvmBJXiueUcI3cIxsyig= +github.com/charmbracelet/log v0.4.2/go.mod h1:qifHGX/tc7eluv2R6pWIpyHDDrrb/AG71Pf2ysQu5nw= +github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE= +github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q= +github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8= +github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= +github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= +github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4= @@ -20,6 +34,8 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= +github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= @@ -72,6 +88,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mackerelio/go-osstat v0.2.6 h1:gs4U8BZeS1tjrL08tt5VUliVvSWP26Ai2Ob8Lr7f2i0= github.com/mackerelio/go-osstat v0.2.6/go.mod h1:lRy8V9ZuHpuRVZh+vyTkODeDPl3/d5MgXHtLSaqG8bA= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= @@ -82,10 +100,14 @@ github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byF github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= +github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -122,6 +144,8 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.68.0 h1:v12Nx16iepr8r9ySOwqI+5RBJ/DqTxhOy1HrHoDFnok= github.com/valyala/fasthttp v1.68.0/go.mod h1:5EXiRfYQAoiO/khu4oU9VISC/eVY6JqmSpPJoHCKsz4= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= @@ -133,6 +157,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= diff --git a/pkg/docs/doc.go b/pkg/docs/doc.go index 3ba2d53..4a378e0 100644 --- a/pkg/docs/doc.go +++ b/pkg/docs/doc.go @@ -2,7 +2,7 @@ package docs import ( "fmt" - "log" + "github.com/charmbracelet/log" "net/http" "strings"