Debugging: Add code to print backtrace for guest on SIGSEGV
[nativeclient.git] / site_scons / site_tools / publish.py
blob963bdd6c2b2e474a62f46bb72f105f3cc6cd705a
1 #!/usr/bin/python2.4
2 # Copyright 2009, Google Inc.
3 # All rights reserved.
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are
7 # met:
9 # * Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # * Redistributions in binary form must reproduce the above
12 # copyright notice, this list of conditions and the following disclaimer
13 # in the documentation and/or other materials provided with the
14 # distribution.
15 # * Neither the name of Google Inc. nor the names of its
16 # contributors may be used to endorse or promote products derived from
17 # this software without specific prior written permission.
19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 """Publish tool for SCons."""
34 # List of published resources. This is a dict indexed by group name. Each
35 # item in this dict is a dict indexed by resource type. Items in that dict
36 # are lists of files for that resource.
37 __published = {}
39 #------------------------------------------------------------------------------
42 class PublishItem(object):
43 """Item to be published."""
45 def __init__(self, source, subdir):
46 """Initialize object.
48 Args:
49 source: Source node.
50 subdir: If not None, subdirectory to copy node into in
51 ReplicatePublished().
52 """
53 object.__init__(self)
54 self.source = source
55 self.subdir = subdir
57 #------------------------------------------------------------------------------
60 def _InitializePublish(env):
61 """Re-initializes published resources.
63 Args:
64 env: Parent environment
65 """
66 env=env # Silence gpylint
68 # Clear the dict of published resources
69 __published.clear()
72 def ReplicatePublished(self, target, group_name, resource_type):
73 """Replicate published resources for the group to the target directory.
75 Args:
76 self: Environment in which this function was called.
77 target: Target directory for resources.
78 group_name: Name of resource group, or a list of names of resource groups.
79 resource_type: Type of resources (string), or a list of resource types.
81 Uses the subdir parameter passed to Publish() when replicating source nodes
82 to the target.
84 Returns:
85 The list of target nodes from the calls to Replicate().
87 Since this is based on Replicate(), it will also use the REPLICATE_REPLACE
88 variable, if it's set in the calling environment.
89 """
90 target_path = self.Dir(target).abspath
92 dest_nodes = []
93 for group in self.SubstList2(group_name):
94 for resource in self.SubstList2(resource_type):
95 # Get items for publish group and resource type
96 items = __published.get(group, {}).get(resource, [])
97 for i in items:
98 if i.subdir:
99 dest_nodes += self.Replicate(target_path + '/' + i.subdir, i.source)
100 else:
101 dest_nodes += self.Replicate(target_path, i.source)
102 return dest_nodes
105 def GetPublished(self, group_name, resource_type):
106 """Returns a list of the published resources of the specified type.
108 Args:
109 self: Environment in which this function was called.
110 group_name: Name of resource group, or a list of names of resource groups.
111 resource_type: Type of resources (string), or a list of resource types.
113 Returns:
114 A flattened list of the source nodes from calls to Publish() for the
115 specified group and resource type. Returns an empty list if there are
116 no matching resources.
118 source_list = []
119 for group in self.SubstList2(group_name):
120 # Get items for publish group and resource type
121 for resource in self.SubstList2(resource_type):
122 items = __published.get(group, {}).get(resource, [])
123 for i in items:
124 source_list.append(i.source)
126 return source_list
129 def Publish(self, group_name, resource_type, source, subdir=None):
130 """Publishes resources for use by other scripts.
132 Args:
133 self: Environment in which this function was called.
134 group_name: Name of resource group.
135 resource_type: Type of resources (string).
136 source: Source file(s) to copy. May be a string, Node, or a list of
137 mixed strings or Nodes. Strings will be passed through env.Glob() to
138 evaluate wildcards. If a source evaluates to a directory, the entire
139 directory will be recursively copied.
140 subdir: Subdirectory to which the resources should be copied, relative to
141 the primary directory for that resource type, if not None.
143 if subdir is None:
144 subdir = '' # Make string so we can append to it
146 # Evaluate SCons variables in group name
147 # TODO: Should Publish() be able to take a list of group names and publish
148 # the resource to all of them?
149 group_name = self.subst(group_name)
151 # Get list of sources
152 items = []
153 for source_entry in self.Flatten(source):
154 if isinstance(source_entry, str):
155 # Search for matches for each source entry
156 # TODO: Should generate an error if there were no matches? But need to
157 # skip this warning if this is a recursive call to self.Publish() from
158 # below.
159 source_nodes = self.Glob(source_entry)
160 else:
161 # Source entry is already a file or directory node; no need to glob it
162 source_nodes = [source_entry]
163 for s in source_nodes:
164 if str(s.__class__) == 'SCons.Node.FS.Dir':
165 # Recursively publish all files in subdirectory. Since glob('*')
166 # doesn't match dot files, also glob('.*').
167 self.Publish(group_name, resource_type,
168 [s.abspath + '/*', s.abspath + '/.*'],
169 subdir=subdir + '/' + s.name)
170 else:
171 items.append(PublishItem(s, subdir))
173 # Publish items, if any
174 if items:
175 # Get publish group
176 if group_name not in __published:
177 __published[group_name] = {}
178 group = __published[group_name]
179 if resource_type not in group:
180 group[resource_type] = []
182 # Publish items into group
183 group[resource_type] += items
186 def generate(env):
187 # NOTE: SCons requires the use of this name, which fails gpylint.
188 """SCons entry point for this tool."""
190 # Defer initializing publish, but do before building SConscripts
191 env.Defer(_InitializePublish)
192 env.Defer('BuildEnvironmentSConscripts', after=_InitializePublish)
194 env.AddMethod(GetPublished)
195 env.AddMethod(Publish)
196 env.AddMethod(ReplicatePublished)