Skip to content

Commit

Permalink
fix(stderr): write save diagnostic output to stderr
Browse files Browse the repository at this point in the history
  • Loading branch information
b5 committed Mar 14, 2019
1 parent 083a2f2 commit 3dac8b8
Show file tree
Hide file tree
Showing 10 changed files with 54 additions and 63 deletions.
38 changes: 2 additions & 36 deletions actions/body.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package actions

import (
"bytes"
"fmt"

"github.com/qri-io/dataset"
"github.com/qri-io/dataset/dsio"
"github.com/qri-io/qfs"
"github.com/qri-io/qri/base"
"github.com/qri-io/qri/p2p"
)

Expand All @@ -32,43 +30,11 @@ func GetBody(node *p2p.QriNode, ds *dataset.Dataset, format dataset.DataFormat,
}
st.Assign(ds.Structure, assign)

data, err = ConvertBodyFile(file, ds.Structure, st, limit, offset, all)
data, err = base.ConvertBodyFile(file, ds.Structure, st, limit, offset, all)
if err != nil {
log.Debug(err.Error())
return nil, err
}

return data, nil
}

// ConvertBodyFile takes an input file & structure, and converts a specified selection
// to the structure specified by out
func ConvertBodyFile(file qfs.File, in, out *dataset.Structure, limit, offset int, all bool) (data []byte, err error) {
buf := &bytes.Buffer{}

w, err := dsio.NewEntryWriter(out, buf)
if err != nil {
return
}

rr, err := dsio.NewEntryReader(in, file)
if err != nil {
err = fmt.Errorf("error allocating data reader: %s", err)
return
}

if !all {
rr = &dsio.PagedReader{
Reader: rr,
Limit: limit,
Offset: offset,
}
}
err = dsio.Copy(rr, w)

if err := w.Close(); err != nil {
return nil, fmt.Errorf("error closing row buffer: %s", err.Error())
}

return buf.Bytes(), nil
}
10 changes: 5 additions & 5 deletions actions/dataset.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func SaveDataset(node *p2p.QriNode, changes *dataset.Dataset, secrets map[string
}

if dryRun {
node.LocalStreams.Print("🏃🏽‍♀️ dry run\n")
node.LocalStreams.PrintErr("🏃🏽‍♀️ dry run\n")
// dry-runs store to an in-memory repo
r, err = repo.NewMemRepo(pro, cafs.NewMapstore(), node.Repo.Filesystem(), profile.NewMemStore(), nil)
if err != nil {
Expand All @@ -50,7 +50,7 @@ func SaveDataset(node *p2p.QriNode, changes *dataset.Dataset, secrets map[string
return
}
// changes.Transform.SetScriptFile(mutable.Transform.ScriptFile())
node.LocalStreams.Print("✅ transform complete\n")
node.LocalStreams.PrintErr("✅ transform complete\n")
}

if prevPath == "" && changes.BodyFile() == nil && changes.Structure == nil {
Expand Down Expand Up @@ -163,7 +163,7 @@ func AddDataset(node *p2p.QriNode, ref *repo.DatasetRef) (err error) {
res.Error = err
return
}
node.LocalStreams.Print("🗼 fetched from registry\n")
node.LocalStreams.PrintErr("🗼 fetched from registry\n")
if pinner, ok := node.Repo.Store().(cafs.Pinner); ok {
err := pinner.Pin(ref.Path, true)
res.Error = err
Expand Down Expand Up @@ -212,9 +212,9 @@ func AddDataset(node *p2p.QriNode, ref *repo.DatasetRef) (err error) {
// SetPublishStatus configures the publish status of a stored reference
func SetPublishStatus(node *p2p.QriNode, ref *repo.DatasetRef, published bool) (err error) {
if published {
node.LocalStreams.Print("📝 listing dataset for p2p discovery\n")
node.LocalStreams.PrintErr("📝 listing dataset for p2p discovery\n")
} else {
node.LocalStreams.Print("unlisting dataset from p2p discovery\n")
node.LocalStreams.PrintErr("unlisting dataset from p2p discovery\n")
}
return base.SetPublishStatus(node.Repo, ref, published)
}
Expand Down
12 changes: 6 additions & 6 deletions actions/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (

// Publish a dataset to a repo's specified registry
func Publish(node *p2p.QriNode, ref repo.DatasetRef) (err error) {
node.LocalStreams.Print("🗼 publishing dataset to registry\n")
node.LocalStreams.PrintErr("🗼 publishing dataset to registry\n")
r := node.Repo
cli, pub, ds, err := dsParams(r, &ref)
if err != nil {
Expand Down Expand Up @@ -84,18 +84,18 @@ func Pin(node *p2p.QriNode, ref repo.DatasetRef) (err error) {
return nil
}

node.LocalStreams.Print("✈️ generating dataset manifest\n")
node.LocalStreams.PrintErr("✈️ generating dataset manifest\n")
mfst, err := NewManifest(node, ref.Path)
if err != nil {
return err
}

node.LocalStreams.Print("🗼 syncing dataset graph to registry\n")
node.LocalStreams.PrintErr("🗼 syncing dataset graph to registry\n")
if err = reg.DsyncSend(context.Background(), ng, mfst); err != nil {
return err
}

node.LocalStreams.Print("📌 pinning dataset\n")
node.LocalStreams.PrintErr("📌 pinning dataset\n")
if err = reg.Pin(ref.Path, pk, nil); err != nil {
if err == registry.ErrPinsetNotSupported {
log.Info("this registry does not support pinning, dataset not pinned.")
Expand All @@ -104,13 +104,13 @@ func Pin(node *p2p.QriNode, ref repo.DatasetRef) (err error) {
}
}

node.LocalStreams.Print(" done\n")
node.LocalStreams.PrintErr(" done\n")
return nil
}

// Unpin reverses the pin process
func Unpin(node *p2p.QriNode, ref repo.DatasetRef) (err error) {
node.LocalStreams.Print("📌 unpinning dataset")
node.LocalStreams.PrintErr("📌 unpinning dataset")
r := node.Repo
reg := node.Repo.Registry()
if reg == nil {
Expand Down
Binary file modified api/testdata/api.snapshot
Binary file not shown.
2 changes: 1 addition & 1 deletion cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func Execute() {
root.SilenceErrors = true
// Execute the subcommand
if err := root.Execute(); err != nil {
printErr(os.Stdout, err)
printErr(os.Stderr, err)
os.Exit(1)
}
}
Expand Down
18 changes: 7 additions & 11 deletions cmd/save_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,11 @@ func TestSaveRun(t *testing.T) {

{"add viz", "me/movies", "testdata/movies/dataset_with_viz.json", "", "", "", false, false, "dataset saved: peer/movies@QmZePf5LeXow3RW5U1AgEiNbW46YnRGhZ7HPvm1UmPFPwt/map/Qmcmjcw1onuvWCvM2NZzqDztfp3djpCErcD2zSirmAw65p\nthis dataset has 1 validation errors\n", "", ""},

{"add transform", "me/movies", "testdata/movies/dataset_with_tf.json", "", "", "", false, false, "dataset saved: peer/movies@QmZePf5LeXow3RW5U1AgEiNbW46YnRGhZ7HPvm1UmPFPwt/map/QmYQxs2XcB6aFibKxJZtRHxW7ySbHjYS5TBFcWmr89RAYy\nthis dataset has 1 validation errors\n", "", ""},
{"add transform", "me/movies", "testdata/movies/dataset_with_tf.json", "", "", "", false, false, "dataset saved: peer/movies@QmZePf5LeXow3RW5U1AgEiNbW46YnRGhZ7HPvm1UmPFPwt/map/QmTMqfrua11V8AK3vMB9QeZcZtX5ZB1RNqAdapBWjn2615\nthis dataset has 1 validation errors\n", "", ""},
}

for _, c := range cases {
ioReset(in, out, errs)
dsr, err := f.DatasetRequests()
if err != nil {
t.Errorf("case \"%s\", error creating dataset request: %s", c.description, err)
Expand All @@ -181,28 +182,23 @@ func TestSaveRun(t *testing.T) {

err = opt.Run()
if (err == nil && c.err != "") || (err != nil && c.err != err.Error()) {
t.Errorf("case \"%s\", mismatched error. Expected: '%s', Got: '%v'", c.description, c.err, err)
ioReset(in, out, errs)
t.Errorf("case '%s', mismatched error. Expected: '%s', Got: '%v'", c.description, c.err, err)
continue
}

if libErr, ok := err.(lib.Error); ok {
if libErr.Message() != c.msg {
t.Errorf("case \"%s\", mismatched user-friendly message. Expected: '%s', Got: '%s'", c.description, c.msg, libErr.Message())
ioReset(in, out, errs)
t.Errorf("case '%s', mismatched user-friendly message. Expected: '%s', Got: '%s'", c.description, c.msg, libErr.Message())
continue
}
} else if c.msg != "" {
t.Errorf("case \"%s\", mismatched user-friendly message. Expected: '%s', Got: ''", c.description, c.msg)
ioReset(in, out, errs)
t.Errorf("case '%s', mismatched user-friendly message. Expected: '%s', Got: ''", c.description, c.msg)
continue
}

if c.expect != out.String() {
t.Errorf("case \"%s\", output mismatch. Expected: '%s', Got: '%s'", c.description, c.expect, out.String())
ioReset(in, out, errs)
if c.expect != errs.String() {
t.Errorf("case '%s', err output mismatch. Expected: '%s', Got: '%s'", c.description, c.expect, errs.String())
continue
}
ioReset(in, out, errs)
}
}
4 changes: 2 additions & 2 deletions config/migrate/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import (
// RunMigrations checks to see if any migrations runs them
func RunMigrations(streams ioes.IOStreams, cfg *config.Config) (migrated bool, err error) {
if cfg.Revision != config.CurrentConfigRevision {
streams.Print("migrating configuration...")
streams.PrintErr("migrating configuration...")
if err := ZeroToOne(cfg); err != nil {
return false, err
}
streams.Print("done!\n")
streams.PrintErr("done!\n")
return true, nil
}
return false, nil
Expand Down
29 changes: 29 additions & 0 deletions lib/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,14 @@ func ReadDatasetFile(path string) (ds *dataset.Dataset, err error) {
if err = yaml.Unmarshal(data, fields); err != nil {
return
}

// TODO (b5): temp hack to deal with terrible interaction with fill_struct,
// we should find a more robust solution to this, enforcing the assumption that all
// dataset documents use string keys
if sti, ok := fields["structure"].(map[interface{}]interface{}); ok {
fields["structure"] = toMapIface(sti)
}

err = fillDatasetOrComponent(fields, path, ds)

case ".json":
Expand Down Expand Up @@ -142,6 +150,27 @@ func ReadDatasetFile(path string) (ds *dataset.Dataset, err error) {
return
}

func toMapIface(i map[interface{}]interface{}) map[string]interface{} {
mapi := map[string]interface{}{}
for ikey, val := range i {
switch x := val.(type) {
case map[interface{}]interface{}:
val = toMapIface(x)
case []interface{}:
for i, v := range x {
if mapi, ok := v.(map[interface{}]interface{}); ok {
x[i] = toMapIface(mapi)
}
}
}

if key, ok := ikey.(string); ok {
mapi[key] = val
}
}
return mapi
}

func fillDatasetOrComponent(fields map[string]interface{}, path string, ds *dataset.Dataset) (err error) {
var fill interface{}
fill = ds
Expand Down
2 changes: 1 addition & 1 deletion lib/lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
var log = golog.Logger("lib")

// VersionNumber is the current version qri
const VersionNumber = "0.7.2-dev"
const VersionNumber = "0.7.2"

// Requests defines a set of library methods
type Requests interface {
Expand Down
2 changes: 1 addition & 1 deletion p2p/p2p.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const (
// QriProtocolID is the top level Protocol Identifier
QriProtocolID = protocol.ID("/qri")
// QriServiceTag tags the type & version of the qri service
QriServiceTag = "qri/0.7.2-dev"
QriServiceTag = "qri/0.7.2"
// default value to give qri peer connections in connmanager, one hunnit
qriSupportValue = 100
// qriSupportKey is the key we store the flag for qri support under in Peerstores and in ConnManager()
Expand Down

0 comments on commit 3dac8b8

Please sign in to comment.