diff options
| -rw-r--r-- | CHANGELOG.md | 7 | ||||
| -rw-r--r-- | Gemfile.lock | 2 | ||||
| -rw-r--r-- | README.md | 33 | ||||
| -rw-r--r-- | config/.default-npm-packages | 1 | ||||
| -rw-r--r-- | config/install.sh | 31 | ||||
| -rw-r--r-- | lib/license/finder/ext.rb | 1 | ||||
| -rw-r--r-- | lib/license/finder/ext/bower.rb | 54 | ||||
| -rw-r--r-- | lib/license/management/version.rb | 2 | ||||
| -rw-r--r-- | spec/fixtures/js/bower/bower.json | 18 | ||||
| -rw-r--r-- | spec/integration/js/bower_spec.rb | 64 |
10 files changed, 187 insertions, 26 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index c3459b0..a973158 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # GitLab License management changelog +## v3.9.1 + +- Add `--allow-root` option when install bower packages. (!150) +- Include nested dependencies in scan report for bower projects. (!150) +- Pass `NPM_CONFIG_CAFILE` to bower install step. (!150) + ## v3.9.0 - Update go list command to be compatible with 1.14 (!143) @@ -8,6 +14,7 @@ ## v3.8.1 - Exclude `devDependencies` from `yarn` scan report. (!147) +- Remove `spandx` dependency and bring back Ruby 2.4+ support. (!147) ## v3.8.0 diff --git a/Gemfile.lock b/Gemfile.lock index e8e1023..4ba5c69 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - license-management (3.9.0) + license-management (3.9.1) license_finder (~> 6.0.0) GEM @@ -76,13 +76,13 @@ The following table shows which languages and package managers are supported. | Language | Package managers | |------------|-------------------------------------------------------------------| -| JavaScript | [Bower](https://bower.io/), [npm](https://www.npmjs.com/) | -| Go | [Godep](https://github.com/tools/godep), go get | -| Java | [Gradle](https://gradle.org/), [Maven](https://maven.apache.org/) | -| .NET | [Nuget](https://www.nuget.org/) | -| Python | [pip](https://pip.pypa.io/en/stable/) | -| Ruby | [gem](https://rubygems.org/) | -| PHP | [composer](https://getcomposer.org) | +| .NET | [.NET Core CLI][dotnet_core], [Nuget][nuget] | +| Go | [Go modules][gomod], [Godep][godep], go get | +| Java | [Gradle][gradle], [Maven][maven] | +| JavaScript | [npm][npm], [yarn][yarn], [Bower][bower] | +| PHP | [composer][composer] | +| Python | [pip][pip], [pipenv][pipenv] | +| Ruby | [Bundler][bundler] | Inject `SETUP_CMD` to the docker command to override the given package managers and run your custom command to setup your environment with a custom package manager. @@ -150,8 +150,21 @@ If you want to help, read the [contribution guidelines](CONTRIBUTING.md). If an unknown license is detected, please consider updating the mapping defined in [normalized-licenses.yml](https://gitlab.com/gitlab-org/security-products/license-management/blob/master/normalized-licenses.yml). A mapping can be for a detected name or url and must correspond to an SDPX identifier found in [spdx-licenses.json](https://gitlab.com/gitlab-org/security-products/license-management/blob/master/spdx-licenses.json). -[license_finder]: https://rubygems.org/gems/license_finder +[bower]: https://bower.io/ [changelog]: https://gitlab.com/gitlab-org/security-products/license-management/-/blob/master/CHANGELOG.md -[version_rb]: https://gitlab.com/gitlab-org/security-products/license-management/-/blob/master/lib/license/management/version.rb -[gemspec]: https://gitlab.com/gitlab-org/security-products/license-management/-/blob/master/license-management.gemspec [gemfile_lock]: https://gitlab.com/gitlab-org/security-products/license-management/-/blob/master/Gemfile.lock +[gemspec]: https://gitlab.com/gitlab-org/security-products/license-management/-/blob/master/license-management.gemspec +[license_finder]: https://rubygems.org/gems/license_finder +[npm]: https://www.npmjs.com/ +[version_rb]: https://gitlab.com/gitlab-org/security-products/license-management/-/blob/master/lib/license/management/version.rb +[yarn]: https://yarnpkg.com/ +[gomod]: https://github.com/golang/go/wiki/Modules +[godep]: https://github.com/tools/godep +[gradle]: https://gradle.org/ +[maven]: https://maven.apache.org/ +[nuget]: https://www.nuget.org/ +[dotnet_core]: https://docs.microsoft.com/en-us/dotnet/core/tools/ +[pip]: https://pip.pypa.io/en/stable/ +[pipenv]: https://github.com/pypa/pipenv +[bundler]: https://bundler.io/ +[composer]: https://getcomposer.org diff --git a/config/.default-npm-packages b/config/.default-npm-packages index 9991b02..8e16e61 100644 --- a/config/.default-npm-packages +++ b/config/.default-npm-packages @@ -1,3 +1,4 @@ bower +bower-npm-resolver npm-install-peers yarn diff --git a/config/install.sh b/config/install.sh index 39a3197..e303910 100644 --- a/config/install.sh +++ b/config/install.sh @@ -77,8 +77,8 @@ apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BF echo "deb https://download.mono-project.com/repo/debian stable-buster main" | tee /etc/apt/sources.list.d/mono-official-stable.list apt-get update -q -apt-get install -y --no-install-recommends dotnet-sdk-3.1 mono-complete -curl -o /usr/local/bin/nuget.exe https://dist.nuget.org/win-x86-commandline/latest/nuget.exe +apt-get install -y --no-install-recommends dotnet-sdk-3.1 mono-complete & +curl -o /usr/local/bin/nuget.exe https://dist.nuget.org/win-x86-commandline/latest/nuget.exe & mkdir -p "$ASDF_DATA_DIR" git clone https://github.com/asdf-vm/asdf.git "$ASDF_DATA_DIR" @@ -101,7 +101,7 @@ for version in $(asdf list python); do asdf shell python "$version" pip download -d "$HOME/.config/virtualenv/app-data" pip-licenses pip setuptools wheel done - +wait rm -fr /tmp mkdir -p /tmp chmod 777 /tmp @@ -159,24 +159,27 @@ rm -fr "$ASDF_DATA_DIR/docs" \ /var/lib/systemd/* \ /var/log/* +zstd_command="/usr/bin/zstd -19" cd /opt -tar --use-compress-program zstd -cf /opt/asdf.tar.zst asdf -rm -fr /opt/asdf/ +tar --use-compress-program "$zstd_command" -cf /opt/asdf.tar.zst asdf & cd /usr/lib -tar --use-compress-program zstd -cf /usr/lib/gcc.tar.zst gcc -rm -fr /usr/lib/gcc +tar --use-compress-program "$zstd_command" -cf /usr/lib/gcc.tar.zst gcc & cd /usr/lib -tar --use-compress-program zstd -cf /usr/lib/mono.tar.zst mono -rm -fr /usr/lib/mono +tar --use-compress-program "$zstd_command" -cf /usr/lib/mono.tar.zst mono & cd /usr/lib -tar --use-compress-program zstd -cf /usr/lib/rustlib.tar.zst rustlib -rm -fr /usr/lib/rustlib +tar --use-compress-program "$zstd_command" -cf /usr/lib/rustlib.tar.zst rustlib & cd /usr/share -tar --use-compress-program zstd -cf /usr/share/dotnet.tar.zst dotnet -rm -fr /usr/share/dotnet - +tar --use-compress-program "$zstd_command" -cf /usr/share/dotnet.tar.zst dotnet & + +wait +rm -fr \ + /opt/asdf/ \ + /usr/lib/gcc \ + /usr/lib/mono \ + /usr/lib/rustlib \ + /usr/share/dotnet echo "Done" diff --git a/lib/license/finder/ext.rb b/lib/license/finder/ext.rb index 3d8a463..3c56c7a 100644 --- a/lib/license/finder/ext.rb +++ b/lib/license/finder/ext.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +require 'license/finder/ext/bower' require 'license/finder/ext/go_modules' require 'license/finder/ext/gradle' require 'license/finder/ext/license' diff --git a/lib/license/finder/ext/bower.rb b/lib/license/finder/ext/bower.rb new file mode 100644 index 0000000..ccfa7ee --- /dev/null +++ b/lib/license/finder/ext/bower.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +module LicenseFinder + class Bower < PackageManager + def prepare + shell.execute([:bower, :install, '--allow-root'], env: default_env) + end + + def current_packages + map_all(bower_output).flatten.compact + end + + def possible_package_paths + [project_path.join('bower.json')] + end + + private + + def bower_output + stdout, _stderr, status = Dir.chdir(project_path) do + shell.execute([:bower, :list, '--json', '-l', 'action', '--allow-root']) + end + return {} unless status.success? + + JSON.parse(stdout) + end + + def map_all(modules) + [map_from(modules)] + + modules.fetch('dependencies', {}).values.map { |x| map_all(x) } + end + + def map_from(bower_module) + meta = bower_module.fetch('pkgMeta', {}) + endpoint = bower_module.fetch('endpoint', {}) + + Package.new( + meta['name'] || endpoint['name'], + meta['version'] || endpoint['target'], + summary: meta['description'], + description: meta['readme'], + homepage: meta['homepage'], + spec_licenses: Package.license_names_from_standard_spec(meta), + install_path: bower_module['canonicalDir'] + ) + end + + def default_env + return {} unless shell.custom_certificate_installed? + + { 'NPM_CONFIG_CAFILE' => ENV.fetch('NPM_CONFIG_CAFILE', shell.custom_certificate_path.to_s) } + end + end +end diff --git a/lib/license/management/version.rb b/lib/license/management/version.rb index b5d5bc9..0fe76f1 100644 --- a/lib/license/management/version.rb +++ b/lib/license/management/version.rb @@ -2,6 +2,6 @@ module License module Management - VERSION = '3.9.0' + VERSION = '3.9.1' end end diff --git a/spec/fixtures/js/bower/bower.json b/spec/fixtures/js/bower/bower.json new file mode 100644 index 0000000..f2760e7 --- /dev/null +++ b/spec/fixtures/js/bower/bower.json @@ -0,0 +1,18 @@ +{ + "name": "example-project", + "license": "ISC", + "private": true, + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "dependencies": { + "jquery": "^3.5.1", + "masonry-layout": "desandro/masonry#^4.2.2", + "cli": "git://github.com/npm/cli.git#^6.14.5", + "stimulus.umd": "https://unpkg.com/stimulus/dist/stimulus.umd.js" + } +} diff --git a/spec/integration/js/bower_spec.rb b/spec/integration/js/bower_spec.rb new file mode 100644 index 0000000..2127c2e --- /dev/null +++ b/spec/integration/js/bower_spec.rb @@ -0,0 +1,64 @@ +require 'spec_helper' + +RSpec.describe "bower" do + context "when scanning a simple bower project" do + subject { runner.scan } + + before do + runner.add_file('bower.json', fixture_file_content('js/bower/bower.json')) + end + + specify { expect(subject).to match_schema(version: '2.0') } + specify { expect(subject.dependency_names).to match_array(['cli', 'ev-emitter', 'example-project', 'fizzy-ui-utils', 'get-size', 'jquery', 'masonry-layout', 'matches-selector', 'outlayer', 'stimulus.umd']) } + specify { expect(subject.licenses_for('cli')).to match_array(['Apache-2.0', 'BSD-3-Clause', 'ISC', 'MIT']) } + specify { expect(subject.licenses_for('ev-emitter')).to match_array(['MIT']) } + specify { expect(subject.licenses_for('example-project')).to match_array(['ISC']) } + specify { expect(subject.licenses_for('fizzy-ui-utils')).to match_array(['MIT']) } + specify { expect(subject.licenses_for('get-size')).to match_array(['MIT']) } + specify { expect(subject.licenses_for('jquery')).to match_array(['MIT']) } + specify { expect(subject.licenses_for('masonry-layout')).to match_array(['MIT']) } + specify { expect(subject.licenses_for('matches-selector')).to match_array(['MIT']) } + specify { expect(subject.licenses_for('outlayer')).to match_array(['MIT']) } + specify { expect(subject.licenses_for('stimulus.umd')).to match_array(['unknown']) } + end + + context "when scanning a bower project with a dependency from a custom registry" do + subject { runner.scan(env: { 'ADDITIONAL_CA_CERT_BUNDLE' => fixture_file_content('js/custom-npm.crt') }) } + + before do + runner.add_file(".npmrc", "registry = https://#{private_npm_host}") + runner.add_file(".bowerrc") do + JSON.pretty_generate({ resolvers: ['bower-npm-resolver'] }) + end + runner.add_file("bower.json") do + JSON.pretty_generate({ + name: "js-bower", + license: "ISC", + dependencies: { lodash: "npm:lodash#4.17.10" } + }) + end + end + + specify { expect(subject).to match_schema(version: '2.0') } + specify { expect(subject.dependency_names).to match_array(%w[js-bower lodash]) } + specify { expect(subject.licenses_for('js-bower')).to match_array(['ISC']) } + specify { expect(subject.licenses_for('lodash')).to match_array(['MIT']) } + end + + [ + 'https://gitlab.com/gitlab-org/ci-training-slides', + 'https://gitlab.com/gitlab-org/frontend/At.js.git', + 'https://gitlab.com/gitlab-org/gitter/gitter-marked.git' + ].each do |git_repo| + context "when scanning #{git_repo}" do + subject { runner.scan } + + before do + runner.clone(git_repo) + end + + specify { expect(subject).to match_schema(version: '2.0') } + specify { expect(subject.dependency_names).not_to be_empty } + end + end +end |
