forked from tomnomnom/gron
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Migrate most code to non-main package
- Loading branch information
1 parent
295f291
commit 26144eb
Showing
49 changed files
with
3,236 additions
and
646 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
gron | ||
/gron | ||
*.tgz | ||
*.zip | ||
*.swp | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package main | ||
package gron | ||
|
||
import "unicode" | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package main | ||
package gron | ||
|
||
import "testing" | ||
|
||
|
Oops, something went wrong.