import os import re from pipenv.patched.pip._internal.network.session import PipSession from pipenv.patched.pip._internal.req import parse_requirements from pipenv.patched.pip._internal.req.constructors import ( install_req_from_parsed_requirement, ) from pipenv.patched.pip._internal.utils.misc import split_auth_from_netloc from pipenv.utils.indexes import parse_indexes from pipenv.utils.internet import get_host_and_port def import_requirements(project, r=None, dev=False): # Parse requirements.txt file with Pip's parser. # Pip requires a `PipSession` which is a subclass of requests.Session. # Since we're not making any network calls, it's initialized to nothing. if r: assert os.path.isfile(r) # Default path, if none is provided. if r is None: r = project.requirements_location with open(r) as f: contents = f.read() indexes = [] trusted_hosts = [] # Find and add extra indexes. for line in contents.split("\n"): index, extra_index, trusted_host, _ = parse_indexes(line.strip(), strict=True) if index: indexes = [index] if extra_index: indexes.append(extra_index) if trusted_host: trusted_hosts.append(get_host_and_port(trusted_host)) indexes = sorted(set(indexes)) trusted_hosts = sorted(set(trusted_hosts)) reqs = [ install_req_from_parsed_requirement(f) for f in parse_requirements(r, session=PipSession()) ] for package in reqs: if package.name not in BAD_PACKAGES: if package.link is not None: if package.editable: package_string = f"-e {package.link}" else: netloc, (user, pw) = split_auth_from_netloc(package.link.netloc) safe = True if user and not re.match(r"\${[\W\w]+}", user): safe = False if pw and not re.match(r"\${[\W\w]+}", pw): safe = False if safe: package_string = str(package.link._url) else: package_string = str(package.link) project.add_package_to_pipfile(package_string, dev=dev) else: project.add_package_to_pipfile(str(package.req), dev=dev) for index in indexes: # don't require HTTPS for trusted hosts (see: https://pip.pypa.io/en/stable/cli/pip/#cmdoption-trusted-host) host_and_port = get_host_and_port(index) require_valid_https = not any( ( v in trusted_hosts for v in ( host_and_port, host_and_port.partition(":")[ 0 ], # also check if hostname without port is in trusted_hosts ) ) ) project.add_index_to_pipfile(index, verify_ssl=require_valid_https) project.recase_pipfile() BAD_PACKAGES = ( "distribute", "pip", "pkg-resources", "setuptools", "wheel", )