Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
Signed-off-by: Yoan Blanc <[email protected]>
  • Loading branch information
greut committed Nov 1, 2019
0 parents commit e747a74
Show file tree
Hide file tree
Showing 8 changed files with 242 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
root = true

[*]
charset = utf-8
end_of_line = lf
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
eclint
vendor
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# eclint - EditorConfig linter

An alternative to the JavaScript _eclint_ written in Go.

## Usage

```
$ go install github.com/greut/eclint
$ eclint -version
```

## Features

- `end_of_line`

## Missing features

- `charset`
- `indent_style`
- `indent_size`
- etc.

## Benchmarks

*TODO*

## Libraries

- [editorconfig-core-go](https://github.com/editorconfig/editorconfig-core-go)
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module github.com/greut/eclint

go 1.13

require github.com/editorconfig/editorconfig-core-go/v2 v2.2.0
20 changes: 20 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/editorconfig/editorconfig-core-go/v2 v2.2.0 h1:Gn1PqdLRUQy8nvWxbLPUCEPeWNpwtkwe0fRKAyd7+uo=
github.com/editorconfig/editorconfig-core-go/v2 v2.2.0/go.mod h1:/LuhWJiQ9Gvo1DhVpa4ssm5qeg8rrztdtI7j/iCie2k=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
gopkg.in/ini.v1 v1.42.0 h1:7N3gPTt50s8GuLortA00n8AqRTk75qOP98+mTPpgzRk=
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
103 changes: 103 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package main

import (
"flag"
"fmt"
"log"
"os"
"path/filepath"

"github.com/editorconfig/editorconfig-core-go/v2"
)

var (
version = "dev"
)

func walk(paths ...string) ([]string, error) {
files := make([]string, 0)
for _, path := range paths {
log.Printf("enter %s\n", path)
err := filepath.Walk(path, func(p string, i os.FileInfo, e error) error {
mode := i.Mode()
if mode.IsRegular() && !mode.IsDir() {
log.Printf("add %s\n", p)
abs, err := filepath.Abs(p)
if err != nil {
return err
}
files = append(files, abs)
}
return nil
})
if err != nil {
return files, err
}
}
return files, nil
}

func lint(filename string) error {
// XXX editorconfig should be able to treat a flux of
// filenames with caching capabilities.
def, err := editorconfig.GetDefinitionForFilename(filename)
if err != nil {
return fmt.Errorf("Cannot open file %s. %w", filename, err)
}
log.Printf("lint %s %#v", filename, def)

fp, err := os.Open(filename)
if err != nil {
return err
}

err = readLines(fp, func(index int, data []byte) error {
log.Printf("line %d: %s", index, data)
if def.EndOfLine != "" {
err := endOfLine(def.EndOfLine, data)
if err != nil {
return err
}
}
return nil
})

return err
}

func main() {
var flagVersion bool

flag.BoolVar(&flagVersion, "version", false, "print the version number")
flag.Parse()

if flagVersion {
fmt.Printf("ec %s\n", version)
return
}

args := flag.Args()
if len(args) == 0 {
args = append(args, ".")
}

files, err := walk(args...)
if err != nil {
log.Printf("[ERROR] %v", err)
os.Exit(1)
return
}
log.Printf("%d files found", len(files))

c := 0
for _, file := range files {
err := lint(file)
if err != nil {
log.Printf("[ERROR] %v", err)
c++
}
}
if c > 0 {
os.Exit(1)
}
}
48 changes: 48 additions & 0 deletions scanner.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package main

import (
"bufio"
"io"
)

// lineFunc is the callback for a line.
//
// It returns the line number starting from zero.
type lineFunc func(int, []byte) error

// splitLines works like bufio.ScanLines while keeping the line endings.
func splitLines(data []byte, atEOF bool) (int, []byte, error) {
for i := 0; i < len(data); {
if data[i] == '\r' {
i++
if data[i] == '\n' {
i++
}
return i, data[0:i], nil
} else if data[i] == '\n' {
i++
return i, data[0:i], nil
}
i++
}
if !atEOF {
return 0, nil, nil
}
return len(data) + 1, data, nil
}

func readLines(r io.Reader, fn lineFunc) error {
sc := bufio.NewScanner(r)
sc.Split(splitLines)

i := 0
for sc.Scan() {
line := sc.Bytes()
if err := fn(i, line); err != nil {
return err
}
i++
}

return nil
}
29 changes: 29 additions & 0 deletions validators.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package main

import "fmt"

// endOfLines checks the line ending
func endOfLine(eol string, data []byte) error {
l := len(data)
switch eol {
case "lf":
if l > 0 && data[l-1] != '\n' {
return fmt.Errorf("line does not end with lf (`\\n`)")
}
if l > 1 && data[l-2] == '\r' {
return fmt.Errorf("line should not end with crlf (`\\r\\n`)")
}
case "crlf":
if l > 0 && data[l-1] != '\n' || (l > 1 && data[l-2] != '\r') {
return fmt.Errorf("line does not end with crlf (`\\r\\n`)")
}
case "cr":
if l > 0 && data[l-1] != '\r' {
return fmt.Errorf("line does not end with cr (`\\r`)")
}
default:
return fmt.Errorf("%q is an invalid value for eol, want cr, crlf, or lf", eol)
}

return nil
}

0 comments on commit e747a74

Please sign in to comment.