8 from distutils
.core
import setup
, Command
, Extension
9 from Pyrex
.Distutils
import build_ext
11 from distutils
.command
.clean
import clean
as distutils_clean
12 from distutils
.command
.sdist
import sdist
as distutils_sdist
14 class clean(distutils_clean
):
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("#"))):
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
:
32 try: os
.unlink("MANIFEST")
35 for base
in ["coverage", "build", "dist"]:
36 path
= os
.path
.join(os
.path
.dirname(__file__
), base
)
37 if os
.path
.isdir(path
):
40 class coverage_cmd(Command
):
41 description
= "generate test coverage data"
44 def initialize_options(self
):
47 def finalize_options(self
):
53 count
=True, trace
=False,
54 ignoredirs
=[sys
.prefix
, sys
.exec_prefix
])
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"))
72 for filename
in glob
.glob(os
.path
.join(coverage
, "*.cover")):
73 lines
= open(filename
, "rU").readlines()
74 total_lines
+= len(lines
)
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
))
83 class sdist(distutils_sdist
):
85 self
.run_command("test")
86 distutils_sdist
.run(self
)
88 class test_cmd(Command
):
89 description
= "run automated tests"
91 ("to-run=", None, "list of tests to run (default all)"),
94 def initialize_options(self
):
98 def finalize_options(self
):
100 self
.to_run
= self
.to_run
.split(",")
104 if tests
.unit(self
.to_run
):
105 raise SystemExit("Test failures are listed above.")
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",
116 packages
=["bulletml"],
117 data_files
=glob
.glob("examples/*/*.xml") + ["examples/template.xml"],
118 scripts
=["bulletml-runner", "bulletml-to-bulletyaml"],
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
128 In addition to the standard BulletML XML format, this module supports
129 an equivalent YAML format.
131 Finally, two simple collision routines are provided, bulletml.overlaps
132 for stationary circles and bulletml.collides for moving circles.
134 A sample renderer for Pygame is included.
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/.