-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsetup.py
executable file
·160 lines (133 loc) · 6.07 KB
/
setup.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
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
#!/usr/bin/env python2
# -*- mode: Python; coding: utf-8 -*-
"""Distutils-based setup script for Dim.
Dim is a pure-Python program, but it requires a few auto-generated
modules (definitions for the standard X cursor font and keysyms).
Since Distutils has no built-in support for auto-generated Python
modules, we'll add a custom command ("generate_py") and associated
infrastructure (subclasses of "Distribution" and "build" that are
aware of the new command and its options). The actual generation
routines are in their own modules, which export a simple functional
interface that we use here.
We also add a new "test" command, which executes the test suite.
The test suite must be run on a display that does not already have
a window manager running; a nesting X server such as Xephyr or Xnest
may be useful here."""
from contextlib import contextmanager
from glob import glob
import os
from distutils.cmd import Command
from distutils.command.build import build as _build
from distutils.core import Distribution as _Distribution, setup
from distutils.dep_util import newer
from distutils.errors import *
from distutils import log
from unittest import TestLoader, TextTestRunner
from dim.util.makecursorfont import make_cursor_font
from dim.util.makekeysymdef import make_keysym_def
class AutogenDistribution(_Distribution):
# Declare options for auto-generation command.
autogen_modules = None
autogen_source_dirs = None
def has_autogen_modules(self):
return self.autogen_modules and len(self.autogen_modules) > 0
class AutogenCommand(Command):
def has_autogen_modules(self):
return self.distribution.has_autogen_modules()
sub_commands = [("generate_py", has_autogen_modules)]
class generate_py(Command):
description = "auto-generate Python modules"
user_options = [("source-dirs=", "S",
"list of directories to search for source files"
" (separated by '%s')" % os.pathsep),
("force", "f", "force auto-(re)generation")]
boolean_options = ["force"]
def initialize_options(self):
self.source_dirs = None
self.force = None
def finalize_options(self):
self.set_undefined_options("build", ("force", "force"))
self.autogen_modules = self.distribution.autogen_modules
if self.source_dirs is None:
self.source_dirs = self.distribution.autogen_source_dirs or []
if isinstance(self.source_dirs, basestring):
self.source_dirs = self.source_dirs.split(os.pathsep)
def run(self):
build_py = self.get_finalized_command("build_py")
for source, module, generator in self.autogen_modules:
path = module.split(".")
package = ".".join(path[0:-1])
package_dir = build_py.get_package_dir(package)
module_base = path[-1]
module_filename = os.path.join(package_dir, module_base + ".py")
for source_dir in self.source_dirs:
source_filename = os.path.join(source_dir, source)
if os.path.exists(source_filename):
break
else:
raise DistutilsFileError("can't find source file '%s'" % source)
if self.force or newer(source_filename, module_filename):
log.info("generating %s from %s" % (module_filename,
source_filename))
if not self.dry_run:
with open(source_filename, "r") as input_file:
with open(module_filename, "w") as output_file:
generator(input_file, output_file)
class build(_build, AutogenCommand):
# Sub-commands are run in order, and auto-generation must precede the
# other build commands.
sub_commands = AutogenCommand.sub_commands + _build.sub_commands
class TestDistribution(_Distribution):
# Declare options for test command.
test_packages = None
test_modules = None
@contextmanager
def display(display_name):
"""Execute a block with the DISPLAY environment variable rebound."""
original_display = os.environ.get("DISPLAY")
if display_name:
os.environ["DISPLAY"] = display_name
try:
yield
finally:
if original_display:
os.environ["DISPLAY"] = original_display
elif display_name:
del os.environ["DISPLAY"]
class test(AutogenCommand):
description = "execute the test suite"
user_options = [("display=", "d", "the X server to contact")]
def initialize_options(self):
self.display = None
def finalize_options(self):
self.test_packages = self.distribution.test_packages or []
self.test_modules = self.distribution.test_modules or []
def run(self):
for cmd_name in self.get_sub_commands():
self.run_command(cmd_name)
build_py = self.get_finalized_command("build_py")
test_names = self.test_modules
for package in self.test_packages:
package_dir = build_py.get_package_dir(package)
for pkg, module, f in build_py.find_package_modules(package,
package_dir):
if module != "__init__":
test_names.append(".".join([pkg, module]))
tests = TestLoader().loadTestsFromNames(test_names)
with display(self.display):
TextTestRunner(verbosity=self.verbose).run(tests)
class Distribution(AutogenDistribution, TestDistribution):
pass
setup(name="dim",
version="0.1",
description="A window manager for the X window system",
author="Alex Plotnick",
author_email="shrike@netaxs.com",
scripts=["bin/dim"],
packages=["dim", "dim.test", "dim.util"],
test_packages=["dim.test"],
autogen_modules=[("cursorfont.h", "dim.cursorfont", make_cursor_font),
("keysymdef.h", "dim.keysymdef", make_keysym_def)],
autogen_source_dirs=["/usr/local/include/X11", "/usr/include/X11"],
cmdclass={"build": build, "generate_py": generate_py, "test": test},
distclass=Distribution)