Skip to content

Commit

Permalink
Migrate most code to non-main package
Browse files Browse the repository at this point in the history
  • Loading branch information
frioux authored and lafrenierejm committed Jul 20, 2023
1 parent 295f291 commit 26144eb
Show file tree
Hide file tree
Showing 49 changed files with 3,236 additions and 646 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
gron
/gron
*.tgz
*.zip
*.swp
Expand Down
14 changes: 9 additions & 5 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@
settings.formatter = {
prettier = {
excludes = [
"testdata/large-line.json"
"testdata/long-stream.json"
"testdata/scalar-stream.json"
"testdata/stream.json"
"internal/gron/testdata/large-line.json"
"internal/gron/testdata/long-stream.json"
"internal/gron/testdata/scalar-stream.json"
"internal/gron/testdata/stream.json"
];
};
};
Expand All @@ -84,7 +84,11 @@
treefmt.enable = true;
typos = {
enable = true;
excludes = [ "ADVANCED.mkd" "testdata/.*" "ungron_test.go" ];
excludes = [
"ADVANCED.mkd"
"internal/gron/testdata/.*"
"internal/gron/ungron_test.go"
];
};
};
};
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ require (
github.com/mattn/go-colorable v0.1.13
github.com/nwidger/jsoncolor v0.3.2
github.com/pkg/errors v0.9.1
gopkg.in/yaml.v3 v3.0.1
)

