Skip to content

Commit

Permalink
Fix Issue runatlantis#1217: Use semver constraints
Browse files Browse the repository at this point in the history
  • Loading branch information
scruplelesswizard committed Jan 15, 2021
1 parent 4c89f9c commit 36fccea
Showing 1 changed file with 48 additions and 14 deletions.
62 changes: 48 additions & 14 deletions server/events/project_command_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import (
"fmt"
"os"
"path/filepath"
"regexp"
"sort"
"strings"

semver "github.com/hashicorp/go-version"
"github.com/runatlantis/atlantis/server/events/yaml/valid"

"github.com/hashicorp/go-version"
Expand All @@ -15,6 +16,7 @@ import (
"github.com/runatlantis/atlantis/server/events/models"
"github.com/runatlantis/atlantis/server/events/vcs"
"github.com/runatlantis/atlantis/server/events/yaml"
lib "github.com/warrensbox/terraform-switcher/lib"
)

const (
Expand All @@ -32,6 +34,10 @@ const (
DefaultParallelPlanEnabled = false
)

const (
tfReleasesURL = "https://releases.hashicorp.com/terraform/"
)

//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_project_command_builder.go ProjectCommandBuilder

// ProjectCommandBuilder builds commands that run on individual projects.
Expand Down Expand Up @@ -471,6 +477,8 @@ func (p *DefaultProjectCommandBuilder) escapeArgs(args []string) []string {
return escaped
}

// TODO: [chaosaffe]Get correct version of TF

// Extracts required_version from Terraform configuration.
// Returns nil if unable to determine version from configuration.
func (p *DefaultProjectCommandBuilder) getTfVersion(ctx *CommandContext, absProjDir string) *version.Version {
Expand All @@ -483,26 +491,52 @@ func (p *DefaultProjectCommandBuilder) getTfVersion(ctx *CommandContext, absProj
return nil
}

if len(module.RequiredCore) != 1 {
ctx.Log.Info("cannot determine which version to use from terraform configuration, detected %d possibilities.", len(module.RequiredCore))
if len(module.RequiredCore) == 0 {
ctx.Log.Debug("no version constraints detected from terrafrom configuration.")
return nil
}
requiredVersionSetting := module.RequiredCore[0]

// We allow `= x.y.z`, `=x.y.z` or `x.y.z` where `x`, `y` and `z` are integers.
re := regexp.MustCompile(`^=?\s*([^\s]+)\s*$`)
matched := re.FindStringSubmatch(requiredVersionSetting)
if len(matched) == 0 {
ctx.Log.Debug("did not specify exact version in terraform configuration, found %q", requiredVersionSetting)
// build constraints
constraintStrings := strings.Join(module.RequiredCore, ",")

constraints, err := semver.NewConstraint(constraintStrings)
if err != nil {
ctx.Log.Err("trying to build constraints: %s", err)
return nil
}
ctx.Log.Debug("found required_version setting of %q", requiredVersionSetting)
version, err := version.NewVersion(matched[1])

// build versions
includePrerelease := true

versionStrings, err := lib.GetTFList(tfReleasesURL, includePrerelease)
if err != nil {
ctx.Log.Debug(err.Error())
ctx.Log.Err("trying to get list of terraform versions from %s", tfReleasesURL)
return nil
}

ctx.Log.Info("detected module requires version: %q", version.String())
return version
versions := make([]*semver.Version, len(versionStrings))
for i, versionString := range versionStrings {
version, err := semver.NewVersion(versionString)
if err != nil {
ctx.Log.Err("trying to build version list: %s", err)
return nil
}

versions[i] = version
}

// sortVersions
sort.Sort(sort.Reverse(semver.Collection(versions)))

for _, version := range versions {
if constraints.Check(version) {
ctx.Log.Info("detected module requires version: %q", version)
return version
}

}

ctx.Log.Info("no versions matched constraint: %s", constraints)
return nil

}

0 comments on commit 36fccea

Please sign in to comment.