
    .                        d 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	m
Z
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ZddlZddlZddlmZ ej8                  Zd	Zd
ZdZdZ dZ!de"fdZ# e#       Z$de%fdZ& e&       Z'dee"   fdZ(de"ddfdZ)d3dZ*	 d4de"dee"   de	e"e"f   fdZ+dede"de	e"e"f   fdZ,dee"   ddfdZ-dee"   dee"   dee"   fdZ.dee"   dee"   dee"   fdZ/de"de"d e%d!d"dee"   f
d#Z0de"fd$Z1de"fd%Z2	 d5d&e3d'ed(   fd)Z4de
e"   fd*Z5de
e"   fd+Z6d,e"de	e"e"f   fd-Z7d.e"de
e"   fd/Z8de"fd0Z9d1e"de%fd2Z:y)6z7A library of functions to handle bq flags consistently.    N)DictListLiteralOptionalTextIO)app)flags)version)credentials)
stringutilz%https://www.googleapis.com/auth/drivez(https://www.googleapis.com/auth/bigqueryz.https://www.googleapis.com/auth/cloud-platformz/https://www.googleapis.com/auth/accounts.reauthVERSIONreturnc                      t         } 	 t        j                  | t              }sd}t        j                  |      j                         }d|vsJ d       |S # t        $ r Y ?w xY w)zDReturns content of VERSION file found in same dir as the cli binary.zunknown-version
z0New lines are not allowed in the version string.)__name__pkgutilget_data_VERSION_FILENAMEFileNotFoundErrorr   
ensure_strstrip)rootversion_strs     platform/bq/bq_utils.py_GetVersionr   #   st    	$	""4):;K 
#K%%k288:+
+878	 
 		s   A 	A"!A"c                  ,    t         j                  d      S )z4Returns true if the current binary is targeting TPC.ztpc-)VERSION_NUMBER
startswith     r   _IsTpcBinaryr!   7   s    		"	"6	**r    c                      t         d   j                  xr t         j                  xs1 t        j                  j                  d      xs t         j                  S )zReturn the name of the bigqueryrc file to use.

  In order, we look for a flag the user specified, an environment
  variable, and finally the default value for the flag.

  Returns:
    bigqueryrc filename as a string.
  
bigqueryrc
BIGQUERYRC)FLAGSpresentr#   osenvirongetr   r    r   GetBigqueryRcFilenamer*   ?   sE     \""7u'7'7 		%			r    flagc                 Z    | |   j                  |       t        | |t        | |             y N)parsesetattrgetattr)flag_valuesr+   values      r   
UpdateFlagr3   O   s(    d% 	+tW[$78r    c                  $    t        dt               y)z7Updates FLAGS with values found in the bigqueryrc file.N)ProcessBigqueryrcSectionr%   r   r    r   ProcessBigqueryrcr6   V   s    4'r    filenamesection_namec                     i }t         j                  j                  |       s|S 	 t        |       5 }t	        ||      }ddd       |S # 1 sw Y   |S xY w# t
        $ r Y |S w xY w)a  Read a configuration file section returned as a dictionary.

  Args:
    filename: The filename of the configuration file.
    section_name: if None, read the global flag settings.

  Returns:
    A dictionary of flag names and values from that section of the file.
  N)r'   pathexistsopen_ProcessSingleConfigSectionIOError)r7   r8   
dictionaryrcfiles       r   _ProcessConfigSectionrA   [   sm     *		!		h6.v|Dj 
 
	 
 
 
 			s-   A AA AA A 	A! A!filec                    i }| }| D ]  }|j                         j                  d      r8|j                         j                  d      r|j	                         dd }||k(  }Z|s]|j                         j                  d      s|j	                         s|j                  d      \  }}}|sd}|j	                         }|j	                         }|j                  d      r|dd	 }|j                  d      r|||<    |S )
zRead a configuration file section returned as a dictionary.

  Args:
    file: The opened configuration file object.
    section_name: Name of the section to read.

  Returns:
    A dictionary of flag names and values from that section of the file.
  []   #=true-N)lstripr   rstripendswithr   	partition)	rB   r8   r?   
