Skip to content

Commit

Permalink
Merge pull request #16 from emicklei/plan
Browse files Browse the repository at this point in the history
add "plan" command
  • Loading branch information
emicklei authored Sep 28, 2018
2 parents 81b83dd + 35c090d commit db5c2cc
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 17 deletions.
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelist of gmig releases

## v1.7.0, 2018-09-28

- add "plan" command that logs all commands that would be executed on "up".

## v1.6.0

- add options to new to set the commands for the do,undo,view section directly
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ and use the `view` subcommand.
up Runs the do section of all pending migrations in order, one after the other.
If a migration file is specified then stop after applying that one.
down Runs the undo section of the last applied migration only.
plan Log commands of the do section of all pending migrations in order, one after the other.
status List all migrations with details compared to the current state.
view Runs the view section of all applied migrations to see the current state reported by your infrastructure.
force state | do | undo
Expand Down Expand Up @@ -133,6 +134,11 @@ List all migrations with an indicator (applied,pending) whether is has been appl

Run this command in the directory where all migrations are stored. Use `--migrations` for a different location.

### plan [path] [|migration file] [--migrations folder]

Log commands of the `do` section of all pending migrations in order, one after the other.
If `migration file` is given then stop after applying that one.

### up [path] [|migration file] [--migrations folder]

Executes the `do` section of each pending migration compared to the last applied change to the infrastructure.
Expand Down
60 changes: 43 additions & 17 deletions commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const (
pending = "... pending ..."
execDo = "... do ..."
execUndo = "... undo ..."
execPlan = "... plan ..."
stopped = "... stopped ..."
)

Expand Down Expand Up @@ -60,6 +61,14 @@ func cmdCreateMigration(c *cli.Context) error {
}

func cmdMigrationsUp(c *cli.Context) error {
return runMigrations(c, !true)
}

func cmdMigrationsPlan(c *cli.Context) error {
return runMigrations(c, true)
}

func runMigrations(c *cli.Context, isLogOnly bool) error {
mtx, err := getMigrationContext(c)
if err != nil {
printError(err.Error())
Expand All @@ -84,26 +93,38 @@ func cmdMigrationsUp(c *cli.Context) error {
reportError(mtx.stateProvider.Config(), "up until stop", errors.New("No such migration file: "+stopAfter))
return errAbort
}
prettyWidth := largestWithOf(all)
for _, each := range all {
log.Println(statusSeparator)
log.Println(execDo, pretty(each.Filename))
if err := ExecuteAll(each.DoSection, mtx.config().shellEnv(), c.GlobalBool("v")); err != nil {
reportError(mtx.stateProvider.Config(), "do", err)
return errAbort
leadingTitle := execDo
if isLogOnly {
leadingTitle = execPlan
}
mtx.lastApplied = each.Filename
// save after each succesful migration
if err := mtx.stateProvider.SaveState(mtx.lastApplied); err != nil {
reportError(mtx.stateProvider.Config(), "save state", err)
return errAbort
log.Printf("%s %-"+strconv.Itoa(prettyWidth)+"s (%s)\n", leadingTitle, pretty(each.Filename), each.Filename)
if isLogOnly {
log.Println("")
if LogAll(each.DoSection, mtx.config().shellEnv(), true); err != nil {
reportError(mtx.stateProvider.Config(), "plan do", err)
return errAbort
}
} else {
if err := ExecuteAll(each.DoSection, mtx.config().shellEnv(), c.GlobalBool("v")); err != nil {
reportError(mtx.stateProvider.Config(), "do", err)
return errAbort
}
mtx.lastApplied = each.Filename
// save after each succesful migration
if err := mtx.stateProvider.SaveState(mtx.lastApplied); err != nil {
reportError(mtx.stateProvider.Config(), "save state", err)
return errAbort
}
}
// if not empty then stop after applying this migration
if stopAfter == each.Filename {
log.Println(stopped)
log.Println(statusSeparator)
break
}
log.Println(statusSeparator)
}
return nil
}
Expand Down Expand Up @@ -139,6 +160,17 @@ func cmdMigrationsDown(c *cli.Context) error {
return nil
}

func largestWithOf(list []Migration) int {
prettyWidth := 0
for _, each := range list {
pf := pretty(each.Filename)
if len(pf) > prettyWidth {
prettyWidth = len(pf)
}
}
return prettyWidth
}

func cmdMigrationsStatus(c *cli.Context) error {
mtx, err := getMigrationContext(c)
if err != nil {
Expand All @@ -152,13 +184,7 @@ func cmdMigrationsStatus(c *cli.Context) error {
}
log.Println(statusSeparator)
var last string
prettyWidth := 0
for _, each := range all {
pf := pretty(each.Filename)
if len(pf) > prettyWidth {
prettyWidth = len(pf)
}
}
prettyWidth := largestWithOf(all)
for _, each := range all {
status := applied
if each.Filename > mtx.lastApplied {
Expand Down
12 changes: 12 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,18 @@ func newApp() *cli.App {
ArgsUsage: `[title]
title - what the effect of this migration is on infrastructure.`,
},
{
Name: "plan",
Usage: "Log commands of the do section of all pending migrations in order, one after the other. If a migration file is specified then stop after applying that one.",
Action: func(c *cli.Context) error {
defer started(c, "plan = log commands of pending migrations")()
return cmdMigrationsPlan(c)
},
Flags: []cli.Flag{migrationsFlag},
ArgsUsage: `[path] [stop]
path - name of the folder that contains the configuration of the target project.
stop - (optional) the name of the migration file after which applying migrations will stop.`,
},
{
Name: "up",
Usage: "Runs the do section of all pending migrations in order, one after the other. If a migration file is specified then stop after applying that one.",
Expand Down
32 changes: 32 additions & 0 deletions migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,38 @@ func ExecuteAll(commands []string, envs []string, verbose bool) error {
return nil
}

// LogAll logs expanded commands using the environment variables of both the config and the OS.
func LogAll(commands []string, envs []string, verbose bool) error {
allEnv := append(os.Environ(), envs...)
envMap := map[string]string{}
for _, each := range allEnv {
kv := strings.Split(each, "=")
envMap[kv[0]] = kv[1]
}
for _, each := range commands {
log.Println(expandVarsIn(envMap, each))
}
return nil
}

// expandVarsIn returns a command with all occurrences of environment variables replaced by known values.
func expandVarsIn(envs map[string]string, command string) string {
// assume no recurse expand
expanded := command
for k, v := range envs {
// if the value itself is a known variable then skip it
if strings.HasPrefix(v, "$") {
if _, ok := envs[v]; ok {
log.Printf("Warning, skipping non-expandable environment var %s=%v\n", k, v)
continue
}
}
varName := "$" + k
expanded = strings.Replace(expanded, varName, v, -1)
}
return expanded
}

func setupShellScript(verbose bool) string {
flag := "-v"
if verbose {
Expand Down

0 comments on commit db5c2cc

Please sign in to comment.