Skip to content

Commit ec34f89

Browse files
[wip] Add project cache
1 parent 4f847e5 commit ec34f89

File tree

3 files changed

+166
-31
lines changed

3 files changed

+166
-31
lines changed

newt/cache/cache.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package cache
21+
22+
import (
23+
"encoding/gob"
24+
"fmt"
25+
"mynewt.apache.org/newt/newt/interfaces"
26+
"mynewt.apache.org/newt/newt/repo"
27+
"mynewt.apache.org/newt/util"
28+
"os"
29+
"path/filepath"
30+
)
31+
32+
type ProjectCache struct {
33+
baseDir string
34+
}
35+
36+
func InitCache(projDir string) *ProjectCache {
37+
pc := ProjectCache{}
38+
pc.baseDir = filepath.Join(projDir, ".cache")
39+
40+
if _, err := os.Stat(pc.baseDir); os.IsNotExist(err) {
41+
if err := os.Mkdir(pc.baseDir, 0754); err != nil {
42+
return nil
43+
}
44+
}
45+
46+
return &pc
47+
}
48+
49+
func (pc *ProjectCache) getPackagesFile(repo *repo.Repo) string {
50+
return fmt.Sprintf(filepath.Join(pc.baseDir, repo.Name()))
51+
}
52+
53+
func (pc *ProjectCache) AddPackages(repo *repo.Repo, pkgMap map[string]interfaces.PackageInterface) {
54+
cacheName := pc.getPackagesFile(repo)
55+
var dirList []string
56+
57+
for _, v := range pkgMap {
58+
dirList = append(dirList, v.BasePath())
59+
}
60+
61+
f, err := os.Create(cacheName)
62+
if err != nil {
63+
util.OneTimeWarning("Failed to create cache file for \"%s\"", repo.Name())
64+
}
65+
66+
defer f.Close()
67+
68+
enc := gob.NewEncoder(f)
69+
err = enc.Encode(dirList)
70+
if err != nil {
71+
util.OneTimeWarning("Failed to update cache file for \"%s\"", repo.Name())
72+
}
73+
}
74+
75+
func (pc *ProjectCache) GetPackagesDirs(repo *repo.Repo) []string {
76+
cacheName := pc.getPackagesFile(repo)
77+
var dirList []string
78+
79+
f, err := os.Open(cacheName)
80+
if err != nil {
81+
//util.OneTimeWarning("Failed to open cache file for \"%s\"\n", repo.Name())
82+
return nil
83+
}
84+
85+
defer f.Close()
86+
87+
enc := gob.NewDecoder(f)
88+
err = enc.Decode(&dirList)
89+
if err != nil {
90+
util.OneTimeWarning("Failed to read cache for \"%s\"", repo.Name())
91+
return nil
92+
}
93+
94+
return dirList
95+
}

newt/pkg/localpackage.go

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -449,8 +449,34 @@ func LocalPackageSpecialName(dirName string) bool {
449449
return ok
450450
}
451451

