mirror of
https://github.com/KevinMidboe/linguist.git
synced 2025-10-29 17:50:22 +00:00
111 lines
2.1 KiB
Go
111 lines
2.1 KiB
Go
package compiler
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"os"
|
|
"os/exec"
|
|
"path"
|
|
"path/filepath"
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
type fsLoader struct {
|
|
*Repository
|
|
abspath string
|
|
}
|
|
|
|
var preferredGrammars = map[string]int{
|
|
".tmlanguage": 0,
|
|
".cson": 1,
|
|
".json": 1,
|
|
".plist": 2,
|
|
".yaml-tmlanguage": 3,
|
|
}
|
|
|
|
func findPreferredExtension(ext []string) string {
|
|
if len(ext) > 1 {
|
|
sort.Slice(ext, func(i, j int) bool {
|
|
a := strings.ToLower(ext[i])
|
|
b := strings.ToLower(ext[j])
|
|
return preferredGrammars[a] < preferredGrammars[b]
|
|
})
|
|
}
|
|
return ext[0]
|
|
}
|
|
|
|
func (l *fsLoader) findGrammars() (files []string, err error) {
|
|
grammars := make(map[string][]string)
|
|
|
|
err = filepath.Walk(l.abspath,
|
|
func(path string, info os.FileInfo, err error) error {
|
|
if err == nil && isValidGrammar(path, info) {
|
|
ext := filepath.Ext(path)
|
|
base := path[0 : len(path)-len(ext)]
|
|
grammars[base] = append(grammars[base], ext)
|
|
}
|
|
return nil
|
|
})
|
|
|
|
for base, ext := range grammars {
|
|
pref := findPreferredExtension(ext)
|
|
files = append(files, base+pref)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (l *fsLoader) load() {
|
|
grammars, err := l.findGrammars()
|
|
if err != nil {
|
|
l.Fail(err)
|
|
return
|
|
}
|
|
|
|
for _, path := range grammars {
|
|
data, err := ioutil.ReadFile(path)
|
|
if err != nil {
|
|
l.Fail(err)
|
|
continue
|
|
}
|
|
|
|
if rel, err := filepath.Rel(l.abspath, path); err == nil {
|
|
path = rel
|
|
}
|
|
|
|
rule, unknown, err := ConvertProto(filepath.Ext(path), data)
|
|
if err != nil {
|
|
l.Fail(&ConversionError{path, err})
|
|
continue
|
|
}
|
|
|
|
if _, ok := l.Files[rule.ScopeName]; ok {
|
|
continue
|
|
}
|
|
|
|
l.AddFile(path, rule, unknown)
|
|
}
|
|
}
|
|
|
|
func gitRemoteName(path string) (string, error) {
|
|
remote, err := exec.Command("git", "-C", path, "remote", "get-url", "origin").Output()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return strings.TrimSpace(string(remote)), nil
|
|
}
|
|
|
|
func LoadFromFilesystem(root, src string) *Repository {
|
|
loader := fsLoader{
|
|
Repository: newRepository(src),
|
|
abspath: path.Join(root, src),
|
|
}
|
|
loader.load()
|
|
|
|
if ups, err := gitRemoteName(loader.abspath); err == nil {
|
|
loader.Repository.Upstream = ups
|
|
}
|
|
|
|
return loader.Repository
|
|
}
|