Skip to content
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

Migrate most code to non-main package #66

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
168 changes: 168 additions & 0 deletions internal/gron/gron.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
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
)

// 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(r, 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(line, 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 @@ -158,7 +158,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 @@ -205,7 +205,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 @@ -244,7 +244,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 @@ -291,7 +291,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 @@ -328,7 +328,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
2 changes: 1 addition & 1 deletion statements.go → internal/gron/statements.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package gron

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

import (
"bytes"
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion token.go → internal/gron/token.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package gron

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

import (
"encoding/json"
Expand Down
Loading