
    l                     l   S 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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\R4                  5      r " S S\5      r " S S\5      r " S S\5      rS r " S S\5      r  " S S\5      r!S r"g)zManages the state of what is installed in the cloud SDK.

This tracks the installed modules along with the files they created.  It also
provides functionality like extracting tar files into the installation and
tracking when we check for updates.
    )absolute_import)division)unicode_literalsN)config)
exceptions)
console_io)
installers)	snapshots)encoding)filesc                       \ rS rSrSrSrg)Error/   z*Base exception for the local_state module. N)__name__
__module____qualname____firstlineno____doc____static_attributes__r       .lib/googlecloudsdk/core/updater/local_state.pyr   r   /   s    2r   r   c                   ,   ^  \ rS rSrSrU 4S jrSrU =r$ )InvalidSDKRootError4   zGError for when the root of the Cloud SDK is invalid or cannot be found.c                 ,   > [         [        U ]  S5        g )NzThe components management action could not be performed because the installation root of the Cloud SDK could not be located. If you previously used the Cloud SDK installer, you could re-install the SDK and retry again.)superr   __init__self	__class__s    r   r   InvalidSDKRootError.__init__7   s    	
t-	89r   r   r   r   r   r   r   r   r   __classcell__r!   s   @r   r   r   4   s    O9 9r   r   c                   ,   ^  \ rS rSrSrU 4S jrSrU =r$ )InvalidDownloadError?   z9Exception for when the SDK that was download was invalid.c                 ,   > [         [        U ]  S5        g )Nz#The Cloud SDK download was invalid.)r   r'   r   r   s    r   r   InvalidDownloadError.__init__B   s    	
.-/r   r   r#   r%   s   @r   r'   r'   ?   s    A/ /r   r'   c                   ,   ^  \ rS rSrSrU 4S jrSrU =r$ )PermissionsErrorG   zCError for when a file operation cannot complete due to permissions.c                 F   > [         [        U ]  SR                  XS95        g)zInitialize a PermissionsError.

Args:
  message: str, The message from the underlying error.
  path: str, The absolute path to a file or directory that needs to be
      operated on, but can't because of insufficient permissions.
zh{message}: [{path}]

Ensure you have the permissions to access the file and that the file is not in use.messagepathN)r   r,   r   format)r    r0   r1   r!   s      r   r   PermissionsError.__init__J   s&     

D*	0		+-r   r   r#   r%   s   @r   r,   r,   G   s    K- -r   r,   c                    ^  U 4S jnU$ )a'  Use this decorator for functions that deal with files.

If an exception indicating file permissions is raised, this decorator will
raise a PermissionsError instead, so that the caller only has to watch for
one type of exception.

Args:
  func: The function to decorate.

Returns:
  A decorator.
c                  z  >  T" U 0 UD6$ ! [         R                   ar  nUR                  S   S   n U S   R                  S5      (       aA  [        R
                  " [        U S   [        R                  R                  U S   5      S95        e S nAf[        [        4 a  nUR                  [        R                  :X  aw  [        R
                  " [        [        R                  " UR                   5      [        R                  " [        R                  R                  UR"                  5      5      S95        e S nAff = f)Nr      z
[Errno 13]r/   )shutilr   args
startswithr   reraiser,   osr1   abspathOSErrorIOErrorerrnoEACCESr   Decodestrerrorfilename)r8   kwargsefuncs      r   _TryFunc)_RaisesPermissionsError.<locals>._TryFuncf   s    4"6""<< 	VVAYq\d 
a		L	)	)T!W"$''//$q'":<	= W 	
ELL	  

