func ExampleGetRepoImportPathPattern() { fmt.Println(gist7480523.GetRepoImportPathPattern("/home/User/Go/src/github.com/owner/repo", "/home/User/Go/src")) fmt.Println(gist7480523.GetRepoImportPathPattern("/home/user/go/src/github.com/owner/repo", "/home/User/Go/src")) // Output: // github.com/owner/repo/... // github.com/owner/repo/... }
// 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 }
// RemoveRepo removes go-gettable repo with no local changes (by moving it into trash). // importPathPattern must match exactly with the repo root. // For example, "github.com/user/repo/...". func RemoveRepo(importPathPattern string) error { // TODO: Use an official Go package for `go list` functionality whenever possible. importPaths := gotool.ImportPaths([]string{importPathPattern}) if len(importPaths) == 0 { return errors.New("no packages to remove") } var firstGoPackage *gist7480523.GoPackage for i, importPath := range importPaths { goPackage := gist7480523.GoPackageFromImportPath(importPath) if goPackage == nil { return errors.New("Import Path not found: " + importPath) } if goPackage.Bpkg.Goroot { return errors.New("can't remove packages from GOROOT") } goPackage.UpdateVcs() if goPackage.Dir.Repo == nil { return errors.New("can't get repo status") } if i == 0 { firstGoPackage = goPackage } else if firstGoPackage.Dir.Repo != goPackage.Dir.Repo { return errors.New("matched Go Packages span more than 1 repo: " + firstGoPackage.Dir.Repo.Vcs.RootPath() + " != " + goPackage.Dir.Repo.Vcs.RootPath()) } else if !strings.HasPrefix(goPackage.Bpkg.Dir, firstGoPackage.Dir.Repo.Vcs.RootPath()) { // TODO: This is probably not neccessary... return errors.New("Go Package not inside repo: " + goPackage.Bpkg.Dir + " doesn't have prefix " + firstGoPackage.Dir.Repo.Vcs.RootPath()) } } if repoImportPathPattern := gist7480523.GetRepoImportPathPattern(firstGoPackage.Dir.Repo.Vcs.RootPath(), firstGoPackage.Bpkg.SrcRoot); repoImportPathPattern != importPathPattern { return errors.New("importPathPattern not exact repo root match: " + importPathPattern + " != " + repoImportPathPattern) } firstGoPackage.UpdateVcsFields() cleanStatus := func(goPackage *gist7480523.GoPackage) bool { packageStatus := presenter(goPackage)[:4] return packageStatus == " " || packageStatus == " + " // Updates are okay to ignore. } if !cleanStatus(firstGoPackage) { return errors.New("non-clean status: " + presenter(firstGoPackage)) } err := trash.MoveTo(firstGoPackage.Dir.Repo.Vcs.RootPath()) return err // TODO: Clean up /pkg folder contents, if any, etc. }