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