Merge pull request #157 from pressly/remove_goose_pkg_deps

Remove goose pkg deps
pull/161/head v2.7.0-rc3
Vojtech Vitek 2019-03-06 01:36:30 -05:00 committed by GitHub
commit f6dca2b18a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 58 additions and 174 deletions

View File

@ -32,7 +32,7 @@ This will install the `goose` binary to your `$GOPATH/bin` directory.
For a lite version of the binary without DB connection dependent commands, use the exclusive build tags:
$ go build -tags='no_mysql no_sqlite no_psql' -i -o goose ./cmd/goose
$ go build -tags='no_postgres no_mysql no_sqlite3' -i -o goose ./cmd/goose
# Usage

View File

@ -3,6 +3,34 @@
package main
import (
"log"
"github.com/go-sql-driver/mysql"
_ "github.com/go-sql-driver/mysql"
_ "github.com/ziutek/mymysql/godrv"
)
// normalizeMySQLDSN parses the dsn used with the mysql driver to always have
// the parameter `parseTime` set to true. This allows internal goose logic
// to assume that DATETIME/DATE/TIMESTAMP can be scanned into the time.Time
// type.
func normalizeDBString(driver string, str string) string {
if driver == "mysql" {
var err error
str, err = normalizeMySQLDSN(str)
if err != nil {
log.Fatalf("failed to normalize MySQL connection string: %v", err)
}
}
return str
}
func normalizeMySQLDSN(dsn string) (string, error) {
config, err := mysql.ParseDSN(dsn)
if err != nil {
return "", err
}
config.ParseTime = true
return config.FormatDSN(), nil
}

View File

@ -0,0 +1,12 @@
// +build no_mysql
package main
import (
_ "github.com/go-sql-driver/mysql"
_ "github.com/ziutek/mymysql/godrv"
)
func normalizeDBString(driver string, str string) string {
return str
}

View File

@ -1,4 +1,4 @@
// +build !no_pq
// +build !no_postgres
package main

View File

@ -1,4 +1,4 @@
// +build !no_sqlite
// +build !no_sqlite3
package main

View File

@ -55,13 +55,7 @@ func main() {
driver, dbstring, command := args[0], args[1], args[2]
switch dbstring {
case "":
log.Fatalf("-dbstring=%q not supported\n", dbstring)
default:
}
db, err := goose.OpenDBWithDriver(driver, dbstring)
db, err := goose.OpenDBWithDriver(driver, normalizeDBString(driver, dbstring))
if err != nil {
log.Fatalf("-dbstring=%q: %v\n", dbstring, err)
}

23
db.go
View File

@ -3,8 +3,6 @@ package goose
import (
"database/sql"
"fmt"
"github.com/go-sql-driver/mysql"
)
// OpenDBWithDriver creates a connection a database, and modifies goose
@ -22,28 +20,9 @@ func OpenDBWithDriver(driver string, dbstring string) (*sql.DB, error) {
}
switch driver {
case "postgres", "sqlite3":
case "postgres", "sqlite3", "mysql":
return sql.Open(driver, dbstring)
case "mysql":
dsn, err := normalizeMySQLDSN(dbstring)
if err != nil {
return nil, err
}
return sql.Open(driver, dsn)
default:
return nil, fmt.Errorf("unsupported driver %s", driver)
}
}
// normalizeMySQLDSN parses the dsn used with the mysql driver to always have
// the parameter `parseTime` set to true. This allows internal goose logic
// to assume that DATETIME/DATE/TIMESTAMP can be scanned into the time.Time
// type.
func normalizeMySQLDSN(dsn string) (string, error) {
config, err := mysql.ParseDSN(dsn)
if err != nil {
return "", err
}
config.ParseTime = true
return config.FormatDSN(), nil
}

View File

@ -1,54 +0,0 @@
package goose
import (
"testing"
)
func TestNormalizeMySQLDSN(t *testing.T) {
t.Parallel()
testCases := []struct {
desc string
in string
out string
expectedErr string
}{
{
desc: "errors if dsn is invalid",
in: "root:password@tcp(mysql:3306)", // forgot the database name
expectedErr: "invalid DSN: missing the slash separating the database name",
},
{
desc: "works when there are no query parameters supplied with the dsn",
in: "root:password@tcp(mysql:3306)/db",
out: "root:password@tcp(mysql:3306)/db?parseTime=true",
},
{
desc: "works when parseTime is already set to true supplied with the dsn",
in: "root:password@tcp(mysql:3306)/db?parseTime=true",
out: "root:password@tcp(mysql:3306)/db?parseTime=true",
},
{
desc: "persists other parameters if they are present",
in: "root:password@tcp(mysql:3306)/db?allowCleartextPasswords=true&interpolateParams=true",
out: "root:password@tcp(mysql:3306)/db?allowCleartextPasswords=true&interpolateParams=true&parseTime=true",
},
}
for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
out, err := normalizeMySQLDSN(tc.in)
if tc.expectedErr != "" {
if err == nil {
t.Errorf("expected an error, but did not have one, had (%#v, %#v)", out, err)
} else if err.Error() != tc.expectedErr {
t.Errorf("expected error %s but had %s", tc.expectedErr, err.Error())
}
} else if err != nil {
t.Errorf("had unexpected error %s", err.Error())
} else if out != tc.out {
t.Errorf("had output mismatch, wanted %s but had %s", tc.out, out)
}
})
}
}

