diff options
Diffstat (limited to 'o3d/site_scons/site_tools/publish.py')
-rw-r--r-- | o3d/site_scons/site_tools/publish.py | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/o3d/site_scons/site_tools/publish.py b/o3d/site_scons/site_tools/publish.py new file mode 100644 index 0000000..08bf724 --- /dev/null +++ b/o3d/site_scons/site_tools/publish.py @@ -0,0 +1,253 @@ +#!/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) |