The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / sconsign.py @ 40c0f755

History | View | Annotate | Download (16.2 KB)

1
#! /usr/bin/env python
2
#
3
# SCons - a Software Constructor
4
#
5
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
6
#
7
# Permission is hereby granted, free of charge, to any person obtaining
8
# a copy of this software and associated documentation files (the
9
# "Software"), to deal in the Software without restriction, including
10
# without limitation the rights to use, copy, modify, merge, publish,
11
# distribute, sublicense, and/or sell copies of the Software, and to
12
# permit persons to whom the Software is furnished to do so, subject to
13
# the following conditions:
14
#
15
# The above copyright notice and this permission notice shall be included
16
# in all copies or substantial portions of the Software.
17
#
18
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
19
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
20
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
#
26

    
27
__revision__ = "src/script/sconsign.py 3842 2008/12/20 22:59:52 scons"
28

    
29
__version__ = "1.2.0"
30

    
31
__build__ = "r3842"
32

    
33
__buildsys__ = "scons-dev"
34

    
35
__date__ = "2008/12/20 22:59:52"
36

    
37
__developer__ = "scons"
38

    
39
import os
40
import os.path
41
import sys
42
import time
43

    
44
##############################################################################
45
# BEGIN STANDARD SCons SCRIPT HEADER
46
#
47
# This is the cut-and-paste logic so that a self-contained script can
48
# interoperate correctly with different SCons versions and installation
49
# locations for the engine.  If you modify anything in this section, you
50
# should also change other scripts that use this same header.
51
##############################################################################
52

    
53
# Strip the script directory from sys.path() so on case-insensitive
54
# (WIN32) systems Python doesn't think that the "scons" script is the
55
# "SCons" package.  Replace it with our own library directories
56
# (version-specific first, in case they installed by hand there,
57
# followed by generic) so we pick up the right version of the build
58
# engine modules if they're in either directory.
59

    
60
script_dir = sys.path[0]
61

    
62
if script_dir in sys.path:
63
    sys.path.remove(script_dir)
64

    
65
libs = []
66

    
67
if os.environ.has_key("SCONS_LIB_DIR"):
68
    libs.append(os.environ["SCONS_LIB_DIR"])
69

    
70
local_version = 'scons-local-' + __version__
71
local = 'scons-local'
72
if script_dir:
73
    local_version = os.path.join(script_dir, local_version)
74
    local = os.path.join(script_dir, local)
75
libs.append(os.path.abspath(local_version))
76
libs.append(os.path.abspath(local))
77

    
78
scons_version = 'scons-%s' % __version__
79

    
80
prefs = []
81

    
82
if sys.platform == 'win32':
83
    # sys.prefix is (likely) C:\Python*;
84
    # check only C:\Python*.
85
    prefs.append(sys.prefix)
86
    prefs.append(os.path.join(sys.prefix, 'Lib', 'site-packages'))
87
else:
88
    # On other (POSIX) platforms, things are more complicated due to
89
    # the variety of path names and library locations.  Try to be smart
90
    # about it.
91
    if script_dir == 'bin':
92
        # script_dir is `pwd`/bin;
93
        # check `pwd`/lib/scons*.
94
        prefs.append(os.getcwd())
95
    else:
96
        if script_dir == '.' or script_dir == '':
97
            script_dir = os.getcwd()
98
        head, tail = os.path.split(script_dir)
99
        if tail == "bin":
100
            # script_dir is /foo/bin;
101
            # check /foo/lib/scons*.
102
            prefs.append(head)
103

    
104
    head, tail = os.path.split(sys.prefix)
105
    if tail == "usr":
106
        # sys.prefix is /foo/usr;
107
        # check /foo/usr/lib/scons* first,
108
        # then /foo/usr/local/lib/scons*.
109
        prefs.append(sys.prefix)
110
        prefs.append(os.path.join(sys.prefix, "local"))
111
    elif tail == "local":
112
        h, t = os.path.split(head)
113
        if t == "usr":
114
            # sys.prefix is /foo/usr/local;
115
            # check /foo/usr/local/lib/scons* first,
116
            # then /foo/usr/lib/scons*.
117
            prefs.append(sys.prefix)
118
            prefs.append(head)
119
        else:
120
            # sys.prefix is /foo/local;
121
            # check only /foo/local/lib/scons*.
122
            prefs.append(sys.prefix)
123
    else:
124
        # sys.prefix is /foo (ends in neither /usr or /local);
125
        # check only /foo/lib/scons*.
126
        prefs.append(sys.prefix)
