Optional Pyrex extension for the collision module. More than doubles its speed.
[python-bulletml.git] / setup.py
1 #!/usr/bin/env python
2
3 import glob
4 import os
5 import shutil
6 import sys
7
8 from distutils.core import setup, Command, Extension
9 from Pyrex.Distutils import build_ext
10
11 from distutils.command.clean import clean as distutils_clean
12 from distutils.command.sdist import sdist as distutils_sdist
13
14 class clean(distutils_clean):
15 def run(self):
16 # In addition to what the normal clean run does, remove pyc
17 # and pyo and backup files from the source tree.
18 distutils_clean.run(self)
19 def should_remove(filename):
20 if (filename.lower()[-4:] in [".pyc", ".pyo"] or
21 filename.endswith("~") or
22 (filename.startswith("#") and filename.endswith("#"))):
23 return True
24 else:
25 return False
26 for pathname, dirs, files in os.walk(os.path.dirname(__file__)):
27 for filename in filter(should_remove, files):
28 try: os.unlink(os.path.join(pathname, filename))
29 except EnvironmentError as err:
30 print(str(err))
31
32 try: os.unlink("MANIFEST")
33 except OSError: pass
34
35 for base in ["coverage", "build", "dist"]:
36 path = os.path.join(os.path.dirname(__file__), base)
37 if os.path.isdir(path):
38 shutil.rmtree(path)
39
40 class coverage_cmd(Command):
41 description = "generate test coverage data"
42 user_options = []
43
44 def initialize_options(self):
45 pass
46
47 def finalize_options(self):
48 pass
49
50 def run(self):
51 import trace
52 tracer = trace.Trace(
53 count=True, trace=False,
54 ignoredirs=[sys.prefix, sys.exec_prefix])
55 def run_tests():
56 import bulletml
57 try:
58 reload(bulletml)
59 except NameError:
60 pass
61 self.run_command("test")
62 tracer.runfunc(run_tests)
63 results = tracer.results()
64 coverage = os.path.join(os.path.dirname(__file__), "coverage")
65 results.write_results(show_missing=True, coverdir=coverage)
66 map(os.unlink, glob.glob(os.path.join(coverage, "[!b]*.cover")))
67 try: os.unlink(os.path.join(coverage, "..setup.cover"))
68 except OSError: pass
69
70 total_lines = 0
71 bad_lines = 0
72 for filename in glob.glob(os.path.join(coverage, "*.cover")):
73 lines = open(filename, "rU").readlines()
74 total_lines += len(lines)
75 bad_lines += len(
76 [line for line in lines if
77 (line.startswith(">>>>>>") and
78 "finally:" not in line and '"""' not in line)])
79 pct = 100.0 * (total_lines - bad_lines) / float(total_lines)
80 print("Coverage data written to %s (%d/%d, %0.2f%%)" % (
81 coverage, total_lines - bad_lines, total_lines, pct))
82
83 class sdist(distutils_sdist):
84 def run(self):
85 self.run_command("test")
86 distutils_sdist.run(self)
87
88 class test_cmd(Command):
89 description = "run automated tests"
90 user_options = [
91 ("to-run=", None, "list of tests to run (default all)"),
92 ]
93
94 def initialize_options(self):
95 self.to_run = []
96 self.quick = False
97
98 def finalize_options(self):
99 if self.to_run:
100 self.to_run = self.to_run.split(",")
101
102 def run(self):
103 import tests
104 if tests.unit(self.to_run):
105 raise SystemExit("Test failures are listed above.")
106
107 if __name__ == "__main__":
108 setup(cmdclass=dict(clean=clean, test=test_cmd, coverage=coverage_cmd,
109 sdist=sdist, build_ext=build_ext),
110 name="python-bulletml", version="1",
111 url="http://code.google.com/p/python-bulletml/",
112 description="parse and run BulletML scripts",
113 author="Joe Wreschnig",
114 author_email="joe.wreschnig@gmail.com",
115 license="MIT-style",
116 packages=["bulletml"],
117 data_files=glob.glob("examples/*/*.xml") + ["examples/template.xml"],
118 scripts=["bulletml-runner", "bulletml-to-bulletyaml"],
119 ext_modules=[
120 Extension('bulletml._collision', ['bulletml/_collision.pyx'])],
121 long_description="""\
122 BulletML is the Bullet Markup Language. BulletML can describe the
123 barrage of bullets in shooting games. (For example Progear, Psyvariar,
124 Gigawing2, G DARIUS, XEVIOUS, ...) This module parses and executes
125 BulletML scripts in Python. All data structures in it are
126 renderer-agnostic.
127
128 In addition to the standard BulletML XML format, this module supports
129 an equivalent YAML format.
130
131 Finally, two simple collision routines are provided, bulletml.overlaps
132 for stationary circles and bulletml.collides for moving circles.
133
134 A sample renderer for Pygame is included.
135
136 More information is available at the BulletML homepage,
137 http://www.asahi-net.or.jp/~cs8k-cyu/bulletml/index_e.html, or the
138 python-bullet homepage, http://code.google.com/p/python-bulletml/.
139 """
140 )