
                         n    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mZ ddlm	Z	 ddl
Z
 G d	 d
e      Zy)z,A module for walking the Cloud SDK CLI tree.    )absolute_import)division)unicode_literals)Any)
console_io)progress_trackerNc                   :    e Zd ZdZ	 d	dZd Zd
dZd Zd Zd Z	y)Walkera=  Base class for walking the Cloud SDK CLI tree.

  Attributes:
    _roots: The root elements of the CLI tree that will be walked.
    _num_nodes: The total number of nodes in the tree.
    _num_visited: The count of visited nodes so far.
    _progress_callback: The progress bar function to call to update progress.
  Nc           	      N   |j                         }|r8|D cg c]  }| j                  ||       }}|D cg c]  }|s|	 c}| _        n|g| _        d| _        |rZt	        j
                  d      5  | j                  D ]+  }| xj                  d|j                  d|      z   z  c_        - 	 ddd       n:| j                  D ]+  }| xj                  d|j                  d|      z   z  c_        - d| _        |xs t        j                  | _
        yc c}w c c}w # 1 sw Y   4xY w)a  Constructor.

    Args:
      cli: The Cloud SDK CLI object.
      progress_callback: f(float), The function to call to update the progress
        bar or None for no progress bar.
      ignore_load_errors: bool, True to ignore command load failures. This
        should only be used when it is not critical that all data is returned,
        like for optimizations like static tab completion.
      restrict: Restricts the walk to the command/group dotted paths in this
        list. For example, restrict=['gcloud.alpha.test', 'gcloud.topic']
        restricts the walk to the 'gcloud topic' and 'gcloud alpha test'
        commands/groups. When provided here, any groups above the restrictions
        in the tree will not be loaded or visited.
    r   zLoading CLI Treeg      ?T)	recursiveignore_load_errorsN)_TopElement_GetSubElement_roots
_num_nodesr   ProgressTrackerLoadAllSubElements_num_visitedr   DefaultProgressBarCallback_progress_callback)	selfcliprogress_callbackr   restricttoprrootsroots	            %lib/googlecloudsdk/calliope/walker.py__init__zWalker.__init__'   s!   $ //
C4<=Hqt""3*He= %+1Q+dkEdkDO++,>?KKD
//S4#:#:1C $; $  /   @? ++$3!8!8/A "9 "
 
 	
 
 DBZBB 	' >+ @?s   DDD1;DD$c                 j    |j                  d      dd  }|}|D ]  }|j                  |      }|r y  |S )N.   )splitLoadSubElement)r   top_elementpathpartscurrentparts         r   r   zWalker._GetSubElementR   sB    JJsOABEG&&t,g  N    c                      dt         dt        fddfd	 fdd _        d} j                  D ]  } |d      }  j	                          |S )	a  Calls self.Visit() on each node in the CLI tree.

    The walk is DFS, ordered by command name for reproducability.

    Args:
      hidden: Include hidden groups and commands if True.
      universe_compatible: Exclusively include commands which are marked
        universe compatible.
      restrict: Restricts the walk to the command/group dotted paths in this
        list. For example, restrict=['gcloud.alpha.test', 'gcloud.topic']
        restricts the walk to the 'gcloud topic' and 'gcloud alpha test'
        commands/groups. When provided here, parent groups will still be visited
        as the walk progresses down to these leaves, but only parent groups
        between the restrictions and the root.

    Returns:
      The return value of the top level Visit() call.
    commandreturnc                 H    t        | t               xr | j                         S )zDetermines if a command is universe compatible.

      Args:
        command: CommandCommon command node.

      Returns:
        True if command is universe compatible.
      )
isinstancedictIsUniverseCompatible)r-   s    r   _IsUniverseCompatiblez*Walker.Walk.<locals>._IsUniverseCompatibleo   s"     GT**O0L0L0NOr+   c                     s| j                         ryr	 |       sysydj                  | j                               }D ]+  }|j                  |      r y|s|j                  |      s+ y y)a  Determines if command should be included in the walk.

      Args:
        command: CommandCommon command node.
        traverse: If True then check traversal through group to subcommands.

      Returns:
        True if command should be included in the walk.
      FTr"   )IsHiddenjoinGetPath
startswith)r-   traverser'   itemr3   hiddenr   universe_compatibles       r   _IncludezWalker.Walk.<locals>._Includez   sn     ((*	%:7%CXXgoo'(d$??4 -	 
 r+   c                 $   | j                   s	j                  | |d       |S 	j                  | |d      }g }| j                  rDt        j                  | j                        D ]"  \  }} |      s|j                  ||df       $ | j                  rFt        j                  | j                        D ]$  \  }} |d      s|j                  ||df       & t        |      D ]&  \  }}}|r
 ||       	j                  ||d       ( |S )a
  Walk() helper that calls self.Visit() on each node in the CLI tree.

      Args:
        node: CommandCommon tree node.
        parent: The parent Visit() return value, None at the top level.

      Returns:
        The return value of the outer Visit() call.
      F)is_groupT)r9   )r?   _Visitcommandssix	iteritemsappendgroupssorted)
nodeparentcommands_and_groupsnamer-   _r?   r=   _Walkr   s
          r   rL   zWalker.Walk.<locals>._Walk   s     ]]D&51{{4${7f	 ]]4==9MD'g&&gu'=> : 
 ]]4;;7MD'g-&&gt'<= 8 #))<"=
!Wh

 
++gv+
6	 #>
 mr+   r   N)F)r   boolr   r   Done)	r   r;   r<   r   rH   r   r=   r3   rL   s	   ````  @@@r   WalkzWalker.Walk[   s`    (	Ps 	Pt 	P 0@ DFT4 f IIKMr+   c                     | xj                   dz  c_         | j                  | j                   | j                  z         | j                  |||      S )Nr#   )r   r   r   Visitr   rG   rH   r?   s       r   r@   zWalker._Visit   sC    D--@A::dFH--r+   c                      y)a  Visits each node in the CLI command tree.

    Called preorder by WalkCLI() using DFS.

    Args:
      node: group/command CommandCommon info.
      parent: The parent Visit() return value, None at the top level.
      is_group: True if node is a group, otherwise its is a command.

    Returns:
      A new parent value for the node subtree. This value is the parent arg
      for the Visit() calls for the children of this node.
    N rR   s       r   rQ   zWalker.Visit   s     	r+   c                      y)z<Cleans up after all nodes in the CLI tree have been visited.NrT   )r   s    r   rN   zWalker.Done   s    r+   )NFN)FFN)
__name__
__module____qualname____doc__r    r   rO   r@   rQ   rN   rT   r+   r   r
   r
      s/     MQ)V\|.
	 	r+   r
   )rY   
__future__r   r   r   typingr   googlecloudsdk.core.consoler   r   rB   objectr
   rT   r+   r   <module>r^      s-     3 &  '  2 8 
s	V s	r+   