You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: check.go
    path of file: ./repos/goreportcard/check
    
    the code of the file until where you have to start completion: package check

import (
	"fmt"
	"log"
	"sort"
)

// Check describes what methods various checks (gofmt, go lint, etc.)
// should implement
type Check interface {
	Name() string
	Description() string
	Weight() float64
	// Percentage returns the passing percentage of the check,
	// as well as a map of filename to output
	Percentage() (float64, []FileSummary, error)
}

// Score represents the result of a single check
type Score struct {
	Name          string        `json:"name"`
	Description   string        `json:"description"`
	FileSummaries []FileSummary `json:"file_summaries"`
	Weight        float64       `json:"weight"`
	Percentag
    
func Run(dir string) (ChecksResult, error) {
	filenames, skipped, err := GoFiles(dir)
	if err != nil {
		return ChecksResult{}, fmt.Errorf("could not get filenames: %v", err)
	}
	if len(filenames) == 0 {
		return ChecksResult{}, fmt.Errorf("no .go files found")
	}

	err = RenameFiles(skipped)
	if err != nil {
		log.Println("Could not rename files:", err)
	}

	checks := []Check{
		GoFmt{Dir: dir, Filenames: filenames},
		GoVet{Dir: dir, Filenames: filenames},
		// GoLint{Dir: dir, Filenames: filenames},
		GoCyclo{Dir: dir, Filenames: filenames},
		License{Dir: dir, Filenames: []string{}},
		Misspell{Dir: dir, Filenames: filenames},
		IneffAssign{Dir: dir, Filenames: filenames},
		// Staticcheck{Dir: dir, Filenames: filenames},
		// ErrCheck{Dir: dir, Filenames: filenames}, // disable errcheck for now, too slow and not finalized
	}

	ch := make(chan Score)
	for _, c := range checks {
		go func(c Check) {
			p, summaries, err := c.Percentage()
			errMsg := ""
			if err != nil {
				log.Printf("ERROR: (%s) %v", c.Name(), err)
				errMsg = err.Error()
			}
			s := Score{
				Name:          c.Name(),
				Description:   c.Description(),
				FileSummaries: summaries,
				Weight:        c.Weight(),
				Percentage:    p,
				Error:         errMsg,
			}
			ch <- s
		}(c)
	}

	resp := ChecksResult{
		Files: len(filenames),
	}

	var total, totalWeight float64
	var issues = make(map[string]bool)
	for i := 0; i < len(checks); i++ {
		s := <-ch
		resp.Checks = append(resp.Checks, s)
		total += s.Percentage * s.Weight
		totalWeight += s.Weight
		for _, fs := range s.FileSummaries {
			issues[fs.Filename] = true
		}
		if s.Error != "" {
			resp.DidError = true
		}
	}
	total /= totalWeight

	sort.Sort(ByWeight(resp.Checks))
	resp.Average = total
	resp.Issues = len(issues)
	resp.Grade = GradeFromPercentage(total * 100)

	return resp, nil
}