Skip to content

Commit 66be85f

Browse files
committed
Enable upgrading only specified repos
Reimplement support for `newt upgrade <repo1> <repo2>...`. Not specifying repos upgrades everything; specifying repos update only the ones given, without upgrading/installing its dependencies, etc. This should allow advanced users to install only what is required, eg. if developing an app for nrf52x one could simply run: `newt upgrade --depth=1 apache-mynewt-core apache-mynewt-nimble nordic-nrfx` This is also useful for CI, eg, for MCUboot it's possible to use MCUboot as the root project and run: `newt upgrade --depth=1 apache-mynewt-core nordic-nrfx mbedtls` And this brings down the complete download from 1GB to just around 250MB. Signed-off-by: Fabio Utzig <utzig@apache.org>
1 parent 30e7e83 commit 66be85f

File tree

5 files changed

+74
-38
lines changed

5 files changed

+74
-38
lines changed

newt/cli/project_cmds.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,14 +121,14 @@ func makeRepoPredicate(repoNames []string) func(r *repo.Repo) bool {
121121
}
122122

123123
func upgradeRunCmd(cmd *cobra.Command, args []string) {
124-
proj := TryGetOrDownloadProject()
124+
proj := TryGetOrDownloadProject(args)
125125
interfaces.SetProject(proj)
126126

127-
proj.GetPkgRepos()
127+
proj.GetPkgRepos(args)
128128

129129
pred := makeRepoPredicate(args)
130130
if err := proj.UpgradeIf(
131-
newtutil.NewtForce, newtutil.NewtAsk, pred); err != nil {
131+
newtutil.NewtForce, newtutil.NewtAsk, args, pred); err != nil {
132132

133133
NewtUsage(nil, err)
134134
}

newt/cli/util.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,11 +210,11 @@ func TryGetProject() *project.Project {
210210
return p
211211
}
212212

213-
func TryGetOrDownloadProject() *project.Project {
213+
func TryGetOrDownloadProject(okRepos []string) *project.Project {
214214
var p *project.Project
215215
var err error
216216

217-
if p, err = project.TryGetOrDownloadProject(); err != nil {
217+
if p, err = project.TryGetOrDownloadProject(okRepos); err != nil {
218218
NewtUsage(nil, err)
219219
}
220220

newt/deprepo/deprepo.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,14 +107,26 @@ func (vm VersionMap) String() string {
107107
return s
108108
}
109109

110+
func isInReqs(repo string, reqs RequirementMap) bool {
111+
for r, _ := range reqs {
112+
if repo == r {
113+
return true
114+
}
115+
}
116+
return false
117+
}
118+
110119
// Builds a repo dependency graph from the repo requirements expressed in the
111120
// `project.yml` file.
112121
func BuildDepGraph(repos RepoMap, rootReqs RequirementMap) (DepGraph, error) {
113122
dg := DepGraph{}
114123

115124
// First, add the hard dependencies expressed in `project.yml`.
116125
for repoName, verReq := range rootReqs {
117-
repo := repos[repoName]
126+
repo, ok := repos[repoName]
127+
if !ok {
128+
continue
129+
}
118130
normalizedReq, err := repo.NormalizeVerReq(verReq)
119131
if err != nil {
120132
return nil, err
@@ -128,13 +140,16 @@ func BuildDepGraph(repos RepoMap, rootReqs RequirementMap) (DepGraph, error) {
128140
// Add inter-repo dependencies to the graph.
129141
for _, r := range repos.Sorted() {
130142
nvers, err := r.NormalizedVersions()
131-
if err != nil {
143+
if err != nil && isInReqs(r.Name(), rootReqs) {
132144
return nil, err
133145
}
134146
for _, v := range nvers {
135147
deps := r.DepsForVersion(v)
136148
reqMap := RequirementMap{}
137149
for _, d := range deps {
150+
if !isInReqs(d.Name, rootReqs) {
151+
continue
152+
}
138153
depRepo := repos[d.Name]
139154
verReqs, err := depRepo.NormalizeVerReq(d.VerReqs)
140155
if err != nil {

newt/install/install.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,10 @@ func (inst *Installer) ensureDepsInList(repos []*repo.Repo,
198198
deps = r.DepsForVersion(vm[r.Name()])
199199
}
200200
for _, d := range deps {
201-
depRepo := inst.repos[d.Name]
202-
result = append(result, recurse(depRepo)...)
201+
depRepo, ok := inst.repos[d.Name]
202+
if ok {
203+
result = append(result, recurse(depRepo)...)
204+
}
203205
}
204206

205207
return result
@@ -706,12 +708,14 @@ func (inst *Installer) remoteRepoInfo(r *repo.Repo, vm *deprepo.VersionMap) {
706708
ri := inst.gatherInfo(r, vm)
707709
s := fmt.Sprintf(" * %s:", r.Name())
708710

709-
s += fmt.Sprintf(" %s", ri.commitHash)
710711
if ri.installedVer == nil {
712+
s += fmt.Sprintf(" ?")
711713
s += ", (not installed)"
712714
} else if ri.errorText != "" {
715+
s += fmt.Sprintf(" %s", ri.commitHash)
713716
s += fmt.Sprintf(", (unknown: %s)", ri.errorText)
714717
} else {
718+
s += fmt.Sprintf(" %s", ri.commitHash)
715719
if ri.installedVer.Commit == "" {
716720
s += fmt.Sprintf(", %s", ri.installedVer.String())
717721
}

newt/project/project.go

Lines changed: 45 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,10 @@ type Project struct {
8585
yc ycfg.YCfg
8686
}
8787

88-
func initProject(dir string, download bool) error {
88+
func initProject(dir string, download bool, okRepos []string) error {
8989
var err error
9090

91-
globalProject, err = LoadProject(dir, download)
91+
globalProject, err = loadProject(dir, download, okRepos)
9292
if err != nil {
9393
return err
9494
}
@@ -99,29 +99,29 @@ func initProject(dir string, download bool) error {
9999
return nil
100100
}
101101

102-
func initialize(download bool) error {
102+
func initialize(download bool, okRepos []string) error {
103103
if globalProject == nil {
104104
wd, err := os.Getwd()
105105
wd = filepath.ToSlash(wd)
106106
if err != nil {
107107
return util.NewNewtError(err.Error())
108108
}
109-
if err := initProject(wd, download); err != nil {
109+
if err := initProject(wd, download, okRepos); err != nil {
110110
return err
111111
}
112112
}
113113
return nil
114114
}
115115

116116
func TryGetProject() (*Project, error) {
117-
if err := initialize(false); err != nil {
117+
if err := initialize(false, nil); err != nil {
118118
return nil, err
119119
}
120120
return globalProject, nil
121121
}
122122

123-
func TryGetOrDownloadProject() (*Project, error) {
124-
if err := initialize(true); err != nil {
123+
func TryGetOrDownloadProject(okRepos []string) (*Project, error) {
124+
if err := initialize(true, okRepos); err != nil {
125125
return nil, err
126126
}
127127
return globalProject, nil
@@ -153,24 +153,36 @@ func ResetDeps(newList interfaces.PackageList) interfaces.PackageList {
153153
return oldList
154154
}
155155

156-
func NewProject(dir string, download bool) (*Project, error) {
156+
func newProject(dir string, download bool, okRepos []string) (*Project, error) {
157157
proj := &Project{}
158158

159-
if err := proj.Init(dir, download); err != nil {
159+
if err := proj.Init(dir, download, okRepos); err != nil {
160160
return nil, err
161161
}
162162

163163
return proj, nil
164164
}
165165

166-
func (proj *Project) GetPkgRepos() error {
166+
func isOkRepo(repo string, okRepos []string) bool {
167+
if okRepos == nil || len(okRepos) == 0 {
168+
return true
169+
}
170+
for _, v := range okRepos {
171+
if repo == v {
172+
return true
173+
}
174+
}
175+
return false
176+
}
177+
178+
func (proj *Project) GetPkgRepos(okRepos []string) error {
167179

168180
for _, pkgList := range proj.packages {
169181
for _, pkg := range *pkgList {
170182
if pkg.PkgConfig().HasKey("repository") {
171183
for k, _ := range pkg.PkgConfig().AllSettings() {
172184
repoName := strings.TrimPrefix(k, "repository.")
173-
if repoName != k {
185+
if repoName != k && isOkRepo(repoName, okRepos) {
174186
fields, err := pkg.PkgConfig().GetValStringMapString(k, nil)
175187
util.OneTimeWarningError(err)
176188

@@ -190,7 +202,7 @@ func (proj *Project) GetPkgRepos() error {
190202
repoName, fields["vers"], err.Error())
191203
}
192204
r.SetPkgName(pkg.Name())
193-
if err := proj.addRepo(r, true); err != nil {
205+
if err := proj.addRepo(r, true, false); err != nil {
194206
return err
195207
}
196208
proj.rootRepoReqs[repoName] = verReq
@@ -302,10 +314,10 @@ func (proj *Project) SelectRepos(pred func(r *repo.Repo) bool) []*repo.Repo {
302314

303315
// Installs or upgrades repos matching the specified predicate.
304316
func (proj *Project) UpgradeIf(
305-
force bool, ask bool, predicate func(r *repo.Repo) bool) error {
317+
force bool, ask bool, okRepos []string, predicate func(r *repo.Repo) bool) error {
306318

307319
// Make sure we have an up to date copy of all `repository.yml` files.
308-
if err := proj.downloadRepositoryYmlFiles(); err != nil {
320+
if err := proj.downloadRepositoryYmlFiles(okRepos); err != nil {
309321
return err
310322
}
311323

@@ -328,7 +340,7 @@ func (proj *Project) InfoIf(predicate func(r *repo.Repo) bool,
328340

329341
if remote {
330342
// Make sure we have an up to date copy of all `repository.yml` files.
331-
if err := proj.downloadRepositoryYmlFiles(); err != nil {
343+
if err := proj.downloadRepositoryYmlFiles(nil); err != nil {
332344
return err
333345
}
334346
}
@@ -425,7 +437,7 @@ func (proj *Project) checkNewtVer() error {
425437
}
426438

427439
// Loads the `repository.yml` file for each depended-on repo. This
428-
func (proj *Project) loadRepoDeps(download bool) error {
440+
func (proj *Project) loadRepoDeps(download bool, okRepos []string) error {
429441
seen := map[string]struct{}{}
430442

431443
loadDeps := func(r *repo.Repo) ([]*repo.Repo, error) {
@@ -434,6 +446,11 @@ func (proj *Project) loadRepoDeps(download bool) error {
434446
depMap := r.CommitDepMap()
435447
for _, depSlice := range depMap {
436448
for _, dep := range depSlice {
449+
if !isOkRepo(dep.Name, okRepos) {
450+
log.Debugf("Skipping repo %s", dep.Name)
451+
continue
452+
}
453+
437454
if _, ok := seen[dep.Name]; !ok {
438455
seen[r.Name()] = struct{}{}
439456

@@ -448,7 +465,7 @@ func (proj *Project) loadRepoDeps(download bool) error {
448465
return nil, err
449466
}
450467
}
451-
if err := proj.addRepo(depRepo, download); err != nil {
468+
if err := proj.addRepo(depRepo, download, true); err != nil {
452469
return nil, err
453470
}
454471
}
@@ -485,7 +502,7 @@ func (proj *Project) loadRepoDeps(download bool) error {
485502
return nil
486503
}
487504

488-
func (proj *Project) downloadRepositoryYmlFiles() error {
505+
func (proj *Project) downloadRepositoryYmlFiles(okRepos []string) error {
489506
// Download the `repository.yml` file for each root-level repo (those
490507
// specified in the `project.yml` file).
491508
for _, r := range proj.repos.Sorted() {
@@ -500,7 +517,7 @@ func (proj *Project) downloadRepositoryYmlFiles() error {
500517
}
501518

502519
// Download the `repository.yml` file for each depended-on repo.
503-
if err := proj.loadRepoDeps(true); err != nil {
520+
if err := proj.loadRepoDeps(true, okRepos); err != nil {
504521
return err
505522
}
506523

@@ -548,13 +565,13 @@ func (proj *Project) verifyNewtCompat() error {
548565

549566
// addRepo Adds an entry to the project's repo map. It clones the repo if it
550567
// does not exist locally.
551-
func (proj *Project) addRepo(r *repo.Repo, download bool) error {
568+
func (proj *Project) addRepo(r *repo.Repo, download bool, isDep bool) error {
552569
if download {
553570
if err := r.EnsureExists(); err != nil {
554571
return err
555572
}
556573
} else {
557-
if !r.CheckExists() {
574+
if !r.CheckExists() && !isDep {
558575
return util.NewNewtError(
559576
fmt.Sprintf(
560577
"Repo \"%s\" is not installed, please run `newt upgrade`!",
@@ -566,7 +583,7 @@ func (proj *Project) addRepo(r *repo.Repo, download bool) error {
566583
return nil
567584
}
568585

569-
func (proj *Project) loadConfig(download bool) error {
586+
func (proj *Project) loadConfig(download bool, okRepos []string) error {
570587
yc, err := config.ReadFile(proj.BasePath + "/" + PROJECT_FILE_NAME)
571588
if err != nil {
572589
return util.NewNewtError(err.Error())
@@ -615,7 +632,7 @@ func (proj *Project) loadConfig(download bool) error {
615632
repoName, fields["vers"], err.Error())
616633
}
617634

618-
if err := proj.addRepo(r, download); err != nil {
635+
if err := proj.addRepo(r, download, false); err != nil {
619636
return err
620637
}
621638
proj.rootRepoReqs[repoName] = verReq
@@ -625,7 +642,7 @@ func (proj *Project) loadConfig(download bool) error {
625642
// Read `repository.yml` files belonging to dependee repos from disk.
626643
// These repos might not be specified in the `project.yml` file, but they
627644
// are still part of the project.
628-
if err := proj.loadRepoDeps(download); err != nil {
645+
if err := proj.loadRepoDeps(download, okRepos); err != nil {
629646
return err
630647
}
631648

@@ -662,7 +679,7 @@ func (proj *Project) loadConfig(download bool) error {
662679
return nil
663680
}
664681

665-
func (proj *Project) Init(dir string, download bool) error {
682+
func (proj *Project) Init(dir string, download bool, okRepos []string) error {
666683
proj.BasePath = filepath.ToSlash(filepath.Clean(dir))
667684

668685
// Only one project per system, when created, set it as the global project
@@ -672,7 +689,7 @@ func (proj *Project) Init(dir string, download bool) error {
672689
proj.rootRepoReqs = map[string]newtutil.RepoVersion{}
673690

674691
// Load Project configuration
675-
if err := proj.loadConfig(download); err != nil {
692+
if err := proj.loadConfig(download, okRepos); err != nil {
676693
return err
677694
}
678695

@@ -813,13 +830,13 @@ func (proj *Project) PackagesOfType(pkgType interfaces.PackageType) []interfaces
813830
return matches
814831
}
815832

816-
func LoadProject(dir string, download bool) (*Project, error) {
833+
func loadProject(dir string, download bool, okRepos []string) (*Project, error) {
817834
projDir, err := findProjectDir(dir)
818835
if err != nil {
819836
return nil, err
820837
}
821838

822-
proj, err := NewProject(projDir, download)
839+
proj, err := newProject(projDir, download, okRepos)
823840

824841
return proj, err
825842
}

0 commit comments

Comments
 (0)