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 7d4ef3f  Mcuboot hack to prevent `newt upgrade` failure
7d4ef3f is described below

commit 7d4ef3fe65a9a83cc58e7bd973654ad235cc68bc
Author: Christopher Collins <[email protected]>
AuthorDate: Tue Oct 15 15:16:33 2019 -0700

    Mcuboot hack to prevent `newt upgrade` failure
    
    For projects using mcuboot, `newt upgrade` has been failing.  The
    error message is:
    
        Error: Error updating "mcuboot": error: The following untracked working
        tree files would be overwritten by checkout:
                ext/mbedtls/include/mbedtls/asn1.h
                ext/mbedtls/include/mbedtls/bignum.h
                ext/mbedtls/include/mbedtls/check_config.h
                ext/mbedtls/include/mbedtls/config.h
                ext/mbedtls/include/mbedtls/ecdsa.h
                ext/mbedtls/include/mbedtls/ecp.h
                ext/mbedtls/include/mbedtls/md.h
                ext/mbedtls/include/mbedtls/oid.h
                ext/mbedtls/include/mbedtls/pk.h
                ext/mbedtls/include/mbedtls/platform.h
                ext/mbedtls/include/mbedtls/platform_util.h
                ext/mbedtls/include/mbedtls/threading.h
        Please move or remove them before you switch branches.
        Aborting
    
    The problem is caused by a recent change to mcuboot - a normal directory
    was replaced with a submodule.  Git is unable to transition from a
    post-replace commit to a pre-replace commit because some files in the
    submodule used to exist in the mcuboot repo itself.
    
    This commit implements a pair of hacks to workaround this problem.  Upon
    performing a checkout operation on the mcuboot repo:
    
    1. If newt detects the above error message, it removes the `ext/mbedtls`
    directory and tries again.
    
    2. If newt detects a different warning message (`unable to rmdir
    'sim/mcuboot-sys/mbedtls': Directory not empty`), it removes
    `sim/mcuboot-sys/mbedtls`.
    
    The second hack is required when transitioning from pre-replace to
    post-replace.  In this case, the checkout operation succeeds, but an
    orphaned directory is left behind, making the repo look dirty.
    
    This is expected to be a short-term fix.  When we have a general fix
    for this issue, this hack can be removed.
---
 newt/downloader/downloader.go | 94 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 92 insertions(+), 2 deletions(-)

diff --git a/newt/downloader/downloader.go b/newt/downloader/downloader.go
index a5af7bf..8b3a607 100644
--- a/newt/downloader/downloader.go
+++ b/newt/downloader/downloader.go
@@ -365,6 +365,87 @@ func (gd *GenericDownloader) ensureInited(path string) 
error {
        return gd.init(path)
 }
 
+// untrackedFilesFromCheckoutErr collects the list of untracked files that
+// prevented a checkout from succeeding.  It returns nil if the provided error
+// does not indicate that untracked files are in the way.
+func untrackedFilesFromCheckoutErr(err error) []string {
+       var files []string
+
+       text := err.Error()
+       lines := strings.Split(text, "\n")
+
+       collecting := false
+       for _, line := range lines {
+               if !collecting {
+                       if strings.Contains(line,
+                               "The following untracked working tree files 
would "+
+                                       "be overwritten by checkout:") {
+                               collecting = true
+                       }
+               } else {
+                       if strings.Contains(line, "Please move or remove them 
before") {
+                               collecting = false
+                       } else {
+                               files = append(files, strings.TrimSpace(line))
+                       }
+               }
+       }
+
+       return files
+}
+
+// applyMcubootPreHack attempts to clean up the mcuboot repo so that the
+// subsequent checkout operation will succeed.  This hack is required because a
+// directory in the mcuboot repo was replaced with a submodule.  Git is unable
+// to transition from a post-replace commit to a pre-replace commit because
+// some files in the submodule used to exist in the mcuboot repo itself.  If
+// this issue is detected, this function deletes the submodule directory so
+// that the checkout operation can be attempted again.
+func applyMcubootPreHack(repoDir string, err error) error {
+       if !strings.HasSuffix(repoDir, "repos/mcuboot") {
+               // Not the mcuboot repo.
+               return err
+       }
+
+       // Check for an "untracked files" error.
+       files := untrackedFilesFromCheckoutErr(err)
+       if len(files) == 0 {
+               // Not a hackable error.
+               return err
+       }
+
+       for _, file := range files {
+               if !strings.HasPrefix(file, "ext/mbedtls") {
+                       return err
+               }
+       }
+
+       path := repoDir + "/ext/mbedtls"
+       log.Debugf("applying mcuboot hack: removing %s", path)
+       os.RemoveAll(path)
+       return nil
+}
+
+// applyMcubootPostHack attempts to clean up the mcuboot repo so that the
+// subsequent checkout operation will succeed.  This hack is required because a
+// directory in the mcuboot repo was replaced with a submodule.  This hack
+// should be applied after a successful checkout from a pre-replace commit to a
+// post-replace commit.  This function deletes an orphan directory left behind
+// by the checkout operation.
+func applyMcubootPostHack(repoDir string, output string) {
+       if !strings.HasSuffix(repoDir, "repos/mcuboot") {
+               // Not the mcuboot repo.
+               return
+       }
+
+       // Check for a "unable to rmdir" warning (pre- to post- submodule move).
+       if strings.Contains(output, "unable to rmdir 
'sim/mcuboot-sys/mbedtls'") {
+               path := repoDir + "/sim/mcuboot-sys/mbedtls"
+               log.Debugf("applying mcuboot hack: removing %s", path)
+               os.RemoveAll(path)
+       }
+}
+
 func (gd *GenericDownloader) Checkout(repoDir string, commit string) error {
        // Get the hash corresponding to the commit in case the caller 
specified a
        // branch or tag.  We always want to check out a hash and end up in a
@@ -380,8 +461,17 @@ func (gd *GenericDownloader) Checkout(repoDir string, 
commit string) error {
                hash,
        }
 
-       if _, err := executeGitCommand(repoDir, cmd, true); err != nil {
-               return err
+       o, err := executeGitCommand(repoDir, cmd, true)
+       if err != nil {
+               if err := applyMcubootPreHack(repoDir, err); err != nil {
+                       return err
+               }
+
+               if _, err := executeGitCommand(repoDir, cmd, true); err != nil {
+                       return err
+               }
+       } else {
+               applyMcubootPostHack(repoDir, string(o))
        }
 
        // Always initialize and update submodules on checkout.  This prevents 
the

Reply via email to