diff --git a/Dockerfile b/Dockerfile index deae63fd2..80935d1e2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -48,11 +48,13 @@ ENV JAVA_HOME=/opt/jdk-12.0.2 ENV PATH=$PATH:$JAVA_HOME/bin RUN java -version -# install python and rebar -RUN apt-get install -y python rebar +# install rebar3 +RUN curl -o rebar3 https://s3.amazonaws.com/rebar3/rebar3 && \ + sudo chmod +x rebar3 && \ + sudo mv rebar3 /usr/local/bin/rebar3 -# install and update python-pip -RUN apt-get install -y python-pip python3-pip && \ +# install and update python and python-pip +RUN apt-get install -y python python-pip python3-pip && \ pip2 install --no-cache-dir --upgrade pip==$PIP_INSTALL_VERSION && \ pip3 install --no-cache-dir --upgrade pip==$PIP3_INSTALL_VERSION diff --git a/features/features/package_managers/rebar_spec.rb b/features/features/package_managers/rebar_spec.rb index cf744312b..3926f8704 100644 --- a/features/features/package_managers/rebar_spec.rb +++ b/features/features/package_managers/rebar_spec.rb @@ -11,6 +11,12 @@ specify 'are shown in reports' do LicenseFinder::TestingDSL::RebarProject.create erlang_developer.run_license_finder - expect(erlang_developer).to be_seeing_line 'envy, "BRANCH: master", "Apache 2.0"' + expect(erlang_developer).to be_seeing_line 'envy, 0.5.0, MIT' + expect(erlang_developer).to be_seeing_line 'hackney, 1.6.0, "Apache 2.0"' + expect(erlang_developer).to be_seeing_line 'certifi, 0.4.0, BSD' + expect(erlang_developer).to be_seeing_line 'idna, 1.2.0, MIT' + expect(erlang_developer).to be_seeing_line 'metrics, 1.0.1, BSD' + expect(erlang_developer).to be_seeing_line 'mimerl, 1.0.2, MIT' + expect(erlang_developer).to be_seeing_line 'ssl_verify_fun, 1.1.0, MIT' end end diff --git a/features/fixtures/rebar.config b/features/fixtures/rebar.config index f388f4165..4c7479295 100644 --- a/features/fixtures/rebar.config +++ b/features/fixtures/rebar.config @@ -1,12 +1,9 @@ -%% -*- mode: erlang -*- -%% -*- tab-width: 4;erlang-indent-level: 4;indent-tabs-mode: nil -*- -%% ex: ts=4 sw=4 ft=erlang et - {erl_opts, [warnings_as_errors, {parse_transform, lager_transform}, debug_info]}. {deps, [ {envy, ".*", - {git, "git://github.com/manderson26/envy.git", {branch, "master"}}} + {git, "git://github.com/manderson26/envy.git", {tag, "0.5.0"}}}, + {hackney, "1.6.0"} ] }. diff --git a/features/support/testing_dsl.rb b/features/support/testing_dsl.rb index 32a9436a0..9445f81b8 100644 --- a/features/support/testing_dsl.rb +++ b/features/support/testing_dsl.rb @@ -466,7 +466,7 @@ def add_dep end def install - shell_out('rebar get-deps') + shell_out('rebar3 get-deps') end end diff --git a/lib/license_finder/configuration.rb b/lib/license_finder/configuration.rb index d73f083f7..a6da6330a 100644 --- a/lib/license_finder/configuration.rb +++ b/lib/license_finder/configuration.rb @@ -35,7 +35,7 @@ def merge(other_hash) end def rebar_deps_dir - path = get(:rebar_deps_dir) || 'deps' + path = get(:rebar_deps_dir) || '_build/default/lib' project_path.join(path).expand_path end diff --git a/lib/license_finder/package_managers/rebar.rb b/lib/license_finder/package_managers/rebar.rb index 15e57e2b7..858bc1054 100644 --- a/lib/license_finder/package_managers/rebar.rb +++ b/lib/license_finder/package_managers/rebar.rb @@ -5,23 +5,25 @@ class Rebar < PackageManager def initialize(options = {}) super @command = options[:rebar_command] || package_management_command - @deps_path = Pathname(options[:rebar_deps_dir] || 'deps') + @deps_path = Pathname(options[:rebar_deps_dir] || File.join(project_path, '_build/default/lib')) end def current_packages - rebar_ouput.map do |name, version_type, version_value, homepage| + rebar_deps.map do |name, version| + licenses, homepage = rebar_pkgs(name) RebarPackage.new( name, - "#{version_type}: #{version_value}", + version, install_path: @deps_path.join(name), homepage: homepage, + spec_licenses: licenses.nil? ? [] : [licenses], logger: logger ) end end def package_management_command - 'rebar' + 'rebar3' end def possible_package_paths @@ -30,15 +32,34 @@ def possible_package_paths private - def rebar_ouput - command = "#{@command} list-deps" + def rebar_deps + command = "#{@command} tree" stdout, stderr, status = Dir.chdir(project_path) { Cmd.run(command) } raise "Command '#{command}' failed to execute: #{stderr}" unless status.success? stdout .each_line - .reject { |line| line.start_with?('=') } - .map { |line| line.split(' ') } + .reject { |line| line.start_with?('=') || line.include?('project app') } + .map do |line| + matches = line.match(/(?\w+)─(?[\S.]+)\s*/) + [matches[:name], matches[:version]] if matches + end.compact + end + + def rebar_pkgs(name) + command = "#{@command} pkgs #{name}" + stdout, _, status = Cmd.run(command) + return [nil, nil] unless status.success? + + licenses = nil + homepage = nil + + stdout.scan(/Licenses: (?.+)|(?(https|http).*)/) do |pkg_licenses, pkg_homepage| + licenses ||= pkg_licenses + homepage ||= pkg_homepage + end + + [licenses, homepage] end end end diff --git a/spec/lib/license_finder/configuration_spec.rb b/spec/lib/license_finder/configuration_spec.rb index d84519abc..4ccb13648 100644 --- a/spec/lib/license_finder/configuration_spec.rb +++ b/spec/lib/license_finder/configuration_spec.rb @@ -158,12 +158,12 @@ module LicenseFinder { rebar_deps_dir: nil }, 'rebar_deps_dir' => nil ) - expect(subject.rebar_deps_dir.to_s).to end_with 'deps' + expect(subject.rebar_deps_dir.to_s).to end_with '_build/default/lib' end it 'prepends project path to default path if project_path option is set' do subject = described_class.new({ project_path: 'magic_path' }, {}) - expect(subject.rebar_deps_dir.to_s).to end_with 'magic_path/deps' + expect(subject.rebar_deps_dir.to_s).to end_with 'magic_path/_build/default/lib' end it 'prepends project path to provided value' do diff --git a/spec/lib/license_finder/package_managers/rebar_spec.rb b/spec/lib/license_finder/package_managers/rebar_spec.rb index d3437faa3..5a0e769b3 100644 --- a/spec/lib/license_finder/package_managers/rebar_spec.rb +++ b/spec/lib/license_finder/package_managers/rebar_spec.rb @@ -8,11 +8,22 @@ module LicenseFinder it_behaves_like 'a PackageManager' - output = <<-CMDOUTPUT -== Sample comment -uuid TAG v1.3.2 git://github.com/okeuday/uuid.git -jiffy TAG 0.9.0 https://github.com/davisp/jiffy.git - CMDOUTPUT + tree_output = <<-TREEOUTPUT +===> bababooie +└─ eetcd─0.3.2 (project app) + └─ hackney─1.6.0 (hex package) + └─ ssl_verify_fun─1.1.0 (hex package) + TREEOUTPUT + + pkgs_output = <<-PKGSOUTPUT +hexpm: + Name: hackney + Description: simple HTTP client + Licenses: Apache 2.0 + Links: + Github: https://github.com/benoitc/hackney + Versions: 1.16.0 + PKGSOUTPUT describe '.current_packages' do before do @@ -20,32 +31,56 @@ module LicenseFinder end it 'lists all the current packages' do - allow(SharedHelpers::Cmd).to receive(:run).with('rebar list-deps').and_return([output, '', cmd_success]) + allow(SharedHelpers::Cmd).to receive(:run).with('rebar3 tree').and_return([tree_output, '', cmd_success]) + allow(SharedHelpers::Cmd).to receive(:run).with(/rebar3 pkgs .*/).and_return([pkgs_output, '', cmd_success]) current_packages = subject.current_packages - expect(current_packages.map(&:name)).to eq(%w[uuid jiffy]) - expect(current_packages.map(&:install_path)).to eq([Pathname('deps/uuid'), Pathname('deps/jiffy')]) + expect(current_packages.map(&:name)).to eq(%w[hackney ssl_verify_fun]) + expect(current_packages.map(&:version)).to eq(%w[1.6.0 1.1.0]) + expect(current_packages.map(&:license_names_from_spec)).to eq([['Apache 2.0'], ['Apache 2.0']]) + expect(current_packages.map(&:homepage)).to eq(%w[https://github.com/benoitc/hackney https://github.com/benoitc/hackney]) + expect(current_packages.map(&:install_path)).to eq([Pathname('/fake/path/_build/default/lib/hackney'), Pathname('/fake/path/_build/default/lib/ssl_verify_fun')]) end - it 'fails when command fails' do - allow(SharedHelpers::Cmd).to receive(:run).with(/rebar/).and_return(['Some error', '', cmd_failure]).once + it 'fails when tree command fails' do + allow(SharedHelpers::Cmd).to receive(:run).with('rebar3 tree').and_return(['Some error', '', cmd_failure]).once expect { subject.current_packages }.to raise_error(RuntimeError) end + context 'when pkgs command fails' do + it 'returns empty license and homepage information' do + allow(SharedHelpers::Cmd).to receive(:run).with('rebar3 tree').and_return([tree_output, '', cmd_success]) + allow(SharedHelpers::Cmd).to receive(:run).with(/rebar3 pkgs .*/).and_return(['Some error', '', cmd_failure]) + + current_packages = subject.current_packages + expect(current_packages.map(&:name)).to eq(%w[hackney ssl_verify_fun]) + expect(current_packages.map(&:version)).to eq(%w[1.6.0 1.1.0]) + expect(current_packages.map(&:license_names_from_spec)).to eq([[], []]) + expect(current_packages.map(&:homepage)).to eq(['', '']) + expect(current_packages.map(&:install_path)).to eq([Pathname('/fake/path/_build/default/lib/hackney'), Pathname('/fake/path/_build/default/lib/ssl_verify_fun')]) + end + end + it 'uses custom rebar command, if provided' do rebar = Rebar.new(rebar_command: 'rebarfoo', project_path: Pathname('/fake/path')) - allow(SharedHelpers::Cmd).to receive(:run).with(/rebarfoo/).and_return([output, '', cmd_success]) + allow(SharedHelpers::Cmd).to receive(:run).with('rebarfoo tree').and_return([tree_output, '', cmd_success]) + allow(SharedHelpers::Cmd).to receive(:run).with(/rebarfoo pkgs .*/).and_return([pkgs_output, '', cmd_success]) current_packages = rebar.current_packages - expect(current_packages.map(&:name)).to eq(%w[uuid jiffy]) + expect(current_packages.map(&:name)).to eq(%w[hackney ssl_verify_fun]) + expect(current_packages.map(&:version)).to eq(%w[1.6.0 1.1.0]) + expect(current_packages.map(&:license_names_from_spec)).to eq([['Apache 2.0'], ['Apache 2.0']]) + expect(current_packages.map(&:homepage)).to eq(%w[https://github.com/benoitc/hackney https://github.com/benoitc/hackney]) + expect(current_packages.map(&:install_path)).to eq([Pathname('/fake/path/_build/default/lib/hackney'), Pathname('/fake/path/_build/default/lib/ssl_verify_fun')]) end it 'uses custom rebar_deps_dir, if provided' do rebar = Rebar.new(rebar_deps_dir: 'foo', project_path: Pathname('/fake/path')) - allow(SharedHelpers::Cmd).to receive(:run).with(/rebar/).and_return([output, '', cmd_success]) + allow(SharedHelpers::Cmd).to receive(:run).with('rebar3 tree').and_return([tree_output, '', cmd_success]) + allow(SharedHelpers::Cmd).to receive(:run).with(/rebar3 pkgs .*/).and_return([pkgs_output, '', cmd_success]) current_packages = rebar.current_packages - expect(current_packages.map(&:install_path)).to eq([Pathname('foo/uuid'), Pathname('foo/jiffy')]) + expect(current_packages.map(&:install_path)).to eq([Pathname('foo/hackney'), Pathname('foo/ssl_verify_fun')]) end end end