
    ܖi                         d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	 ddl
mZmZmZ ddlmZ ddlmZ d	d
lmZ d	dlmZmZ  ej.                  e      Z G d dej4                        Z G d de      Zy)z[
Create virtual environments with a custom set of packages and inspect their dependencies.
    )annotationsN)Iterator)PathLike)NamedTemporaryFileTemporaryDirectory
gettempdir)SimpleNamespace)Version   )
AuditState)CalledProcessErrorrunc                  |     e Zd ZdZdg  e       f	 	 	 	 	 	 	 d fdZd	 fdZd
dZedd       Z	edd       Z
 xZS )
VirtualEnva  
    A wrapper around `EnvBuilder` that allows a custom `pip install` command to be executed, and its
    resulting dependencies inspected.

    The `pip-audit` API uses this functionality internally to deduce what the dependencies are for a
    given requirements file since this can't be determined statically.

    The `create` method MUST be called before inspecting the `installed_packages` property otherwise
    a `VirtualEnvError` will be raised.

    The expected usage is:
    ```
    # Create a virtual environment and install the `pip-api` package.
    ve = VirtualEnv(["pip-api"])
    ve.create(".venv/")
    for (name, version) in ve.installed_packages:
        print(f"Installed package {name} ({version})")
    ```
    Nc                l    t         |   d       || _        || _        || _        d| _        || _        y)a  
        Create a new `VirtualEnv`.

        `install_args` is the list of arguments that would be used the custom install command. For
        example, if you wanted to execute `pip install -e /tmp/my_pkg`, you would create the
        `VirtualEnv` like so:
        ```
        ve = VirtualEnv(["-e", "/tmp/my_pkg"])
        ```

        `index_url` is the base URL of the package index.

        `extra_index_urls` are the extra URLs of package indexes.

        `state` is an `AuditState` to use for state callbacks.
        T)with_pipN)super__init___install_args
_index_url_extra_index_urls	_packages_state)selfinstall_args	index_urlextra_index_urlsstate	__class__s        Z/var/www/html/content-pipeline/venv/lib/python3.12/site-packages/pip_audit/_virtual_env.pyr   zVirtualEnv.__init__,   s:    . 	$')#!1;?    c                p    	 t         |   |      S # t        $ r t               }t	        d| d      w xY w)z2
        Creates the virtual environment.
        z0Couldn't execute in a temporary directory under z. This is sometimes caused by a noexec mount flag or other setting. Consider changing this setting or explicitly specifying a different temporary directory via the TMPDIR environment variable.)r   createPermissionErrorr   VirtualEnvError)r   env_dirbase_tmpdirr   s      r    r#   zVirtualEnv.createJ   sP    
	7>'** 	 %,K!B;- PK K 	s    #5c           
        | j                   j                  d       |j                  dddddddg}	 t        || j                          | j                   j                  d       t               5 }t        |d      5 }|j                  dddddg| j                  dd|j                  | j                  }	 t        |d| j                          | j                   j                  d       t        j                  |      }|d   }g | _        |D ]3  }	|	d   }
| j                   j#                  |
d   t%        |
d         f       5 	 d
d
d
       d
d
d
       y
# t        $ r}t        d	|       |d
}~ww xY w# t        $ r6}t        j                  d|j                          t        d|       |d
}~ww xY w# 1 sw Y   txY w# 1 sw Y   y
xY w)ac  
        Install the custom package and populate the list of installed packages.

        This method is overridden from `EnvBuilder` to execute immediately after the virtual
        environment has been created and should not be called directly.

        We do a few things in our custom post-setup:
        - Upgrade the `pip` version. We'll be using `pip list` with the `--format json` option which
          requires a non-ancient version for `pip`.
        - Install `wheel`. When our packages install their own dependencies, they might be able
          to do so through wheels, which are much faster and don't require us to run
          setup scripts.
        - Execute the custom install command.
        - Call `pip list`, and parse the output into a list of packages to be returned from when the
          `installed_packages` property is queried.
        z1Updating pip installation in isolated environmentz-mpipinstallz	--upgradewheel
setuptools)r   zFailed to upgrade `pip`: Nz*Installing package in isolated environmentF)dirdeletez
--no-inputz--keyring-provider=subprocessz	--dry-runz--reportT)
log_stdoutr   zinternal pip failure: zFailed to install packages: z1Processing package list from isolated environmentmetadatanameversion)r   update_stateenv_exer   r   r%   r   r   _index_url_argsr1   r   loggererrorstderrjsonloadr   appendr
   )r   contextpip_upgrade_cmdcpeve_dirtmppackage_install_cmdinstall_reportpackage_listpackagepackage_metadatas              r    
post_setupzVirtualEnv.post_setupd   s   " 	  !TU OO	
	Zt{{3 	  !MN! +	V-?FSX-Y +	]` /# %%# # # # ###e'DL KK$$%XY!YYs^N))4L  DN' #*:#6 %%%f-w7G	7R/STO+	 +	 +	 " 	Z!$=o=N"OPVYY	Z@ & e5cjj\BC%(DEXDY&Z[adde7+	 +	 +	 +	s`   E -G;;F77E5A4F7G	E2E--E25	F4>1F//F44F77G 	<GGc              #  f   K   | j                   t        d      | j                   E d{    y7 w)z
        A property to inspect the list of packages installed in the virtual environment.

        This method can only be called after the `create` method has been called.
        NzcInvalid usage of wrapper.The `create` method must be called before inspecting `installed_packages`.)r   r%   )r   s    r    installed_packageszVirtualEnv.installed_packages   s4      >>!!] 
 >>!!s   '1/1c                    g }| j                   r|j                  d| j                   g       | j                  D ]  }|j                  d|g        |S )Nz--index-urlz--extra-index-url)r   extendr   )r   argsr   s      r    r5   zVirtualEnv._index_url_args   sO    ??KK89// 	:IKK,i89	:r!   )r   	list[str]r   z
str | Noner   rL   r   r   )r&   z-str | bytes | PathLike[str] | PathLike[bytes]returnNone)r<   r	   rM   rN   )rM   zIterator[tuple[str, Version]])rM   rL   )__name__
__module____qualname____doc__r   r   r#   rF   propertyrH   r5   __classcell__)r   s   @r    r   r      st    . !%&(&L  $	
 <4Sj " "  r!   r   c                      e Zd ZdZy)r%   zZ
    Raised when `VirtualEnv` fails to build or inspect dependencies, for any reason.
    N)rO   rP   rQ   rR    r!   r    r%   r%      s     	r!   r%   )rR   
__future__r   r9   loggingvenvcollections.abcr   osr   tempfiler   r   r   typesr	   packaging.versionr
   r   r   _subprocessr   r   	getLoggerrO   r6   
EnvBuilderr   	Exceptionr%   rV   r!   r    <module>rc      sa    #    $  G G ! %  0			8	$x xv	i 	r!   