in_sectionlinenext_sectionr+   	equalsignr2   s	            r   r=   r=   t   s     **d{{}$)?)?)DZZ\!B'l</j		!	!#	&djjl!^^C0D)Ue::<DKKME
//#
!"Xd //#
Jt# $ 
r    c           
         t               }t        ||       }|j                         D ]  \  }}||vr%t        j                  d|d| r|       d      ||   j
                  st        |||       L||   j                         }|j                  d      sqt        ||      }||   j                  |       t        |||t        ||      z           y)zRead the bigqueryrc file into flag_values for section section_name.

  Args:
    section_name: if None, read the global flag settings.
    flag_values: FLAGS instance.

  Raises:
    UsageError: Unknown flag found.
  )r7   r8   zUnknown flag z% found in bigqueryrc file in section globalmultiN)r*   rA   itemsr   
UsageErrorr&   r3   	flag_typer   r0   r.   r/   )r8   r1   r#   r?   r+   r2   rY   	old_values           r   r5   r5      s     %&*$*  %%'kdE ;NN<<=? 5==?  t$$dE*d#--/i			g	&K.	D&T9w{D/I#IJ (r    quota_project_idfallback_project_idc                 (    | s|r|S t        | |      S )zUReturn the final resolved quota project ID after cross-referencing gcloud properties.r[   r\   ) _GetResolvedGcloudQuotaProjectIDr^   s     r   GetResolvedQuotaProjectIDr`      s#    
 
1	)'-
 r    c                 "    | r| dv r|S d| k(  ry| S )zReturn the resolved quota project ID after cross-referencing gcloud properties.

  Args:
    quota_project_id: The quota project ID to resolve.
    fallback_project_id: The fallback project ID to use.
  )CURRENT_PROJECTCURRENT_PROJECT_WITH_FALLBACKLEGACYNr   r^   s     r   r_   r_      s.     * /  !!	r    
project_iduse_google_authr   zgoogle_oauth2.Credentialsc                 P    |rt        |d      r|j                  S t        | |      S )zGReturn the effective quota project ID to be set in the API HTTP header._quota_project_idr^   )hasattrrh   r_   )r[   re   rf   r   s       r   'GetEffectiveQuotaProjectIDForHTTPHeaderrj      s/     .AB(((	)'Z
 r    c                      dj                  t        j                         t        j                         t        j                         g      S )N:)joinplatformpython_implementationpython_versionr   r    r   GetPlatformStringrq      s<    	$$& 
 r    c                     t               } 	 t        j                  }	 t
        j                  d   }	 t
        j                  d   }t        j                  dj                  t        | t        j                         t        j                  j!                  dd      |t"        j                  t$        j                  t&        j                  t
        j(                  j+                  t        j,                        ||            S # t        $ r t        j                  j                  }Y w xY w# t        $ r d}Y w xY w# t        $ r d}Y w xY w)z/Gets the info string for the current execution.PATHN
PYTHONPATHa        BigQuery CLI [{version}]

      Platform: [{platform_str}] {uname}
      Python Version: [{python_version}]

      Requests Version: [{requests_version}]
      Urllib3 Version: [{urllib3_version}]
      Httplib2: [{httplib2_version}]
      Google Auth Version: [{google_auth_version}]

      System PATH: [{sys_path}]
      Shell PATH: [{shell_path}]
      Python PATH: [{python_path}]

      r    )r
   platform_strunamerp   httplib2_versiongoogle_auth_versionrequests_versionurllib3_versionsys_path
shell_pathpython_path)rq   httplib2__version__AttributeErrorpython3r'   r(   KeyErrortextwrapdedentformatr   rn   rw   sysr
   replacery   requestsurllib3pathseprm   r:   )rv   rx   r}   r~   s       r   GetInfoStringr      s   "$,4++F#J**\*K 

 & # ,,T37+1==#//!--::??388,!  !
  
 4  ''334 
 J 
 Ks3   C< D& D8 <#D#"D#&D54D58EEobjdefault_format)json
prettyjsonc                    ddg}t         j                  |v rt         j                  }n|}|dk(  r!t        t        j                  | d             y
|dk(  r"t        t        j                  | dd             y
t        d|d	|      )zPrints obj in a JSON format according to the "--format" flag.

  Args:
    obj: The object to print.
    default_format: The format to use if the "--format" flag does not specify a
      valid json format: 'json' or 'prettyjson'.
  r   r   ),rl   )
