U
    eb                     @   sx   d dl Z d dlZd dlZd dlZd dlmZ d dlmZ G dd dee j	Z
G dd dee j	ZG dd	 d	ee jZdS )
    N)BaseCommandMixin)CONFIGc                       sZ   e Zd ZdZejjjejjjejjjdZ	 fddZ
edd Zdd Zd	d
 Z  ZS )RootCommandzAThis class defers to either the PluginCommand or the builtin cmds)infotoolsdevc                    s  dd l }dd l}ddddddg}|d}g }g }|jD ]R t fd	d
|D r\|  | }	|	d k	r8|	 \}
| d|
 f q8|s|r|rdd| }t	j
td|dd |rddd
 |D }d| }t	j
td|dd |d t j|| d | _d S )Nr   u   ‘u   ’u   “u   ”u   —u   –z--m-(\S+)-categoryc                 3   s   | ]}| kV  qd S N ).0xZcommandr	   Flib/python3.8/site-packages/q2cli-2024.2.0-py3.8.egg/q2cli/commands.py	<genexpr>%   s     z'RootCommand.__init__.<locals>.<genexpr>z--m-%s-columnzdError: Detected invalid character in: %s
Verify the correct quotes or dashes (ASCII) are being used., errorTerr
c                 s   s   | ]\}}d ||f V  qdS )zInstead of %s, trying using %sNr	   )r
   oldnewr	   r	   r   r   5   s   z|Error: The following options no longer exist because metadata *categories* are now called metadata *columns* in QIIME 2.

%s)resyscompileargvanyappend	fullmatchgroupsjoinclickechor   	cfg_styleexitsuper__init___plugins)selfargskwargsr   r   ZunicodesZcategory_regexZinvalid_charsZ
categoriesmatchZ
param_namemsgZold_to_new_names	__class__r   r   r%      s<    






zRootCommand.__init__c                 C   s\   dd l }| jd kr(dd l}|jjjj| _i }| j D ] \}}|d r6|||j	|< q6|S )Nr   actions)

q2cli.utilr&   Zq2cli.core.cachecorecacheZCACHEpluginsitemsutilto_cli_name)r'   q2cliZname_mapnamepluginr	   r	   r   _plugin_lookupD   s    
zRootCommand._plugin_lookupc                 C   s$   dd l }| j}t| j}|||S )Nr   )	itertools_builtin_commandssortedr9   chain)r'   ctxr:   builtinsr2   r	   r	   r   list_commandsU   s    
zRootCommand.list_commandsc              	   C   s   || j kr| j | S z| j| }W n tk
r   ddlm} ||| j}t|dkrdd|d  }n|rxdd| }nd}tjt	
dd	| | d
d |d Y nX t||S )Nr   get_close_matches     Did you mean %r?  (Possible commands: %s)r    r   z.Error: QIIME 2 has no plugin/command named %r.Tr      )r;   r9   KeyErrorr/   rB   lenr   r    r!   r   r"   r#   PluginCommand)r'   r>   r7   r8   rB   possibilitieshintr	   r	   r   get_command_   s,    

zRootCommand.get_command)__name__
__module____qualname____doc__r6   Zbuiltinr   r   r   r;   r%   propertyr9   r@   rM   __classcell__r	   r	   r,   r   r      s   )

r   c                       sP   e Zd ZdZ fddZdd Zdd Zdd	 Zd
d Zdd Z	dd Z
  ZS )rJ   z2Provides ActionCommands based on available Actionsc              
      s  dd l }|| _i | _i | _|d  D ]8\}}|drL|| j|j|< q&|| j|j|< q&d|d  }d|d  }	d|d	  }
d
	|
