blob: 08bf72415c7c09018f3cd15b7cbca1147a388f91 [file] [log] [blame]
#!/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)