Skip to content

Commit

Permalink
docs(help): Add help command and flesh out README.md (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
robinjoseph08 authored Aug 13, 2018
1 parent 87246cb commit 4872a7f
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 4 deletions.
18 changes: 18 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Copyright 2018 Robin Joseph

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
93 changes: 91 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,100 @@
# go-pg-migrations

[![GoDoc](https://godoc.org/github.com/robinjoseph08/go-pg-migrations?status.svg)](http://godoc.org/github.com/robinjoseph08/go-pg-migrations)
[![Build Status](https://travis-ci.org/robinjoseph08/go-pg-migrations.svg?branch=master)](https://travis-ci.org/robinjoseph08/go-pg-migrations)
[![Go Report Card](https://goreportcard.com/badge/github.com/robinjoseph08/go-pg-migrations)](https://goreportcard.com/report/github.com/robinjoseph08/go-pg-migrations)

A Go package to help write migrations with [`go-pg/pg`](https://github.com/go-pg/pg).

>**This repo is currently still a work in progress and isn't meant to be used just
>yet.**
## Usage

### Installation

```sh
$ go get github.com/robinjoseph08/go-pg-migrations
```

### Running

To see how this package is intended to be used, you can look at the [example
directory](/example). All you need to do is have a `main` package (e.g.
`example`); call `migrations.Run` with the directory you want the migration
files to be saved in (which will be the same directory of the main package, e.g.
`example`), an instance of `*pg.DB`, and `os.Args`; and log any potential errors
that could be returned.

Once this has been set up, then you can use the `create`, `migrate`, `rollback`,
`help` commands like so:

```
$ go run example/*.go create create_users_table
Creating example/20180812001528_create_users_table.go...
$ go run example/*.go migrate
Running batch 1 with 1 migration(s)...
Finished running "20180812001528_create_users_table"
$ go run example/*.go rollback
Rolling back batch 1 with 1 migration(s)...
Finished rolling back "20180812001528_create_users_table"
$ go run example/*.go help
Usage:
go run example/*.go [command]
Commands:
create - create a new migration in example with the provided name
migrate - run any migrations that haven't been run yet
rollback - roll back the previous run batch of migrations
help - print this help text
Examples:
go run example/*.go create create_users_table
go run example/*.go migrate
go run example/*.go rollback
go run example/*.go help
```

While this works when you have the Go toolchain installed, there might be a
scenario where you have to run migrations and you don't have the toolchain
available (e.g. in a `scratch` or `alpine` Docker image deployed to production).
In that case, you should compile another binary (in addition to your actual
application) and copy it into the final image. This will include all of your
migrations and allow you to run it by overriding the command when running the
Docker container.

This would look something like this:

```dockerfile
# Dockerfile
FROM golang:1.10.3 as build

RUN curl -fsSL -o /usr/local/bin/dep https://github.com/golang/dep/releases/download/v0.4.1/dep-linux-amd64
RUN chmod +x /usr/local/bin/dep

WORKDIR /go/src/github.com/sample/service

COPY Gopkg.toml Gopkg.toml
COPY Gopkg.lock Gopkg.lock
RUN dep ensure -vendor-only

COPY . .

RUN CGO_ENABLED=0 GOOS=linux go build -installsuffix cgo -ldflags '-w -s' -o ./bin/serve ./cmd/serve
RUN CGO_ENABLED=0 GOOS=linux go build -installsuffix cgo -ldflags '-w -s' -o ./bin/migrations ./cmd/migrations

FROM alpine:3.7

RUN apk --no-cache add ca-certificates
COPY --from=build /go/src/github.com/sample/service/bin /bin

CMD ["serve"]
```

```sh
$ docker build -t service:latest .
$ docker run --rm service:latest migrations migrate
```

## Why?

Expand Down
2 changes: 2 additions & 0 deletions create.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,7 @@ func create(directory, name string) error {
fullname := fmt.Sprintf("%s_%s", version, name)
filename := path.Join(directory, fmt.Sprintf("%s.go", fullname))

fmt.Printf("Creating %s...\n", filename)

return ioutil.WriteFile(filename, []byte(fmt.Sprintf(template, fullname)), 0644)
}
29 changes: 29 additions & 0 deletions example/20180812001528_create_users_table.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package main

import (
"github.com/go-pg/pg/orm"
"github.com/robinjoseph08/go-pg-migrations"
)

func init() {
up := func(db orm.DB) error {
_, err := db.Exec(`
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username TEXT NOT NULL UNIQUE,
date_created TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
date_modified TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
)
`)
return err
}

down := func(db orm.DB) error {
_, err := db.Exec("DROP TABLE users")
return err
}

opts := migrations.MigrationOptions{}

migrations.Register("20180812001528_create_users_table", up, down, opts)
}
24 changes: 24 additions & 0 deletions example/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package main

import (
"log"
"os"

"github.com/go-pg/pg"
"github.com/robinjoseph08/go-pg-migrations"
)

const directory = "example"

func main() {
db := pg.Connect(&pg.Options{
Addr: "localhost:5432",
User: "test_user",
Database: "test",
})

err := migrations.Run(db, directory, os.Args)
if err != nil {
log.Fatalln(err)
}
}
23 changes: 23 additions & 0 deletions help.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package migrations

import "fmt"

const helpText = `Usage:
go run %s/*.go [command]
Commands:
create - create a new migration in %s with the provided name
migrate - run any migrations that haven't been run yet
rollback - roll back the previous run batch of migrations
help - print this help text
Examples:
go run %s/*.go create create_users_table
go run %s/*.go migrate
go run %s/*.go rollback
go run %s/*.go help
`

func help(directory string) {
fmt.Printf(helpText, directory, directory, directory, directory, directory, directory)
}
5 changes: 5 additions & 0 deletions migrate.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package migrations

import (
"fmt"
"sort"
"time"

Expand Down Expand Up @@ -40,6 +41,7 @@ func migrate(db *pg.DB, directory string) error {

// if there are no migrations that need to be run, exit early
if len(uncompleted) == 0 {
fmt.Println("Migrations already up to date")
return nil
}

Expand All @@ -57,6 +59,8 @@ func migrate(db *pg.DB, directory string) error {
}
batch = batch + 1

fmt.Printf("Running batch %d with %d migration(s)...\n", batch, len(uncompleted))

for _, m := range uncompleted {
m.Batch = batch
var err error
Expand All @@ -76,6 +80,7 @@ func migrate(db *pg.DB, directory string) error {
if err != nil {
return err
}
fmt.Printf("Finished running %q\n", m.Name)
}

return nil
Expand Down
3 changes: 1 addition & 2 deletions migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package migrations

import (
"errors"
"fmt"
"time"

"github.com/go-pg/pg"
Expand Down Expand Up @@ -69,7 +68,7 @@ func Run(db *pg.DB, directory string, args []string) error {
case "rollback":
return rollback(db, directory)
default:
fmt.Println("help")
help(directory)
return nil
}
}
5 changes: 5 additions & 0 deletions rollback.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package migrations

import (
"fmt"
"sort"

"github.com/go-pg/pg"
Expand Down Expand Up @@ -32,12 +33,15 @@ func rollback(db *pg.DB, directory string) error {
}
// if no migrations have been run yet, exit early
if batch == 0 {
fmt.Println("No migrations have been run yet")
return nil
}

rollback := getMigrationsForBatch(completed, batch)
rollback = filterMigrations(migrations, rollback, true)

fmt.Printf("Rolling back batch %d with %d migration(s)...\n", batch, len(rollback))

for _, m := range rollback {
var err error
if m.DisableTransaction {
Expand All @@ -55,6 +59,7 @@ func rollback(db *pg.DB, directory string) error {
if err != nil {
return err
}
fmt.Printf("Finished rolling back %q\n", m.Name)
}

return nil
Expand Down

0 comments on commit 4872a7f

Please sign in to comment.