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

sjanc 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 1f565a44 newt/project: Load only repo dependencies of required versions
1f565a44 is described below

commit 1f565a446535423bfc6a898ddd2a7505297230a4
Author: Szymon Janc <[email protected]>
AuthorDate: Thu Oct 15 17:18:34 2026 +0200

    newt/project: Load only repo dependencies of required versions
    
    newt loaded and cloned every repo listed in repo.deps, regardless of
    which repo version mapped to it. A repository dropped as a dependency
    in recent versions, but still listed for older releases, was cloned
    for all projects (e.g. apache-mynewt-mcumgr for core master).
    
    Follow only dependencies that apply to the required repo versions.
    If a requirement cannot be mapped to a repository.yml commit (e.g.
    commit hash pin or unknown version) all dependencies are followed as
    before.
    
    Assisted-by: Claude:claude-opus-5-5
---
 newt/project/project.go | 111 ++++++++++++++++++++++++++++++++++--------------
 1 file changed, 78 insertions(+), 33 deletions(-)

diff --git a/newt/project/project.go b/newt/project/project.go
index 48ac5774..46c969bf 100644
--- a/newt/project/project.go
+++ b/newt/project/project.go
@@ -511,49 +511,92 @@ func (proj *Project) checkNewtVer() error {
        }
 }
 
-// Loads the `repository.yml` file for each depended-on repo.  This
+// Returns the dependencies of a repo that apply to the specified version
+// requirements.  If a requirement cannot be mapped to a `repository.yml`
+// commit (e.g., it is a commit hash or the version is unknown), all
+// dependencies are returned.
+func repoDepsForReqs(r *repo.Repo,
+       verReqs []newtutil.RepoVersion) []*repo.RepoDependency {
+
+       if len(verReqs) == 0 {
+               return r.AllDeps()
+       }
+
+       var deps []*repo.RepoDependency
+       for _, verReq := range verReqs {
+               if verReq.Commit != "" {
+                       return r.AllDeps()
+               }
+
+               commit, err := r.CommitFromVer(verReq)
+               if err != nil {
+                       return r.AllDeps()
+               }
+
+               deps = append(deps, r.CommitDepMap()[commit]...)
+       }
+
+       return deps
+}
+
+// Loads the `repository.yml` file for each depended-on repo.  Only the
+// dependencies of the required repo versions are followed, so repos that are
+// listed in `repo.deps` for other versions only are not loaded.
 func (proj *Project) loadRepoDeps(download bool) error {
-       seen := map[string]struct{}{}
+       verReqs := map[string][]newtutil.RepoVersion{}
+       for name, verReq := range proj.rootRepoReqs {
+               verReqs[name] = append(verReqs[name], verReq)
+       }
+
+       // Records a version requirement for a repo.  Returns true if the
+       // requirement was not known before.
+       addVerReq := func(name string, verReq newtutil.RepoVersion) bool {
+               for _, v := range verReqs[name] {
+                       if v.String() == verReq.String() {
+                               return false
+                       }
+               }
+
+               verReqs[name] = append(verReqs[name], verReq)
+               return true
+       }
 
        loadDeps := func(r *repo.Repo) ([]*repo.Repo, error) {
                var newRepos []*repo.Repo
 
-               depMap := r.CommitDepMap()
-               for _, depSlice := range depMap {
-                       for _, dep := range depSlice {
-                               if _, ok := seen[dep.Name]; !ok {
-                                       seen[r.Name()] = struct{}{}
+               for _, dep := range repoDepsForReqs(r, verReqs[r.Name()]) {
+                       if !addVerReq(dep.Name, dep.VerReqs) {
+                               continue
+                       }
 
-                                       depRepo := proj.repos[dep.Name]
-                                       if depRepo == nil {
-                                               var err error
+                       depRepo := proj.repos[dep.Name]
+                       if depRepo == nil {
+                               var err error
 
-                                               if 
!proj.isRepoAllowed(dep.Name) {
-                                                       continue
-                                               }
+                               if !proj.isRepoAllowed(dep.Name) {
+                                       continue
+                               }
 
-                                               depRepo, err = 
proj.loadRepo(dep.Name, dep.Fields)
-                                               if err != nil {
-                                                       // if `repository.yml` 
does not exist, it is not an
-                                                       // error; we will just 
download a new copy.
-                                                       if 
!util.IsNotExist(err) {
-                                                               return nil, err
-                                                       }
-                                               }
-                                               if depRepo == nil {
-                                                       continue
-                                               }
-                                               if err := proj.addRepo(depRepo, 
download); err != nil {
-                                                       return nil, err
-                                               }
+                               depRepo, err = proj.loadRepo(dep.Name, 
dep.Fields)
+                               if err != nil {
+                                       // if `repository.yml` does not exist, 
it is not an
+                                       // error; we will just download a new 
copy.
+                                       if !util.IsNotExist(err) {
+                                               return nil, err
                                        }
-                                       newRepos = append(newRepos, depRepo)
+                               }
+                               if depRepo == nil {
+                                       continue
+                               }
+                               if err := proj.addRepo(depRepo, download); err 
!= nil {
+                                       return nil, err
+                               }
+                       }
+                       newRepos = append(newRepos, depRepo)
 
-                                       if download {
-                                               if _, err := 
depRepo.UpdateDesc(); err != nil {
-                                                       return nil, err
-                                               }
-                                       }
+                       if download {
+                               if _, err := depRepo.UpdateDesc(); err != nil {
+                                       return nil, err
                                }
                        }
                }
@@ -561,6 +604,8 @@ func (proj *Project) loadRepoDeps(download bool) error {
                return newRepos, nil
        }
 
+       // A repo is processed again whenever a new version requirement is added
+       // for it.  This terminates since the set of requirements only grows.
        curRepos := proj.repos.Sorted()
        for len(curRepos) > 0 {
                var nextRepos []*repo.Repo

Reply via email to