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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
# (c) 2007 The Board of Trustees of the University of Illinois.
# Process-management and directory management routines are collected here.
import os
import os.path as path
import stat
from itertools import imap, ifilter, chain
import globals
def scan_for_files(topdir, directory=False, boring=[]):
"""Scan the contents of the directory 'topdir'. If 'directory' is
True, return a sequence of all directories found in that directory;
otherwise, return a sequence of all files found in that directory.
Directories whose names are found in the 'boring' list are excluded."""
# Look for directories or regular files, depending on the 'directory'
# parameter
if directory: valid_test = path.isdir
else: valid_test = path.isfile
def interesting(fname):
# True if 'dirname' is not a boring name, and it is a directory
if fname in boring: return False
fpath = path.join(topdir, fname)
try: return valid_test(fpath)
except OSError: return False # Ignore file-not-found errors
if not path.isdir(topdir):
raise OSError, "Cannot access '" + str(topdir) + "' as a directory"
# Return names of all directories found
return ifilter(interesting, os.listdir(topdir))
def scan_for_benchmarks(topdir):
"""Scan subdirectories of the benchmark repository to find
benchmarks. Return a sequence containing all benchmark
directory names."""
return scan_for_files(path.join(topdir, "benchmarks"), True, boring=['_darcs','.svn'])
def scan_for_benchmark_versions(bmkdir):
"""Scan subdirectories of a benchmark directory 'bmkdir' to find
benchmark versions. Return a sequence containing all benchmark
version names."""
return scan_for_files(path.join(bmkdir, "src"), True, boring=['.svn'])
def scan_for_benchmark_datasets(bmkdir):
"""Scan subdirectories of a benchmark directory 'bmkdir' to find
data sets. Return a sequence containing all data set names."""
# Get input and output subdirectories
inp_dir = path.join(bmkdir, "input")
if path.exists(inp_dir):
inp_dirs = scan_for_files(path.join(bmkdir, "input"), True, boring=['.svn'])
else:
# Assume no input files are found because the benchmark
# doesn't need input
inp_dirs = []
out_dirs = scan_for_files(path.join(bmkdir, "output"), True, boring=['.svn'])
# Return the union of the dataset directories
return dict(imap(lambda x: (x, None), chain(inp_dirs, out_dirs))).keys()
def read_description_file(dirpath):
"""Read the contents of a file in 'dirpath' called DESCRIPTION,
if one exists. This returns the file text as a string, or None
if no description was found."""
descr_path = os.path.join(dirpath, 'DESCRIPTION')
if os.access(descr_path, os.R_OK):
descr_file = file(descr_path, 'r')
descr = descr_file.read()
descr_file.close()
return descr
# else, return None
def touch_directory(dirpath):
"""Ensures that the directory 'dirpath' and its parent directories
exist. If they do not exist, they will be created. It is an
error if the path exists but is not a directory."""
if path.isdir(dirpath):
return
elif path.exists(dirpath):
raise OSError, "Path exists but is not a directory"
else:
(head, tail) = path.split(dirpath)
if head: touch_directory(head)
os.mkdir(dirpath)
def with_path(wd, action):
"""Executes an action in a separate working directory. The action
should be a callable object."""
cwd = os.getcwd()
os.chdir(wd)
try: result = action()
finally: os.chdir(cwd)
return result
def makefile(target=None, action=None, filepath=None, env={}):
"""Run a makefile. An optional command, makefile path, and dictionary of
variables to define on the command line may be defined. The return code
value is the return code returned by the makefile.
If no action is given, 'make' is invoked. Returns True if make was
successful and False otherwise.
A 'q' action queries whether the target needs to be rebuilt. True is
returned if the target is up to date."""
args = ["make"]
if action is None:
def run():
rc = os.spawnvp(os.P_WAIT, "make", args)
return rc == 0
elif action in ['q']:
args.append('-q')
def run():
rc = os.spawnvp(os.P_WAIT, "make", args)
if rc == 0:
# Up-to-date
return True
elif rc == 1:
# Needs remake
return False
else:
# Error
return False
else:
raise ValueError, "invalid action"
# Pass the target as the second argument
if target: args.append(target)
# Pass the path the the makefile
if filepath:
args.append('-f')
args.append(filepath)
# Pass variables
for (k,v) in env.iteritems():
args.append(k + "=" + v)
# Print a status message, if running in verbose mode
if globals.verbose:
print "Running '" + " ".join(args) + "' in " + os.getcwd()
# Run the makefile and return result info
return run()
def spawnwaitv(prog, args):
"""Spawn a program and wait for it to complete. The program is
spawned in a modified environment."""
env = dict(os.environ)
env.update(globals.program_env)
# Print a status message if running in verbose mode
if globals.verbose:
print "Running '" + " ".join(args) + "' in " + os.getcwd()
# Check that the program is runnable
if not os.access(prog, os.X_OK):
raise OSError, "Cannot execute '" + prog + "'"
# Run the program
return os.spawnve(os.P_WAIT, prog, args, env)
def spawnwaitl(prog, *argl):
"""Spawn a program and wait for it to complete. The program is
spawned in a modified environment."""
return spawnwaitv(prog, argl)
|