feat: add config loader
Docker Build and Push / Build and Push Docker Image (push) Successful in 13m50s
Docker Build and Push / Build and Push Docker Image (push) Successful in 13m50s
This commit is contained in:
@@ -0,0 +1,74 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/joho/godotenv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config interface {
|
||||||
|
Addr() string
|
||||||
|
Port() string
|
||||||
|
DatabaseURL() string
|
||||||
|
}
|
||||||
|
type config struct {
|
||||||
|
addr string
|
||||||
|
port string
|
||||||
|
databaseURL string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *config) Addr() string {
|
||||||
|
return c.addr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *config) Port() string {
|
||||||
|
return c.port
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *config) DatabaseURL() string {
|
||||||
|
return c.databaseURL
|
||||||
|
}
|
||||||
|
|
||||||
|
func parse() (*config, error) {
|
||||||
|
domain := getenv("ADDRESS", "0.0.0.0")
|
||||||
|
sshPort := getenv("PORT", "8080")
|
||||||
|
databaseURL := getenv("DATABASE_URL", "")
|
||||||
|
|
||||||
|
if databaseURL == "" {
|
||||||
|
return nil, fmt.Errorf("DATABASE_URL environment variable not set")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &config{
|
||||||
|
addr: domain,
|
||||||
|
port: sshPort,
|
||||||
|
databaseURL: databaseURL,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadEnvFile() error {
|
||||||
|
if _, err := os.Stat(".env"); err == nil {
|
||||||
|
return godotenv.Load(".env")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getenv(key, def string) string {
|
||||||
|
if v := os.Getenv(key); v != "" {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return def
|
||||||
|
}
|
||||||
|
|
||||||
|
func MustLoad() (Config, error) {
|
||||||
|
if err := loadEnvFile(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg, err := parse()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return cfg, nil
|
||||||
|
}
|
||||||
@@ -11,12 +11,12 @@ import (
|
|||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
addr string
|
addr string
|
||||||
port uint16
|
port string
|
||||||
repository *repository.Queries
|
repository *repository.Queries
|
||||||
jwt *jwt.JWT
|
jwt *jwt.JWT
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(addr string, port uint16, repository *repository.Queries, jwt *jwt.JWT) *Server {
|
func New(addr string, port string, repository *repository.Queries, jwt *jwt.JWT) *Server {
|
||||||
return &Server{
|
return &Server{
|
||||||
addr: addr,
|
addr: addr,
|
||||||
port: port,
|
port: port,
|
||||||
@@ -55,7 +55,7 @@ func router(repository *repository.Queries, jwt *jwt.JWT) *http.ServeMux {
|
|||||||
func (s *Server) Start() error {
|
func (s *Server) Start() error {
|
||||||
r := router(s.repository, s.jwt)
|
r := router(s.repository, s.jwt)
|
||||||
hs := &http.Server{
|
hs := &http.Server{
|
||||||
Addr: fmt.Sprintf("%s:%d", s.addr, s.port),
|
Addr: fmt.Sprintf("%s:%s", s.addr, s.port),
|
||||||
Handler: middleware.Handler(middleware.CORS(r)),
|
Handler: middleware.Handler(middleware.CORS(r)),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,23 +5,22 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
"ristek-task-be/internal/config"
|
||||||
"ristek-task-be/internal/db/sqlc/repository"
|
"ristek-task-be/internal/db/sqlc/repository"
|
||||||
"ristek-task-be/internal/jwt"
|
"ristek-task-be/internal/jwt"
|
||||||
"ristek-task-be/internal/server"
|
"ristek-task-be/internal/server"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/jackc/pgx/v5/pgxpool"
|
"github.com/jackc/pgx/v5/pgxpool"
|
||||||
"github.com/joho/godotenv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
log.SetOutput(os.Stdout)
|
log.SetOutput(os.Stdout)
|
||||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||||
|
|
||||||
if _, err := os.Stat(".env"); err == nil {
|
conf, err := config.MustLoad()
|
||||||
if err = godotenv.Load(".env"); err != nil {
|
if err != nil {
|
||||||
log.Printf("Warning: Failed to load .env file: %s", err)
|
log.Fatalf("failed to load config: %s", err)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
errChan := make(chan error, 1)
|
errChan := make(chan error, 1)
|
||||||
@@ -29,18 +28,10 @@ func main() {
|
|||||||
|
|
||||||
signal.Notify(signalChan, os.Interrupt, syscall.SIGTERM)
|
signal.Notify(signalChan, os.Interrupt, syscall.SIGTERM)
|
||||||
|
|
||||||
addr := "localhost"
|
|
||||||
port := uint16(8080)
|
|
||||||
|
|
||||||
dbURL := os.Getenv("DATABASE_URL")
|
|
||||||
if dbURL == "" {
|
|
||||||
log.Fatal("DATABASE_URL is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
connect, err := pgxpool.New(ctx, dbURL)
|
connect, err := pgxpool.New(ctx, conf.DatabaseURL())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -48,12 +39,12 @@ func main() {
|
|||||||
repo := repository.New(connect)
|
repo := repository.New(connect)
|
||||||
j := jwt.New("yomama")
|
j := jwt.New("yomama")
|
||||||
go func() {
|
go func() {
|
||||||
s := server.New(addr, port, repo, j)
|
s := server.New(conf.Addr(), conf.Port(), repo, j)
|
||||||
err = s.Start()
|
err = s.Start()
|
||||||
errChan <- err
|
errChan <- err
|
||||||
}()
|
}()
|
||||||
|
|
||||||
log.Printf("Server is running on %s:%d", addr, port)
|
log.Printf("Server is running on %s:%s", conf.Addr(), conf.Port())
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case err = <-errChan:
|
case err = <-errChan:
|
||||||
|
|||||||
Reference in New Issue
Block a user