o
    3gi>                     @  s   d dl mZ d dlZd dlZd dlm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mZmZ G d
d deZG dd deZG dd deZG dd dZG dd deZdS )    )annotationsN)NamedTemporaryFile)CommandNotFoundConcreteCommandshquote)ProcInfo)BaseMachine)BaseEnv)	LocalPath)
RemotePathRemoteWorkdirStatResc                      s`   e Zd ZdZddg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 Z  ZS )	RemoteEnvz?The remote machine's environment; exposes a dict-like interface_origremotec                   s   |j   d}|d dkr#|d  s#tdd |d dD }n' dd  }d	d |D }d
d |D } fdd|D }dd |D }t j|jd|d || _	| j
 | _d S )Nzenv -0; echor      c                 s  s$    | ]}d |v r| d dV  qdS =   Nsplit.0line r   O/home/garg/my-data/venv/lib/python3.10/site-packages/plumbum/machines/remote.py	<genexpr>   s    z%RemoteEnv.__init__.<locals>.<genexpr>r    z	env; echoc                 s  s    | ]	}| d dV  qdS r   r   r   r   r   r   r       s    c                 s  s$    | ]}t |d kr|d V  qdS )r   r   N)lenr   r   r   r   r   !   s   " c                 3  s&    | ]}|  d | dfV  qdS )z
printenv "z"; echoN)run)r   keysessionr   r   r   "      $ c                 S  sB   i | ]\}}|d  d kr|d  dr|d s||d  dqS )r   r   
r   )rstrip)r   r    r   r   r   r   
<dictcomp>#   s
    "z&RemoteEnv.__init__.<locals>.<dictcomp>:)_curr)_sessionr   r%   dictr   
splitlinessuper__init__pathr   r(   copyr   )selfr   env0r(   linesr   keysruns	__class__r!   r   r-      s    

zRemoteEnv.__init__c                 C  s$   t | | | jjd|  d S Nzunset )r	   __delitem__r   r)   r   r0   namer   r   r   r8   -   s   zRemoteEnv.__delitem__c                 C  s0   t | || | jjd| dt|  d S )Nexport r   )r	   __setitem__r   r)   r   r   )r0   r:   valuer   r   r   r<   1   s   "zRemoteEnv.__setitem__c                 G  s,   t j| |g|R   | jjd|  d S r7   )r	   popr   r)   r   )r0   r:   defaultr   r   r   r>   5   s   zRemoteEnv.popc                 O  sF   t j| g|R i | | jjdddd |   D   d S )Nr;    c                 s  s&    | ]\}}| d t | V  qdS )r   N)r   )r   kvr   r   r   r   <   r#   z#RemoteEnv.update.<locals>.<genexpr>)r	   updater   r)   r   joingetdictitemsr0   argskwargsr   r   r   rC   9   s   zRemoteEnv.updatec                 C     | j |S )aE  Expands any environment variables and home shortcuts found in ``expr``
        (like ``os.path.expanduser`` combined with ``os.path.expandvars``)

        :param expr: An expression containing environment variables (as ``$FOO``) or
                     home shortcuts (as ``~/.bashrc``)

        :returns: The expanded string)r   expandr0   exprr   r   r   rK   ?   s   zRemoteEnv.expandc                 C  rJ   )zExpand home shortcuts (e.g., ``~/foo/bar`` or ``~john/foo/bar``)

        :param expr: An expression containing home shortcuts

        :returns: The expanded string)r   
expanduserrL   r   r   r   rN   I   s   zRemoteEnv.expanduserc                 C  s   | j  | jd< i }| j D ]\}}|| jvrt|||< q| j D ]\}}|| jvr2d||< q$|| j| kr@| j| ||< q$|S )znReturns the difference between the this environment and the original environment of
        the remote machinePATH )r.   rD   r(   rF   r   str)r0   deltarA   rB   r   r   r   getdeltaU   s   


zRemoteEnv.getdelta)__name__
__module____qualname____doc__	__slots__r-   r8   r<   r>   rC   rK   rN   rS   __classcell__r   r   r5   r   r      s    
r   c                   @  sF   e Zd ZdZdZdddZedd Zdd	 ZdddZ	dddZ
dS )RemoteCommandr   r   autoc                 C  s,   || _ t| ||dkr|j d S | d S )Nr\   )r   r   r-   custom_encoding)r0   r   
executableencodingr   r   r   r-   l   s   zRemoteCommand.__init__c                 C  s   | j S Nr[   r0   r   r   r   machiner   s   zRemoteCommand.machinec                 C  s   d| j d| jdS )NzRemoteCommand(z, ))r   r^   ra   r   r   r   __repr__v      zRemoteCommand.__repr__r   c                 K  s   | j j| | fi |S r`   )r   popenrG   r   r   r   rf   y   s   zRemoteCommand.popen.	nohup.outNTc                 C  s   | j | ||||S )zRuns a command detached.)rb   daemonic_popen)r0   cwdstdoutstderrappendr   r   r   nohup|   s   zRemoteCommand.nohup)r\   )r   )rg   rh   NT)rT   rU   rV   rX   QUOTE_LEVELr-   propertyrb   rd   rf   rn   r   r   r   r   rZ   h   s    


