o
    X                     @   s  d Z ddlmZ ddlmZ ddlmZ ddlZddlZddlZddlZddl	Z	ddl
Z
ddlZ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 ddlmZ ddlmZ ddlmZ ddlZddlmZ ddlm Z  ddlm!Z! G dd dej"Z"G dd de"Z#G dd de"Z$G dd de"Z%e& ' d Z(ej)ddde(dkre(nddZ*dd Z+ej,dd  Z-d!d" Z.d#d$ Z/dad%d&Z0dbd'd(Z1d)d* Z2d+d, Z3	-		dcd.d/Z4d0d1 Z5d2d3 Z6ddd4d5Z7ded6d7Z8d8d9 Z9d:d; Z:dfd<d=Z;d>Z<			dgd?d@Z=	dhdAdBZ>dCdD Z?dEdF Z@ejAdGd-d-dfdHdIZBdJdK ZCdLdM ZDG dNdO dOeEZFG dPdQ dQeEZGG dRdS dSeEZHG dTdU dUeEZIdidVdWZJG dXdY dYeEZKdZd[ ZLG d\d] d]ejMZN	^		djd_d`ZOdS )kz9General console printing utilities used by the Cloud SDK.    )absolute_import)division)unicode_literalsN)
exceptions)log)
properties)console_attr)console_pager)prompt_completer)encoding)files)	platformsinput)map)rangec                   @   s   e Zd ZdZdS )ErrorzBase exception for the module.N)__name__
__module____qualname____doc__ r   r   C/tmp/google-cloud-sdk/lib/googlecloudsdk/core/console/console_io.pyr   3   s    r   c                           e Zd ZdZ fddZ  ZS )RequiredPromptErrorzEAn exception for when a prompt cannot silenced with the --quiet flag.c                       t t| d d S )NzThis prompt could not be answered because you are not in an interactive session.  Please re-run the command without the --quiet flag to respond to the prompts.)superr   __init__self	__class__r   r   r   ;      
zRequiredPromptError.__init__r   r   r   r   r   __classcell__r   r   r    r   r   8       r   c                       r   )UnattendedPromptError2An exception for when a prompt cannot be answered.c                    r   )NzThis prompt could not be answered because you are not in an interactive session.  You can re-run the command with the --quiet flag to accept default answers for all prompts.)r   r&   r   r   r    r   r   r   E   r"   zUnattendedPromptError.__init__r#   r   r   r    r   r&   B   r%   r&   c                       s&   e Zd ZdZdZd fdd	Z  ZS )OperationCancelledErrorr'   zAborted by user.Nc                    s   t t| |p	| j d S N)r   r(   r   DEFAULT_MESSAGE)r   messager    r   r   r   Q   s   
z OperationCancelledError.__init__r)   )r   r   r   r   r*   r   r$   r   r   r    r   r(   L   s    r(   FP   )replace_whitespacedrop_whitespacebreak_on_hyphenswidthc                 C   s   d dd |  D S )zText wrap the given message and correctly handle newlines in the middle.

  Args:
    message: str, The message to wrap.  It may have newlines in the middle of
      it.

  Returns:
    str, The wrapped message.
  