View File

@ -1,3 +1,5 @@
// This is custom goose binary with sqlite3 support only.
package main
import (
@ -7,11 +9,7 @@ import (
"github.com/pressly/goose"
// Init DB drivers.
_ "github.com/go-sql-driver/mysql"
_ "github.com/lib/pq"
_ "github.com/mattn/go-sqlite3"
_ "github.com/ziutek/mymysql/godrv"
)
var (
@ -20,49 +18,19 @@ var (
)
func main() {
flags.Usage = usage
flags.Parse(os.Args[1:])
args := flags.Args()
if len(args) == 0 || args[0] == "-h" || args[0] == "--help" {
if len(args) < 2 {
flags.Usage()
return
}
switch args[0] {
case "create":
if err := goose.Run("create", nil, *dir, args[1:]...); err != nil {
log.Fatalf("goose run: %v", err)
}
return
case "fix":
if err := goose.Run("fix", nil, *dir); err != nil {
log.Fatalf("goose run: %v", err)
}
return
}
dbstring, command := args[1], args[2]
if len(args) < 3 {
flags.Usage()
return
}
if args[0] == "-h" || args[0] == "--help" {
flags.Usage()
return
}
driver, dbstring, command := args[0], args[1], args[2]
switch dbstring {
case "":
log.Fatalf("-dbstring=%q not supported\n", dbstring)
default:
}
db, err := goose.OpenDBWithDriver(driver, dbstring)
db, err := goose.OpenDBWithDriver("sqlite3", dbstring)
if err != nil {
log.Fatalf("goose run: %v\n", err)
log.Fatalf("goose: failed to open DB: %v\n", err)
}
arguments := []string{}
@ -71,49 +39,6 @@ func main() {
}
if err := goose.Run(command, db, *dir, arguments...); err != nil {
log.Fatalf("goose run: %v", err)
log.Fatalf("goose %v: %v", command, err)
}
}
func usage() {
log.Print(usagePrefix)
flags.PrintDefaults()
log.Print(usageCommands)
}
var (
usagePrefix = `Usage: goose [OPTIONS] DRIVER DBSTRING COMMAND
Drivers:
postgres
mysql
sqlite3
redshift
Examples:
goose sqlite3 ./foo.db status
goose sqlite3 ./foo.db create init sql
goose sqlite3 ./foo.db create add_some_column sql
goose sqlite3 ./foo.db create fetch_user_data go
goose sqlite3 ./foo.db up
goose postgres "user=postgres dbname=postgres sslmode=disable" status
goose mysql "user:password@/dbname?parseTime=true" status
goose redshift "postgres://user:password@qwerty.us-east-1.redshift.amazonaws.com:5439/db" status
Options:
`
usageCommands = `
Commands:
up Migrate the DB to the most recent version available
up-to VERSION Migrate the DB to a specific VERSION
down Roll back the version by 1
down-to VERSION Roll back to a specific VERSION
redo Re-run the latest migration
status Dump the migration status for the current DB
version Print the current version of the database
create NAME [sql|go] Creates new migration file with the current timestamp
fix Apply sequential ordering to migrations
`
)

View File

@ -47,20 +47,20 @@ func TestLiteBinary(t *testing.T) {
t.Fatal(err)
}
defer os.RemoveAll(dir) // clean up
defer os.Remove("./bin/light-goose") // clean up
defer os.RemoveAll(dir) // clean up
defer os.Remove("./bin/lite-goose") // clean up
// this has to be done outside of the loop
// since go only supports space separated tags list.
cmd := exec.Command("go", "build", "-tags='no_mysql no_sqlite no_psql'", "-o", "./bin/light-goose", "./cmd/goose")
cmd := exec.Command("go", "build", "-tags='no_postgres no_mysql no_sqlite3'", "-o", "./bin/lite-goose", "./cmd/goose")
out, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("%s:\n%v\n\n%s", err, cmd, out)
}
commands := []string{
fmt.Sprintf("./bin/light-goose -dir=%s create user_indices sql", dir),
fmt.Sprintf("./bin/light-goose -dir=%s fix", dir),
fmt.Sprintf("./bin/lite-goose -dir=%s create user_indices sql", dir),
fmt.Sprintf("./bin/lite-goose -dir=%s fix", dir),
}
for _, cmd := range commands {