diff --git a/cmd/noms/noms_show.go b/cmd/noms/noms_show.go index 88d7368ef8..6281a2bf40 100644 --- a/cmd/noms/noms_show.go +++ b/cmd/noms/noms_show.go @@ -5,7 +5,9 @@ package main import ( + "bytes" "fmt" + "io" "os" "github.com/attic-labs/noms/cmd/util" @@ -19,17 +21,20 @@ import ( var nomsShow = &util.Command{ Run: runShow, - UsageLine: "show ", + UsageLine: "show [flags] ", Short: "Shows a serialization of a Noms object", Long: "See Spelling Objects at https://github.com/attic-labs/noms/blob/master/doc/spelling.md for details on the object argument.", Flags: setupShowFlags, Nargs: 1, } +var showRaw = false + func setupShowFlags() *flag.FlagSet { showFlagSet := flag.NewFlagSet("show", flag.ExitOnError) outputpager.RegisterOutputpagerFlags(showFlagSet) verbose.RegisterVerboseFlags(showFlagSet) + showFlagSet.BoolVar(&showRaw, "raw", false, "If true, dumps the raw binary version of the data") return showFlagSet } @@ -44,6 +49,14 @@ func runShow(args []string) int { return 0 } + if showRaw { + ch := types.EncodeValue(value, database) + buf := bytes.NewBuffer(ch.Data()) + _, err = io.Copy(os.Stdout, buf) + d.CheckError(err) + return 0 + } + pgr := outputpager.Start() defer pgr.Stop() diff --git a/cmd/noms/noms_show_test.go b/cmd/noms/noms_show_test.go index ba987b8b70..332134ae44 100644 --- a/cmd/noms/noms_show_test.go +++ b/cmd/noms/noms_show_test.go @@ -5,8 +5,10 @@ package main import ( + "fmt" "testing" + "github.com/attic-labs/noms/go/chunks" "github.com/attic-labs/noms/go/spec" "github.com/attic-labs/noms/go/types" "github.com/attic-labs/noms/go/util/clienttest" @@ -69,3 +71,51 @@ func (s *nomsShowTestSuite) TestNomsShow() { res, _ = s.MustRun(main, []string{"show", str}) test.EqualsIgnoreHashes(s.T(), res5, res) } + +func (s *nomsShowTestSuite) TestNomsShowNotFound() { + str := spec.CreateValueSpecString("ldb", s.LdbDir, "not-there") + stdout, stderr, err := s.Run(main, []string{"show", str}) + s.Equal("", stdout) + s.Equal(fmt.Sprintf("Object not found: %s\n", str), stderr) + s.Nil(err) +} + +func (s *nomsShowTestSuite) TestNomsShowRaw() { + datasetName := "showRaw" + str := spec.CreateValueSpecString("ldb", s.LdbDir, datasetName) + sp, err := spec.ForDataset(str) + s.NoError(err) + defer sp.Close() + + db := sp.GetDatabase() + + // Put a value into the db, get its raw serialization, then deserialize it and ensure it comes + // out to same thing. + test := func(in types.Value) { + r1 := db.WriteValue(in) + res, _ := s.MustRun(main, []string{"show", "--raw", + spec.CreateValueSpecString("ldb", s.LdbDir, "#"+r1.TargetHash().String())}) + ch := chunks.NewChunk([]byte(res)) + out := types.DecodeValue(ch, db) + s.True(out.Equals(in)) + } + + // Primitive value with no child chunks + test(types.String("hello")) + + // Ref (one child chunk) + test(db.WriteValue(types.Number(42))) + + // Prolly tree with multiple child chunks + items := make([]types.Value, 10000) + for i := 0; i < len(items); i++ { + items[i] = types.Number(i) + } + l := types.NewList(items...) + numChildChunks := 0 + l.WalkRefs(func(r types.Ref) { + numChildChunks++ + }) + s.True(numChildChunks > 0) + test(l) +}