3__RWW__QZZ%@AC	D s"    D:A-BD:BD55D:r   )rF   rG   s   ` r   _RaisesPermissionsErrorrI   X   s    ( 
/r   c                      \ rS rSrSr\R                  R                  rSr	Sr
SrSrSr\S 5       rS	 r\S
 5       r\S 5       r\S 5       r\S 5       rS r\S 5       r\S 5       rS"S jr\S"S j5       r\S"S j5       r\S 5       rS rS r\S"S j5       r \S"S j5       r!\S"S j5       r"\  S#S j5       r#\ S"S j5       r$\S"S j5       r%\S 5       r&S r'S$S  jr(S!r)g)%InstallationState}   z@The main class for checking / updating local installation state.z.backupz.trashz.stagingz.snapshot.json)zlib/third_party/grpcc                      [         R                  " 5       R                  n U (       d
  [        5       e[	        [
        R                  R                  U 5      5      $ )zGets the installation state for the SDK that this code is running in.

Returns:
  InstallationState, The state for this area.

Raises:
  InvalidSDKRootError: If this code is not running under a valid SDK.
)r   Pathssdk_rootr   rK   r;   r1   realpath)rO   s    r   
ForCurrentInstallationState.ForCurrent   s;     ||~&&H!!RWW--h788r   c                     U R                  5       (       d  g[        [        R                  R	                  U R
                  5      5      $ )zGets the installation state for the backup of this  state, if it exists.

Returns:
  InstallationState, The state for this area or None if the backup does not
      exist.
N)	HasBackuprK   r;   r1   rP   $_InstallationState__backup_directoryr    s    r   BackupInstallationState)InstallationState.BackupInstallationState   s4     >>RWW--d.E.EFGGr   c                      [         R                  5       n[        UR                  U 5      R	                  5       $ !   [
        R                  " SU [        R                  " 5       5         g= f)a  Gets the version string for the given installed component.

This function is to be used to get component versions for metrics reporting.
If it fails in any way or if the component_id is unknown, it will return
None.  This prevents errors from surfacing when the version is needed
strictly for reporting purposes.

Args:
  component_id: str, The component id of the component you want the version
    for.

Returns:
  str, The installed version of the component, or None if it is not
    installed or if an error occurs.
z8Failed to get installed version for component [%s]: [%s]N)	rK   rQ   InstallationManifest_state_directoryVersionStringloggingdebugsysexc_info)component_idstates     r   VersionForInstalledComponent.InstallationState.VersionForInstalledComponent   sY    "2**,e!

 
 ,00=@2mmN #,,.2s	   7: -A)c                    [         R                  R                  U5      (       d  [        SR	                  U5      5      e[
        R                  " U5      U l        [         R                  R                  U R                  [        R                  5      U l        [         R                  R                  U R                  [        R                  5      U l        [         R                  R                  U R                  [        R                  5      U l        [         R                  R!                  U R                  5      [        R"                  -   U l        [&        R(                  " U R                  U R                  5      U l        g)zInitializes the installation state for the given sdk install.

Args:
  sdk_root: str, The file path of the root of the SDK installation.

Raises:
  ValueError: If the given SDK root does not exist.
z.The given Cloud SDK root does not exist: [{0}]N)r;   r1   isdir
ValueErrorr2   r   rA   _InstallationState__sdk_rootjoinrK   STATE_DIR_NAMEr[   BACKUP_DIR_NAMErU   TRASH_DIR_NAME#_InstallationState__trash_directorynormpathSTAGING_ROOT_SUFFIX$_InstallationState__sdk_staging_rootr	   ComponentInstaller_component_installer)r    rO   s     r   r   InstallationState.__init__   s    77==""Gx(* * ooh/DOGGLL):)I)IKD ggll4+@+@+<+L+LNDWW\\$*?*?*;*J*JLD  "ww//@0DD ED * = =..!0Dr   c                     [         R                  R                  U R                  5      (       d!  [        R
                  " U R                  5        gg)z1Creates the state directory if it does not exist.N)r;   r1   rf   r[   
file_utilsMakeDirrV   s    r   _CreateStateDir!InstallationState._CreateStateDir   s6     77==..//../ 0r   c                     U R                   $ )zjGets the root of the SDK that this state corresponds to.

Returns:
  str, the path to the root directory.
)rh   rV   s    r   rO   InstallationState.sdk_root   s     ??r   c           	         [         R                  R                  U R                  5      (       d  / $ [         R                  " U R                  5      nU Vs/ s Hk  n[         R                  R                  [         R                  R                  U R                  U5      5      (       d  MQ  UR                  U5      (       d  Mi  UPMm     nnU$ s  snf )zReturns the files in the state directory that have the given suffix.

Args:
  suffix: str, The file suffix to match on.

Returns:
  list of str, The file names that match.
)r;   r1   rf   r[   listdirisfileri   endswith)r    suffixr   fmatchings        r   _FilesForSuffix!InstallationState._FilesForSuffix   s     77==..//iJJt,,-E  (5a77>>"'',,t/D/Da"HI JJv& 5H ( O(s   AC)CCc                     U R                  [        R                  5      n0 nU H8  nUS[        [        R                  5      *  n[	        U R
                  U5      X$'   M:     U$ )zGets all the components that are currently installed.

Returns:
  A dictionary of component id string to InstallationManifest.
N)r   rK   COMPONENT_SNAPSHOT_FILE_SUFFIXlenrZ   r[   )r    snapshot_files	manifestsr   ra   s        r   InstalledComponents%InstallationState.InstalledComponents   si     ))88:NIN.MMNNOl 4T5J5J5A!Ci  r   c                 @    [         R                  R                  U 5      $ )zFGenerates a ComponentSnapshot from the currently installed components.)r
   ComponentSnapshotFromInstallStaterV   s    r   SnapshotInstallationState.Snapshot	  s     &&77==r   Nc                 >    U R                  5       R                  UUS9$ )aZ  Generates a ComponentSnapshotDiff from current state and the given state.

