B
    XM\e                 @   sH  d Z ddlmZ ddlmZ ddlZddlmZmZm	Z	 ddl
mZ ddlZddlZddlZddl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 ddlmZ dejjejjddderdnddeeddddg ddgddddgddZeddded d < d!d"d"d#d$d!d"d"d#d$d%d&d&d'd$d(d)d*d+d(d,d-d.d(d,d/Ze d0d1d2 Z!ddd3d4d5d6Z"ed7d8 Z#d9d: Z$d;d< Z%d=d> Z&ded@dAZ'dfdCdDZ(dgdEdFZ)dGdH Z*dIdJ Z+dKdL Z,dMdN Z-dOdP Z.dQdR Z/dSdT Z0edUdV Z1dhdWdXZ2dYdZ Z3did[d\Z4djd]d^Z5edkd_d`Z6dadb Z7dcdd Z8dS )lziThis file handles the parsing of feature specifications from files,
ending up with a configuration matrix    )OrderedDict)productN)abspath
expanduser
expandvars)parse_version)ensure_listtrim_empty_keys
get_logger)string_types)subdir)cc_conda_build)memoized)on_winz{0}.{1}z1.11z5.26.05z3.4z3.5Znoconazx.x)Zmin_pinZmax_pin)pythonr   numpypin_run_as_buildignore_versionignore_build_only_depsextend_keyszhttps://cran.r-project.org)r   r   perlluar_baseZcpu_optimization_targetr   r   r   r   Zcran_mirrorzx.x.xzr-baseZvs2008Zvs2010Zvs2015)z2.7z3.3z3.4z3.59Z10Z14Zgfortran)ccxxvcfortranZgccZgxx)r   r   r   ZclangZclangxx)winZlinuxZosx-   r   r   r   )PYZNPYZLUAZPERLRc             C   s   t |   }| dkr^t|tdkr*d}nt|tdkr>d}|d | |d< |d | |d< dd | D }| dkrt |  d	 | |d	< |S )
Nr   z3.5z3.2z2.7r   r   c             S   s"   i | ]\}}|d kr||d qS )r   Z	_compiler ).0Zlangpkg_namer%   r%   3lib/python3.7/site-packages/conda_build/variants.py
<dictcomp>a   s   z*_get_default_compilers.<locals>.<dictcomp>r   )DEFAULT_COMPILERScopyr   items)platformZpy_verZ	compilersr%   r%   r(   _get_default_compilersW   s    r.   c             C   sP   t  }| j|d< t| dr(| jds0|d n| jd }|t| j| |S )NZtarget_platformvariantr   )	DEFAULT_VARIANTSr+   r   hasattrr/   getupdater.   r-   )configbaser   r%   r%   r(   get_default_varianti   s    

r6   c          	   C   s`   ddl m}m} t| }| }W d Q R X ||||dd}tj|tjjdpRi }t	| |S )Nr   )select_linesns_cfgF)Zvariants_in_place)Loader)
Zconda_build.metadatar7   r8   openreadyamlloadloaderZ
BaseLoaderr	   )pathr4   r7   r8   fcontentsZcontentr%   r%   r(   parse_config_filer   s    
rB   c             C   s   g }x$| D ]}d|kr
| d| q
W t| }xN|D ]F}x@|D ]8}x2|dD ]$}|| krR| d||d qRW qBW q8W |rtd|d S )Nr    z;"-" is a disallowed character in variant keys.  Key was: {}#z7zip_key entry {} in group {} does not have any settingsz!Variant configuration errors: 
{})appendformat_get_zip_groupssplit
ValueError)specerrorskeyZ
zip_groupsgroupZ	group_keyZvariant_keyr%   r%   r(   validate_spec|   s    


rM   Fc             C   s   dd |pg D }|s|st dr:tttt d }ntjtdd}tj|rb|	| tjt
 d}tj|r|	| t| drtj| jd}ntj| d}tj|r|	| |r|dd |D  |S )zFind files to load variables from.  Note that order here determines clobbering.

    Later files clobber earlier ones.  order is user-wide < cwd < recipe dir < additional filesc             S   s    g | ]}t jt j|qS r%   )osr?   r   r   )r&   config_filer%   r%   r(   
<listcomp>   s   z%find_config_files.<locals>.<listcomp>rO   ~zconda_build_config.yamlr?   c             S   s   g | ]}t j|qS r%   )rN   r?   r   )r&   Zadditional_filer%   r%   r(   rP      s    )r   r2   r   r   r   rN   r?   joinisfilerD   getcwdr1   extend)Zmetadata_or_pathZadditional_filesignore_system_configexclusive_config_filesfilesZsystem_pathcwdZrecipe_configr%   r%   r(   find_config_files   s&    




rZ   Tc                s  i t |}t |}x|  D ]\}r |rJtt}|d| x D ]\ }|rl |krV |krt|dr krt  dr  | q|  < n:t 	 g  <   
t | tt   < qV dkrtdd |D }t|d ts,t|d ts,|g}	 g  <   
| tdd td	d   D D  < qVt|dr|  < qV g}	|rx|D ]}
 |
kr|
}	P qW tfd
d|	D r<xf|	D ]^}tt | tt |kr$td| |tt |tt | t | |< qW qV krVxn|	D ]Z}|krxtt | tt |krxP |krJtt | tt |krJP qJW |  < t fddt |D rVtd|qVW q W S )NzAdding in variants from {}keyszip_keysc             S   s   g | ]}|r|qS r%   r%   )r&   Zsubvalr%   r%   r(   rP      s    z._combine_spec_dictionaries.<locals>.<listcomp>r   c             s   s   | ]}t |V  qd S )N)list)r&   Z	set_groupr%   r%   r(   	<genexpr>   s    z-_combine_spec_dictionaries.<locals>.<genexpr>c             s   s   | ]}t |V  qd S )N)tuple)r&   rL   r%   r%   r(   r^      s   c             3   s   | ]}| kV  qd S )Nr%   )r&   
group_item)rI   r%   r(   r^      s    znAll entries associated by a zip_key field must be the same length.  In {}, {} and {} are different ({} and {})c             3   s   | ]}|  kV  qd S )Nr%   )r&   Zsubvalue)kvaluesr%   r(   r^      s   zvariant config in {} is ambiguous because it does not fully implement all zipped keys, or specifies a subspace that is not fully implemented.)r   r,   r
   __name__inforE   r1   r3   r+   r2   rU   r]   set
isinstancer_   alllenrH   any)specsr   filter_keysr\   
log_outputr[   Zspec_sourcelogvZkeys_in_grouprL   r`   r%   )ra   rI   rb   r(   _combine_spec_dictionaries   sp    

 






ro   c             C   sV   t d dd }|dd |  D  t| |dg|ddg }t| |||d}|S )a  With arbitrary sets of sources, combine into a single aggregate spec.

    Later specs in the input set have priority and overwrite duplicate entries.

    specs: list of dictionaries.  Keys are arbitrary, but correspond to variable
           names used in Jinja2 templated recipes.  Values can be either single
           values (strings or integers), or collections (lists, tuples, sets).
    r   Nc             S   s(   g | ] }|rt |d D ]}|qqS )r   )r   r2   )r&   rI   rK   r%   r%   r(   rP     s    z!combine_specs.<locals>.<listcomp>r\   )r   rk   rl   )r   r\   rl   )r0   rU   rb   ro   r2   )rj   rl   r   r\   rb   r%   r%   r(   combine_specs  s    	rp   c             C   sp   dd t  D }i }xT| D ]H\}}|| kr t| | }|dkr\d|ddd }||d| < q W |S )	zGiven args passed into conda command, set language env vars to be made available.

    Search terms: CONDA_PY, CONDA_R, CONDA_PERL, CONDA_LUA, CONDA_NPY
    c             S   s   i | ]\}}||qS r%   r%   )r&   ra   rn   r%   r%   r(   r)     s    z)set_language_env_vars.<locals>.<dictcomp>r#    .N   ZCONDA_)
