This is an automated email from the ASF dual-hosted git repository.

ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-newt.git


The following commit(s) were added to refs/heads/master by this push:
     new 4566ff1  On install/upgrade, try latest "_rc" tag
4566ff1 is described below

commit 4566ff12d1183ac83193f52c99944a21d1f78895
Author: Christopher Collins <ccoll...@apache.org>
AuthorDate: Mon Jul 22 14:30:17 2019 -0700

    On install/upgrade, try latest "_rc" tag
    
    During install / upgrade, if the requested commit doesn't exist, try to
    check out the latest "rc" tag instead.  This behavior is useful when a
    release candidate is being tested.  In this case, the "rc" tags exist,
    but the official release tag has not been created yet.
    
    Example:
    
     ### project.yml
        repository.apache-mynewt-core:
            type: git
            vers: 2.0.0
            url: 'g...@github.com:apache/mynewt-core.git'
    
     ### repository.yml (mynewt-core)
        repo.versions:
            "2.0.0": "mynewt_2_0_0_tag"
    
    The "mynewt_2_0_0_tag" doesn't actually exist yet.  This tag will not
    get created until 2.0.0 is actually released.  However, the following
    tags do exist:
    
        * mynewt_2_0_0_rc1_tag
        * mynewt_2_0_0_rc2_tag
    
    When newt attempts to upgrade, upon discovering that the requested tag
    does not exist, it uses the latest "rc" tag instead (rc2 in this case).
    If an "rc3" tag is later added, then the next upgrade operation will
    check out the new tag.
---
 newt/downloader/downloader.go | 49 +++++++++++++++++++++++++++++++++++++++++++
 newt/repo/repo.go             | 21 +++++++++++++++++++
 2 files changed, 70 insertions(+)

diff --git a/newt/downloader/downloader.go b/newt/downloader/downloader.go
index 1e58ea4..0ecbecf 100644
--- a/newt/downloader/downloader.go
+++ b/newt/downloader/downloader.go
@@ -25,7 +25,9 @@ import (
        "os"
        "os/exec"
        "path/filepath"
+       "regexp"
        "sort"
+       "strconv"
        "strings"
 
        log "github.com/sirupsen/logrus"
@@ -76,6 +78,15 @@ type Downloader interface {
        // Retrieves the name of the currently checked out local branch, or "" 
if
        // the repo is in a "detached head" state.
        CurrentBranch(path string) (string, error)
+
+       // LatestRc finds the commit of the latest release candidate.  It looks
+       // for commits with names matching the base commit string, but with with
+       // "_rc#" inserted.  This is useful when a release candidate is being
+       // tested.  In this case, the "rc" tags exist, but the official release
+       // tag has not been created yet.
+       //
+       // If such a commit exists, it is returned.  Otherwise, "" is returned.
+       LatestRc(path string, base string) (string, error)
 }
 
 type Commit struct {
@@ -608,6 +619,44 @@ func (gd *GenericDownloader) DirtyState(path string) 
(string, error) {
        return "", nil
 }
 
+func (gd *GenericDownloader) LatestRc(path string,
+       base string) (string, error) {
+
+       if err := gd.ensureInited(path); err != nil {
+               return "", err
+       }
+
+       // Example:
+       // [BASE] mynewt_1_7_0_tag
+       // [RC]   mynewt_1_7_0_rc1_tag
+
+       notag := strings.TrimSuffix(base, "_tag")
+       if notag == base {
+               return "", nil
+       }
+
+       restr := fmt.Sprintf("^%s_rc(\\d+)_tag$", regexp.QuoteMeta(notag))
+       re, err := regexp.Compile(restr)
+       if err != nil {
+               return "", util.FmtNewtError("internal error: %s", err.Error())
+       }
+
+       bestNum := -1
+       bestStr := ""
+       for commit, _ := range gd.commits {
+               match := re.FindStringSubmatch(commit)
+               if len(match) >= 2 {
+                       num, _ := strconv.Atoi(match[1])
+                       if num > bestNum {
+                               bestNum = num
+                               bestStr = commit
+                       }
+               }
+       }
+
+       return bestStr, nil
+}
+
 func (gd *GithubDownloader) Fetch(repoDir string) error {
        return gd.cachedFetch(func() error {
                util.StatusMessage(util.VERBOSITY_VERBOSE, "Fetching repo %s\n",
diff --git a/newt/repo/repo.go b/newt/repo/repo.go
index 1c566b0..99c2bf8 100644
--- a/newt/repo/repo.go
+++ b/newt/repo/repo.go
@@ -237,6 +237,27 @@ func (r *Repo) updateRepo(commit string) error {
                return util.FmtNewtError(
                        "Error updating \"%s\": %s", r.Name(), err.Error())
        }
+
+       // If the specified commit doesn't exist, try inserting "_rc#" into the
+       // string.  This is useful when a release candidate is being tested.  In
+       // this case, the "rc" tags exist, but the official release tag has not
+       // been created yet.
+       if _, err := r.downloader.CommitType(r.Path(), commit); err != nil {
+               newCommit, err := r.downloader.LatestRc(r.Path(), commit)
+               if err != nil {
+                       return util.FmtNewtError(
+                               "Error updating \"%s\": %s", r.Name(), 
err.Error())
+               }
+
+               if newCommit != "" {
+                       util.StatusMessage(util.VERBOSITY_DEFAULT,
+                               "in repo \"%s\": commit \"%s\" does not exist; 
"+
+                                       "using \"%s\" instead\n",
+                               r.Name(), commit, newCommit)
+                       commit = newCommit
+               }
+       }
+
        if err := r.downloader.Checkout(r.Path(), commit); err != nil {
                return util.FmtNewtError(
                        "Error updating \"%s\": %s", r.Name(), err.Error())

Reply via email to