Args:
  latest_snapshot:  snapshots.ComponentSnapshot, The current state of the
    world to diff against.
  platform_filter: platforms.Platform, A platform that components must
    match in order to be considered for any operations.

Returns:
  A ComponentSnapshotDiff.
)platform_filter)r   
CreateDiff)r    latest_snapshotr   s      r   DiffCurrentState"InstallationState.DiffCurrentState  s)     ==?%%o6E & G Gr   c                    U R                  5         [        R                  " 5        n[        R                  R                  US5      n[        R                  R                  US5      n[        R                  " USS/5      u  pg[        R                  " XUSS9n[        R                  " XUS9  [        R                  " U5      n	[        U	5      S:w  a
  [        5       e[        R                  R                  XYS   5      n
[        R                  " XR                  5        SSS5        [!        U R                  5      nUR#                  5         U R%                  U5        U$ ! , (       d  f       NF= f)	a  Creates a new staging area from a fresh download of the Cloud SDK.

Args:
  url: str, The url to download the new SDK from.
  progress_callback: f(float), A function to call with the fraction of
    completeness.

Returns:
  An InstallationState object for the new install.

Raises:
  installers.URLFetchError: If the new SDK could not be downloaded.
  InvalidDownloadError: If the new SDK was malformed.
z	.downloadz.extract   zcomponents.reinstallprogress_callbackcommand_pathr   r   N)_ClearStagingru   TemporaryDirectoryr;   r1   ri   r   SplitProgressBarr	   DownloadTar
ExtractTarr|   r   r'   MoveDirrp   rK   rw   CopyMachinePropertiesTo)r    urlr   tdownload_dirextract_dirdownload_callbackextract_callbackdownloaded_tarr   rO   staging_sdks               r   CreateStagingFromDownload+InstallationState.CreateStagingFromDownload  s     			&	&	(AWW\\![1lGGLLJ/k

%
%&7!Q
@ ,!--
/@-/n 
9IKjj%e	Uq"$$k84h#:#:; 
)  $D$;$;<K!  -) 
)	(s   C8E
E,c                    U R                  5         U R                  5         U R                  5         UR                  5         UR                  5         [        R                  " U R
                  UR                  5        U(       a  U" S5        [        R                  " UR
                  U R
                  5        U(       a	  U" S5        gg)ad  Replaces this installation with the given other installation.

This moves the current installation to the backup directory of the other
installation.  Then, it moves the entire second installation to replace
this one on the file system.  The result is that the other installation
completely replaces the current one, but the current one is snapshotted and
stored as a backup under the new one (and can be restored later).

Args:
  other_install_state: InstallationState, The other state with which to
    replace this one.
  progress_callback: f(float), A function to call with the fraction of
    completeness.
g      ?g      ?N)rw   ClearBackup
ClearTrashru   r   rh   rU   )r    other_install_stater   s      r   ReplaceWithInstallationState.ReplaceWithE  s      	OO'')##%t(;(N(NO*55tG r   c                    U R                  5       (       d  gU R                  5         [        R                  " U R                  U R
                  5        [        U R
                  5      nUR                  5         UR                  5         [        R                  " U R                  UR                  5        [        R                  " UR                  U R                  5        g)aF  Restore the backup from this install state if it exists.

If this installation has a backup stored in it (created by and update that
used ReplaceWith(), above), it replaces this installation with the backup,
using a temporary staging area.  This installation is moved to the trash
directory under the installation that exists after this is done.  The trash
directory can be removed at any point in the future.  We just don't want to
delete code that is running since some platforms have a problem with that.

Returns:
  bool, True if there was a backup to restore, False otherwise.
FT)rT   r   ru   r   rU   rp   rK   rw   r   rh   rm   )r    staging_states     r   RestoreBackupInstallationState.RestoreBackupc  s     >>t..0G0GH%d&=&=>M!!#t(G(GH}//Ar   c                 T    [         R                  R                  U R                  5      $ )zDetermines if this install has a valid backup that can be restored.

Returns:
  bool, True if there is a backup, False otherwise.
)r;   r1   rf   rU   rV   s    r   rT   InstallationState.HasBackup  s     77==0011r   c                 F    U R                  5       (       a  U R                  $ g)zGets the backup directory of this installation if it exists.

Returns:
  str, The path to the backup directory or None if it does not exist.
N)rT   rU   rV   s    r   BackupDirectory!InstallationState.BackupDirectory  s      ~~$$$r   c                     [         R                  R                  U R                  5      (       a   [        R
                  " U R                  5        U(       a	  U" S5        gg)zDeletes the current staging directory if it exists.

Args:
  progress_callback: f(float), A function to call with the fraction of
    completeness.
r   N)r;   r1   existsrp   ru   RmTreer    r   s     r   r   InstallationState._ClearStaging  sA     
ww~~d--..//0 r   c                     [         R                  R                  U R                  5      (       a   [        R
                  " U R                  5        U(       a	  U" S5        gg)zDeletes the current backup if it exists.

Args:
  progress_callback: f(float), A function to call with the fraction of
    completeness.
r   N)r;   r1   rf   rU   ru   r   r   s     r   r   InstallationState.ClearBackup  sA     
ww}}T,,--//0 r   c                     [         R                  R                  U R                  5      (       a   [        R
                  " U R                  5        U(       a	  U" S5        gg)zDeletes the current trash directory if it exists.

