-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactored how firecore tools
handles printing
#69
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,7 +30,7 @@ import ( | |
"github.com/streamingfast/dstore" | ||
firecore "github.com/streamingfast/firehose-core" | ||
"github.com/streamingfast/firehose-core/cmd/tools/check" | ||
"github.com/streamingfast/firehose-core/json" | ||
fcjson "github.com/streamingfast/firehose-core/json" | ||
fcproto "github.com/streamingfast/firehose-core/proto" | ||
"github.com/streamingfast/firehose-core/types" | ||
"go.uber.org/multierr" | ||
|
@@ -73,9 +73,7 @@ func NewToolsCompareBlocksCmd[B firecore.Block](chain *firecore.Chain[B]) *cobra | |
|
||
flags := cmd.PersistentFlags() | ||
flags.Bool("diff", false, "When activated, difference is displayed for each block with a difference") | ||
flags.String("bytes-encoding", "hex", "Encoding for bytes fields, either 'hex' or 'base58'") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here you replaced with the global |
||
flags.Bool("include-unknown-fields", false, "When activated, the 'unknown fields' in the protobuf message will also be compared. These would not generate any difference when unmarshalled with the current protobuf definition.") | ||
flags.StringSlice("proto-paths", []string{""}, "Paths to proto files to use for dynamic decoding of blocks") | ||
|
||
return cmd | ||
} | ||
|
@@ -363,16 +361,16 @@ func Compare(reference proto.Message, current proto.Message, includeUnknownField | |
|
||
//todo: check if there is a equals that do not compare unknown fields | ||
if !proto.Equal(reference, current) { | ||
var opts []json.MarshallerOption | ||
var opts []fcjson.MarshallerOption | ||
if !includeUnknownFields { | ||
opts = append(opts, json.WithoutUnknownFields()) | ||
opts = append(opts, fcjson.WithoutUnknownFields()) | ||
} | ||
|
||
if bytesEncoding == "base58" { | ||
opts = append(opts, json.WithBytesEncoderFunc(json.ToBase58)) | ||
if bytesEncoding != "" { | ||
opts = append(opts, fcjson.WithBytesEncoding(bytesEncoding)) | ||
} | ||
|
||
encoder := json.NewMarshaller(registry, opts...) | ||
encoder := fcjson.NewMarshaller(registry, opts...) | ||
|
||
referenceAsJSON, err := encoder.MarshalToString(reference) | ||
cli.NoError(err, "marshal JSON reference") | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
// Copyright 2021 dfuse Platform Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package print | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"strconv" | ||
"unsafe" | ||
|
||
"github.com/spf13/cobra" | ||
"github.com/streamingfast/cli/sflags" | ||
fcproto "github.com/streamingfast/firehose-core/proto" | ||
"google.golang.org/protobuf/reflect/protoreflect" | ||
) | ||
|
||
func GetOutputPrinter(cmd *cobra.Command, chainFileDescriptor protoreflect.FileDescriptor) (OutputPrinter, error) { | ||
printer := sflags.MustGetString(cmd, "output") | ||
if printer == "" { | ||
printer = "jsonl" | ||
} | ||
|
||
var protoPaths []string | ||
if sflags.FlagDefined(cmd, "proto-paths") { | ||
protoPaths = sflags.MustGetStringSlice(cmd, "proto-paths") | ||
} | ||
|
||
bytesEncoding := "hex" | ||
if sflags.FlagDefined(cmd, "bytes-encoding") { | ||
bytesEncoding = sflags.MustGetString(cmd, "bytes-encoding") | ||
} | ||
|
||
registry, err := fcproto.NewRegistry(chainFileDescriptor, protoPaths...) | ||
if err != nil { | ||
return nil, fmt.Errorf("new registry: %w", err) | ||
} | ||
|
||
if printer == "json" || printer == "jsonl" { | ||
jsonPrinter, err := NewJSONOutputPrinter(bytesEncoding, printer == "jsonl", registry) | ||
if err != nil { | ||
return nil, fmt.Errorf("unable to create json encoder: %w", err) | ||
} | ||
|
||
return jsonPrinter, nil | ||
} | ||
|
||
if printer == "protojson" || printer == "protojsonl" { | ||
indent := "" | ||
if printer == "protojson" { | ||
indent = " " | ||
} | ||
|
||
return NewProtoJSONOutputPrinter(indent, registry), nil | ||
} | ||
|
||
if printer == "text" { | ||
// Supports the `transactions` flag defined on `firecore tools print` sub-command, | ||
// we should move it to a proper `text` sub-option like `output-text-details` or something | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe just a different output mode: or There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah let's discuss that part, I created a generic block printer using Golang protoreflect, we could maybe extend it! |
||
// like that. | ||
printTransactions := false | ||
if sflags.FlagDefined(cmd, "transactions") { | ||
printTransactions = sflags.MustGetBool(cmd, "transactions") | ||
} | ||
|
||
return NewTextOutputPrinter(bytesEncoding, registry, printTransactions), nil | ||
} | ||
|
||
return nil, fmt.Errorf("unsupported output printer %q", printer) | ||
} | ||
|
||
//go:generate go-enum -f=$GOFILE --marshal --names --nocase | ||
|
||
// ENUM(Text, JSON, JSONL, ProtoJSON, ProtoJSONL) | ||
type PrintOutputMode uint | ||
|
||
type OutputPrinter interface { | ||
PrintTo(message any, w io.Writer) error | ||
} | ||
|
||
func writeStringToWriter(w io.Writer, str string) error { | ||
return writeBytesToWriter(w, unsafe.Slice(unsafe.StringData(str), len(str))) | ||
} | ||
|
||
func writeStringFToWriter(w io.Writer, format string, args ...any) error { | ||
return writeStringToWriter(w, fmt.Sprintf(format, args...)) | ||
} | ||
|
||
func writeBytesToWriter(w io.Writer, data []byte) error { | ||
n, err := w.Write(data) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if n != len(data) { | ||
return io.ErrShortWrite | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func ptr[T any](v T) *T { | ||
return &v | ||
} | ||
|
||
func deref[T any](v *T, orDefault T) T { | ||
if v == nil { | ||
return orDefault | ||
} | ||
|
||
return *v | ||
} | ||
|
||
func uint64PtrToString(v *uint64, orDefault string) string { | ||
if v == nil { | ||
return orDefault | ||
} | ||
|
||
return strconv.FormatUint(*v, 10) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I plan to remove all printing support from
check
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed.