pulumi/cmd/history.go
diana-slaba bf300038d4
Initial stack history command (#2270)
* Initial stack history command

* Adding use of color pkg, adding background colors to color pkg, and removing extra stack output

* gofmt-ed colors file

* Fixing format and removing JSON output

* Fixing nits, changing output for environment, and adding some tests

* fixing failing history test
2019-01-14 18:19:24 -08:00

120 lines
3.8 KiB
Go

// Copyright 2018, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cmd
import (
"fmt"
"sort"
"strings"
"time"
"github.com/dustin/go-humanize"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/pulumi/pulumi/pkg/backend"
"github.com/pulumi/pulumi/pkg/backend/display"
"github.com/pulumi/pulumi/pkg/diag/colors"
"github.com/pulumi/pulumi/pkg/util/cmdutil"
)
func newHistoryCmd() *cobra.Command {
var stack string
var cmd = &cobra.Command{
Use: "history",
Aliases: []string{"hist"},
SuggestFor: []string{"updates"},
Short: "Update history for a stack",
Long: `Update history for a stack
This command lists data about previous updates for a stack.`,
Args: cmdutil.NoArgs,
Run: cmdutil.RunFunc(func(cmd *cobra.Command, args []string) error {
opts := display.Options{
Color: cmdutil.GetGlobalColorization(),
}
s, err := requireStack(stack, false /*offerNew */, opts, false /*setCurrent*/)
if err != nil {
return err
}
b := s.Backend()
updates, err := b.GetHistory(commandContext(), s.Ref())
if err != nil {
return errors.Wrap(err, "getting history")
}
displayUpdate(updates, opts)
return nil
}),
}
cmd.PersistentFlags().StringVarP(
&stack, "stack", "s", "",
"Choose a stack other than the currently selected one")
return cmd
}
func displayUpdate(updates []backend.UpdateInfo, opts display.Options) {
if len(updates) == 0 {
fmt.Println("Stack has never been updated")
return
}
printResourceChanges := func(background, text, sign, reset string, amount int) {
msg := opts.Color.Colorize(fmt.Sprintf("%s%s%s%v%s", background, text, sign, amount, reset))
fmt.Print(msg)
}
for _, update := range updates {
fmt.Printf("UpdateKind: %v\n", update.Kind)
if update.Result == "succeeded" {
fmt.Print(opts.Color.Colorize(fmt.Sprintf("%sStatus: %v%s\n", colors.Green, update.Result, colors.Reset)))
} else {
fmt.Print(opts.Color.Colorize(fmt.Sprintf("%sStatus: %v%s\n", colors.Red, update.Result, colors.Reset)))
}
fmt.Printf("Message: %v\n", update.Message)
printResourceChanges(colors.GreenBackground, colors.Black, "+", colors.Reset, update.ResourceChanges["create"])
printResourceChanges(colors.RedBackground, colors.Black, "-", colors.Reset, update.ResourceChanges["delete"])
printResourceChanges(colors.YellowBackground, colors.Black, "~", colors.Reset, update.ResourceChanges["update"])
printResourceChanges(colors.BlueBackground, colors.Black, " ", colors.Reset, update.ResourceChanges["same"])
timeStart := time.Unix(update.StartTime, 0)
timeCreated := humanize.Time(timeStart)
timeEnd := time.Unix(update.EndTime, 0)
duration := timeEnd.Sub(timeStart)
fmt.Printf("%sUpdated %s took %s\n", " ", timeCreated, duration)
isEmpty := func(s string) bool {
return len(strings.TrimSpace(s)) == 0
}
var keys []string
for k := range update.Environment {
keys = append(keys, k)
}
sort.Strings(keys)
indent := 4
for _, k := range keys {
if k == backend.GitHead && !isEmpty(update.Environment[k]) {
fmt.Print(opts.Color.Colorize(
fmt.Sprintf("%*s%s%s: %s%s\n", indent, "", colors.Yellow, k, update.Environment[k], colors.Reset)))
} else if !isEmpty(update.Environment[k]) {
fmt.Printf("%*s%s: %s\n", indent, "", k, update.Environment[k])
}
}
fmt.Println("")
}
}