Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] [breaking] fogg setup #204

Merged
merged 19 commits into from
Jan 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,4 @@ clean: ## clean the repo
rm -rf dist
packr clean

.PHONY: build clean coverage test install lint lint-slow packr release help
.PHONY: build clean coverage test install lint lint-slow packr release help setup
62 changes: 22 additions & 40 deletions apply/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"github.com/chanzuckerberg/fogg/config"
"github.com/chanzuckerberg/fogg/errs"
"github.com/chanzuckerberg/fogg/plan"
"github.com/chanzuckerberg/fogg/plugins"
"github.com/chanzuckerberg/fogg/templates"
"github.com/chanzuckerberg/fogg/util"
"github.com/gobuffalo/packr"
Expand All @@ -28,7 +27,7 @@ import (
const rootPath = "terraform"

// Apply will run a plan and apply all the changes to the current repo.
func Apply(fs afero.Fs, conf *config.Config, tmp *templates.T, upgrade bool, noPlugins bool) error {
func Apply(fs afero.Fs, conf *config.Config, tmp *templates.T, upgrade bool) error {
if !upgrade {
toolVersion, err := util.VersionString()
if err != nil {
Expand All @@ -39,7 +38,7 @@ func Apply(fs afero.Fs, conf *config.Config, tmp *templates.T, upgrade bool, noP
return errs.NewUserf("fogg version (%s) is different than version currently used to manage repo (%s). To upgrade add --upgrade.", toolVersion, repoVersion)
}
}
p, err := plan.Eval(conf, false, noPlugins)
p, err := plan.Eval(conf, false)
if err != nil {
return errs.WrapUser(err, "unable to evaluate plan")
}
Expand All @@ -56,11 +55,6 @@ func Apply(fs afero.Fs, conf *config.Config, tmp *templates.T, upgrade bool, noP
}
}

e = applyPlugins(fs, p)
if e != nil {
return errs.WrapUser(e, "unable to apply plugins")
}

e = applyAccounts(fs, p, &tmp.Account)
if e != nil {
return errs.WrapUser(e, "unable to apply accounts")
Expand Down Expand Up @@ -116,29 +110,6 @@ func applyRepo(fs afero.Fs, p *plan.Plan, repoTemplates *packr.Box) error {
return applyTree(fs, repoTemplates, "", p)
}

func applyPlugins(fs afero.Fs, p *plan.Plan) error {
log.Debug("applying plugins")
apply := func(name string, plugin *plugins.CustomPlugin) error {
log.Infof("Applying plugin %s", name)
return errs.WrapUserf(plugin.Install(fs, name), "Error applying plugin %s", name)
}

for pluginName, plugin := range p.Plugins.CustomPlugins {
err := apply(pluginName, plugin)
if err != nil {
return err
}
}

for providerName, provider := range p.Plugins.TerraformProviders {
err := apply(providerName, provider)
if err != nil {
return err
}
}
return nil
}

func applyGlobal(fs afero.Fs, p plan.Component, repoBox *packr.Box) error {
log.Debug("applying global")
path := fmt.Sprintf("%s/global", rootPath)
Expand Down Expand Up @@ -250,17 +221,12 @@ func applyTree(dest afero.Fs, source *packr.Box, targetBasePath string, subst in
return errs.WrapUserf(err, "could not read source file %#v", sourceFile)
}

baseFs, ok := dest.(*afero.BasePathFs)
if !ok {
return errs.NewInternal("unable to type assert fs to basefs")
}
linkTarget := string(linkTargetBytes)

fullLinkTarget, err := baseFs.RealPath(linkTarget)
err = linkFile(target, linkTarget)
if err != nil {
return errs.WrapInternal(err, "unable to find real path for link target")
return errs.WrapInternal(err, "can't symlink file")
}
err = linkFile(target, fullLinkTarget)
} else {
e = afero.WriteReader(dest, target, sourceFile)
if e != nil {
Expand Down Expand Up @@ -437,7 +403,10 @@ func calculateModuleAddressForSource(path, moduleAddress string) (string, error)
if e != nil || u.Scheme == "file" {
// This indicates that we have a local path to the module.
// It is possible that this test is unreliable.
moduleAddressForSource, _ = filepath.Rel(path, moduleAddress)
moduleAddressForSource, e = filepath.Rel(path, moduleAddress)
if e != nil {
return "", e
}
} else {
moduleAddressForSource = moduleAddress
}
Expand All @@ -455,6 +424,19 @@ func getTargetPath(basePath, path string) string {
}

func linkFile(name, target string) error {
log.Debugf("removing link at %s", name)
os.Remove(name)
log.Debugf("linking %s to %s", name, target)
return os.Symlink(target, name)
relativePath, err := filepathRel(name, target)
log.Debugf("relative link %s err %#v", relativePath, err)
if err != nil {
return err
}
return os.Symlink(relativePath, name)
}

func filepathRel(path, name string) (string, error) {
dirs := strings.Count(path, "/")
fullPath := fmt.Sprintf("%s/%s", strings.Repeat("../", dirs), name)
return filepath.Clean(fullPath), nil
}
30 changes: 29 additions & 1 deletion apply/apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ func TestCreateFileNonExistentDirectory(t *testing.T) {
}

func TestApplySmokeTest(t *testing.T) {
t.Skip("doesn't currently work because afero doesn't support symlinks")
// We have to use a BasePathFs so that we can calculate `RealPath` for symlinking. Afero doesn't support symlinks
fs := afero.NewBasePathFs(afero.NewMemMapFs(), "/")
json := `
Expand Down Expand Up @@ -233,7 +234,7 @@ func TestApplySmokeTest(t *testing.T) {
c, e := config.ReadConfig(ioutil.NopCloser(strings.NewReader(json)))
assert.NoError(t, e)

e = Apply(fs, c, templates.Templates, false, false)
e = Apply(fs, c, templates.Templates, false)
assert.NoError(t, e)
}

Expand Down Expand Up @@ -411,3 +412,30 @@ func writeFile(fs afero.Fs, path string, contents string) error {
_, e = f.WriteString(contents)
return e
}

func Test_filepathRel(t *testing.T) {
type args struct {
name string
path string
}
tests := []struct {
name string
args args
want string
wantErr bool
}{
{"terraform.d", args{"terraform/accounts/idseq/terraform.d", "terraform.d"}, "../../../terraform.d", false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := filepathRel(tt.args.name, tt.args.path)
if (err != nil) != tt.wantErr {
t.Errorf("filepathRel() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("filepathRel() = %v, want %v", got, tt.want)
}
})
}
}
17 changes: 3 additions & 14 deletions cmd/apply.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
package cmd

import (
"os"

"github.com/chanzuckerberg/fogg/apply"
"github.com/chanzuckerberg/fogg/templates"
"github.com/spf13/afero"
"github.com/spf13/cobra"
)

func init() {
applyCmd.Flags().StringP("config", "c", "fogg.json", "Use this to override the fogg config file.")
applyCmd.Flags().BoolP("verbose", "v", false, "use this to turn on verbose output")
applyCmd.Flags().BoolP("upgrade", "u", false, "use this when running a new version of fogg")
applyCmd.Flags().Bool("no-plugins", false, "do not apply fogg plugins; this may result in unexpected behavior.")
rootCmd.AddCommand(applyCmd)
}

Expand All @@ -26,12 +22,10 @@ var applyCmd = &cobra.Command{
setupDebug(debug)

var e error
// Set up fs
pwd, e := os.Getwd()
fs, e := openFs()
if e != nil {
return e
}
fs := afero.NewBasePathFs(afero.NewOsFs(), pwd)

// handle flags
verbose, e := cmd.Flags().GetBool("verbose")
Expand All @@ -48,13 +42,8 @@ var applyCmd = &cobra.Command{
return e
}

noPlugins, e := cmd.Flags().GetBool("no-plugins")
if e != nil {
return e
}

// check that we are at root of initialized git repo
openGitOrExit(pwd)
openGitOrExit(fs)

config, err := readAndValidateConfig(fs, configFile, verbose)

Expand All @@ -64,7 +53,7 @@ var applyCmd = &cobra.Command{
}

// apply
e = apply.Apply(fs, config, templates.Templates, upgrade, noPlugins)
e = apply.Apply(fs, config, templates.Templates, upgrade)

return e
},
Expand Down
2 changes: 1 addition & 1 deletion cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var initCmd = &cobra.Command{
fs := afero.NewBasePathFs(afero.NewOsFs(), pwd)

// check that we are at root of initialized git repo
openGitOrExit(pwd)
openGitOrExit(fs)

return fogg_init.Init(fs)
},
Expand Down
10 changes: 2 additions & 8 deletions cmd/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
func init() {
planCmd.Flags().StringP("config", "c", "fogg.json", "Use this to override the fogg config file.")
planCmd.Flags().BoolP("verbose", "v", false, "use this to turn on verbose output")
planCmd.Flags().Bool("no-plugins", false, "do not apply fogg plugins; this may result in unexpected behavior.")
rootCmd.AddCommand(planCmd)
}

Expand Down Expand Up @@ -43,13 +42,8 @@ var planCmd = &cobra.Command{
return errs.WrapInternal(e, "couldn't parse config flag")
}

noPlugins, e := cmd.Flags().GetBool("no-plugins")
if e != nil {
return e
}

// check that we are at root of initialized git repo
openGitOrExit(pwd)
openGitOrExit(fs)

config, err := readAndValidateConfig(fs, configFile, verbose)

Expand All @@ -58,7 +52,7 @@ var planCmd = &cobra.Command{
return e
}

p, e := plan.Eval(config, verbose, noPlugins)
p, e := plan.Eval(config, verbose)
if e != nil {
return e
}
Expand Down
32 changes: 32 additions & 0 deletions cmd/setup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package cmd

import (
"github.com/chanzuckerberg/fogg/setup"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

func init() {
setupCmd.Flags().StringP("config", "c", "fogg.json", "Use this to override the fogg config file.")
setupCmd.Flags().BoolP("verbose", "v", false, "use this to turn on verbose output")

rootCmd.AddCommand(setupCmd)
}

var setupCmd = &cobra.Command{
Use: "setup",
Short: "Setup dependencies for curent working directory",
SilenceErrors: true,
RunE: func(cmd *cobra.Command, args []string) error {
fs, config, err := bootstrapCmd(cmd, debug)

if err != nil {
return err
}

// check that we are at root of initialized git repo
openGitOrExit(fs)
log.Debug("setup")
return setup.Setup(fs, config)
},
}
43 changes: 40 additions & 3 deletions cmd/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ import (
"github.com/chanzuckerberg/fogg/errs"
log "github.com/sirupsen/logrus"
"github.com/spf13/afero"
"github.com/spf13/cobra"
validator "gopkg.in/go-playground/validator.v9"
)

func openGitOrExit(pwd string) {
log.Debugf("opening git at %s", pwd)
_, err := os.Stat(".git")
func openGitOrExit(fs afero.Fs) {
_, err := fs.Stat(".git")
if err != nil {
// assuming this means no repository
log.Fatal("fogg must be run from the root of a git repo")
Expand Down Expand Up @@ -68,3 +68,40 @@ func setupDebug(debug bool) {
}
log.SetLevel(logLevel)
}

func openFs() (afero.Fs, error) {
pwd, e := os.Getwd()
if e != nil {
return nil, e
}
fs := afero.NewBasePathFs(afero.NewOsFs(), pwd)
return fs, nil
}

func bootstrapCmd(cmd *cobra.Command, debug bool) (afero.Fs, *config.Config, error) {
setupDebug(debug)

fs, err := openFs()
if err != nil {
return nil, nil, err
}

verbose, err := cmd.Flags().GetBool("verbose")
if err != nil {
return nil, nil, err
}

configFile, err := cmd.Flags().GetString("config")
if err != nil {
return nil, nil, err
}

config, err := readAndValidateConfig(fs, configFile, verbose)

err = mergeConfigValidationErrors(err)
if err != nil {
return nil, nil, err
}

return fs, config, nil
}
2 changes: 0 additions & 2 deletions errs/errs.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"

"github.com/go-errors/errors"
log "github.com/sirupsen/logrus"
)

type User struct {
Expand Down Expand Up @@ -49,7 +48,6 @@ func WrapUser(e error, msg string) error {
}

func WrapUserf(e error, msg string, a ...interface{}) error {
log.Debugf("wrapuser e: %#v", e)
if e == nil {
return nil
}
Expand Down
Loading