
    khc                         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m	Z	m
Z
mZmZmZmZ d dlmZ ddlmZmZ dd	lmZmZmZ dd
lmZ ddlmZ erd dlmZ  G d de      Z G d de      Zy)    N)contextmanager)cycle)PathLike)TYPE_CHECKINGAny	GeneratorIteratorListOptionalUnion)Mock   )Config	DataProxy)FailureAuthFailureResponseNotAccepted)Result)FailingResponder)Runnerc            	       L   e Zd ZdZddee   ddfdZedefd       Zej                  deddfd       Zd	e
d
edee   fdZddd	e
d
edee   fdZd	e
d
edee   fdZddd	e
d
edee   fdZd	e
de
fdZed	e
ded   fd       Zede
fd       Zedeee
f   ded   fd       Zy)Contexta  
    Context-aware API wrapper & state-passing object.

    `.Context` objects are created during command-line parsing (or, if desired,
    by hand) and used to share parser and configuration state with executed
    tasks (see :ref:`why-context`).

    Specifically, the class offers wrappers for core API calls (such as `.run`)
    which take into account CLI parser flags, configuration files, and/or
    changes made at runtime. It also acts as a proxy for its `~.Context.config`
    attribute - see that attribute's documentation for details.

    Instances of `.Context` may be shared between tasks when executing
    sub-tasks - either the same context the caller was given, or an altered
    copy thereof (or, theoretically, a brand new one).

    .. versionadded:: 1.0
    Nconfigreturnc                     ||n	t               }| j                  |       t               }| j                  |       t               }| j                  |       y)z
        :param config:
            `.Config` object to use as the base configuration.

            Defaults to an anonymous/default `.Config` instance.
        N_config)command_prefixes)command_cwds)r   _setlist)selfr   r   r   s       `/var/www/pru.catia.catastroantioquia-mas.com/tasa/lib/python3.12/site-packages/invoke/context.py__init__zContext.__init__.   sP      "-68		&	! '+f		#3	4 #'&		|	,    c                     | j                   S Nr   )r"   s    r#   r   zContext.configK   s     ||r%   valuec                 (    | j                  |       y )Nr   )r    )r"   r(   s     r#   r   zContext.configQ   s     			%	 r%   commandkwargsc                 t    | j                   j                  j                  |       } | j                  ||fi |S )a  
        Execute a local shell command, honoring config options.

        Specifically, this method instantiates a `.Runner` subclass (according
        to the ``runner`` config option; default is `.Local`) and calls its
        ``.run`` method with ``command`` and ``kwargs``.

        See `.Runner.run` for details on ``command`` and the available keyword
        arguments.

        .. versionadded:: 1.0
        )r   runnerslocal_runr"   r*   r+   runners       r#   runzContext.runZ   s6     $$**40tyy3F33r%   r1   r   c                 J    | j                  |      } |j                  |fi |S r'   )_prefix_commandsr2   )r"   r1   r*   r+   s       r#   r/   zContext._runm   s*     ''0vzz',V,,r%   c                 t    | j                   j                  j                  |       } | j                  ||fi |S )a  
        Execute a shell command via ``sudo`` with password auto-response.

        **Basics**

        This method is identical to `run` but adds a handful of
        convenient behaviors around invoking the ``sudo`` program. It doesn't
        do anything users could not do themselves by wrapping `run`, but the
        use case is too common to make users reinvent these wheels themselves.

        .. note::
            If you intend to respond to sudo's password prompt by hand, just
            use ``run("sudo command")`` instead! The autoresponding features in
            this method will just get in your way.

        Specifically, `sudo`:

        * Places a `.FailingResponder` into the ``watchers`` kwarg (see
          :doc:`/concepts/watchers`) which:

            * searches for the configured ``sudo`` password prompt;
            * responds with the configured sudo password (``sudo.password``
              from the :doc:`configuration </concepts/configuration>`);
            * can tell when that response causes an authentication failure
              (e.g. if the system requires a password and one was not
              configured), and raises `.AuthFailure` if so.

        * Builds a ``sudo`` command string using the supplied ``command``
          argument, prefixed by various flags (see below);
        * Executes that command via a call to `run`, returning the result.

        **Flags used**

        ``sudo`` flags used under the hood include:

        - ``-S`` to allow auto-responding of password via stdin;
        - ``-p <prompt>`` to explicitly state the prompt to use, so we can be
          sure our auto-responder knows what to look for;
        - ``-u <user>`` if ``user`` is not ``None``, to execute the command as
          a user other than ``root``;
        - When ``-u`` is present, ``-H`` is also added, to ensure the
          subprocess has the requested user's ``$HOME`` set properly.

        **Configuring behavior**

        There are a couple of ways to change how this method behaves:

        - Because it wraps `run`, it honors all `run` config parameters and
          keyword arguments, in the same way that `run` does.

            - Thus, invocations such as ``c.sudo('command', echo=True)`` are
              possible, and if a config layer (such as a config file or env
              var) specifies that e.g. ``run.warn = True``, that too will take
              effect under `sudo`.

        - `sudo` has its own set of keyword arguments (see below) and they are
          also all controllable via the configuration system, under the
          ``sudo.*`` tree.

            - Thus you could, for example, pre-set a sudo user in a config
              file; such as an ``invoke.json`` containing ``{"sudo": {"user":
              "someuser"}}``.

        :param str password: Runtime override for ``sudo.password``.
        :param str user: Runtime override for ``sudo.user``.

        .. versionadded:: 1.0
        )r   r-   r.   _sudor0   s       r#   sudozContext.sudos   s7    J $$**40tzz&'4V44r%   c                    | j                   j                  j                  }|j                  d| j                   j                  j                        }|j                  d| j                   j                  j
                        }|j                  di       }d}|dj                  |      }d}	|r.dj                  dj                  |j                                     }	| j                  |      }dj                  ||	||      }
t        t        j                  |      d	j                  |      d
      }|j                  dt        | j                   j                  j                               }|j#                  |       	  |j                  |
fd|i|S # t$        $ r9}t'        |j(                  t*              rt-        |j.                  |      }| d }~ww xY w)Npassworduserenv z	-H -u {} z--preserve-env='{}' ,zsudo -S -p '{}' {}{}{}z{}
zSorry, try again.
)patternresponsesentinelwatchers)resultprompt)r   r7   rC   popr9   r:   getformatjoinkeysr4   r   reescaper!   r2   rA   appendr   
isinstancereasonr   r   rB   )r"   r1   r*   r+   rC   r9   r:   r;   
user_flags	env_flagscmd_strwatcherrA   failureerrors                  r#   r6   zContext._sudo   s    !!((::j$++*:*:*C*CDzz&$++"2"2"7"78jj# 
$++D1J	.55chhsxxz6JKI''0*11Iz7
 #IIf%]]8,*
 ::j$t{{/G/G*HI 	6::gCCFCC 	 '..*=>#7>>&I 	s   :F 	G4GGc                     t        | j                        }| j                  }|r!|j                  ddj	                  |             dj                  ||gz         S )z
        Prefixes ``command`` with all prefixes found in ``command_prefixes``.

        ``command_prefixes`` is a list of strings which is modified by the
        `prefix` context manager.
        r   zcd {}z && )r!   r   cwdinsertrF   rG   )r"   r*   prefixescurrent_directorys       r#   r4   zContext._prefix_commands   sO     --. HHOOAw~~.?@A{{8wi/00r%   )NNNc              #      K   | j                   j                  |       	 d | j                   j                          y# | j                   j                          w xY ww)a  
        Prefix all nested `run`/`sudo` commands with given command plus ``&&``.

        Most of the time, you'll want to be using this alongside a shell script
        which alters shell state, such as ones which export or alter shell
        environment variables.

        For example, one of the most common uses of this tool is with the
        ``workon`` command from `virtualenvwrapper
        <https://virtualenvwrapper.readthedocs.io/en/latest/>`_::

            with c.prefix('workon myvenv'):
                c.run('./manage.py migrate')

        In the above snippet, the actual shell command run would be this::

            $ workon myvenv && ./manage.py migrate

        This context manager is compatible with `cd`, so if your virtualenv
        doesn't ``cd`` in its ``postactivate`` script, you could do the
        following::

            with c.cd('/path/to/app'):
                with c.prefix('workon myvenv'):
                    c.run('./manage.py migrate')
                    c.run('./manage.py loaddata fixture')

        Which would result in executions like so::

            $ cd /path/to/app && workon myvenv && ./manage.py migrate
            $ cd /path/to/app && workon myvenv && ./manage.py loaddata fixture

        Finally, as alluded to above, `prefix` may be nested if desired, e.g.::

            with c.prefix('workon myenv'):
                c.run('ls')
                with c.prefix('source /some/script'):
                    c.run('touch a_file')

        The result::

            $ workon myenv && ls
            $ workon myenv && source /some/script && touch a_file

        Contrived, but hopefully illustrative.

        .. versionadded:: 1.0
        N)r   rK   rD   )r"   r*   s     r#   prefixzContext.prefix
  sI     d 	$$W-	(!!%%'D!!%%'s   A> AAAc                 n   | j                   syt        t        t        | j                                     D ])  \  }}|j	                  d      s|j	                  d      s) n | j                   d D cg c]  }|j                  dd       }}t        t        j                  j                  |       S c c}w )zs
        Return the current working directory, accounting for uses of `cd`.

        .. versionadded:: 1.0
        r<   ~/N z\ )
