
    \                     8   S r SSKJr  SSKJr  SSKJr  SSKJr  SSKrSSKrSSKrSSK	r	SSK
r
SSKrSSKrSSKrSSKJr  SSKrSSKJr  SS	KJr  SSKrSS
KJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKrSSKJ r   SSKJ!r!  SSKJ"r"  SSK#J$r$  SSK%J&r&  SSK'J(r(  SSK)J*r*  SSK+J,r,  SSK-J.r.  SSK-J/r/  SSK-J0r0  SSK1J2r2  SSK1J3r3  SSK4J5r5  SSK6J7r7  SS K8J9r9  SS!K8J:r:  SS"K8J;r;  SS#K8J<r<  SS$K=J>r>  SS%K?J@r@  SS&K?JArA  S' rBS( rCS) rD " S* S+\E5      rFg),z'Class that runs a named gsutil command.    )absolute_import)print_function)division)unicode_literalsN)input)config)BucketStorageUri)metrics)CloudApiDelegator)CommandCreateOrGetGsutilLogger)GetFailureCount)OLD_ALIAS_MAP)ShutDownGsutil)ApiSelector)GsutilApiClassMapFactory)GsutilApiMapFactory)DiscardMessagesQueue)CommandException)
GcsJsonApi)NoOpCredentials)MakeCompleter)	boto_util)	shim_util)system_util)RELEASE_NOTES_URL)UTF8)IsCustomMetadataHeader)$CheckMultiprocessingAvailableAndInit)CompareVersions)InsistAsciiHeader)InsistAsciiHeaderValue)print_to_fd)SECONDS_PER_DAY)LookUpGsutilVersion)GsutilPubTarballc                    U (       d  gU  Hk  n[        U5        [        U5      (       a?  [        X   [        R                  5      (       d   X   R                  [        5      X'   M[  M]  [        XU   5        Mm     g! [         aL    [        SR                  [        R                  " S[        U5      < S[        X   5      < S35      5      5      ef = f)a  Handles coding of headers and their values. Alters the dict in-place.

Converts a dict of headers and their values to their appropriate types. We
ensure that all headers and their values will contain only ASCII characters,
with the exception of custom metadata header values; these values may contain
Unicode characters, and thus if they are not already unicode-type objects,
we attempt to decode them to Unicode using UTF-8 encoding.

Args:
  headers: A dict mapping headers to their values. All keys and values must
      be either str or unicode objects.

Raises:
  CommandException: If a header or its value cannot be encoded in the
      required encoding.
N
z#Invalid encoding for header value (z: z). Values must be decodable as Unicode. NOTE: the value printed above replaces the problematic characters with a hex-encoded printable representation. For more details (including how to convert to a gsutil-compatible encoding) see `gsutil help encoding`.)r"   r   
isinstancesix	text_typedecoder   UnicodeDecodeErrorr   jointextwrapwrapreprr#   )headerskeys     'platform/gsutil/gslib/command_runner.pyHandleHeaderCodingr6   D   s    " 

ccc""cmm44
	D ,,T2', 5 S#,/#  " 	D mm #'s)T',-?AB"C D D	Ds   A;;ACc                 D   [        [        U 5      5       H@  nX   n[        U[        R                  5      (       a  M(   UR                  [        5      X'   MB     g! [         a;    [        SR                  [        R                  " S[        U5      -  5      5      5      ef = f)zHandles coding of command-line args. Alters the list in-place.

Args:
  args: A list of command-line args.

Raises:
  CommandException: if errors encountered.
r)   a%  Invalid encoding for argument (%s). Arguments must be decodable as Unicode. NOTE: the argument printed above replaces the problematic characters with a hex-encoded printable representation. For more details (including how to convert to a gsutil-compatible encoding) see `gsutil help encoding`.N)rangelenr*   r+   r,   r-   r   r.   r   r/   r0   r1   r2   )argsiargs      r5   HandleArgCodingr=   l   s     Ta
'Cc3==))
**T"	 
   tyyMMJ
 S	   	s   AABc                 Z    [         R                  (       a  U R                  [        5      $ U $ )zDConverts a string literal (unicode) to the same type as sys.argv[0].)r+   PY2encoder   )unicode_strs    r5   _StringToSysArgTyperB      s"     	WWd##	    c                   x    \ rS rSrSr\\S4S jrS rS r	S r
S rS	 r           SS
 jrS rS rS rSrg)CommandRunner   z?Runs gsutil commands and does some top-level argument handling.Nc                 b    Xl         X l        U(       a  X0l        gU R                  5       U l        g)a  Instantiates a CommandRunner.

Args:
  bucket_storage_uri_class: Class to instantiate for cloud StorageUris.
                            Settable for testing/mocking.
  gsutil_api_class_map_factory: Creates map of cloud storage interfaces.
                                Settable for testing/mocking.
  command_map: Map of command names to their implementations for
               testing/mocking. If not set, the map is built dynamically.
N)bucket_storage_uri_classgsutil_api_class_map_factorycommand_map_LoadCommandMap)selfrH   rI   rJ   s       r5   __init__CommandRunner.__init__   s*     %=!(D%$--/drC   c                 @   [         R                  " [        R                  R                  5       H  u  pn[        SU-  5        M     0 n[        R                  " 5        H<  nXCUR                  R                  '   UR                  R                   H  nXCU'   M	     M>     U$ )z=Returns dict mapping each command_name to implementing class.zgslib.commands.%s)pkgutiliter_modulesgslibcommands__path__
__import__r   __subclasses__command_speccommand_namecommand_name_aliases)rL   _module_namerJ   commandrY   s         r5   rK   CommandRunner._LoadCommandMap   s     %11%..2I2IJ${23 K K))+7>'&&334")"6"6"K"K
,3() #L , rC   c                     [        S5      $ )z$Returns a logger for tab completion.tab_completer   )rL   s    r5   _GetTabCompleteLogger#CommandRunner._GetTabCompleteLogger   s    ">22rC   c                   ^ ^^^^ T R                  5       mUUU4S jnUUUU U4S jn[        T[        5      (       a  U" 5         g[        T[        5      (       a  U" 5         gSn[	        UR                  T[        T5      5      5      e)a  Creates parsers recursively for potentially nested subcommands.

Args:
  parser: argparse parser object.
  subcommands_or_arguments: list of CommandArgument objects, or recursive
      dict with subcommand names as keys.
  gsutil_api: gsutil Cloud API instance to use.

Raises:
  RuntimeError: if argument is configured with unsupported completer
  TypeError: if subcommands_or_arguments is not a dict or list

c                     > T HW  n TR                   " U R                  0 U R                  D6nU R                  (       d  M<  [	        U R                  T5      Ul        MY     g )N)add_argumentr:   kwargs	completerr   )command_argumentaction
gsutil_apiparsersubcommands_or_argumentss     r5   
HandleListJCommandRunner._ConfigureCommandArgumentParserArguments.<locals>.HandleList   s\    6
$$&6&;&; @'7'>'>@%%%*+;+E+E+57&
	 7rC   c                     > TR                  5       n TR                  5        HH  u  pU R                  USS9nTR                  SR	                  U5      5        TR                  UUT5        MJ     g )NF)add_helpz$Constructing argument parsers for {})add_subparsersitems
