Skip to content

Commit

Permalink
Handle output and move types
Browse files Browse the repository at this point in the history
  • Loading branch information
metal3d committed Jun 27, 2023
1 parent 03c9e86 commit 83cfd48
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 105 deletions.
34 changes: 18 additions & 16 deletions cmd/goreorder/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,20 @@ import (
"github.com/spf13/viper"
)

const (
usage = `%[1]s reorders the types, methods... in a Go
source file. By default, it will print the result to stdout. To allow %[1]s
to write to the file, use the -write flag.`
var (
version = "master" // changed at compilation time
defaultOutpout io.Writer = os.Stdout // default output is stdout
defaultErrOutpout io.Writer = os.Stderr // default error output is stderr
)

var (
version = "master" // changed at compilation time
examples = []string{
"$ %[1]s reorder --write --reorder-types --format gofmt file.go",
"$ %[1]s reorder --diff ./mypackage",
"$ cat file.go | %[1]s reorder",
}
completionExamples = []string{
func buildCompletionCommand() *cobra.Command {
var completionExamples = []string{
"$ %[1]s completion bash",
"$ %[1]s completion bash -no-documentation",
"$ %[1]s completion zsh",
"$ %[1]s completion fish",
"$ %[1]s completion powershell",
}
defaultOutpout io.Writer = os.Stdout
)

func buildCompletionCommand() *cobra.Command {
noDocumentation := false
bashv1Completion := false
completionCmd := &cobra.Command{
Expand Down Expand Up @@ -80,6 +70,14 @@ func buildCompletionCommand() *cobra.Command {
}

func buildMainCommand() *cobra.Command {
const usage = `%[1]s reorders the types, methods... in a Go
source file. By default, it will print the result to stdout. To allow %[1]s
to write to the file, use the -write flag.`
var examples = []string{
"$ %[1]s reorder --write --reorder-types --format gofmt file.go",
"$ %[1]s reorder --diff ./mypackage",
"$ cat file.go | %[1]s reorder",
}

cmd := cobra.Command{
Use: "goreorder [flags] [file.go|directory|stdin]",
Expand All @@ -95,6 +93,10 @@ func buildMainCommand() *cobra.Command {
},
}

// my god this is so cool...
cmd.SetOut(defaultOutpout)
cmd.SetErr(defaultErrOutpout)

config := &ReorderConfig{
FormatToolName: "gofmt",
Write: false,
Expand Down
5 changes: 5 additions & 0 deletions cmd/goreorder/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import (
"gopkg.in/yaml.v3"
)

func init() {
defaultOutpout = bytes.NewBuffer([]byte{})
defaultErrOutpout = bytes.NewBuffer([]byte{})
}

func TestNoConfigFile(t *testing.T) {
defaultOutpout = bytes.NewBuffer([]byte{})
printConfigFile(&ReorderConfig{
Expand Down
79 changes: 41 additions & 38 deletions cmd/goreorder/main.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package main

import (
"bytes"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
Expand All @@ -17,7 +19,7 @@ var (

func main() {
if err := buildMainCommand().Execute(); err != nil {
fmt.Println(fmt.Errorf("%w", err))
io.WriteString(defaultErrOutpout, fmt.Sprintf("%s\n", err))
os.Exit(1)
}
}
Expand All @@ -32,6 +34,37 @@ type ReorderConfig struct {
DefOrder []string `yaml:"order"`
}

func reorder(config *ReorderConfig, args ...string) error {

// is there something in stdin?
filename := ""
var input []byte
var err error
stat, _ := os.Stdin.Stat()
if (stat.Mode() & os.ModeCharDevice) == 0 {
// read from stdin
input, err = ioutil.ReadAll(os.Stdin)
if err != nil {
return fmt.Errorf("Error while reading stdin: %w", err)
}
filename = "stdin.go"
config.Write = false
log.Println("Processing stdin, write is set to false")
} else {
// read from file or directory
filename = args[0]
if filename == "" {
return fmt.Errorf("Filename is empty")
}
_, err := os.Stat(filename)
if err != nil {
return fmt.Errorf("Error while getting file stat: %w", err)
}
}

return processFile(filename, input, config)
}

func processFile(fileOrDirectoryName string, input []byte, config *ReorderConfig) error {
if strings.HasSuffix(fileOrDirectoryName, "_test.go") {
return fmt.Errorf("Skipping test file: " + fileOrDirectoryName)
Expand All @@ -47,15 +80,15 @@ func processFile(fileOrDirectoryName string, input []byte, config *ReorderConfig
Src: input,
})
if err != nil {
return fmt.Errorf("Error while reordering source: %v", err)
return fmt.Errorf("Error while reordering source: %w", err)
}
fmt.Print(string(content))
return nil
}

stat, err := os.Stat(fileOrDirectoryName)
if err != nil {
return fmt.Errorf("Error while getting file stat: %v", err)
return fmt.Errorf("Error while getting file stat: %w", err)
}
if stat.IsDir() {
// skip vendor directory
Expand All @@ -66,7 +99,7 @@ func processFile(fileOrDirectoryName string, input []byte, config *ReorderConfig
log.Println("Processing directory: " + fileOrDirectoryName)
return filepath.Walk(fileOrDirectoryName, func(path string, info os.FileInfo, err error) error {
if err != nil {
return fmt.Errorf("Error while walking directory: %v", err)
return fmt.Errorf("Error while walking directory: %w", err)
}
if strings.HasSuffix(path, ".go") {
processFile(path, nil, config)
Expand All @@ -85,46 +118,16 @@ func processFile(fileOrDirectoryName string, input []byte, config *ReorderConfig
Src: input,
})
if err != nil {
return fmt.Errorf("Error while reordering file: %v", err)
return fmt.Errorf("Error while reordering file: %w", err)
}
if config.Write {
err = ioutil.WriteFile(fileOrDirectoryName, []byte(output), 0644)
if err != nil {
return fmt.Errorf("Error while writing to file: %v", err)
return fmt.Errorf("Error while writing to file: %w", err)
}
} else {
fmt.Println(output)
//fmt.Println(output)
io.Copy(defaultOutpout, bytes.NewBufferString(output))
}
return nil
}

func reorder(config *ReorderConfig, args ...string) error {

// is there something in stdin?
filename := ""
var input []byte
var err error
stat, _ := os.Stdin.Stat()
if (stat.Mode() & os.ModeCharDevice) == 0 {
// read from stdin
input, err = ioutil.ReadAll(os.Stdin)
if err != nil {
return fmt.Errorf("Error while reading stdin: %v", err)
}
filename = "stdin.go"
config.Write = false
log.Println("Processing stdin, write is set to false")
} else {
// read from file or directory
filename = args[0]
if filename == "" {
return fmt.Errorf("Filename is empty")
}
_, err := os.Stat(filename)
if err != nil {
return fmt.Errorf("Error while getting file stat: %v", err)
}
}

return processFile(filename, input, config)
}
8 changes: 5 additions & 3 deletions cmd/goreorder/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import (
"testing"
)

func init() {
defaultOutpout = bytes.NewBuffer([]byte{})
defaultErrOutpout = bytes.NewBuffer([]byte{})
}

func TestBuildCommand(t *testing.T) {
cmd := buildMainCommand()
if cmd == nil {
Expand Down Expand Up @@ -138,9 +143,6 @@ func TestNoArgs(t *testing.T) {
}

func TestCompletionCommands(t *testing.T) {

defaultOutpout = &bytes.Buffer{}

for _, shell := range []string{"bash", "zsh", "fish", "powershell"} {
cmd := buildMainCommand()
cmd.SetArgs([]string{"completion", shell})
Expand Down
23 changes: 0 additions & 23 deletions ordering/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,12 @@ import (
"strings"
)

const (
Const Order = "const"
Init Order = "init"
Main Order = "main"
Var Order = "var"
Interface Order = "interface"
Type Order = "type"
Func Order = "func"
)

// DefaultOrder is the default order of elements.
//
// Note, Init and Main are not in the list. If they are present, the init and main functions
// will be moved.
var DefaultOrder = []Order{Const, Var, Interface, Type, Func}

// Order is the type of order, it's an alias of string.
type Order = string

// ReorderConfig is the configuration for the reorder function.
type ReorderConfig struct {
Filename string
FormatCommand string
ReorderStructs bool
Diff bool
Src interface{}
DefOrder []Order
}

func formatWithCommand(content []byte, output string, opt ReorderConfig) (newcontent []byte, err error) {
// we use the format command given by the user
// on a temporary file we need to create and remove
Expand Down
25 changes: 0 additions & 25 deletions ordering/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,6 @@ import (
"strings"
)

// GoType represents a struct, method or constructor. The "SourceCode" field contains the doc comment and source in Go, formated and ready to be injected in the source file.
type GoType struct {
// Name of the struct, method or constructor
Name string
// SourceCode contains the doc comment and source in Go, formated and ready to be injected in the source file.
SourceCode string
// OpeningLine is the line number where the struct, method or constructor starts in the source file.
OpeningLine int
// ClosingLine is the line number where the struct, method or constructor ends in the source file.
ClosingLine int
}

// ParsedInfo contains information we need to sort in the source file.
type ParsedInfo struct {
Functions map[string]*GoType
Methods map[string][]*GoType
Constructors map[string][]*GoType
Types map[string]*GoType
Interfaces map[string]*GoType
Constants map[string]*GoType
Variables map[string]*GoType
TypeNames *StingList
InterfaceNames *StingList
}

// Parse the given file and return the methods, constructors and structs.
func Parse(filename string, src interface{}) (*ParsedInfo, error) {
fset := token.NewFileSet()
Expand Down
52 changes: 52 additions & 0 deletions ordering/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package ordering

const (
Const Order = "const"
Init Order = "init"
Main Order = "main"
Var Order = "var"
Interface Order = "interface"
Type Order = "type"
Func Order = "func"
)

// GoType represents a struct, method or constructor. The "SourceCode" field contains the doc comment and source in Go, formated and ready to be injected in the source file.
type GoType struct {
// Name of the struct, method or constructor
Name string

// SourceCode contains the doc comment and source in Go, formated and ready to be injected in the source file.
SourceCode string

// OpeningLine is the line number where the struct, method or constructor starts in the source file.
OpeningLine int

// ClosingLine is the line number where the struct, method or constructor ends in the source file.
ClosingLine int
}

// Order is the type of order, it's an alias of string.
type Order = string

// ParsedInfo contains information we need to sort in the source file.
type ParsedInfo struct {
Functions map[string]*GoType
Methods map[string][]*GoType
Constructors map[string][]*GoType
Types map[string]*GoType
Interfaces map[string]*GoType
Constants map[string]*GoType
Variables map[string]*GoType
TypeNames *StingList
InterfaceNames *StingList
}

// ReorderConfig is the configuration for the reorder function.
type ReorderConfig struct {
Filename string
FormatCommand string
ReorderStructs bool
Diff bool
Src interface{}
DefOrder []Order
}

0 comments on commit 83cfd48

Please sign in to comment.