func runChecks(config *checks.Config, change scm.Change, modes []checks.Mode, prereqReady *sync.WaitGroup) error { enabledChecks, options := config.EnabledChecks(modes) log.Printf("mode: %s; %d checks; %d max seconds allowed", modes, len(enabledChecks), options.MaxDuration) if change == nil { log.Printf("no change") return nil } var wg sync.WaitGroup errs := make(chan error, len(enabledChecks)) warnings := make(chan error, len(enabledChecks)) start := time.Now() for _, c := range enabledChecks { wg.Add(1) go func(check checks.Check) { defer wg.Done() if len(check.GetPrerequisites()) != 0 { // If this check has prerequisites, wait for all prerequisites to be // checked for presence. prereqReady.Wait() } log.Printf("%s...", check.GetName()) duration, err := callRun(check, change, options) if err != nil { log.Printf("... %s in %1.2fs FAILED\n%s", check.GetName(), duration.Seconds(), err) errs <- err return } log.Printf("... %s in %1.2fs", check.GetName(), duration.Seconds()) // A check that took too long is a check that failed. max := time.Duration(options.MaxDuration) * time.Second if duration > max { warnings <- fmt.Errorf("check %s took %1.2fs -> IT IS TOO SLOW (limit: %s)", check.GetName(), duration.Seconds(), max) } }(c) } wg.Wait() var err error for { select { case err = <-errs: fmt.Printf("%s\n", err) case warning := <-warnings: fmt.Printf("warning: %s\n", warning) default: if err != nil { duration := time.Now().Sub(start) return fmt.Errorf("checks failed in %1.2fs", duration.Seconds()) } return err } } }
func cmdWriteConfig(repo scm.ReadOnlyRepo, config *checks.Config, configPath string) error { config.MinVersion = version content, err := yaml.Marshal(config) if err != nil { return fmt.Errorf("internal error when marshaling config: %s", err) } _ = os.Remove(configPath) return ioutil.WriteFile(configPath, append([]byte(yamlHeader), content...), 0666) }
// cmdInstallPrereq installs all the packages needed to run the enabled checks. func cmdInstallPrereq(repo scm.ReadOnlyRepo, config *checks.Config, modes []checks.Mode, noUpdate bool) error { var wg sync.WaitGroup enabledChecks, _ := config.EnabledChecks(modes) number := 0 c := make(chan string, len(enabledChecks)) for _, check := range enabledChecks { for _, p := range check.GetPrerequisites() { number++ wg.Add(1) go func(prereq checks.CheckPrerequisite) { defer wg.Done() if !prereq.IsPresent() { c <- prereq.URL } }(p) } } wg.Wait() log.Printf("Checked for %d prerequisites", number) loop := true // Use a map to remove duplicates. m := map[string]bool{} for loop { select { case url := <-c: m[url] = true default: loop = false } } urls := make([]string, 0, len(m)) for url := range m { urls = append(urls, url) } wd, err := os.Getwd() if err != nil { return err } sort.Strings(urls) if len(urls) != 0 { if noUpdate { out := "-n is specified but prerequites are missing:\n" for _, url := range urls { out += " " + url + "\n" } return errors.New(out) } fmt.Printf("Installing:\n") for _, url := range urls { fmt.Printf(" %s\n", url) } out, _, err := internal.Capture(wd, nil, append([]string{"go", "get"}, urls...)...) if len(out) != 0 { return fmt.Errorf("prerequisites installation failed: %s", out) } if err != nil { return fmt.Errorf("prerequisites installation failed: %s", err) } } log.Printf("Prerequisites installation succeeded") return nil }