SUFFIX_MAPr,   strrR   rG   )r/   Zinverse_mapenvZvariant_nameZenv_var_namevaluer%   r%   r(   set_language_env_vars  s    rx   c                s*   t   d }t fdd| D  }|p(|S )Nc             3   s*   | ]"}|D ]}| kp  |V  q
qd S )N)add)r&   Z_setitem)seenr%   r(   r^   -  s    zall_unique.<locals>.<genexpr>)re   ri   )Z_listrz   uniquer%   )r{   r(   
all_unique*  s    r}   c             C   s,   t dd | D }t dd | D }||fS )Nc             s   s   | ]}t |tV  qd S )N)rf   r   )r&   rK   r%   r%   r(   r^   2  s    z$_get_zip_key_type.<locals>.<genexpr>c             s   s$   | ]}t |d ot|t V  qdS )__iter__N)r1   rf   r   )r&   rK   r%   r%   r(   r^   3  s   )rg   )r\   
is_stringsis_list_of_stringsr%   r%   r(   _get_zip_key_type1  s    
r   c                s     d}t }|rt|dr(t|tr0tdt|\}}|sL|sLtdt }|rnt|dkrn|| nFt	|}|dk	rt
d|x&|D ]}t|dkr|t| qW  fdd|D }|S )	z/Used to exclude particular keys from the matrixr\   r~   zKzip_keys must be uniformly a list of strings, or a list of lists of stringsr!   TzXAll packages in zip keys must belong to only one group.  '{}' is in more than one group.c                s   h | ]}| kr|qS r%   r%   )r&   rK   )combined_variantr%   r(   	<setcomp>Q  s    z#_get_zip_key_set.<locals>.<setcomp>)r2   re   r1   rf   r   AssertionErrorr   rh   r3   r}   rH   rE   )r   r\   Zkey_setr   r   Z_all_uniqueZksr%   )r   r(   _get_zip_key_set8  s&    

r   c          	      s    fdd|D }i }|rd |}tt |d  }xD|D ]<}tt | |ks>td|d  |d  | | q>W tt fdd|D  }dd |D }||i}|S )Nc                s   g | ]}| kr|qS r%   r%   )r&   rK   )r   r%   r(   rP   V  s    z*_get_zip_dict_of_lists.<locals>.<listcomp>rC   r   zyzip field {} ({}) length does not match zip field {} ({}) length.  All zip fields within a group must be the same length.c                s   g | ]}t  | qS r%   )r   )r&   rK   )r   r%   r(   rP   d  s    c             S   s   g | ]}d  |qS )rC   )rR   )r&   rw   r%   r%   r(   rP   e  s    )rR   rh   r   rH   rE   r]   zip)r   Zlist_of_stringsZ	used_keysoutZdict_keylengthrK   rb   r%   )r   r(   _get_zip_dict_of_listsU  s    

r   c             C   sZ   |  d}g }|rVt|\}}|r4|t| | n"|rVx|D ]}|t| | q>W |S )zJreturns a list of dictionaries - each one is a concatenated collection of r\   )r2   r   rD   r   )r   r\   groupsr   r   rL   r%   r%   r(   rF   j  s    

