Skip to content

Commit

Permalink
feat(lib.Datasets.Save): add force flag to skip empty-commit checking
Browse files Browse the repository at this point in the history
  • Loading branch information
b5 committed Feb 11, 2019
1 parent 1d9aa57 commit 6fd5b1f
Show file tree
Hide file tree
Showing 14 changed files with 74 additions and 37 deletions.
8 changes: 4 additions & 4 deletions actions/actions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import (
"testing"

"github.com/libp2p/go-libp2p-crypto"
"github.com/qri-io/qfs/cafs"
"github.com/qri-io/dataset/dstest"
"github.com/qri-io/qfs"
"github.com/qri-io/qfs/cafs"
"github.com/qri-io/qfs/httpfs"
"github.com/qri-io/qfs/localfs"
"github.com/qri-io/qfs/muxfs"
Expand Down Expand Up @@ -116,7 +116,7 @@ func addCitiesDataset(t *testing.T, node *p2p.QriNode) repo.DatasetRef {
t.Fatal(err.Error())
}

ref, err := SaveDataset(node, tc.Input, nil, nil, false, true, false)
ref, err := SaveDataset(node, tc.Input, nil, nil, false, true, false, false)
if err != nil {
t.Fatal(err.Error())
}
Expand All @@ -129,7 +129,7 @@ func addFlourinatedCompoundsDataset(t *testing.T, node *p2p.QriNode) repo.Datase
t.Fatal(err.Error())
}

ref, err := SaveDataset(node, tc.Input, nil, nil, false, true, false)
ref, err := SaveDataset(node, tc.Input, nil, nil, false, true, false, false)
if err != nil {
t.Fatal(err.Error())
}
Expand All @@ -145,7 +145,7 @@ func addNowTransformDataset(t *testing.T, node *p2p.QriNode) repo.DatasetRef {
// this was put here to satisfy qri-io/qri/actions.TestUpdateDatasetLocal
tc.Input.Peername = "peer"

ref, err := SaveDataset(node, tc.Input, nil, nil, false, true, false)
ref, err := SaveDataset(node, tc.Input, nil, nil, false, true, false, false)
if err != nil {
t.Fatal(err.Error())
}
Expand Down
4 changes: 2 additions & 2 deletions actions/dataset.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
)