add_parserinfoformat(_ConfigureCommandArgumentParserArguments)	
subparserssubcommand_namesubcommand_valuecur_subcommand_parserri   loggerrj   rL   rk   s	       r5   
HandleDictJCommandRunner._ConfigureCommandArgumentParserArguments.<locals>.HandleDict   sw    ((*j/G/M/M/O
+/ * 5 5o?D !6 !F299/J	L556K6F6@	B 0PrC   zAsubcommands_or_arguments {} should be list or dict, found type {}N)r`   r*   listdict	TypeErrorrt   type)rL   rj   rk   ri   rl   r{   error_formatrz   s   ````   @r5   ru   6CommandRunner._ConfigureCommandArgumentParserArguments   sz      '')F7	B 	B *D11l	,d	3	3l&l


6"#;<>? ?rC   c                 H   [         R                  [         R                  /[         R                  /S.n[         R                  [         R                  S.n[        R                  " U R
                  X5      n[        U R                  UU R                  5       [        5       SS9nU$ )zlBuilds and returns a gsutil_api based off gsutil_api_class_map_factory.

Returns:
  the gsutil_api instance
)gss3r   )debug)
r   XMLJSONr   	GetApiMaprI   r   rH   r`   r   )rL   support_mapdefault_mapgsutil_api_mapri   s        r5   GetGsutilApiForTabComplete(CommandRunner.GetGsutilApiForTabComplete   s      0 01K %))AK(22));EN #4#@#@#1#'#=#=#?#7#9)*	,J
 rC   c                     U R                  5       nU R                  R                  5        Vs0 s H.  nUR                  R                  UR                  R
                  _M0     nnU R                  XU5        gs  snf )zConfigures argparse arguments and argcomplete completers for commands.

