Skip to content

Commit d534ef7

Browse files
committed
Support golang as package manager
1 parent 6504904 commit d534ef7

15 files changed

+135
-24
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ However, some packages have archived their source code repositories or have had
1919
| Python | poetry | poetry.lock | (later) |
2020
| Python | pipenv | Pipfile.lock | (later) |
2121
| PHP | composer | composer.lock | :heavy_check_mark: |
22-
| Go | | go.sum | (later) |
22+
| Go | golang | go.mod | :heavy_check_mark: |
2323
| Rust | cargo | Cargo.lock | (later) |
2424

2525
## Support repository hosting services

cmd/bundler.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ func (d *BundlerDoctor) Deps(r parser_io.ReadSeekerAt) []types.Library {
2323
return deps
2424
}
2525

26-
func (d *BundlerDoctor) SourceCodeURL(name string) (string, error) {
27-
rubyGems := RubyGems{name: name}
26+
func (d *BundlerDoctor) SourceCodeURL(lib types.Library) (string, error) {
27+
rubyGems := RubyGems{name: lib.Name}
2828
url, err := rubyGems.fetchURLFromRegistry(d.HTTPClient)
2929
return url, err
3030
}

cmd/composer.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ func (d *ComposerDoctor) Deps(r parser_io.ReadSeekerAt) []types.Library {
2323
return deps
2424
}
2525

26-
func (d *ComposerDoctor) SourceCodeURL(name string) (string, error) {
27-
packagist := Packagist{name: name}
26+
func (d *ComposerDoctor) SourceCodeURL(lib types.Library) (string, error) {
27+
packagist := Packagist{lib: lib}
2828
url, err := packagist.fetchURLFromRegistry(d.HTTPClient)
2929
return url, err
3030
}

cmd/diagnose.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ type Diagnosis struct {
3636

3737
type MedicalTechnician interface {
3838
Deps(r parser_io.ReadSeekerAt) []types.Library
39-
SourceCodeURL(name string) (string, error)
39+
SourceCodeURL(lib types.Library) (string, error)
4040
}
4141

4242
func FetchRepositoryParams(libs []types.Library, g MedicalTechnician) []github.FetchRepositoryParam {
@@ -54,7 +54,7 @@ func FetchRepositoryParams(libs []types.Library, g MedicalTechnician) []github.F
5454

5555
fmt.Printf("%s\n", lib.Name)
5656

57-
githubUrl, err := g.SourceCodeURL(lib.Name)
57+
githubUrl, err := g.SourceCodeURL(lib)
5858
if err != nil {
5959
return
6060
}
@@ -164,6 +164,7 @@ var doctors = map[string]MedicalTechnician{
164164
"pip": NewPipDoctor(),
165165
"npm": NewNPMDoctor(),
166166
"composer": NewComposerDoctor(),
167+
"golang": NewGolangDoctor(),
167168
}
168169

169170
var diagnoseCmd = &cobra.Command{

cmd/golang.go

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package cmd
2+
3+
import (
4+
"net/http"
5+
6+
"github.com/aquasecurity/go-dep-parser/pkg/golang/mod"
7+
parser_io "github.com/aquasecurity/go-dep-parser/pkg/io"
8+
"github.com/aquasecurity/go-dep-parser/pkg/types"
9+
)
10+
11+
type GolangDoctor struct {
12+
HTTPClient http.Client
13+
}
14+
15+
func NewGolangDoctor() *GolangDoctor {
16+
client := &http.Client{}
17+
return &GolangDoctor{HTTPClient: *client}
18+
}
19+
20+
func (d *GolangDoctor) Deps(r parser_io.ReadSeekerAt) []types.Library {
21+
p := &mod.Parser{}
22+
deps, _, _ := p.Parse(r)
23+
return deps
24+
}
25+
26+
func (d *GolangDoctor) SourceCodeURL(lib types.Library) (string, error) {
27+
proxyGolang := ProxyGolang{lib: lib}
28+
if len(lib.ExternalReferences) > 0 {
29+
return lib.ExternalReferences[0].URL, nil
30+
}
31+
32+
url, err := proxyGolang.fetchURLFromRegistry(d.HTTPClient)
33+
return url, err
34+
}

cmd/golang/mod/testdata/go.mod

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module github.com/org/repo
2+
3+
go 1.17
4+
5+
require github.com/aquasecurity/go-dep-parser v0.0.0-20211224170007-df43bca6b6ff
6+
7+
require (
8+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
9+
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
10+
)

cmd/nodejs.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"fmt"
77
"io"
88
"net/http"
9+
10+
"github.com/aquasecurity/go-dep-parser/pkg/types"
911
)
1012

1113
// https://docs.npmjs.com/cli/v8/using-npm/registry
@@ -18,11 +20,11 @@ type NodejsRegistryResponse struct {
1820
}
1921

2022
type Nodejs struct {
21-
name string
23+
lib types.Library
2224
}
2325

2426
func (n *Nodejs) fetchURLFromRegistry(client http.Client) (string, error) {
25-
url := fmt.Sprintf(NODEJS_REGISTRY_API, n.name)
27+
url := fmt.Sprintf(NODEJS_REGISTRY_API, n.lib.Name)
2628
req, err := http.NewRequest(http.MethodGet, url, nil)
2729
if err != nil {
2830
return "", err

cmd/nodejs_test.go

+8-5
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,20 @@ import (
55
"strings"
66
"testing"
77

8+
"github.com/aquasecurity/go-dep-parser/pkg/types"
89
"github.com/stretchr/testify/assert"
910
)
1011

1112
func TestNodejs_fetchURLFromRegistry(t *testing.T) {
1213
tests := []struct {
13-
name string
14-
dep_name string
14+
name string
15+
lib types.Library
1516
}{
1617
{
17-
name: "source_code_uri exists",
18-
dep_name: "react",
18+
name: "source_code_uri exists",
19+
lib: types.Library{
20+
Name: "react",
21+
},
1922
},
2023
}
2124
expects := []struct {
@@ -30,7 +33,7 @@ func TestNodejs_fetchURLFromRegistry(t *testing.T) {
3033

3134
for i, tt := range tests {
3235
t.Run(tt.name, func(t *testing.T) {
33-
n := Nodejs{name: tt.dep_name}
36+
n := Nodejs{lib: tt.lib}
3437
r, _ := n.fetchURLFromRegistry(http.Client{})
3538
expect := expects[i]
3639
assert.Equal(t, true, strings.HasPrefix(r, expect.url))

cmd/npm.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ func (d *NPMDoctor) Deps(r parser_io.ReadSeekerAt) []types.Library {
2222
return deps
2323
}
2424

25-
func (d *NPMDoctor) SourceCodeURL(name string) (string, error) {
26-
nodejs := Nodejs{name: name}
25+
func (d *NPMDoctor) SourceCodeURL(lib types.Library) (string, error) {
26+
nodejs := Nodejs{lib: lib}
2727
url, err := nodejs.fetchURLFromRegistry(d.HTTPClient)
2828
return url, err
2929
}

cmd/packagist.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"fmt"
77
"io"
88
"net/http"
9+
10+
"github.com/aquasecurity/go-dep-parser/pkg/types"
911
)
1012

1113
// https://packagist.org/apidoc#get-package-data
@@ -20,11 +22,11 @@ type PackagistRegistryResponse struct {
2022
}
2123

2224
type Packagist struct {
23-
name string
25+
lib types.Library
2426
}
2527

2628
func (p *Packagist) fetchURLFromRegistry(client http.Client) (string, error) {
27-
url := fmt.Sprintf(PACKAGIST_REGISTRY_API, p.name)
29+
url := fmt.Sprintf(PACKAGIST_REGISTRY_API, p.lib.Name)
2830
req, err := http.NewRequest(http.MethodGet, url, nil)
2931
if err != nil {
3032
return "", err
@@ -49,5 +51,5 @@ func (p *Packagist) fetchURLFromRegistry(client http.Client) (string, error) {
4951
return "", nil
5052
}
5153

52-
return registryResponse.Packages[p.name][0].Source.URL, nil
54+
return registryResponse.Packages[p.lib.Name][0].Source.URL, nil
5355
}

cmd/pip.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ func (d *PipDoctor) Deps(r parser_io.ReadSeekerAt) []types.Library {
2323
return deps
2424
}
2525

26-
func (d *PipDoctor) SourceCodeURL(name string) (string, error) {
27-
pypi := Pypi{name: name}
26+
func (d *PipDoctor) SourceCodeURL(lib types.Library) (string, error) {
27+
pypi := Pypi{name: lib.Name}
2828
url, err := pypi.fetchURLFromRegistry(d.HTTPClient)
2929
return url, err
3030
}

cmd/proxy_golang.go

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package cmd
2+
3+
import (
4+
"encoding/json"
5+
"errors"
6+
"fmt"
7+
"io"
8+
"net/http"
9+
10+
"github.com/aquasecurity/go-dep-parser/pkg/types"
11+
)
12+
13+
// https://proxy.golang.org/
14+
const PROXY_GOLANG_REGISTRY_API = "https://proxy.golang.org/%s/@latest"
15+
16+
type ProxyGolangRegistryResponse struct {
17+
Origin struct {
18+
Vcs string `json:"VCS"`
19+
URL string `json:"URL"`
20+
} `json:"Origin"`
21+
}
22+
23+
type ProxyGolang struct {
24+
lib types.Library
25+
}
26+
27+
func (g *ProxyGolang) fetchURLFromRegistry(client http.Client) (string, error) {
28+
url := fmt.Sprintf(PROXY_GOLANG_REGISTRY_API, g.lib.Name)
29+
req, err := http.NewRequest(http.MethodGet, url, nil)
30+
if err != nil {
31+
return "", err
32+
}
33+
34+
resp, err := client.Do(req)
35+
if err != nil {
36+
return "", err
37+
}
38+
39+
defer resp.Body.Close()
40+
if resp.StatusCode < 200 || 299 < resp.StatusCode {
41+
m := fmt.Sprintf("Got status code: %d from %s", resp.StatusCode, PROXY_GOLANG_REGISTRY_API)
42+
return "", errors.New(m)
43+
}
44+
45+
body, _ := io.ReadAll(resp.Body)
46+
47+
var ProxyGolangRegistryResponse ProxyGolangRegistryResponse
48+
err = json.Unmarshal(body, &ProxyGolangRegistryResponse)
49+
if err != nil {
50+
return "", err
51+
}
52+
53+
return ProxyGolangRegistryResponse.Origin.URL, nil
54+
}

cmd/yarn.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ func (d *YarnDoctor) Deps(r parser_io.ReadSeekerAt) []types.Library {
2323
return deps
2424
}
2525

26-
func (d *YarnDoctor) SourceCodeURL(name string) (string, error) {
27-
nodejs := Nodejs{name: name}
26+
func (d *YarnDoctor) SourceCodeURL(lib types.Library) (string, error) {
27+
nodejs := Nodejs{lib: lib}
2828
url, err := nodejs.fetchURLFromRegistry(d.HTTPClient)
2929
return url, err
3030
}

go.mod

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ require (
1616
go.uber.org/multierr v1.10.0 // indirect
1717
go.uber.org/zap v1.26.0 // indirect
1818
golang.org/x/exp v0.0.0-20220407100705-7b9b53b0aca4 // indirect
19+
golang.org/x/mod v0.13.0 // indirect
1920
golang.org/x/net v0.17.0 // indirect
2021
golang.org/x/sys v0.13.0 // indirect
2122
golang.org/x/text v0.13.0 // indirect
@@ -27,7 +28,7 @@ require (
2728

2829
require (
2930
github.com/MakeNowJust/heredoc v1.0.0
30-
github.com/aquasecurity/go-dep-parser v0.0.0-20231013060839-6f348921ea39
31+
github.com/aquasecurity/go-dep-parser v0.0.0-20231030050624-4548cca9a5c9
3132
github.com/fatih/color v1.15.0
3233
github.com/google/go-cmp v0.6.0
3334
github.com/inconshreveable/mousetrap v1.1.0 // indirect

go.sum

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ
22
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
33
github.com/aquasecurity/go-dep-parser v0.0.0-20231013060839-6f348921ea39 h1:5yB6PHCaU4yZzN1mMFnrpBerz2pgqYdDRRVSOj4EjVo=
44
github.com/aquasecurity/go-dep-parser v0.0.0-20231013060839-6f348921ea39/go.mod h1:RpdbxLhxxvWmv83HWNEiv+reFkmnV+GqHqr66mIU8nU=
5+
github.com/aquasecurity/go-dep-parser v0.0.0-20231030050624-4548cca9a5c9 h1:AYees+PQjw47SEdM6e/xxgrFzHA+UWxQl6WndDzILNY=
6+
github.com/aquasecurity/go-dep-parser v0.0.0-20231030050624-4548cca9a5c9/go.mod h1:RpdbxLhxxvWmv83HWNEiv+reFkmnV+GqHqr66mIU8nU=
57
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
68
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
79
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -53,6 +55,8 @@ go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
5355
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
5456
golang.org/x/exp v0.0.0-20220407100705-7b9b53b0aca4 h1:K3x+yU+fbot38x5bQbU2QqUAVyYLEktdNH2GxZLnM3U=
5557
golang.org/x/exp v0.0.0-20220407100705-7b9b53b0aca4/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
58+
golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
59+
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
5660
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
5761
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
5862
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=

0 commit comments

Comments
 (0)