diff --git a/lib/license_finder/package_managers/pip.rb b/lib/license_finder/package_managers/pip.rb index f67462ebc..830c41500 100644 --- a/lib/license_finder/package_managers/pip.rb +++ b/lib/license_finder/package_managers/pip.rb @@ -25,6 +25,18 @@ def self.package_management_command 'pip' end + def self.prepare_command + 'pip install' + end + + def prepare + prep_cmd = "#{Pip.prepare_command} -r #{@requirements_path}" + _stdout, stderr, status = Dir.chdir(project_path) { Cmd.run(prep_cmd) } + return if status.success? + log_errors stderr + raise "Prepare command '#{prep_cmd}' failed" unless @prepare_no_fail + end + def possible_package_paths if project_path.nil? [@requirements_path] diff --git a/spec/fixtures/config/pip.json b/spec/fixtures/config/pip.json new file mode 100644 index 000000000..3dc66d602 --- /dev/null +++ b/spec/fixtures/config/pip.json @@ -0,0 +1,121 @@ +[{ + "version": "3.12", + "name": "PyYAML", + "dependencies": [], + "location": "/usr/local/lib/python2.7/dist-packages" +}, { + "version": "0.24.0", + "name": "wheel", + "dependencies": [], + "location": "/usr/lib/python2.7/dist-packages" +}, { + "version": "3.4.2", + "name": "rsa", + "dependencies": ["pyasn1"], + "location": "/usr/local/lib/python2.7/dist-packages" +}, { + "version": "1.3.0", + "name": "mock", + "dependencies": ["six", "funcsigs", "pbr"], + "location": "/usr/local/lib/python2.7/dist-packages" +}, { + "version": "0.3.7", + "name": "colorama", + "dependencies": [], + "location": "/usr/local/lib/python2.7/dist-packages" +}, { + "version": "1.3.0", + "name": "nose", + "dependencies": [], + "location": "/usr/local/lib/python2.7/dist-packages" +}, { + "version": "0.9.3", + "name": "jmespath", + "dependencies": [], + "location": "/workspace/LicenseFinder/bin/src/jmespath" +}, { + "version": "0.1.13", + "name": "s3transfer", + "dependencies": ["botocore", "futures", "futures"], + "location": "/workspace/LicenseFinder/bin/src/s3transfer" +}, { + "version": "1.9.19", + "name": "botocore", + "dependencies": ["jmespath", "python-dateutil", "docutils"], + "location": "/workspace/LicenseFinder/bin/src/botocore" +}, { + "version": "0.14", + "name": "docutils", + "dependencies": [], + "location": "/usr/local/lib/python2.7/dist-packages" +}, { + "version": "2.9.1", + "name": "tox", + "dependencies": ["py", "pluggy", "six", "virtualenv"], + "location": "/usr/local/lib/python2.7/dist-packages" +}, { + "version": "0.4.2", + "name": "pyasn1", + "dependencies": [], + "location": "/usr/local/lib/python2.7/dist-packages" +}, { + "version": "4.0.0", + "name": "pbr", + "dependencies": [], + "location": "/usr/local/lib/python2.7/dist-packages" +}, { + "version": "1.0.2", + "name": "funcsigs", + "dependencies": [], + "location": "/usr/local/lib/python2.7/dist-packages" +}, { + "version": "1.11.0", + "name": "six", + "dependencies": [], + "location": "/usr/local/lib/python2.7/dist-packages" +}, { + "version": "3.2.0", + "name": "futures", + "dependencies": [], + "location": "/usr/local/lib/python2.7/dist-packages" +}, { + "version": "1.9.19", + "name": "botocore", + "dependencies": ["jmespath", "python-dateutil", "docutils"], + "location": "/workspace/LicenseFinder/bin/src/botocore" +}, { + "version": "2.6.1", + "name": "python-dateutil", + "dependencies": ["six"], + "location": "/usr/local/lib/python2.7/dist-packages" +}, { + "version": "0.9.3", + "name": "jmespath", + "dependencies": [], + "location": "/workspace/LicenseFinder/bin/src/jmespath" +}, { + "version": "15.2.0", + "name": "virtualenv", + "dependencies": [], + "location": "/usr/local/lib/python2.7/dist-packages" +}, { + "version": "1.11.0", + "name": "six", + "dependencies": [], + "location": "/usr/local/lib/python2.7/dist-packages" +}, { + "version": "0.6.0", + "name": "pluggy", + "dependencies": [], + "location": "/usr/local/lib/python2.7/dist-packages" +}, { + "version": "1.5.3", + "name": "py", + "dependencies": [], + "location": "/usr/local/lib/python2.7/dist-packages" +}, { + "version": "1.11.0", + "name": "six", + "dependencies": [], + "location": "/usr/local/lib/python2.7/dist-packages" +}] \ No newline at end of file diff --git a/spec/lib/license_finder/package_managers/npm_spec.rb b/spec/lib/license_finder/package_managers/npm_spec.rb index fe397df20..98ba69911 100644 --- a/spec/lib/license_finder/package_managers/npm_spec.rb +++ b/spec/lib/license_finder/package_managers/npm_spec.rb @@ -42,6 +42,7 @@ module LicenseFinder .and_return([dependency_json, '', cmd_success]) npm.prepare end + context 'ignored_groups contains devDependencies' do let(:npm) { NPM.new project_path: Pathname.new(root), ignored_groups: 'devDependencies' } it 'should include a production flag' do diff --git a/spec/lib/license_finder/package_managers/pip_spec.rb b/spec/lib/license_finder/package_managers/pip_spec.rb index e6b8cb9ee..fe18a2c7a 100644 --- a/spec/lib/license_finder/package_managers/pip_spec.rb +++ b/spec/lib/license_finder/package_managers/pip_spec.rb @@ -2,9 +2,66 @@ module LicenseFinder describe Pip do - let(:pip) { Pip.new } + let(:root) { '/fake-python-project' } + let(:pip) { Pip.new(project_path: Pathname(root)) } it_behaves_like 'a PackageManager' + + let(:requirements_txt) do +<=2.3.1,<3.0.0 +docutils>=0.10 +# botocore and the awscli packages are typically developed +# in tandem, so we're requiring the latest develop +# branch of botocore when working on the awscli. +-e git://github.com/boto/botocore.git@develop#egg=botocore +-e git://github.com/boto/s3transfer.git@develop#egg=s3transfer +-e git://github.com/boto/jmespath.git@develop#egg=jmespath +nose==1.3.0 +colorama>=0.2.5,<=0.3.7 +mock==1.3.0 +rsa>=3.1.2,<=3.5.0 +wheel==0.24.0 +PyYAML>=3.10,<=3.12" +eos + end + + let(:dependency_json) do + FakeFS.without do + fixture_from('pip.json') + end + end + + describe '.prepare' do + include FakeFS::SpecHelpers + before do + FileUtils.mkdir_p(Dir.tmpdir) + FileUtils.mkdir_p(root) + File.write(File.join(root, 'requirements.txt'), requirements_txt) + user_provided_dir = File.join(root, 'user-provided') + @user_provided_requirements = File.join(user_provided_dir, 'requirements.txt') + FileUtils.mkdir_p(user_provided_dir) + File.write(@user_provided_requirements, requirements_txt) + end + + it 'should call pip install with the requirements file' do + expect(SharedHelpers::Cmd).to receive(:run).with('pip install -r requirements.txt') + .and_return([dependency_json, '', cmd_success]) + pip.prepare + end + + context 'user provides a requirements file' do + let(:pip) { Pip.new(project_path: Pathname(root), pip_requirements_path: @user_provided_requirements) } + + it 'should use the provided requirements file' do + expect(SharedHelpers::Cmd).to receive(:run).with("pip install -r #{@user_provided_requirements}") + .and_return([dependency_json, '', cmd_success]) + pip.prepare + end + end + end + + describe '.current_packages' do def stub_pip(stdout) allow(pip).to receive('`').with(/license_finder_pip.py/).and_return(stdout)