U
    ee2+                     @   sr   d dl Z d dlZd dlmZmZ d dlmZmZmZm	Z	m
Z
mZ d dlmZmZmZ G dd dZefddZdS )	    N)existsjoin)debuginfoinfo_notifywarning	Err_StyleErr_Fore)current_directoryBuildInterruptingExceptionrmdirc                	   @   s   e Zd ZdZdZdZdZdZdZdZ	g Z
g ZdZdd Zdd Zd	d
 Zedg ddg dddddZdd Zdd Zeg fddZdd ZdS )Distributiona   State container for information about a distribution (i.e. an
    Android project).

    This is separate from a Bootstrap because the Bootstrap is
    concerned with building and populating the dist directory, whereas
    the dist itself could also come from e.g. a binary download.
    NF c                 C   s
   || _ d S N)ctx)selfr    r   A/tmp/pip-unpacked-wheel-h4dze4ss/pythonforandroid/distribution.py__init__"   s    zDistribution.__init__c                 C   s   d | jd| jS )Nz)<Distribution: name {} with recipes ({})>, )formatnamer   recipesr   r   r   r   __str__%   s     
zDistribution.__str__c                 C   s   t | S r   )strr   r   r   r   __repr__*   s    zDistribution.__repr__T)r   r   ndk_apiforce_buildextra_dist_dirsrequire_perfect_matchallow_replace_distc             	      s  t |}
td|
  d}dk	rVrV fdd|
D }
td|
  |
rV|
d }g }|
D ]t|dk	rtj|ks~jdkrtd d| d	j  q^|D ]&}|jkrtd d
|   q^q| q^|}
td|
  |
rtd t|
 ntd |
D ]ĉ|rtd q|dk	r@j|kr@td qtfdd D sdtd qt	jt	|kst	|
t	jr|stdj   S tdt	| dt	j  q|dk	r|	stdj||jd|d|jdt|
dk stt |d_sbd}d}tt|j||rX|d7 }q4||_t|j_|_|j_ _S )a  Takes information about the distribution, and decides what kind of
        distribution it will be.

        If parameters conflict (e.g. a dist with that name already
        exists, but doesn't have the right set of recipes),
        an error is thrown.

        Parameters
        ----------
        name : str
            The name of the distribution. If a dist with this name already '
            exists, it will be used.
        ndk_api : int
            The NDK API to compile against, included in the dist because it cannot
            be changed later during APK packaging.
        archs : list
            The target architectures list to compile against, included in the dist because
            it cannot be changed later during APK packaging.
        recipes : list
            The recipes that the distribution must contain.
        force_download: bool
            If True, only downloaded dists are considered.
        force_build : bool
            If True, the dist is forced to be built locally.
        extra_dist_dirs : list
            Any extra directories in which to search for dists.
        require_perfect_match : bool
            If True, will only match distributions with precisely the
            correct set of recipes.
        allow_replace_dist : bool
            If True, will allow an existing dist with the specified
            name but incompatible requirements to be overwritten by
            a new one with the current requirements.
        zAll possible dists: Nc                    s0   g | ](  j krt fd dD r qS )c                 3   s   | ]}| j kV  qd S r   archs.0Z	arch_namedr   r   	<genexpr>h   s     z;Distribution.get_distribution.<locals>.<listcomp>.<genexpr>)r   all)r%   )r#   r   r&   r   
