prow/plugins/golint/golint.go
func problemsInFiles(r *git.Repo, files map[string]string) (map[string]map[int]lint.Problem, []github.DraftReviewComment) {
	problems := make(map[string]map[int]lint.Problem)
	var lintErrorComments []github.DraftReviewComment
	l := new(lint.Linter)
	for f, patch := range files {
		problems[f] = make(map[int]lint.Problem)
		src, err := ioutil.ReadFile(filepath.Join(r.Dir, f))
		if err != nil {
			lintErrorComments = append(lintErrorComments, github.DraftReviewComment{
				Path: f,
				Body: fmt.Sprintf("%v", err),
			})
		}
		ps, err := l.Lint(f, src)
		if err != nil {
			// Get error line by parsing the error message
			errLineIndexStart := strings.LastIndex(err.Error(), f) + len(f)
			reNumber := regexp.MustCompile(`:([0-9]+):`)
			matches := reNumber.FindStringSubmatch(err.Error()[errLineIndexStart:])
			newComment := github.DraftReviewComment{
				Path: f,
				Body: err.Error(),
			}
			if len(matches) > 1 {
				errLineString := matches[1]
				errLine, errAtoi := strconv.Atoi(errLineString)
				if errAtoi == nil {
					newComment.Position = errLine
				}
				// Trim error message to after the line and column numbers
				reTrimError := regexp.MustCompile(`(:[0-9]+:[0-9]+: )`)
				matches = reTrimError.FindStringSubmatch(err.Error())
				if len(matches) > 0 {
					newComment.Body = err.Error()[len(matches[0])+errLineIndexStart:]
				}
			}
			lintErrorComments = append(lintErrorComments, newComment)
		}
		al, err := AddedLines(patch)
		if err != nil {
			lintErrorComments = append(lintErrorComments,
				github.DraftReviewComment{
					Path: f,
					Body: fmt.Sprintf("computing added lines in %s: %v", f, err),
				})
		}
		for _, p := range ps {
			if pl, ok := al[p.Position.Line]; ok {
				problems[f][pl] = p
			}
		}
	}
	return problems, lintErrorComments
}
func problemsInFiles(r *git.Repo, files map[string]string) (map[string]map[int]lint.Problem, []github.DraftReviewComment) {
	problems := make(map[string]map[int]lint.Problem)
	var lintErrorComments []github.DraftReviewComment
	l := new(lint.Linter)
	for f, patch := range files {
		problems[f] = make(map[int]lint.Problem)
		src, err := ioutil.ReadFile(filepath.Join(r.Dir, f))
		if err != nil {
			lintErrorComments = append(lintErrorComments, github.DraftReviewComment{
				Path: f,
				Body: fmt.Sprintf("%v", err),
			})
		}
		ps, err := l.Lint(f, src)
		if err != nil {
			// Get error line by parsing the error message
			errLineIndexStart := strings.LastIndex(err.Error(), f) + len(f)
			reNumber := regexp.MustCompile(`:([0-9]+):`)
			matches := reNumber.FindStringSubmatch(err.Error()[errLineIndexStart:])
			newComment := github.DraftReviewComment{
				Path: f,
				Body: err.Error(),
			}
			if len(matches) > 1 {
				errLineString := matches[1]
				errLine, errAtoi := strconv.Atoi(errLineString)
				if errAtoi == nil {
					newComment.Position = errLine
				}
				// Trim error message to after the line and column numbers
				reTrimError := regexp.MustCompile(`(:[0-9]+:[0-9]+: )`)
				matches = reTrimError.FindStringSubmatch(err.Error())
				if len(matches) > 0 {
					newComment.Body = err.Error()[len(matches[0])+errLineIndexStart:]
				}
			}
			lintErrorComments = append(lintErrorComments, newComment)
		}
		al, err := AddedLines(patch)
		if err != nil {
			lintErrorComments = append(lintErrorComments,
				github.DraftReviewComment{
					Path: f,
					Body: fmt.Sprintf("computing added lines in %s: %v", f, err),
				})
		}
		for _, p := range ps {
			if pl, ok := al[p.Position.Line]; ok {
				problems[f][pl] = p
			}
		}
	}
	return problems, lintErrorComments
}
// problemsInFiles runs golint on the files. It returns a map from the file to
// a map from the line in the patch to the problem.