o
    >                     @   s"  d 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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ZdZedddgZddiZdd Zdd ZdZdZd(ddZG dd deZefddZdd Zdd Zd d! Z d"Z!d#Z"d$d% Z#d&d' Z$dS ))z9Utilities for configuring platform specific installation.    )absolute_import)division)print_function)unicode_literalsN)
properties)
console_io)encoding)files)	platformsbashzshkshfishc                 C   s   t | tjd dS )z Prints action to standard error.)fileN)printsysstderr)action r   B/tmp/google-cloud-sdk/lib/googlecloudsdk/core/platforms_install.py_TraceAction+   s   r   c                    s   zddl ddlddlm W n ty"   tdj| d Y dS w fdd fdd	d
d  fdd}|d| g tdj| d dS )zUpdate the Windows system path to include bin_path.

  Args:
    bin_path: str, The absolute path to the directory that will contain
        Cloud SDK binaries.
  r   NwinregzThe installer is unable to automatically update your system PATH. Please add
  {path}
to your system PATH to enable easy use of the Cloud SDK Command Line Tools.
)pathc                    sH    j }d} ||d j}z || \}}W |S  ty#   Y dS w )NEnvironmentr    )HKEY_CURRENT_USEROpenKeyKEY_READQueryValueExWindowsError)namerootsubkeykeyvalue_r   r   r   GetEnvG   s   z%_UpdatePathForWindows.<locals>.GetEnvc                    sJ    jddj}|| dj| |  j jdd |S )Nr   r   )	r   r   KEY_ALL_ACCESS
SetValueExREG_EXPAND_SZCloseKeySendMessageHWND_BROADCASTWM_SETTINGCHANGE)r!   r%   r$   )win32conwin32guir   r   r   SetEnvR   s   
z%_UpdatePathForWindows.<locals>.SetEnvc                 S   s"   || v r|  | || v sd S d S N)remove)pathsr%   r   r   r   Remove[   s   
z%_UpdatePathForWindows.<locals>.Removec                    sJ    |  d}|D ]}||v r|| |d| q	| d| d S )N;r   )splitinsertjoin)r!   valuesr4   r%   )r'   r5   r1   r   r   
PrependEnv_   s   
z)_UpdatePathForWindows.<locals>.PrependEnvPathz~The following directory has been added to your PATH.
  {bin_path}

Create a new command shell for the changes to take effect.
)bin_path)r/   r0   	six.movesr   ImportErrorr   format)r=   r;   r   )r'   r5   r1   r/   r0   r   r   _UpdatePathForWindows1   s$   
	rA   z9
{comment}
if [ -f '{rc_path}' ]; then . '{rc_path}'; fi
z5
{comment}
if [ -f '{rc_path}' ]; . '{rc_path}'; end
c           	      C   s`   |st | }t d| d t j}|dkrtnt}|j| |d}|d|}dj||d}|S )a  Generates the RC file contents with new comment and `source rc_path` lines.

  Args:
    comment: The shell comment string that precedes the source line.
    rc_path: The path of the rc file to source.
    rc_contents: The current contents.
    shell: The shell base name, specific to this module.
    pattern: A regex pattern that matches comment, None for exact match on
      comment.

  Returns:
    The comment and `source rc_path` lines to be inserted into a shell rc file.
  
z
(source '.*'|if .*; then
  source .*
fi|if .*; then (\.|source) .*; fi|if .*; (\.|source) .*; end|if .*; if type source .*; end)
r   )commentrc_pathr   z{filtered_contents}{line})filtered_contentsline)reescapecompile	MULTILINE_INJECT_FISH
_INJECT_SHr@   sub)	rC   rD   rc_contentsshellpatternsubreinjectrF   rE   r   r   r   _GetRcContents}   s   

rS   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	
_RcUpdaterz7Updates the RC file completion and PATH code injection.c                 C   sX   || _ || _|| _t||}tj|dj|d| _	tj|dj|d| _|| _
d S )Nzcompletion.{shell}.incrO   zpath.{shell}.inc)completion_updatepath_updaterD   _COMPATIBLE_INC_SHELLgetosr   r9   r@   
completionrO   )selfrV   rW   rO   rD   sdk_rootcompatible_shellr   r   r   __init__   s   
z_RcUpdater.__init__c                 C   s   t j| jS r2   )rZ   r   existsr[   )r\   r   r   r   _CompletionExists   s   z_RcUpdater._CompletionExistsc              
   C   s  | j rtj| j rt| j }|}ntj| j r%tdj| j d dS d}d}| j	r5t
d| j|| j}| jrG|  rGt
d| j|| jdd}||krVtd	j| j d
 dS tj| j rs| j d }tdj| j |d t| j | tj| j }zt| W n tjttfy   tdj| j d Y dS w z	t| j | W n tjttfy   tdj| j d Y dS w tdj| j d ttd tjjj }|rdnd}| js|  rt|dj| jd
  | j	st|dj| jd
  dS dS )zCreates or updates the RC file.z>[{rc_path}] exists and is not a file, so it cannot be updated.rD   Nr   z6# The next line updates PATH for the Google Cloud SDK.z<# The next line enables shell command completion for gcloud.zB# The next line enables [a-z][a-z]* command completion for gcloud.)rP   z No changes necessary for [{rc}].)rcz.backupz Backing up [{rc}] to [{backup}].)rc   backupzFCould not create directories for [{rc_path}], so it cannot be updated.zLCould not update [{rc_path}]. Ensure you have write access to this location.z[{rc_path}] has been updated.z1Start a new shell for the changes to take effect.z==> zLSource [{rc}] in your profile to enable shell command completion for gcloud.z[Source [{rc}] in your profile to add the Google Cloud SDK command line tools to your $PATH.)rD   rZ   r   isfiler	   ReadFileContentsr`   r   r@   rW   rS   rO   rV   ra   r[   shutilcopyfiledirnameMakeDirErrorIOErrorOSErrorWriteFileContentsr   FormatRequiredUserActionr   VALUESaccessibilityscreen_readerGetBool)r\   rN   original_rc_contents	rc_backuprc_dirrr   prefixr   r   r   Update   s   



