1
1
mirror of https://github.com/go-gitea/gitea synced 2025-09-28 03:28:13 +00:00

upgrade gopkg.in/editorconfig/editorconfig-core-go.v1 (#8501)

editorconfig-core-go made breaking api changes and has recently released
v2.1.1. This change consumes the new api and fixes up any breaking
references.
This commit is contained in:
Colin Arnott
2019-10-15 21:24:16 +00:00
committed by zeripath
parent 80655026d2
commit 66e99d722a
23 changed files with 394 additions and 121 deletions

View File

@@ -1,13 +0,0 @@
; http://editorconfig.org/
root = true
[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8
trim_trailing_whitespace = true
[*.go]
indent_style = tab
indent_size = 8

View File

@@ -1,5 +0,0 @@
* text eol=lf
*.jpg binary
*.jpeg binary
*.png binary
*.ico binary

View File

@@ -1,29 +0,0 @@
# ---> Go
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test
*.prof
# EditorConfig
/editorconfig

View File

@@ -1,3 +0,0 @@
[submodule "core-test"]
path = core-test
url = https://github.com/editorconfig/editorconfig-core-test.git

View File

@@ -1,14 +0,0 @@
---
language: go
sudo: false
go:
- '1.8'
- '1.9'
- '1.10'
go_import_path: gopkg.in/editorconfig/editorconfig-core-go.v1
install:
- make installdeps
script:
- make test

View File

@@ -1,8 +0,0 @@
MIT License
Copyright (c) 2016 The Editorconfig Team
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -1,25 +0,0 @@
PROJECT_ROOT_DIR := $(CURDIR)
SRC := editorconfig.go cmd/editorconfig/main.go
.PHONY: bin test test-go test-core submodule installdeps
test: test-go test-core
submodule:
git submodule update --init
installdeps:
go get -t ./...
editorconfig: $(SRC)
go build ./cmd/editorconfig
test-go:
go test -v
test-core: editorconfig
cd $(PROJECT_ROOT_DIR)/core-test && \
cmake -DEDITORCONFIG_CMD="$(PROJECT_ROOT_DIR)/editorconfig" .
# Temporarily disable core-test
# cd $(PROJECT_ROOT_DIR)/core-test && \
# ctest --output-on-failure .

View File

@@ -1,122 +0,0 @@
[![Build Status](https://travis-ci.org/editorconfig/editorconfig-core-go.svg?branch=master)](https://travis-ci.org/editorconfig/editorconfig-core-go)
[![GoDoc](https://godoc.org/gopkg.in/editorconfig/editorconfig-core-go.v1?status.svg)](https://godoc.org/gopkg.in/editorconfig/editorconfig-core-go.v1)
[![Go Report Card](https://goreportcard.com/badge/gopkg.in/editorconfig/editorconfig-core-go.v1)](https://goreportcard.com/report/gopkg.in/editorconfig/editorconfig-core-go.v1)
# Editorconfig Core Go
A [Editorconfig][editorconfig] file parser and manipulator for Go.
> This package is already working, but still under testing.
## Installing
We recommend the use of [gopkg.in][gopkg] for this package:
```bash
go get -u gopkg.in/editorconfig/editorconfig-core-go.v1
```
Import by the same path. The package name you will use to access it is
`editorconfig`.
```go
import (
"gopkg.in/editorconfig/editorconfig-core-go.v1"
)
```
## Usage
### Parse from file
```go
editorConfig, err := editorconfig.ParseFile("path/to/.editorconfig")
if err != nil {
log.Fatal(err)
}
```
### Parse from slice of bytes
```go
data := []byte("...")
editorConfig, err := editorconfig.ParseBytes(data)
if err != nil {
log.Fatal(err)
}
```
### Get definition to a given filename
This method builds a definition to a given filename.
This definition is a merge of the properties with selectors that matched the
given filename.
The lasts sections of the file have preference over the priors.
```go
def := editorConfig.GetDefinitionForFilename("my/file.go")
```
This definition have the following properties:
```go
type Definition struct {
Selector string
Charset string
IndentStyle string
IndentSize string
TabWidth int
EndOfLine string
TrimTrailingWhitespace bool
InsertFinalNewline bool
}
```
#### Automatic search for `.editorconfig` files
If you want a definition of a file without having to manually
parse the `.editorconfig` files, you can then use the static version
of `GetDefinitionForFilename`:
```go
def, err := editorconfig.GetDefinitionForFilename("foo/bar/baz/my-file.go")
```
In the example above, the package will automatically search for
`.editorconfig` files on:
- `foo/bar/baz/.editorconfig`
- `foo/baz/.editorconfig`
- `foo/.editorconfig`
Until it reaches a file with `root = true` or the root of the filesystem.
### Generating a .editorconfig file
You can easily convert a Editorconfig struct to a compatible INI file:
```go
// serialize to slice of bytes
data, err := editorConfig.Serialize()
if err != nil {
log.Fatal(err)
}
// save directly to file
err := editorConfig.Save("path/to/.editorconfig")
if err != nil {
log.Fatal(err)
}
```
## Contributing
To run the tests:
```bash
go test -v
```
[editorconfig]: http://editorconfig.org/
[gopkg]: https://gopkg.in

View File

@@ -1,288 +0,0 @@
// Package editorconfig can be used to parse and generate editorconfig files.
// For more information about editorconfig, see http://editorconfig.org/
package editorconfig
import (
"bytes"
"io/ioutil"
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
"gopkg.in/ini.v1"
)
const (
ConfigNameDefault = ".editorconfig"
)
// IndentStyle possible values
const (
IndentStyleTab = "tab"
IndentStyleSpaces = "space"
)
// EndOfLine possible values
const (
EndOfLineLf = "lf"
EndOfLineCr = "cr"
EndOfLineCrLf = "crlf"
)
// Charset possible values
const (
CharsetLatin1 = "latin1"
CharsetUTF8 = "utf-8"
CharsetUTF16BE = "utf-16be"
CharsetUTF16LE = "utf-16le"
)
// Definition represents a definition inside the .editorconfig file.
// E.g. a section of the file.
// The definition is composed of the selector ("*", "*.go", "*.{js.css}", etc),
// plus the properties of the selected files.
type Definition struct {
Selector string `ini:"-" json:"-"`
Charset string `ini:"charset" json:"charset,omitempty"`
IndentStyle string `ini:"indent_style" json:"indent_style,omitempty"`
IndentSize string `ini:"indent_size" json:"indent_size,omitempty"`
TabWidth int `ini:"tab_width" json:"tab_width,omitempty"`
EndOfLine string `ini:"end_of_line" json:"end_of_line,omitempty"`
TrimTrailingWhitespace bool `ini:"trim_trailing_whitespace" json:"trim_trailing_whitespace,omitempty"`
InsertFinalNewline bool `ini:"insert_final_newline" json:"insert_final_newline,omitempty"`
Raw map[string]string `ini:"-" json:"-"`
}
// Editorconfig represents a .editorconfig file.
// It is composed by a "root" property, plus the definitions defined in the
// file.
type Editorconfig struct {
Root bool
Definitions []*Definition
}
// ParseBytes parses from a slice of bytes.
func ParseBytes(data []byte) (*Editorconfig, error) {
iniFile, err := ini.Load(data)
if err != nil {
return nil, err
}
editorConfig := &Editorconfig{}
editorConfig.Root = iniFile.Section(ini.DEFAULT_SECTION).Key("root").MustBool(false)
for _, sectionStr := range iniFile.SectionStrings() {
if sectionStr == ini.DEFAULT_SECTION {
continue
}
var (
iniSection = iniFile.Section(sectionStr)
definition = &Definition{}
raw = make(map[string]string)
)
err := iniSection.MapTo(&definition)
if err != nil {
return nil, err
}
// tab_width defaults to indent_size:
// https://github.com/editorconfig/editorconfig/wiki/EditorConfig-Properties#tab_width
if definition.TabWidth <= 0 {
if num, err := strconv.Atoi(definition.IndentSize); err == nil {
definition.TabWidth = num
}
}
// Shallow copy all properties
for k, v := range iniSection.KeysHash() {
raw[k] = v
}
definition.Selector = sectionStr
definition.Raw = raw
editorConfig.Definitions = append(editorConfig.Definitions, definition)
}
return editorConfig, nil
}
// ParseFile parses from a file.
func ParseFile(f string) (*Editorconfig, error) {
data, err := ioutil.ReadFile(f)
if err != nil {
return nil, err
}
return ParseBytes(data)
}
var (
regexpBraces = regexp.MustCompile("{.*}")
)
func filenameMatches(pattern, name string) bool {
// basic match
matched, _ := filepath.Match(pattern, name)
if matched {
return true
}
// foo/bar/main.go should match main.go
matched, _ = filepath.Match(pattern, filepath.Base(name))
if matched {
return true
}
// foo should match foo/main.go
matched, _ = filepath.Match(filepath.Join(pattern, "*"), name)
if matched {
return true
}
// *.{js,go} should match main.go
if str := regexpBraces.FindString(pattern); len(str) > 0 {
// remote initial "{" and final "}"
str = strings.TrimPrefix(str, "{")
str = strings.TrimSuffix(str, "}")
// testing for empty brackets: "{}"
if len(str) == 0 {
patt := regexpBraces.ReplaceAllString(pattern, "*")
matched, _ = filepath.Match(patt, filepath.Base(name))
return matched
}
for _, patt := range strings.Split(str, ",") {
patt = regexpBraces.ReplaceAllString(pattern, patt)
matched, _ = filepath.Match(patt, filepath.Base(name))
if matched {
return true
}
}
}
return false
}
func (d *Definition) merge(md *Definition) {
if len(d.Charset) == 0 {
d.Charset = md.Charset
}
if len(d.IndentStyle) == 0 {
d.IndentStyle = md.IndentStyle
}
if len(d.IndentSize) == 0 {
d.IndentSize = md.IndentSize
}
if d.TabWidth <= 0 {
d.TabWidth = md.TabWidth
}
if len(d.EndOfLine) == 0 {
d.EndOfLine = md.EndOfLine
}
if !d.TrimTrailingWhitespace {
d.TrimTrailingWhitespace = md.TrimTrailingWhitespace
}
if !d.InsertFinalNewline {
d.InsertFinalNewline = md.InsertFinalNewline
}
for k, v := range md.Raw {
if _, ok := d.Raw[k]; !ok {
d.Raw[k] = v
}
}
}
func (d *Definition) InsertToIniFile(iniFile *ini.File) {
iniSec := iniFile.Section(d.Selector)
for k, v := range d.Raw {
iniSec.Key(k).SetValue(v)
}
}
// GetDefinitionForFilename returns a definition for the given filename.
// The result is a merge of the selectors that matched the file.
// The last section has preference over the priors.
func (e *Editorconfig) GetDefinitionForFilename(name string) *Definition {
def := &Definition{}
def.Raw = make(map[string]string)
for i := len(e.Definitions) - 1; i >= 0; i-- {
actualDef := e.Definitions[i]
if filenameMatches(actualDef.Selector, name) {
def.merge(actualDef)
}
}
return def
}
func boolToString(b bool) string {
if b {
return "true"
}
return "false"
}
// Serialize converts the Editorconfig to a slice of bytes, containing the
// content of the file in the INI format.
func (e *Editorconfig) Serialize() ([]byte, error) {
var (
iniFile = ini.Empty()
buffer = bytes.NewBuffer(nil)
)
iniFile.Section(ini.DEFAULT_SECTION).Comment = "http://editorconfig.org"
if e.Root {
iniFile.Section(ini.DEFAULT_SECTION).Key("root").SetValue(boolToString(e.Root))
}
for _, d := range e.Definitions {
d.InsertToIniFile(iniFile)
}
_, err := iniFile.WriteTo(buffer)
if err != nil {
return nil, err
}
return buffer.Bytes(), nil
}
// Save saves the Editorconfig to a compatible INI file.
func (e *Editorconfig) Save(filename string) error {
data, err := e.Serialize()
if err != nil {
return err
}
return ioutil.WriteFile(filename, data, 0666)
}
// GetDefinitionForFilename given a filename, searches
// for .editorconfig files, starting from the file folder,
// walking through the previous folders, until it reaches a
// folder with `root = true`, and returns the right editorconfig
// definition for the given file.
func GetDefinitionForFilename(filename string) (*Definition, error) {
return GetDefinitionForFilenameWithConfigname(filename, ConfigNameDefault)
}
func GetDefinitionForFilenameWithConfigname(filename string, configname string) (*Definition, error) {
abs, err := filepath.Abs(filename)
if err != nil {
return nil, err
}
definition := &Definition{}
definition.Raw = make(map[string]string)
dir := abs
for dir != filepath.Dir(dir) {
dir = filepath.Dir(dir)
ecFile := filepath.Join(dir, configname)
if _, err := os.Stat(ecFile); os.IsNotExist(err) {
continue
}
ec, err := ParseFile(ecFile)
if err != nil {
return nil, err
}
definition.merge(ec.GetDefinitionForFilename(filename))
if ec.Root {
break
}
}
return definition, nil
}