func (this *GoPackage) UpdateVcsFields() { if this.Dir.Repo == nil { return } gist7802150.MakeUpdated(this.Dir.Repo.VcsLocal) gist7802150.MakeUpdated(this.Dir.Repo.VcsRemote) repoImportPath := GetRepoImportPath(this.Dir.Repo.Vcs.RootPath(), this.Bpkg.SrcRoot) if repoRoot, err := vcs.RepoRootForImportPath(repoImportPath, false); err == nil { this.Dir.Repo.RepoRoot = repoRoot } }
// updateWorker is a sequential updater of Go packages. It does not update them in parallel // to avoid race conditions or other problems, since `go get -u` does not seem to protect against that. func updateWorker() { for updateRequest := range updateRequestChan { if !production { fmt.Println("got req:", updateRequest.importPathPattern) time.Sleep(time.Second) fmt.Println("Done.") updateRequest.resultChan <- nil continue } var updateErr = fmt.Errorf("import path pattern %q not found in GOPATH", updateRequest.importPathPattern) gist7802150.MakeUpdated(goPackages) for _, goPackage := range goPackages.List() { if rootPath := getRootPath(goPackage); rootPath != "" { if gist7480523.GetRepoImportPathPattern(rootPath, goPackage.Bpkg.SrcRoot) == updateRequest.importPathPattern { vcs := goPackage.Dir.Repo.RepoRoot.VCS fmt.Printf("cd %s\n", rootPath) fmt.Printf("%s %s", vcs.Cmd, vcs.DownloadCmd) updateErr = vcs.Download(rootPath) // Invalidate cache of the package's local revision, since it's expected to change after updating. gist7802150.ExternallyUpdated(goPackage.Dir.Repo.VcsLocal.GetSources()[1].(gist7802150.DepNode2ManualI)) break } } } updateRequest.resultChan <- updateErr fmt.Println("\nDone.") } }
func (u GopathUpdater) Update(importPathPattern string) error { // TODO: This uses a legacy gist7802150 caching/cache-invalidation system. It's functional, // but poorly documented, has known flaws (it does not allow concurrent updates), // and very contributor-unfriendly (people don't like packages that have the word "gist" in // the import path, even if's not actually a gist; which is understandable, since it's basically // a package without a name that describes what it's for - that's something acceptable during // rapid prototyping, but not for the finished product). Need to redesign it and replace with // something better. // // First step might be to simply drop the caching behavior and hope the user doesn't try // to manually refresh their browser page very often. var updateErr = fmt.Errorf("import path pattern %q not found in GOPATH", importPathPattern) gist7802150.MakeUpdated(u.GoPackages) for _, goPackage := range u.GoPackages.List() { if rootPath := util.GetRootPath(goPackage); rootPath != "" { if gist7480523.GetRepoImportPathPattern(rootPath, goPackage.Bpkg.SrcRoot) == importPathPattern { vcs := goPackage.Dir.Repo.RepoRoot.VCS fmt.Printf("cd %s\n", rootPath) fmt.Printf("%s %s", vcs.Cmd, vcs.DownloadCmd) updateErr = vcs.Download(rootPath) // Invalidate cache of the package's local revision, since it's expected to change after updating. gist7802150.ExternallyUpdated(goPackage.Dir.Repo.VcsLocal.GetSources()[1].(gist7802150.DepNode2ManualI)) break } } } return updateErr }
func newGitHubPresenter(repo *gist7480523.GoPackageRepo, gitHubOwner, gitHubRepo string) Presenter { goPackage := repo.GoPackages()[0] comparison := newGithubComparison(gitHubOwner, gitHubRepo, goPackage.Dir.Repo.VcsLocal, goPackage.Dir.Repo.VcsRemote) gist7802150.MakeUpdated(comparison) p := &gitHubPresenter{repo: repo, gitHubOwner: gitHubOwner, gitHubRepo: gitHubRepo, comparison: comparison} return p }
// Main index page handler. func mainHandler(w http.ResponseWriter, req *http.Request) { if err := loadTemplates(); err != nil { fmt.Fprintln(w, "loadTemplates:", err) return } //started := time.Now() CommonHat(w) defer CommonTail(w) io.WriteString(w, `<div id="checking_updates"><h2 style="text-align: center;">Checking for updates...</h2></div>`) io.WriteString(w, `<div id="no_updates" style="display: none;"><h2 style="text-align: center;">No Updates Available</h2></div>`) defer io.WriteString(w, `<script>document.getElementById("checking_updates").style.display = "none";</script>`) flusher := w.(http.Flusher) flusher.Flush() notifier := w.(http.CloseNotifier) go func() { <-notifier.CloseNotify() //fmt.Println("Exiting, since the HTTP request was cancelled/interrupted.") //close(updateRequestChan) }() //fmt.Printf("Part 1: %v ms.\n", time.Since(started).Seconds()*1000) // rootPath -> []*gist7480523.GoPackage var goPackagesInRepo = make(map[string][]*gist7480523.GoPackage) gist7802150.MakeUpdated(goPackages) //fmt.Printf("Part 1b: %v ms.\n", time.Since(started).Seconds()*1000) if false { for _, goPackage := range goPackages.List() { if rootPath := util.GetRootPath(goPackage); rootPath != "" { goPackagesInRepo[rootPath] = append(goPackagesInRepo[rootPath], goPackage) } } } else { inChan := make(chan interface{}) go func() { // This needs to happen in the background because sending input will be blocked on reading output. for _, goPackage := range goPackages.List() { inChan <- goPackage } close(inChan) }() reduceFunc := func(in interface{}) interface{} { goPackage := in.(*gist7480523.GoPackage) if rootPath := util.GetRootPath(goPackage); rootPath != "" { return gist7480523.NewGoPackageRepo(rootPath, []*gist7480523.GoPackage{goPackage}) } return nil } outChan := gist7651991.GoReduce(inChan, 64, reduceFunc) for out := range outChan { repo := out.(gist7480523.GoPackageRepo) goPackagesInRepo[repo.RootPath()] = append(goPackagesInRepo[repo.RootPath()], repo.GoPackages()[0]) } } //goon.DumpExpr(len(goPackages.List())) //goon.DumpExpr(len(goPackagesInRepo)) //fmt.Printf("Part 2: %v ms.\n", time.Since(started).Seconds()*1000) updatesAvailable := 0 inChan := make(chan interface{}) go func() { // This needs to happen in the background because sending input will be blocked on reading output. for rootPath, goPackages := range goPackagesInRepo { inChan <- gist7480523.NewGoPackageRepo(rootPath, goPackages) } close(inChan) }() reduceFunc := func(in interface{}) interface{} { repo := in.(gist7480523.GoPackageRepo) goPackage := repo.GoPackages()[0] goPackage.UpdateVcsFields() if !shouldPresentUpdate(goPackage) { return nil } repoPresenter := presenter.New(&repo) return repoPresenter } outChan := gist7651991.GoReduce(inChan, 8, reduceFunc) for out := range outChan { //started2 := time.Now() repoPresenter := out.(presenter.Presenter) updatesAvailable++ WriteRepoHtml(w, repoPresenter) flusher.Flush() //fmt.Printf("Part 2b: %v ms.\n", time.Since(started2).Seconds()*1000) /*log.Println("WriteRepoHtml") goon.DumpExpr(repoPresenter.Repo().ImportPathPattern()) goon.DumpExpr(repoPresenter.Repo().ImportPaths()) goon.DumpExpr(len(repoPresenter.Repo().GoPackages())) goon.DumpExpr(repoPresenter.Repo().GoPackages()[0].Bpkg.ImportPath) goon.DumpExpr(repoPresenter.Repo().GoPackages()[0].Dir.Repo.VcsLocal.LocalRev) goon.DumpExpr(repoPresenter.Repo().GoPackages()[0].Dir.Repo.VcsRemote.RemoteRev) goon.DumpExpr(repoPresenter.HomePage()) goon.DumpExpr(repoPresenter.Image()) var changes []presenter.Change if changesChan := repoPresenter.Changes(); changesChan != nil { for c := range changesChan { changes = append(changes, c) } } goon.DumpExpr(changes)*/ } if updatesAvailable == 0 { io.WriteString(w, `<script>document.getElementById("no_updates").style.display = "";</script>`) } //fmt.Printf("Part 3: %v ms.\n", time.Since(started).Seconds()*1000) }
// This is okay to call concurrently (a mutex is used internally). // Actually, not completely okay because MakeUpdated technology is not thread-safe. func (this *GoPackage) UpdateVcs() { if this.Bpkg.Goroot == false { // Optimization that assume packages under Goroot are not under vcs gist7802150.MakeUpdated(this.Dir) } }
func (this *CmdTemplateDynamic2) NewCommand() *exec.Cmd { gist7802150.MakeUpdated(this) return this.Template.NewCommand() }
func (this *pipeTemplateDynamic) NewPipe(stdout, stderr io.Writer) (*pipe.State, pipe.Pipe) { gist7802150.MakeUpdated(this) return this.Template.NewPipe(stdout, stderr) }