Args:
  main_parser: argparse object that can be called to get subparsers to add
  subcommands (called just 'commands' in gsutil)
N)r   rJ   valuesrW   rX   argparse_argumentsru   )rL   main_parserri   r\   command_to_argparse_argumentss        r5   ConfigureCommandArgumentParsers-CommandRunner.ConfigureCommandArgumentParsers   s     002J ''..0% 1G 	))  33	40 " %0 	11J@1%s   5A7c                 4   SnU(       d\  U R                  X5      (       aF  SnSn[        S5      /n[        R                  " 5       (       a  U(       a  [        R
                  " 5         U R                  U5        U(       d  / n[        R                  R                  SSS5      nU(       d  0 nXS'   XR                  ;  a  [        R                  " UU R                  R                  5       S	S
9nU(       aQ  [        R                  " US   U5      S   n[!        S["        R$                  S9  [!        SU-  ["        R$                  S9  O:US:X  a4  [&        R(                  (       a  ["        R$                  R+                  S5        [-        SU-  5      e[        S5      U;   a\  U/nU R                  U   nUR.                  R0                  R                  5       nU H  nUU;   d  M  UR3                  U5          O   UnSn[5        U5        [7        U5        U R                  U   nU" U UUUUUU R8                  U R:                  UUU
US9nU(       a*  [        R<                  " UR>                  UR@                  US9  URC                  5       (       a  URE                  5       nOURG                  5       n[I        5       RJ                  (       a  U	(       a
  [M        5         [O        5       S:  a  S	nU(       a0  S	n[!        SRQ                  [R        RT                  " S5      5      5        U$ )a5  Runs the named command.

Used by gsutil main, commands built atop other commands, and tests.

Args:
  command_name: The name of the command being run.
  args: Command-line args (arg0 = actual arg, not command name ala bash).
  headers: Dictionary containing optional HTTP headers to pass to boto.
  debug: Debug level to pass in to boto connection (range 0..3).
  trace_token: Trace token to pass to the underlying API.
  parallel_operations: Should command operations be executed in parallel?
  skip_update_check: Set to True to disable checking for gsutil updates.
  logging_filters: Optional list of logging.Filters to apply to this
      command's logger.
  do_shutdown: Stop all parallelism framework workers iff this is True.
  perf_trace_token: Performance measurement trace token to pass to the
      underlying API.
  user_project: The project to bill this request to.
  collect_analytics: Set to True to collect an analytics metric logging this
      command.

Raises:
  CommandException: if errors encountered.

Returns:
  Return value(s) from Command that was run.
FupdateTz-nGSUtildefault_api_version1zx-goog-api-version   )nr   zDid you mean this?)filez	%szgUpdate command is not supported for package installs; please instead update using your package manager.zInvalid command "%s".z--helphelp)command_alias_usedperf_trace_tokenuser_project)rX   sub_optscommand_aliasr)   zUpdate was successful. Exiting with code 1 as the original command issued prior to the update was not executed and should be re-run.)+#MaybeCheckForAndOfferSoftwareUpdaterB   r   IsRunningInteractivelyr
   'CheckAndMaybePromptForAnalyticsEnablingMaybePromptForPythonUpdatebotor   	get_valuerJ   difflibget_close_matcheskeysr   getprintsysstderrrR   IS_PACKAGE_INSTALLwriter   	help_specsubcommand_help_textappendr=   r6   rH   rI   LogCommandParamsrX   r   (translate_to_gcloud_storage_if_requestedrun_gcloud_storage
RunCommandr    is_availabler   r   r/   r0   r1   )rL   rX   r:   r3   r   trace_tokenparallel_operationsskip_update_checklogging_filtersdo_shutdownr   r   collect_analyticscommand_changed_to_updateapi_versionclose_matchestranslated_command_namenew_argsoriginal_command_classsubcommandsr<   command_classcommand_instreturn_codes                           r5   RunNamedCommandCommandRunner.RunNamedCommand'  s   P !&00EEl"&!$'(d 
	+	+	-	-2C779##L1d ++''2GMKg$/ !+++//040@0@0E0E0G235m 
 $1#4#4]15E5B$DDE$G"4f..SZZ@8#(@(@

@	A 4|CDD 8$,h#//=*44IINNPk#+
//#

  dlDw$$\2M !%!(!&!,!4!%!>!>!%!B!B!04@2B.:<L" L,E,E(4(=(=-9; <<>> !335k !++-k+-::{1k  kDII
--R 
 rC   c                     [         R                  " 5       n[        R                  " 5       (       a>  UR	                  [         R
                  5      (       a  [        R                  " 5       (       a  gg)a  Helper function that will determine if update checks should be skipped.

Args:
  command_name: The name of the command being run.

Returns:
  True if:
  - gsutil is not connected to a tty (e.g., if being run from cron);
  - user is running gsutil -q
  - user specified gs_host (which could be a non-production different
    service instance, in which case credentials won't work for checking
    gsutil tarball).TF)logging	getLoggerr   r   isEnabledForINFOr   HasUserSpecifiedGsHost)rL   rz   s     r5   SkipUpdateCheckCommandRunner.SkipUpdateCheck  sK      F..00--((**rC   c                     [         R                  R                  S:w  dA  U R                  5       (       d,  US;  d&  [        R
                  R                  SSS5      (       a  g[        S5        g)zAlert the user that they should install Python 3.

Args:
  command_name: The name of the command being run.

Returns:
  True if a prompt was output.
   )r   verversionr   skip_python_update_promptFzxGsutil 5 drops Python 2 support. Please install Python 3 to update to the latest version of gsutil. https://goo.gle/py3
T)r   version_infomajorr   r   r   getboolr$   )rL   rX   s     r5   r   (CommandRunner.MaybePromptForPythonUpdate  sb     	!#t';';'='=88H&A5II 	AB rC   c                    [         R                  " 5       nU R                  5       (       d   US;   d  [        R                  " 5       (       a  g[
        R                  R                  SSS5      nUS:X  a  g[        R                  " 5       n[        [        R                  " 5       5      n[        R                  R                  U5      (       dE  [        R                   " 5       n[#        US5       nUR%                  ['        U5      5        SSS5        O/ [#        US	5       n[        UR)                  5       5      nSSS5        UW-
  U[.        -  :  Ga  [1        U R2                  U[5        5       [7        5       US
9n	[        R8                  n
 [;        U	[=        5       5      n
[#        US5       nUR%                  ['        U5      5        SSS5        [A        U
[        R8                  5      u  pU(       a  [C        SRE                  [F        RH                  " SU
< S[        R8                  < S[J        < S35      5      5        [        RL                  (       a  g[C        S5        [O        S5      nU=(       a    URQ                  5       S   S:H  $ U(       a  [C        SRE                  [F        RH                  " SU
< S[        R8                  < S[J        < S35      5      5        [        RL                  (       a  g[C        S5        [O        S5      nU(       + =(       d    URQ                  5       S   S:g  $ g! , (       d  f       GN= f! , (       d  f       GN= f! [*        [,        4 a     gf = f! [>         a     gf = f! , (       d  f       GN= f)at  Checks the last time we checked for an update and offers one if needed.

Offer is made if the time since the last update check is longer
than the configured threshold offers the user to update gsutil.

Args:
  command_name: The name of the command being run.
  debug: Debug level to pass in to boto connection (range 0..3).

Returns:
  True if the user decides to update.
)r   r   r   r   Fr   software_update_check_period   r   wNr)credentialsr   r)   zA newer version of gsutil (z1) is available than the version you are running (zp). NOTE: This is a major new version, so it is strongly recommended that you review the release note details at zJ before updating to this version, especially if you use gsutil in scripts.z Would you like to update [y/N]? yz<). A detailed log of gsutil release changes is available at z0 if you would like to read them before updating.z Would you like to update [Y/n]? r   ))r   r   r   r   InvokedViaCloudSdkr   r   getintr   *GetLastCheckedForGsutilUpdateTimestampFileinttimeospathisfilerR   GetGsutilVersionModifiedTimeopenr   strreadliner   
ValueErrorr%   r   rH   r   r   VERSIONr&   r'   	Exceptionr!   r$   r/   r0   r1   r   r   r   lower)rL   rX   r   rz   r   -last_checked_for_gsutil_update_timestamp_filecur_tslast_checked_tsfri   cur_vergmanswers                 r5   r   1CommandRunner.MaybeCheckForAndOfferSoftwareUpdate  s   6  F>>&&((#';;#5#50"$6  $q( 	<<> 2 F77>>GHH ::<o=sCq	O$% DC?E

-/ F
 	 
&
8	9 d;;$24*9*;$)	+j g%j2B2DE =sCq	F Dw6fq	
DIIMM
 ")%--9J	LMN 	O ##D9:2&,,.+s22DIIMM EMM+<>?@ 	A ##D9:z5V\\^A.#55k DC FE$     DCsZ   ,L+M L=7M M% (M5+
L:=
MM M M"!M"%
M21M25
N)rH   rJ   rI   )NNr   NFFNTNNF)__name__
__module____qualname____firstlineno____doc__r	   r   rM   rK   r`   ru   r   r   r   r   r   r   __static_attributes__ rC   r5   rE   rE      sk    G )9,D0*3.?`,%@R  ""&*/(-&*"&'+#'(-M^((frC   rE   )Gr  
__future__r   r   r   r   r   r   r   rP   r   r0   r   r+   	six.movesr   r   r   boto.storage_urir	   rR   r
   gslib.cloud_api_delegatorr   gslib.commandr   r   r   r   r   gslib.commandsgslib.cs_api_mapr   r   r   gslib.discard_messages_queuer   gslib.exceptionr   gslib.gcs_json_apir   gslib.no_op_credentialsr   gslib.tab_completer   gslib.utilsr   r   r   gslib.utils.constantsr   r   gslib.utils.metadata_utilr   &gslib.utils.parallelism_framework_utilr    gslib.utils.text_utilr!   r"   r#   r$   gslib.utils.unit_utilr%   gslib.utils.update_utilr&   r'   r6   r=   rB   objectrE   r  rC   r5   <module>r     s    . & %  '   	  
   
    -   7 ! 1 ) ' (  ( 5 0 = , ) 3 , ! ! # 3 & < W 1 3 8 - 1 7 4%0P6tF trC   