dependabot-dep 0.90.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ad3792a0b60d7e2a72c30da5a98570a58b8da9f6902dd13f03caf0ca2af76f36
4
+ data.tar.gz: f09e301e1c1b3800f7a674d85943c2c9848993fdc8e652425b60f23fe4d06bf5
5
+ SHA512:
6
+ metadata.gz: bb482848e957c68149efc201af8cfa44862c2350e30f81bdd6f4324b62132bc48030c8c6368618608bb84389fc58ab9e4662cd89d26b1560cf83432b1e0f932c
7
+ data.tar.gz: 5467bdff0c0249674b448f3b6813a7d998e1d584186fbb4c9e71f636ca471916413169826e8e8c617b0f5349cd1b5461387345436449838c4a67d24644f83604
data/helpers/Makefile ADDED
@@ -0,0 +1,9 @@
1
+ .PHONY = all
2
+
3
+ all: darwin linux
4
+
5
+ darwin:
6
+ GO111MODULE=on GOOS=darwin GOARCH=amd64 go build -o go-helpers.darwin64 .
7
+
8
+ linux:
9
+ GO111MODULE=on GOOS=linux GOARCH=amd64 go build -o go-helpers.linux64 .
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,8 @@
1
+ module github.com/dependabot/dependabot-core/helpers/go
2
+
3
+ require (
4
+ github.com/Masterminds/vcs v1.12.0
5
+ github.com/dependabot/dependabot-core/helpers/go/importresolver v0.0.0
6
+ )
7
+
8
+ replace github.com/dependabot/dependabot-core/helpers/go/importresolver => ./importresolver
data/helpers/go.sum ADDED
@@ -0,0 +1,2 @@
1
+ github.com/Masterminds/vcs v1.12.0 h1:bt9Hb4XlfmEfLnVA0MVz2NO0GFuMN5vX8iOWW38Xde4=
2
+ github.com/Masterminds/vcs v1.12.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA=
@@ -0,0 +1 @@
1
+ module github.com/dependabot/dependabot-core/helpers/go/importresolver
@@ -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,67 @@
1
+ package main
2
+
3
+ import (
4
+ "encoding/json"
5
+ "fmt"
6
+ "log"
7
+ "os"
8
+
9
+ "github.com/dependabot/dependabot-core/helpers/go/importresolver"
10
+ )
11
+
12
+ type HelperParams struct {
13
+ Function string `json:"function"`
14
+ Args json.RawMessage `json:"args"`
15
+ }
16
+
17
+ type Output struct {
18
+ Error string `json:"error,omitempty"`
19
+ Result interface{} `json:"result,omitempty"`
20
+ }
21
+
22
+ func main() {
23
+ d := json.NewDecoder(os.Stdin)
24
+ helperParams := &HelperParams{}
25
+ if err := d.Decode(helperParams); err != nil {
26
+ abort(err)
27
+ }
28
+
29
+ var (
30
+ funcOut interface{}
31
+ funcErr error
32
+ )
33
+ switch helperParams.Function {
34
+ case "getVcsRemoteForImport":
35
+ var args importresolver.Args
36
+ parseArgs(helperParams.Args, &args)
37
+ funcOut, funcErr = importresolver.VCSRemoteForImport(&args)
38
+ default:
39
+ abort(fmt.Errorf("Unrecognised function '%s'", helperParams.Function))
40
+ }
41
+
42
+ if funcErr != nil {
43
+ abort(funcErr)
44
+ }
45
+
46
+ output(&Output{Result: funcOut})
47
+ }
48
+
49
+ func parseArgs(data []byte, args interface{}) {
50
+ if err := json.Unmarshal(data, args); err != nil {
51
+ abort(err)
52
+ }
53
+ }
54
+
55
+ func output(o *Output) {
56
+ bytes, jsonErr := json.Marshal(o)
57
+ if jsonErr != nil {
58
+ log.Fatal(jsonErr)
59
+ }
60
+
61
+ os.Stdout.Write(bytes)
62
+ }
63
+
64
+ func abort(err error) {
65
+ output(&Output{Error: err.Error()})
66
+ os.Exit(1)
67
+ }
@@ -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/dep/file_fetcher"
6
+ require "dependabot/dep/file_parser"
7
+ require "dependabot/dep/update_checker"
8
+ require "dependabot/dep/file_updater"
9
+ require "dependabot/dep/metadata_finder"
10
+ require "dependabot/dep/requirement"
11
+ require "dependabot/dep/version"
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dependabot/file_fetchers"
4
+ require "dependabot/file_fetchers/base"
5
+
6
+ module Dependabot
7
+ module Dep
8
+ class FileFetcher < Dependabot::FileFetchers::Base
9
+ def self.required_files_in?(filenames)
10
+ (%w(Gopkg.toml Gopkg.lock) - filenames).empty?
11
+ end
12
+
13
+ def self.required_files_message
14
+ "Repo must contain a Gopkg.toml and Gopkg.lock."
15
+ end
16
+
17
+ private
18
+
19
+ def fetch_files
20
+ fetched_files = []
21
+ fetched_files << manifest if manifest
22
+ fetched_files << lockfile if lockfile
23
+
24
+ unless manifest
25
+ raise(
26
+ Dependabot::DependencyFileNotFound,
27
+ File.join(directory, "Gopkg.toml")
28
+ )
29
+ end
30
+
31
+ unless lockfile
32
+ raise(
33
+ Dependabot::DependencyFileNotFound,
34
+ File.join(directory, "Gopkg.lock")
35
+ )
36
+ end
37
+
38
+ # Fetch the main.go file if present, as this will later identify
39
+ # this repo as an app.
40
+ fetched_files << main if main
41
+ fetched_files
42
+ end
43
+
44
+ def manifest
45
+ @manifest ||= fetch_file_if_present("Gopkg.toml")
46
+ end
47
+
48
+ def lockfile
49
+ @lockfile ||= fetch_file_if_present("Gopkg.lock")
50
+ end
51
+
52
+ def main
53
+ return @main if @main
54
+
55
+ go_files = repo_contents.select { |f| f.name.end_with?(".go") }
56
+
57
+ go_files.each do |go_file|
58
+ file = fetch_file_from_host(go_file.name, type: "package_main")
59
+ next unless file.content.match?(/\s*package\s+main/)
60
+
61
+ return @main = file.tap { |f| f.support_file = true }
62
+ end
63
+
64
+ nil
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+ Dependabot::FileFetchers.register("dep", Dependabot::Dep::FileFetcher)
@@ -0,0 +1,189 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "toml-rb"
4
+
5
+ require "dependabot/errors"
6
+ require "dependabot/dependency"
7
+ require "dependabot/shared_helpers"
8
+ require "dependabot/source"
9
+
10
+ require "dependabot/file_parsers"
11
+ require "dependabot/file_parsers/base"
12
+ require "dependabot/dep/requirement"
13
+ require "dependabot/dep/path_converter"
14
+
15
+ # Relevant dep docs can be found at:
16
+ # - https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
17
+ # - https://github.com/golang/dep/blob/master/docs/Gopkg.lock.md
18
+ module Dependabot
19
+ module Dep
20
+ class FileParser < Dependabot::FileParsers::Base
21
+ require "dependabot/file_parsers/base/dependency_set"
22
+
23
+ REQUIREMENT_TYPES = %w(constraint override).freeze
24
+
25
+ def parse
26
+ dependency_set = DependencySet.new
27
+ dependency_set += manifest_dependencies
28
+ dependency_set += lockfile_dependencies
29
+ dependency_set.dependencies
30
+ end
31
+
32
+ private
33
+
34
+ def manifest_dependencies
35
+ dependency_set = DependencySet.new
36
+
37
+ REQUIREMENT_TYPES.each do |type|
38
+ parsed_file(manifest).fetch(type, []).each do |details|
39
+ next if lockfile && !appears_in_lockfile?(details.fetch("name"))
40
+ next if missing_version_in_manifest_and_lockfile(details)
41
+
42
+ dependency_set << Dependency.new(
43
+ name: details.fetch("name"),
44
+ version: version_from_declaration(details),
45
+ package_manager: "dep",
46
+ requirements: [{
47
+ requirement: requirement_from_declaration(details),
48
+ file: manifest.name,
49
+ groups: [],
50
+ source: source_from_declaration(details)
51
+ }]
52
+ )
53
+ end
54
+ end
55
+
56
+ dependency_set
57
+ end
58
+
59
+ def lockfile_dependencies
60
+ dependency_set = DependencySet.new
61
+
62
+ parsed_file(lockfile).fetch("projects", []).each do |details|
63
+ dependency_set << Dependency.new(
64
+ name: details.fetch("name"),
65
+ version: version_from_lockfile(details),
66
+ package_manager: "dep",
67
+ requirements: []
68
+ )
69
+ end
70
+
71
+ dependency_set
72
+ end
73
+
74
+ def version_from_lockfile(details)
75
+ details["version"]&.sub(/^v?/, "") || details.fetch("revision")
76
+ end
77
+
78
+ def requirement_from_declaration(declaration)
79
+ unless declaration.is_a?(Hash)
80
+ raise "Unexpected dependency declaration: #{declaration}"
81
+ end
82
+
83
+ return if git_declaration?(declaration)
84
+
85
+ declaration["version"]
86
+ end
87
+
88
+ def source_from_declaration(declaration)
89
+ source = declaration["source"] || declaration["name"]
90
+
91
+ git_source_url = git_source(source)
92
+
93
+ if git_source_url && git_declaration?(declaration)
94
+ {
95
+ type: "git",
96
+ url: git_source_url,
97
+ branch: declaration["branch"],
98
+ ref: declaration["revision"] || declaration["version"]
99
+ }
100
+ elsif git_declaration?(declaration)
101
+ raise "No git source for a git declaration!"
102
+ else
103
+ {
104
+ type: "default",
105
+ source: source
106
+ }
107
+ end
108
+ end
109
+
110
+ def version_from_declaration(declaration)
111
+ lockfile_details =
112
+ parsed_file(lockfile).fetch("projects", []).
113
+ find { |details| details["name"] == declaration.fetch("name") }
114
+
115
+ if source_from_declaration(declaration).fetch(:type) == "git"
116
+ lockfile_details["revision"] ||
117
+ version_from_lockfile(lockfile_details)
118
+ else
119
+ version_from_lockfile(lockfile_details)
120
+ end
121
+ end
122
+
123
+ def appears_in_lockfile?(dependency_name)
124
+ parsed_file(lockfile).fetch("projects", []).
125
+ any? { |details| details["name"] == dependency_name }
126
+ end
127
+
128
+ def git_declaration?(declaration)
129
+ return true if declaration["branch"] || declaration["revision"]
130
+ return false unless declaration["version"]
131
+ return false unless declaration["version"].match?(/^[A-Za-z0-9]/)
132
+
133
+ Dep::Requirement.new(declaration["version"])
134
+ false
135
+ rescue Gem::Requirement::BadRequirementError
136
+ true
137
+ end
138
+
139
+ def git_source(path)
140
+ Dependabot::Dep::PathConverter.git_url_for_path(path)
141
+ rescue Dependabot::SharedHelpers::HelperSubprocessFailed => error
142
+ if error.message == "Cannot detect VCS"
143
+ msg = error.message + " for #{path}"
144
+ raise Dependabot::DependencyFileNotResolvable, msg
145
+ end
146
+
147
+ if error.message.end_with?("Not Found")
148
+ msg = "#{path} returned a 404"
149
+ raise Dependabot::DependencyFileNotResolvable, msg
150
+ end
151
+
152
+ raise
153
+ end
154
+
155
+ def parsed_file(file)
156
+ @parsed_file ||= {}
157
+ @parsed_file[file.name] ||= TomlRB.parse(file.content)
158
+ rescue TomlRB::ParseError
159
+ raise Dependabot::DependencyFileNotParseable, file.path
160
+ end
161
+
162
+ def manifest
163
+ @manifest ||= get_original_file("Gopkg.toml")
164
+ end
165
+
166
+ def lockfile
167
+ @lockfile ||= get_original_file("Gopkg.lock")
168
+ end
169
+
170
+ def check_required_files
171
+ %w(Gopkg.toml Gopkg.lock).each do |filename|
172
+ raise "No #{filename}!" unless get_original_file(filename)
173
+ end
174
+ end
175
+
176
+ def missing_version_in_manifest_and_lockfile(declaration)
177
+ return false if git_declaration?(declaration)
178
+
179
+ lockfile_decl =
180
+ parsed_file(lockfile).
181
+ fetch("projects", []).
182
+ find { |details| details["name"] == declaration["name"] }
183
+ lockfile_decl&.fetch("version", nil).nil?
184
+ end
185
+ end
186
+ end
187
+ end
188
+
189
+ Dependabot::FileParsers.register("dep", Dependabot::Dep::FileParser)
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dependabot/shared_helpers"
4
+ require "dependabot/file_updaters"
5
+ require "dependabot/file_updaters/base"
6
+
7
+ module Dependabot
8
+ module Dep
9
+ class FileUpdater < Dependabot::FileUpdaters::Base
10
+ require_relative "file_updater/manifest_updater"
11
+ require_relative "file_updater/lockfile_updater"
12
+
13
+ def self.updated_files_regex
14
+ [
15
+ /^Gopkg\.toml$/,
16
+ /^Gopkg\.lock$/,
17
+ /^go\.mod$/,
18
+ /^go\.sum$/
19
+ ]
20
+ end
21
+
22
+ def updated_dependency_files
23
+ updated_files = []
24
+
25
+ if manifest && file_changed?(manifest)
26
+ updated_files <<
27
+ updated_file(
28
+ file: manifest,
29
+ content: updated_manifest_content
30
+ )
31
+ end
32
+
33
+ if lockfile
34
+ updated_files <<
35
+ updated_file(file: lockfile, content: updated_lockfile_content)
36
+ end
37
+
38
+ raise "No files changed!" if updated_files.none?
39
+
40
+ updated_files
41
+ end
42
+
43
+ private
44
+
45
+ def check_required_files
46
+ return if get_original_file("Gopkg.toml")
47
+ return if get_original_file("go.mod")
48
+
49
+ raise "No Gopkg.toml or go.mod!"
50
+ end
51
+
52
+ def manifest
53
+ @manifest ||= get_original_file("Gopkg.toml")
54
+ end
55
+
56
+ def lockfile
57
+ @lockfile ||= get_original_file("Gopkg.lock")
58
+ end
59
+
60
+ def updated_manifest_content
61
+ ManifestUpdater.new(
62
+ dependencies: dependencies,
63
+ manifest: manifest
64
+ ).updated_manifest_content
65
+ end
66
+
67
+ def updated_lockfile_content
68
+ LockfileUpdater.new(
69
+ dependencies: dependencies,
70
+ dependency_files: dependency_files,
71
+ credentials: credentials
72
+ ).updated_lockfile_content
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ Dependabot::FileUpdaters.register("dep", Dependabot::Dep::FileUpdater)