/
moduleconfig.py
131 lines (103 loc) · 4.43 KB
/
moduleconfig.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
"""Utility functions for SCons to discover and configure
MongoDB modules (sub-trees of db/modules/). This file exports
two functions:
discover_modules, which returns a dictionary of module name
to the imported python module object for the module's
build.py file
configure_modules, which runs per-module configuration, and
is given the SCons environment, its own path, etc
Each module must have a "build.py" script, which is expected to
have a "configure" function, and optionally a "test" function
if the module exposes per-module tests.
"""
__all__ = ('discover_modules', 'configure_modules', 'register_module_test')
import imp
from os import listdir, makedirs
from os.path import abspath, dirname, join, isdir, isfile
def discover_modules(mongo_root):
"""Scan <mongo_root>/db/modules/ for directories that
look like MongoDB modules (i.e. they contain a "build.py"
file), and return a dictionary of module name (the directory
name) to build.py python modules.
"""
found_modules = {}
module_root = abspath(join(mongo_root, 'db', 'modules'))
if not isdir(module_root):
return found_modules
for name in listdir(module_root):
root = join(module_root, name)
if '.' in name or not isdir(root):
continue
build_py = join(root, 'build.py')
module = None
if isfile(build_py):
print "adding module: %s" % name
fp = open(build_py, "r")
module = imp.load_module("module_" + name, fp, build_py, (".py", "r", imp.PY_SOURCE))
found_modules[name] = module
fp.close()
return found_modules
def configure_modules(modules, conf, env):
"""
Run the configure() function in the build.py python modules
for each module listed in the modules dictionary (as created
by discover_modules). The configure() function should use the
prepare the Mongo build system for building the module.
build.py files may specify a "customIncludes" flag, which, if
True, causes configure() to be called with three arguments:
the SCons Configure() object, the SCons environment, and an
empty list which should be modified in-place by the configure()
function; if false, configure() is called with only the first
two arguments, and the source files are discovered with a
glob against the <module_root>/src/*.cpp.
Returns a dictionary mapping module name to a list of source
files to be compiled for the module.
"""
source_map = {}
for name, module in modules.items():
print "configuring module: %s" % name
root = dirname(module.__file__)
module_sources = []
if getattr(module, "customIncludes", False):
# then the module configures itself and its
# configure() takes 3 args
module.configure(conf, env, module_sources)
else:
# else we glob the files in the module's src/
# subdirectory, and its configure() takes 2 args
module.configure(conf, env)
module_sources.extend(env.Glob(join(root, "src/*.cpp")))
if not module_sources:
print "WARNING: no source files for module %s, module will not be built." % name
else:
source_map[name] = module_sources
_setup_module_tests_file(str(env.File(env['MODULETEST_LIST'])))
return source_map
module_tests = []
def register_module_test(*command):
"""Modules can register tests as part of their configure(), which
are commands whose exit status indicates the success or failure of
the test.
Use this function from configure() like:
register_module_test('/usr/bin/python', '/path/to/module/tests/foo.py')
register_module_test('/bin/bash', '/path/to/module/tests/bar.sh')
The registered test commands can be run with "scons smokeModuleTests"
"""
command = ' '.join(command)
module_tests.append(command)
def _setup_module_tests_file(test_file):
"""Modules' configure() functions may have called register_module_test,
in which case, we need to record the registered tests' commands into
a text file which smoke.py and SCons know how to work with.
"""
if not module_tests:
return
folder = dirname(test_file)
if not isdir(folder):
makedirs(folder)
fp = file(test_file, 'w')
for test in module_tests:
fp.write(test)
fp.write('\n')
fp.close()
print "Generated %s" % test_file