z_RcUpdater.UpdateN)__name__
__module____qualname____doc__r_   ra   rx   r   r   r   r   rT      s
    rT   c                 C   s8   | s|S t j| }tD ]}|t|v r|  S q|S )a*  Returns the preferred shell name based on the base file name in path.

  Args:
    path: str, The file path to check.
    default: str, The default value to return if a preferred name cannot be
      determined.

  Returns:
    The preferred user shell name or default if none can be determined.
  )rZ   r   basename_SUPPORTED_SHELLSsix	text_type)r   defaultr!   rO   r   r   r   _GetPreferredShell	  s   r   c                 C   s|   | dkrt tjddpdS | dkrtjdddS | dkr$d	j| d
S |tjj	kr,dS |tjj
kr4dS |tjjkr<dS dS )zReturns the RC file name for shell and host_os.

  Args:
    shell: str, The shell base name.
    host_os: str, The host os identification string.

  Returns:
    The shell RC file name, '.bashrc' by default.
  r   ENVNz.kshrcr   z.configzconfig.fishr   z
.{shell}rcrU   z.bashrcz.bash_profilez.profile)r   GetEncodedValuerZ   environr   r9   r@   r
   OperatingSystemLINUXMACOSXMSYS)rO   host_osr   r   r   _GetShellRcFileName  s   
r   c                 C   s   | s|sdS |r
|S t ttjdd}tjt t	||}t
 s.tdj|d |S t
dj|d}|r>t|S |S )a4  Returns an rc path based on the default rc path or user input.

  Gets default rc path based on environment. If prompts are enabled,
  allows user to update to preferred file path. Otherwise, prints a warning
  that the default rc path will be updated.

  Args:
    completion_update: bool, Whether or not to do command completion.
    path_update: bool, Whether or not to update PATH.
    rc_path: str, the rc path given by the user, from --rc-path arg.
    host_os: str, The host os identification string.

  Returns:
    str, A path to the rc file to update.
  NSHELL/bin/shzcYou specified that you wanted to update your rc file. The default file will be updated: [{rc_path}]rb   zThe Google Cloud SDK installer will now prompt you to update an rc file to bring the Google Cloud CLIs into your environment.

Enter a path to an rc file to update, or leave blank to use [{rc_path}]:  )r   r   r   rZ   r   r   r9   r	   
GetHomeDirr   r   	CanPromptr   r@   PromptResponseExpandHomeDir)rV   rW   rD   r   preferred_shelldefault_rc_pathrc_path_updater   r   r   _GetAndUpdateRcPath6  s,   r   c                 C   s:   t | |||}t|tttjddd}t| ||||S )a  Returns an _RcUpdater object for the preferred user shell.

  Args:
    completion_update: bool, Whether or not to do command completion.
    path_update: bool, Whether or not to update PATH.
    rc_path: str, The path to the rc file to update. If None, ask.
    sdk_root: str, The path to the Cloud SDK root.
    host_os: str, The host os identification string.

  Returns:
    An _RcUpdater() object for the preferred user shell.
  r   r   )r   )r   r   r   r   rZ   r   rT   )rV   rW   rD   r]   r   r   r   r   r   _GetRcUpdater`  s   
r   zupdate your $PATHzenable shell command completionc                 C   s   | dur|dur| |fS g }| du r| t |du r | t dd|}t|}| du r3|n| } |du r;|n|}| |fS )ag  Prompt the user to update path or command completion if unspecified.

  Args:
    path_update: bool, Value of the --update-path arg.
    completion_update: bool, Value of the --command-completion arg.

  Returns:
    (path_update, completion_update) (bool, bool) Whether to update path and
        enable completion, respectively, after prompting the user.
  Nz
Modify profile to {}?z and )append_PATH_PROMPT_COMPLETION_PROMPTr@   r9   r   PromptContinue)rW   rV   actionspromptresponser   r   r   _PromptToUpdate|  s   


r   c                 C   s   t j }|t jjkr|du rtjdd}|rt| dS t r)t|| \}} n|r?|du r?| du r?d}d} t	d
tt t| ||||  dS )a-  Update the system path to include bin_path.

  Args:
    completion_update: bool, Whether or not to do command completion. From
      --command-completion arg during install. If None, ask.
    path_update: bool, Whether or not to update PATH. From --path-update arg
      during install. If None, ask.
    rc_path: str, The path to the rc file to update. From --rc-path during
      install. If None, ask.
    bin_path: str, The absolute path to the directory that will contain
      Cloud SDK binaries.
    sdk_root: str, The path to the Cloud SDK root.
  Nz,Update %PATH% to include Cloud SDK binaries?)prompt_stringTz&Profile will be modified to {} and {}.)r
   r   CurrentWINDOWSr   r   rA   r   r   r   r@   r   r   r   rx   )rV   rW   rD   r=   r]   r   r   r   r   UpdateRC  s.   



r   r2   )%r|   
__future__r   r   r   r   rZ   rG   rg   r   googlecloudsdk.corer   googlecloudsdk.core.consoler   googlecloudsdk.core.utilr   r	   r
   r   _DEFAULT_SHELLr~   rX   r   rA   rL   rK   rS   objectrT   r   r   r   r   r   r   r   r   r   r   r   r   <module>   s@   @
.^*!