func ProcessDir()

in pkg/linguist/linguist.go [196:293]


func ProcessDir(dirname string) ([]*Language, error) {
	var (
		langs     = make(map[string]int)
		totalSize int
	)
	if err := initLinguistAttributes(dirname); err != nil {
		return nil, err
	}
	exists, err := osutil.Exists(dirname)
	if err != nil {
		return nil, err
	}
	if !exists {
		return nil, os.ErrNotExist
	}
	filepath.Walk(dirname, func(path string, file os.FileInfo, err error) error {
		size := int(file.Size())
		log.Debugf("with file: %s", path)
		log.Debugln(path, "is", size, "bytes")
		if isIgnored(path) {
			log.Debugln(path, "is ignored, skipping")
			if file.IsDir() {
				return filepath.SkipDir
			}
			return nil
		}
		if size == 0 {
			log.Debugln(path, "is empty file, skipping")
			return nil
		}
		if file.IsDir() {
			if file.Name() == ".git" {
				log.Debugln(".git directory, skipping")
				return filepath.SkipDir
			}
		} else if (file.Mode() & os.ModeSymlink) == 0 {
			log.Debugf("%s: filename to be ignored: %s", path, strconv.FormatBool(ShouldIgnoreFilename(path)))
			if ShouldIgnoreFilename(path) {
				log.Debugf("%s: filename should be ignored, skipping", path)
				return nil
			}

			byGitAttr := isDetectedInGitAttributes(path)
			if byGitAttr != "" {
				log.Debugln(path, "got result by .gitattributes: ", byGitAttr)
				langs[byGitAttr] += size
				totalSize += size
				return nil
			}

			if byName := LanguageByFilename(path); byName != "" {
				log.Debugln(path, "got result by name: ", byName)
				langs[byName] += size
				totalSize += size
				return nil
			}

			contents, err := fileGetContents(path)
			if err != nil {
				return err
			}

			if ShouldIgnoreContents(contents) {
				log.Debugln(path, ": contents should be ignored, skipping")
				return nil
			}

			hints := LanguageHints(path)
			log.Debugf("%s got language hints: %#v\n", path, hints)
			byData := LanguageByContents(contents, hints)

			if byData != "" {
				log.Debugln(path, "got result by data: ", byData)
				langs[byData] += size
				totalSize += size
				return nil
			}

			log.Debugln(path, "got no result!!")
			langs["(unknown)"] += size
			totalSize += size
		}
		return nil
	})

	results := []*Language{}
	for lang, size := range langs {
		l := &Language{
			Language: lang,
			Percent:  (float64(size) / float64(totalSize)) * 100.0,
			Color:    LanguageColor(lang),
		}
		results = append(results, l)
		log.Debugf("language: %s percent: %f color: %s", l.Language, l.Percent, l.Color)
	}
	sort.Sort(sort.Reverse(sortableResult(results)))
	return results, nil
}