Skip to content

Commit d41944f

Browse files
change func proto
1 parent 712d30d commit d41944f

File tree

7 files changed

+56
-137
lines changed

7 files changed

+56
-137
lines changed
File renamed without changes.

backend/cmd/compile_user_code.go

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,25 @@ import (
1616
"github.com/pkg/errors"
1717
)
1818

19+
type CompileUserCodeResult struct {
20+
Ok bool
21+
Result []byte
22+
Msg string
23+
}
24+
1925
const CompilationMemoryLimit = 100 * 1024 * 1024
2026
const CompilationTimeLimit = 10 * time.Second
2127

28+
var ErrCompilationError = errors.New("compilation error")
29+
2230
// it is required that the docker image is built before the program runs
2331
const imageCompile = "markhuang1212/code-grader/runtime-compile:latest"
2432

2533
// The function compiles user's code inside a docker container, and returns the
2634
// executable on success
27-
func CompileUserCode(ctx context.Context, gr types.GradeRequest) ([]byte, error) {
35+
func CompileUserCode(ctx context.Context, gr types.GradeRequest) (*CompileUserCodeResult, error) {
36+
37+
result := &CompileUserCodeResult{}
2838

2939
ctxdl, cancel := context.WithTimeout(ctx, CompilationTimeLimit)
3040
defer cancel()
@@ -50,7 +60,7 @@ func CompileUserCode(ctx context.Context, gr types.GradeRequest) ([]byte, error)
5060
}, nil, nil, "")
5161

5262
if err != nil {
53-
return nil, errors.Wrap(ErrInternalError, "cannot create container")
63+
return nil, errors.Wrap(err, "cannot create container")
5464
}
5565

5666
hjresp, err := cli.ContainerAttach(ctxdl, resp.ID, dockertypes.ContainerAttachOptions{
@@ -59,14 +69,14 @@ func CompileUserCode(ctx context.Context, gr types.GradeRequest) ([]byte, error)
5969
})
6070

6171
if err != nil {
62-
return nil, errors.Wrap(ErrInternalError, "cannot attach container")
72+
return nil, errors.Wrap(err, "cannot attach container")
6373
}
6474

6575
statusCh, errCh := cli.ContainerWait(ctxdl, resp.ID, container.WaitConditionNextExit)
6676

6777
err = cli.ContainerStart(ctxdl, resp.ID, dockertypes.ContainerStartOptions{})
6878
if err != nil {
69-
return nil, errors.Wrap(ErrInternalError, "cannot start container")
79+
return nil, errors.Wrap(ErrCompilationError, "cannot start container")
7080
}
7181

7282
defer func() {
@@ -85,7 +95,7 @@ func CompileUserCode(ctx context.Context, gr types.GradeRequest) ([]byte, error)
8595
hjresp.Close()
8696

8797
if err != nil {
88-
return nil, errors.Wrap(ErrInternalError, "cannot close attached session (output)")
98+
return nil, errors.Wrap(err, "cannot close attached session (output)")
8999
}
90100

91101
select {
@@ -97,26 +107,30 @@ func CompileUserCode(ctx context.Context, gr types.GradeRequest) ([]byte, error)
97107
ShowStderr: false,
98108
})
99109
if err != nil {
100-
return nil, errors.Wrap(ErrInternalError, "error reading stdout")
110+
return nil, errors.Wrap(err, "error reading stdout")
101111
}
102-
result, _ := io.ReadAll(stdout)
112+
program, _ := io.ReadAll(stdout)
113+
result.Ok = true
114+
result.Result = program
103115
return result, nil
104116
case 1:
105117
stderr, err := cli.ContainerLogs(ctxdl, resp.ID, dockertypes.ContainerLogsOptions{
106118
ShowStderr: true,
107119
ShowStdout: false,
108120
})
109121
if err != nil {
110-
return nil, errors.Wrap(ErrInternalError, "error reading stdout")
122+
return nil, errors.Wrap(err, "error reading stdout")
111123
}
112-
result, _ := io.ReadAll(stderr)
113-
return result, ErrCompilationError
124+
errText, _ := io.ReadAll(stderr)
125+
result.Msg = string(errText)
126+
result.Ok = false
127+
return result, nil
114128
case 2:
115-
return nil, ErrInternalError
129+
return nil, ErrCompilationError
116130
default:
117-
return nil, ErrInternalError
131+
return nil, ErrCompilationError
118132
}
119-
case <-errCh:
120-
return nil, errors.Wrap(ErrInternalError, "error waiting container")
133+
case err := <-errCh:
134+
return nil, errors.Wrap(err, "error waiting container")
121135
}
122136
}