<listcomp>f   s   
 z1Distribution.get_distribution.<locals>.<listcomp>zDist matching name and arch: r   zdist z% failed to match ndk_api, target api z, dist api z missing recipe z"Dist matching ndk_api and recipe: zIOf the existing distributions, the following meet the given requirements:z.No existing dists meet the given requirements!z!Skipping dist due to forced buildz%Skipping dist due to ndk_api mismatchc                 3   s   | ]}| j kV  qd S r   r"   r$   )distr   r   r(      s     z0Distribution.get_distribution.<locals>.<genexpr>z"Skipping dist due to arch mismatchz){} has compatible recipes, using this onez0Skipping dist due to recipes mismatch, expected z	, actual zAsked for dist with name {name} with recipes ({req_recipes}) and NDK API {req_ndk_api}, but a dist with this name already exists and has either incompatible recipes ({dist_recipes}) or NDK API {dist_ndk_api}r   )r   Zreq_ndk_apiZdist_ndk_apiZreq_recipesZdist_recipes   Tzunnamed_dist_{}   )r   get_distributionsr   r   r   appendr   pretty_log_distsr)   setissubsetr   r   r   r   r   lenAssertionErrorneeds_buildr   dist_dirr#   )clsr   r#   r   r   r   r   r   r    r!   Zpossible_distsZfolder_match_distZ_possible_distsZrecipeZfilenir   )r#   r+   r   r   get_distribution-   s    1




zDistribution.get_distributionc                 C   s
   t | jS r   )r   r6   r   r   r   r   folder_exists   s    zDistribution.folder_existsc                 C   s   t | j d S r   )r   r6   r   r   r   r   delete   s    zDistribution.deletec              
   C   s   |rt d|j}tt|d}|D ]}|tt|d q&g }|D ]}tt|drJtt|d}t|}	W 5 Q R X | |}
|	d |
_	||
_d|
_
|	d |
_d|	kr|	d |
_d|	kr|	d |
_nd	|
_td
j|
j	|
jd ||
 qJ|S )z,Returns all the distributions found locally.zDextra_dist_dirs argument to get_distributions is not yet implemented*dist_info.json	dist_nameFr   r#   r   NzxDistribution {distname}: ({distdir}) has been built with an unknown api target, ignoring it, you might want to delete it)distnameZdistdir)r   r6   globr   extendr   openjsonloadr   r5   r   r#   r   r   r   r/   )r7   r   r   r6   foldersdirdistsfolderfilehZ	dist_infor+   r   r   r   r.      s>    


zDistribution.get_distributionsc                 C   s   t |v td tddX}t| j| jjjdd | jjD | jj	| jj
| jj| jj | jj| jjjd| W 5 Q R X W 5 Q R X dS )zJ
        Save information about the distribution in its dist_dir.
        zSaving distribution infor=   wc                 S   s   g | ]
}|j qS r   )arch)r%   rK   r   r   r   r*      s     z*Distribution.save_info.<locals>.<listcomp>)r>   	bootstrapr#   r   use_setup_pyr   
hostpythonpython_versionN)r
   r   rB   rC   dumpr   r   rL   r#   r   rM   Zrecipe_build_orderZpython_modulesrN   Zpython_recipeZmajor_minor_version_string)r   ZdirnrI   r   r   r   	save_info   s    
zDistribution.save_info)__name__
__module____qualname____doc__r   r   r5   urlr6   r   r#   r   descriptionr   r   r   classmethodr9   r:   r;   r.   rQ   r   r   r   r   r      s8    &r   c                 C   st   g }| D ]P}|j d krdn|j }|dj||jd|j|jrJd|jndttd q|D ]}|d|  q^d S )Nunknownz{Fore.GREEN}{Style.BRIGHT}{name}{Style.RESET_ALL}: min API {ndk_api}, includes recipes ({Fore.GREEN}{recipes}{Style.RESET_ALL}), built for archs ({Fore.BLUE}{archs}{Style.RESET_ALL})r   UNKNOWN)r   r   r   r#   ForeStyle	)	r   r/   r   r   r   r   r#   r	   r   )rG   Zlog_funcZinfosr+   r   liner   r   r   r0     s     
 
	r0   )rC   r@   os.pathr   r   Zpythonforandroid.loggerr   r   r   r   r   r	   Zpythonforandroid.utilr
   r   r   r   r0   r   r   r   r   <module>   s     ~