#!/usr/bin/python2.4 # Copyright 2009, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following disclaimer # in the documentation and/or other materials provided with the # distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """Publish tool for SCons.""" # List of published resources. This is a dict indexed by group name. Each # item in this dict is a dict indexed by resource type. Items in that dict # are lists of files for that resource. __published = {} #------------------------------------------------------------------------------ class PublishItem(object): """Item to be published.""" def __init__(self, source, subdir): """Initialize object. Args: source: Source node. subdir: If not None, subdirectory to copy node into in ReplicatePublished(). """ object.__init__(self) self.source = source self.subdir = subdir #------------------------------------------------------------------------------ def _InitializePublish(env): """Re-initializes published resources. Args: env: Parent environment """ env=env # Silence gpylint # Clear the dict of published resources __published.clear() def ReplicatePublished(self, target, group_name, resource_type): """Replicate published resources for the group to the target directory. Args: self: Environment in which this function was called. target: Target directory for resources. group_name: Name of resource group, or a list of names of resource groups. resource_type: Type of resources (string), or a list of resource types. Uses the subdir parameter passed to Publish() when replicating source nodes to the target. Returns: The list of target nodes from the calls to Replicate(). Since this is based on Replicate(), it will also use the REPLICATE_REPLACE variable, if it's set in the calling environment. """ target_path = self.Dir(target).abspath #GOOGLE_CHANGE(pss) - FROM THIS: #GOOGLE_CHANGE(pss) - TO THIS: source_list = self.GetPublishedWithSubdirs(group_name, resource_type) #GOOGLE_CHANGE(pss) - END CHANGES dest_nodes = [] #GOOGLE_CHANGE(pss) - FROM THIS: # for group in self.SubstList2(group_name): # for resource in self.SubstList2(resource_type): # # Get items for publish group and resource type # items = __published.get(group, {}).get(resource, []) # for i in items: # if i.subdir: # dest_nodes += self.Replicate(target_path + '/' + i.subdir, i.source) # else: # dest_nodes += self.Replicate(target_path, i.source) #GOOGLE_CHANGE(pss) - TO THIS: for source in source_list: # Add the subdir if there is one in the source tuple. if source[1]: dest_nodes += self.Replicate(target_path + '/' + source[1], source[0]) else: dest_nodes += self.Replicate(target_path, source[0]) #GOOGLE_CHANGE(pss) - END CHANGES return dest_nodes #GOOGLE_CHANGE(pss) - FROM THIS: # def GetPublished(self, group_name, resource_type): # """Returns a list of the published resources of the specified type. # # Args: # self: Environment in which this function was called. # group_name: Name of resource group, or a list of names of resource groups. # resource_type: Type of resources (string), or a list of resource types. # # Returns: # A flattened list of the source nodes from calls to Publish() for the # specified group and resource type. Returns an empty list if there are # no matching resources. # """ #GOOGLE_CHANGE(pss) - TO THIS: def GetPublishedWithSubdirs(self, group_name, resource_type): """Returns a list of the published resources of the specified type. Args: self: Environment in which this function was called. group_name: Name of resource group, or a list of names of resource groups. resource_type: Type of resources (string), or a list of resource types. Returns: A flattened list of the source nodes from calls to Publish() for the specified group and resource type. Each source node is represented by a pair consisting of (source_node, subdir). Returns an empty list if there are no matching resources. """ #GOOGLE_CHANGE(pss) - END CHANGES source_list = [] for group in self.SubstList2(group_name): # Get items for publish group and resource type for resource in self.SubstList2(resource_type): items = __published.get(group, {}).get(resource, []) for i in items: #GOOGLE_CHANGE(pss) - FROM THIS: # source_list.append(i.source) #GOOGLE_CHANGE(pss) - TO THIS: source_list.append((i.source, i.subdir)) #GOOGLE_CHANGE(pss) - END CHANGES return source_list #GOOGLE_CHANGE(pss) - FROM THIS: #GOOGLE_CHANGE(pss) - TO THIS: def GetPublished(self, group_name, resource_type): """Returns a list of the published resources of the specified type. Args: self: Environment in which this function was called. group_name: Name of resource group, or a list of names of resource groups. resource_type: Type of resources (string), or a list of resource types. Returns: A flattened list of the source nodes from calls to Publish() for the specified group and resource type. Returns an empty list if there are no matching resources. """ source_list = self.GetPublishedWithSubdirs(group_name, resource_type) return [source[0] for source in source_list] #GOOGLE_CHANGE(pss) - END CHANGES def Publish(self, group_name, resource_type, source, subdir=None): """Publishes resources for use by other scripts. Args: self: Environment in which this function was called. group_name: Name of resource group. resource_type: Type of resources (string). source: Source file(s) to copy. May be a string, Node, or a list of mixed strings or Nodes. Strings will be passed through env.Glob() to evaluate wildcards. If a source evaluates to a directory, the entire directory will be recursively copied. subdir: Subdirectory to which the resources should be copied, relative to the primary directory for that resource type, if not None. """ if subdir is None: subdir = '' # Make string so we can append to it # Evaluate SCons variables in group name # TODO: Should Publish() be able to take a list of group names and publish # the resource to all of them? group_name = self.subst(group_name) # Get list of sources items = [] for source_entry in self.Flatten(source): if isinstance(source_entry, str): # Search for matches for each source entry # TODO: Should generate an error if there were no matches? But need to # skip this warning if this is a recursive call to self.Publish() from # below. source_nodes = self.Glob(source_entry) else: # Source entry is already a file or directory node; no need to glob it source_nodes = [source_entry] for s in source_nodes: if str(s.__class__) == 'SCons.Node.FS.Dir': # Recursively publish all files in subdirectory. Since glob('*') # doesn't match dot files, also glob('.*'). self.Publish(group_name, resource_type, [s.abspath + '/*', s.abspath + '/.*'], subdir=subdir + '/' + s.name) else: items.append(PublishItem(s, subdir)) # Publish items, if any if items: # Get publish group if group_name not in __published: __published[group_name] = {} group = __published[group_name] if resource_type not in group: group[resource_type] = [] # Publish items into group group[resource_type] += items def generate(env): # NOTE: SCons requires the use of this name, which fails gpylint. """SCons entry point for this tool.""" # Defer initializing publish, but do before building SConscripts env.Defer(_InitializePublish) env.Defer('BuildEnvironmentSConscripts', after=_InitializePublish) #GOOGLE_CHANGE(pss) - FROM THIS: #GOOGLE_CHANGE(pss) - TO THIS: env.AddMethod(GetPublishedWithSubdirs) #GOOGLE_CHANGE(pss) - END CHANGES env.AddMethod(GetPublished) env.AddMethod(Publish) env.AddMethod(ReplicatePublished)