backend/cmd/compile_user_code_test.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,19 @@ func TestCompileUserCode(t *testing.T) {
1717
UserCode: " ",
1818
}
1919

20-
out, err := cmd.CompileUserCode(ctx, gr1)
21-
assert.ErrorIs(t, err, cmd.ErrCompilationError)
22-
t.Log(out)
20+
result, err := cmd.CompileUserCode(ctx, gr1)
21+
assert.Nil(t, err)
22+
assert.False(t, result.Ok)
23+
t.Log(result)
2324

2425
gr2 := types.GradeRequest{
2526
TestCaseName: "example-1",
2627
UserCode: "int main() { cout << \"Hello\" << endl; }",
2728
}
2829

29-
out, err = cmd.CompileUserCode(ctx, gr2)
30-
assert.Equal(t, err, nil)
31-
t.Log(out)
30+
result, err = cmd.CompileUserCode(ctx, gr2)
31+
assert.Nil(t, err)
32+
assert.True(t, result.Ok)
33+
t.Log(result)
3234

3335
}

backend/cmd/errors.go

Lines changed: 0 additions & 12 deletions
This file was deleted.

backend/cmd/exec_user_code.go

Lines changed: 7 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -2,118 +2,21 @@ package cmd
22

33
import (
44
"context"
5-
"encoding/json"
6-
"io"
7-
"os"
8-
"path/filepath"
9-
"time"
105

11-
dockertypes "github.com/docker/docker/api/types"
12-
"github.com/docker/docker/api/types/container"
13-
"github.com/docker/docker/client"
14-
"github.com/docker/docker/pkg/stdcopy"
156
"github.com/markhuang1212/code-grader/backend/types"
16-
"github.com/pkg/errors"
177
)
188

199
const imageExec = "markhuang1212/code-grader/runtime-exec:latest"
2010

