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

commit 70ed2d6f9984b17a8d5357beb51fb6d9b37e232b
Author: Szymon Janc <[email protected]>
AuthorDate: Mon Oct 19 17:49:29 2026 +0200

    newt/project: Fix treating the project as a repo dependency
    
    The local project repo is stored in the repo map under project.name.
    If a repo depends on a repo with the same name as the project (e.g.
    apache-mynewt-core depends on mcuboot and the project is an mcuboot
    checkout), newt took the local repo for that dependency, "updated" it
    and ran "git remote set-url origin ''" on the project checkout. The
    upgrade then failed normalizing the dependency version on the local
    repo.
    
    A dependency on the project's name is now considered satisfied by the
    project itself: it is not loaded, updated or installed, and it is
    left out of the repo dependency graph.
    
    Assisted-by: Claude:claude-opus-5-5
---
 newt/deprepo/deprepo.go                 |  6 ++-
 newt/install/install.go                 |  5 +-
 newt/localrepo_test.go                  | 82 +++++++++++++++++++++++++++++++++
 newt/project/project.go                 |  9 ++++
 newt/testdata/localrepo_dep/project.yml | 27 +++++++++++
 5 files changed, 125 insertions(+), 4 deletions(-)

diff --git a/newt/deprepo/deprepo.go b/newt/deprepo/deprepo.go
index 6bbc7ac8..a371d877 100644
--- a/newt/deprepo/deprepo.go
+++ b/newt/deprepo/deprepo.go
@@ -136,8 +136,10 @@ func BuildDepGraph(repos RepoMap, rootReqs RequirementMap) 
(DepGraph, error) {
                        reqMap := RequirementMap{}
                        for _, d := range deps {
                                depRepo := repos[d.Name]
-                               // This might be nil if d.Name is not on 
allowed repositories list
-                               if depRepo == nil {
+                               // This might be nil if d.Name is not on 
allowed repositories
+                               // list.  A dependency on the local project 
repo (same name
+                               // as the project) is satisfied by the project 
itself.
+                               if depRepo == nil || depRepo.IsLocal() {
                                        continue
                                }
                                verReqs, err := 
depRepo.NormalizeVerReq(d.VerReqs)
diff --git a/newt/install/install.go b/newt/install/install.go
index 2d48eea5..a3dc53f3 100644
--- a/newt/install/install.go
+++ b/newt/install/install.go
@@ -200,8 +200,9 @@ func (inst *Installer) ensureDepsInList(repos []*repo.Repo,
                }
                for _, d := range deps {
                        depRepo := inst.repos[d.Name]
-                       // This might be nil if d.Name is not on allowed 
repositories list
-                       if depRepo == nil {
+                       // This might be nil if d.Name is not on allowed 
repositories
+                       // list.  The local project repo is never installed.
+                       if depRepo == nil || depRepo.IsLocal() {
                                continue
                        }
                        result = append(result, recurse(depRepo)...)
diff --git a/newt/localrepo_test.go b/newt/localrepo_test.go
new file mode 100644
index 00000000..ed2fc15c
--- /dev/null
+++ b/newt/localrepo_test.go
@@ -0,0 +1,82 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package main
+
+import (
+       "path/filepath"
+       "strings"
+       "testing"
+)
+
+var localRepoDir = filepath.Join("testdata", "localrepo_dep")
+
+// localRepoGitInit turns dir into a git repository with a single commit and
+// an "origin" remote. Returns the commit hash.
+func localRepoGitInit(t *testing.T, env []string, dir string,
+       origin string) string {
+
+       t.Helper()
+
+       env = append(env,
+               "GIT_AUTHOR_NAME=newt test", 
"[email protected]",
+               "GIT_COMMITTER_NAME=newt test",
+               "[email protected]")
+
+       runGit(t, env, nil, "-C", dir, "init", "-q")
+       runGit(t, env, nil, "-C", dir, "add", ".")
+       runGit(t, env, nil, "-C", dir, "commit", "-q", "-m", "project")
+       runGit(t, env, nil, "-C", dir, "remote", "add", "origin", origin)
+
+       return runGit(t, env, nil, "-C", dir, "rev-parse", "HEAD")
+}
+
+// A repo dependency with the same name as the project (e.g., the project is
+// a checkout of a repo that apache-mynewt-core depends on) must be satisfied
+// by the project itself and must not modify the project's git checkout.
+func TestLocalRepoDependency(t *testing.T) {
+       env := dummyReposEnv(t)
+       projDir := copyToTemp(t, localRepoDir)
+
+       const origin = "https://example.invalid/project.git";
+       head := localRepoGitInit(t, env, projDir, origin)
+
+       for i := 0; i < 2; i++ {
+               out, err := newtCombinedOutput(projDir, env, "upgrade")
+               if err != nil {
+                       t.Fatalf("newt upgrade failed: %v\n%s", err, out)
+               }
+
+               gotOrigin := runGit(t, env, nil, "-C", projDir, "remote", 
"get-url",
+                       "origin")
+               if gotOrigin != origin {
+                       t.Fatalf("project origin changed to %q", gotOrigin)
+               }
+
+               gotHead := runGit(t, env, nil, "-C", projDir, "rev-parse", 
"HEAD")
+               if gotHead != head {
+                       t.Fatalf("project HEAD changed to %s", gotHead)
+               }
+
+               checkOutput(t, "installed repos",
+                       "mynewt-dummy-repo-01\nmynewt-dummy-repo-03\n"+
+                               "mynewt-dummy-repo-04",
+                       strings.Join(installedRepos(t, projDir), "\n"))
+       }
+}
diff --git a/newt/project/project.go b/newt/project/project.go
index 298abffd..4a967b49 100644
--- a/newt/project/project.go
+++ b/newt/project/project.go
@@ -601,6 +601,15 @@ func (proj *Project) loadRepoDeps(download bool) error {
                var newRepos []*repo.Repo
 
                for _, dep := range repoDepsForReqs(r, verReqs[r.Name()]) {
+                       // A dependency with the same name as the project 
refers to
+                       // the project itself (e.g., when the project is a 
checkout of
+                       // that repo).  The local repo is never downloaded or 
updated.
+                       if dep.Name == proj.localRepo.Name() {
+                               log.Debugf("Repo \"%s\" depends on \"%s\"; 
using the "+
+                                       "local project", r.Name(), dep.Name)
+                               continue
+                       }
+
                        if !addVerReq(dep.Name, dep.VerReqs) {
                                continue
                        }
diff --git a/newt/testdata/localrepo_dep/project.yml 
b/newt/testdata/localrepo_dep/project.yml
new file mode 100644
index 00000000..c118650f
--- /dev/null
+++ b/newt/testdata/localrepo_dep/project.yml
@@ -0,0 +1,27 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# The project has the same name as a repo that mynewt-dummy-repo-01 depends
+# on, i.e., it is a checkout of that repo.
+project.name: mynewt-dummy-repo-02
+
+repository.mynewt-dummy-repo-01:
+   type: git
+   vers: 0.0.0
+   url: 'https://dummy.invalid/mynewt-dummy-repo-01.git'

Reply via email to