127

    
128
    temp = map(lambda x: os.path.join(x, 'lib'), prefs)
129
    temp.extend(map(lambda x: os.path.join(x,
130
                                           'lib',
131
                                           'python' + sys.version[:3],
132
                                           'site-packages'),
133
                           prefs))
134
    prefs = temp
135

    
136
    # Add the parent directory of the current python's library to the
137
    # preferences.  On SuSE-91/AMD64, for example, this is /usr/lib64,
138
    # not /usr/lib.
139
    try:
140
        libpath = os.__file__
141
    except AttributeError:
142
        pass
143
    else:
144
        # Split /usr/libfoo/python*/os.py to /usr/libfoo/python*.
145
        libpath, tail = os.path.split(libpath)
146
        # Split /usr/libfoo/python* to /usr/libfoo
147
        libpath, tail = os.path.split(libpath)
148
        # Check /usr/libfoo/scons*.
149
        prefs.append(libpath)
150

    
151
# Look first for 'scons-__version__' in all of our preference libs,
152
# then for 'scons'.
153
libs.extend(map(lambda x: os.path.join(x, scons_version), prefs))
154
libs.extend(map(lambda x: os.path.join(x, 'scons'), prefs))
155

    
156
sys.path = libs + sys.path
157

    
158
##############################################################################
159
# END STANDARD SCons SCRIPT HEADER
160
##############################################################################
161

    
162
import cPickle
163
import imp
164
import string
165
import whichdb
166

    
167
import SCons.SConsign
168

    
169
def my_whichdb(filename):
170
    if filename[-7:] == ".dblite":
171
        return "SCons.dblite"
172
    try:
173
        f = open(filename + ".dblite", "rb")
174
        f.close()
175
        return "SCons.dblite"
176
    except IOError:
177
        pass
178
    return _orig_whichdb(filename)
179

    
180
_orig_whichdb = whichdb.whichdb
181
whichdb.whichdb = my_whichdb
182

    
183
def my_import(mname):
184
    if '.' in mname:
185
        i = string.rfind(mname, '.')
186
        parent = my_import(mname[:i])
187
        fp, pathname, description = imp.find_module(mname[i+1:],
188
                                                    parent.__path__)
189
    else:
190
        fp, pathname, description = imp.find_module(mname)
191
    return imp.load_module(mname, fp, pathname, description)
192

    
193
class Flagger:
194
    default_value = 1
195
    def __setitem__(self, item, value):
196
        self.__dict__[item] = value
197
        self.default_value = 0
198
    def __getitem__(self, item):
199
        return self.__dict__.get(item, self.default_value)
200

    
201
Do_Call = None
202
Print_Directories = []
203
Print_Entries = []
204
Print_Flags = Flagger()
205
Verbose = 0
206
Readable = 0
207

    
208
def default_mapper(entry, name):
209
    try:
210
        val = eval("entry."+name)
211
    except:
212
        val = None
213
    return str(val)
214

    
215
def map_action(entry, name):
216
    try:
217
        bact = entry.bact
218
        bactsig = entry.bactsig
219
    except AttributeError:
220
        return None
221
    return '%s [%s]' % (bactsig, bact)
222

    
223
def map_timestamp(entry, name):
224
    try:
225
        timestamp = entry.timestamp
226
    except AttributeError:
227
        timestamp = None
228
    if Readable and timestamp:
229
        return "'" + time.ctime(timestamp) + "'"
230
    else:
231
        return str(timestamp)
232

    
233
def map_bkids(entry, name):
234
    try:
235
        bkids = entry.bsources + entry.bdepends + entry.bimplicit
236
        bkidsigs = entry.bsourcesigs + entry.bdependsigs + entry.bimplicitsigs
237
    except AttributeError:
238
        return None
239
    result = []
240
    for i in xrange(len(bkids)):
241
        result.append(nodeinfo_string(bkids[i], bkidsigs[i], "        "))
242
    if result == []:
243
        return None
244
    return string.join(result, "\n        ")
245

    
246
map_field = {
247
    'action'    : map_action,
248
    'timestamp' : map_timestamp,
249
    'bkids'     : map_bkids,
250
}
251

    
252
map_name = {
253
    'implicit'  : 'bkids',
254
}
255

    
256
def field(name, entry, verbose=Verbose):
257
    if not Print_Flags[name]:
258
        return None
259
    fieldname = map_name.get(name, name)
260
    mapper = map_field.get(fieldname, default_mapper)
261
    val = mapper(entry, name)
262
    if verbose:
263
        val = name + ": " + val
264
    return val
