You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2018/11/07 19:27:46 UTC

[mynewt-newt] branch master updated: When pruning deps, delete dangling orphans

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 f27018f  When pruning deps, delete dangling orphans
f27018f is described below

commit f27018f776300b6518aebc098c1ec39f5821347f
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Fri Nov 2 15:14:03 2018 -0700

    When pruning deps, delete dangling orphans
    
    During dependency resolution, some newly-discovered syscfg values may
    nullify existing conditional dependencies.  If the last dependency for a
    particular package is removed, the package must be removed entirely from
    the build, as it is not actually depended on.
    
    Newt was already doing the above.  However, it failed to also check the
    removed package's dependencies.  If the removed package was the only
    dependent for a second package, the second package must also be removed.
    This needs to be done recursively
    
    Prior to this fix, some orphaned packages could be incorrectly included
    in the build.
---
 newt/resolve/resolve.go | 35 +++++++++++++++++++++++++++++++----
 1 file changed, 31 insertions(+), 4 deletions(-)

diff --git a/newt/resolve/resolve.go b/newt/resolve/resolve.go
index 29dcee5..a85c97e 100644
--- a/newt/resolve/resolve.go
+++ b/newt/resolve/resolve.go
@@ -330,6 +330,34 @@ func (r *Resolver) calcApiReqs() {
 	}
 }
 
+// Completely removes a package from the resolver.  This is used to prune
+// packages when newly-discovered syscfg values nullify dependencies.
+func (r *Resolver) deletePkg(rpkg *ResolvePackage) error {
+	delete(r.pkgMap, rpkg.Lpkg)
+
+	// Delete the package from syscfg.
+	r.cfg.DeletePkg(rpkg.Lpkg)
+
+	// If the deleted package is the only depender for any other packages
+	// (i.e., if any of its dependencies have a reference count of one), delete
+	// them as well.
+	for rdep, _ := range rpkg.Deps {
+		if rdep.refCount <= 0 {
+			return util.FmtNewtError(
+				"package %s unexpectedly has refcount <= 0",
+				rdep.Lpkg.FullName())
+		}
+		rdep.refCount--
+		if rdep.refCount == 0 {
+			if err := r.deletePkg(rdep); err != nil {
+				return nil
+			}
+		}
+	}
+
+	return nil
+}
+
 // @return bool                 True if this this function changed the resolver
 //                                  state; another full iteration is required
 //                                  in this case.
@@ -384,10 +412,9 @@ func (r *Resolver) loadDepsForPkg(rpkg *ResolvePackage) (bool, error) {
 			// If we just deleted the last reference to a package, remove the
 			// package entirely from the resolver and syscfg.
 			if rdep.refCount == 0 {
-				delete(r.pkgMap, rdep.Lpkg)
-
-				// Delete the package from syscfg.
-				r.cfg.DeletePkg(rdep.Lpkg)
+				if err := r.deletePkg(rdep); err != nil {
+					return true, err
+				}
 			}
 		}
 	}