r   reversedr!   	enumerate
startswithreplacestrospathrG   )r"   ire   pathss       r#   rU   zContext.cwdB  s          Yt/@/@%A BC 	GAts#ts';	 7;6G6G6KLdc5)LL277<<'(( Ms   2B2re   c              #      K   t        |      }| j                  j                  |       	 d | j                  j                          y# | j                  j                          w xY ww)aq  
        Context manager that keeps directory state when executing commands.

        Any calls to `run`, `sudo`, within the wrapped block will implicitly
        have a string similar to ``"cd <path> && "`` prefixed in order to give
        the sense that there is actually statefulness involved.

        Because use of `cd` affects all such invocations, any code making use
        of the `cwd` property will also be affected by use of `cd`.

        Like the actual 'cd' shell builtin, `cd` may be called with relative
        paths (keep in mind that your default starting directory is your user's
        ``$HOME``) and may be nested as well.

        Below is a "normal" attempt at using the shell 'cd', which doesn't work
        since all commands are executed in individual subprocesses -- state is
        **not** kept between invocations of `run` or `sudo`::

            c.run('cd /var/www')
            c.run('ls')

        The above snippet will list the contents of the user's ``$HOME``
        instead of ``/var/www``. With `cd`, however, it will work as expected::

            with c.cd('/var/www'):
                c.run('ls')  # Turns into "cd /var/www && ls"

        Finally, a demonstration (see inline comments) of nesting::

            with c.cd('/var/www'):
                c.run('ls') # cd /var/www && ls
                with c.cd('website1'):
                    c.run('ls')  # cd /var/www/website1 && ls

        .. note::
            Space characters will be escaped automatically to make dealing with
            such directory names easier.

        .. versionadded:: 1.0
        .. versionchanged:: 1.5
            Explicitly cast the ``path`` argument (the only argument) to a
            string; this allows any object defining ``__str__`` to be handed in
            (such as the various ``Path`` objects out there), and not just
            string literals.
        N)rc   r   rK   rD   )r"   re   s     r#   cdz
