forked from SciTools/iris
-
Notifications
You must be signed in to change notification settings - Fork 0
/
setup.py
125 lines (91 loc) · 3.52 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
from contextlib import contextmanager
import os
from shutil import copyfile
import sys
from setuptools import Command, setup
from setuptools.command.build_py import build_py
from setuptools.command.develop import develop as develop_cmd
@contextmanager
def temporary_path(directory):
"""
Context manager that adds and subsequently removes the given directory
to sys.path
"""
sys.path.insert(0, directory)
try:
yield
finally:
del sys.path[0]
# Add full path so Python doesn't load any __init__.py in the intervening
# directories, thereby saving setup.py from additional dependencies.
with temporary_path("lib/iris/tests/runner"):
from _runner import TestRunner # noqa:
class SetupTestRunner(TestRunner, Command):
pass
class BaseCommand(Command):
"""A valid no-op command for setuptools & distutils."""
description = "A no-op command."
user_options = []
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
pass
class CleanSource(BaseCommand):
description = "clean orphaned pyc/pyo files from the source directory"
def run(self):
for root_path, dir_names, file_names in os.walk("lib"):
for file_name in file_names:
if file_name.endswith("pyc") or file_name.endswith("pyo"):
compiled_path = os.path.join(root_path, file_name)
source_path = compiled_path[:-1]
if not os.path.exists(source_path):
print("Cleaning", compiled_path)
os.remove(compiled_path)
def copy_copyright(cmd, directory):
# Copy the COPYRIGHT information into the package root
iris_build_dir = os.path.join(directory, "iris")
for fname in ["COPYING", "COPYING.LESSER"]:
copyfile(fname, os.path.join(iris_build_dir, fname))
def build_std_names(cmd, directory):
# Call out to tools/generate_std_names.py to build std_names module.
script_path = os.path.join("tools", "generate_std_names.py")
xml_path = os.path.join("etc", "cf-standard-name-table.xml")
module_path = os.path.join(directory, "iris", "std_names.py")
args = (sys.executable, script_path, xml_path, module_path)
cmd.spawn(args)
def custom_cmd(command_to_override, functions, help_doc=""):
"""
Allows command specialisation to include calls to the given functions.
"""
class ExtendedCommand(command_to_override):
description = help_doc or command_to_override.description
def run(self):
# Run the original command first to make sure all the target
# directories are in place.
command_to_override.run(self)
# build_lib is defined if we are building the package. Otherwise
# we want to to the work in-place.
dest = getattr(self, "build_lib", None)
if dest is None:
print(" [Running in-place]")
# Pick the source dir instead (currently in the sub-dir "lib")
dest = "lib"
for func in functions:
func(self, dest)
return ExtendedCommand
custom_commands = {
"test": SetupTestRunner,
"develop": custom_cmd(develop_cmd, [build_std_names]),
"build_py": custom_cmd(build_py, [build_std_names, copy_copyright]),
"std_names": custom_cmd(
BaseCommand,
[build_std_names],
help_doc="generate CF standard name module",
),
"clean_source": CleanSource,
}
setup(
cmdclass=custom_commands,
)