c                 S      g | ]}t |qS r   )TEXTWRAPfill).0liner   r   r   
<listcomp>j       z_DoWrap.<locals>.<listcomp>)join
splitlinesr+   r   r   r   _DoWrap`   s   
r<   c                 c   s(    t  j| 8  _t V  t  j| 7  _dS )z'Temporarily narrows the global wrapper.N)r3   r0   )	narrow_byr   r   r   _NarrowWrapm   s   r>   c                   C   s   zt  W S  ty   Y d S w r)   )r   EOFErrorr   r   r   r   	_GetInputu   s
   r@   c                 C   s*   | dkr	t |dS |rt| S t| S )a,  Returns the contents of the specified file or stdin if path is '-'.

  Args:
    path: str, The path of the file to read.
    binary: bool, True to open the file in binary mode.

  Raises:
    Error: If the file cannot be read or is larger than max_bytes.

  Returns:
    The contents of the file.
  -)binary)	ReadStdinr   ReadBinaryFileContentsReadFileContents)pathrB   r   r   r   ReadFromFileOrStdin|   s
   


rG   c                 C   s*   | rt  S tj }tjrt|}|S )a  Reads data from stdin, correctly accounting for encoding.

  Anything that needs to read sys.stdin must go through this method.

  Args:
    binary: bool, True to read raw bytes, False to read text.

  Returns:
    A text string if binary is False, otherwise a byte string.
  )	r   ReadStdinBytessysstdinreadsixPY2r   Decode)rB   datar   r   r   rC      s   

rC   c                 C   s   zt j s	W dS | rt j sW dS |rt j sW dS W n
 ty(   Y dS w |rCttj	d}ttj	d}|sC|rA|dkrCdS dS )a  Determines if the current terminal session is interactive.

  sys.stdin must be a terminal input stream.

  Args:
    output: If True then sys.stdout must also be a terminal output stream.
    error: If True then sys.stderr must also be a terminal output stream.
    heuristic: If True then we also do some additional heuristics to check if
               we are in an interactive context. Checking home path for example.

  Returns:
    True if the current terminal session is interactive.
  FHOMEHOMEPATH/T)
rI   rJ   isattystdoutstderrAttributeErrorr   GetEncodedValueosenviron)outputerror	heuristichomehomepathr   r   r   IsInteractive   s"   
r_   c                   C   s*   t j t jjkrt t krdS dS )z<Check if command is being run from command line or a script.TF)r   OperatingSystemCurrentWINDOWSrX   getppidgetpgrpr   r   r   r   IsRunFromShellScript   s   re   c                   C   s   t ddotjjj  S )a  Returns true if we can prompt the user for information.

  This combines all checks (IsInteractive(), disable_prompts is False) to
  verify that we can prompt the user for information.

  Returns:
    bool, True if we can prompt the user for information.
  Tr[   )r_   r   VALUEScoredisable_promptsGetBoolr   r   r   r   	CanPrompt   s   
	rk   Tc              	      s   t jjj r s|rt  S t jjj }|t jjjj	j
kr"tnt}|| | ||d\}}	}
tj|  fdd}z||	}W |
rLtj|
 n
|
rVtj|
 w w |s_|r_t||S )a  Prompts the user a yes or no question and asks if they want to continue.

  Args:
    message: str, The prompt to print before the question.
    prompt_string: str, An alternate yes/no prompt to display.  If None, it
      defaults to 'Do you want to continue'.
    default: bool, What the default answer should be.  True for yes, False for
      no.
    throw_if_unattended: bool, If True, this will throw if there was nothing
      to consume on stdin and stdin is not a tty.
    cancel_on_no: bool, If True and the user answers no, throw an exception to
      cancel the entire operation.  Useful if you know you don't want to
      continue doing anything and don't want to have to raise your own
      exception.
    cancel_string: str, An alternate error to display on No. If None, it
      defaults to 'Aborted by user.'.

  Raises:
    UnattendedPromptError: If there is no input to consume and this is not
      running in an interactive terminal.
    OperationCancelledError: If the user answers no and cancel_on_no is True.

  Returns:
    bool, False if the user said no, True if the user said anything else or if
    prompts are disabled.
  r+   prompt_stringdefaultthrow_if_unattendedcancel_on_nocancel_stringc                    sj   	 t  }|dkr
 S |du rrt st  S |  dv r"dS |  dv r,dS | r4tj|  q)zGet answer to input prompt.T N)yyes)nnoF)r@   r_   r&   striplowerrI   rU   write)repromptanswerrn   ro   r   r   	GetAnswer  s   
z!PromptContinue.<locals>.GetAnswer)r   rg   rh   ri   rj   r(   interactive_ux_styleGetInteractiveUXStylesTESTINGname"_TestPromptContinuePromptGenerator$_NormalPromptContinuePromptGeneratorrI   rU   ry   )r+   rm   rn   ro   rp   rq   styleprompt_generatorpromptrz   endingr}   r{   r   r|   r   PromptContinue   s6   
r   c                 C   s^   ~~~t  }| r|t| d  |sd}|r|d7 }n|d7 }|t| | ddfS )z>Generates prompts for prompt continue under normal conditions.z

zDo you want to continuez	 (Y/n)?  z	 (y/N)?  zPlease enter 'y' or 'n':  r1   )ioStringIOry   r<   getvalue)r+   rm   rn   ro   rp   rq   bufr   r   r   r   5  s   
r   c                 C   s"   ~~~t tj| ||dd ddfS )z1Generates prompts for prompt continue under test.)r+   rm   rq   r1   N)
JsonUXStubUXElementTypePROMPT_CONTINUErl   r   r   r   r   L  s   r   c                 C   s   t jjj r	dS |rtddrtj| |d S t jjj	
 t jjjjjkr5tjttj| d t S tjt|  t S )a;  Prompts the user for a string.

  Args:
    message: str, The prompt to print before the question.
    choices: callable or list, A callable with no arguments that returns the
      list of all choices, or the list of choices.

  Returns:
    str, The string entered by the user, or None if prompts are disabled.
  NTrf   choicesr;   )r   rg   rh   ri   rj   r_   r
   PromptCompleterInputr~   r   r   r   r   rI   rU   ry   r   r   PROMPT_RESPONSEr<   r@   )r+   r   r   r   r   PromptResponseY  s   r   c                 C   sB   | pd} |r| r| d7 } | dj |d7 } n| d7 } t| |dp |S )a  Prompts the user for a string, allowing a default.

  Unlike PromptResponse, this also appends a ':  ' to the prompt.  If 'default'
  is specified, the default is also written written into the prompt (e.g.
  if message is "message" and default is "default", the prompt would be
  "message (default): ").

  The default is returned if the user simply presses enter (no input) or an
  EOF is received.

  Args:
    message: str, The prompt to print before the question.
    default: str, The default value (if any).
    choices: callable or list, A callable with no arguments that returns the
      list of all choices, or the list of choices.

  Returns:
    str, The string entered by the user, or the default if no value was
    entered or prompts are disabled.
  rr    z({default}):  rn   :  r   )formatr   )r+   rn   r   r   r   r   PromptWithDefaultp  s   r   c                 C   sV   zt | W S  ty   Y nw |sdS zttt|| d W S  ty*   Y dS w )a  Parses answer and returns 1-based index in options list.

  Args:
    answer: str, The answer input by the user to be parsed as a choice.
    options: [object], A list of objects to select.  Their str()
          method will be used to select them via freeform text.
    allow_freeform: bool, A flag which, if defined, will allow the user to input
          the choice as a str, not just as a number. If not set, only numbers
          will be accepted.

  Returns:
    int, The 1-indexed value in the options list that corresponds to the answer
          that was given, or None if the selection is invalid. Note that this
          function does not do any validation that the value is a valid index
          (in the case that an integer answer was given)
  N   )int
ValueErrorlistr   strindex)r{   optionsallow_freeformr   r   r   _ParseAnswer  s   
r   c                 C   s   |  tt| | |S )a<  Checks if there is a suitable close choice to suggest.

  Args:
    suggester: object, An object which has methods AddChoices and
      GetSuggestion which is used to detect if an answer which is not present
      in the options list is a likely typo, and to provide a suggestion
      accordingly.
    answer: str, The freeform answer input by the user as a choice.
    options: [object], A list of objects to select.  Their str()
          method will be used to compare them to answer.

  Returns:
    str, the closest option in options to answer, or None otherwise.
  )
AddChoicesr   r   GetSuggestion)	suggesterr{   r   r   r   r   _SuggestFreeformAnswer  s   
r   c                 C   sJ   |du r| n| d| }t |D ]\}}|dj|d t|d qdS )aJ  Prints the options provided to stderr.

  Args:
    options:  [object], A list of objects to print as choices.  Their str()
      method will be used to display them.
    write: f(x)->None, A function to call to write the data.
    limit: int, If set, will only print the first number of options equal
      to the given limit.
  Nz [{index}] {option}
r   )r   option)	enumerater   rL   	text_type)r   ry   limitlimited_optionsir   r   r   r   _PrintOptions  s   

r   2   c                    sp  | st d|r| dg n| } t| }|dur+d|  kr!|k s+n t dj||dtjjj r4|S tjjj	 }|tjjj
jjkr]dd tjttj| d	d
 | D dd  ntjj|rkt|d  |tkrt| td |t }	dj|	d dj|d nt|   s|rd nd |du rdndj|d d fdd}
|
  	 t }|du s|s|dur҈d |r||d krt |S |dkrt|  |
  qt|| |}|r||krt |dur|dkr||krd |d S |r#|r#t||| }|dur#dj||d d |r/dj|d ndj|d q) ai  Prompt the user to select a choice from a list of items.

  Args:
    options:  [object], A list of objects to print as choices.  Their
      six.text_type() method will be used to display them.
    default: int, The default index to return if prompting is disabled or if
      they do not enter a choice.
    message: str, An optional message to print before the choices are displayed.
    prompt_string: str, A string to print when prompting the user to enter a
      choice.  If not given, a default prompt is used.
    allow_freeform: bool, A flag which, if defined, will allow the user to input
      the choice as a str, not just as a number. If not set, only numbers will
      be accepted.
    freeform_suggester: object, An object which has methods AddChoices and
      GetSuggestion which is used to detect if an answer which is not present
      in the options list is a likely typo, and to provide a suggestion
      accordingly.
    cancel_option: bool, A flag indicating whether an option to cancel the
      operation should be added to the end of the list of choices.

  Raises:
    ValueError: If no options are given or if the default is not in the range of
      available options.
    OperationCancelledError: If a `cancel` option is selected by user.

  Returns:
    The index of the item in the list that was chosen, or the default if prompts
    are disabled.
  z%You must provide at least one option.cancelNr   z^Default option [{default}] is not a valid index for the options list [{maximum} options given])rn   maximumc                 S      d S r)   r   xr   r   r   <lambda>      zPromptChoice.<locals>.<lambda>c                 S   r2   r   )rL   r   )r5   or   r   r   r7     r8   z PromptChoice.<locals>.<listcomp>)r+   rm   r   r1   )r   z%Did not print [{truncated}] options.
)	truncatedzMToo many options [{maximum}]. Enter "list" at prompt to print choices fully.
)r   zHPlease enter numeric choice or text value (must exactly match list item)z Please enter your numeric choicer   z ({default}):  r   r   c                      s   t    d S r)   )r<   r   rm   suffix_stringry   r   r   _PrintPrompt+     z"PromptChoice.<locals>._PrintPromptTr   z4[{answer}] not in list. Did you mean [{suggestion}]?)r{   
suggestionzOPlease enter a value between 1 and {maximum}, or a value present in the list:  z/Please enter a value between 1 and {maximum}:  )r   lenr   r   rg   rh   ri   rj   r~   r   r   r   r   rI   rU   ry   r   r   PROMPT_CHOICEr<   PROMPT_OPTIONS_OVERFLOWr   r@   r(   r   r   )r   rn   r+   rm   r   freeform_suggestercancel_optionr   r   r   r   r{   
num_choicer   r   r   r   PromptChoice  s    




r   c              	   C   s   t jjj r	dS t jjj }|t jjjjj	kr.dd }t
jttj||||dd  nt
jj}|r<|t|d  	 |t| t }| |rL|S |t|d  |r]tddr]|S q=)	a  Prompts the user for a string that must pass a validator.

  Args:
    validator: function, A validation function that accepts a string and returns
      a boolean value indicating whether or not the user input is valid.
    error_message: str, Error message to display when user input does not pass
      in a valid string.
    prompt_string: str, A string to print when prompting the user to enter a
      choice.  If not given, a default prompt is used.
    message: str, An optional message to print before prompting.
    allow_invalid: bool, Allow returning the answer if validation fails.

  Returns:
    str, The string entered by the user, or the default if no value was
    entered or prompts are disabled.
  Nc                 S   r   r)   r   r   r   r   r   r   p  r   z%PromptWithValidator.<locals>.<lambda>)error_messagerm   r+   allow_invalidr1   TFr   )r   rg   rh   ri   rj   r~   r   r   r   r   rI   rU   ry   r   r   PROMPT_WITH_VALIDATORr<   r@   r   )	validatorr   rm   r+   r   r   ry   r{   r   r   r   PromptWithValidatorX  s0   r   c                    s    fdd}t d|| S )a  Expands {key} => value for key, value in kwargs.

  Details:
    * {{<identifier>}} expands to {<identifier>}
    * {<unknown-key>} expands to {<unknown-key>}
    * {key} values are recursively expanded before substitution into the result

  Args:
    s: str, The string to format.
    **kwargs: {str:str}, A dict of strings for named parameters.

  Returns:
    str, The lazily-formatted string.
  c                    s   |  ddd }|  d}|  ddd }|r!|r!|| | S  |}|du r/|  dS t|r6| }|t|fi   | S )z7Returns one replacement string for LazyFormat re.sub().r   N      r   )groupgetcallable
LazyFormat)matchprefixr   suffixvaluekwargsr   r   _Replacement  s   


z LazyFormat.<locals>._Replacementz(\{+)(\w+)(\}+))resub)sr   r   r   r   r   r     s   r   c                 C   sf   t d%}d}|}tjjj }|rd}d}||||  d W  d   S 1 s,w   Y  dS )a  Formats an action a user must initiate to complete a command.

  Some actions can't be prompted or initiated by gcloud itself, but they must
  be completed to accomplish the task requested of gcloud; the canonical example
  is that after installation or update, the user must restart their shell for
  all aspects of the update to take effect. Unlike most console output, such
  instructions need to be highlighted in some way. Using this function ensures
  that all such instances are highlighted the *same* way.

  Args:
    s: str, The message to format. It shouldn't begin or end with newlines.

  Returns:
    str, The formatted message. This should be printed starting on its own
      line, and followed by a newline.
     z
==> z
 r1   N)r>   r   rg   accessibilityscreen_readerrj   r9   wrap)r   wrapper	separatorr   r   r   r   r   FormatRequiredUserAction  s   
$r   <   c                 C   sn   t jjj }|t jjjjjkrt S |t jjjj	jkr!t
| |S |s*t jjj r/t| |S t| ||||S )a%  A simple progress bar for tracking completion of an action.

  This progress bar works without having to use any control characters.  It
  prints the action that is being done, and then fills a progress bar below it.
  You should not print anything else on the output stream during this time as it
  will cause the progress bar to break on lines.

  Progress bars can be stacked into a group. first=True marks the first bar in
  the group and last=True marks the last bar in the group. The default assumes
  a singleton bar with first=True and last=True.

  This class can also be used in a context manager.

  Args:
    label: str, The action that is being performed.
    stream: The output stream to write to, stderr by default.
    total_ticks: int, The number of ticks wide to make the progress bar.
    first: bool, True if this is the first bar in a stacked group.
    last: bool, True if this is the last bar in a stacked group.
    screen_reader: bool, override for screen reader accessibility property
      toggle.

  Returns:
    The progress bar.
  )r   rg   rh   r~   r   r   OFFr   NoOpProgressBarr   _StubProgressBarr   r   rj   _TextPercentageProgressBar_NormalProgressBar)labelstreamtotal_ticksfirstlastr   r   r   r   r   ProgressBar  s   

r   c                    sx    du s t krtdd tt|D S  fdd}t|}g }d}|D ]}|| }|||| ||7 }q%t|S )a  Splits a progress bar into logical sections.

  Wraps the original callback so that each of the subsections can use the full
  range of 0 to 1 to indicate its progress.  The overall progress bar will
  display total progress based on the weights of the tasks.

  Args:
    original_callback: f(float), The original callback for the progress bar.
    weights: [float], The weights of the tasks to create.  These can be any
      numbers you want and the split will be based on their proportions to
      each other.

  Raises:
    ValueError: If the weights don't add up to 1.

  Returns:
    (f(float), ), A tuple of callback functions, in order, for the subtasks.
  Nc                 S   s   g | ]}t qS r   )DefaultProgressBarCallback)r5   _r   r   r   r7      s    z$SplitProgressBar.<locals>.<listcomp>c                    s    fdd}|S )Nc                    s    |    d S r)   r   )done_fraction)already_doneoriginal_callbackweightr   r   Callback  r   z8SplitProgressBar.<locals>.MakeCallback.<locals>.Callbackr   )r   r   r   r   )r   r   r   MakeCallback  s   z&SplitProgressBar.<locals>.MakeCallbackr   )r   tupler   r   sumappend)r   weightsr   total	callbacksr   r   normalized_weightr   r   r   SplitProgressBar  s   
r   c                 C   s   ~ d S r)   r   )progress_factorr   r   r   r     s   r   c                   @   sH   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dS )r   ab  A simple progress bar for tracking completion of an action.

  This progress bar works without having to use any control characters.  It
  prints the action that is being done, and then fills a progress bar below it.
  You should not print anything else on the output stream during this time as it
  will cause the progress bar to break on lines.

  Progress bars can be stacked into a group. first=True marks the first bar in
  the group and last=True marks the last bar in the group. The default assumes
  a singleton bar with first=True and last=True.

  This class can also be used in a context manager.
  c                 C   s   || _ || _d| _|| _|| _|| _t }| | _	| j	j
| j	jkp*| j	j| j	jk| _| jr:tdds:d| _d| _| jd }t||krP|d|d  d }nt||k rb|t| }|d| 7 }| j	j| j	j }	| j	j| j	j }
d	j|	||
d
| _dS )a  Creates a progress bar for the given action.

    Args:
      label: str, The action that is being performed.
      stream: The output stream to write to, stderr by default.
      total_ticks: int, The number of ticks wide to make the progress bar.
      first: bool, True if this is the first bar in a stacked group.
      last: bool, True if this is the last bar in a stacked group.
    r   Trf   r   Nr   z...r   z{left} {label} {right})leftr   right)
_raw_label_stream_ticks_written_total_ticks_first_lastr   ConsoleAttrGetBoxLineCharacters_boxd_drd_vrd_dld_vl_redrawr_   r   d_hr   _label)r   r   r   r   r   r   attrmax_label_widthdiffr   r  r   r   r   r   %  s2   


z_NormalProgressBar.__init__c                 C   s   | j s| jr.| j r| jjn| jj}| j r| jjn| jj}dj|| jj| j	 |d}| 
| | 
| jd  | 
| jj d| _dS )z:Starts the progress bar by writing the top rule and label.z{left}{middle}{right}
)r   middler  r1   r   N)r  r  r
  r  r  r  r  r   r  r  _Writer  d_urr  )r   r   r  ruler   r   r   StartM  s   

z_NormalProgressBar.Startc                 C   s   t | j| }|| j }t|| j| j }|dkrH| | jj|  |  j|7  _|| jkrA| js4| js6dnd}| | jj	|  | j
  dS dS )a  Sets the current progress of the task.

    This method has no effect if the progress bar has already progressed past
    the progress you call it with (since the progress bar cannot back up).

    Args:
      progress_factor: float, The current progress as a float between 0 and 1.
    r   r1   N)r   r  r  minr  r
  r  r  r  d_ulr  flush)r   r   expected_ticks	new_ticksendr   r   r   SetProgressY  s   	

z_NormalProgressBar.SetProgressc                 C      |  d dS Mark the progress as done.r   Nr!  r   r   r   r   Finisho     z_NormalProgressBar.Finishc                 C   s   | j | d S r)   r  ry   r   msgr   r   r   r  s     z_NormalProgressBar._Writec                 C      |    | S r)   r  r   r   r   r   	__enter__v     z_NormalProgressBar.__enter__c                 G      |    d S r)   r&  r   argsr   r   r   __exit__z     z_NormalProgressBar.__exit__Nr   r   r   r   r   r  r!  r&  r  r.  r4  r   r   r   r   r     s    (r   c                   @   sJ   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dS )r   +A progress bar that outputs nothing at all.      @c                 C   s    || _ || _d| _|d | _dS )a  Creates a progress bar for the given action.

    Args:
      label: str, The action that is being performed.
      stream: The output stream to write to, stderr by default.
      percentage_display_increments: Minimum change in percetnage to display new
        progress
    r         Y@N)r  r  _last_percentage_percentage_display_increments)r   r   r   percentage_display_incrementsr   r   r   r     s   	z#_TextPercentageProgressBar.__init__c                 C   s   |  | j d S r)   )r  r  r   r   r   r   r    r+  z _TextPercentageProgressBar.Startc                 C   sH   t |d}|| j| j k}|s|dkr"| d|d  || _d S d S )Ng      ?z{0:.0f}%r9  )r  r:  r;  r  r   )r   r   should_update_progressr   r   r   r!    s   


z&_TextPercentageProgressBar.SetProgressc                 C   r"  r#  r%  r   r   r   r   r&    r'  z!_TextPercentageProgressBar.Finishc                 C   s   | j |d  d S )Nr1   r(  r)  r   r   r   r    r   z!_TextPercentageProgressBar._Writec                 C   r,  r)   r-  r   r   r   r   r.    r/  z$_TextPercentageProgressBar.__enter__c                 G   r0  r)   r1  r2  r   r   r   r4    r5  z#_TextPercentageProgressBar.__exit__N)r8  r6  r   r   r   r   r   ~  s    
	r   c                   @   @   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )r   r7  c                 C   r   r)   r   r   r   r   r   r        zNoOpProgressBar.__init__c                 C   r   r)   r   r   r   r   r   r    r?  zNoOpProgressBar.Startc                 C   r   r)   r   r   r   r   r   r   r!    r?  zNoOpProgressBar.SetProgressc                 C   r"  r#  r%  r   r   r   r   r&    r'  zNoOpProgressBar.Finishc                 C   r,  r)   r-  r   r   r   r   r.    r/  zNoOpProgressBar.__enter__c                 G   r0  r)   r1  r2  r   r   r   r4    r5  zNoOpProgressBar.__exit__N
r   r   r   r   r   r  r!  r&  r.  r4  r   r   r   r   r     s    r   c                   @   r>  )r   zA progress bar that only prints deterministic start and end points.

  No UX about progress should be exposed here. This is strictly for being able
  to tell that the progress bar was invoked, not what it actually looks like.
  c                 C   s   || _ || _d S r)   )r  r  )r   r   r   r   r   r   r     s   
z_StubProgressBar.__init__c                 C   s   | j ttj| jd d S )Nr;   )r  ry   r   r   PROGRESS_BARr  r   r   r   r   r    s   z_StubProgressBar.Startc                 C   r   r)   r   r@  r   r   r   r!    r?  z_StubProgressBar.SetProgressc                 C   s   |  d | jd dS )r$  r   r1   N)r!  r  ry   r   r   r   r   r&    s   
z_StubProgressBar.Finishc                 C   r,  r)   r-  r   r   r   r   r.    r/  z_StubProgressBar.__enter__c                 G   r0  r)   r1  r2  r   r   r   r4    r5  z_StubProgressBar.__exit__NrA  r   r   r   r   r     s    r   c           
      C   s  t dds|s
tj}||  dS |stj|  tj}|rt	t
jdd}|dkr-d}n|s=dD ]}t|r<|} nq1|rt	t
jdd}d|pKd	 }tt
jd| tj|tjdd
}t  }	|j| |	d |  |du r}tt
jdd dS t| ||  dS )a$  Run a user specified pager or fall back to the internal pager.

  Args:
    contents: The entire contents of the text lines to page.
    out: The output stream, log.out (effectively) if None.
    prompt: The page break prompt.
    check_pager: Checks the PAGER env var and uses it if True.
  T)rZ   NPAGERrA   )lesspagerLESSz-Rrr   )rJ   shellr   )r_   r   outry   file_only_loggerinforI   rT   r   rW   rX   rY   r   FindExecutableOnPathSetEncodedValue
subprocessPopenPIPEr   GetConsoleAttrGetEncodingcommunicateencodewaitr	   PagerRun)
contentsrH  r   check_pagerrE  command	less_origrD  pencr   r   r   More  s<   
	

r]  c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )TickableProgressBarz;A thread safe progress bar with a discrete number of tasks.c                 O   s*   d| _ || _t|i || _t | _d S )Nr   )	completedr   r   _progress_bar	threadingLock_lock)r   r   r3  r   r   r   r   r     s   zTickableProgressBar.__init__c                 C   s   | j   | S r)   )r`  r.  r   r   r   r   r.    s   
zTickableProgressBar.__enter__c                 C   s   | j ||| d S r)   )r`  r4  )r   exc_type	exc_value	tracebackr   r   r   r4    r   zTickableProgressBar.__exit__c                 C   sN   | j  |  jd7  _| j| j| j  W d    d S 1 s w   Y  d S )Nr   )rc  r_  r`  r!  r   r   r   r   r   Tick   s   "zTickableProgressBar.TickN)r   r   r   r   r   r.  r4  rg  r   r   r   r   r^    s    r^  c                 K   sp   t  }| j|d< tt|t|   }|r td| j||  D ]}||d}|r2|||< q$t	
|S )z/Generates a stub message for UX console output.uxz%Extraneous args for Ux Element {}: {}N)collectionsOrderedDictr   r   setGetDataFieldsr   r   r   jsondumps)ux_typer   rZ   
extra_argsfieldvalr   r   r   r   &  s   

