U
    ad.                     @   s   d dl Z 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 d dl	m
Z
 d dlmZ d dlmZ d dlmZ G dd	 d	Zd
d ZG dd deZG dd deZdS )    N)ArgumentTypeError)apps)settings)CommandError)EmailNotificationCommand)signalcommandc                   @   s   e Zd ZdZdZdZdS )DirPolicyChoicesnoneZeachrootN)__name__
__module____qualname__NONEEACHROOT r   r   S/tmp/pip-unpacked-wheel-portabvm/django_extensions/management/commands/runscript.pyr      s   r   c                 C   s$   | d kst j| s td|  | S )Nz%s is not a directory!)ospathisdirr   )valuer   r   r   check_is_directory   s    r   c                   @   s   e Zd Zdd Zdd ZdS )BadCustomDirectoryExceptionc                 C   s   |d | _ d S )Nzm If --dir-policy is custom than you must set correct directory in --dir option or in settings.RUNSCRIPT_CHDIRmessage)selfr   r   r   r   __init__   s    z$BadCustomDirectoryException.__init__c                 C   s   | j S )Nr   )r   r   r   r   __str__#   s    z#BadCustomDirectoryException.__str__N)r   r   r   r   r   r   r   r   r   r      s   r   c                       s8   e Zd ZdZ fddZ fddZedd Z  ZS )Commandz Runs a script in django context.c                    s"   t  j|| t | _d| _d S )Nr   )superr   r   getcwdcurrent_directorylast_exit_code)r   argskwargs	__class__r   r   r   *   s    
zCommand.__init__c                    s   t  | |jddd |jdddddd	 |jd
ddddd	 |jddddddd	 |jddddddd	 |jdddddd	 |jddtdd |jdttjtjtjgdd |jdtd d! d S )"Nscript+)nargsz
--fixtures
store_true
infixturesFz Also look in app.fixtures subdir)actiondestdefaulthelpz--noscripts	noscriptsz!Do not look in app.scripts subdirz-sz--silentsilentzRRun silently, do not show errors and tracebacks. Also implies --continue-on-error.z-cz--continue-on-errorcontinue_on_errorzContinue executing other scripts even though one has failed. It will print a traceback unless --no-traceback or --silent are given The exit code used when terminating will always be 1.z--no-tracebackno_tracebackzDo not show tracebacksz--script-args*z|Space-separated argument list to be passed to the scripts. Note that the same arguments will be passed to all named scripts.)r)   typer/   z--dir-policyzPolicy of selecting scripts execution directory: none - start all scripts in current directory each - start all scripts in their directories root - start all scripts in BASE_DIR directory )r5   choicesr/   z--chdirz^If dir-policy option is set to custom, than this option determines script execution directory.)r5   r/   )	r   add_argumentsadd_argumentstrr   r   r   r   r   )r   parserr%   r   r   r7   /   sp                         zCommand.add_argumentsc              	      s  j jj jj j j jg 
d }
d sFttdd 
d rXd 
d 
d 
d	 	
d
 	rdnd
d rdd
d tdk rt	d d S t|dk rt	 d d S 
fdd
fdd
fdd 	f	dd} fddfdd}
d rZ
d }ng }g }|D ]H}||}	|	sd_
dkrfsft	 d |  qf||	 qfj
rވd!k rԈst	 d" sg }|D ]0}
dkrt	d#|
j  ||
f|  qj
dkrrBtd$r6d S tj
 ztd%j
d&W nT tk
r   j
dkrztd%t	 d% td$rY d S tj
 Y nX d S )'Nr'   r0   ZRUNSCRIPT_SCRIPT_DIRscriptsr+   Zfixtures	verbosity	tracebackr3   r2   FTr1   r   email_notifications   zNo subdirs to run left.zScript name required.c               
      sT    d pt tdd } zt|  W n. tk