|	|g}t
jdddd| jdd|j| j|j| jg}| ji kr|t
jdddd| jdd t j|f||d ||d| d S )Nr   r.   _zGetting user support: %sZuser_support_textzPlugin website: %swebsitezDescription: %sdescription

)z	--versionTFzShow the version and exit.)is_flagZexpose_valueZis_eagercallbackhelp)z--show-hidden-actionszThis plugin has hidden actions with names starting with '_'. These are generally called internally by pipelines. Passing this flag will display those actions.Zshort_description)
short_helprZ   params)r/   _plugin_action_lookup_hidden_actionsr3   
startswithr4   Zhidden_to_cli_namer5   r   r    Option_get_versionexample_data_option_get_plugincitations_option_get_citation_recordsr   _get_hidden_actionsr$   r%   )r'   r8   r7   r(   r)   r6   idaZsupportrU   rV   help_r\   r,   r	   r   r%   {   sJ    

 
  
 zPluginCommand.__init__c           	      C   s   |r
|j rd S dd l}|j }|j D ]$}| jd |jkr*|j}|j	} qXq*d }}t
d| jd | jd ||f  |  d S )Nr   r7   z	[UNKNOWN]z=QIIME 2 Plugin '%s' version %s (from package '%s' version %s)version)resilient_parsingr/   r4   get_plugin_managerr2   valuesr]   r7   Zproject_namerk   r    r!   r#   )	r'   r>   paramvaluer6   pmr8   pkg_nameZpkg_versionr	   r	   r   rb      s&    

 zPluginCommand._get_versionc                 C   s$   dd l }|j }|j| jd  jS Nr   r7   )r/   r4   rm   r2   r]   	citationsr'   r6   rq   r	   r	   r   rf      s    
z#PluginCommand._get_citation_recordsc                 C   sF   |r
|j rdS ddlm} | j| j || |jd |  dS )z0Add actions that start with _ back to the lookupNr   )r!   )color)	rl   Zclick.utilsr!   r^   updater_   Zget_helprv   r#   )r'   r>   ro   rp   r!   r	   r	   r   rg      s    	
z!PluginCommand._get_hidden_actionsc                 C   s"   dd l }|j }|j| jd  S rs   )r/   r4   rm   r2   r]   ru   r	   r	   r   rd      s    
zPluginCommand._get_pluginc                 C   s
   t | jS r   )r<   r^   r'   r>   r	   r	   r   r@      s    zPluginCommand.list_commandsc              
   C   s   z| j | j | j | }W n tk
r   ddlm} ||| j }t|dkr^d|d  }n|rrdd| }nd}tj	t
dd	| jd
 |f | dd |d Y nX t|| j|S )Nr   rA   rC   rD   rE   r   rF   r   z*Error: QIIME 2 plugin %r has no action %r.r7   Tr   rG   )r^   rw   r_   rH   r/   rB   rI   r   r    r!   r   r"   r]   r#   ActionCommand)r'   r>   r7   actionrB   rK   rL   r	   r	   r   rM      s*    zPluginCommand.get_command)rN   rO   rP   rQ   r%   rb   rf   rg   rd   r@   rM   rS   r	   r	   r,   r   rJ   y   s   +rJ   c                       sj   e Zd ZdZ fddZdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dddZdd Zdd Z  ZS )ry   zGA click manifestation of a QIIME 2 API Action (Method/Visualizer)

    c                    sx  dd l }dd l}|| _|| _|  \| _| _| _tj	dg|jj
 ddtj	dgd dddg| _|  }|j
d	kr| jtj	d
gdtddtj	dgddddtj	dgddddtj	dgdtjdddddtj	dgdtjdddddg | j|j| j| jd |j| jg | j| j| j| j}|d g}| jd rT|tdd t j||| |d d|d  d S )!Nr   z--output-dirz)Output unspecified results to a directory)typerZ   z--verbose / --quietFzDisplay verbose output to stdout and/or stderr during execution of this action. Or silence output if execution is successful (silence is golden).)defaultrequiredrZ   pipelinez--recycle-poolaw  Use a cache pool for pipeline resumption. QIIME 2 will cache your results in this pool for reuse by future invocations. These pool are retained until deleted by the user. If not provided, QIIME 2 will create a pool which is automatically reused by invocations of the same action and removed if the action is successful. Note: these pools are local to the cache you are using.)r}   r{   rZ   z--no-recycleTzrDo not recycle results from a previous failed pipeline run or save the results from this run for future recycling.)rX   r}   rZ   z
--parallelzQExecute your action in parallel. This flag will use your default parallel config.z--parallel-config)existsZdir_okayzEExecute your action in parallel using a config at the indicated path.z--use-cache)r   Z	file_okayaL  Specify the cache to be used for the intermediate work of this pipeline. If not provided, the default cache under $TMP/qiime2/<uname> will be used. IMPORTANT FOR HPC USERS: If you are on an HPC system and are using parallel execution it is important to set this to a location that is globally accessible to all nodes in the cluster.rh   rV   
deprecatedwarningz\WARNING:

This command is deprecated and will be removed in a future version of this plugin.r7   rW   )r\   rY   r[   rZ   )r/   Zq2cli.click.typer8   rz   _build_generated_options_inputs_params_outputsr    ra   r{   Z
OutDirType_misc_get_actionextendstrPathr4   rc   rd   re   rf   r   r   r"   r$   r%   r   )r'   r7   r8   rz   r6   Z
action_objZoptionsrj   r,   r	   r   r%      sl    




$ 
  zActionCommand.__init__c           	      C   s   dd l }g }g }g }| jd D ]\}| }|d}|dkrB|}n|dkrP|}n|}|jjjf d|d i|}|| q|||fS )Nr   	signaturer{   inputZ	parameterprefix)Zq2cli.click.optionrz   copypopr    ZoptionZGeneratedOptionr   )	r'   r6   Zinputsr\   outputsitemr{   ZstorageZoptr	   r	   r   r   F  s    
z&ActionCommand._build_generated_optionsc                 C   s"   | j | j| j| j| |g dS )N)ZInputsZ
ParametersZOutputsZMiscellaneous)r   r   r   r   Zget_help_optionrx   r	   r	   r   get_opt_groups]  s
    zActionCommand.get_opt_groupsc                 C   s
   |   jS r   )r   rt   )r'   r	   r	   r   rf   e  s    z#ActionCommand._get_citation_recordsc                 C   s"   dd l }|j }|j| jd  S rs   )r/   r4   rm   r2   r8   ru   r	   r	   r   rd   h  s    
zActionCommand._get_pluginc                 C   s   |   }|j| jd  S )Nrh   )rd   r.   rz   )r'   r8   r	   r	   r   r   m  s    zActionCommand._get_actionc           0   
      s  ddl }ddl}ddl}ddlm}m}m} ddlm} ddl	m
}	 |d}
|
r|
ddd }|r|j|r||rtd	|
 d
|dd}|dd}|dk	r|rtd|dd}|dk	r||std| d|dd}|dd}|dk	rd}|d}|dkr*d}d}n|r6d}nd}||d i }i }| D ]$\}}|d^}}d|}|dkr|dkr|j|
|}|||< n|dkr|||dtd  < n|dkrp|dk	rp|}t|tr fdd|D }njt|tst||	r, fdd| D }n:t|trPt fd d|D }n|dk	rf j|}|||< n|||< qT| |}|  }||j d|j }|s|jd!kr|dkr|}|dk	r||kr|   krd"| jf }|!t"#d#| d}|s*ddl$}|j%d$d%dd&d'}|j&r`d(t'j()| j*d) | j+f }|!t"#d#| d} zz|j(j.||d*| |rdd+l/m0}!m1}" |j2}|dkr|" }#n|!|\}$}%|"|$|%}#|# | 3|| |}&W 5 Q R X n| 3|| |}&W 5 Q R X W nV t4k
rR }' z6d,t'j()| j*d)  }(|r0d-}t'j(j5|'|(|d. W 5 d}'~'X Y nX d} W 5 |r| r|j|j+r|,  |-|j+ X |
dk	r|6|
 t7|&|D ]\})}*t|*t8rt|*dkr|*d }*||*r0|
