Add error handling for ForEach's.

This commit is contained in:
Andrey Smirnov
2013-12-26 16:58:04 +04:00
parent be7a1762ac
commit 218057ea48
9 changed files with 151 additions and 40 deletions
+2 -1
View File
@@ -18,8 +18,9 @@ func aptlyMirrorList(cmd *commander.Command, args []string) error {
fmt.Printf("List of mirrors:\n") fmt.Printf("List of mirrors:\n")
repoCollection := debian.NewRemoteRepoCollection(context.database) repoCollection := debian.NewRemoteRepoCollection(context.database)
repoCollection.ForEach(func(repo *debian.RemoteRepo) { repoCollection.ForEach(func(repo *debian.RemoteRepo) error {
fmt.Printf(" * %s\n", repo) fmt.Printf(" * %s\n", repo)
return nil
}) })
fmt.Printf("\nTo get more information about repository, run `aptly mirror show <name>`.\n") fmt.Printf("\nTo get more information about repository, run `aptly mirror show <name>`.\n")
+12 -4
View File
@@ -40,7 +40,7 @@ func aptlySnapshotCreate(cmd *commander.Command, args []string) error {
return fmt.Errorf("unable to add snapshot: %s", err) return fmt.Errorf("unable to add snapshot: %s", err)
} }
fmt.Printf("\nSnapshot %s successfully created.\nYou can run 'aptly snapshot publish %s' to publish snapshot as Debian repository.\n", snapshot.Name, snapshot.Name) fmt.Printf("\nSnapshot %s successfully created.\nYou can run 'aptly publish snapshot %s' to publish snapshot as Debian repository.\n", snapshot.Name, snapshot.Name)
return err return err
} }
@@ -55,8 +55,9 @@ func aptlySnapshotList(cmd *commander.Command, args []string) error {
fmt.Printf("List of snapshots:\n") fmt.Printf("List of snapshots:\n")
snapshotCollection := debian.NewSnapshotCollection(context.database) snapshotCollection := debian.NewSnapshotCollection(context.database)
snapshotCollection.ForEach(func(snapshot *debian.Snapshot) { snapshotCollection.ForEach(func(snapshot *debian.Snapshot) error {
fmt.Printf(" * %s\n", snapshot) fmt.Printf(" * %s\n", snapshot)
return nil
}) })
fmt.Printf("\nTo get more information about snapshot, run `aptly snapshot show <name>`.\n") fmt.Printf("\nTo get more information about snapshot, run `aptly snapshot show <name>`.\n")
@@ -91,10 +92,17 @@ func aptlySnapshotShow(cmd *commander.Command, args []string) error {
packageCollection := debian.NewPackageCollection(context.database) packageCollection := debian.NewPackageCollection(context.database)
snapshot.RefList().ForEach(func(key []byte) { err = snapshot.RefList().ForEach(func(key []byte) error {
p, _ := packageCollection.ByKey(key) p, err := packageCollection.ByKey(key)
if err != nil {
return err
}
fmt.Printf(" %s\n", p) fmt.Printf(" %s\n", p)
return nil
}) })
if err != nil {
return fmt.Errorf("unable to load packages: %s", err)
}
return err return err
} }
+14 -8
View File
@@ -35,12 +35,15 @@ func (l *PackageList) Add(p *Package) error {
} }
// ForEach calls handler for each package in list // ForEach calls handler for each package in list
// func (l *PackageList) ForEach(handler func(*Package) error) error {
// TODO: Error handling var err error
func (l *PackageList) ForEach(handler func(*Package)) {
for _, p := range l.packages { for _, p := range l.packages {
handler(p) err = handler(p)
if err != nil {
return err
}
} }
return err
} }
// Len returns number of packages in the list // Len returns number of packages in the list
@@ -105,10 +108,13 @@ func (l *PackageRefList) Decode(input []byte) error {
} }
// ForEach calls handler for each package ref in list // ForEach calls handler for each package ref in list
// func (l *PackageRefList) ForEach(handler func([]byte) error) error {
// TODO: Error handling var err error
func (l *PackageRefList) ForEach(handler func([]byte)) {
for _, p := range l.Refs { for _, p := range l.Refs {
handler(p) err = handler(p)
if err != nil {
return err
}
} }
return err
} }
+24 -2
View File
@@ -1,6 +1,7 @@
package debian package debian
import ( import (
"errors"
. "launchpad.net/gocheck" . "launchpad.net/gocheck"
) )
@@ -46,11 +47,22 @@ func (s *PackageListSuite) TestForeach(c *C) {
s.list.Add(s.p3) s.list.Add(s.p3)
Len := 0 Len := 0
s.list.ForEach(func(*Package) { err := s.list.ForEach(func(*Package) error {
Len++ Len++
return nil
}) })
c.Check(Len, Equals, 2) c.Check(Len, Equals, 2)
c.Check(err, IsNil)
e := errors.New("a")
err = s.list.ForEach(func(*Package) error {
return e
})
c.Check(err, Equals, e)
} }
func (s *PackageListSuite) TestNewPackageRefList(c *C) { func (s *PackageListSuite) TestNewPackageRefList(c *C) {
@@ -91,9 +103,19 @@ func (s *PackageListSuite) TestPackageRefListForeach(c *C) {
reflist := NewPackageRefListFromPackageList(s.list) reflist := NewPackageRefListFromPackageList(s.list)
Len := 0 Len := 0
reflist.ForEach(func([]byte) { err := reflist.ForEach(func([]byte) error {
Len++ Len++
return nil
}) })
c.Check(Len, Equals, 4) c.Check(Len, Equals, 4)
c.Check(err, IsNil)
e := errors.New("b")
err = reflist.ForEach(func([]byte) error {
return e
})
c.Check(err, Equals, e)
} }
+31 -9
View File
@@ -50,10 +50,16 @@ func (p *PublishedRepo) Publish(repo *Repository, packageCollection *PackageColl
// Load all packages // Load all packages
list := NewPackageList() list := NewPackageList()
p.snapshot.RefList().ForEach(func(key []byte) { err = p.snapshot.RefList().ForEach(func(key []byte) error {
pkg, _ := packageCollection.ByKey(key) pkg, err := packageCollection.ByKey(key)
list.Add(pkg) if err != nil {
return err
}
return list.Add(pkg)
}) })
if err != nil {
return fmt.Errorf("unable to load packages: %s", err)
}
if list.Len() == 0 { if list.Len() == 0 {
return fmt.Errorf("repository is empty, can't publish") return fmt.Errorf("repository is empty, can't publish")
@@ -61,10 +67,11 @@ func (p *PublishedRepo) Publish(repo *Repository, packageCollection *PackageColl
if p.Architectures == nil { if p.Architectures == nil {
p.Architectures = make([]string, 0, 10) p.Architectures = make([]string, 0, 10)
list.ForEach(func(pkg *Package) { list.ForEach(func(pkg *Package) error {
if pkg.Architecture != "all" && !utils.StrSliceHasItem(p.Architectures, pkg.Architecture) { if pkg.Architecture != "all" && !utils.StrSliceHasItem(p.Architectures, pkg.Architecture) {
p.Architectures = append(p.Architectures, pkg.Architecture) p.Architectures = append(p.Architectures, pkg.Architecture)
} }
return nil
}) })
} }
@@ -89,18 +96,33 @@ func (p *PublishedRepo) Publish(repo *Repository, packageCollection *PackageColl
bufWriter := bufio.NewWriter(packagesFile) bufWriter := bufio.NewWriter(packagesFile)
list.ForEach(func(pkg *Package) { err = list.ForEach(func(pkg *Package) error {
if pkg.Architecture == arch || pkg.Architecture == "all" { if pkg.Architecture == arch || pkg.Architecture == "all" {
path, _ := repo.LinkFromPool(p.Prefix, p.Component, pkg.Filename, pkg.HashMD5, pkg.Source) path, err := repo.LinkFromPool(p.Prefix, p.Component, pkg.Filename, pkg.HashMD5, pkg.Source)
if err != nil {
return err
}
// TODO: error handling
pkg.Filename = path pkg.Filename = path
pkg.Stanza().WriteTo(bufWriter)
bufWriter.WriteByte('\n') err = pkg.Stanza().WriteTo(bufWriter)
if err != nil {
return err
}
err = bufWriter.WriteByte('\n')
if err != nil {
return err
}
} }
return nil
}) })
if err != nil {
return fmt.Errorf("unable to creates process packages: %s", err)
}
err = bufWriter.Flush() err = bufWriter.Flush()
if err != nil { if err != nil {
return fmt.Errorf("unable to write Packages file: %s", err) return fmt.Errorf("unable to write Packages file: %s", err)
+36 -12
View File
@@ -176,31 +176,50 @@ func (repo *RemoteRepo) Download(d utils.Downloader, packageCollection *PackageC
} }
// Save package meta information to DB // Save package meta information to DB
list.ForEach(func(p *Package) { err := list.ForEach(func(p *Package) error {
packageCollection.Update(p) return packageCollection.Update(p)
}) })
if err != nil {
return fmt.Errorf("unable to save packages to db: %s", err)
}
// Download all package files // Download all package files
ch := make(chan error, list.Len()) ch := make(chan error, list.Len())
count := 0 count := 0
list.ForEach(func(p *Package) { err = list.ForEach(func(p *Package) error {
poolPath, err := packageRepo.PoolPath(p.Filename, p.HashMD5) poolPath, err := packageRepo.PoolPath(p.Filename, p.HashMD5)
if err == nil { if err != nil {
if !p.VerifyFile(poolPath) { return err
d.Download(repo.PackageURL(p.Filename).String(), poolPath, ch)
count++
}
} }
if !p.VerifyFile(poolPath) {
d.Download(repo.PackageURL(p.Filename).String(), poolPath, ch)
count++
}
return nil
}) })
if err != nil {
return fmt.Errorf("unable to download packages: %s", err)
}
errors := make([]string, 0)
// Wait for all downloads to finish // Wait for all downloads to finish
// TODO: report errors
for count > 0 { for count > 0 {
_ = <-ch err = <-ch
if err != nil {
errors = append(errors, err.Error())
}
count-- count--
} }
if len(errors) > 0 {
return fmt.Errorf("download errors: %s", strings.Join(errors, ", "))
}
repo.LastDownloadDate = time.Now() repo.LastDownloadDate = time.Now()
repo.packageRefs = NewPackageRefListFromPackageList(list) repo.packageRefs = NewPackageRefListFromPackageList(list)
@@ -331,8 +350,13 @@ func (collection *RemoteRepoCollection) ByUUID(uuid string) (*RemoteRepo, error)
} }
// ForEach runs method for each repository // ForEach runs method for each repository
func (collection *RemoteRepoCollection) ForEach(handler func(*RemoteRepo)) { func (collection *RemoteRepoCollection) ForEach(handler func(*RemoteRepo) error) error {
var err error
for _, r := range collection.list { for _, r := range collection.list {
handler(r) err = handler(r)
if err != nil {
return err
}
} }
return err
} }
+13 -1
View File
@@ -1,6 +1,7 @@
package debian package debian
import ( import (
"errors"
"github.com/smira/aptly/database" "github.com/smira/aptly/database"
"github.com/smira/aptly/utils" "github.com/smira/aptly/utils"
. "launchpad.net/gocheck" . "launchpad.net/gocheck"
@@ -187,8 +188,19 @@ func (s *RemoteRepoCollectionSuite) TestForEach(c *C) {
s.collection.Add(repo) s.collection.Add(repo)
count := 0 count := 0
s.collection.ForEach(func(*RemoteRepo) { count++ }) err := s.collection.ForEach(func(*RemoteRepo) error {
count++
return nil
})
c.Assert(count, Equals, 1) c.Assert(count, Equals, 1)
c.Assert(err, IsNil)
e := errors.New("c")
err = s.collection.ForEach(func(*RemoteRepo) error {
return e
})
c.Assert(err, Equals, e)
} }
const exampleReleaseFile = `Origin: LP-PPA-agenda-developers-daily const exampleReleaseFile = `Origin: LP-PPA-agenda-developers-daily
+7 -2
View File
@@ -162,8 +162,13 @@ func (collection *SnapshotCollection) ByName(name string) (*Snapshot, error) {
} }
// ForEach runs method for each snapshot // ForEach runs method for each snapshot
func (collection *SnapshotCollection) ForEach(handler func(*Snapshot)) { func (collection *SnapshotCollection) ForEach(handler func(*Snapshot) error) error {
var err error
for _, s := range collection.list { for _, s := range collection.list {
handler(s) err = handler(s)
if err != nil {
return err
}
} }
return err
} }
+12 -1
View File
@@ -1,6 +1,7 @@
package debian package debian
import ( import (
"errors"
"github.com/smira/aptly/database" "github.com/smira/aptly/database"
. "launchpad.net/gocheck" . "launchpad.net/gocheck"
) )
@@ -116,6 +117,16 @@ func (s *SnapshotCollectionSuite) TestForEach(c *C) {
s.collection.Add(s.snapshot2) s.collection.Add(s.snapshot2)
count := 0 count := 0
s.collection.ForEach(func(*Snapshot) { count++ }) err := s.collection.ForEach(func(*Snapshot) error {
count++
return nil
})
c.Assert(count, Equals, 2) c.Assert(count, Equals, 2)
c.Assert(err, IsNil)
e := errors.New("d")
err = s.collection.ForEach(func(*Snapshot) error {
return e
})
c.Assert(err, Equals, e)
} }