@@ -10,6 +10,7 @@ import (
1010 "github.com/sourcegraph/sourcegraph/internal/conf/reposource"
1111 "github.com/sourcegraph/sourcegraph/internal/extsvc"
1212 "github.com/sourcegraph/sourcegraph/internal/extsvc/perforce"
13+ "github.com/sourcegraph/sourcegraph/internal/gitserver"
1314 "github.com/sourcegraph/sourcegraph/internal/jsonc"
1415 "github.com/sourcegraph/sourcegraph/internal/types"
1516 "github.com/sourcegraph/sourcegraph/internal/vcs"
@@ -45,10 +46,19 @@ func newPerforceSource(svc *types.ExternalService, c *schema.PerforceConnection)
4546 }, nil
4647}
4748
48- // CheckConnection at this point assumes availability and relies on errors returned
49- // from the subsequent calls. This is going to be expanded as part of issue #44683
50- // to actually only return true if the source can serve requests .
49+ // CheckConnection tests the code host connection to make sure it works.
50+ // For Perforce, it uses the host (p4.port), username (p4.user) and password (p4.passwd)
51+ // from the code host configuration .
5152func (s PerforceSource ) CheckConnection (ctx context.Context ) error {
53+ // since CheckConnection is called from the frontend, we can't rely on the `p4` executable
54+ // being available, so we need to make an RPC call to `gitserver`, where it is available.
55+ // Use what is for us a "no-op" `p4` command that should always succeed.
56+ gclient := gitserver .NewClient ()
57+ rc , _ , err := gclient .P4Exec (ctx , s .config .P4Port , s .config .P4User , s .config .P4Passwd , "users" )
58+ if err != nil {
59+ return errors .Wrap (err , "Unable to connect to the Perforce server" )
60+ }
61+ rc .Close ()
5262 return nil
5363}
5464
@@ -85,12 +95,15 @@ func (s PerforceSource) ListRepos(ctx context.Context, results chan SourceResult
8595// composePerforceCloneURL composes a clone URL for a Perforce depot based on
8696// given information. e.g.
8797// perforce://ssl:111.222.333.444:1666//Sourcegraph/
88- func composePerforceCloneURL (host , depot string ) string {
98+ func composePerforceCloneURL (host , depot , username , password string ) string {
8999 cloneURL := url.URL {
90100 Scheme : "perforce" ,
91101 Host : host ,
92102 Path : depot ,
93103 }
104+ if username != "" && password != "" {
105+ cloneURL .User = url .UserPassword (username , password )
106+ }
94107 return cloneURL .String ()
95108}
96109
@@ -101,7 +114,7 @@ func (s PerforceSource) makeRepo(depot string) *types.Repo {
101114 name := strings .Trim (depot , "/" )
102115 urn := s .svc .URN ()
103116
104- cloneURL := composePerforceCloneURL (s .config .P4Port , depot )
117+ cloneURL := composePerforceCloneURL (s .config .P4Port , depot , "" , "" )
105118
106119 return & types.Repo {
107120 Name : reposource .PerforceRepoName (
0 commit comments