21-
func ExecUserCode(ctx context.Context, gr types.GradeRequest) ([]byte, error) {
22-
23-
var testCase types.TestCaseOptions
24-
25-
testCaseJson, err := os.ReadFile(filepath.Join(GetAppRoot(), "testcases", gr.TestCaseName, "testcase.json"))
26-
if err != nil {
27-
return nil, errors.Wrap(ErrInternalError, "cannot open testcase.json")
28-
}
29-
30-
err = json.Unmarshal(testCaseJson, &testCase)
31-
if err != nil {
32-
return nil, errors.Wrap(ErrInternalError, "cannot parse testcase.json")
33-
}
34-
35-
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
36-
if err != nil {
37-
return nil, errors.Wrap(ErrInternalError, "cannot create docker client")
38-
}
39-
40-
resp, err := cli.ContainerCreate(ctx, &container.Config{
41-
Image: imageExec,
42-
Env: []string{
43-
"TEST_CASE_DIR=" + filepath.Join("/code-grader/testcases", gr.TestCaseName),
44-
},
45-
OpenStdin: true,
46-
StdinOnce: true,
47-
}, &container.HostConfig{
48-
NetworkMode: "none",
49-
Resources: container.Resources{
50-
Memory: CompilationMemoryLimit,
51-
},
52-
}, nil, nil, "")
53-
54-
if err != nil {
55-
return nil, errors.Wrap(ErrInternalError, "cannot create container")
56-
}
57-
58-
hjresp, err := cli.ContainerAttach(ctx, resp.ID, dockertypes.ContainerAttachOptions{
59-
Stream: true,
60-
Stdin: true,
61-
Stdout: true,
62-
Stderr: true,
63-
})
64-
65-
if err != nil {
66-
return nil, errors.Wrap(ErrInternalError, "cannot attach container")
67-
}
68-
69-
ctxdl, cancel := context.WithTimeout(ctx, time.Second*time.Duration(testCase.RuntimeOptions.RuntimeLimit))
70-
defer cancel()
71-
72-
statusCh, errCh := cli.ContainerWait(ctxdl, resp.ID, container.WaitConditionNextExit)
73-
74-
err = cli.ContainerStart(ctxdl, resp.ID, dockertypes.ContainerStartOptions{})
75-
if err != nil {
76-
return nil, errors.Wrap(ErrInternalError, "cannot start container")
77-
}
11+
type ExecUserCodeResult struct {
12+
Ok bool
13+
Msg string
14+
}
7815

79-
defer cli.ContainerRemove(ctx, resp.ID, dockertypes.ContainerRemoveOptions{
80-
Force: true,
81-
})
82-
defer cli.ContainerStop(ctx, resp.ID, nil)
16+
func ExecUserCode(ctx context.Context, gr types.GradeRequest) (*ExecUserCodeResult, error) {
8317

84-
outR, outW := io.Pipe()
85-
errR, errW := io.Pipe()
86-
hjresp.Conn.Write([]byte(gr.UserCode))
87-
hjresp.Conn.Close()
88-
stdcopy.StdCopy(outW, errW, hjresp.Conn)
89-
outW.Close()
90-
errW.Close()
18+
result := &ExecUserCodeResult
9119

92-
select {
93-
case status := <-statusCh:
94-
switch status.StatusCode {
95-
case 0: // success
96-
result, err := io.ReadAll(outR)
97-
if err != nil {
98-
return nil, errors.Wrap(ErrInternalError, "error reading outR")
99-
}
100-
return result, nil
101-
case 1: // wrong result
102-
result, err := io.ReadAll(errR)
103-
if err != nil {
104-
return nil, errors.Wrap(ErrInternalError, "error reading errR")
105-
}
106-
return result, ErrCompilationError
107-
case 2: // internal error
108-
return nil, ErrInternalError
109-
default:
110-
return nil, ErrInternalError
111-
}
112-
case err := <-errCh:
113-
if errors.Is(err, context.DeadlineExceeded) {
114-
return nil, ErrTimeLimitExceed
115-
}
116-
return nil, errors.Wrap(ErrInternalError, "error waiting container")
117-
}
20+
return result, nil
11821

11922
}

backend/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ require (
77
github.com/docker/docker v20.10.7+incompatible
88
github.com/docker/go-connections v0.4.0 // indirect
99
github.com/gin-gonic/gin v1.7.2
10+
github.com/morikuni/aec v1.0.0 // indirect
1011
github.com/pkg/errors v0.9.1
1112
github.com/sirupsen/logrus v1.8.1 // indirect
1213
github.com/stretchr/testify v1.7.0
1314
google.golang.org/grpc v1.38.0 // indirect
14-
gotest.tools/v3 v3.0.3
1515
)

backend/go.sum

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
2323
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
2424
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
2525
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
26+
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
2627
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
2728
github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
2829
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
@@ -266,6 +267,7 @@ github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL9
266267
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
267268
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
268269
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
270+
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
269271
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
270272
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
271273
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
@@ -342,6 +344,7 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m
342344
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
343345
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
344346
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
347+
github.com/gorilla/mux v1.7.2 h1:zoNxOV7WjqXptQOVngLmcSQgXmgk4NMz1HibBchjl/I=
345348
github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
346349
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
347350
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
@@ -391,9 +394,11 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv
391394
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
392395
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
393396
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
397+
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
394398
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
395399
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
396400
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
401+
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
397402
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
398403
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
399404
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
@@ -419,13 +424,16 @@ github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQ
419424
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
420425
github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
421426
github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ=
427+
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd h1:aY7OQNf2XqY/JQ6qREWamhI/81os/agb2BAGpcx5yWI=
422428
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
423429
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
424430
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
425431
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
426432
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
427433
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
428434
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
435+
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
436+
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
429437
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
430438
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
431439
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
@@ -761,11 +769,13 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
761769
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
762770
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
763771
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
772+
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
764773
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
765774
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
766775
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
767776
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
768777
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
778+
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s=
769779
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
770780
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
771781
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -807,6 +817,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
807817
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
808818
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
809819
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
820+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
810821
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
811822
google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
812823
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
@@ -880,6 +891,7 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
880891
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
881892
gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
882893
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
894+
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
883895
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
884896
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
885897
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=

0 commit comments

Comments
 (0)