# frozen_string_literal: true module LicenseFinder class Pip def possible_package_paths path = project_path || Pathname.pwd [ path.join(@requirements_path), path.join('setup.py') ] end def installed?(*) true end def prepare within_project_path do return install_packages if detected_package_path == @requirements_path requirements_path = detected_package_path.dirname.join('requirements.txt') requirements_path.write('.') unless requirements_path.exist? install_packages end end def current_packages within_project_path do return legacy_results unless File.exist?('.venv/bin/activate') dependencies = pip_licenses.map do |dependency| ::LicenseFinder::Dependency.new( 'Pip', dependency['Name'], dependency['Version'], description: dependency['Description'], detection_path: detected_package_path, homepage: dependency['URL'], spec_licenses: [dependency['License']] ) end dependencies.any? ? dependencies : legacy_results end end private def python_version(env: ENV) tool_box.version_of(:python, env: env) end def install_packages within_project_path do tool_box.install(tool: :python, version: python_version, env: default_env) shell.execute([:virtualenv, '-p', 'python', '--activators=bash', '--seeder=app-data', '.venv'], capture: false) shell.sh([". .venv/bin/activate", "&&", 'pip', 'install', '-v', '-r', @requirements_path], env: default_env) end end def legacy_results pip_output.map do |name, version, _children, _location| spec = PyPI.definition(name, version) Dependency.new( 'Pip', name, version, description: spec['summary'] || spec['description'], detection_path: detected_package_path, homepage: spec['home_page'], spec_licenses: PipPackage.license_names_from_spec(spec) ) end end def pip_output stdout, _, status = shell.execute([ :asdf, :exec, :python, LicenseFinder::BIN_PATH.join('license_finder_pip.py'), detected_package_path ], env: default_env) return [] unless status.success? JSON.parse(stdout).map do |package| package.values_at('name', 'version', 'dependencies', 'location') end end def pip_licenses shell.sh([". .venv/bin/activate", '&&', 'pip', 'install', '--no-index', "--find-links /opt/gitlab/.config/virtualenv/app-data", 'pip-licenses'], env: default_env) stdout, _, status = shell.sh([". .venv/bin/activate", '&&', 'pip-licenses', '--with-description', '--with-urls', '--format=json'], env: default_env) status.success? ? JSON.parse(stdout[stdout.index('[')..-1]) : [] end def default_env @default_env ||= { 'PIP_CERT' => ENV.fetch('PIP_CERT', shell.default_certificate_path).to_s, 'PIP_DISABLE_PIP_VERSION_CHECK' => '1', 'PIP_INDEX_URL' => ENV.fetch('PIP_INDEX_URL', 'https://pypi.org/simple/'), 'PIP_NO_PYTHON_VERSION_WARNING' => '1' } end end end