265

    
266
def nodeinfo_raw(name, ninfo, prefix=""):
267
    # This just formats the dictionary, which we would normally use str()
268
    # to do, except that we want the keys sorted for deterministic output.
269
    d = ninfo.__dict__
270
    try:
271
        keys = ninfo.field_list + ['_version_id']
272
    except AttributeError:
273
        keys = d.keys()
274
        keys.sort()
275
    l = []
276
    for k in keys:
277
        l.append('%s: %s' % (repr(k), repr(d.get(k))))
278
    if '\n' in name:
279
        name = repr(name)
280
    return name + ': {' + string.join(l, ', ') + '}'
281

    
282
def nodeinfo_cooked(name, ninfo, prefix=""):
283
    try:
284
        field_list = ninfo.field_list
285
    except AttributeError:
286
        field_list = []
287
    f = lambda x, ni=ninfo, v=Verbose: field(x, ni, v)
288
    if '\n' in name:
289
        name = repr(name)
290
    outlist = [name+':'] + filter(None, map(f, field_list))
291
    if Verbose:
292
        sep = '\n    ' + prefix
293
    else:
294
        sep = ' '
295
    return string.join(outlist, sep)
296

    
297
nodeinfo_string = nodeinfo_cooked
298

    
299
def printfield(name, entry, prefix=""):
300
    outlist = field("implicit", entry, 0)
301
    if outlist:
302
        if Verbose:
303
            print "    implicit:"
304
        print "        " + outlist
305
    outact = field("action", entry, 0)
306
    if outact:
307
        if Verbose:
308
            print "    action: " + outact
309
        else:
310
            print "        " + outact
311

    
312
def printentries(entries, location):
313
    if Print_Entries:
314
        for name in Print_Entries:
315
            try:
316
                entry = entries[name]
317
            except KeyError:
318
                sys.stderr.write("sconsign: no entry `%s' in `%s'\n" % (name, location))
319
            else:
320
                try:
321
                    ninfo = entry.ninfo
322
                except AttributeError:
323
                    print name + ":"
324
                else:
325
                    print nodeinfo_string(name, entry.ninfo)
326
                printfield(name, entry.binfo)
327
    else:
328
        names = entries.keys()
329
        names.sort()
330
        for name in names:
331
            entry = entries[name]
332
            try:
333
                ninfo = entry.ninfo
334
            except AttributeError:
335
                print name + ":"
336
            else:
337
                print nodeinfo_string(name, entry.ninfo)
338
            printfield(name, entry.binfo)
339

    
340
class Do_SConsignDB:
341
    def __init__(self, dbm_name, dbm):
342
        self.dbm_name = dbm_name
343
        self.dbm = dbm
344

    
345
    def __call__(self, fname):
346
        # The *dbm modules stick their own file suffixes on the names
347
        # that are passed in.  This is causes us to jump through some
348
        # hoops here to be able to allow the user
349
        try:
350
            # Try opening the specified file name.  Example:
351
            #   SPECIFIED                  OPENED BY self.dbm.open()
352
            #   ---------                  -------------------------
353
            #   .sconsign               => .sconsign.dblite
354
            #   .sconsign.dblite        => .sconsign.dblite.dblite
355
            db = self.dbm.open(fname, "r")
356
        except (IOError, OSError), e:
357
            print_e = e
358
            try:
359
                # That didn't work, so try opening the base name,
360
                # so that if the actually passed in 'sconsign.dblite'
361
                # (for example), the dbm module will put the suffix back
362
                # on for us and open it anyway.
363
                db = self.dbm.open(os.path.splitext(fname)[0], "r")
364
            except (IOError, OSError):
365
                # That didn't work either.  See if the file name
366
                # they specified just exists (independent of the dbm
367
                # suffix-mangling).
368
                try:
369
                    open(fname, "r")
370
                except (IOError, OSError), e:
371
                    # Nope, that file doesn't even exist, so report that
372
                    # fact back.
373
                    print_e = e
374
                sys.stderr.write("sconsign: %s\n" % (print_e))
375
                return
376
        except KeyboardInterrupt:
377
            raise
378
        except cPickle.UnpicklingError:
379
            sys.stderr.write("sconsign: ignoring invalid `%s' file `%s'\n" % (self.dbm_name, fname))
380
            return
381
        except Exception, e:
382
            sys.stderr.write("sconsign: ignoring invalid `%s' file `%s': %s\n" % (self.dbm_name, fname, e))
383
            return
384

    
385
        if Print_Directories:
386
            for dir in Print_Directories:
387
                try:
388
                    val = db[dir]
