dependabot-go_modules 0.87.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/helpers/Makefile +9 -0
- data/helpers/build +26 -0
- data/helpers/go.mod +13 -0
- data/helpers/go.sum +6 -0
- data/helpers/importresolver/main.go +34 -0
- data/helpers/main.go +77 -0
- data/helpers/updatechecker/main.go +107 -0
- data/helpers/updater/go.mod +3 -0
- data/helpers/updater/go.sum +2 -0
- data/helpers/updater/helpers.go +57 -0
- data/helpers/updater/main.go +48 -0
- data/lib/dependabot/go_modules.rb +11 -0
- data/lib/dependabot/go_modules/file_fetcher.rb +66 -0
- data/lib/dependabot/go_modules/file_parser.rb +131 -0
- data/lib/dependabot/go_modules/file_updater.rb +73 -0
- data/lib/dependabot/go_modules/file_updater/go_mod_updater.rb +80 -0
- data/lib/dependabot/go_modules/metadata_finder.rb +58 -0
- data/lib/dependabot/go_modules/native_helpers.rb +20 -0
- data/lib/dependabot/go_modules/path_converter.rb +72 -0
- data/lib/dependabot/go_modules/requirement.rb +148 -0
- data/lib/dependabot/go_modules/update_checker.rb +114 -0
- data/lib/dependabot/go_modules/version.rb +43 -0
- metadata +191 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: bb5f0e8824ed0a3c60ce0cfc69bddb79e1d3d543df45e7e5682a56162a4890b2
|
4
|
+
data.tar.gz: a4b0207e8c5c10f44897928e6f7c8710d941ef80b76209d923c9c2bf1a0379ed
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d3da4238b2bf752585fa3e892a48a88e5edc9c76b1ea9de1dff18a68be9a839f0664ae8602414e718d7f5d9726fb91ba4ae11b3a74b1bf57d4b7499442805ae4
|
7
|
+
data.tar.gz: 655b4ab4aaf213cafd84a88f956a029c6d28c088dc465b831a1f914e558fc98155fca27b566fea380ae5ec850e66497a445849d754ffeb11f1f38697f8288c67
|
data/helpers/Makefile
ADDED
data/helpers/build
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
install_dir=$1
|
6
|
+
if [ -z "$install_dir" ]; then
|
7
|
+
echo "usage: $0 INSTALL_DIR"
|
8
|
+
exit 1
|
9
|
+
fi
|
10
|
+
|
11
|
+
if ! [[ "$install_dir" =~ ^/ ]]; then
|
12
|
+
echo "$install_dir must be an absolute path"
|
13
|
+
exit 1
|
14
|
+
fi
|
15
|
+
|
16
|
+
if [ ! -d "$install_dir/bin" ]; then
|
17
|
+
mkdir -p "$install_dir/bin"
|
18
|
+
fi
|
19
|
+
|
20
|
+
helpers_dir="$(dirname "${BASH_SOURCE[0]}")"
|
21
|
+
cd $helpers_dir
|
22
|
+
|
23
|
+
os="$(uname -s | tr '[:upper:]' '[:lower:]')"
|
24
|
+
echo "building $install_dir/bin/helper"
|
25
|
+
|
26
|
+
GO111MODULE=on GOOS="$os" GOARCH=amd64 go build -o "$install_dir/bin/helper" .
|
data/helpers/go.mod
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
module github.com/dependabot/dependabot-core/go_modules/helpers
|
2
|
+
|
3
|
+
require (
|
4
|
+
github.com/Masterminds/vcs v1.12.0
|
5
|
+
github.com/dependabot/dependabot-core/go_modules/helpers/updater v0.0.0
|
6
|
+
github.com/dependabot/gomodules-extracted v0.0.0-20181020215834-1b2f850478a3
|
7
|
+
)
|
8
|
+
|
9
|
+
replace github.com/dependabot/dependabot-core/go_modules/helpers/importresolver => ./importresolver
|
10
|
+
|
11
|
+
replace github.com/dependabot/dependabot-core/go_modules/helpers/updater => ./updater
|
12
|
+
|
13
|
+
replace github.com/dependabot/dependabot-core/go_modules/helpers/updatechecker => ./updatechecker
|
data/helpers/go.sum
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
github.com/Masterminds/vcs v1.12.0 h1:bt9Hb4XlfmEfLnVA0MVz2NO0GFuMN5vX8iOWW38Xde4=
|
2
|
+
github.com/Masterminds/vcs v1.12.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA=
|
3
|
+
github.com/dependabot/dependabot-core v0.74.6 h1:SB2Oyie+Ex9ARXLHbFrnoQSWSixAG4ORHA+s6YEvVag=
|
4
|
+
github.com/dependabot/dependabot-core v0.79.4 h1:d3/V6TTj+58ULw6824RK2zR+esZQw3bU/vRkCtCh4JU=
|
5
|
+
github.com/dependabot/gomodules-extracted v0.0.0-20181020215834-1b2f850478a3 h1:Xj2leY0FVyZuo+p59vkIWG3dIqo+QtjskT5O1iTiywA=
|
6
|
+
github.com/dependabot/gomodules-extracted v0.0.0-20181020215834-1b2f850478a3/go.mod h1:+dRXSrUymjpT4yzKtn1QmeknT1S/yAHRr35en18dHp8=
|
@@ -0,0 +1,34 @@
|
|
1
|
+
package importresolver
|
2
|
+
|
3
|
+
import (
|
4
|
+
"io/ioutil"
|
5
|
+
"strings"
|
6
|
+
|
7
|
+
"github.com/Masterminds/vcs"
|
8
|
+
)
|
9
|
+
|
10
|
+
type Args struct {
|
11
|
+
Import string
|
12
|
+
}
|
13
|
+
|
14
|
+
func VCSRemoteForImport(args *Args) (interface{}, error) {
|
15
|
+
remote := args.Import
|
16
|
+
scheme := strings.Split(remote, ":")[0]
|
17
|
+
switch scheme {
|
18
|
+
case "http", "https":
|
19
|
+
default:
|
20
|
+
remote = "https://" + remote
|
21
|
+
}
|
22
|
+
|
23
|
+
local, err := ioutil.TempDir("", "unused-vcs-local-dir")
|
24
|
+
if err != nil {
|
25
|
+
return nil, err
|
26
|
+
}
|
27
|
+
|
28
|
+
repo, err := vcs.NewRepo(remote, local)
|
29
|
+
if err != nil {
|
30
|
+
return nil, err
|
31
|
+
}
|
32
|
+
|
33
|
+
return repo.Remote(), nil
|
34
|
+
}
|
data/helpers/main.go
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
package main
|
2
|
+
|
3
|
+
import (
|
4
|
+
"encoding/json"
|
5
|
+
"fmt"
|
6
|
+
"log"
|
7
|
+
"os"
|
8
|
+
|
9
|
+
"github.com/dependabot/dependabot-core/go_modules/helpers/importresolver"
|
10
|
+
"github.com/dependabot/dependabot-core/go_modules/helpers/updatechecker"
|
11
|
+
"github.com/dependabot/dependabot-core/go_modules/helpers/updater"
|
12
|
+
)
|
13
|
+
|
14
|
+
type HelperParams struct {
|
15
|
+
Function string `json:"function"`
|
16
|
+
Args json.RawMessage `json:"args"`
|
17
|
+
}
|
18
|
+
|
19
|
+
type Output struct {
|
20
|
+
Error string `json:"error,omitempty"`
|
21
|
+
Result interface{} `json:"result,omitempty"`
|
22
|
+
}
|
23
|
+
|
24
|
+
func main() {
|
25
|
+
d := json.NewDecoder(os.Stdin)
|
26
|
+
helperParams := &HelperParams{}
|
27
|
+
if err := d.Decode(helperParams); err != nil {
|
28
|
+
abort(err)
|
29
|
+
}
|
30
|
+
|
31
|
+
var (
|
32
|
+
funcOut interface{}
|
33
|
+
funcErr error
|
34
|
+
)
|
35
|
+
switch helperParams.Function {
|
36
|
+
case "getUpdatedVersion":
|
37
|
+
var args updatechecker.Args
|
38
|
+
parseArgs(helperParams.Args, &args)
|
39
|
+
funcOut, funcErr = updatechecker.GetUpdatedVersion(&args)
|
40
|
+
case "updateDependencyFile":
|
41
|
+
var args updater.Args
|
42
|
+
parseArgs(helperParams.Args, &args)
|
43
|
+
funcOut, funcErr = updater.UpdateDependencyFile(&args)
|
44
|
+
case "getVcsRemoteForImport":
|
45
|
+
var args importresolver.Args
|
46
|
+
parseArgs(helperParams.Args, &args)
|
47
|
+
funcOut, funcErr = importresolver.VCSRemoteForImport(&args)
|
48
|
+
default:
|
49
|
+
abort(fmt.Errorf("Unrecognised function '%s'", helperParams.Function))
|
50
|
+
}
|
51
|
+
|
52
|
+
if funcErr != nil {
|
53
|
+
abort(funcErr)
|
54
|
+
}
|
55
|
+
|
56
|
+
output(&Output{Result: funcOut})
|
57
|
+
}
|
58
|
+
|
59
|
+
func parseArgs(data []byte, args interface{}) {
|
60
|
+
if err := json.Unmarshal(data, args); err != nil {
|
61
|
+
abort(err)
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
func output(o *Output) {
|
66
|
+
bytes, jsonErr := json.Marshal(o)
|
67
|
+
if jsonErr != nil {
|
68
|
+
log.Fatal(jsonErr)
|
69
|
+
}
|
70
|
+
|
71
|
+
os.Stdout.Write(bytes)
|
72
|
+
}
|
73
|
+
|
74
|
+
func abort(err error) {
|
75
|
+
output(&Output{Error: err.Error()})
|
76
|
+
os.Exit(1)
|
77
|
+
}
|
@@ -0,0 +1,107 @@
|
|
1
|
+
package updatechecker
|
2
|
+
|
3
|
+
import (
|
4
|
+
"errors"
|
5
|
+
"io/ioutil"
|
6
|
+
|
7
|
+
"github.com/dependabot/gomodules-extracted/cmd/go/_internal_/modfetch"
|
8
|
+
"github.com/dependabot/gomodules-extracted/cmd/go/_internal_/modfile"
|
9
|
+
"github.com/dependabot/gomodules-extracted/cmd/go/_internal_/modload"
|
10
|
+
"github.com/dependabot/gomodules-extracted/cmd/go/_internal_/semver"
|
11
|
+
)
|
12
|
+
|
13
|
+
type Dependency struct {
|
14
|
+
Name string `json:"name"`
|
15
|
+
Version string `json:"version"`
|
16
|
+
Indirect bool `json:"indirect"`
|
17
|
+
}
|
18
|
+
|
19
|
+
type IgnoreRange struct {
|
20
|
+
MinVersionInclusive string `json:"min_version_inclusive"`
|
21
|
+
MaxVersionExclusive string `json:"max_version_exclusive"`
|
22
|
+
}
|
23
|
+
|
24
|
+
type Args struct {
|
25
|
+
Dependency *Dependency `json:"dependency"`
|
26
|
+
IgnoreRanges []*IgnoreRange `json:"ignore_ranges"`
|
27
|
+
}
|
28
|
+
|
29
|
+
func GetUpdatedVersion(args *Args) (interface{}, error) {
|
30
|
+
if args.Dependency == nil {
|
31
|
+
return nil, errors.New("Expected args.dependency to not be nil")
|
32
|
+
}
|
33
|
+
|
34
|
+
modload.InitMod()
|
35
|
+
|
36
|
+
repo, err := modfetch.Lookup(args.Dependency.Name)
|
37
|
+
if err != nil {
|
38
|
+
return nil, err
|
39
|
+
}
|
40
|
+
|
41
|
+
versions, err := repo.Versions("")
|
42
|
+
if err != nil {
|
43
|
+
return nil, err
|
44
|
+
}
|
45
|
+
|
46
|
+
excludes, err := goModExcludes(args.Dependency.Name)
|
47
|
+
if err != nil {
|
48
|
+
return nil, err
|
49
|
+
}
|
50
|
+
|
51
|
+
currentVersion := args.Dependency.Version
|
52
|
+
currentMajor := semver.Major(currentVersion)
|
53
|
+
currentPrerelease := semver.Prerelease(currentVersion)
|
54
|
+
latestVersion := args.Dependency.Version
|
55
|
+
|
56
|
+
Outer:
|
57
|
+
for _, v := range versions {
|
58
|
+
if semver.Major(v) != currentMajor {
|
59
|
+
continue
|
60
|
+
}
|
61
|
+
|
62
|
+
if semver.Compare(v, latestVersion) < 1 {
|
63
|
+
continue
|
64
|
+
}
|
65
|
+
|
66
|
+
if currentPrerelease == "" && semver.Prerelease(v) != "" {
|
67
|
+
continue
|
68
|
+
}
|
69
|
+
|
70
|
+
for _, exclude := range excludes {
|
71
|
+
if v == exclude {
|
72
|
+
continue Outer
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
76
|
+
latestVersion = v
|
77
|
+
}
|
78
|
+
|
79
|
+
return latestVersion, nil
|
80
|
+
}
|
81
|
+
|
82
|
+
func goModExcludes(dependency string) ([]string, error) {
|
83
|
+
data, err := ioutil.ReadFile("go.mod")
|
84
|
+
if err != nil {
|
85
|
+
return nil, err
|
86
|
+
}
|
87
|
+
|
88
|
+
var f *modfile.File
|
89
|
+
// TODO library detection - don't consider exclude etc for libraries
|
90
|
+
if "library" == "true" {
|
91
|
+
f, err = modfile.ParseLax("go.mod", data, nil)
|
92
|
+
} else {
|
93
|
+
f, err = modfile.Parse("go.mod", data, nil)
|
94
|
+
}
|
95
|
+
if err != nil {
|
96
|
+
return nil, err
|
97
|
+
}
|
98
|
+
|
99
|
+
var excludes []string
|
100
|
+
for _, e := range f.Exclude {
|
101
|
+
if e.Mod.Path == dependency {
|
102
|
+
excludes = append(excludes, e.Mod.Version)
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
return excludes, nil
|
107
|
+
}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
package updater
|
2
|
+
|
3
|
+
import (
|
4
|
+
"strings"
|
5
|
+
|
6
|
+
"github.com/dependabot/gomodules-extracted/cmd/go/_internal_/modfile"
|
7
|
+
)
|
8
|
+
|
9
|
+
// Private methods lifted from the `modfile` package
|
10
|
+
|
11
|
+
// setIndirect sets line to have (or not have) a "// indirect" comment.
|
12
|
+
func setIndirect(line *modfile.Line, indirect bool) {
|
13
|
+
if isIndirect(line) == indirect {
|
14
|
+
return
|
15
|
+
}
|
16
|
+
if indirect {
|
17
|
+
// Adding comment.
|
18
|
+
if len(line.Suffix) == 0 {
|
19
|
+
// New comment.
|
20
|
+
line.Suffix = []modfile.Comment{{Token: "// indirect", Suffix: true}}
|
21
|
+
return
|
22
|
+
}
|
23
|
+
// Insert at beginning of existing comment.
|
24
|
+
com := &line.Suffix[0]
|
25
|
+
space := " "
|
26
|
+
if len(com.Token) > 2 && com.Token[2] == ' ' || com.Token[2] == '\t' {
|
27
|
+
space = ""
|
28
|
+
}
|
29
|
+
com.Token = "// indirect;" + space + com.Token[2:]
|
30
|
+
return
|
31
|
+
}
|
32
|
+
|
33
|
+
// Removing comment.
|
34
|
+
f := strings.Fields(line.Suffix[0].Token)
|
35
|
+
if len(f) == 2 {
|
36
|
+
// Remove whole comment.
|
37
|
+
line.Suffix = nil
|
38
|
+
return
|
39
|
+
}
|
40
|
+
|
41
|
+
// Remove comment prefix.
|
42
|
+
com := &line.Suffix[0]
|
43
|
+
i := strings.Index(com.Token, "indirect;")
|
44
|
+
com.Token = "//" + com.Token[i+len("indirect;"):]
|
45
|
+
}
|
46
|
+
|
47
|
+
// isIndirect reports whether line has a "// indirect" comment,
|
48
|
+
// meaning it is in go.mod only for its effect on indirect dependencies,
|
49
|
+
// so that it can be dropped entirely once the effective version of the
|
50
|
+
// indirect dependency reaches the given minimum version.
|
51
|
+
func isIndirect(line *modfile.Line) bool {
|
52
|
+
if len(line.Suffix) == 0 {
|
53
|
+
return false
|
54
|
+
}
|
55
|
+
f := strings.Fields(line.Suffix[0].Token)
|
56
|
+
return (len(f) == 2 && f[1] == "indirect" || len(f) > 2 && f[1] == "indirect;") && f[0] == "//"
|
57
|
+
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
package updater
|
2
|
+
|
3
|
+
import (
|
4
|
+
"io/ioutil"
|
5
|
+
|
6
|
+
"github.com/dependabot/gomodules-extracted/cmd/go/_internal_/modfile"
|
7
|
+
)
|
8
|
+
|
9
|
+
type Dependency struct {
|
10
|
+
Name string `json:"name"`
|
11
|
+
Version string `json:"version"`
|
12
|
+
Indirect bool `json:"indirect"`
|
13
|
+
}
|
14
|
+
|
15
|
+
type Args struct {
|
16
|
+
Dependencies []Dependency `json:"dependencies"`
|
17
|
+
}
|
18
|
+
|
19
|
+
func UpdateDependencyFile(args *Args) (interface{}, error) {
|
20
|
+
data, err := ioutil.ReadFile("go.mod")
|
21
|
+
if err != nil {
|
22
|
+
return nil, err
|
23
|
+
}
|
24
|
+
|
25
|
+
f, err := modfile.Parse("go.mod", data, nil)
|
26
|
+
if err != nil {
|
27
|
+
return nil, err
|
28
|
+
}
|
29
|
+
|
30
|
+
for _, dep := range args.Dependencies {
|
31
|
+
f.AddRequire(dep.Name, dep.Version)
|
32
|
+
}
|
33
|
+
|
34
|
+
for _, r := range f.Require {
|
35
|
+
for _, dep := range args.Dependencies {
|
36
|
+
if r.Mod.Path == dep.Name {
|
37
|
+
setIndirect(r.Syntax, dep.Indirect)
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
f.SortBlocks()
|
43
|
+
f.Cleanup()
|
44
|
+
|
45
|
+
newModFile, _ := f.Format()
|
46
|
+
|
47
|
+
return string(newModFile), nil
|
48
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# These all need to be required so the various classes can be registered in a
|
4
|
+
# lookup table of package manager names to concrete classes.
|
5
|
+
require "dependabot/go_modules/file_fetcher"
|
6
|
+
require "dependabot/go_modules/file_parser"
|
7
|
+
require "dependabot/go_modules/update_checker"
|
8
|
+
require "dependabot/go_modules/file_updater"
|
9
|
+
require "dependabot/go_modules/metadata_finder"
|
10
|
+
require "dependabot/go_modules/requirement"
|
11
|
+
require "dependabot/go_modules/version"
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dependabot/file_fetchers"
|
4
|
+
require "dependabot/file_fetchers/base"
|
5
|
+
|
6
|
+
module Dependabot
|
7
|
+
module GoModules
|
8
|
+
class FileFetcher < Dependabot::FileFetchers::Base
|
9
|
+
def self.required_files_in?(filenames)
|
10
|
+
filenames.include?("go.mod")
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.required_files_message
|
14
|
+
"Repo must contain a go.mod."
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def fetch_files
|
20
|
+
unless go_mod
|
21
|
+
raise(
|
22
|
+
Dependabot::DependencyFileNotFound,
|
23
|
+
File.join(directory, "go.mod")
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
fetched_files = [go_mod]
|
28
|
+
|
29
|
+
# Fetch the (optional) go.sum
|
30
|
+
fetched_files << go_sum if go_sum
|
31
|
+
|
32
|
+
# Fetch the main.go file if present, as this will later identify
|
33
|
+
# this repo as an app.
|
34
|
+
fetched_files << main if main
|
35
|
+
|
36
|
+
fetched_files
|
37
|
+
end
|
38
|
+
|
39
|
+
def go_mod
|
40
|
+
@go_mod ||= fetch_file_if_present("go.mod")
|
41
|
+
end
|
42
|
+
|
43
|
+
def go_sum
|
44
|
+
@go_sum ||= fetch_file_if_present("go.sum")
|
45
|
+
end
|
46
|
+
|
47
|
+
def main
|
48
|
+
return @main if @main
|
49
|
+
|
50
|
+
go_files = repo_contents.select { |f| f.name.end_with?(".go") }
|
51
|
+
|
52
|
+
go_files.each do |go_file|
|
53
|
+
file = fetch_file_from_host(go_file.name, type: "package_main")
|
54
|
+
next unless file.content.match?(/\s*package\s+main/)
|
55
|
+
|
56
|
+
return @main = file.tap { |f| f.support_file = true }
|
57
|
+
end
|
58
|
+
|
59
|
+
nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
Dependabot::FileFetchers.
|
66
|
+
register("go_modules", Dependabot::GoModules::FileFetcher)
|