separatorsT   )	sort_keysindentz#Invalid json format for printing: 'z', expected one of: N)r%   r   printr   dumps
ValueError)r   r   json_formats
use_formats       r   PrintFormattedJsonObjectr   !  sw     ,',
\\\!JJ6	$**SZ
01\!	$**SD
34
|	% r    c                      t         t        g} t        j                  r| j	                  t
               | j	                  t               | S )z1Returns auth scopes based on user supplied flags.)_BIGQUERY_SCOPE_CLOUD_PLATFORM_SCOPEr%   enable_gdriveappend_GDRIVE_SCOPE_REAUTH_SCOPE)client_scopes    r   GetClientScopesFromFlagsr   <  s8    !#89,
&m$	r    c                      t         gS )z:Returns the scopes list for 3rd Party Identity Federation.)r   r   r    r   GetClientScopesFor3pir   E  s    
	  r    tagsc                    | j                         } | st        j                  d      i }| j                  d      D ]  }|j	                  d      \  }}}|j                         }|st        j                  d      |j                         }|st        j                  d      ||v rt        j                  d|z        |||<    |S )aB  Parses user-supplied string representing tags.

  Args:
    tags: A comma separated user-supplied string representing tags. It is
      expected to be in the format "key1:value1,key2:value2".

  Returns:
    A dictionary mapping tag keys to tag values.

  Raises:
    UsageError: Incorrect tags or no tags are supplied.
  zNo tags suppliedr   rl   Tag key cannot be NonezTag value cannot be None*Cannot specify tag key "%s" multiple times)r   r   rX   split
rpartition)r   	tags_dict	key_valuek_vs         r   	ParseTagsr   J  s     
$	
..+
,,)::c?i""3'GAq!		ANN344		ANN566I~NNG!KLLIaL # 
r    tag_keysc                 N   | j                         } | st        j                  d      t               }| j	                  d      D ]V  }|j                         }|st        j                  d      ||v rt        j                  d|z        |j                  |       X t        |      S )ac  Parses user-supplied string representing tag keys.

  Args:
    tag_keys: A comma separated user-supplied string representing tag keys.  It
      is expected to be in the format "key1,key2" or
      "tpczero-system:key1,tpczero-system:key2".

  Returns:
    A list of tag keys.

  Raises:
    UsageError: Incorrect tag_keys or no tag_keys are supplied.
  zNo tag keys suppliedr   r   r   )r   r   rX   setr   addlist)r   tags_setkeys      r   ParseTagKeysr   i  s     ^^(	
../
00U(^^C c
))+CNN344
hNNG#MNNLL ! 
hr    c                      d} t         j                  j                  d      dk(  r-dt         j                  j                  dt              z   dz   | z   S dt        z   dz   | z   S )zRReturns the user agent for BigQuery API requests based on environment and version.zgoogle-api-python-client (gzip)CLOUDSDK_WRAPPER1zgoogle-cloud-sdkCLOUDSDK_VERSIONru   zbq/)r'   r(   r)   r   )google_python_client_names    r   GetUserAgentr     sh    ?ZZ^^&'3.
**..+^
<	=
	 $	$ >!C'*CCCr    accountc                 2    t        j                  d|       duS )znReturns whether the account may be a service account based on the user-created or system-created account name.z!^.+@(.+)(\.gserviceaccount\.com)$N)re	fullmatch)r   s    r   IsServiceAccountr     s    	:G	DD	PPr    )r   Nr-   )r   );__doc__r   r'   r   rn   r   r   r   typingr   r   r   r   r   abslr   r	   google.authr
   ry   google.oauth2r   google_oauth2r   r   r   pyglibr   r%   r   r   r   r   r   strr   r   boolr!   IS_TPC_BINARYr*   r3   r6   rA   r=   r5   r`   r_   rj   rq   r   objectr   r   r   r   r   r   r   r   r    r   <module>r      sb   =  	   	 
  8 8   6 6     	7<H A  S " +d +
 x}  9# 9 9( 26!)#	#s(^2 
  # 	#s(^ FK8C= K$ KB
sm
!#
 c]
sm!# c](  -	
 c]3 /s /f BH	!()=!>6$s) !tCy !
C DcN >3 49 8Dc DQc Qd Qr    