Context.cdY  sR     ^ 4y  &	$!!#D!!#s   'A(A	 A(	A%%A(r'   )__name__
__module____qualname____doc__r   r   r$   propertyr   setterrc   r   r   r2   r/   r7   r6   r4   r   r   rZ   rU   r   r   ri    r%   r#   r   r      s   &-x/ -4 -:   
 ]]!F !t ! !43 4# 4(62B 4&--),-8;-	&	-F5C F53 F58F3C F5R;;),;8;;	&	;@1 1 1 5(c 5(i0@&A 5( 5(n )S ) ), 3$uXs]+ 3$	:J0K 3$ 3$r%   r   c                        e Zd ZdZddee   deddf fdZdedee   fdZ	d	e
d
e
defdZd
e
dededefdZd
e
dededefdZd	e
d
e
deddfdZ xZS )MockContexta  
    A `.Context` whose methods' return values can be predetermined.

    Primarily useful for testing Invoke-using codebases.

    .. note::
        This class wraps its ``run``, etc methods in `unittest.mock.Mock`
        objects. This allows you to easily assert that the methods (still
        returning the values you prepare them with) were actually called.

    .. note::
        Methods not given `Results <.Result>` to yield will raise
        ``NotImplementedError`` if called (since the alternative is to call the
        real underlying method - typically undesirable when mocking.)

    .. versionadded:: 1.0
    .. versionchanged:: 1.5
        Added ``Mock`` wrapping of ``run`` and ``sudo``.
    Nr   r+   r   c           
      `   t         	|   |       | j                  d|j                  dd             |j	                         D ]  \  }}t
        t        t        f}t        |t              r-|j	                         D ]  \  }}| j                  |      ||<    nOt        ||      st        |d      r| j                  |      }n%d}t        |j                  t        |                  | j                  dj                  |      |       | j                  |t        t!        | |                    y)	a  
        Create a ``Context``-like object whose methods yield `.Result` objects.

        :param config:
            A Configuration object to use. Identical in behavior to `.Context`.

        :param run:
            A data structure indicating what `.Result` objects to return from
            calls to the instantiated object's `~.Context.run` method (instead
            of actually executing the requested shell command).

            Specifically, this kwarg accepts:

            - A single `.Result` object.
            - A boolean; if True, yields a `.Result` whose ``exited`` is ``0``,
              and if False, ``1``.
            - An iterable of the above values, which will be returned on each
              subsequent call to ``.run`` (the first item on the first call,
              the second on the second call, etc).
            - A dict mapping command strings or compiled regexen to the above
              values (including an iterable), allowing specific
              call-and-response semantics instead of assuming a call order.

        :param sudo:
            Identical to ``run``, but whose values are yielded from calls to
            `~.Context.sudo`.

        :param bool repeat:
            A flag determining whether results yielded by this class' methods
            repeat or are consumed.

            For example, when a single result is indicated, it will normally
            only be returned once, causing ``NotImplementedError`` afterwards.
            But when ``repeat=True`` is given, that result is returned on
            every call, forever.

            Similarly, iterable results are normally exhausted once, but when
            this setting is enabled, they are wrapped in `itertools.cycle`.

            Default: ``True``.

        :raises:
            ``TypeError``, if the values given to ``run`` or other kwargs
            aren't of the expected types.

        .. versionchanged:: 1.5
            Added support for boolean and string result values.
        .. versionchanged:: 1.5
            Added support for regex dict keys.
        .. versionchanged:: 1.5
            Added the ``repeat`` keyword argument.
        .. versionchanged:: 2.0
            Changed ``repeat`` default value from ``False`` to ``True``.
        __repeatrepeatT__iter__z)Not sure how to yield results from a {!r}__{})wrapsN)superr$   r    rD   itemsr   boolrc   rL   dict
_normalizehasattr	TypeErrorrF   typer   getattr)
r"   r   r+   methodresults
singletonskeyr(   err	__class__s
            r#   r$   zMockContext.__init__  s   p 	 		*fjj489%||~ 	AOFG !$,J'4(")--/ :JC#'??5#9GCL:GZ0G5 //'2 B

4= 9::IIfmmF+W5IIfdv)>?@%	Ar%   r(   c                 0   t        |d      rt        |t              r|g}g }|D ]O  }t        |t              rt	        |rdnd      }nt        |t              rt	        |      }|j                  |       Q t        | d      rt        |      S t        |      S )Nrv   r   r   )exitedrt   )	r~   rL   rc   r{   r   rK   r   r   iter)r"   r(   r   objs       r#   r}   zMockContext._normalize  s    uj)Zs-CGE 	 C#t$A!4C%SkNN3	  ")z!:uW~MWMr%   attnamer*   c                 v   	 t        | |      }t        |t              r	 ||   }t        |      }|j                  s||_        |S # t        $ rC |j	                         D ]'  \  }}t        |d      s|j                  |      s%|} n t        Y kw xY w# t        t        t        t        f$ r t        |      w xY w)Nmatch)r   rL   r|   KeyErrorrz   r~   r   nextr*   AttributeError
IndexErrorStopIterationNotImplementedError)r"   r   r*   r   r   r(   rB   s          r#   _yield_resultzMockContext._yield_result	  s    	/$(C#t$'g,C "#YF >>!(M%   	' '*iik '
U"30SYYw5G"'C!' ' "	'& 
HmD 	/%g..	/s9   B A B +B0BBB BB %B8argsc                 &    | j                  d|      S )N__runr   r"   r*   r   r+   s       r#   r2   zMockContext.run'  s    
 !!'733r%   c                 &    | j                  d|      S )N__sudor   r   s       r#   r7   zMockContext.sudo.  s    
 !!(G44r%   rB   c                     dj                  |      }t        d      }	 t        | |      }t	        |t
              s|| j                  |      ||<   y# t        $ r |w xY w)a  
        Modify the stored mock results for given ``attname`` (e.g. ``run``).

        This is similar to how one instantiates `MockContext` with a ``run`` or
        ``sudo`` dict kwarg. For example, this::

            mc = MockContext(run={'mycommand': Result("mystdout")})
            assert mc.run('mycommand').stdout == "mystdout"

        is functionally equivalent to this::

            mc = MockContext()
            mc.set_result_for('run', 'mycommand', Result("mystdout"))
            assert mc.run('mycommand').stdout == "mystdout"

        `set_result_for` is mostly useful for modifying an already-instantiated
        `MockContext`, such as one created by test setup or helper methods.

        .. versionadded:: 1.0
        rw   z>Can't update results for non-dict or nonexistent mock results!N)rF   r   r   r   rL   r|   r}   )r"   r   r*   rB   heckr(   s         r#   set_result_forzMockContext.set_result_for5  si    . --(L
	D'*E %&J0g  	J	s   A Ar'   )rj   rk   rl   rm   r   r   r   r$   r	   r}   rc   r   r   r2   r7   r   __classcell__)r   s   @r#   rr   rr     s    (NAx/ NA# NA$ NA`N N N(/S /3 /6 /<43 4s 4c 4f 45C 5 5s 5v 5%1%1%(%128%1	%1r%   rr   ) rd   rI   
contextlibr   	itertoolsr   r   typingr   r   r   r	   r
   r   r   unittest.mockr   r   r   r   
exceptionsr   r   r   r-   r   rA   r   invoke.runnersr   r   rr   rp   r%   r#   <module>r      sZ    	 	 %      % A A  &%s$i s$lJ1' J1r%   