diff options
| author | Can Eldem <celdem@gitlab.com> | 2020-06-04 08:53:19 +0000 |
|---|---|---|
| committer | Can Eldem <celdem@gitlab.com> | 2020-06-04 08:53:19 +0000 |
| commit | 834d7a4fdf3fd295386e4b12a31de81507d3a658 (patch) | |
| tree | b58db2991d16737d4942cad4b63949bc1330ba28 | |
| parent | a49e935ee3e2e07d90da7c78b543a5592a3b1a4a (diff) | |
| parent | cd9cd852dac41980169f0521eb795e460994367b (diff) | |
Merge branch 'heila-license-go-fix' into 'master'v3.11.1
List go modules found in `mod.sum` including modules that do not end up in vendor directory
See merge request gitlab-org/security-products/license-management!161
27 files changed, 692 insertions, 53 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bee703c..0c3e134 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -47,3 +47,5 @@ dependency_scanning: license_scanning: image: name: $TMP_IMAGE + variables: + LM_REPORT_VERSION: '2.1' diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a0a129..3dbd565 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # GitLab License management changelog +## v3.11.1 + +- Fix dependency scanning in golang projects. (!160) +- Parse `go.sum` files to support offline environments (!161) + ## v3.11.0 - Add support for providing custom [Conan](https://conan.io/) configuration. (!159) diff --git a/Gemfile.lock b/Gemfile.lock index a35044f..a3b02e0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - license-management (3.11.0) + license-management (3.11.1) license_finder (~> 6.0.0) GEM diff --git a/lib/license/finder/ext/go_modules.rb b/lib/license/finder/ext/go_modules.rb index e2f025f..d22c59c 100644 --- a/lib/license/finder/ext/go_modules.rb +++ b/lib/license/finder/ext/go_modules.rb @@ -2,42 +2,91 @@ module LicenseFinder class GoModules + FORMAT = "'{{.Main}},{{.Path}},{{.Version}},{{.Dir}}'" + HEADER = [:main_module, :name, :version, :dir].freeze + def prepare - shell.execute([:go, :env]) - shell.execute([:go, :mod, :tidy, '-v', '&&', :go, :mod, :vendor, '-v']) - end + return if vendored? - def active? - sum_files.any? + shell.execute([:go, :mod, :download, '-json']) end def current_packages - stdout, _stderr, status = shell.execute(go_list_command) + modules = vendored? ? parse_go_sum : go_list_all + modules.map { |hash| map_from(hash) }.compact + end + + private + + def go_list_all + env = { 'GOFLAGS' => ENV.fetch('GOFLAGS', '-mod=readonly') } + command = [:go, :list, '-m', '-f', FORMAT, :all] + stdout, _stderr, status = shell.execute(command, env: env) return [] unless status.success? - stdout.each_line.map { |line| map_from(line) }.compact + stdout.each_line.map { |line| Hash[HEADER.zip(line.chomp.split(','))] } end - private + def parse_go_sum + go_sum_path + .each_line.map { |x| x.split(' ') } + .each_with_object({}) do |(name, version), memo| + next unless module_path?(name) - def sum_files - Pathname.glob(project_path.join('go.sum')) + memo["#{name}:#{version}"] = { + name: name, + version: version.split('/')[0], + dir: vendored_path_to(name) + } + end.values end - def go_list_command - [:go, :list, '-m', '-f', "'{{.Path}},{{.Version}},{{.Dir}}'", :all] + def map_from(hash) + return if hash[:main_module] == "true" + + Dependency.new( + 'Go', + hash[:name], + hash[:version], + install_path: install_dir_for(hash), + detection_path: go_sum_path + ) end - def absolute_project_path - @absolute_project_path ||= Pathname(project_path).cleanpath + def go_sum_path + @go_sum_path ||= Pathname.glob(project_path.join('go.sum')).find(&:exist?) end - def map_from(line) - name, version, dir = line.chomp.split(',') - return if dir.nil? - return if Pathname(dir).cleanpath == absolute_project_path + def vendor_path + @vendor_path ||= go_sum_path.parent.join('vendor') + end + + def vendored? + vendor_path.exist? && vendor_path.directory? + end + + def vendored_path_to(module_name) + vendor_path.join(module_name) + end + + def install_dir_for(hash) + dir = hash[:dir] + pathname = dir && !dir.empty? ? Pathname.new(dir) : vendored_path_to(hash[:name]) + pathname.exist? ? pathname : nil + end + + # https://golang.org/ref/mod#tmp_9 + def module_path?(module_path) + !module_path.start_with?('/') && + !module_path.end_with?('/') && + module_path.split('/').all? { |x| element?(x) } + end - Dependency.new('Go', name, version, install_path: dir, detection_path: sum_files.find(&:exist?)) + def element?(element) + !element.empty? && + !element.start_with?('.') && + !element.end_with?('.') && + element.match?(/\A[A-Za-z0-9+-._~]+\Z/) end end end diff --git a/lib/license/management.rb b/lib/license/management.rb index 6306faf..3b8cb69 100644 --- a/lib/license/management.rb +++ b/lib/license/management.rb @@ -24,8 +24,8 @@ module License def self.logger @logger ||= Logger.new(STDOUT, level: ENV.fetch('LOG_LEVEL', Logger::WARN)).tap do |x| - x.formatter = proc do |severity, _datetime, _progname, message| - "#{severity} -- : #{message}\n" + x.formatter = proc do |_severity, _datetime, _progname, message| + "#{message}\n" end end end diff --git a/lib/license/management/shell.rb b/lib/license/management/shell.rb index 9ea66ca..9868f1e 100644 --- a/lib/license/management/shell.rb +++ b/lib/license/management/shell.rb @@ -18,7 +18,7 @@ module License stdout, stderr, status = Open3.capture3(env, expanded_command) - record(stdout, stderr) + record(stdout, stderr, status) [stdout, stderr, status] end @@ -76,9 +76,15 @@ module License !item.nil? && !item.empty? end - def record(stdout, stderr) + def record(stdout, stderr, status) logger.debug(stdout) if present?(stdout) - logger.error(stderr) if present?(stderr) + return unless present?(stderr) + + if status.success? + logger.debug(stderr) + else + logger.error(stderr) + end end end end diff --git a/lib/license/management/version.rb b/lib/license/management/version.rb index e53a751..bf992e9 100644 --- a/lib/license/management/version.rb +++ b/lib/license/management/version.rb @@ -2,6 +2,6 @@ module License module Management - VERSION = '3.11.0' + VERSION = '3.11.1' end end diff --git a/spec/fixtures/expected/go/modules/v1.0.json b/spec/fixtures/expected/go/modules/v1.0.json index 83fdbdd..1433dbf 100644 --- a/spec/fixtures/expected/go/modules/v1.0.json +++ b/spec/fixtures/expected/go/modules/v1.0.json @@ -1,25 +1,42 @@ { "licenses": [ { - "count": 3, + "count": 5, "name": "MIT" }, { + "count": 2, + "name": "unknown" + }, + { "count": 1, "name": "ISC" }, { "count": 1, - "name": "New BSD" + "name": "MIT, Apache 2.0" }, { "count": 1, - "name": "unknown" + "name": "New BSD" } ], "dependencies": [ { "license": { + "name": "MIT", + "url": "http://opensource.org/licenses/mit-license" + }, + "dependency": { + "name": "github.com/astaxie/beego", + "description": "", + "pathes": [ + "." + ] + } + }, + { + "license": { "name": "ISC", "url": "http://en.wikipedia.org/wiki/ISC_license" }, @@ -75,6 +92,19 @@ "url": "http://opensource.org/licenses/mit-license" }, "dependency": { + "name": "github.com/stretchr/objx", + "description": "", + "pathes": [ + "." + ] + } + }, + { + "license": { + "name": "MIT", + "url": "http://opensource.org/licenses/mit-license" + }, + "dependency": { "name": "github.com/stretchr/testify", "description": "", "pathes": [ @@ -94,6 +124,31 @@ "." ] } + }, + { + "license": { + "name": "unknown" + }, + "dependency": { + "name": "gopkg.in/check.v1", + "description": "", + "pathes": [ + "." + ] + } + }, + { + "license": { + "name": "MIT, Apache 2.0", + "url": "http://opensource.org/licenses/mit-license" + }, + "dependency": { + "name": "gopkg.in/yaml.v2", + "description": "", + "pathes": [ + "." + ] + } } ] }
\ No newline at end of file diff --git a/spec/fixtures/expected/go/modules/v1.1.json b/spec/fixtures/expected/go/modules/v1.1.json index 3e0b543..6316bec 100644 --- a/spec/fixtures/expected/go/modules/v1.1.json +++ b/spec/fixtures/expected/go/modules/v1.1.json @@ -2,26 +2,49 @@ "version": "1.1", "licenses": [ { - "count": 3, + "count": 5, "name": "MIT" }, { + "count": 2, + "name": "unknown" + }, + { "count": 1, "name": "ISC" }, { "count": 1, - "name": "New BSD" + "name": "MIT, Apache 2.0" }, { "count": 1, - "name": "unknown" + "name": "New BSD" } ], "dependencies": [ { "licenses": [ { + "name": "MIT", + "url": "http://opensource.org/licenses/mit-license" + } + ], + "license": { + "name": "MIT", + "url": "http://opensource.org/licenses/mit-license" + }, + "dependency": { + "name": "github.com/astaxie/beego", + "description": "", + "pathes": [ + "." + ] + } + }, + { + "licenses": [ + { "name": "ISC", "url": "http://en.wikipedia.org/wiki/ISC_license" } @@ -106,6 +129,25 @@ "url": "http://opensource.org/licenses/mit-license" }, "dependency": { + "name": "github.com/stretchr/objx", + "description": "", + "pathes": [ + "." + ] + } + }, + { + "licenses": [ + { + "name": "MIT", + "url": "http://opensource.org/licenses/mit-license" + } + ], + "license": { + "name": "MIT", + "url": "http://opensource.org/licenses/mit-license" + }, + "dependency": { "name": "github.com/stretchr/testify", "description": "", "pathes": [ @@ -131,6 +173,47 @@ "." ] } + }, + { + "licenses": [ + { + "name": "unknown", + "url": "" + } + ], + "license": { + "name": "unknown" + }, + "dependency": { + "name": "gopkg.in/check.v1", + "description": "", + "pathes": [ + "." + ] + } + }, + { + "licenses": [ + { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.txt" + }, + { + "name": "MIT", + "url": "http://opensource.org/licenses/mit-license" + } + ], + "license": { + "name": "MIT, Apache 2.0", + "url": "http://opensource.org/licenses/mit-license" + }, + "dependency": { + "name": "gopkg.in/yaml.v2", + "description": "", + "pathes": [ + "." + ] + } } ] }
\ No newline at end of file diff --git a/spec/fixtures/expected/go/modules/v2.0.json b/spec/fixtures/expected/go/modules/v2.0.json index b7dfe00..0e60fb8 100644 --- a/spec/fixtures/expected/go/modules/v2.0.json +++ b/spec/fixtures/expected/go/modules/v2.0.json @@ -5,7 +5,19 @@ "id": "MIT", "name": "MIT License", "url": "https://opensource.org/licenses/MIT", - "count": 3 + "count": 6 + }, + { + "id": "unknown", + "name": "unknown", + "url": "", + "count": 2 + }, + { + "id": "Apache-2.0", + "name": "Apache License 2.0", + "url": "https://opensource.org/licenses/Apache-2.0", + "count": 1 }, { "id": "BSD-3-Clause", @@ -18,16 +30,21 @@ "name": "ISC License", "url": "https://opensource.org/licenses/ISC", "count": 1 - }, - { - "id": "unknown", - "name": "unknown", - "url": "", - "count": 1 } ], "dependencies": [ { + "name": "github.com/astaxie/beego", + "url": "", + "description": "", + "paths": [ + "." + ], + "licenses": [ + "MIT" + ] + }, + { "name": "github.com/davecgh/go-spew", "url": "", "description": "", @@ -72,6 +89,17 @@ ] }, { + "name": "github.com/stretchr/objx", + "url": "", + "description": "", + "paths": [ + "." + ], + "licenses": [ + "MIT" + ] + }, + { "name": "github.com/stretchr/testify", "url": "", "description": "", @@ -92,6 +120,29 @@ "licenses": [ "BSD-3-Clause" ] + }, + { + "name": "gopkg.in/check.v1", + "url": "", + "description": "", + "paths": [ + "." + ], + "licenses": [ + "unknown" + ] + }, + { + "name": "gopkg.in/yaml.v2", + "url": "", + "description": "", + "paths": [ + "." + ], + "licenses": [ + "Apache-2.0", + "MIT" + ] } ] }
\ No newline at end of file diff --git a/spec/fixtures/expected/go/modules/v2.1.json b/spec/fixtures/expected/go/modules/v2.1.json index f06fbd0..1782d06 100644 --- a/spec/fixtures/expected/go/modules/v2.1.json +++ b/spec/fixtures/expected/go/modules/v2.1.json @@ -2,6 +2,11 @@ "version": "2.1", "licenses": [ { + "id": "Apache-2.0", + "name": "Apache License 2.0", + "url": "https://opensource.org/licenses/Apache-2.0" + }, + { "id": "BSD-3-Clause", "name": "BSD 3-Clause \"New\" or \"Revised\" License", "url": "https://opensource.org/licenses/BSD-3-Clause" @@ -24,6 +29,15 @@ ], "dependencies": [ { + "name": "github.com/astaxie/beego", + "version": "v1.10.0", + "package_manager": "go", + "path": "go.sum", + "licenses": [ + "MIT" + ] + }, + { "name": "github.com/davecgh/go-spew", "version": "v1.1.1", "package_manager": "go", @@ -60,6 +74,15 @@ ] }, { + "name": "github.com/stretchr/objx", + "version": "v0.1.1", + "package_manager": "go", + "path": "go.sum", + "licenses": [ + "MIT" + ] + }, + { "name": "github.com/stretchr/testify", "version": "v1.2.2", "package_manager": "go", @@ -76,6 +99,25 @@ "licenses": [ "BSD-3-Clause" ] + }, + { + "name": "gopkg.in/check.v1", + "version": "v0.0.0-20161208181325-20d25e280405", + "package_manager": "go", + "path": "go.sum", + "licenses": [ + "unknown" + ] + }, + { + "name": "gopkg.in/yaml.v2", + "version": "v2.2.2", + "package_manager": "go", + "path": "go.sum", + "licenses": [ + "Apache-2.0", + "MIT" + ] } ] -} +}
\ No newline at end of file diff --git a/spec/fixtures/go/1.14-vendored-modules/.tool-versions b/spec/fixtures/go/1.14-vendored-modules/.tool-versions new file mode 100644 index 0000000..6973eed --- /dev/null +++ b/spec/fixtures/go/1.14-vendored-modules/.tool-versions @@ -0,0 +1 @@ +golang 1.14 diff --git a/spec/fixtures/go/1.14-vendored-modules/go.mod b/spec/fixtures/go/1.14-vendored-modules/go.mod new file mode 100644 index 0000000..e670615 --- /dev/null +++ b/spec/fixtures/go/1.14-vendored-modules/go.mod @@ -0,0 +1,5 @@ +module example.com/vendored-modules + +go 1.14 + +require github.com/sirupsen/logrus v1.6.0 diff --git a/spec/fixtures/go/1.14-vendored-modules/go.sum b/spec/fixtures/go/1.14-vendored-modules/go.sum new file mode 100644 index 0000000..08faa8b --- /dev/null +++ b/spec/fixtures/go/1.14-vendored-modules/go.sum @@ -0,0 +1,10 @@ +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +// my comment +github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/spec/fixtures/go/1.14-vendored-modules/main.go b/spec/fixtures/go/1.14-vendored-modules/main.go new file mode 100644 index 0000000..56becf1 --- /dev/null +++ b/spec/fixtures/go/1.14-vendored-modules/main.go @@ -0,0 +1,7 @@ +package main + +import "github.com/sirupsen/logrus" + +func main() { + logrus.Info("Hello World") +} diff --git a/spec/fixtures/go/1.14-vendored-modules/vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE b/spec/fixtures/go/1.14-vendored-modules/vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE new file mode 100644 index 0000000..14127cd --- /dev/null +++ b/spec/fixtures/go/1.14-vendored-modules/vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE @@ -0,0 +1,9 @@ +(The MIT License) + +Copyright (c) 2017 marvin + konsorten GmbH (open-source@konsorten.de) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/spec/fixtures/go/1.14-vendored-modules/vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod b/spec/fixtures/go/1.14-vendored-modules/vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod new file mode 100644 index 0000000..716c613 --- /dev/null +++ b/spec/fixtures/go/1.14-vendored-modules/vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod @@ -0,0 +1 @@ +module github.com/konsorten/go-windows-terminal-sequences diff --git a/spec/fixtures/go/1.14-vendored-modules/vendor/github.com/sirupsen/logrus/LICENSE b/spec/fixtures/go/1.14-vendored-modules/vendor/github.com/sirupsen/logrus/LICENSE new file mode 100644 index 0000000..f090cb4 --- /dev/null +++ b/spec/fixtures/go/1.14-vendored-modules/vendor/github.com/sirupsen/logrus/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Simon Eskildsen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/spec/fixtures/go/1.14-vendored-modules/vendor/github.com/sirupsen/logrus/go.mod b/spec/fixtures/go/1.14-vendored-modules/vendor/github.com/sirupsen/logrus/go.mod new file mode 100644 index 0000000..d413296 --- /dev/null +++ b/spec/fixtures/go/1.14-vendored-modules/vendor/github.com/sirupsen/logrus/go.mod @@ -0,0 +1,11 @@ +module github.com/sirupsen/logrus + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/konsorten/go-windows-terminal-sequences v1.0.3 + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/testify v1.2.2 + golang.org/x/sys v0.0.0-20190422165155-953cdadca894 +) + +go 1.13 diff --git a/spec/fixtures/go/1.14-vendored-modules/vendor/github.com/sirupsen/logrus/go.sum b/spec/fixtures/go/1.14-vendored-modules/vendor/github.com/sirupsen/logrus/go.sum new file mode 100644 index 0000000..49c690f --- /dev/null +++ b/spec/fixtures/go/1.14-vendored-modules/vendor/github.com/sirupsen/logrus/go.sum @@ -0,0 +1,12 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/spec/fixtures/go/1.14-vendored-modules/vendor/golang.org/x/sys/AUTHORS b/spec/fixtures/go/1.14-vendored-modules/vendor/golang.org/x/sys/AUTHORS new file mode 100644 index 0000000..15167cd --- /dev/null +++ b/spec/fixtures/go/1.14-vendored-modules/vendor/golang.org/x/sys/AUTHORS @@ -0,0 +1,3 @@ +# This source code refers to The Go Authors for copyright purposes. +# The master list of authors is in the main Go distribution, +# visible at http://tip.golang.org/AUTHORS. diff --git a/spec/fixtures/go/1.14-vendored-modules/vendor/golang.org/x/sys/CONTRIBUTORS b/spec/fixtures/go/1.14-vendored-modules/vendor/golang.org/x/sys/CONTRIBUTORS new file mode 100644 index 0000000..1c4577e --- /dev/null +++ b/spec/fixtures/go/1.14-vendored-modules/vendor/golang.org/x/sys/CONTRIBUTORS @@ -0,0 +1,3 @@ +# This source code was written by the Go contributors. +# The master list of contributors is in the main Go distribution, +# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/spec/fixtures/go/1.14-vendored-modules/vendor/golang.org/x/sys/LICENSE b/spec/fixtures/go/1.14-vendored-modules/vendor/golang.org/x/sys/LICENSE new file mode 100644 index 0000000..6a66aea --- /dev/null +++ b/spec/fixtures/go/1.14-vendored-modules/vendor/golang.org/x/sys/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/spec/fixtures/go/1.14-vendored-modules/vendor/golang.org/x/sys/PATENTS b/spec/fixtures/go/1.14-vendored-modules/vendor/golang.org/x/sys/PATENTS new file mode 100644 index 0000000..7330990 --- /dev/null +++ b/spec/fixtures/go/1.14-vendored-modules/vendor/golang.org/x/sys/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/spec/fixtures/go/1.14-vendored-modules/vendor/golang.org/x/sys/unix/README.md b/spec/fixtures/go/1.14-vendored-modules/vendor/golang.org/x/sys/unix/README.md new file mode 100644 index 0000000..eb2f78a --- /dev/null +++ b/spec/fixtures/go/1.14-vendored-modules/vendor/golang.org/x/sys/unix/README.md @@ -0,0 +1,173 @@ +# Building `sys/unix` + +The sys/unix package provides access to the raw system call interface of the +underlying operating system. See: https://godoc.org/golang.org/x/sys/unix + +Porting Go to a new architecture/OS combination or adding syscalls, types, or +constants to an existing architecture/OS pair requires some manual effort; +however, there are tools that automate much of the process. + +## Build Systems + +There are currently two ways we generate the necessary files. We are currently +migrating the build system to use containers so the builds are reproducible. +This is being done on an OS-by-OS basis. Please update this documentation as +components of the build system change. + +### Old Build System (currently for `GOOS != "linux"`) + +The old build system generates the Go files based on the C header files +present on your system. This means that files +for a given GOOS/GOARCH pair must be generated on a system with that OS and +architecture. This also means that the generated code can differ from system +to system, based on differences in the header files. + +To avoid this, if you are using the old build system, only generate the Go +files on an installation with unmodified header files. It is also important to +keep track of which version of the OS the files were generated from (ex. +Darwin 14 vs Darwin 15). This makes it easier to track the progress of changes +and have each OS upgrade correspond to a single change. + +To build the files for your current OS and architecture, make sure GOOS and +GOARCH are set correctly and run `mkall.sh`. This will generate the files for +your specific system. Running `mkall.sh -n` shows the commands that will be run. + +Requirements: bash, go + +### New Build System (currently for `GOOS == "linux"`) + +The new build system uses a Docker container to generate the go files directly +from source checkouts of the kernel and various system libraries. This means +that on any platform that supports Docker, all the files using the new build +system can be generated at once, and generated files will not change based on +what the person running the scripts has installed on their computer. + +The OS specific files for the new build system are located in the `${GOOS}` +directory, and the build is coordinated by the `${GOOS}/mkall.go` program. When +the kernel or system library updates, modify the Dockerfile at +`${GOOS}/Dockerfile` to checkout the new release of the source. + +To build all the files under the new build system, you must be on an amd64/Linux +system and have your GOOS and GOARCH set accordingly. Running `mkall.sh` will +then generate all of the files for all of the GOOS/GOARCH pairs in the new build +system. Running `mkall.sh -n` shows the commands that will be run. + +Requirements: bash, go, docker + +## Component files + +This section describes the various files used in the code generation process. +It also contains instructions on how to modify these files to add a new +architecture/OS or to add additional syscalls, types, or constants. Note that +if you are using the new build system, the scripts/programs cannot be called normally. +They must be called from within the docker container. + +### asm files + +The hand-written assembly file at `asm_${GOOS}_${GOARCH}.s` implements system +call dispatch. There are three entry points: +``` + func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) + func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) + func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) +``` +The first and second are the standard ones; they differ only in how many +arguments can be passed to the kernel. The third is for low-level use by the +ForkExec wrapper. Unlike the first two, it does not call into the scheduler to +let it know that a system call is running. + +When porting Go to an new architecture/OS, this file must be implemented for +each GOOS/GOARCH pair. + +### mksysnum + +Mksysnum is a Go program located at `${GOOS}/mksysnum.go` (or `mksysnum_${GOOS}.go` +for the old system). This program takes in a list of header files containing the +syscall number declarations and parses them to produce the corresponding list of +Go numeric constants. See `zsysnum_${GOOS}_${GOARCH}.go` for the generated +constants. + +Adding new syscall numbers is mostly done by running the build on a sufficiently +new installation of the target OS (or updating the source checkouts for the +new build system). However, depending on the OS, you make need to update the +parsing in mksysnum. + +### mksyscall.go + +The `syscall.go`, `syscall_${GOOS}.go`, `syscall_${GOOS}_${GOARCH}.go` are +hand-written Go files which implement system calls (for unix, the specific OS, +or the specific OS/Architecture pair respectively) that need special handling +and list `//sys` comments giving prototypes for ones that can be generated. + +The mksyscall.go program takes the `//sys` and `//sysnb` comments and converts +them into syscalls. This requires the name of the prototype in the comment to +match a syscall number in the `zsysnum_${GOOS}_${GOARCH}.go` file. The function +prototype can be exported (capitalized) or not. + +Adding a new syscall often just requires adding a new `//sys` function prototype +with the desired arguments and a capitalized name so it is exported. However, if +you want the interface to the syscall to be different, often one will make an +unexported `//sys` prototype, an then write a custom wrapper in +`syscall_${GOOS}.go`. + +### types files + +For each OS, there is a hand-written Go file at `${GOOS}/types.go` (or +`types_${GOOS}.go` on the old system). This file includes standard C headers and +creates Go type aliases to the corresponding C types. The file is then fed +through godef to get the Go compatible definitions. Finally, the generated code +is fed though mkpost.go to format the code correctly and remove any hidden or +private identifiers. This cleaned-up code is written to +`ztypes_${GOOS}_${GOARCH}.go`. + +The hardest part about preparing this file is figuring out which headers to +include and which symbols need to be `#define`d to get the actual data +structures that pass through to the kernel system calls. Some C libraries +preset alternate versions for binary compatibility and translate them on the +way in and out of system calls, but there is almost always a `#define` that can +get the real ones. +See `types_darwin.go` and `linux/types.go` for examples. + +To add a new type, add in the necessary include statement at the top of the +file (if it is not already there) and add in a type alias line. Note that if +your type is significantly different on different architectures, you may need +some `#if/#elif` macros in your include statements. + +### mkerrors.sh + +This script is used to generate the system's various constants. This doesn't +just include the error numbers and error strings, but also the signal numbers +an a wide variety of miscellaneous constants. The constants come from the list +of include files in the `includes_${uname}` variable. A regex then picks out +the desired `#define` statements, and generates the corresponding Go constants. +The error numbers and strings are generated from `#include <errno.h>`, and the +signal numbers and strings are generated from `#include <signal.h>`. All of +these constants are written to `zerrors_${GOOS}_${GOARCH}.go` via a C program, +`_errors.c`, which prints out all the constants. + +To add a constant, add the header that includes it to the appropriate variable. +Then, edit the regex (if necessary) to match the desired constant. Avoid making +the regex too broad to avoid matching unintended constants. + + +## Generated files + +### `zerror_${GOOS}_${GOARCH}.go` + +A file containing all of the system's generated error numbers, error strings, +signal numbers, and constants. Generated by `mkerrors.sh` (see above). + +### `zsyscall_${GOOS}_${GOARCH}.go` + +A file containing all the generated syscalls for a specific GOOS and GOARCH. +Generated by `mksyscall.go` (see above). + +### `zsysnum_${GOOS}_${GOARCH}.go` + +A list of numeric constants for all the syscall number of the specific GOOS +and GOARCH. Generated by mksysnum (see above). + +### `ztypes_${GOOS}_${GOARCH}.go` + +A file containing Go types for passing into (or returning from) syscalls. +Generated by godefs and the types file (see above). diff --git a/spec/fixtures/go/1.14-vendored-modules/vendor/modules.txt b/spec/fixtures/go/1.14-vendored-modules/vendor/modules.txt new file mode 100644 index 0000000..11cc014 --- /dev/null +++ b/spec/fixtures/go/1.14-vendored-modules/vendor/modules.txt @@ -0,0 +1,7 @@ +# github.com/konsorten/go-windows-terminal-sequences v1.0.3 +github.com/konsorten/go-windows-terminal-sequences +# github.com/sirupsen/logrus v1.6.0 +## explicit +github.com/sirupsen/logrus +# golang.org/x/sys v0.0.0-20190422165155-953cdadca894 +golang.org/x/sys/unix diff --git a/spec/integration/go/modules_spec.rb b/spec/integration/go/modules_spec.rb index 66dadb0..3be04af 100644 --- a/spec/integration/go/modules_spec.rb +++ b/spec/integration/go/modules_spec.rb @@ -1,6 +1,12 @@ require 'spec_helper' RSpec.describe "modules" do + before do + # Delete go module cache + system('rm -fr ~/.local/pkg') + system('rm -fr /opt/asdf/installs/golang/**/packages/pkg/') + end + include_examples "each report version", "go", "modules" ['1.11', '1.12', '1.13', '1.14'].each do |version| @@ -14,15 +20,15 @@ RSpec.describe "modules" do runner.add_file('.tool-versions', "golang #{version}") end - specify { expect(subject).to match_schema } - specify { expect(subject[:licenses]).not_to be_empty } - specify do + expect(subject).to match_schema + expect(subject[:licenses]).not_to be_empty expect(subject.dependency_names).to match_array([ + "cloud.google.com/go", "github.com/davecgh/go-spew", "github.com/dimfeld/httptreemux/v5", - "github.com/golang/protobuf", "github.com/go-logfmt/logfmt", + "github.com/golang/protobuf", "github.com/google/uuid", "github.com/pmezard/go-difflib", "github.com/stretchr/objx", @@ -30,17 +36,17 @@ RSpec.describe "modules" do "golang.org/x/net", "golang.org/x/oauth2", "golang.org/x/sync", + "golang.org/x/text", "google.golang.org/appengine", "gopkg.in/check.v1", "gopkg.in/yaml.v2" ]) + expect(subject.licenses_for('github.com/dimfeld/httptreemux/v5')).to match_array(['MIT']) + expect(subject.licenses_for('github.com/go-logfmt/logfmt')).to match_array(['MIT']) + expect(subject.licenses_for('github.com/google/uuid')).to match_array(['BSD-3-Clause']) + expect(subject.licenses_for('github.com/stretchr/testify')).to match_array(['MIT']) + expect(subject.licenses_for('golang.org/x/oauth2')).to match_array(['BSD-3-Clause']) end - - specify { expect(subject.licenses_for('github.com/dimfeld/httptreemux/v5')).to match_array(['MIT']) } - specify { expect(subject.licenses_for('github.com/go-logfmt/logfmt')).to match_array(['MIT']) } - specify { expect(subject.licenses_for('github.com/google/uuid')).to match_array(['BSD-3-Clause']) } - specify { expect(subject.licenses_for('github.com/stretchr/testify')).to match_array(['MIT']) } - specify { expect(subject.licenses_for('golang.org/x/oauth2')).to match_array(['BSD-3-Clause']) } end end @@ -51,8 +57,36 @@ RSpec.describe "modules" do runner.clone('https://gitlab.com/gitlab-org/gitaly.git') end - specify { expect(subject).to match_schema } - specify { expect(subject[:licenses]).not_to be_empty } - specify { expect(subject[:dependencies]).not_to be_empty } + specify do + expect(subject).to match_schema + expect(subject[:licenses]).not_to be_empty + expect(subject[:dependencies]).not_to be_empty + end + end + + context "when scanning a project with vendored modules" do + subject { runner.scan } + + before do + runner.mount(dir: fixture_file('go/1.14-vendored-modules')) + end + + specify do + expect(subject).to match_schema + expect(subject.dependency_names).to match_array([ + "github.com/davecgh/go-spew", + "github.com/konsorten/go-windows-terminal-sequences", + "github.com/pmezard/go-difflib", + "github.com/sirupsen/logrus", + "github.com/stretchr/testify", + "golang.org/x/sys" + ]) + expect(subject.licenses_for("github.com/davecgh/go-spew")).to match_array(['unknown']) + expect(subject.licenses_for("github.com/konsorten/go-windows-terminal-sequences")).to match_array(['MIT']) + expect(subject.licenses_for("github.com/pmezard/go-difflib")).to match_array(['unknown']) + expect(subject.licenses_for("github.com/sirupsen/logrus")).to match_array(['MIT']) + expect(subject.licenses_for("github.com/stretchr/testify")).to match_array(['unknown']) + expect(subject.licenses_for("golang.org/x/sys")).to match_array(['BSD-3-Clause']) + end end end |
