diff --git a/internal/cache/cache.go b/internal/cache/cache.go index f3db59e..d459028 100644 --- a/internal/cache/cache.go +++ b/internal/cache/cache.go @@ -2,9 +2,12 @@ package cache import ( + log "github.com/sirupsen/logrus" "io/ioutil" "path" + "github.com/Masterminds/semver" + "github.com/Nightapes/go-semantic-release/internal/shared" "gopkg.in/yaml.v2" ) @@ -23,31 +26,68 @@ type ReleaseVersionEntry struct { } // Write version into .version -func Write(repository string, versionFileContent ReleaseVersion) error { +func Write(repository string, releaseVersion shared.ReleaseVersion) error { completePath := path.Join(path.Dir(repository), ".version") - data, err := yaml.Marshal(&versionFileContent) + toCache := &ReleaseVersion{ + Next: ReleaseVersionEntry{ + Commit: releaseVersion.Next.Commit, + Version: releaseVersion.Next.Version.String(), + }, + Last: ReleaseVersionEntry{ + Commit: releaseVersion.Last.Commit, + Version: releaseVersion.Last.Version.String(), + }, + Branch: releaseVersion.Branch, + Draft: releaseVersion.Draft, + } + + data, err := yaml.Marshal(toCache) if err != nil { return err } + log.Debugf("Save %s with hash %s to cache", releaseVersion.Next.Version.String(), releaseVersion.Next.Commit) return ioutil.WriteFile(completePath, data, 0644) } // Read version into .version -func Read(repository string) (*ReleaseVersion, error) { +func Read(repository string) (*shared.ReleaseVersion, error) { completePath := path.Join(path.Dir(repository), ".version") content, err := ioutil.ReadFile(completePath) if err != nil { - return &ReleaseVersion{}, err + return &shared.ReleaseVersion{}, err } - var versionFileContent ReleaseVersion - err = yaml.Unmarshal(content, &versionFileContent) + var parsedContent ReleaseVersion + err = yaml.Unmarshal(content, &parsedContent) if err != nil { - return &ReleaseVersion{}, err + return &shared.ReleaseVersion{}, err } - return &versionFileContent, nil + nextVersion, err := semver.NewVersion(parsedContent.Next.Version) + if err != nil { + return nil, err + } + + lastVersion, err := semver.NewVersion(parsedContent.Last.Version) + if err != nil { + return nil, err + } + + releaseVersion := &shared.ReleaseVersion{ + Next: shared.ReleaseVersionEntry{ + Commit: parsedContent.Next.Commit, + Version: nextVersion, + }, + Last: shared.ReleaseVersionEntry{ + Commit: parsedContent.Last.Commit, + Version: lastVersion, + }, + Branch: parsedContent.Branch, + Draft: parsedContent.Draft, + } + log.Infof("Found cache, will return cached version %s", parsedContent.Next.Version) + return releaseVersion, nil } diff --git a/internal/calculator/calculator.go b/internal/calculator/calculator.go new file mode 100644 index 0000000..d2541fb --- /dev/null +++ b/internal/calculator/calculator.go @@ -0,0 +1,68 @@ +package calculator + +import ( + "strconv" + "strings" + + "github.com/Masterminds/semver" + "github.com/Nightapes/go-semantic-release/internal/analyzer" + + log "github.com/sirupsen/logrus" +) + +// Calculator struct +type Calculator struct{} + +// New Calculator struct +func New() *Calculator { + return &Calculator{} +} + +//IncPrerelease increase prerelease by one +func (c *Calculator) IncPrerelease(preReleaseType string, version *semver.Version) (semver.Version, error) { + defaultPrerelease := preReleaseType + ".0" + if version.Prerelease() == "" || !strings.HasPrefix(version.Prerelease(), preReleaseType) { + return version.SetPrerelease(defaultPrerelease) + } + + parts := strings.Split(version.Prerelease(), ".") + if len(parts) == 2 { + i, err := strconv.Atoi(parts[1]) + if err != nil { + log.Warnf("Could not parse release tag %s, use version %s", version.Prerelease(), version.String()) + return version.SetPrerelease(defaultPrerelease) + } + return version.SetPrerelease(preReleaseType + "." + strconv.Itoa((i + 1))) + + } + log.Warnf("Could not parse release tag %s, use version %s", version.Prerelease(), version.String()) + return version.SetPrerelease(defaultPrerelease) +} + +//CalculateNewVersion from given commits and lastversion +func (c *Calculator) CalculateNewVersion(commits map[analyzer.Release][]analyzer.AnalyzedCommit, lastVersion *semver.Version, releaseType string, firstRelease bool) (semver.Version, bool) { + switch releaseType { + case "beta", "alpha": + if len(commits["major"]) > 0 || len(commits["minor"]) > 0 || len(commits["patch"]) > 0 { + version, _ := c.IncPrerelease(releaseType, lastVersion) + return version, true + } + case "rc": + if len(commits["major"]) > 0 || len(commits["minor"]) > 0 || len(commits["patch"]) > 0 { + version, _ := c.IncPrerelease(releaseType, lastVersion) + return version, false + } + case "release": + if !firstRelease { + if len(commits["major"]) > 0 { + return lastVersion.IncMajor(), false + } else if len(commits["minor"]) > 0 { + return lastVersion.IncMinor(), false + } else if len(commits["patch"]) > 0 { + return lastVersion.IncPatch(), false + } + } + } + + return *lastVersion, false +} diff --git a/internal/releaser/util/util.go b/internal/releaser/util/util.go index 6fc9882..86745e1 100644 --- a/internal/releaser/util/util.go +++ b/internal/releaser/util/util.go @@ -46,7 +46,7 @@ func PrepareAssets(repository string, assets []config.Asset) ([]*string, error) filesToUpload := []*string{} for _, asset := range assets { if asset.Name == "" { - return nil, fmt.Errorf("Asset name declaration is empty, please check your configuration file") + return nil, fmt.Errorf("asset name declaration is empty, please check your configuration file") } else if asset.Compress { log.Debugf("Asset %s will now be compressed", asset.Name) log.Debugf("Repo url %s", repository) diff --git a/pkg/semanticrelease/helper.go b/pkg/semanticrelease/helper.go deleted file mode 100644 index 990f57e..0000000 --- a/pkg/semanticrelease/helper.go +++ /dev/null @@ -1,87 +0,0 @@ -package semanticrelease - -import ( - "strconv" - "strings" - - "github.com/Masterminds/semver" - "github.com/Nightapes/go-semantic-release/internal/cache" - "github.com/Nightapes/go-semantic-release/internal/shared" - log "github.com/sirupsen/logrus" -) - -func (s *SemanticRelease) incPrerelease(preReleaseType string, version semver.Version) semver.Version { - defaultPrerelease := preReleaseType + ".0" - if version.Prerelease() == "" || !strings.HasPrefix(version.Prerelease(), preReleaseType) { - version, _ = version.SetPrerelease(defaultPrerelease) - } else { - parts := strings.Split(version.Prerelease(), ".") - if len(parts) == 2 { - i, err := strconv.Atoi(parts[1]) - if err != nil { - version, _ = version.SetPrerelease(defaultPrerelease) - log.Warnf("Could not parse release tag %s, use version %s", version.Prerelease(), version.String()) - } else { - version, _ = version.SetPrerelease(preReleaseType + "." + strconv.Itoa((i + 1))) - } - } else { - version, _ = version.SetPrerelease(defaultPrerelease) - log.Warnf("Could not parse release tag %s, use version %s", version.Prerelease(), version.String()) - } - } - - return version -} - -func (s *SemanticRelease) saveToCache(releaseVersion shared.ReleaseVersion) error { - - toCache := cache.ReleaseVersion{ - Next: cache.ReleaseVersionEntry{ - Commit: releaseVersion.Next.Commit, - Version: releaseVersion.Next.Version.String(), - }, - Last: cache.ReleaseVersionEntry{ - Commit: releaseVersion.Last.Commit, - Version: releaseVersion.Last.Version.String(), - }, - Branch: releaseVersion.Branch, - } - - log.Debugf("Save %s with hash %s to cache", releaseVersion.Next.Version.String(), releaseVersion.Next.Commit) - return cache.Write(s.repository, toCache) -} - -func (s *SemanticRelease) readFromCache(currentHash string) (*shared.ReleaseVersion, error) { - content, err := cache.Read(s.repository) - - if err == nil && content.Next.Commit == currentHash { - - nextVersion, err := semver.NewVersion(content.Next.Version) - if err != nil { - return nil, err - } - - lastVersion, err := semver.NewVersion(content.Last.Version) - if err != nil { - return nil, err - } - - releaseVersion := &shared.ReleaseVersion{ - Next: shared.ReleaseVersionEntry{ - Commit: content.Next.Commit, - Version: nextVersion, - }, - Last: shared.ReleaseVersionEntry{ - Commit: content.Last.Commit, - Version: lastVersion, - }, - Branch: content.Branch, - } - - log.Infof("Found cache, will return cached version %s", content.Next.Version) - return releaseVersion, nil - - } - log.Debugf("Mismatch git and version file %s - %s", content.Next.Commit, currentHash) - return nil, nil -} diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index 979ba2b..bbdade5 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -8,6 +8,8 @@ import ( "github.com/Masterminds/semver" "github.com/Nightapes/go-semantic-release/internal/analyzer" + "github.com/Nightapes/go-semantic-release/internal/cache" + "github.com/Nightapes/go-semantic-release/internal/calculator" "github.com/Nightapes/go-semantic-release/internal/changelog" "github.com/Nightapes/go-semantic-release/internal/ci" "github.com/Nightapes/go-semantic-release/internal/gitutil" @@ -23,6 +25,7 @@ type SemanticRelease struct { config *config.ReleaseConfig gitutil *gitutil.GitUtil analyzer *analyzer.Analyzer + calculator *calculator.Calculator releaser releaser.Releaser repository string } @@ -50,6 +53,7 @@ func New(c *config.ReleaseConfig, repository string) (*SemanticRelease, error) { releaser: releaser, analyzer: analyzer, repository: repository, + calculator: calculator.New(), }, nil } @@ -70,12 +74,12 @@ func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, er log.Debugf("Ignore .version file if exits, %t", force) if !force { - releaseVersion, err := s.readFromCache(provider.Commit) + releaseVersion, err := cache.Read(s.repository) if err != nil { return nil, err } - if releaseVersion != nil { + if releaseVersion.Next.Commit == provider.Commit && releaseVersion != nil { return releaseVersion, nil } } @@ -85,16 +89,12 @@ func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, er return nil, err } - var newVersion semver.Version firstRelease := false if lastVersion == nil { defaultVersion, _ := semver.NewVersion("1.0.0") - newVersion = *defaultVersion lastVersion = defaultVersion firstRelease = true - } else { - newVersion = *lastVersion } commits, err := s.gitutil.GetCommits(lastVersionHash) @@ -108,28 +108,14 @@ func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, er if err != nil { return nil, err } - result := a.Analyze(commits) + isDraft := false + var newVersion semver.Version for branch, releaseType := range s.config.Branch { if provider.Branch == branch || strings.HasPrefix(provider.Branch, branch) { log.Debugf("Found branch config for branch %s with release type %s", provider.Branch, releaseType) - switch releaseType { - case "beta", "alpha": - isDraft = true - newVersion = s.incPrerelease(releaseType, newVersion) - case "rc": - newVersion = s.incPrerelease(releaseType, newVersion) - case "release": - if !firstRelease { - if len(result["major"]) > 0 { - newVersion = newVersion.IncMajor() - } else if len(result["minor"]) > 0 { - newVersion = newVersion.IncMinor() - } else if len(result["patch"]) > 0 { - newVersion = newVersion.IncPatch() - } - } - } + newVersion, isDraft = s.calculator.CalculateNewVersion(a.Analyze(commits), lastVersion, releaseType, firstRelease) + break } } @@ -147,7 +133,7 @@ func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, er } log.Infof("New version %s -> %s", lastVersion.String(), newVersion.String()) - err = s.saveToCache(releaseVersion) + err = cache.Write(s.repository, releaseVersion) if err != nil { return nil, err } @@ -176,7 +162,7 @@ func (s *SemanticRelease) SetVersion(version string) error { lastVersion, _ = semver.NewVersion("1.0.0") } - return s.saveToCache(shared.ReleaseVersion{ + return cache.Write(s.repository, shared.ReleaseVersion{ Next: shared.ReleaseVersionEntry{ Commit: provider.Commit, Version: newVersion,