// SaveDataset initializes a dataset from a dataset pointer and data file
func SaveDataset(node *p2p.QriNode, changes *dataset.Dataset, secrets map[string]string, scriptOut io.Writer, dryRun, pin, convertFormatToPrev bool) (ref repo.DatasetRef, err error) {
func SaveDataset(node *p2p.QriNode, changes *dataset.Dataset, secrets map[string]string, scriptOut io.Writer, dryRun, pin, convertFormatToPrev, force bool) (ref repo.DatasetRef, err error) {
var (
prevPath string
pro *profile.Profile
Expand Down Expand Up @@ -87,7 +87,7 @@ func SaveDataset(node *p2p.QriNode, changes *dataset.Dataset, secrets map[string
// let's make history, if it exists:
changes.PreviousPath = prevPath

return base.CreateDataset(r, node.LocalStreams, changes, prev, dryRun, pin)
return base.CreateDataset(r, node.LocalStreams, changes, prev, dryRun, pin, force)
}

// UpdateRemoteDataset brings a reference to the latest version, syncing to the
Expand Down
19 changes: 9 additions & 10 deletions actions/dataset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func TestUpdateRemoteDataset(t *testing.T) {
ds.SetBodyFile(qfs.NewMemfileBytes("body.json", []byte("[]")))

// run a local update to advance history
now0, err := SaveDataset(peers[0], ds, nil, nil, false, true, false)
now0, err := SaveDataset(peers[0], ds, nil, nil, false, true, false, false)
if err != nil {
t.Error(err)
}
Expand Down Expand Up @@ -120,7 +120,7 @@ func TestSaveDataset(t *testing.T) {
}
ds.SetBodyFile(qfs.NewMemfileBytes("body.json", []byte("[]")))

ref, err := SaveDataset(n, ds, nil, nil, true, false, false)
ref, err := SaveDataset(n, ds, nil, nil, true, false, false, false)
if err != nil {
t.Errorf("dry run error: %s", err.Error())
}
Expand All @@ -143,7 +143,7 @@ func TestSaveDataset(t *testing.T) {
ds.SetBodyFile(qfs.NewMemfileBytes("body.json", []byte("[]")))

// test save
ref, err = SaveDataset(n, ds, nil, nil, false, true, false)
ref, err = SaveDataset(n, ds, nil, nil, false, true, false, false)
if err != nil {
t.Error(err)
}
Expand Down Expand Up @@ -173,7 +173,7 @@ func TestSaveDataset(t *testing.T) {
ds.Transform.OpenScriptFile(nil)

// dryrun should work
ref, err = SaveDataset(n, ds, secrets, nil, true, false, false)
ref, err = SaveDataset(n, ds, secrets, nil, true, false, false, false)
if err != nil {
t.Fatal(err)
}
Expand All @@ -200,7 +200,7 @@ func TestSaveDataset(t *testing.T) {
ds.Transform.OpenScriptFile(nil)

// test save with transform
ref, err = SaveDataset(n, ds, secrets, nil, false, true, false)
ref, err = SaveDataset(n, ds, secrets, nil, false, true, false, false)
if err != nil {
t.Fatal(err)
}
Expand All @@ -219,7 +219,7 @@ func TestSaveDataset(t *testing.T) {
},
}

ref, err = SaveDataset(n, ds, nil, nil, false, true, false)
ref, err = SaveDataset(n, ds, nil, nil, false, true, false, false)
if err != nil {
t.Error(err)
}
Expand Down Expand Up @@ -247,7 +247,7 @@ func TestSaveDataset(t *testing.T) {
t.Error(err)
}

ref, err = SaveDataset(n, ds, secrets, nil, false, true, false)
ref, err = SaveDataset(n, ds, secrets, nil, false, true, false, false)
if err != nil {
t.Error(err)
}
Expand All @@ -256,18 +256,17 @@ func TestSaveDataset(t *testing.T) {
}
}


func TestSaveDatasetWithoutStructureOrBody(t *testing.T) {
n := newTestNode(t)

ds := &dataset.Dataset{
Name: "no_st_or_body_test",
Name: "no_st_or_body_test",
Meta: &dataset.Meta{
Title: "test title",
},
}

_, err := SaveDataset(n, ds, nil, nil, false, false, false)
_, err := SaveDataset(n, ds, nil, nil, false, false, false, false)
expect := "creating a new dataset requires a structure or a body"
if err == nil || err.Error() != expect {
t.Errorf("expected error, but got %s", err.Error())
Expand Down
1 change: 1 addition & 0 deletions api/datasets.go
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,7 @@ func (h *DatasetHandlers) saveHandler(w http.ResponseWriter, r *http.Request) {
Private: r.FormValue("private") == "true",
DryRun: r.FormValue("dry_run") == "true",
ReturnBody: r.FormValue("return_body") == "true",
Force: r.FormValue("force") == "true",
ConvertFormatToPrev: true,
ScriptOutput: scriptOutput,
}
Expand Down
8 changes: 4 additions & 4 deletions base/base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import (
"testing"

"github.com/libp2p/go-libp2p-crypto"
"github.com/qri-io/qfs/cafs"
"github.com/qri-io/dataset/dstest"
"github.com/qri-io/ioes"
"github.com/qri-io/qfs"
"github.com/qri-io/qfs/cafs"
"github.com/qri-io/qri/repo"
"github.com/qri-io/qri/repo/profile"
"github.com/qri-io/registry/regserver/mock"
Expand Down Expand Up @@ -62,7 +62,7 @@ func addCitiesDataset(t *testing.T, r repo.Repo) repo.DatasetRef {
t.Fatal(err.Error())
}

ref, err := CreateDataset(r, ioes.NewDiscardIOStreams(), tc.Input, nil, false, true)
ref, err := CreateDataset(r, ioes.NewDiscardIOStreams(), tc.Input, nil, false, true, false)
if err != nil {
t.Fatal(err.Error())
}
Expand Down Expand Up @@ -94,7 +94,7 @@ func updateCitiesDataset(t *testing.T, r repo.Repo) repo.DatasetRef {
tc.Input.PreviousPath = ""
}()

ref, err = CreateDataset(r, ioes.NewDiscardIOStreams(), tc.Input, nil, false, true)
ref, err = CreateDataset(r, ioes.NewDiscardIOStreams(), tc.Input, nil, false, true, false)
if err != nil {
t.Fatal(err.Error())
}
Expand All @@ -107,7 +107,7 @@ func addFlourinatedCompoundsDataset(t *testing.T, r repo.Repo) repo.DatasetRef {
t.Fatal(err.Error())
}

ref, err := CreateDataset(r, ioes.NewDiscardIOStreams(), tc.Input, nil, false, true)
ref, err := CreateDataset(r, ioes.NewDiscardIOStreams(), tc.Input, nil, false, true, false)
if err != nil {
t.Fatal(err.Error())
}
Expand Down
4 changes: 2 additions & 2 deletions base/dataset.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func ListDatasets(r repo.Repo, limit, offset int, RPC, publishedOnly bool) (res
// CreateDataset uses dsfs to add a dataset to a repo's store, updating all
// references within the repo if successful. CreateDataset is a lower-level
// component of github.com/qri-io/qri/actions.CreateDataset
func CreateDataset(r repo.Repo, streams ioes.IOStreams, ds, dsPrev *dataset.Dataset, dryRun, pin bool) (ref repo.DatasetRef, err error) {
func CreateDataset(r repo.Repo, streams ioes.IOStreams, ds, dsPrev *dataset.Dataset, dryRun, pin, force bool) (ref repo.DatasetRef, err error) {
var (
pro *profile.Profile
path string
Expand All @@ -124,7 +124,7 @@ func CreateDataset(r repo.Repo, streams ioes.IOStreams, ds, dsPrev *dataset.Data
return
}

if path, err = dsfs.CreateDataset(r.Store(), ds, dsPrev, r.PrivateKey(), pin); err != nil {
if path, err = dsfs.CreateDataset(r.Store(), ds, dsPrev, r.PrivateKey(), pin, force); err != nil {
return
}
if ds.PreviousPath != "" && ds.PreviousPath != "/" {
Expand Down
21 changes: 17 additions & 4 deletions base/dataset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,11 @@ func TestCreateDataset(t *testing.T) {
}
ds.SetBodyFile(qfs.NewMemfileBytes("body.json", []byte("[]")))

if _, err := CreateDataset(r, streams, &dataset.Dataset{}, &dataset.Dataset{}, false, true); err == nil {
if _, err := CreateDataset(r, streams, &dataset.Dataset{}, &dataset.Dataset{}, false, true, false); err == nil {
t.Error("expected bad dataset to error")
}

ref, err := CreateDataset(r, streams, ds, &dataset.Dataset{}, false, true)
ref, err := CreateDataset(r, streams, ds, &dataset.Dataset{}, false, true, false)
if err != nil {
t.Fatal(err.Error())
}
Expand All @@ -96,7 +96,7 @@ func TestCreateDataset(t *testing.T) {

prev := ref.Dataset

ref, err = CreateDataset(r, streams, ds, prev, false, true)
ref, err = CreateDataset(r, streams, ds, prev, false, true, false)
if err != nil {
t.Fatal(err.Error())
}
Expand All @@ -107,6 +107,19 @@ func TestCreateDataset(t *testing.T) {
if len(refs) != 1 {
t.Errorf("ref length mismatch. expected 1, got: %d", len(refs))
}

ds.PreviousPath = ref.Path
ds.SetBodyFile(qfs.NewMemfileBytes("body.json", []byte("[]")))
prev = ref.Dataset

if ref, err = CreateDataset(r, streams, ds, prev, false, true, false); err == nil {
t.Error("expected unchanged dataset with no force flag to error")
}

ds.SetBodyFile(qfs.NewMemfileBytes("body.json", []byte("[]")))
if ref, err = CreateDataset(r, streams, ds, prev, false, true, true); err != nil {
t.Errorf("unexpected force-save error: %s", err)
}
}

func TestFetchDataset(t *testing.T) {
Expand Down Expand Up @@ -328,7 +341,7 @@ func TestDatasetPinning(t *testing.T) {
return
}

ref2, err := CreateDataset(r, streams, tc.Input, nil, false, false)
ref2, err := CreateDataset(r, streams, tc.Input, nil, false, false, false)
if err != nil {
t.Error(err.Error())
return
Expand Down
3 changes: 3 additions & 0 deletions cmd/save.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ commit message and title to the save.`,
cmd.Flags().StringSliceVar(&o.Secrets, "secrets", nil, "transform secrets as comma separated key,value,key,value,... sequence")
cmd.Flags().BoolVarP(&o.Publish, "publish", "p", false, "publish this dataset to the registry")
cmd.Flags().BoolVar(&o.DryRun, "dry-run", false, "simulate saving a dataset")
cmd.Flags().BoolVar(&o.Force, "force", false, "force a new commit, even if no changes are detected")
cmd.Flags().BoolVarP(&o.KeepFormat, "keep-format", "k", false, "convert incoming data to stored data format")

return cmd
Expand All @@ -86,6 +87,7 @@ type SaveOptions struct {
Publish bool
DryRun bool
KeepFormat bool
Force bool
Secrets []string

DatasetRequests *lib.DatasetRequests
Expand Down Expand Up @@ -145,6 +147,7 @@ func (o *SaveOptions) Run() (err error) {
DryRun: o.DryRun,
Recall: o.Recall,
ConvertFormatToPrev: o.KeepFormat,
Force: o.Force,
}

if o.Secrets != nil {
Expand Down
7 changes: 5 additions & 2 deletions lib/datasets.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ type SaveParams struct {
ConvertFormatToPrev bool
// string of references to recall before saving
Recall string
// force a new commit, even if no changes are detected
Force bool
// optional writer to have transform script record standard output to
// note: this won't work over RPC, only on local calls
ScriptOutput io.Writer
Expand Down Expand Up @@ -255,7 +257,8 @@ func (r *DatasetRequests) Save(p *SaveParams, res *repo.DatasetRef) (err error)
if ds.Name == "" {
return fmt.Errorf("name is required")
}
if ds.BodyPath == "" &&
if !p.Force &&
ds.BodyPath == "" &&
ds.Body == nil &&
ds.BodyBytes == nil &&
ds.Structure == nil &&
Expand All @@ -269,7 +272,7 @@ func (r *DatasetRequests) Save(p *SaveParams, res *repo.DatasetRef) (err error)
return
}

ref, err := actions.SaveDataset(r.node, ds, p.Secrets, p.ScriptOutput, p.DryRun, true, p.ConvertFormatToPrev)
ref, err := actions.SaveDataset(r.node, ds, p.Secrets, p.ScriptOutput, p.DryRun, true, p.ConvertFormatToPrev, p.Force)
if err != nil {
log.Debugf("create ds error: %s\n", err.Error())
return err
Expand Down
18 changes: 18 additions & 0 deletions lib/datasets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,24 @@ func TestDatasetRequestsSave(t *testing.T) {
}
}

func TestDatasetRequestsForceSave(t *testing.T) {
node := newTestQriNode(t)
ref := addCitiesDataset(t, node)
r := NewDatasetRequests(node, nil)

res := &repo.DatasetRef{}
if err := r.Save(&SaveParams{Dataset: &dataset.Dataset{Name: ref.Name, Peername: ref.Peername}}, res); err == nil {
t.Error("expected empty save without force flag to error")
}

if err := r.Save(&SaveParams{
Dataset: &dataset.Dataset{Name: ref.Name, Peername: ref.Peername},
Force: true,
}, res); err != nil {
t.Errorf("expected empty save with flag to not error. got: %s", err.Error())
}
}

func TestDatasetRequestsSaveRecall(t *testing.T) {
node := newTestQriNode(t)
ref := addNowTransformDataset(t, node)
Expand Down
6 changes: 3 additions & 3 deletions lib/lib_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import (
"testing"

crypto "github.com/libp2p/go-libp2p-crypto"
"github.com/qri-io/qfs/cafs"
"github.com/qri-io/dataset/dstest"
"github.com/qri-io/qfs"
"github.com/qri-io/qfs/cafs"
"github.com/qri-io/qri/actions"
"github.com/qri-io/qri/p2p"
"github.com/qri-io/qri/p2p/test"
Expand Down Expand Up @@ -79,7 +79,7 @@ func addCitiesDataset(t *testing.T, node *p2p.QriNode) repo.DatasetRef {
ds.Name = tc.Name
ds.BodyBytes = tc.Body

ref, err := actions.SaveDataset(node, ds, nil, nil, false, true, false)
ref, err := actions.SaveDataset(node, ds, nil, nil, false, true, false, false)
if err != nil {
t.Fatal(err.Error())
}
Expand All @@ -95,7 +95,7 @@ func addNowTransformDataset(t *testing.T, node *p2p.QriNode) repo.DatasetRef {
ds.Name = tc.Name
ds.Transform.ScriptPath = "testdata/now_tf/transform.star"

ref, err := actions.SaveDataset(node, ds, nil, nil, false, true, false)
ref, err := actions.SaveDataset(node, ds, nil, nil, false, true, false, false)
if err != nil {
t.Fatal(err.Error())
}
Expand Down
6 changes: 3 additions & 3 deletions p2p/log_diff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import (
"context"
"testing"

"github.com/qri-io/qfs/cafs"
"github.com/qri-io/dataset/dstest"
"github.com/qri-io/ioes"
"github.com/qri-io/qfs/cafs"
"github.com/qri-io/qri/base"
p2ptest "github.com/qri-io/qri/p2p/test"
)
Expand All @@ -31,7 +31,7 @@ func TestRequestLogDiff(t *testing.T) {
}

// add a dataset to peer 4
ref, err := base.CreateDataset(peers[4].Repo, streams, tc.Input, nil, false, true)
ref, err := base.CreateDataset(peers[4].Repo, streams, tc.Input, nil, false, true, false)
if err != nil {
t.Fatal(err)
}
Expand All @@ -50,7 +50,7 @@ func TestRequestLogDiff(t *testing.T) {
update.Name = tc.Name

// add an update on peer 4
ref2, err := base.CreateDataset(peers[4].Repo, streams, update, tc.Input, false, true)
ref2, err := base.CreateDataset(peers[4].Repo, streams, update, tc.Input, false, true, false)
if err != nil {
t.Fatal(err)
}
Expand Down
Loading

0 comments on commit 6fd5b1f

Please sign in to comment.