dkr0||*\}+}||+},t|)|	r|,9|)| |*}-n|,|)| |*}-n
|)|*}-|s||*rdd/|)j d0|+ d1| }.n<t|)|	rd2t|): d j d3n|)j}/d4|/ d5|- }.|!t"#d6|. q||krʈ -| dS )7zACalled when user hits return, **kwargs are Dict[click_names, Obj]r   N)output_in_cache_get_cache_path_and_keyget_default_recycle_pool)Cache)ResultCollection
output_dir:rC   zThe given output dir 'zL' appears to be a cache:key combo. Cache keys cannot be used as output dirs.recycle_pool
no_recycleFzICannot set a pool to be used for recycling and no recycle simultaneously.Z	use_cachez
The path 'zK' is not a valid cache, please supply a path to a valid pre-existing cache.parallelparallel_configTverbose)pathrT   omZ_fileic                    s   g | ]} j |qS r	   process_poolsaver
   vr1   r	   r   
<listcomp>  s     z*ActionCommand.__call__.<locals>.<listcomp>c                    s   i | ]\}}| j |qS r	   r   )r
   kr   r   r	   r   
<dictcomp>  s    z*ActionCommand.__call__.<locals>.<dictcomp>c                    s   g | ]} j |qS r	   r   r   r   r	   r   r     s     r~   zFThe pool '%s' does not exist on the cache at '%s'. It will be created.r   zqiime2-q2cli-err-z.logw)r   suffixdeletemodezaPlugin warning from %s:

%s is deprecated and will be removed in a future version of this plugin.r7   )stdoutstderr)get_config_from_fileParallelConfigzPlugin error from %s:r   )header	tracebackzAdded z to cache: z as: zCollection[]zSaved z to: Zsuccess);osr    Zqiime2.utilr/   r   r   r   Zqiime2.core.cacher   Z
qiime2.sdkr   r   rsplitr   r   Zis_cache
ValueErrorr3   splitr   rI   
isinstancelistdictsetr   r   _order_outputsr   Z	plugin_idrh   r{   Z	get_poolsr!   r   r"   tempfileZNamedTemporaryFiler   r6   r4   r5   r8   r7   closeremoveZredirected_stdioZqiime2.sdk.parallel_configr   r   r   _execute_action	ExceptionZexit_with_errormakedirsziptupleZsave_collectionrn   )0r'   r)   r   r    Zqiime2r   r   r   r   r   r   Zpotential_cacher   r   Z
used_cacher   Zparallel_config_fpr   quiet	argumentsZinit_outputskeyrp   r   partsZvalue_r   rz   Zdefault_poolr+   logr   Zcleanup_logfiler   r   r   Zconfigmappingresultser   resultoutput
cache_pathZoutput_cacher   messager{   r	   r   r   __call__q  s*   














 

      $




zActionCommand.__call__Nc              
   C   s`   |R |d kr"|f |}|  }n0|j|dd}| |f |}|  }W 5 Q R X W 5 Q R X |S )NT)r   Zreuse)Z_resultZcreate_pool)r'   rz   r   r1   r   r   Zpoolr	   r	   r   r   B  s    


zActionCommand._execute_actionc                 C   s6   g }| j d D ]"}|d dkr|||d   q|S )Nr   r{   r   r7   )rz   r   )r'   r   Zorderedr   r	   r	   r   r   T  s
    zActionCommand._order_outputsc              	   C   sb   | j d r^|tjddd: | j d D ](}|d|j  || |d q*W 5 Q R X d S )NZepilogZExamplesT)Zbold r   )rz   Zsectionr    ZstylewriteZcurrent_indent)r'   r>   Z	formatterliner	   r	   r   format_epilog[  s    

zActionCommand.format_epilog)N)rN   rO   rP   rQ   r%   r   r   rf   rd   r   r   r   r   r   rS   r	   r	   r,   r   ry      s   K R
ry   )r    Zq2cli.builtin.devr6   Zq2cli.builtin.infoZq2cli.builtin.toolsZq2cli.click.commandr   Zq2cli.core.configr   ZMultiCommandr   rJ   ZCommandry   r	   r	   r	   r   <module>	   s   f~