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'