rN } ztt|W 5 d }~X Y nX | S )NchdirRUNSCRIPT_CHDIR)getattrr   r   r   r   r9   )	directorye)optionsr   r   get_directory_from_chdir   s    z0Command.handle.<locals>.get_directory_from_chdirc                    sL    d pt tdtj}|tjkr&tjS |tjkrBtj	t
| S jS d S )N
dir_policyZRUNSCRIPT_CHDIR_POLICY)rB   r   r   r   r   BASE_DIRr   r   r   dirnameinspectgetfiler!   )script_modulepolicy)rE   r   r   r   get_directory_basing_on_policy   s    

z6Command.handle.<locals>.get_directory_basing_on_policyc                    sT   d r }n.d r" | }nt tdd r6 }n | }ttj| d S )Nr@   rG   rA   )rB   r   r   r@   r   abspath)rL   rC   )rN   rF   rE   r   r   set_directory   s    
z%Command.handle.<locals>.set_directoryc              
      s`  d }z|  | j | }t|tr.|r*dnd}t|tr|dkrztd| j|f |dW n& tk
r   td| j|f Y nX rj| jd W n tk
rZ } zt|trt	|dr|j
}t|tr|nd_rW Y ld S dkrt d| j  r rt  W Y 2d S r6j| jdd	 rHtt| W 5 d }~X Y nX d S )
Nr?   r   z'%s' failed with exit code %s
returncode)notification_idrR   z%Exception while running run() in '%s'T)rS   Zinclude_traceback)run
isinstanceboolintr   r   	TypeErrorZsend_email_notification	ExceptionhasattrrR   r"   printr=   	print_excrepr)modscript_argsZ	exit_coderD   )	ERRORr2   r>   r3   r   rP   show_tracebackr1   r<   r   r   
run_script   s>    





z"Command.handle.<locals>.run_scriptc                    s  d| |f }dkr$t d|  zt|  W n: tk
rl } zt|dr\W Y dS W 5 d }~X Y nX zt|}W n tk
rN } zz tj|d krW W Y dS W nJ tk
r   t	j
jtjf|d d }t	j
|sY W Y PdS Y nX rW Y :dS rt  dkr8t  d	||f  W Y dS d }~X Y nX t|d
rzdkrvt d|  |S dkrt d|  d S )N%s.%sr?   zCheck for %szNo module namedF.z.pyr   zCannot import module '%s': %s.rT   zFound script '%s' ...z.Found script '%s' but no run() function found.)r[   	importlibimport_moduleImportErrorr9   
startswithutil	find_specrY   r   r   joinr   rH   splitisfiler=   r\   rZ   )parent_packagemodule_nameZfull_module_pathrD   tZmodule_file)r`   ERROR2NOTICENOTICE2ra   r1   r<   r   r   	my_import   s>    



z!Command.handle.<locals>.my_importc                    s   g }t  D ]0}D ]&} d|j|f | }|r|| qq| ddkrv| dd\}} ||}|r|| n"D ]} || }|rz|| qz|S )z3 Find script module which contains 'run' attribute rc   rd   r?   )r   Zget_app_configsnameappendfindrsplit)r'   modulesZappsubdirr^   parentmod_name)rt   subdirsr   r   find_modules_for_script   s     

z/Command.handle.<locals>.find_modules_for_scriptr_   z'No (valid) module for script '%s' found   z:Try running with a higher verbosity level like: -v2 or -v3zRunning script '%s' ...Zrunning_testsz8An error has occurred running scripts. See errors above.rQ   )styleZ	SQL_TABLEZ	SQL_FIELDr`   rr   rw   rB   r   lenr[   r"   extendr   rZ   sysexitr   rX   )r   r#   rE   r;   rb   r   r_   Zscript_to_runr'   Zscript_modulesZ
script_modr   )r`   rq   rr   rs   r2   r>   rN   rF   rt   r3   rE   r   rP   ra   r1   r~   r<   r   handleZ   s    
	$)


zCommand.handle)	r   r   r   r/   r   r7   r   r   __classcell__r   r   r%   r   r   '   s
   +r   )r   r   re   rJ   r=   argparser   Zdjango.appsr   Zdjango.confr   Zdjango.core.management.baser   Z0django_extensions.management.email_notificationsr   Z"django_extensions.management.utilsr   r   r   rY   r   r   r   r   r   r   <module>   s   	