diff options
| author | Michael Vogt <michael.vogt@gmail.com> | 2018-02-01 09:41:06 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-02-01 09:41:06 +0100 |
| commit | ac14cf92398883d7558589d97ae815d9df86d998 (patch) | |
| tree | b04c7342b501595ca7cf5c4da1ba6163815f623a /advisor | |
| parent | b6e6ebb4b106243507b232f2059bdec5f7046f3b (diff) | |
| parent | f045cbda14a614821b279a94f37dfc3af212bcab (diff) | |
Merge pull request #4459 from mvo5/snap-advise-snap
snap: add support for `snap advise-snap pkgName`
Diffstat (limited to 'advisor')
| -rw-r--r-- | advisor/backend.go | 69 | ||||
| -rw-r--r-- | advisor/cmdfinder.go | 19 | ||||
| -rw-r--r-- | advisor/cmdfinder_test.go | 8 | ||||
| -rw-r--r-- | advisor/finder.go | 36 | ||||
| -rw-r--r-- | advisor/pkgfinder.go | 35 |
5 files changed, 132 insertions, 35 deletions
diff --git a/advisor/backend.go b/advisor/backend.go index 8856b5a7a3..6166513b18 100644 --- a/advisor/backend.go +++ b/advisor/backend.go @@ -28,18 +28,22 @@ import ( "github.com/snapcore/snapd/dirs" ) -var cmdBucketKey = []byte("Commands") +var ( + cmdBucketKey = []byte("Commands") + pkgBucketKey = []byte("Snaps") +) type writer struct { - db *bolt.DB - tx *bolt.Tx - bucket *bolt.Bucket + db *bolt.DB + tx *bolt.Tx + cmdBucket *bolt.Bucket + pkgBucket *bolt.Bucket } type CommandDB interface { // AddSnap adds the entries for commands pointing to the given // snap name to the commands database. - AddSnap(snapName string, commands []string) error + AddSnap(snapName, summary string, commands []string) error // Commit persist the changes, and closes the database. If the // database has already been committed/rollbacked, does nothing. Commit() error @@ -64,12 +68,23 @@ func Create() (CommandDB, error) { t.tx, err = t.db.Begin(true) if err == nil { - err = t.tx.DeleteBucket(cmdBucketKey) + err := t.tx.DeleteBucket(cmdBucketKey) if err == nil || err == bolt.ErrBucketNotFound { - t.bucket, err = t.tx.CreateBucket(cmdBucketKey) + t.cmdBucket, err = t.tx.CreateBucket(cmdBucketKey) } if err != nil { t.tx.Rollback() + + } + + if err == nil { + err := t.tx.DeleteBucket(pkgBucketKey) + if err == nil || err == bolt.ErrBucketNotFound { + t.pkgBucket, err = t.tx.CreateBucket(pkgBucketKey) + } + if err != nil { + t.tx.Rollback() + } } } @@ -81,22 +96,26 @@ func Create() (CommandDB, error) { return t, nil } -func (t *writer) AddSnap(snapName string, commands []string) error { +func (t *writer) AddSnap(snapName, summary string, commands []string) error { bname := []byte(snapName) for _, cmd := range commands { bcmd := []byte(cmd) - row := t.bucket.Get(bcmd) + row := t.cmdBucket.Get(bcmd) if row == nil { row = bname } else { row = append(append(row, ','), bname...) } - if err := t.bucket.Put(bcmd, row); err != nil { + if err := t.cmdBucket.Put(bcmd, row); err != nil { return err } } + if err := t.pkgBucket.Put([]byte(snapName), []byte(summary)); err != nil { + return err + } + return nil } @@ -111,7 +130,8 @@ func (t *writer) Rollback() error { func (t *writer) done(commit bool) error { var e1, e2 error - t.bucket = nil + t.cmdBucket = nil + t.pkgBucket = nil if t.tx != nil { if commit { e1 = t.tx.Commit() @@ -130,8 +150,9 @@ func (t *writer) done(commit bool) error { return e1 } -// Dump returns the whole database as a map. For use in testing and debugging. -func Dump() (map[string][]string, error) { +// DumpCommands returns the whole database as a map. For use in +// testing and debugging. +func DumpCommands() (map[string][]string, error) { db, err := bolt.Open(dirs.SnapCommandsDB, 0600, &bolt.Options{ ReadOnly: true, Timeout: 1 * time.Second, @@ -178,7 +199,7 @@ func Open() (Finder, error) { return &boltFinder{*db}, nil } -func (f *boltFinder) Find(command string) ([]Command, error) { +func (f *boltFinder) FindCommand(command string) ([]Command, error) { tx, err := f.Begin(false) if err != nil { return nil, err @@ -206,3 +227,23 @@ func (f *boltFinder) Find(command string) ([]Command, error) { return cmds, nil } + +func (f *boltFinder) FindPackage(pkgName string) (*Package, error) { + tx, err := f.Begin(false) + if err != nil { + return nil, err + } + defer tx.Rollback() + + b := tx.Bucket(pkgBucketKey) + if b == nil { + return nil, nil + } + + bsummary := b.Get([]byte(pkgName)) + if bsummary == nil { + return nil, nil + } + + return &Package{Snap: pkgName, Summary: string(bsummary)}, nil +} diff --git a/advisor/cmdfinder.go b/advisor/cmdfinder.go index 0960dfda08..15d50eb388 100644 --- a/advisor/cmdfinder.go +++ b/advisor/cmdfinder.go @@ -24,8 +24,6 @@ type Command struct { Command string } -var newFinder = Open - func FindCommand(command string) ([]Command, error) { finder, err := newFinder() if err != nil { @@ -33,7 +31,7 @@ func FindCommand(command string) ([]Command, error) { } defer finder.Close() - return finder.Find(command) + return finder.FindCommand(command) } const ( @@ -88,7 +86,7 @@ func FindMisspelledCommand(command string) ([]Command, error) { alternatives := make([]Command, 0, 32) for _, w := range similarWords(command) { - res, err := finder.Find(w) + res, err := finder.FindCommand(w) if err != nil { return nil, err } @@ -99,16 +97,3 @@ func FindMisspelledCommand(command string) ([]Command, error) { return alternatives, nil } - -type Finder interface { - Find(command string) ([]Command, error) - Close() error -} - -func ReplaceCommandsFinder(constructor func() (Finder, error)) (restore func()) { - old := newFinder - newFinder = constructor - return func() { - newFinder = old - } -} diff --git a/advisor/cmdfinder_test.go b/advisor/cmdfinder_test.go index c84c918615..da8c1028c1 100644 --- a/advisor/cmdfinder_test.go +++ b/advisor/cmdfinder_test.go @@ -44,8 +44,8 @@ func (s *cmdfinderSuite) SetUpTest(c *C) { db, err := advisor.Create() c.Assert(err, IsNil) - c.Assert(db.AddSnap("foo", []string{"foo", "meh"}), IsNil) - c.Assert(db.AddSnap("bar", []string{"bar", "meh"}), IsNil) + c.Assert(db.AddSnap("foo", "foo summary", []string{"foo", "meh"}), IsNil) + c.Assert(db.AddSnap("bar", "bar summary", []string{"bar", "meh"}), IsNil) c.Assert(db.Commit(), IsNil) } @@ -125,8 +125,8 @@ func (s *cmdfinderSuite) TestFindMisspelledCommandMiss(c *C) { c.Check(cmds, HasLen, 0) } -func (s *cmdfinderSuite) TestDump(c *C) { - cmds, err := advisor.Dump() +func (s *cmdfinderSuite) TestDumpCommands(c *C) { + cmds, err := advisor.DumpCommands() c.Assert(err, IsNil) c.Check(cmds, DeepEquals, map[string][]string{ "foo": {"foo"}, diff --git a/advisor/finder.go b/advisor/finder.go new file mode 100644 index 0000000000..ca3b9982fe --- /dev/null +++ b/advisor/finder.go @@ -0,0 +1,36 @@ +// -*- Mode: Go; indent-tabs-mode: t -*- + +/* + * Copyright (C) 2018 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +package advisor + +var newFinder = Open + +type Finder interface { + FindCommand(command string) ([]Command, error) + FindPackage(pkgName string) (*Package, error) + Close() error +} + +func ReplaceCommandsFinder(constructor func() (Finder, error)) (restore func()) { + old := newFinder + newFinder = constructor + return func() { + newFinder = old + } +} diff --git a/advisor/pkgfinder.go b/advisor/pkgfinder.go new file mode 100644 index 0000000000..43dd143203 --- /dev/null +++ b/advisor/pkgfinder.go @@ -0,0 +1,35 @@ +// -*- Mode: Go; indent-tabs-mode: t -*- + +/* + * Copyright (C) 2018 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +package advisor + +type Package struct { + Snap string + Summary string +} + +func FindPackage(pkgName string) (*Package, error) { + finder, err := newFinder() + if err != nil { + return nil, err + } + defer finder.Close() + + return finder.FindPackage(pkgName) +} |
