Skip to content

Commit

Permalink
feat(published): datasets now have a publish flag
Browse files Browse the repository at this point in the history
  • Loading branch information
b5 committed Oct 29, 2018
1 parent 5580e4e commit 84019b7
Show file tree
Hide file tree
Showing 14 changed files with 249 additions and 16 deletions.
7 changes: 7 additions & 0 deletions actions/dataset.go
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,13 @@ func AddDataset(node *p2p.QriNode, ref *repo.DatasetRef) (err error) {
return
}

// SetPublishStatus configures the publish status
func SetPublishStatus(node *p2p.QriNode, ref *repo.DatasetRef) (err error) {
// currently we're just passing this call off to the base package,
// in the near future we'll start publishing to registries here
return base.SetPublishStatus(node.Repo, ref)
}

// RenameDataset alters a dataset name
func RenameDataset(node *p2p.QriNode, current, new *repo.DatasetRef) (err error) {
r := node.Repo
Expand Down
4 changes: 2 additions & 2 deletions actions/list_datasets.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

// ListDatasets lists a peer's datasets
func ListDatasets(node *p2p.QriNode, ds *repo.DatasetRef, limit, offset int, RPC bool) (res []repo.DatasetRef, err error) {
func ListDatasets(node *p2p.QriNode, ds *repo.DatasetRef, limit, offset int, RPC, publishedOnly bool) (res []repo.DatasetRef, err error) {
r := node.Repo
pro, err := r.Profile()
if err != nil {
Expand Down Expand Up @@ -71,5 +71,5 @@ func ListDatasets(node *p2p.QriNode, ds *repo.DatasetRef, limit, offset int, RPC
return
}

return base.ListDatasets(node.Repo, limit, offset, RPC)
return base.ListDatasets(node.Repo, limit, offset, RPC, publishedOnly)
}
2 changes: 1 addition & 1 deletion actions/list_datasets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ func TestListDatasets(t *testing.T) {
node := newTestNode(t)
addCitiesDataset(t, node)

res, err := ListDatasets(node, &repo.DatasetRef{Peername: "me"}, 1, 0, false)
res, err := ListDatasets(node, &repo.DatasetRef{Peername: "me"}, 1, 0, false, false)
if err != nil {
t.Error(err.Error())
}
Expand Down
14 changes: 13 additions & 1 deletion base/datasets.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,26 @@ import (
)

// ListDatasets lists datasets from a repo
func ListDatasets(r repo.Repo, limit, offset int, RPC bool) (res []repo.DatasetRef, err error) {
func ListDatasets(r repo.Repo, limit, offset int, RPC, publishedOnly bool) (res []repo.DatasetRef, err error) {
store := r.Store()
res, err = r.References(limit, offset)
if err != nil {
log.Debug(err.Error())
return nil, fmt.Errorf("error getting dataset list: %s", err.Error())
}

if publishedOnly {
pub := make([]repo.DatasetRef, len(res))
i := 0
for _, ref := range res {
if ref.Published {
pub[i] = ref
i++
}
}
res = pub[:i]
}

renames := repo.NewNeedPeernameRenames()
for i, ref := range res {
// May need to change peername.
Expand Down
28 changes: 25 additions & 3 deletions base/datasets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,36 @@ import (

func TestListDatasets(t *testing.T) {
r := newTestRepo(t)
addCitiesDataset(t, r)
ref := addCitiesDataset(t, r)

res, err := ListDatasets(r, 1, 0, false)
res, err := ListDatasets(r, 1, 0, false, false)
if err != nil {
t.Error(err.Error())
}

if len(res) != 1 {
t.Error("expected one dataset response")
}

res, err = ListDatasets(r, 1, 0, false, true)
if err != nil {
t.Error(err.Error())
}

if len(res) != 0 {
t.Error("expected no published datasets")
}

ref.Published = true
if err := SetPublishStatus(r, &ref); err != nil {
t.Fatal(err)
}

res, err = ListDatasets(r, 1, 0, false, true)
if err != nil {
t.Error(err.Error())
}

if len(res) != 1 {
t.Error("expected one published dataset response")
}
}
30 changes: 30 additions & 0 deletions base/ref.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package base

import (
"fmt"

"github.com/qri-io/qri/repo"
)

// InLocalNamespace checks if a dataset ref is local, assumes the reference is already canonicalized
func InLocalNamespace(r repo.Repo, ref *repo.DatasetRef) bool {
p, err := r.Profile()
if err != nil {
return false
}

return p.ID == ref.ProfileID
}

// SetPublishStatus updates the Published field of a dataset ref
func SetPublishStatus(r repo.Repo, ref *repo.DatasetRef) error {
if err := repo.CanonicalizeDatasetRef(r, ref); err != nil {
return err
}

if !InLocalNamespace(r, ref) {
return fmt.Errorf("can't publish datsets that are not in your namespace")
}

return r.PutRef(*ref)
}
73 changes: 73 additions & 0 deletions base/ref_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package base

import (
"testing"

"github.com/qri-io/qri/repo"
"github.com/qri-io/qri/repo/profile"
)

func TestInLocalNamespace(t *testing.T) {
r := newTestRepo(t)
reff := addCitiesDataset(t, r)
ref := &reff

if !InLocalNamespace(r, ref) {
t.Errorf("expected %s true", ref.String())
}

ref = &repo.DatasetRef{}
if InLocalNamespace(r, ref) {
t.Errorf("expected %s false", ref.String())
}

ref = &repo.DatasetRef{ProfileID: profile.ID("fake")}
if InLocalNamespace(r, ref) {
t.Errorf("expected %s false", ref.String())
}
}

func TestSetPublishStatus(t *testing.T) {
r := newTestRepo(t)
ref := addCitiesDataset(t, r)

ref.Published = true
if err := SetPublishStatus(r, &ref); err != nil {
t.Error(err)
}
res, err := r.GetRef(repo.DatasetRef{Peername: ref.Peername, Name: ref.Name})
if err != nil {
t.Fatal(err)
}
if res.Published != true {
t.Errorf("expected published to equal true: %s,%s", ref, res)
}

ref.Published = false
if err := SetPublishStatus(r, &ref); err != nil {
t.Error(err)
}
res, err = r.GetRef(repo.DatasetRef{Peername: ref.Peername, Name: ref.Name})
if err != nil {
t.Fatal(err)
}
if res.Published != false {
t.Errorf("expected published to equal false: %s,%s", ref, res)
}

if err := SetPublishStatus(r, &repo.DatasetRef{Name: "foo"}); err == nil {
t.Error("expected invalid reference to error")
}

outside := repo.MustParseDatasetRef("a/b@QmX1oSPMbzkhk33EutuadL4sqsivsRKmMx5hAnZL2mRAM1/ipfs/d")
if err := r.PutRef(outside); err != nil {
t.Fatal(err)
}

r.Profiles().PutProfile(&profile.Profile{ID: outside.ProfileID, Peername: outside.Peername})

outside.Published = true
if err := SetPublishStatus(r, &outside); err == nil {
t.Error("expected setting the publish status of a name outside peer's namespace to fail")
}
}
15 changes: 9 additions & 6 deletions cmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ must have ` + "`qri connect`" + ` running in a separate terminal window.`,
cmd.Flags().StringVarP(&o.Format, "format", "f", "", "set output format [json]")
cmd.Flags().IntVarP(&o.Limit, "limit", "l", 25, "limit results, default 25")
cmd.Flags().IntVarP(&o.Offset, "offset", "o", 0, "offset results, default 0")
cmd.Flags().BoolVarP(&o.Published, "published", "p", false, "list only published datasets")

return cmd
}
Expand All @@ -57,10 +58,11 @@ must have ` + "`qri connect`" + ` running in a separate terminal window.`,
type ListOptions struct {
ioes.IOStreams

Format string
Limit int
Offset int
Peername string
Format string
Limit int
Offset int
Peername string
Published bool

DatasetRequests *lib.DatasetRequests
}
Expand All @@ -79,8 +81,9 @@ func (o *ListOptions) Run() (err error) {
if o.Peername == "" {

p := &lib.ListParams{
Limit: o.Limit,
Offset: o.Offset,
Limit: o.Limit,
Offset: o.Offset,
Published: o.Published,
}
refs := []repo.DatasetRef{}
if err = o.DatasetRequests.List(p, &refs); err != nil {
Expand Down
75 changes: 75 additions & 0 deletions cmd/publish.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package cmd

import (
"github.com/qri-io/ioes"
"github.com/qri-io/qri/lib"
"github.com/qri-io/qri/repo"
"github.com/spf13/cobra"
)

// NewPublishCommand creates a `qri publish` subcommand for working with configured registries
func NewPublishCommand(f Factory, ioStreams ioes.IOStreams) *cobra.Command {
o := &PublishOptions{IOStreams: ioStreams}
cmd := &cobra.Command{
Use: "publish",
Short: "set dataset publicity",
Long: `Publish makes your dataset available to others. While online, peers that connect
to you can only see datasets and versions that you've published. Publishing a
dataset always makes all previous history entries available, and any updates
to a published dataset will be immideately visible to connected peers.
`,
Example: ` # publish a dataset
$ qri publish me/dataset
# publish a few datasets
$ qri publish me/dataset me/other_dataset
# unpublish a dataset
$ qri publish -d me/dataset`,
Annotations: map[string]string{
"group": "network",
},
RunE: func(cmd *cobra.Command, args []string) error {
if err := o.Complete(f, args); err != nil {
return err
}
return o.Run()
},
}

return cmd
}

// PublishOptions encapsulates state for the publish command
type PublishOptions struct {
ioes.IOStreams

Refs []string

DatasetRequests *lib.DatasetRequests
}

// Complete adds any missing configuration that can only be added just before calling Run
func (o *PublishOptions) Complete(f Factory, args []string) (err error) {
o.Refs = args
o.DatasetRequests, err = f.DatasetRequests()
return
}

// Run executes the publish command
func (o *PublishOptions) Run() error {
var res bool

for _, arg := range o.Refs {
ref, err := repo.ParseDatasetRef(arg)
if err != nil {
return err
}

if err = o.DatasetRequests.SetPublishStatus(&ref, &res); err != nil {
return err
}
printInfo(o.Out, "published dataset %s", ref)
}
return nil
}
1 change: 1 addition & 0 deletions cmd/publish_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package cmd
8 changes: 7 additions & 1 deletion lib/datasets.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (r *DatasetRequests) List(p *ListParams, res *[]repo.DatasetRef) error {
p.Offset = 0
}

replies, err := actions.ListDatasets(r.node, ds, p.Limit, p.Offset, p.RPC)
replies, err := actions.ListDatasets(r.node, ds, p.Limit, p.Offset, p.RPC, p.Published)

*res = replies
return err
Expand Down Expand Up @@ -162,6 +162,12 @@ func (r *DatasetRequests) Save(p *SaveParams, res *repo.DatasetRef) (err error)
return nil
}

// SetPublishStatus updates the pubilicity of a reference in the peer's namespace
func (r *DatasetRequests) SetPublishStatus(ref *repo.DatasetRef, res *bool) error {
res = &ref.Published
return actions.SetPublishStatus(r.node, ref)
}

// RenameParams defines parameters for Dataset renaming
type RenameParams struct {
Current, New repo.DatasetRef
Expand Down
2 changes: 2 additions & 0 deletions lib/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ type ListParams struct {
// RPC is a horrible hack while we work to replace the net/rpc package
// TODO - remove this
RPC bool
// Published only applies to listing datasets
Published bool
}

// NewListParams creates a ListParams from page & pagesize, pages are 1-indexed
Expand Down
2 changes: 1 addition & 1 deletion p2p/datasets.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (n *QriNode) handleDatasetsList(ws *WrappedStream, msg Message) (hangup boo
dlp.Limit = listMax
}

refs, err := base.ListDatasets(n.Repo, dlp.Limit, dlp.Offset, false)
refs, err := base.ListDatasets(n.Repo, dlp.Limit, dlp.Offset, false, true)
if err != nil {
log.Error(err)
return
Expand Down
4 changes: 3 additions & 1 deletion repo/mem_refstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ func (r *MemRefstore) PutRef(put DatasetRef) error {
return ErrPathRequired
}

for _, ref := range *r {
for i, ref := range *r {
if ref.Match(put) {
rs := *r
rs[i] = put
return nil
}
}
Expand Down

0 comments on commit 84019b7

Please sign in to comment.