rZ   c                   @  s   e Zd ZdS )ClosedRemoteMachineN)rT   rU   rV   r   r   r   r   rq      s    rq   c                   @  s,   e Zd ZddgZdd Zdd Zdd Zd	S )
ClosedRemote_obj__weakref__c                 C  s
   || _ d S r`   )rs   )r0   objr   r   r   r-      s   
zClosedRemote.__init__c                 C  s   d S r`   r   ra   r   r   r   close      zClosedRemote.closec                 C  s   t | jd)Nz has been closed)rq   rs   r9   r   r   r   __getattr__   s   zClosedRemote.__getattr__N)rT   rU   rV   rX   r-   rv   rx   r   r   r   r   rr      s
    rr   c                   @  sJ  e Zd ZdZeZedd ZdNddZd	d
 Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zedd ZdOddddZdd Zd d! Zd"d# Zd$d% Zd&d' Zejd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Zd6d7 Z d8d9 Z!	:	;dPd<d=Z"d>d? Z#d@dA Z$dBdC Z%dDdE Z&dFdG Z'dHdI Z(dJdK Z)dLdM Z*d:S )QBaseRemoteMachinea  Represents a *remote machine*; serves as an entry point to everything related to that
    remote machine, such as working directory and environment manipulation, command creation,
    etc.

    Attributes:

    * ``cwd`` - the remote working directory
    * ``env`` - the remote environment
    * ``custom_encoding`` - the remote machine's default encoding (assumed to be UTF8)
    * ``connect_timeout`` - the connection timeout


    There also is a _cwd attribute that exists if the cwd is not current (del if cwd is changed).
    c                 C  s   t | ds
t| | _| jS )N_cwd)hasattrr   rz   ra   r   r   r   rj      s   

zBaseRemoteMachine.cwdutf8
   Fc                 C  s>   || _ || _| j|d| _|  | _t| | _d | _i | _	d S )Nnew_session)
r]   connect_timeoutr"   r)   
_get_unameunamer   env_python_program_cache)r0   r_   r   r   r   r   r   r-      s   


zBaseRemoteMachine.__init__c                 C  sP   | j jdd d\}}}|dkr| S | j jdd d\}}}|dkr&| S dS )Nr   retcoder   z7python3 -c 'import platform;print(platform.uname()[0])'Windowsr)   r   strip)r0   rcout_r   r   r   r      s   zBaseRemoteMachine._get_unamec                 C  s   d| j j d|  dS )N<r@   >)r6   rT   ra   r   r   r   rd      re   zBaseRemoteMachine.__repr__c                 C  s   | S r`   r   ra   r   r   r   	__enter__   rw   zBaseRemoteMachine.__enter__c                 C  s   |    d S r`   )rv   )r0   trB   tbr   r   r   __exit__   s   zBaseRemoteMachine.__exit__c                 C  s   | j   t| | _ dS )z_closes the connection to the remote machine; all paths and programs will
        become defunctN)r)   rv   rr   ra   r   r   r   rv      s   
zBaseRemoteMachine.closec                 G  sR   t | jg}|D ]}t|trtd||| t | qt| g|R  S )zA factory for :class:`RemotePaths <plumbum.path.remote.RemotePath>`.
        Usage: ``p = rem.path("/usr", "lib", "python2.7")``
        z!Cannot construct RemotePath from )rQ   rj   
isinstancer
   	TypeErrorrm   rN   r   )r0   partsparts2pr   r   r   r.      s   