r   c                   @   s<   e Zd ZdZdZdZdZdZdZdZ	dZ
d	d
 Zdd ZdS )r   z#Describes the type of a ux element.)r   r+   )r   r+   aborted_messagestatus)r   r+   rt  succeeded_stagesfailed_stage)r   r+   rm   rq   )r   r+   )   r+   rm   r   )   r   rm   r+   r   c                 G   s   ~|| _ d S r)   _data_fields)r   ordinaldata_fieldsr   r   r   r   A  s   
zUXElementType.__init__c                 C   s   | j S )z@Returns the ordered list of additional fields in the UX Element.ry  r   r   r   r   rl  H  s   zUXElementType.GetDataFieldsN)r   r   r   r   rB  PROGRESS_TRACKERSTAGED_PROGRESS_TRACKERr   r   r   r   r   rl  r   r   r   r   r   5  s    r   Invalid Passwordc                 C   sv   t jjj r	dS t| }t|}t|r|ntj}t|r7||s7t	j
t|d  t|}||r$||S )z2Prompt user for password with optional validation.Nr1   )r   rg   rh   ri   rj   rL   
ensure_strgetpassr   rI   rU   ry   r<   )r   r   validation_callableencoder_callable
str_promptpass_wdencoderr   r   r   PromptPasswordM  s   


r  )F)FFF)NNTFFN)NN)NNNr)   )NNNFNF)NF)NNT)r  NN)Pr   
__future__r   r   r   ri  
contextlibenumr  r   rm  rX   r   rM  rI   textwrapra  googlecloudsdk.corer   r   r   googlecloudsdk.core.consoler   r	   r
   googlecloudsdk.core.utilr   r   r   rL   	six.movesr   r   r   r   r   r&   r(   rP  GetTermSize_CONSOLE_WIDTHTextWrapperr3   r<   contextmanagerr>   r@   rG   rC   r_   re   rk   r   r   r   r   r   r   r   r   r   r   r   r   r   rt  r   r   r   objectr   r   r   r   r]  r^  r   Enumr   r  r   r   r   r   <module>   s   




+	
O

'

z
.$
&'h,
/