rF   c          
   C   st   g }t |dr| }n\xZ| D ]R}||dk	rF|||krF|| qtt}|dj|||||d qW |S )zvariants is the exploded out list of dicts, with one value per key in each dict.
    key and values come from subsequent variants before they are exploded out.r[   NzrFiltering variant with key {key} not matching target value(s) ({tgt_vals}) from {source_name}, actual {actual_val})rK   Ztgt_valssource_nameZ
actual_val)r1   r2   rD   r
   rc   debugrE   )variantsrK   rb   r   Zreduced_variantsr/   rm   r%   r%   r(   filter_by_key_valuex  s    

r   c             C   s
   |  |S )N)rG   )stringcharr%   r%   r(   
_split_str  s    r   c                sj  g }|st t| d}t dddgtt| tt|    fdd|  D }xt| D ]}|| q`W t| xt	|
  D ]}ttj||}x* D ]"}| |}|s|dkr|||< qW t  }	xp| D ]d\}
}t|
trt|trt|
d}t|d}x t||D ]\}}|||< qW d|
kr|	|
 qW x|	D ]}||= qHW || qW |S )Nr   r\   r   c                s   i | ]\}}| kr||qS r%   r%   )r&   ra   rn   )pass_through_keysr%   r(   r)     s    z2dict_of_lists_to_list_of_dicts.<locals>.<dictcomp>rq   rC   )re   r   r2   r]   r   r,   rF   r3   r	   r   rb   dictsixZmovesr   rf   r   r   ry   rD   )Zdict_of_listsr   ZdictsZ
dimensionsrL   xZremappedcolrn   Zto_delra   r[   rb   Z_kZ_vrK   r%   )r   r(   dict_of_lists_to_list_of_dicts  s:    




r   c                s  | sdS t   t }d}d| d kr<| d d r<| d d ng }|rt| d d d tspt| d d d tr~| d d }n| d d g}x$|D ]}x|D ]}|| qW qW x| D ]}x| D ]\}}|dkrqt|dr |t  }	|		| |	 |< qt|tr2t |t t|B  |< qt |g t
|  |< ||krtt |  |< qW qW |rxT|D ]L}tttt fdd|D   }
x"t|D ]\}}|
|  |< qW q~W | d<  S )zOpposite of dict_of_lists_to_list_of_dicts function.

    Take broken out collection of variants, and squish it into a dict, where each value is a list.
    Only squishes string/int values; does "update" for dict keys
    Nr\   r   r[   c             3   s   | ]} | V  qd S )Nr%   )r&   rK   )squishedr%   r(   r^     s    z1list_of_dicts_to_dict_of_lists.<locals>.<genexpr>)r   re   rf   r]   r_   ry   r,   r1   r2   r3   r   r   	enumerate)Zlist_of_dictsZall_zip_keysr   Zzip_key_groupsrL   rz   r/   ra   rn   Zexisting_valuerb   idxrK   r%   )r   r(   list_of_dicts_to_dict_of_lists  sF    




 
"r   c             C   s  t | dr| j}|s&ddlm} | }t| t|j|j|jd}t	t
|d}x|D ]}t||||< qTW t |dr|jr|j|d< |r||d< xX| D ]L\}}yt| W q tk
r } ztd	|t|W d d }~X Y qX qW t||jd
}	tt|	d}
|
ddh | }|d= t|	|
d}	xRt| D ]B\}}x6| D ]*\}}||
krRt|	|||dpx|	}	qRW q@W |	S )Nr4   r   )Config)rV   rW   )internal_defaultsr/   zconfig.variantZargument_variantszError in config {}: {})rl   r   r\   r   )r   )r   )r1   r4   Zconda_build.configr   rZ   r   Zvariant_config_filesZignore_system_variantsrW   r   r6   rB   r/   r,   rM   rH   rE   ru   rp   verbosere   r2   r3   r+   r   reversedr   )Zrecipedir_or_metadatar4   r   r   rX   rj   r@   rI   eZcombined_specr   sourceZsource_specsra   Zvsr%   r%   r(   get_package_variants  s@    



*
r   c                sD   dddh ttd d  fddd D }|S )z|For purposes of naming/identifying, provide a way of identifying which variables contribute
    to the matrix dimensionalityr   r\   r   r   r   c                s<   g | ]4  krr4t  fd ddd D r qS )c             3   s"   | ]}|  d    kV  qdS )r   Nr%   )r&   r/   )ra   r   r%   r(   r^   !  s    z&get_vars.<locals>.<listcomp>.<genexpr>r!   N)ri   )r&   )	loop_onlyspecial_keysr   )ra   r(   rP     s    
zget_vars.<locals>.<listcomp>)r3   re   r   r2   )r   r   Z	loop_varsr%   )r   r   r   r(   get_vars  s    
r   c                s  t  }| }x| D  ]g  td}|rl|sl|ddt } | fdd|D }nfdd|D }|sqt}dttj	d}	d	| }
d
| }d| d }d|	 }|r܈ 
|g n 
|
||g d  t fdd|D r| qW |S )Nz(.*?)_compiler(_version)?$r!   z&\{\s*compiler\([\'\"]%s[\"\'][^\{]*?\}c                s    g | ]}|ks |kr|qS r%   r%   )r&   line)compiler_langrn   r%   r(   rP   2  s    z/find_used_variables_in_text.<locals>.<listcomp>c                s    g | ]} | d dkr|qS )r    _)replace)r&   r   )rn   r%   r(   rP   4  s    z[-_]r   z-\{\s*(?:pin_[a-z]+\(\s*?['\"])?%s[^'\"]*?\}\}z/^[^#\[]*?\#?\s\[[^\]]*?(?<![_\w\d])%s[=\s<>!\]]z(?:^|[^\{])\{%\s*(?:el)?if\s*z\s*(?:[^%]*?)?%\}z^\s+\-\s+%s\s*(?:\s[\[#]|$)|c             3   s   | ]}t  |V  qd S )N)research)r&   r   )all_resr%   r(   r^   D  s    z.find_used_variables_in_text.<locals>.<genexpr>)re   
splitlinesr   matchrL   escaperD   rR   maprG   rU   ri   ry   )r/   Zrecipe_textZ	selectorsused_variablesZrecipe_linesZcompiler_matchZcompiler_regexZvariant_linesZv_regexZv_req_regexvariant_regexZselector_regexZconditional_regexZrequirement_regexr%   )r   r   rn   r(   find_used_variables_in_text%  s4    



r   c          	   C   s^   t |}| }W d Q R X t }x6| D ].}d| }tj||tjtjB dr(|| q(W |S )Nz(^[^$]*?\$\{?\s*%s\s*[\s|\}]))flags)r:   r;   re   r   r   	MULTILINEDOTALLry   )r/   	file_pathr@   textr   rn   r   r%   r%   r(   #find_used_variables_in_shell_scriptI  s    

r   c          	   C   sb   t |}| }W d Q R X t }x:| D ]2}d| d }tj||tjtjB dr(|| q(W |S )Nz\%)r   )r:   r;   re   r   r   r   r   ry   )r/   r   r@   r   r   rn   r   r%   r%   r(   #find_used_variables_in_batch_scriptT  s    

r   )NFN)NNNT)T)N)NN)F)F)9__doc__collectionsr   	itertoolsr   rN   os.pathr   r   r   Zpkg_resourcesr   r   sysr   r<   Zconda_build.utilsr   r	   r
   Zconda_build.conda_interfacer   r   r   r   r   rE   version_infomajorminorr0   r*   rsplitZ	arch_namert   r.   r6   rB   rM   rZ   ro   rp   rx   r}   r   r   r   rF   r   r   r   r   r   r   r   r   r   r%   r%   r%   r(   <module>   s   

	
 
" 
P

).
2
#