389
                except KeyError:
390
                    sys.stderr.write("sconsign: no dir `%s' in `%s'\n" % (dir, args[0]))
391
                else:
392
                    self.printentries(dir, val)
393
        else:
394
            keys = db.keys()
395
            keys.sort()
396
            for dir in keys:
397
                self.printentries(dir, db[dir])
398

    
399
    def printentries(self, dir, val):
400
        print '=== ' + dir + ':'
401
        printentries(cPickle.loads(val), dir)
402

    
403
def Do_SConsignDir(name):
404
    try:
405
        fp = open(name, 'rb')
406
    except (IOError, OSError), e:
407
        sys.stderr.write("sconsign: %s\n" % (e))
408
        return
409
    try:
410
        sconsign = SCons.SConsign.Dir(fp)
411
    except KeyboardInterrupt:
412
        raise
413
    except cPickle.UnpicklingError:
414
        sys.stderr.write("sconsign: ignoring invalid .sconsign file `%s'\n" % (name))
415
        return
416
    except Exception, e:
417
        sys.stderr.write("sconsign: ignoring invalid .sconsign file `%s': %s\n" % (name, e))
418
        return
419
    printentries(sconsign.entries, args[0])
420

    
421
##############################################################################
422

    
423
import getopt
424

    
425
helpstr = """\
426
Usage: sconsign [OPTIONS] FILE [...]
427
Options:
428
  -a, --act, --action         Print build action information.
429
  -c, --csig                  Print content signature information.
430
  -d DIR, --dir=DIR           Print only info about DIR.
431
  -e ENTRY, --entry=ENTRY     Print only info about ENTRY.
432
  -f FORMAT, --format=FORMAT  FILE is in the specified FORMAT.
433
  -h, --help                  Print this message and exit.
434
  -i, --implicit              Print implicit dependency information.
435
  -r, --readable              Print timestamps in human-readable form.
436
  --raw                       Print raw Python object representations.
437
  -s, --size                  Print file sizes.
438
  -t, --timestamp             Print timestamp information.
439
  -v, --verbose               Verbose, describe each field.
440
"""
441

    
442
opts, args = getopt.getopt(sys.argv[1:], "acd:e:f:hirstv",
443
                            ['act', 'action',
444
                             'csig', 'dir=', 'entry=',
445
                             'format=', 'help', 'implicit',
446
                             'raw', 'readable',
447
                             'size', 'timestamp', 'verbose'])
448

    
449

    
450
for o, a in opts:
451
    if o in ('-a', '--act', '--action'):
452
        Print_Flags['action'] = 1
453
    elif o in ('-c', '--csig'):
454
        Print_Flags['csig'] = 1
455
    elif o in ('-d', '--dir'):
456
        Print_Directories.append(a)
457
    elif o in ('-e', '--entry'):
458
        Print_Entries.append(a)
459
    elif o in ('-f', '--format'):
460
        Module_Map = {'dblite'   : 'SCons.dblite',
461
                      'sconsign' : None}
462
        dbm_name = Module_Map.get(a, a)
463
        if dbm_name:
464
            try:
465
                dbm = my_import(dbm_name)
466
            except:
467
                sys.stderr.write("sconsign: illegal file format `%s'\n" % a)
468
                print helpstr
469
                sys.exit(2)
470
            Do_Call = Do_SConsignDB(a, dbm)
471
        else:
472
            Do_Call = Do_SConsignDir
473
    elif o in ('-h', '--help'):
474
        print helpstr
475
        sys.exit(0)
476
    elif o in ('-i', '--implicit'):
477
        Print_Flags['implicit'] = 1
478
    elif o in ('--raw',):
479
        nodeinfo_string = nodeinfo_raw
480
    elif o in ('-r', '--readable'):
481
        Readable = 1
482
    elif o in ('-s', '--size'):
483
        Print_Flags['size'] = 1
484
    elif o in ('-t', '--timestamp'):
485
        Print_Flags['timestamp'] = 1
486
    elif o in ('-v', '--verbose'):
487
        Verbose = 1
488

    
489
if Do_Call:
490
    for a in args:
491
        Do_Call(a)
492
else:
493
    for a in args:
494
        dbm_name = whichdb.whichdb(a)
495
        if dbm_name:
496
            Map_Module = {'SCons.dblite' : 'dblite'}
497
            dbm = my_import(dbm_name)
498
            Do_SConsignDB(Map_Module.get(dbm_name, dbm_name), dbm)(a)
499
        else:
500
            Do_SConsignDir(a)
501

    
502
sys.exit(0)