Commit 7e464d64 authored by OptimismBot's avatar OptimismBot Committed by GitHub

Merge pull request #6521 from ethereum-optimism/aj/cannon-gzip

cannon: Support gzip compression for JSON files.
parents 778a047a d8397264
...@@ -9,6 +9,7 @@ example/bin ...@@ -9,6 +9,7 @@ example/bin
contracts/out contracts/out
state.json state.json
*.json *.json
*.json.gz
*.pprof *.pprof
*.out *.out
bin bin
package cmd package cmd
import ( import (
"compress/gzip"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io" "io"
"os" "os"
"strings"
) )
func loadJSON[X any](inputPath string) (*X, error) { func loadJSON[X any](inputPath string) (*X, error) {
if inputPath == "" { if inputPath == "" {
return nil, errors.New("no path specified") return nil, errors.New("no path specified")
} }
var f io.ReadCloser
f, err := os.OpenFile(inputPath, os.O_RDONLY, 0) f, err := os.OpenFile(inputPath, os.O_RDONLY, 0)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open file %q: %w", inputPath, err) return nil, fmt.Errorf("failed to open file %q: %w", inputPath, err)
} }
defer f.Close() defer f.Close()
if isGzip(inputPath) {
f, err = gzip.NewReader(f)
if err != nil {
return nil, fmt.Errorf("create gzip reader: %w", err)
}
defer f.Close()
}
var state X var state X
if err := json.NewDecoder(f).Decode(&state); err != nil { if err := json.NewDecoder(f).Decode(&state); err != nil {
return nil, fmt.Errorf("failed to decode file %q: %w", inputPath, err) return nil, fmt.Errorf("failed to decode file %q: %w", inputPath, err)
...@@ -33,6 +43,11 @@ func writeJSON[X any](outputPath string, value X, outIfEmpty bool) error { ...@@ -33,6 +43,11 @@ func writeJSON[X any](outputPath string, value X, outIfEmpty bool) error {
} }
defer f.Close() defer f.Close()
out = f out = f
if isGzip(outputPath) {
g := gzip.NewWriter(f)
defer g.Close()
out = g
}
} else if outIfEmpty { } else if outIfEmpty {
out = os.Stdout out = os.Stdout
} else { } else {
...@@ -48,3 +63,7 @@ func writeJSON[X any](outputPath string, value X, outIfEmpty bool) error { ...@@ -48,3 +63,7 @@ func writeJSON[X any](outputPath string, value X, outIfEmpty bool) error {
} }
return nil return nil
} }
func isGzip(path string) bool {
return strings.HasSuffix(path, ".gz")
}
package cmd
import (
"encoding/json"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
)
func TestRoundTripJSON(t *testing.T) {
dir := t.TempDir()
file := filepath.Join(dir, "test.json")
data := &jsonTestData{A: "yay", B: 3}
err := writeJSON(file, data, false)
require.NoError(t, err)
// Confirm the file is uncompressed
fileContent, err := os.ReadFile(file)
require.NoError(t, err)
err = json.Unmarshal(fileContent, &jsonTestData{})
require.NoError(t, err)
var result *jsonTestData
result, err = loadJSON[jsonTestData](file)
require.NoError(t, err)
require.EqualValues(t, data, result)
}
func TestRoundTripJSONWithGzip(t *testing.T) {
dir := t.TempDir()
file := filepath.Join(dir, "test.json.gz")
data := &jsonTestData{A: "yay", B: 3}
err := writeJSON(file, data, false)
require.NoError(t, err)
// Confirm the file isn't raw JSON
fileContent, err := os.ReadFile(file)
require.NoError(t, err)
err = json.Unmarshal(fileContent, &jsonTestData{})
require.Error(t, err, "should not be able to decode without decompressing")
var result *jsonTestData
result, err = loadJSON[jsonTestData](file)
require.NoError(t, err)
require.EqualValues(t, data, result)
}
type jsonTestData struct {
A string `json:"a"`
B int `json:"b"`
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment