Skip to content

Commit 48fc311

Browse files
authored
Merge pull request #64 from codecrafters-io/feat-add-ping-command
feat(ping): add ping command to test connection to repository
2 parents 56b8f56 + 8a16a3e commit 48fc311

File tree

3 files changed

+125
-0
lines changed

3 files changed

+125
-0
lines changed

cmd/codecrafters/main.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ COMMANDS
3333
submit: Commit changes & submit to move to next step
3434
task: View current stage instructions
3535
update-buildpack: Update language version
36+
ping: Test the connection to a CodeCrafters repository
3637
help: Show usage instructions
3738
3839
VERSION
@@ -91,6 +92,8 @@ func run() error {
9192
return commands.TaskCommand(*stageSlug, *raw)
9293
case "update-buildpack":
9394
return commands.UpdateBuildpackCommand()
95+
case "ping":
96+
return commands.PingCommand()
9497
case "help",
9598
"": // no argument
9699
flag.Usage()

internal/client/ping.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package client
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
7+
"github.com/levigross/grequests"
8+
)
9+
10+
type PingResponse struct {
11+
Actions []ActionDefinition `json:"actions"`
12+
}
13+
14+
func (c CodecraftersClient) Ping(repositoryId string) (PingResponse, error) {
15+
response, err := grequests.Post(c.ServerUrl+"/services/cli/ping", &grequests.RequestOptions{
16+
JSON: map[string]interface{}{
17+
"repository_id": repositoryId,
18+
},
19+
Headers: c.headers(),
20+
})
21+
22+
if err != nil {
23+
return PingResponse{}, fmt.Errorf("failed to ping CodeCrafters: %s", err)
24+
}
25+
26+
if !response.Ok {
27+
return PingResponse{}, fmt.Errorf("failed to ping CodeCrafters. status code: %d, body: %s", response.StatusCode, response.String())
28+
}
29+
30+
pingResponse := PingResponse{}
31+
32+
err = json.Unmarshal(response.Bytes(), &pingResponse)
33+
if err != nil {
34+
return PingResponse{}, fmt.Errorf("failed to parse ping response: %s", err)
35+
}
36+
37+
return pingResponse, nil
38+
}

internal/commands/ping.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package commands
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
7+
"github.com/codecrafters-io/cli/internal/actions"
8+
"github.com/codecrafters-io/cli/internal/client"
9+
"github.com/codecrafters-io/cli/internal/globals"
10+
"github.com/codecrafters-io/cli/internal/utils"
11+
"github.com/getsentry/sentry-go"
12+
)
13+
14+
func PingCommand() (err error) {
15+
utils.Logger.Debug().Msg("ping command starts")
16+
17+
defer func() {
18+
utils.Logger.Debug().Err(err).Msg("ping command ends")
19+
}()
20+
21+
defer func() {
22+
if p := recover(); p != nil {
23+
utils.Logger.Panic().Str("panic", fmt.Sprintf("%v", p)).Stack().Msg("panic")
24+
sentry.CurrentHub().Recover(p)
25+
26+
panic(p)
27+
}
28+
29+
if err == nil {
30+
return
31+
}
32+
33+
var noRepo utils.NoCodecraftersRemoteFoundError
34+
if errors.Is(err, &noRepo) {
35+
// ignore
36+
return
37+
}
38+
39+
sentry.CurrentHub().CaptureException(err)
40+
}()
41+
42+
utils.Logger.Debug().Msg("computing repository directory")
43+
44+
repoDir, err := utils.GetRepositoryDir()
45+
if err != nil {
46+
return err
47+
}
48+
49+
utils.Logger.Debug().Msgf("found repository directory: %s", repoDir)
50+
51+
utils.Logger.Debug().Msg("identifying remotes")
52+
53+
codecraftersRemote, err := utils.IdentifyGitRemote(repoDir)
54+
if err != nil {
55+
return err
56+
}
57+
58+
utils.Logger.Debug().Msgf("identified remote: %s, %s", codecraftersRemote.Name, codecraftersRemote.Url)
59+
60+
globals.SetCodecraftersServerURL(codecraftersRemote.CodecraftersServerURL())
61+
codecraftersClient := client.NewCodecraftersClient()
62+
63+
utils.Logger.Debug().Msg("sending ping request")
64+
65+
pingResponse, err := codecraftersClient.Ping(codecraftersRemote.CodecraftersRepositoryId())
66+
if err != nil {
67+
return fmt.Errorf("ping: %w", err)
68+
}
69+
70+
utils.Logger.Debug().Msgf("received %d actions", len(pingResponse.Actions))
71+
72+
for _, actionDefinition := range pingResponse.Actions {
73+
action, err := actions.ActionFromDefinition(actionDefinition)
74+
if err != nil {
75+
return fmt.Errorf("parse action: %w", err)
76+
}
77+
78+
if err := action.Execute(); err != nil {
79+
return fmt.Errorf("execute action: %w", err)
80+
}
81+
}
82+
83+
return nil
84+
}

0 commit comments

Comments
 (0)