Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Side by Side Diff: site_scons/site_tools/defer.py

Issue 6329: Dropping in software construction toolkit. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 12 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « site_scons/site_tools/concat_source.py ('k') | site_scons/site_tools/directx_9_0_c.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/python2.4
2 # Copyright 2008, Google Inc.
3 # All rights reserved.
4 #
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are
7 # met:
8 #
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.
18 #
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.
30
31 """Defer tool for SCons."""
32
33
34 import os
35 import sys
36 import types
37
38
39 __defer_groups = {}
40
41
42 def _InitializeDefer(self):
43 """Re-initializes deferred function handling.
44
45 Args:
46 self: Parent environment
47 """
48 # Clear the list of deferred groups
49 __defer_groups.clear()
50
51
52 def _ExecuteDefer(self):
53 """Executes deferred functions.
54
55 Args:
56 self: Parent environment
57 """
58 # Save directory, so SConscript functions can occur in the right subdirs
59 oldcwd = os.getcwd()
60
61 # Loop through deferred functions
62 while __defer_groups:
63 did_work = False
64 for name, group in __defer_groups.items():
65 if group.after.intersection(__defer_groups.keys()):
66 continue # Still have dependencies
67 if group.func_env_cwd:
68 # Run all the functions in our named group
69 for func, env, cwd in group.func_env_cwd:
70 os.chdir(cwd)
71 func(env)
72 did_work = True
73 del __defer_groups[name]
74 break
75 if not did_work:
76 print 'Error in _ExecuteDefer: dependency cycle detected.'
77 for name, group in __defer_groups.items():
78 print ' %s after: %s' % (name, group.after)
79 # TODO(rspangler): should throw exception?
80 sys.exit(1)
81
82 # Restore directory
83 os.chdir(oldcwd)
84
85
86 class DeferFunc(object):
87 """Named list of functions to be deferred."""
88
89 def __init__(self):
90 """Initialize deferred function object."""
91 object.__init__(self)
92 self.func_env_cwd = []
93 self.after = set()
94
95
96 def Defer(self, *args, **kwargs):
97 """Adds a deferred function or modifies defer dependencies.
98
99 Args:
100 self: Environment in which Defer() was called
101 args: Positional arguments
102 kwargs: Named arguments
103
104 The deferred function will be passed the environment used to call Defer(),
105 and will be executed in the same working directory as the calling SConscript.
106
107 All deferred functions run after all SConscripts. Additional dependencies
108 may be specified with the after= keyword.
109
110 Usage:
111
112 env.Defer(func)
113 # Defer func() until after all SConscripts
114
115 env.Defer(func, after=otherfunc)
116 # Defer func() until otherfunc() runs
117
118 env.Defer(func, 'bob')
119 # Defer func() until after SConscripts, put in group 'bob'
120
121 env.Defer(func2, after='bob')
122 # Defer func2() until after all funcs in 'bob' group have run
123
124 env.Defer(func3, 'sam')
125 # Defer func3() until after SConscripts, put in group 'sam'
126
127 env.Defer('bob', after='sam')
128 # Defer all functions in group 'bob' until after all functions in group
129 # 'sam' have run.
130
131 env.Defer(func4, after=['bob', 'sam'])
132 # Defer func4() until after all functions in groups 'bob' and 'sam' have
133 # run.
134 """
135 # Get name of group to defer and/or the a function
136 name = None
137 func = None
138 for a in args:
139 if isinstance(a, str):
140 name = a
141 elif isinstance(a, types.FunctionType):
142 func = a
143 if func and not name:
144 name = func.__name__
145
146 # Get list of names and/or functions this function should defer until after
147 after = []
148 for a in self.Flatten(kwargs.get('after')):
149 if isinstance(a, str):
150 after.append(a)
151 elif isinstance(a, types.FunctionType):
152 after.append(a.__name__)
153 elif a is not None:
154 # Deferring
155 # TODO(rspangler): should throw an exception
156 print ('Warning: Defer can only wait for functions or names; ignoring'
157 'after = ', a)
158
159 # Find the deferred function
160 if name not in __defer_groups:
161 __defer_groups[name] = DeferFunc()
162 group = __defer_groups[name]
163
164 # If we were given a function, also save environment and current directory
165 if func:
166 group.func_env_cwd.append((func, self, os.getcwd()))
167
168 # Add dependencies for the function
169 group.after.update(after)
170
171
172 def generate(env):
173 # NOTE: SCons requires the use of this name, which fails gpylint.
174 """SCons entry point for this tool."""
175
176 env.AddMethod(_InitializeDefer)
177 env.AddMethod(_ExecuteDefer)
178 env.AddMethod(Defer)
OLDNEW
« no previous file with comments | « site_scons/site_tools/concat_source.py ('k') | site_scons/site_tools/directx_9_0_c.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698