-
Notifications
You must be signed in to change notification settings - Fork 450
/
languages.go
87 lines (78 loc) · 2.82 KB
/
languages.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// Copyright 2021 Security Scorecard Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package githubrepo
import (
"context"
"fmt"
"path"
"sync"
"github.com/google/go-github/v38/github"
"github.com/ossf/scorecard/v4/clients"
)
type languagesHandler struct {
ghclient *github.Client
once *sync.Once
ctx context.Context
errSetup error
repourl *repoURL
languages []clients.Language
}
func (handler *languagesHandler) init(ctx context.Context, repourl *repoURL) {
handler.ctx = ctx
handler.repourl = repourl
handler.errSetup = nil
handler.once = new(sync.Once)
}
// TODO: Can add support to parse the raw reponse JSON and mark languages that are not in
// our defined Language consts in clients/languages.go as "not supported languages".
func (handler *languagesHandler) setup() error {
handler.once.Do(func() {
client := handler.ghclient
reqURL := path.Join("repos", handler.repourl.owner, handler.repourl.repo, "languages")
req, err := client.NewRequest("GET", reqURL, nil)
if err != nil {
handler.errSetup = fmt.Errorf("request for repo languages failed with %w", err)
return
}
bodyJSON := map[clients.LanguageName]int{}
// The client.repoClient.Do API writes the reponse body to var bodyJSON,
// so we can ignore the first returned variable (the entire http response object)
// since we only need the response body here.
_, err = client.Do(handler.ctx, req, &bodyJSON)
if err != nil {
handler.errSetup = fmt.Errorf("response for repo languages failed with %w", err)
return
}
// Parse the raw JSON to an array of languages.
for k, v := range bodyJSON {
// TODO: once the const defined in clients/languages.go becomes a complete list of langs supported,
// add support here so that for not supported langs, it emits an "not-supported" error and break the parse.
// Currently, we are parsing all the JSON-returned langs into the result since the const is incomplete.
handler.languages = append(handler.languages,
clients.Language{
Name: k,
NumLines: v,
},
)
}
handler.errSetup = nil
})
return handler.errSetup
}
func (handler *languagesHandler) listProgrammingLanguages() ([]clients.Language, error) {
if err := handler.setup(); err != nil {
return nil, fmt.Errorf("error during languagesHandler.setup: %w", err)
}
return handler.languages, nil
}