452+
func ReadPackage(repo *repo.Repo, pkgMap map[string]interfaces.PackageInterface,
453+
pkgPath string) ([]string, error) {
454+
455+
var warnings []string
456+
457+
pkg, err := LoadLocalPackage(repo, pkgPath)
458+
if err != nil {
459+
warnings = append(warnings, err.Error())
460+
return warnings, nil
461+
}
462+
463+
if oldPkg, ok := pkgMap[pkg.Name()]; ok {
464+
oldlPkg := oldPkg.(*LocalPackage)
465+
warnings = append(warnings,
466+
fmt.Sprintf("Multiple packages with same pkg.name=%s "+
467+
"in repo %s; path1=%s path2=%s", oldlPkg.Name(), repo.Name(),
468+
oldlPkg.BasePath(), pkg.BasePath()))
469+
470+
return warnings, nil
471+
}
472+
473+
pkgMap[pkg.Name()] = pkg
474+
475+
return warnings, nil
476+
}
477+
452478
func ReadLocalPackageRecursive(repo *repo.Repo,
453-
pkgList map[string]interfaces.PackageInterface, basePath string,
479+
pkgMap map[string]interfaces.PackageInterface, basePath string,
454480
pkgName string, searchedMap map[string]struct{}) ([]string, error) {
455481

456482
var warnings []string
@@ -465,7 +491,7 @@ func ReadLocalPackageRecursive(repo *repo.Repo,
465491
continue
466492
}
467493

468-
subWarnings, err := ReadLocalPackageRecursive(repo, pkgList,
494+
subWarnings, err := ReadLocalPackageRecursive(repo, pkgMap,
469495
basePath, filepath.Join(pkgName, name), searchedMap)
470496
warnings = append(warnings, subWarnings...)
471497
if err != nil {
@@ -477,39 +503,21 @@ func ReadLocalPackageRecursive(repo *repo.Repo,
477503
return warnings, nil
478504
}
479505

480-
pkg, err := LoadLocalPackage(repo, filepath.Join(basePath, pkgName))
481-
if err != nil {
482-
warnings = append(warnings, err.Error())
483-
return warnings, nil
484-
}
506+
var subWarnings []string
507+
subWarnings, err = ReadPackage(repo, pkgMap, filepath.Join(basePath, pkgName))
508+
warnings = append(warnings, subWarnings...)
485509

486-
if oldPkg, ok := pkgList[pkg.Name()]; ok {
487-
oldlPkg := oldPkg.(*LocalPackage)
488-
warnings = append(warnings,
489-
fmt.Sprintf("Multiple packages with same pkg.name=%s "+
490-
"in repo %s; path1=%s path2=%s", oldlPkg.Name(), repo.Name(),
491-
oldlPkg.BasePath(), pkg.BasePath()))
492-
493-
return warnings, nil
494-
}
495-
496-
pkgList[pkg.Name()] = pkg
497-
498-
return warnings, nil
510+
return warnings, err
499511
}
500512

501-
func ReadLocalPackages(repo *repo.Repo, basePath string) (
502-
*map[string]interfaces.PackageInterface, []string, error) {
503-
504-
pkgMap := &map[string]interfaces.PackageInterface{}
505-
513+
func ReadLocalPackages(repo *repo.Repo, pkgMap map[string]interfaces.PackageInterface, basePath string) ([]string, error) {
506514
// Keep track of which directories we have traversed. Prevent infinite
507515
// loops caused by symlink cycles by not inspecting the same directory
508516
// twice.
509517
searchedMap := map[string]struct{}{}
510518

511-
warnings, err := ReadLocalPackageRecursive(repo, *pkgMap,
519+
warnings, err := ReadLocalPackageRecursive(repo, pkgMap,
512520
basePath, "", searchedMap)
513521

514-
return pkgMap, warnings, err
522+
return warnings, err
515523
}

newt/project/project.go

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ package project
2121

2222
import (
2323
"fmt"
24+
"mynewt.apache.org/newt/newt/cache"
2425
"os"
2526
"path"
2627
"path/filepath"
@@ -57,6 +58,8 @@ type Project struct {
5758
// Base path of the project
5859
BasePath string
5960

61+
cache *cache.ProjectCache
62+
6063
packages interfaces.PackageList
6164

6265
// Contains all the repos that form this project. Each repo is in one of
@@ -634,6 +637,11 @@ func (proj *Project) Init(dir string, download bool) error {
634637
return err
635638
}
636639

640+
proj.cache = cache.InitCache(proj.BasePath)
641+
if proj.cache == nil {
642+
util.OneTimeWarning("Failed to initialize cache")
643+
}
644+
637645
return nil
638646
}
639647

@@ -741,12 +749,36 @@ func (proj *Project) loadPackageList() error {
741749
// packages / store them in the project package list.
742750
repos := proj.Repos()
743751
for name, repo := range repos {
744-
list, warnings, err := pkg.ReadLocalPackages(repo, repo.Path())
745-
if err == nil {
746-
proj.packages[name] = list
752+
pkgMap := &map[string]interfaces.PackageInterface{}
753+
754+
var dirList []string
755+
756+
if proj.cache != nil {
757+
dirList = proj.cache.GetPackagesDirs(repo)
747758
}
748759

749-
proj.warnings = append(proj.warnings, warnings...)
760+
if proj.cache != nil && dirList != nil {
761+
fmt.Printf("Reading packages for \"%s\" from cache\n", repo.Name())
762+
for _, pkgPath := range dirList {
763+
warnings, err := pkg.ReadPackage(repo, *pkgMap, pkgPath)
764+
if err == nil {
765+
proj.packages[name] = pkgMap
766+
}
767+
768+
proj.warnings = append(proj.warnings, warnings...)
769+
}
770+
} else {
771+
warnings, err := pkg.ReadLocalPackages(repo, *pkgMap, repo.Path())
772+
if err == nil {
773+
proj.packages[name] = pkgMap
774+
}
775+
776+
if proj.cache != nil {
777+
proj.cache.AddPackages(repo, *pkgMap)
778+
}
779+
780+
proj.warnings = append(proj.warnings, warnings...)
781+
}
750782
}
751783

752784
return nil

0 commit comments

Comments
 (0)