Args:
  progress_callback: f(float), A function to call with the fraction of
    completeness.
r   N)r;   r1   rf   rm   ru   r   r   s     r   r   InstallationState.ClearTrash  sA     
ww}}T++,,../ r   c                 |    U R                  5         UR                  U5      nU R                  R                  XSUS9nU$ )a  Downloads the given component based on the given snapshot.

Args:
  snapshot: snapshots.ComponentSnapshot, The snapshot that describes the
    component to install.
  component_id: str, The component to install from the given snapshot.
  progress_callback: f(float), A function to call with the fraction of
    completeness.
  command_path: the command path to include in the User-Agent header if the
    URL is HTTP

Returns:
  Optional[str], The path of the downloaded archive, or None if the
    component has no actual sources.

Raises:
  installers.URLFetchError: If the component associated with the provided
    component ID has a URL that is not fetched correctly.
r   )rw   ComponentFromIdrr   Download)r    snapshotra   r   r   	componentdownloaded_archives          r   r   InstallationState.Download  sJ    , 	((6I22;;! < # r   c                     U R                   R                  X4S9n[        U R                  U5      nUR	                  X5        g)a  Installs the archive previously downloaded from self.Download().

Args:
  snapshot: snapshots.ComponentSnapshot, The snapshot that describes the
    component to install.
  component_id: str, The component to install from the given snapshot.
  downloaded_archive: Optional[str], The path to the archive downloaded
    previously.
  progress_callback: f(float), A function to call with the fraction of
    completeness.
r   N)rr   ExtractrZ   r[   MarkInstalled)r    r   ra   r   r   r   manifests          r   InstallInstallationState.Install  sC     %%-- . AE#D$9$9<HH8+r   c                    [        U R                  U5      nUR                  5       n[        U5      nU R                  n[        5       n[        5       n[        USS9 GH  u  p[        R                  R                  Xj5      n[        R                  R                  U5      (       d%  [        R                  R                  U5      (       Ga4  [        R                  " U5        [        R                  R                  [        R                  R                  U
5      5      nU
R                  S5      (       an  US-   n[        R                  R                  U5      (       a  [        R                  " U5        UR!                  [        R                  R                  XlS5      5        U(       aV  UR!                  [        R                  R                  Xl5      5        [        R                  R                  U5      nU(       a  MV  OR[        R                  R#                  U5      (       a.  UR!                  [        R                  R                  U5      5        U(       d  GM  U" X-  5        GM     U He  n[        R                  R#                  U5      (       d  M)  [        R                  R                  U5      (       a  MO  [$        R&                  " U5        Mg     [)        U[        SS9 H  n[        R                  R#                  U5      (       d  M)  [        R                  R                  U5      (       a  MO  [        R*                  " U5      (       a  Ml  [        R,                  " U5        M     UR/                  5         g)	a  Uninstalls the given component.

Deletes all the files for this component and marks it as no longer being
installed.

Args:
  component_id: str, The id of the component to uninstall.
  progress_callback: f(float), A function to call with the fraction of
    completeness.
r   )startz.pyc__pycache__T)keyreverseN)rZ   r[   InstalledPathsr   rh   set	enumerater;   r1   ri   r}   islinkremovedirnamern   r~   addrf   ru   r   sortedr|   rmdirMarkUninstalled)r    ra   r   r   pathstotal_pathsrootdirs_to_removepycache_dirsnumpr1   dir_pathpyc_pathds                  r   	UninstallInstallationState.Uninstall  s+    $D$9$9<HH##%Ee*K??DUN5LE+WW\\$"d			!5!5
		$77??277#3#3A#67::e CZ(WW^^H%%IIh 

277<<F
G


RWW\\$9
:WW__X.( h 77==277++D12		#+,1 ,4 	q		"''.."3"3!  NT:	q		"''.."3"3BJJqMM
 ; r   c                     U R                    Hi  n[        R                  R                  U R                  U5      n[        R                  R                  U5      (       d  MS  [        R                  " U5        Mk     g)z=Clear deprecated directories that were not removed correctly.N)DEPRECATED_DIRSr;   r1   ri   rO   rf   ru   r   )r    r   r1   s      r   ClearDeprecatedDirs%InstallationState.ClearDeprecatedDirs"  sM     !!WW\\$--+d	t		$ "r   c                    [         R                  R                  U R                  [        R
                  R                  5      n[         R                  R                  UR                  [        R
                  R                  5      n[         R                  R                  U5      (       d  g[        R                  " X#5        g)a6  Copy this state's properties file to another state.

This is primarily intended to be used to maintain the machine properties
file during a schema-change-induced reinstall.

Args:
  other_state: InstallationState, The installation state of the fresh
      Cloud SDK that needs the properties file mirrored in.
N)
r;   r1   ri   rO   r   rN   CLOUDSDK_PROPERTIES_NAMEr   r7   copyfile)r    other_statemy_propertiesother_propertiess       r   r   )InstallationState.CopyMachinePropertiesTo*  st     GGLLv||<<>Mww||fllCCE77>>-((
OOM4r   c           
         [         R                  (       a  [        R                  " S5      nO^[        R
                  S   S:X  a  [        R                  " S5      nO0[        R
                  S   S:  a  [        R                  " S5      nOSn[        R                  " U R                  5         [        R                  R                  SS	5      [        R                  R                  S
S5      SS/nUc  [        [        R                  " 5       S5      OUnU H  n[        R                  " XcSXS9  M     SSS5        g! , (       d  f       g= f)aR  Attempts to compile all the python files into .pyc files.

Args:
  force: boolean, passed to force option of compileall.compiledir,
  workers: int, can be used to explicitly set number of worker processes;
    otherwise we determine it automatically. Only set for testing.

This does not raise exceptions if compiling a given file fails.
a(  (httplib2/python3|typing/python3|platform/bq/third_party/yaml/lib3|third_party/google/api_core|third_party/google/auth|third_party/google/oauth2|third_party/overrides|third_party/proto|dulwich|gapic|pubsublite|pubsub/lite_subscriptions.py|logging_v2|platform/bundledpythonunix|pubsub_v1/services)r      z.*   a
  (kubernetes/utils/create_from_yaml.py|platform/google_appengine|gslib/vendored/boto/boto/iam/connection.py|gslib/vendored/boto/tests/|third_party/.*/python2/|third_party/yaml/[a-z]*.py|third_party/yaml/lib2/|third_party/antlr3/|appengine/|google/cloud/appengine_|google/cloud/bigquery_logging_v1|third_party/fancy_urllib/|platform/bq/third_party/gflags|platform/ext-runtime/nodejs/test/|platform/gsutil/third_party/apitools/ez_setup|platform/gsutil/third_party/pyparsing|platform/gsutil/third_party/crcmod_osx/crcmod/test)Nbinbootstrappingdataclilibplatform   r6   )rxquietforceworkers)sixPY2recompiler_   version_inforu   ChDirrO   r;   r1   ri   min	cpu_count
compileallcompile_dir)r    r  r  regex_exclusion
to_compilenum_workersr   s          r   CompilePythonFiles$InstallationState.CompilePythonFiles<  s     ww

 $: ;o  
		!		!**T*A!#**CD& 
 
		$--	(
'',,uo
.
'',,vu
%

	j /6oC*7k!
 	%	N  
)	(	(s   +BD::
E)__backup_directory
__sdk_root__sdk_staging_root__trash_directoryrr   r[   )N)Nunknown)FN)*r   r   r   r   r   r   rN   CLOUDSDK_STATE_DIRrj   rk   rl   ro   r   r   staticmethodrQ   rW   rc   rI   r   rw   propertyrO   r   r   r   r   r   r   r   rT   r   r   r   r   r   r   r   r   r   r  r   r   r   r   rK   rK   }   s   H<<22./."#3 -/9 9	H  6 0 04 0 0
  $   > >G % %N  :  82 
 
 
 
 
 
 ?C% 8  $, ,$ 6 6p    5$KNr   rK   c                   F    \ rS rSrSrSrS rS rS rS r	S r
S	 rS
 rSrg)rZ   i  zDClass to encapsulate the data stored in installation manifest files.z	.manifestc                    Xl         X l        [        R                  R	                  U R                   U[
        R                  -   5      U l        [        R                  R	                  U R                   U[        R                  -   5      U l
        g)zCreates a new InstallationManifest.

Args:
  state_dir: str, The directory path where install state is stored.
  component_id: str, The component id that you want to get the manifest for.
N)	state_diridr;   r1   ri   rK   r   snapshot_filerZ   MANIFEST_SUFFIXmanifest_file)r    r   ra   s      r   r   InstallationManifest.__init__  sg     NG(GGGID +;;;=Dr   c                    [         R                  " U R                  5       n[        U5       H  nUR	                  US-   5        M     SSS5        UR                  U R                  U R                  S9  g! , (       d  f       N3= f)a^  Marks this component as installed with the given snapshot and files.

This saves the ComponentSnapshot and writes the installed files to a
manifest so they can be removed later.

Args:
  snapshot: snapshots.ComponentSnapshot, The snapshot that was the source
    of the install.
  files: list of str, The files that were created by the installation.

N)ra   )ru   
FileWriterr$  _NormalizeFileListwriteWriteToFiler"  r!  )r    r   r   fpr   s        r   r   "InstallationManifest.MarkInstalled  sf     
		t11	2b!%(!
T ) 
3 ++$''B 
3	2s   'A55
Bc                     U R                   U R                  4 H?  n[        R                  R	                  U5      (       d  M)  [        R
                  " U5        MA     g)zMarks this component as no longer being installed.

This does not actually uninstall the component, but rather just removes the
snapshot and manifest.
N)r$  r"  r;   r1   r}   r   )r    r   s     r   r   $InstallationManifest.MarkUninstalled  s=       $"4"45			
		! 6r   c                 T    [         R                  R                  U R                  5      $ )zvLoads the local ComponentSnapshot for this component.

Returns:
  The snapshots.ComponentSnapshot for this component.
)r
   r   FromFiler"  rV   s    r   r   &InstallationManifest.ComponentSnapshot  s!     &&//0B0BCCr   c                 T    U R                  5       R                  U R                  5      $ )zLoads the ComponentSnapshot and get the schemas.Component this component.

Returns:
  The schemas.Component for this component.
)r   r   r!  rV   s    r   ComponentDefinition(InstallationManifest.ComponentDefinition  s"     !!#33DGG<<r   c                 J    U R                  5       R                  R                  $ )zyGets the version string of this component as it was installed.

Returns:
  str, The installed version of this component.
)r4  versionversion_stringrV   s    r   r\   "InstallationManifest.VersionString  s     ##%--<<<r   c                     [         R                  " U R                  5       nU Vs/ s H  o"R                  5       PM     nnSSS5        U$ s  snf ! , (       d  f       W$ = f)zGets the list of files and dirs created by installing this component.

Returns:
  list of str, The files and directories installed by this component.
N)ru   
FileReaderr$  rstrip)r    r   liner   s       r   r   #InstallationManifest.InstalledPaths  sO     
		t11	2a)*+{{}e+ 
3L , 
3	2Ls   AAAA
A)r!  r$  r"  r   N)r   r   r   r   r   r#  r   r   r   r   r4  r\   r   r   r   r   r   rZ   rZ     s/    L/= C D==r   rZ   c                    [        / 5      n[        / 5      n[        / 5      nU  H  n[        R                  " U5      nUR                  S5      (       a  UR	                  US-   5        OUR	                  U5        [
        R                  R                  U5      nU(       d  M}  UR	                  US-   5        [
        R                  R                  U5      nU(       a  M<  M     [        X!-
  U-  5      $ )z=Removes non-empty directory entries and sorts resulting list./)	r   	posixpathrn   r~   r   r;   r1   r   r   )	file_listparent_directoriesdirectoriesr   r   norm_file_paths         r   r)  r)    s    2wB+
b'%a''*Nzz#oons*+iiWW__^4N
.^c12ww~6n .  
1U:	;;r   )#r   
__future__r   r   r   r  r?   r]   r;   rA  r	  r7   r_   googlecloudsdk.corer   r   googlecloudsdk.core.consoler   googlecloudsdk.core.updaterr	   r
   googlecloudsdk.core.utilr   r   ru   r  r   r   r'   r,   rI   objectrK   rZ   r)  r   r   r   <module>rL     s     '  '    	  	  
 & * 2 2 1 - 8 
J 
9% 9/5 /-u -""JJN JNZO6 Od<r   