func ExamplePartBag() { d, _ := ioutil.TempDir("", "test-xyzzy-") defer os.RemoveAll(d) dirs.SetRootDir(d) os.MkdirAll(filepath.Join(dirs.SnapDataDir, "foo.bar", "0.1"), 0755) os.MkdirAll(filepath.Join(dirs.SnapDataDir, "foo.bar", "0.2"), 0755) os.MkdirAll(filepath.Join(dirs.SnapDataDir, "foo.bar", "0.5"), 0755) os.MkdirAll(filepath.Join(dirs.SnapDataDir, "baz", "0.4"), 0755) os.MkdirAll(filepath.Join(dirs.SnapDataDir, "qux", "0.5"), 0755) bags := lightweight.AllPartBags() for _, k := range []string{"foo.bar", "baz"} { bag := bags[k] fmt.Printf("Found %d versions for %s, type %q: %s\n", len(bag.Versions), bag.QualifiedName(), bag.Type, bag.Versions) } // Output: // Found 3 versions for foo.bar, type "app": [0.5 0.2 0.1] // Found 1 versions for baz, type "framework": [0.4] }
// plural! func getSnapsInfo(c *Command, r *http.Request) Response { route := c.d.router.Get(snapCmd.Path) if route == nil { return InternalError("router can't find route for snaps") } lock, err := lockfile.Lock(dirs.SnapLockFile, true) if err != nil { return InternalError("unable to acquire lock: %v", err) } defer lock.Unlock() // TODO: Marshal incrementally leveraging json.RawMessage. results := make(map[string]map[string]interface{}) sources := make([]string, 0, 2) query := r.URL.Query() var includeStore, includeLocal bool if len(query["sources"]) > 0 { for _, v := range strings.Split(query["sources"][0], ",") { if v == "store" { includeStore = true } else if v == "local" { includeLocal = true } } } else { includeStore = true includeLocal = true } searchTerm := query.Get("q") var includeTypes []string if len(query["types"]) > 0 { includeTypes = strings.Split(query["types"][0], ",") } var bags map[string]*lightweight.PartBag if includeLocal { sources = append(sources, "local") bags = lightweight.AllPartBags() for _, v := range bags { m := v.Map(nil) name, _ := m["name"].(string) origin, _ := m["origin"].(string) resource := "no resource URL for this resource" url, err := route.URL("name", name, "origin", origin) if err == nil { resource = url.String() } fullname := name + "." + origin // strings.Contains(fullname, "") is true if !strings.Contains(fullname, searchTerm) { continue } results[fullname] = webify(m, resource) } } if includeStore { repo := newRemoteRepo() var found []snappy.Part // repo.Find("") finds all // // TODO: Instead of ignoring the error from Find: // * if there are no results, return an error response. // * If there are results at all (perhaps local), include a // warning in the response found, _ = repo.Find(searchTerm) sources = append(sources, "store") sort.Sort(byQN(found)) for _, part := range found { name := part.Name() origin := part.Origin() url, err := route.URL("name", name, "origin", origin) if err != nil { return InternalError("can't get route to details for %s.%s: %v", name, origin, err) } fullname := name + "." + origin qn := snappy.QualifiedName(part) results[fullname] = webify(bags[qn].Map(part), url.String()) } } // TODO: it should be possible to search on the "content" field on the store // with multiple values, see: // https://wiki.ubuntu.com/AppStore/Interfaces/ClickPackageIndex#Search if len(includeTypes) > 0 { for name, result := range results { if !resultHasType(result, includeTypes) { delete(results, name) } } } return SyncResponse(map[string]interface{}{ "snaps": results, "sources": sources, "paging": map[string]interface{}{ "pages": 1, "page": 1, "count": len(results), }, }) }
// plural! func getSnapsInfo(c *Command, r *http.Request) Response { route := c.d.router.Get(snapCmd.Path) if route == nil { return InternalError("router can't find route for snaps") } lock, err := lockfile.Lock(dirs.SnapLockFile, true) if err != nil { return InternalError("unable to acquire lock: %v", err) } defer lock.Unlock() // TODO: Marshal incrementally leveraging json.RawMessage. results := make(map[string]map[string]interface{}) sources := make([]string, 0, 2) query := r.URL.Query() var includeStore, includeLocal bool if len(query["sources"]) > 0 { for _, v := range strings.Split(query["sources"][0], ",") { if v == "store" { includeStore = true } else if v == "local" { includeLocal = true } } } else { includeStore = true includeLocal = true } var bags map[string]*lightweight.PartBag if includeLocal { sources = append(sources, "local") bags = lightweight.AllPartBags() for _, v := range bags { m := v.Map(nil) name, _ := m["name"].(string) origin, _ := m["origin"].(string) resource := "no resource URL for this resource" url, err := route.URL("name", name, "origin", origin) if err == nil { resource = url.String() } results[name+"."+origin] = webify(m, resource) } } if includeStore { // TODO: If there are no results (local or remote), report the error. If // there are results at all, inform that the result is partial. found, _ := newRemoteRepo().All() if len(found) > 0 { sources = append(sources, "store") } sort.Sort(byQN(found)) for _, part := range found { name := part.Name() origin := part.Origin() url, err := route.URL("name", name, "origin", origin) if err != nil { return InternalError("can't get route to details for %s.%s: %v", name, origin, err) } fullname := name + "." + origin qn := snappy.QualifiedName(part) results[fullname] = webify(bags[qn].Map(part), url.String()) } } return SyncResponse(map[string]interface{}{ "snaps": results, "sources": sources, "paging": map[string]interface{}{ "pages": 1, "page": 1, "count": len(results), }, }) }