(self, path_to_tree, path_replacements, list_replacements,
                       variables, package, file_filter=None)
Walk a file tree and copy files or process templates.

    Walks a file tree to write on output package, running all files ending in
    ".tmpl" through the template renderer, and directly copying all the other
    files. While doing so, the caller may provide for some transformations of
    the file path:
    1. They can pass in a dictionary of string literals to replacements which
       are applied directly to the file path. E.g. '___package___' might be
       replaced by a path snippet of the form 'com/google/tasks'
    2. They can pass a dictionary of strings literals which, if found in the
       file path trigger the evaluation of thats template against a list of
       CodeObjects, with a distinct output file being generated for each object.
       E.g. The ApiLibraryGenerator uses the pattern  '___models_className___'
       to generate a set of files, each named by its className member.

    Args:
      path_to_tree: (str) path relative to the language template directory.
      path_replacements: (dict) dict holding elements which should be replaced
        if found in a path.
      list_replacements: (dict) dict holding elements which should be replaced
        by many files when found in a path. The keys of the dict are strings
        to be found in a path. The values are a tuple of
           (name_to_bind, [list of code objects])
        where name_to_bind is a variable name which will be bound to each
        successive code object during template evaluation. See the
        GenerateListOfFiles method for more details about name expansion.
      variables: (dict) The dictionary of variable replacements to pass to the
         templates.
      package: (LibraryPackage) output package.
      file_filter: (func) method to allow the caller to filter files included
         by name. The method is called with 2 arguments, the template file path
         and the path after all path replacements are done.
Walk a file tree and copy files or process templates.
Walk a file tree and copy files or process templates .
def WalkTemplateTree(self, path_to_tree, path_replacements, list_replacements,
                       variables, package, file_filter=None):
    """Walk a file tree and copy files or process templates.

    Walks a file tree to write on output package, running all files ending in
    ".tmpl" through the template renderer, and directly copying all the other
    files. While doing so, the caller may provide for some transformations of
    the file path:
    1. They can pass in a dictionary of string literals to replacements which
       are applied directly to the file path. E.g. '___package___' might be
       replaced by a path snippet of the form 'com/google/tasks'
    2. They can pass a dictionary of strings literals which, if found in the
       file path trigger the evaluation of thats template against a list of
       CodeObjects, with a distinct output file being generated for each object.
       E.g. The ApiLibraryGenerator uses the pattern  '___models_className___'
       to generate a set of files, each named by its className member.

    Args:
      path_to_tree: (str) path relative to the language template directory.
      path_replacements: (dict) dict holding elements which should be replaced
        if found in a path.
      list_replacements: (dict) dict holding elements which should be replaced
        by many files when found in a path. The keys of the dict are strings
        to be found in a path. The values are a tuple of
           (name_to_bind, [list of code objects])
        where name_to_bind is a variable name which will be bound to each
        successive code object during template evaluation. See the
        GenerateListOfFiles method for more details about name expansion.
      variables: (dict) The dictionary of variable replacements to pass to the
         templates.
      package: (LibraryPackage) output package.
      file_filter: (func) method to allow the caller to filter files included
         by name. The method is called with 2 arguments, the template file path
         and the path after all path replacements are done.
    """

    def ExpandZipFile(path):
      """Expand a zip file found in the template tree.

      Args:
        path: Path to file, relative to top of template tree.
      """
      full_path = os.path.join(self._template_dir, path)
      zip_slurp = files.GetFileContents(full_path)
      archive = zipfile.ZipFile(StringIO.StringIO(zip_slurp), 'r')
      for info in archive.infolist():
        package.WriteDataAsFile(
            archive.read(info.filename),
            os.path.join(relative_path, info.filename))

    top_of_tree = os.path.normpath(
        os.path.join(self._template_dir, path_to_tree))
    # Walk tree for jar files to directly include
    variables.update({'template_dir': top_of_tree})
    for path in files.IterFiles(top_of_tree):
      root, file_name = os.path.split(path)
      template_path = file_name
      relative_path = root[len(top_of_tree) + 1:]

      # Perform the replacements on the path and file name
      for path_item, replacement in path_replacements.iteritems():
        relative_path = relative_path.replace(path_item, replacement)
      for path_item, replacement in path_replacements.iteritems():
        file_name = file_name.replace(path_item, replacement)
      full_template_path = os.path.join(relative_path, template_path)

      for path_item, call_info in list_replacements.iteritems():
        if file_name.find(path_item) >= 0:
          self.GenerateListOfFiles(path_item, call_info, path, relative_path,
                                   file_name, variables, package,
                                   file_filter=file_filter)

      if file_name.startswith('___unzip___'):
        # TODO(user) Doesn't account for changes to relative_path above.
        ExpandZipFile(path)
        continue
      if file_name.startswith('_'):
        continue
      if file_name.endswith('.tmpl'):
        name_in_zip = file_name[:-5]  # strip '.tmpl'
        if name_in_zip in _SPECIAL_FILENAMES:
          name_in_zip = name_in_zip.replace('_', '.')
        full_output_path = os.path.join(relative_path, name_in_zip)
        if file_filter and not file_filter(full_template_path,
                                           full_output_path):
          continue
        self.RenderTemplateToFile(path, variables, package, full_output_path)
      else:
        full_output_path = os.path.join(relative_path, file_name)
        if file_filter and not file_filter(full_template_path,
                                           full_output_path):
          continue
        package.IncludeFile(path, full_output_path)