zBaseRemoteMachine.pathc                 C  s   || j ddf}tt | j| W  d   S 1 sw   Y  |g}d|v r8||dd|ddg7 }|D ]!}| j jD ]}|| }|drZ|	 sZ|| j|< |    S q@q:t
|| j j)a2  Looks up a program in the ``PATH``. If the program is not found, raises
        :class:`CommandNotFound <plumbum.commands.CommandNotFound>`

        :param progname: The program's name. Note that if underscores (``_``) are present
                         in the name, and the exact name is not found, they will be replaced
                         in turn by hyphens (``-``) then periods (``.``), and the name will
                         be looked up again for each alternative

        :returns: A :class:`RemotePath <plumbum.path.local.RemotePath>`
        rO   rP   Nr   -rg   x)r   get
contextlibsuppressKeyErrorr   replacer.   accessis_dirr   )r0   prognamer    alternativesr:   r   fnr   r   r   which   s     
zBaseRemoteMachine.whichc                 C  st   t |tr|j| u r| | |S td|t |ts3| | d|v s'd|v r-| |S | |S td|)ar  Returns a `Command` object representing the given program. ``cmd`` can be a string or
        a :class:`RemotePath <plumbum.path.remote.RemotePath>`; if it is a path, a command
        representing this path will be returned; otherwise, the program name will be looked up in
        the system's ``PATH`` (using ``which``). Usage::

            r_ls = rem["ls"]
        z3Given path does not belong to this remote machine: /\zcmd must not be a LocalPath: )r   r   r   rZ   r   r
   r.   r   )r0   cmdr   r   r   __getitem__   s   


zBaseRemoteMachine.__getitem__c                 C  s   | j s| d | _ | j S )z?A command that represents the default remote python interpreterpython3)r   ra   r   r   r   python  s   
zBaseRemoteMachine.pythonr~   c                C     t  )zCreates a new :class:`ShellSession <plumbum.session.ShellSession>` object; this invokes the user's
        shell on the remote machine and executes commands on it over stdin/stdout/stderr
        NotImplementedError)r0   isattyr   r   r   r   r"        zBaseRemoteMachine.sessionc                 C  r   )a1  Downloads a remote file/directory (``src``) to a local destination (``dst``).
        ``src`` must be a string or a :class:`RemotePath <plumbum.path.remote.RemotePath>`
        pointing to this remote machine, and ``dst`` must be a string or a
        :class:`LocalPath <plumbum.machines.local.LocalPath>`r   r0   srcdstr   r   r   download     zBaseRemoteMachine.downloadc                 C  r   )a/  Uploads a local file/directory (``src``) to a remote destination (``dst``).
        ``src`` must be a string or a :class:`LocalPath <plumbum.machines.local.LocalPath>`,
        and ``dst`` must be a string or a :class:`RemotePath <plumbum.path.remote.RemotePath>`
        pointing to this remote machiner   r   r   r   r   upload#  r   zBaseRemoteMachine.uploadc                 K  r   )zSpawns the given command on the remote machine, returning a ``Popen``-like object;
        do not use this method directly, unless you need "low-level" control on the remote
        processr   rG   r   r   r   rf   *  r   zBaseRemoteMachine.popenc              
   c  sp    | d }|ddd  }|d |D ]!}|  }tt|d t|d |d d|d	d
 V  qd
S )z
        Returns information about all running processes (on POSIX systems: using ``ps``)

        .. versionadded:: 1.3
        psz-ez-ozpid,uid,stat,argsr   r   r   r@      N)r+   r>   r   r   r   intrD   )r0   r   r2   r   r   r   r   r   list_processes0  s   
4z BaseRemoteMachine.list_processesc                 c  s0    t |}|  D ]}||jr|V  q
dS )z|
        Process grep: return information about all processes whose command-line args match the given regex pattern
        N)recompiler   searchrH   )r0   patternpatprocinfor   r   r   pgrep=  s   
zBaseRemoteMachine.pgrepc                 c  sB    | j d\}}}| | }z
|V  W |  dS |  w )zlA context manager that creates a remote temporary directory, which is removed when
        the context exitsz1mktemp -d 2>/dev/null || mktemp -d tmp.XXXXXXXXXXN)r)   r   r.   r   delete)r0   r   r   	local_dirr   r   r   tempdirF  s   
zBaseRemoteMachine.tempdirc                 C  s6   | j dt| d  }|d |d |S )Nzls -a r   rg   z..)r)   r   r   r+   remove)r0   r   filesr   r   r   _path_listdirV  s   

zBaseRemoteMachine._path_listdirc                 C  s\   | dd}| dd}| jd| d| dd  }t|dkr,| |d s,g S |S )Nr@   z\ z
for fn in r   z; do echo $fn; doner   r   )r   r)   r   r+   r   
_path_stat)r0   r   r   matchesr   r   r   
_path_glob\  s   zBaseRemoteMachine._path_globc                 C  4   | j dvrdnd}| j|t| d  dS )NDarwinFreeBSDzstat -c '%u,%U' zstat -f '%u,%Su' r   ,r   r)   r   r   r   r   r0   r   stat_cmdr   r   r   _path_getuidg  
   