require (
github.com/mattn/go-isatty v0.0.19 // indirect
golang.org/x/sys v0.10.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
26 changes: 26 additions & 0 deletions internal/gron/decoder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package gron

import (
"encoding/json"
"gopkg.in/yaml.v3"
"io"
)

// an ActionFn represents a main action of the program, it accepts
// an input, output and a bitfield of options; returning an exit
// code and any error that occurred
type ActionFn func(io.Reader, io.Writer, int) (int, error)

type Decoder interface {
Decode(interface{}) error
}

func MakeDecoder(r io.Reader, optYAML int) Decoder {
if optYAML > 0 {
return yaml.NewDecoder(r)
} else {
d := json.NewDecoder(r)
d.UseNumber()
return d
}
}
169 changes: 169 additions & 0 deletions internal/gron/gron.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
package gron

import (
"bufio"
"bytes"
"fmt"
"io"
"sort"

"github.com/fatih/color"
)

// Exit codes
const (
exitOK = iota
exitOpenFile
exitReadInput
exitFormStatements
exitFetchURL
exitParseStatements
exitJSONEncode
)

// Option bitfields
const (
optMonochrome = 1 << iota
optNoSort
optJSON
optYAML
)

// Output colors
var (
strColor = color.New(color.FgYellow)
braceColor = color.New(color.FgMagenta)
bareColor = color.New(color.FgBlue, color.Bold)
numColor = color.New(color.FgRed)
boolColor = color.New(color.FgCyan)
)

// Gron is the default action. Given JSON as the input it returns a list
// of assignment statements. Possible options are optNoSort and optMonochrome
func Gron(r io.Reader, w io.Writer, opts int) (int, error) {
var err error

var conv StatementConv
if opts&optMonochrome > 0 {
conv = StatementToString
} else {
conv = StatementToColorString
}

ss, err := StatementsFromJSON(MakeDecoder(r, opts&optYAML), Statement{{"json", TypBare}})
if err != nil {
goto out
}

// Go's maps do not have well-defined ordering, but we want a consistent
// output for a given input, so we must sort the statements
if opts&optNoSort == 0 {
sort.Sort(ss)
}

for _, s := range ss {
if opts&optJSON > 0 {
s, err = s.Jsonify()
if err != nil {
goto out
}
}
fmt.Fprintln(w, conv(s))
}

out:
if err != nil {
return exitFormStatements, fmt.Errorf("failed to form statements: %s", err)
}
return exitOK, nil
}

// GronStream is like the gron action, but it treats the input as one
// JSON object per line. There's a bit of code duplication from the
// gron action, but it'd be fairly messy to combine the two actions
func GronStream(r io.Reader, w io.Writer, opts int) (int, error) {
var err error
errstr := "failed to form statements"
var i int
var sc *bufio.Scanner
var buf []byte

var conv func(s Statement) string
if opts&optMonochrome > 0 {
conv = StatementToString
} else {
conv = StatementToColorString
}

// Helper function to make the prefix statements for each line
makePrefix := func(index int) Statement {
return Statement{
{"json", TypBare},
{"[", TypLBrace},
{fmt.Sprintf("%d", index), TypNumericKey},
{"]", TypRBrace},
}
}

// The first line of output needs to establish that the top-level
// thing is actually an array...
top := Statement{
{"json", TypBare},
{"=", TypEquals},
{"[]", TypEmptyArray},
{";", TypSemi},
}

if opts&optJSON > 0 {
top, err = top.Jsonify()
if err != nil {
goto out
}
}

fmt.Fprintln(w, conv(top))

// Read the input line by line
sc = bufio.NewScanner(r)
buf = make([]byte, 0, 64*1024)
sc.Buffer(buf, 1024*1024)
i = 0
for sc.Scan() {

line := bytes.NewBuffer(sc.Bytes())

var ss Statements
ss, err = StatementsFromJSON(MakeDecoder(line, opts&optYAML), makePrefix(i))
i++
if err != nil {
goto out
}

// Go's maps do not have well-defined ordering, but we want a consistent
// output for a given input, so we must sort the statements
if opts&optNoSort == 0 {
sort.Sort(ss)
}

for _, s := range ss {
if opts&optJSON > 0 {
s, err = s.Jsonify()
if err != nil {
goto out
}

}
fmt.Fprintln(w, conv(s))
}
}
if err = sc.Err(); err != nil {
errstr = "error reading multiline input: %s"
}

out:
if err != nil {
return exitFormStatements, fmt.Errorf(errstr+": %s", err)
}
return exitOK, nil

}
18 changes: 9 additions & 9 deletions main_test.go → internal/gron/gron_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package gron

import (
"bytes"
Expand Down Expand Up @@ -32,7 +32,7 @@ func TestGron(t *testing.T) {
}

out := &bytes.Buffer{}
code, err := gron(in, out, optMonochrome)
code, err := Gron(in, out, optMonochrome)

if code != exitOK {
t.Errorf("want exitOK; have %d", code)
Expand Down Expand Up @@ -71,7 +71,7 @@ func TestGronStream(t *testing.T) {
}

out := &bytes.Buffer{}
code, err := gronStream(in, out, optMonochrome)
code, err := GronStream(in, out, optMonochrome)

if code != exitOK {
t.Errorf("want exitOK; have %d", code)
Expand Down Expand Up @@ -109,7 +109,7 @@ func TestLargeGronStream(t *testing.T) {
}

out := &bytes.Buffer{}
code, err := gronStream(in, out, optMonochrome)
code, err := GronStream(in, out, optMonochrome)

if code != exitOK {
t.Errorf("want exitOK; have %d", code)
Expand Down Expand Up @@ -159,7 +159,7 @@ func TestUngron(t *testing.T) {
}

out := &bytes.Buffer{}
code, err := ungron(in, out, optMonochrome)
code, err := Ungron(in, out, optMonochrome)

if code != exitOK {
t.Errorf("want exitOK; have %d", code)
Expand Down Expand Up @@ -206,7 +206,7 @@ func TestGronJ(t *testing.T) {
}

out := &bytes.Buffer{}
code, err := gron(in, out, optMonochrome|optJSON)
code, err := Gron(in, out, optMonochrome|optJSON)

if code != exitOK {
t.Errorf("want exitOK; have %d", code)
Expand Down Expand Up @@ -245,7 +245,7 @@ func TestGronStreamJ(t *testing.T) {
}

out := &bytes.Buffer{}
code, err := gronStream(in, out, optMonochrome|optJSON)
code, err := GronStream(in, out, optMonochrome|optJSON)

if code != exitOK {
t.Errorf("want exitOK; have %d", code)
Expand Down Expand Up @@ -292,7 +292,7 @@ func TestUngronJ(t *testing.T) {
}

out := &bytes.Buffer{}
code, err := ungron(in, out, optMonochrome|optJSON)
code, err := Ungron(in, out, optMonochrome|optJSON)

if code != exitOK {
t.Errorf("want exitOK; have %d", code)
Expand Down Expand Up @@ -329,7 +329,7 @@ func BenchmarkBigJSON(b *testing.B) {
b.Fatalf("failed to rewind input: %s", err)
}

_, err := gron(in, out, optMonochrome|optNoSort)
_, err := Gron(in, out, optMonochrome|optNoSort)
if err != nil {
b.Fatalf("failed to gron: %s", err)
}
Expand Down
2 changes: 1 addition & 1 deletion identifier.go → internal/gron/identifier.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package gron

import "unicode"

Expand Down
2 changes: 1 addition & 1 deletion identifier_test.go → internal/gron/identifier_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package gron

import "testing"

Expand Down
Loading

0 comments on commit 26144eb

Please sign in to comment.