Skip to content

Commit

Permalink
Implements and tests a SDK roll forward strategy that mimics Microsof…
Browse files Browse the repository at this point in the history
…t's roll forward policy

[#167848284]
  • Loading branch information
ForestEckhardt committed Aug 30, 2019
1 parent d2bfc96 commit 6be1176
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 48 deletions.
3 changes: 1 addition & 2 deletions src/dotnetcore/integration/deploy_dotnetcore_app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,7 @@ var _ = Describe("CF Dotnet Buildpack", func() {

})

XContext("when the sdk is missing", func() {
//TODO: https://www.pivotaltracker.com/story/show/167848284
Context("when the sdk is missing", func() {
BeforeEach(func() {
app = ReplaceFileTemplate(filepath.Join(bpDir, "fixtures", "source_2.1_global_json_templated"), "global.json", "sdk_version", "2.1.500")
})
Expand Down
32 changes: 0 additions & 32 deletions src/dotnetcore/supply/mocks_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 31 additions & 6 deletions src/dotnetcore/supply/supply.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"log"
"os"
"path/filepath"
"strconv"
"strings"

"github.com/cloudfoundry/dotnet-core-buildpack/src/dotnetcore/config"
Expand Down Expand Up @@ -292,13 +293,37 @@ func (s *Supplier) commandsInProjFiles(commands []string) (bool, error) {
// Turn a semver string into major.minor.x
// Will turn a.b.c into a.b.x
// Will not modify strings that don't match a.b.c
func majorMinorOnly(version string) string {
func sdkRollForward(version string, versions []string) (string, error) {
var featureLine string
var highestPatch string
parts := strings.SplitN(version, ".", 3)
if len(parts) == 3 {
parts[2] = "x" // ignore patch version
return strings.Join(parts, ".")
featureLine = parts[2][:1]
}
return version

for _, v := range versions {
versionSplit := strings.SplitN(v, ".", 3)
if len(versionSplit) == 3 && versionSplit[2][:1] == featureLine {
if highestPatch == "" {
highestPatch = versionSplit[2][1:]
} else {
current, err := strconv.Atoi(highestPatch)
comp, err := strconv.Atoi(versionSplit[2][1:])
if err != nil {
return "", err
}
if current < comp {
highestPatch = versionSplit[2][1:]
}
}
}
}

if highestPatch == "" {
return "", fmt.Errorf("could not find sdk in same feature line")
}

return fmt.Sprintf("%s.%s.%s%s", parts[0], parts[1], featureLine, highestPatch), nil
}

func (s *Supplier) pickVersionToInstall() (string, error) {
Expand Down Expand Up @@ -327,7 +352,7 @@ func (s *Supplier) pickVersionToInstall() (string, error) {
return globalJSONVersion, nil
}
s.Log.Warning("SDK %s in global.json is not available", globalJSONVersion)
installVersion, err := project.FindMatchingVersionWithPreview(majorMinorOnly(globalJSONVersion), allVersions)
installVersion, err := sdkRollForward(globalJSONVersion, allVersions)
if err == nil {
s.Log.Info("falling back to latest version in version line")
return installVersion, nil
Expand Down Expand Up @@ -408,7 +433,7 @@ func (s *Supplier) suppliedVersion(allVersions []string) (string, error) {
}
s.Log.Warning("SDK %s in global.json is not available", globalJSONVersion)
// TODO: Reevaluate this logic in light of patch lines? https://docs.microsoft.com/en-us/dotnet/core/versions/
installVersion, err := project.FindMatchingVersionWithPreview(majorMinorOnly(globalJSONVersion), allVersions)
installVersion, err := sdkRollForward(globalJSONVersion, allVersions)
if err != nil {
return "", nil
}
Expand Down
16 changes: 8 additions & 8 deletions src/dotnetcore/supply/supply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,12 +336,12 @@ var _ = Describe("Supply", func() {

Context("that is missing, but matches existing version lines", func() {
BeforeEach(func() {
Expect(ioutil.WriteFile(filepath.Join(buildDir, "global.json"), []byte(`{"sdk": {"version": "1.2.3"}}`), 0644)).To(Succeed())
mockManifest.EXPECT().AllDependencyVersions("dotnet-sdk").Return([]string{"1.1.1", "1.2.5", "1.2.6", "1.3.7"})
Expect(ioutil.WriteFile(filepath.Join(buildDir, "global.json"), []byte(`{"sdk": {"version": "1.2.301"}}`), 0644)).To(Succeed())
mockManifest.EXPECT().AllDependencyVersions("dotnet-sdk").Return([]string{"1.1.113", "1.2.303", "1.2.608", "1.3.709"})
})

It("installs the latest of the same version line", func() {
dep := libbuildpack.Dependency{Name: "dotnet-sdk", Version: "1.2.6"}
It("installs the latest of the same feature line", func() {
dep := libbuildpack.Dependency{Name: "dotnet-sdk", Version: "1.2.303"}
mockInstaller.EXPECT().InstallDependency(dep, filepath.Join(depsDir, depsIdx, "dotnet-sdk"))

Expect(supplier.InstallDotnetSdk()).To(Succeed())
Expand Down Expand Up @@ -423,12 +423,12 @@ var _ = Describe("Supply", func() {

Context("that is missing, but matches existing version lines", func() {
BeforeEach(func() {
Expect(ioutil.WriteFile(filepath.Join(buildDir, "global.json"), []byte(`{"sdk": {"version": "1.2.3"}}`), 0644)).To(Succeed())
mockManifest.EXPECT().AllDependencyVersions("dotnet-sdk").Return([]string{"1.1.1", "1.2.5", "1.2.6", "1.3.7"})
Expect(ioutil.WriteFile(filepath.Join(buildDir, "global.json"), []byte(`{"sdk": {"version": "1.2.301"}}`), 0644)).To(Succeed())
mockManifest.EXPECT().AllDependencyVersions("dotnet-sdk").Return([]string{"1.1.113", "1.2.303", "1.2.608", "1.3.709"})
})

It("installs the latest of the same version line", func() {
dep := libbuildpack.Dependency{Name: "dotnet-sdk", Version: "1.2.6"}
It("installs the latest of the same feature line", func() {
dep := libbuildpack.Dependency{Name: "dotnet-sdk", Version: "1.2.303"}
mockInstaller.EXPECT().InstallDependency(dep, filepath.Join(depsDir, depsIdx, "dotnet-sdk"))

Expect(supplier.InstallDotnetSdk()).To(Succeed())
Expand Down

0 comments on commit 6be1176

Please sign in to comment.