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
 | |
| }
 |