"zBaseRemoteMachine._path_getuidc                 C  r   )Nr   zstat -c '%g,%G' zstat -f '%g,%Sg' r   r   r   r   r   r   r   _path_getgido  r   zBaseRemoteMachine._path_getgidc           	      C  s   | j dvrd}nd}| jj|t| d d\}}}|dkrd S | d}|d }tt	|d dgt
dd	 |d
d  D R }||_|S )Nr   z+stat -c '%F,%f,%i,%d,%h,%u,%g,%s,%X,%Y,%Z' z-stat -f '%HT,%Xp,%i,%d,%l,%u,%g,%z,%a,%m,%c' r   r   r      c                 s  s    | ]}t |V  qd S r`   )r   )r   srr   r   r   r     s    z/BaseRemoteMachine._path_stat.<locals>.<genexpr>r   )r   r)   r   r   r   r   r>   lowerr   r   tuple	text_mode)	r0   r   r   r   r   r   statresr   resr   r   r   r   w  s   
0zBaseRemoteMachine._path_statc                 C  s   | j dt|  d S )Nzrm -rf r)   r   r   )r0   r   r   r   r   _path_delete     zBaseRemoteMachine._path_deletec                 C  $   | j dt| dt|  d S )Nzmv r@   r   r   r   r   r   
_path_move     $zBaseRemoteMachine._path_movec                 C  r   )Nzcp -r r@   r   r   r   r   r   
_path_copy  r   zBaseRemoteMachine._path_copyNTc                 C  s.   |rdnd}d| t | }| j| d S )Nz-p rP   zmkdir )r   r)   r   )r0   r   modeminus_pp_strr   r   r   r   _path_mkdir  s   zBaseRemoteMachine._path_mkdirc                 C  s"   | j d|ddt|  d S )Nzchmod or@   r   )r0   r   r   r   r   r   _path_chmod  s   "zBaseRemoteMachine._path_chmodc                 C  s   | j d|  d S )Nztouch )r)   r   )r0   r.   r   r   r   _path_touch  re   zBaseRemoteMachine._path_touchc                 C  s   dg}|r
| d |d ur|d ur| | d|  n|d ur)| t| n|d ur5| d|  | t| | jd| d S )Nchownz-Rr'   r@   )rm   rQ   r   r)   r   rD   )r0   r   ownergroup	recursiverH   r   r   r   _path_chown  s   
zBaseRemoteMachine._path_chownc                 C  s,   | d |}| j rt|tr|| j S |S )Ncat)r]   r   rQ   encode)r0   r   datar   r   r   
_path_read  s   zBaseRemoteMachine._path_readc                 C  sr   | j rt|tr|| j }t }|| |  |d | |j	| W d    d S 1 s2w   Y  d S )Nr   )
r]   r   rQ   r   r   writeflushseekr   r:   )r0   r   r   fr   r   r   _path_write  s   

"zBaseRemoteMachine._path_writec                 C  s4   |rdnd}| j d| t| dt|  d S )Nz-s rP   zln r@   r   )r0   r   r   symlinksymlink_strr   r   r   
_path_link  s   (zBaseRemoteMachine._path_linkc                 C  s   | j d| d  S )Necho r   r   rL   r   r   r   rK     r   zBaseRemoteMachine.expandc                 C  sB   t dd |dD s|S |dd}| jd| d  S )Nc                 s  s    | ]}| d V  qdS )~N)
startswith)r   partr   r   r   r     s    z/BaseRemoteMachine.expanduser.<locals>.<genexpr>r   $z\$r   r   )anyr   r   r)   r   r   )r0   rM   	expr_replr   r   r   rN     s   zBaseRemoteMachine.expanduser)r|   r}   F)F)NT)+rT   rU   rV   rW   rZ   rp   rj   r-   r   rd   r   r   rv   r.   r   r   r   r"   r   r   rf   r   r   r   contextmanagerr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rK   rN   r   r   r   r   ry      sV    

	
	


	ry   )
__future__r   r   r   tempfiler   plumbum.commandsr   r   r   plumbum.libr   plumbum.machines.baser   plumbum.machines.envr	   plumbum.path.localr
   plumbum.path.remoter   r   r   r   rZ   	Exceptionrq   rr   ry   r   r   r   r   <module>   s    Y