func syncDependencies(plugins *core.PluginJSON, l *log.Logger, errChan chan errMsg) { // Sync each of them to get dependencies wg := &sync.WaitGroup{} rand.Seed(time.Now().UTC().UnixNano()) for url, version := range plugins.Dependencies { wg.Add(1) go func(url, version string) { defer wg.Done() // Check out specific commit var outB []byte var errB error if version != "*" { l.Debug("checking out", url, "at", version) p := filepath.Join(os.Getenv("GOPATH"), "src", url) c := fmt.Sprintf("git -C %s checkout %s", p, version) outB, errB = exec. Command("/bin/sh", "-c", c). CombinedOutput() if errB != nil { l.Debug(string(outB)) errChan <- errMsg{msg: "", err: errB} return } } // Anonymously increment the plugin's download count // at itsabot.org l.Debug("incrementing download count", url) p := struct{ Path string }{Path: url} outB, errB = json.Marshal(p) if errB != nil { errChan <- errMsg{msg: "failed to build itsabot.org JSON.", err: errB} return } var u string u = os.Getenv("ITSABOT_URL") + "/api/plugins.json" req, errB := http.NewRequest("PUT", u, bytes.NewBuffer(outB)) if errB != nil { errChan <- errMsg{msg: "failed to build request to itsabot.org.", err: errB} return } client := &http.Client{Timeout: 10 * time.Second} resp, errB := client.Do(req) if errB != nil { errChan <- errMsg{msg: "failed to update itsabot.org.", err: errB} return } defer func() { if errB = resp.Body.Close(); errB != nil { errChan <- errMsg{msg: "", err: errB} } }() if resp.StatusCode != 200 { l.Infof("WARN: %d - %s\n", resp.StatusCode, resp.Status) } }(url, version) } wg.Wait() // Ensure dependencies are still there with the latest checked out // versions, and install the plugins l.Info("Installing plugins...") outC, err := exec. Command("/bin/sh", "-c", "go get ./..."). CombinedOutput() if err != nil { errChan <- errMsg{msg: string(outC), err: err} return } embedPluginConfs(plugins, l) updateGlockfileAndInstall(l) errChan <- errMsg{msg: "Success!"} }