1#!/usr/bin/python2.4 2# Copyright 2009 The Native Client Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6"""Publish tool for SCons.""" 7 8 9# List of published resources. This is a dict indexed by group name. Each 10# item in this dict is a dict indexed by resource type. Items in that dict 11# are lists of files for that resource. 12__published = {} 13 14#------------------------------------------------------------------------------ 15 16 17class PublishItem(object): 18 """Item to be published.""" 19 20 def __init__(self, source, subdir): 21 """Initialize object. 22 23 Args: 24 source: Source node. 25 subdir: If not None, subdirectory to copy node into in 26 ReplicatePublished(). 27 """ 28 object.__init__(self) 29 self.source = source 30 self.subdir = subdir 31 32#------------------------------------------------------------------------------ 33 34 35def _InitializePublish(env): 36 """Re-initializes published resources. 37 38 Args: 39 env: Parent environment 40 """ 41 env=env # Silence gpylint 42 43 # Clear the dict of published resources 44 __published.clear() 45 46 47def ReplicatePublished(self, target, group_name, resource_type): 48 """Replicate published resources for the group to the target directory. 49 50 Args: 51 self: Environment in which this function was called. 52 target: Target directory for resources. 53 group_name: Name of resource group, or a list of names of resource groups. 54 resource_type: Type of resources (string), or a list of resource types. 55 56 Uses the subdir parameter passed to Publish() when replicating source nodes 57 to the target. 58 59 Returns: 60 The list of target nodes from the calls to Replicate(). 61 62 Since this is based on Replicate(), it will also use the REPLICATE_REPLACE 63 variable, if it's set in the calling environment. 64 """ 65 target_path = self.Dir(target).abspath 66 #GOOGLE_CHANGE(pss) - FROM THIS: 67 #GOOGLE_CHANGE(pss) - TO THIS: 68 source_list = self.GetPublishedWithSubdirs(group_name, resource_type) 69 #GOOGLE_CHANGE(pss) - END CHANGES 70 dest_nodes = [] 71 #GOOGLE_CHANGE(pss) - FROM THIS: 72 # for group in self.SubstList2(group_name): 73 # for resource in self.SubstList2(resource_type): 74 # # Get items for publish group and resource type 75 # items = __published.get(group, {}).get(resource, []) 76 # for i in items: 77 # if i.subdir: 78 # dest_nodes += self.Replicate(target_path + '/' + i.subdir, i.source) 79 # else: 80 # dest_nodes += self.Replicate(target_path, i.source) 81 #GOOGLE_CHANGE(pss) - TO THIS: 82 for source in source_list: 83 # Add the subdir if there is one in the source tuple. 84 if source[1]: 85 dest_nodes += self.Replicate(target_path + '/' + source[1], source[0]) 86 else: 87 dest_nodes += self.Replicate(target_path, source[0]) 88 #GOOGLE_CHANGE(pss) - END CHANGES 89 return dest_nodes 90 91 92#GOOGLE_CHANGE(pss) - FROM THIS: 93# def GetPublished(self, group_name, resource_type): 94# """Returns a list of the published resources of the specified type. 95# 96# Args: 97# self: Environment in which this function was called. 98# group_name: Name of resource group, or a list of names of resource groups. 99# resource_type: Type of resources (string), or a list of resource types. 100# 101# Returns: 102# A flattened list of the source nodes from calls to Publish() for the 103# specified group and resource type. Returns an empty list if there are 104# no matching resources. 105# """ 106#GOOGLE_CHANGE(pss) - TO THIS: 107def GetPublishedWithSubdirs(self, group_name, resource_type): 108 """Returns a list of the published resources of the specified type. 109 110 Args: 111 self: Environment in which this function was called. 112 group_name: Name of resource group, or a list of names of resource groups. 113 resource_type: Type of resources (string), or a list of resource types. 114 115 Returns: 116 A flattened list of the source nodes from calls to Publish() for the 117 specified group and resource type. Each source node is represented 118 by a pair consisting of (source_node, subdir). Returns an empty list 119 if there are no matching resources. 120 """ 121#GOOGLE_CHANGE(pss) - END CHANGES 122 source_list = [] 123 for group in self.SubstList2(group_name): 124 # Get items for publish group and resource type 125 for resource in self.SubstList2(resource_type): 126 items = __published.get(group, {}).get(resource, []) 127 for i in items: 128 #GOOGLE_CHANGE(pss) - FROM THIS: 129 # source_list.append(i.source) 130 #GOOGLE_CHANGE(pss) - TO THIS: 131 source_list.append((i.source, i.subdir)) 132 #GOOGLE_CHANGE(pss) - END CHANGES 133 134 return source_list 135 136 137#GOOGLE_CHANGE(pss) - FROM THIS: 138#GOOGLE_CHANGE(pss) - TO THIS: 139def GetPublished(self, group_name, resource_type): 140 """Returns a list of the published resources of the specified type. 141 142 Args: 143 self: Environment in which this function was called. 144 group_name: Name of resource group, or a list of names of resource groups. 145 resource_type: Type of resources (string), or a list of resource types. 146 147 Returns: 148 A flattened list of the source nodes from calls to Publish() for the 149 specified group and resource type. Returns an empty list if there are 150 no matching resources. 151 """ 152 source_list = self.GetPublishedWithSubdirs(group_name, resource_type) 153 return [source[0] for source in source_list] 154 155 156#GOOGLE_CHANGE(pss) - END CHANGES 157def Publish(self, group_name, resource_type, source, subdir=None): 158 """Publishes resources for use by other scripts. 159 160 Args: 161 self: Environment in which this function was called. 162 group_name: Name of resource group. 163 resource_type: Type of resources (string). 164 source: Source file(s) to copy. May be a string, Node, or a list of 165 mixed strings or Nodes. Strings will be passed through env.Glob() to 166 evaluate wildcards. If a source evaluates to a directory, the entire 167 directory will be recursively copied. 168 subdir: Subdirectory to which the resources should be copied, relative to 169 the primary directory for that resource type, if not None. 170 """ 171 if subdir is None: 172 subdir = '' # Make string so we can append to it 173 174 # Evaluate SCons variables in group name 175 # TODO: Should Publish() be able to take a list of group names and publish 176 # the resource to all of them? 177 group_name = self.subst(group_name) 178 179 # Get list of sources 180 items = [] 181 for source_entry in self.Flatten(source): 182 if isinstance(source_entry, str): 183 # Search for matches for each source entry 184 # TODO: Should generate an error if there were no matches? But need to 185 # skip this warning if this is a recursive call to self.Publish() from 186 # below. 187 source_nodes = self.Glob(source_entry) 188 else: 189 # Source entry is already a file or directory node; no need to glob it 190 source_nodes = [source_entry] 191 for s in source_nodes: 192 if str(s.__class__) == 'SCons.Node.FS.Dir': 193 # Recursively publish all files in subdirectory. Since glob('*') 194 # doesn't match dot files, also glob('.*'). 195 self.Publish(group_name, resource_type, 196 [s.abspath + '/*', s.abspath + '/.*'], 197 subdir=subdir + '/' + s.name) 198 else: 199 items.append(PublishItem(s, subdir)) 200 201 # Publish items, if any 202 if items: 203 # Get publish group 204 if group_name not in __published: 205 __published[group_name] = {} 206 group = __published[group_name] 207 if resource_type not in group: 208 group[resource_type] = [] 209 210 # Publish items into group 211 group[resource_type] += items 212 213 214def generate(env): 215 # NOTE: SCons requires the use of this name, which fails gpylint. 216 """SCons entry point for this tool.""" 217 218 # Defer initializing publish, but do before building SConscripts 219 env.Defer(_InitializePublish) 220 env.Defer('BuildEnvironmentSConscripts', after=_InitializePublish) 221 222 #GOOGLE_CHANGE(pss) - FROM THIS: 223 #GOOGLE_CHANGE(pss) - TO THIS: 224 env.AddMethod(GetPublishedWithSubdirs) 225 #GOOGLE_CHANGE(pss) - END CHANGES 226 env.AddMethod(GetPublished) 227 env.AddMethod(Publish) 228 env.AddMethod(ReplicatePublished) 229