1 Star 0 Fork 0

lonely / gometalinter

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
partition.go 3.71 KB
一键复制 编辑 原始数据 按行查看 历史
package main
import (
"encoding/json"
"fmt"
"path/filepath"
)
// MaxCommandBytes is the maximum number of bytes used when executing a command
const MaxCommandBytes = 32000
type partitionStrategy func([]string, []string) ([][]string, error)
func (ps *partitionStrategy) UnmarshalJSON(raw []byte) error {
var strategyName string
if err := json.Unmarshal(raw, &strategyName); err != nil {
return err
}
switch strategyName {
case "directories":
*ps = partitionPathsAsDirectories
case "files":
*ps = partitionPathsAsFiles
case "packages":
*ps = partitionPathsAsPackages
case "files-by-package":
*ps = partitionPathsAsFilesGroupedByPackage
case "single-directory":
*ps = partitionPathsByDirectory
default:
return fmt.Errorf("unknown parition strategy %s", strategyName)
}
return nil
}
func pathsToFileGlobs(paths []string) ([]string, error) {
filePaths := []string{}
for _, dir := range paths {
paths, err := filepath.Glob(filepath.Join(dir, "*.go"))
if err != nil {
return nil, err
}
filePaths = append(filePaths, paths...)
}
return filePaths, nil
}
func partitionPathsAsDirectories(cmdArgs []string, paths []string) ([][]string, error) {
return partitionToMaxSize(cmdArgs, paths, MaxCommandBytes), nil
}
func partitionToMaxSize(cmdArgs []string, paths []string, maxSize int) [][]string {
partitions := newSizePartitioner(cmdArgs, maxSize)
for _, path := range paths {
partitions.add(path)
}
return partitions.end()
}
type sizePartitioner struct {
base []string
parts [][]string
current []string
size int
max int
}
func newSizePartitioner(base []string, max int) *sizePartitioner {
p := &sizePartitioner{base: base, max: max}
p.new()
return p
}
func (p *sizePartitioner) add(arg string) {
if p.size+len(arg)+1 > p.max {
p.new()
}
p.current = append(p.current, arg)
p.size += len(arg) + 1
}
func (p *sizePartitioner) new() {
p.end()
p.size = 0
p.current = []string{}
for _, arg := range p.base {
p.add(arg)
}
}
func (p *sizePartitioner) end() [][]string {
if len(p.current) > 0 {
p.parts = append(p.parts, p.current)
}
return p.parts
}
func partitionPathsAsFiles(cmdArgs []string, paths []string) ([][]string, error) {
filePaths, err := pathsToFileGlobs(paths)
if err != nil || len(filePaths) == 0 {
return nil, err
}
return partitionPathsAsDirectories(cmdArgs, filePaths)
}
func partitionPathsAsFilesGroupedByPackage(cmdArgs []string, paths []string) ([][]string, error) {
parts := [][]string{}
for _, path := range paths {
filePaths, err := pathsToFileGlobs([]string{path})
if err != nil {
return nil, err
}
if len(filePaths) == 0 {
continue
}
parts = append(parts, append(cmdArgs, filePaths...))
}
return parts, nil
}
func partitionPathsAsPackages(cmdArgs []string, paths []string) ([][]string, error) {
packagePaths, err := pathsToPackagePaths(paths)
if err != nil || len(packagePaths) == 0 {
return nil, err
}
return partitionPathsAsDirectories(cmdArgs, packagePaths)
}
func pathsToPackagePaths(paths []string) ([]string, error) {
packages := []string{}
for _, path := range paths {
pkg, err := packageNameFromPath(path)
if err != nil {
return nil, err
}
packages = append(packages, pkg)
}
return packages, nil
}
func packageNameFromPath(path string) (string, error) {
if !filepath.IsAbs(path) {
return path, nil
}
for _, gopath := range getGoPathList() {
rel, err := filepath.Rel(filepath.Join(gopath, "src"), path)
if err != nil {
continue
}
return rel, nil
}
return "", fmt.Errorf("%s not in GOPATH", path)
}
func partitionPathsByDirectory(cmdArgs []string, paths []string) ([][]string, error) {
parts := [][]string{}
for _, path := range paths {
parts = append(parts, append(cmdArgs, path))
}
return parts, nil
}
1
https://gitee.com/lonely0422/gometalinter.git
git@gitee.com:lonely0422/gometalinter.git
lonely0422
gometalinter
gometalinter
v3.0.0

搜索帮助