B
    lz]!                 @   sV  d dl mZmZ d dlm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 d dlmZ d d	lmZ d d
lm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 yd dl m!Z!m"Z" W n$ e#k
r   d dl$m!Z!m"Z" Y nX dZ%dd Z&dd Z'd#ddZ(dd Z)dd Z*G dd deZ+d$dd Z,G d!d" d"e-Z.dS )%    )absolute_importprint_function)OrderedDict)chainN)context)common)yaml_load_standard)
PrefixData)PackageType)	MatchSpec)PrefixGraph)dump   )compat
exceptionsyaml)History)concatvgroupby)namedependenciesprefixchannelsc       
         s  g }| r|   ni }x,|  D ] }|tkr|| || qW |r|d}t|dkr`dnd}t|dkrtdnd}tdj|||d x|D ]}td	| qW td | d
g }t	
d xL|D ]D}	t|	trd|	krt fdd|D std |d
 dd qW |S )z8Check for unknown keys, remove them and print a warning.filenamer   Zareiss zn
EnvironmentSectionNotValid: The following section{plural} on '{filename}' {verb} invalid and will be ignored:)r   pluralverbz - {}r   z[<>~\s=]pipc             3   s*   | ]"}t |d s |d dkV  qdS )keysr   r   N)hasattrsplit).0_)depsplit ,lib/python3.7/site-packages/conda_env/env.py	<genexpr>8   s    z validate_keys.<locals>.<genexpr>aE  Warning: you have pip-installed dependencies in your environment file, but you do not list pip itself as one of your conda dependencies.  Conda may not use the correct pip to install your packages, and they may end up in the wrong place.  Please add an explicit pip dependency.  I'm adding one for you, but still nagging you.r   )copyr    
VALID_KEYSappendpopgetlenprintformatrecompile
isinstancedictanyinsert)
datakwargsZinvalid_keysZnew_datakeyr   r   r   depsZdepr&   )r%   r'   validate_keys    s.    




r;   c          	   C   sr   ddg}xVx6|D ].}yt tj| |S  tjk
r<   Y qX qW | }tj| } | |kr
P q
W t|d dS )z=Load and return an ``Environment`` from a given ``directory``zenvironment.ymlzenvironment.yamlr   N)	from_fileospathjoinr   EnvironmentFileNotFounddirname)Z	directoryfilesfZold_directoryr&   r&   r'   load_from_directoryB   s    

rD   Fc             C   s\  |r8t | }dd | D }t| |ttj|dS t|dd}tt	|
 j}tdd |}	tt|	dd	|	tjd	|	tjd	d
d d}
tt|	tjd	|	tjd	|	tjd	dd d}|rdd |
D }ndd |
D }|r|ddd |D i ttj}|sLx,|
D ]$}|jj}||kr$|d| q$W t| |||dS )af  
        Get environment object from prefix
    Args:
        name: The name of environment
        prefix: The path of prefix
        no_builds: Whether has build requirement
        ignore_channels: whether ignore_channels
        from_history: Whether environment file should be based on explicit specs in history

    Returns:     Environment object
    c             S   s   g | ]}t |qS r&   )str)r#   packager&   r&   r'   
<listcomp>b   s    z$from_environment.<locals>.<listcomp>)r   r   r   r   T)Zpip_interop_enabledc             S   s   | j S )N)Zpackage_type)xr&   r&   r'   <lambda>h       z"from_environment.<locals>.<lambda>Nr&   c             S   s   | j S )N)r   )rH   r&   r&   r'   rI   m   rJ   )r9   c             S   s   | j S )N)r   )rH   r&   r&   r'   rI   t   rJ   c             S   s   g | ]}d  |j|jfqS )=)r?   r   version)r#   ar&   r&   r'   rG   w   s    c             S   s"   g | ]}d  |j|j|jfqS )rK   )r?   r   rL   Zbuild)r#   rM   r&   r&   r'   rG   y   s    r   c             S   s   g | ]}d |j |jf qS )z%s==%s)r   rL   )r#   rM   r&   r&   r'   rG   {   s    r   )r   Zget_requested_specs_mapvaluesEnvironmentlistr   r   r	   tupler   Ziter_recordsZgraphr   sortedr   r-   r
   ZNOARCH_GENERICZNOARCH_PYTHONZVIRTUAL_PYTHON_WHEELZVIRTUAL_PYTHON_EGG_MANAGEABLEZVIRTUAL_PYTHON_EGG_UNMANAGEABLEr+   Zchannelcanonical_namer6   )r   r   Z	no_buildsZignore_channelsZfrom_historyhistoryr:   ZpdZprecsZgrouped_precsZconda_precsZ	pip_precsr   r   ZprecrS   r&   r&   r'   from_environmentS   s<    



rU   c             K   sB   t | }t||}|dk	r8x| D ]\}}|||< q$W tf |S )z>Load and return a ``Environment`` from a given ``yaml string``N)r   r;   itemsrO   )yamlstrr8   r7   r9   valuer&   r&   r'   	from_yaml   s    
rY   c          	   C   s@   t j| st| t| d}| }t|| dS Q R X d S )Nr)r   )r=   r>   existsr   r@   openreadrY   )r   fprW   r&   r&   r'   r<      s
    
r<   c                   s,   e Zd Z fddZdd Zdd Z  ZS )Dependenciesc                s$   t t| j|| || _|   d S )N)superr_   __init__rawparse)selfrb   argsr8   )	__class__r&   r'   ra      s    zDependencies.__init__c             C   s   | j s
d S | dg i x8| j D ].}t|tr:| | q | d t| q W d| kr| d sh| d= tdd | d D s| d d d S )NZcondar   c             s   s   | ]}t |jd kV  qdS )r   N)r   r   )r#   r   r&   r&   r'   r(      s    z%Dependencies.parse.<locals>.<genexpr>)rb   updater3   r4   r+   r   Zarg2specr5   )rd   liner&   r&   r'   rc      s    
zDependencies.parsec             C   s   | j | |   d S )N)rb   r+   rc   )rd   Zpackage_namer&   r&   r'   add   s    zDependencies.add)__name__
__module____qualname__ra   rc   ri   __classcell__r&   r&   )rf   r'   r_      s   r_   c             c   sj   t  }|j}|dkr:xP| D ]}||kr|| |V  qW n,x*| D ]"}||}||kr@|| |V  q@W dS )a   Return only unique elements of a sequence
    >>> tuple(unique((1, 2, 3)))
    (1, 2, 3)
    >>> tuple(unique((1, 2, 1, 3)))
    (1, 2, 3)
    Uniqueness can be defined by key keyword
    >>> tuple(unique(['cat', 'mouse', 'dog', 'hen'], key=len))
    ('cat', 'mouse')
    N)setri   )seqr9   seenZseen_additemvalr&   r&   r'   unique   s    


rs   c               @   sB   e Zd ZdddZdd Zdd Zddd	Zdd
dZdd ZdS )rO   Nc             C   s2   || _ || _|| _t|| _|d kr(g }|| _d S )N)r   r   r   r_   r   r   )rd   r   r   r   r   r   r&   r&   r'   ra      s    
zEnvironment.__init__c             C   s   t tt|| jf| _d S )N)rP   rs   r   from_iterabler   )rd   r   r&   r&   r'   add_channels   s    zEnvironment.add_channelsc             C   s
   g | _ d S )N)r   )rd   r&   r&   r'   remove_channels   s    zEnvironment.remove_channelsc             C   sd   t d| jfg}| jr"| j|d< | jr4| jj|d< | jrD| j|d< |d krP|S |t	| d S )Nr   r   r   r   )
r   r4   r   r   r   rb   r   writejsondumps)rd   streamdr&   r&   r'   to_dict   s    

zEnvironment.to_dictc             C   s:   |   }tt|}|d kr"|S |tj|dd d S )Nzutf-8)encoding)r|   r   ur   rw   b)rd   rz   r{   outr&   r&   r'   to_yaml   s
    zEnvironment.to_yamlc          	   C   s(   t | jd}| j|d W d Q R X d S )Nwb)rz   )r\   r   r   )rd   r^   r&   r&   r'   save   s    zEnvironment.save)NNNNN)N)N)	rj   rk   rl   ra   ru   rv   r|   r   r   r&   r&   r&   r'   rO      s    



rO   )FFF)N)/Z
__future__r   r   collectionsr   	itertoolsr   r=   r1   rx   Zconda.base.contextr   Z	conda.clir   Zconda.common.serializer   Zconda.core.prefix_datar	   Zconda.models.enumsr
   Zconda.models.match_specr   Zconda.models.prefix_graphr   Zconda_env.yamlr   r   r   r   r   Zconda.historyr   Zcytoolz.itertoolzr   r   ImportErrorZconda._vendor.toolz.itertoolzr*   r;   rD   rU   rY   r<   r_   rs   objectrO   r&   r&   r&   r'   <module>   s8   "
3	
