func (c *RepoCmd) Execute(args []string) error { if localRepo != nil { fmt.Println("# Local repository:") fmt.Printf("Root directory:\t%s\n", localRepo.RootDir) fmt.Printf("VCS type:\t%s\n", localRepo.VCSType) fmt.Printf("Commit ID:\t%s\n", localRepo.CommitID) fmt.Printf("Clone URL:\t%s\n", localRepo.CloneURL) fmt.Println() if localRepoErr != nil { fmt.Printf("# Warning: %s\n", localRepoErr) fmt.Println("# Not trying to fetch and display remote repository information due to the above error.") } else { cl := NewAPIClientWithAuthIfPresent() remoteRepo, err := getRemoteRepo(cl) if err == nil { fmt.Println("# Remote repository:") printRemoteRepo(remoteRepo) } else if sourcegraph.IsHTTPErrorCode(err, http.StatusNotFound) { fmt.Println("# No remote repository found.") fmt.Println("# Use `src remote add` to create it.") } else { fmt.Printf("# Error getting remote repository: %s.\n", err) } } } else { fmt.Println("# No local git/hg repository found in or above the current directory.") if localRepoErr != nil { fmt.Printf("# Error was: %s.\n", localRepoErr) } } return nil }
func (c *RemoteCmd) getRemoteRepo(cl *sourcegraph.Client) (*sourcegraph.Repo, error) { if c.RepoURI == "" { lrepo, err := openLocalRepo() var errMsg string if lrepo == nil { errMsg = "no git/hg repository found in or above the current dir" } else if err == errNoVCSCloneURL { errMsg = err.Error() + "\n\n" } else { errMsg = err.Error() } return nil, errors.New(errMsg + "; to specify which remote repository to act upon instead of attempting automatic detection, use --repo (e.g., '--repo github.com/owner/repo')") } rrepo, _, err := cl.Repos.Get(sourcegraph.RepoSpec{URI: c.RepoURI}, nil) if sourcegraph.IsHTTPErrorCode(err, http.StatusNotFound) { return nil, fmt.Errorf("No repository exists on the remote with the URI %q. To add it, use 'src remote add'. The underlying error was: %s", c.RepoURI, err) } return rrepo, err }
// getCommitWithRefreshAndRetry tries to get a repository commit. If // it doesn't exist, it triggers a refresh of the repo's VCS data and // then retries (until maxGetCommitVCSRefreshWait has elapsed). func getCommitWithRefreshAndRetry(cl *sourcegraph.Client, repoRevSpec sourcegraph.RepoRevSpec) (*sourcegraph.Commit, error) { timeout := time.After(maxGetCommitVCSRefreshWait) done := make(chan struct{}) var commit *sourcegraph.Commit var err error go func() { refreshTriggered := false for { commit, _, err = cl.Repos.GetCommit(repoRevSpec, nil) // Keep retrying if it's a 404, but stop trying if we succeeded, or if it's some other // error. if !sourcegraph.IsHTTPErrorCode(err, http.StatusNotFound) { break } if !refreshTriggered { _, err = cl.Repos.RefreshVCSData(repoRevSpec.RepoSpec) if err != nil { err = fmt.Errorf("failed to trigger VCS refresh for repo %s: %s", repoRevSpec.URI, err) break } log.Printf("Repository %s revision %s wasn't found on remote. Triggered refresh of VCS data; waiting %s.", repoRevSpec.URI, repoRevSpec.Rev, maxGetCommitVCSRefreshWait) refreshTriggered = true } time.Sleep(time.Second) } done <- struct{}{} }() select { case <-done: return commit, err case <-timeout: return nil, fmt.Errorf("repo %s revision %s not found on remote, even after triggering a VCS refresh and waiting %s (if you are sure that commit has been pushed, try again later)", repoRevSpec.URI, repoRevSpec.Rev, maxGetCommitVCSRefreshWait) } }