def WalkTemplateTree ( self , path_to_tree , path_replacements , list_replacements , variables , package , file_filter = None ) : def ExpandZipFile ( path ) : """Expand a zip file found in the template tree.

      Args:
        path: Path to file, relative to top of template tree.
      """ full_path = os . path . join ( self . _template_dir , path ) zip_slurp = files . GetFileContents ( full_path ) archive = zipfile . ZipFile ( StringIO . StringIO ( zip_slurp ) , 'r' ) for info in archive . infolist ( ) : package . WriteDataAsFile ( archive . read ( info . filename ) , os . path . join ( relative_path , info . filename ) ) top_of_tree = os . path . normpath ( os . path . join ( self . _template_dir , path_to_tree ) ) # Walk tree for jar files to directly include variables . update ( { 'template_dir' : top_of_tree } ) for path in files . IterFiles ( top_of_tree ) : root , file_name = os . path . split ( path ) template_path = file_name relative_path = root [ len ( top_of_tree ) + 1 : ] # Perform the replacements on the path and file name for path_item , replacement in path_replacements . iteritems ( ) : relative_path = relative_path . replace ( path_item , replacement ) for path_item , replacement in path_replacements . iteritems ( ) : file_name = file_name . replace ( path_item , replacement ) full_template_path = os . path . join ( relative_path , template_path ) for path_item , call_info in list_replacements . iteritems ( ) : if file_name . find ( path_item ) >= 0 : self . GenerateListOfFiles ( path_item , call_info , path , relative_path , file_name , variables , package , file_filter = file_filter ) if file_name . startswith ( '___unzip___' ) : # TODO(user) Doesn't account for changes to relative_path above. ExpandZipFile ( path ) continue if file_name . startswith ( '_' ) : continue if file_name . endswith ( '.tmpl' ) : name_in_zip = file_name [ : - 5 ] # strip '.tmpl' if name_in_zip in _SPECIAL_FILENAMES : name_in_zip = name_in_zip . replace ( '_' , '.' ) full_output_path = os . path . join ( relative_path , name_in_zip ) if file_filter and not file_filter ( full_template_path , full_output_path ) : continue self . RenderTemplateToFile ( path , variables , package , full_output_path ) else : full_output_path = os . path . join ( relative_path , file_name ) if file_filter and not file_filter ( full_template_path , full_output_path ) : continue package . IncludeFile ( path , full_output_path )