예제 #1
0
파일: main.go 프로젝트: rexposadas/gx
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
	}
}
예제 #2
0
// 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.")
	}
}
예제 #3
0
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
}
예제 #4
0
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
}
예제 #5
0
// 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)
}
예제 #6
0
파일: main.go 프로젝트: rexposadas/gx
// 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)
	}
}
예제 #7
0
파일: main.go 프로젝트: rexposadas/gx
func (this *CmdTemplateDynamic2) NewCommand() *exec.Cmd {
	gist7802150.MakeUpdated(this)
	return this.Template.NewCommand()
}
예제 #8
0
파일: main.go 프로젝트: rexposadas/gx
func (this *pipeTemplateDynamic) NewPipe(stdout, stderr io.Writer) (*pipe.State, pipe.Pipe) {
	gist7802150.MakeUpdated(this)
	return this.Template.NewPipe(stdout, stderr)
}