diff --git a/Makefile b/Makefile index 4e09fd5b..b1bc2324 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,7 @@ DEP := $(shell command -v dep 2> /dev/null) PACKR2 := $(shell command -v packr2 2> /dev/null) NPM := $(shell command -v npm 2> /dev/null) HUB := $(shell command -v hub 2> /dev/null) +COMPILEDAEMON := $(shell command -v CompileDaemon 2> /dev/null) ## installation install: install-go install-js @@ -18,6 +19,11 @@ ifndef PACKR2 @go get -u github.com/gobuffalo/packr/v2/packr2 endif +ifndef COMPILEDAEMON + @echo "==> installing CompileDaemon" + @go get -u github.com/githubnemo/CompileDaemon +endif + @echo "==> installing go dependencies" @dep ensure .PHONY: install-go diff --git a/pkg/server/.env.dev b/pkg/server/.env.dev index b37996d6..2be2070a 100644 --- a/pkg/server/.env.dev +++ b/pkg/server/.env.dev @@ -1,7 +1,7 @@ GO_ENV=DEVELOPMENT DBHost=localhost -DBPost=5432 +DBPort=5432 DBName=dnote DBUser=postgres DBPassword= diff --git a/pkg/server/.gitignore b/pkg/server/.gitignore index 7de9e987..fa49c96a 100644 --- a/pkg/server/.gitignore +++ b/pkg/server/.gitignore @@ -5,3 +5,4 @@ tmp/ test-dnote /dist /build +server diff --git a/pkg/server/api/scripts/makeDemoDigests/main.go b/pkg/server/api/scripts/makeDemoDigests/main.go index 0ba4d4be..b41d39cb 100644 --- a/pkg/server/api/scripts/makeDemoDigests/main.go +++ b/pkg/server/api/scripts/makeDemoDigests/main.go @@ -21,11 +21,19 @@ package main import ( "github.com/dnote/dnote/pkg/server/api/helpers" "github.com/dnote/dnote/pkg/server/database" + "os" "time" ) func main() { - database.InitDB() + c := database.Config{ + Host: os.Getenv("DBHost"), + Port: os.Getenv("DBPort"), + Name: os.Getenv("DBName"), + User: os.Getenv("DBUser"), + Password: os.Getenv("DBPassword"), + } + database.Open(c) db := database.DBConn tx := db.Begin() diff --git a/pkg/server/database/database.go b/pkg/server/database/database.go index e1112f12..6414e413 100644 --- a/pkg/server/database/database.go +++ b/pkg/server/database/database.go @@ -23,6 +23,7 @@ import ( "os" "github.com/jinzhu/gorm" + "github.com/pkg/errors" // Use postgres _ "github.com/lib/pq" @@ -33,7 +34,49 @@ var ( MigrationTableName = "migrations" ) -func getPGConnectionString() string { +// Config holds the connection configuration +type Config struct { + Host string + Port string + Name string + User string + Password string +} + +// ErrConfigMissingHost is an error for an incomplete configuration missing the host +var ErrConfigMissingHost = errors.New("Host is empty") + +// ErrConfigMissingPort is an error for an incomplete configuration missing the port +var ErrConfigMissingPort = errors.New("Port is empty") + +// ErrConfigMissingName is an error for an incomplete configuration missing the name +var ErrConfigMissingName = errors.New("Name is empty") + +// ErrConfigMissingUser is an error for an incomplete configuration missing the user +var ErrConfigMissingUser = errors.New("User is empty") + +func validateConfig(c Config) error { + if c.Host == "" { + return ErrConfigMissingHost + } + if c.Port == "" { + return ErrConfigMissingPort + } + if c.Name == "" { + return ErrConfigMissingName + } + if c.User == "" { + return ErrConfigMissingUser + } + + return nil +} + +func getPGConnectionString(c Config) (string, error) { + if err := validateConfig(c); err != nil { + return "", errors.Wrap(err, "invalid database config") + } + var sslmode string if os.Getenv("GO_ENV") == "PRODUCTION" { sslmode = "require" @@ -44,12 +87,12 @@ func getPGConnectionString() string { return fmt.Sprintf( "sslmode=%s host=%s port=%s dbname=%s user=%s password=%s", sslmode, - os.Getenv("DBHost"), - os.Getenv("DBPort"), - os.Getenv("DBName"), - os.Getenv("DBUser"), - os.Getenv("DBPassword"), - ) + c.Host, + c.Port, + c.Name, + c.User, + c.Password, + ), nil } var ( @@ -64,11 +107,12 @@ const ( TokenTypeEmailPreference = "email_preference" ) -// InitDB opens the connection with the database -func InitDB() { - var err error - - connStr := getPGConnectionString() +// Open opens the connection with the database +func Open(c Config) { + connStr, err := getPGConnectionString(c) + if err != nil { + panic(err) + } DBConn, err = gorm.Open("postgres", connStr) if err != nil { @@ -76,8 +120,8 @@ func InitDB() { } } -// CloseDB closes database connection -func CloseDB() { +// Close closes database connection +func Close() { DBConn.Close() } diff --git a/pkg/server/database/database_test.go b/pkg/server/database/database_test.go new file mode 100644 index 00000000..2495a3a1 --- /dev/null +++ b/pkg/server/database/database_test.go @@ -0,0 +1,79 @@ +package database + +import ( + "github.com/dnote/dnote/pkg/assert" + "testing" +) + +func TestValidateConfig(t *testing.T) { + testCases := []struct { + input Config + expected error + }{ + { + input: Config{ + Host: "mockHost", + Port: "mockPort", + Name: "mockName", + User: "mockUser", + Password: "mockPassword", + }, + expected: nil, + }, + { + input: Config{ + Host: "mockHost", + Port: "mockPort", + Name: "mockName", + User: "mockUser", + }, + expected: nil, + }, + { + input: Config{ + Port: "mockPort", + Name: "mockName", + User: "mockUser", + Password: "mockPassword", + }, + expected: ErrConfigMissingHost, + }, + { + input: Config{ + Host: "mockHost", + Name: "mockName", + User: "mockUser", + Password: "mockPassword", + }, + expected: ErrConfigMissingPort, + }, + { + input: Config{ + Host: "mockHost", + Port: "mockPort", + User: "mockUser", + Password: "mockPassword", + }, + expected: ErrConfigMissingName, + }, + { + input: Config{ + Host: "mockHost", + Port: "mockPort", + Name: "mockName", + Password: "mockPassword", + }, + expected: ErrConfigMissingUser, + }, + { + input: Config{}, + expected: ErrConfigMissingHost, + }, + } + + for _, tc := range testCases { + result := validateConfig(tc.input) + + assert.Equal(t, result, tc.expected, "result mismatch") + } +} diff --git a/pkg/server/database/migrate/main.go b/pkg/server/database/migrate/main.go index d87e1417..06d5b705 100644 --- a/pkg/server/database/migrate/main.go +++ b/pkg/server/database/migrate/main.go @@ -43,7 +43,14 @@ func init() { } } - database.InitDB() + c := database.Config{ + Host: os.Getenv("DBHost"), + Port: os.Getenv("DBPort"), + Name: os.Getenv("DBName"), + User: os.Getenv("DBUser"), + Password: os.Getenv("DBPassword"), + } + database.Open(c) } func main() { diff --git a/pkg/server/mailer/mailer.go b/pkg/server/mailer/mailer.go index a1754620..ce448003 100644 --- a/pkg/server/mailer/mailer.go +++ b/pkg/server/mailer/mailer.go @@ -86,8 +86,14 @@ func initTemplate(box *packr.Box, templateName string) (*template.Template, erro } // InitTemplates initializes templates -func InitTemplates() { - box := packr.New("emailTemplates", "./templates/src") +func InitTemplates(srcDir *string) { + var box *packr.Box + + if srcDir != nil { + box = packr.Folder(*srcDir) + } else { + box = packr.New("emailTemplates", "./templates/src") + } weeklyDigestTmpl, err := initTemplate(box, EmailTypeWeeklyDigest) if err != nil { diff --git a/pkg/server/mailer/templates/main.go b/pkg/server/mailer/templates/main.go index 0db366b5..81c4d6b1 100644 --- a/pkg/server/mailer/templates/main.go +++ b/pkg/server/mailer/templates/main.go @@ -21,6 +21,7 @@ package main import ( "log" "net/http" + "os" "github.com/dnote/dnote/pkg/server/database" "github.com/dnote/dnote/pkg/server/job" @@ -76,10 +77,17 @@ func init() { } func main() { - database.InitDB() - defer database.CloseDB() + c := database.Config{ + Host: os.Getenv("DBHost"), + Port: os.Getenv("DBPort"), + Name: os.Getenv("DBName"), + User: os.Getenv("DBUser"), + Password: os.Getenv("DBPassword"), + } + database.Open(c) + defer database.Close() - mailer.InitTemplates() + mailer.InitTemplates(nil) log.Println("Email template debug server running on http://127.0.0.1:2300") diff --git a/pkg/server/main.go b/pkg/server/main.go index 55e0a7c4..65a4bebe 100644 --- a/pkg/server/main.go +++ b/pkg/server/main.go @@ -23,6 +23,7 @@ import ( "fmt" "log" "net/http" + "os" "strings" "github.com/dnote/dnote/pkg/server/api/clock" @@ -37,7 +38,7 @@ import ( ) var versionTag = "master" -var port = flag.String("port", "8080", "port to connect to") +var port = flag.String("port", "3000", "port to connect to") func init() { } @@ -78,10 +79,18 @@ func initServer() *mux.Router { } func startCmd() { - mailer.InitTemplates() - database.InitDB() + c := database.Config{ + Host: os.Getenv("DBHost"), + Port: os.Getenv("DBPort"), + Name: os.Getenv("DBName"), + User: os.Getenv("DBUser"), + Password: os.Getenv("DBPassword"), + } + database.Open(c) database.InitSchema() - defer database.CloseDB() + defer database.Close() + + mailer.InitTemplates(nil) // Perform database migration if err := database.Migrate(); err != nil { diff --git a/pkg/server/testutils/main.go b/pkg/server/testutils/main.go index d40c22d6..097ab657 100644 --- a/pkg/server/testutils/main.go +++ b/pkg/server/testutils/main.go @@ -24,6 +24,7 @@ import ( "fmt" "net/http" "net/http/httptest" + "os" "strings" "testing" "time" @@ -38,7 +39,14 @@ import ( // InitTestDB establishes connection pool with the test database specified by // the environment variable configuration and initalizes a new schema func InitTestDB() { - database.InitDB() + c := database.Config{ + Host: os.Getenv("DBHost"), + Port: os.Getenv("DBPort"), + Name: os.Getenv("DBName"), + User: os.Getenv("DBUser"), + Password: os.Getenv("DBPassword"), + } + database.Open(c) database.InitSchema() } diff --git a/web/scripts/dev.sh b/web/scripts/dev.sh index e5da5127..ee3b0089 100755 --- a/web/scripts/dev.sh +++ b/web/scripts/dev.sh @@ -35,4 +35,5 @@ set +a devServerPID=$! # run server -(cd "$serverPath" && go run main.go) +(cd "$serverPath" && CompileDaemon \ + -command="$serverPath/server start")