Skip to content

Commit

Permalink
Add ext_map path flag (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
EthanThatOneKid committed Jun 20, 2023
1 parent 4edbcde commit 5c73743
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 39 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,20 @@ switch (thing) {
//LINT.END
```

### Custom file extensions

```bash
git diff | difflint --ext_map="difflint.json"
```

#### `difflint.json`

```json
{
"yaml": ["#LINT.?"]
}
```

## Development

Run the tool from source with the Go toolchain:
Expand Down
8 changes: 7 additions & 1 deletion cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ func NewApp() *App {
Usage: "exclude files matching the given glob",
Required: false,
},
&cli.PathFlag{
Name: "ext_map",
Usage: "path to file extension map[string][]string (see README.md for format)",
Required: false,
},
&cli.BoolFlag{
Name: "verbose",
Usage: "enable verbose logging",
Expand Down Expand Up @@ -69,8 +74,9 @@ func NewApp() *App {
func action(ctx *cli.Context) error {
include := ctx.StringSlice("include")
exclude := ctx.StringSlice("exclude")
extMapPath := ctx.String("ext_map")

if err := difflint.Do(ctx.App.Reader, include, exclude); err != nil {
if err := difflint.Do(ctx.App.Reader, include, exclude, extMapPath); err != nil {
return err
}

Expand Down
43 changes: 7 additions & 36 deletions difflint.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import (
"github.com/sourcegraph/go-diff/diff"
)

// Hello world

// Range represents a range of line numbers.
type Range struct {
// Start line number.
Expand Down Expand Up @@ -57,7 +55,7 @@ func (o *LintOptions) TemplatesFromFile(file string) ([]string, error) {

templateIndices, ok := o.FileExtMap[fileType]
if !ok {
return nil, errors.Errorf("no directive template found for file type %q", fileType)
templateIndices = []int{o.DefaultTemplate}
}

var filteredTemplates []string
Expand Down Expand Up @@ -195,45 +193,18 @@ func Check(rulesMap map[string][]Rule) ([]UnsatisfiedRule, error) {
}

// Entrypoint for the difflint command.
func Do(r io.Reader, include, exclude []string) error {
func Do(r io.Reader, include, exclude []string, extMapPath string) error {
// Parse options.
extMap := NewExtMap(extMapPath)

// Lint the hunks.
result, err := Lint(LintOptions{
Reader: r,
Include: include,
Exclude: exclude,
DefaultTemplate: 0,
Templates: []string{
"#LINT.?",
"//LINT.?",
"/*LINT.?",
"<!--LINT.?",
"'LINT.?",
},
FileExtMap: map[string][]int{
"py": {0},
"sh": {0},
"go": {1},
"js": {1, 2},
"jsx": {1, 2},
"mjs": {1, 2},
"ts": {1, 2},
"tsx": {1, 2},
"jsonc": {1, 2},
"c": {1, 2},
"cc": {1, 2},
"cpp": {1, 2},
"h": {1, 2},
"hpp": {1, 2},
"java": {1},
"rs": {1},
"swift": {1},
"svelte": {1, 2, 3},
"css": {2},
"html": {3},
"md": {3},
"markdown": {3},
"bas": {4},
},
Templates: extMap.Templates,
FileExtMap: extMap.FileExtMap,
})
if err != nil {
return errors.Wrap(err, "failed to lint hunks")
Expand Down
101 changes: 101 additions & 0 deletions ext.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package difflint

import (
"encoding/json"
"log"
)

var (
// DefaultTemplates is the default list of directive templates.
DefaultTemplates = []string{
"#LINT.?",
"//LINT.?",
"/*LINT.?",
"<!--LINT.?",
"'LINT.?",
}

// DefaultFileExtMap is the default map of file extensions to directive templates.
DefaultFileExtMap = map[string][]int{
"py": {0},
"sh": {0},
"go": {1},
"js": {1, 2},
"jsx": {1, 2},
"mjs": {1, 2},
"ts": {1, 2},
"tsx": {1, 2},
"jsonc": {1, 2},
"c": {1, 2},
"cc": {1, 2},
"cpp": {1, 2},
"h": {1, 2},
"hpp": {1, 2},
"java": {1},
"rs": {1},
"swift": {1},
"svelte": {1, 2, 3},
"css": {2},
"html": {3},
"md": {3},
"markdown": {3},
"bas": {4},
}
)

// ExtFileJSON is a JSON representation of a file extension to directive template map.
type ExtFileJSON map[string][]string

// ExtMap represents the extensions and templates for a linting operation.
type ExtMap struct {
// Templates is the list of directive templates.
Templates []string

// FileExtMap is a map of file extensions to directive templates.
FileExtMap map[string][]int
}

// NewExtMap returns a new ExtMap instance.
func NewExtMap(path string) *ExtMap {
o := &ExtMap{
Templates: DefaultTemplates,
FileExtMap: DefaultFileExtMap,
}

// If a path is provided, update the templates and file extension map.
if path != "" {
// Unmarshal the JSON file.
var extFile ExtFileJSON
if err := json.Unmarshal([]byte(path), &extFile); err != nil {
log.Fatalf("error unmarshaling JSON file %q: %v", path, err)
}

// Update the templates and file extension map.
for ext, tpls := range extFile {
for _, tpl := range tpls {
o.With(ext, tpl)
}
}
}

return o
}

// With adds a directive template for a file extension.
func (o *ExtMap) With(ext, tpl string) *ExtMap {
tplIndex := -1
for i, t := range o.Templates {
if t == tpl {
tplIndex = i
break
}
}

if tplIndex == -1 {
tplIndex = len(o.Templates)
o.Templates = append(o.Templates, tpl)
}

o.FileExtMap[ext] = append(o.FileExtMap[ext], tplIndex)
return o
}
2 changes: 0 additions & 2 deletions lex.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,5 +195,3 @@ func parseTargets(o parseTargetsOptions) ([]Target, error) {

return targets, nil
}

// This change does not affect the given target because we have a bug. The bug is that we cannot read any files that are not included in the hunk, so the files in the rules must be recursively read.

0 comments on commit 5c73743

Please sign in to comment.