aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSix <unknown>2010-12-11 18:09:41 -0500
committerSix <unknown>2010-12-11 18:09:41 -0500
commit797a5819e43b1fe35a7ef21afb9810d37e496069 (patch)
tree218122bc019acff85515f883a33aafde56132c1f
parent09a34696d529e1686970df5cf1555e160fd0c8f3 (diff)
downloaddodai-macsupport-797a5819e43b1fe35a7ef21afb9810d37e496069.tar.bz2
dodai-macsupport-797a5819e43b1fe35a7ef21afb9810d37e496069.tar.xz
dodai-macsupport-797a5819e43b1fe35a7ef21afb9810d37e496069.zip
added build code
-rw-r--r--.hgignore6
-rw-r--r--lib/dodai/build/__init__.py216
-rw-r--r--lib/dodai/build/after_install.py84
3 files changed, 302 insertions, 4 deletions
diff --git a/.hgignore b/.hgignore
index b3dab9e..b4caba7 100644
--- a/.hgignore
+++ b/.hgignore
@@ -1,9 +1,7 @@
1syntax: glob 1syntax: glob
2*.pyc 2*.pyc
3*.pyo
3*~ 4*~
4*.kpf
5bin
6include
7lib
8.coverage 5.coverage
9examples/config/example.log 6examples/config/example.log
7lib/dodai.egg-info
diff --git a/lib/dodai/build/__init__.py b/lib/dodai/build/__init__.py
new file mode 100644
index 0000000..c4989be
--- /dev/null
+++ b/lib/dodai/build/__init__.py
@@ -0,0 +1,216 @@
1from setuptools.command.easy_install import easy_install
2from distutils.util import convert_path
3from pkg_resources import Distribution, PathMetadata, normalize_path
4from distutils import log
5from distutils.errors import *
6import sys, os, setuptools, glob
7import virtualenv
8import textwrap
9import tempfile
10import subprocess
11import stat
12import pprint
13
14
15
16class Filler(object):
17
18 TAB_WIDTH = 4
19 TAB_CHAR = ' '
20 LINE_LEN = 79
21
22 def __init__(self, indent):
23 self._obj = None
24 self.initial_indent = self.TAB_CHAR*self.TAB_WIDTH*indent
25 indent+=1
26 self.subsequent_indent = self.TAB_CHAR*self.TAB_WIDTH*indent
27
28 def __call__(self, text):
29 text = text.rstrip()
30 return self.process(text)
31
32 @property
33 def obj(self):
34 if not self._obj:
35 self._obj = textwrap.TextWrapper(
36 width=self.LINE_LEN,
37 initial_indent=self.initial_indent,
38 subsequent_indent=self.subsequent_indent,
39 )
40 return self._obj.fill
41
42 def process(self, text):
43 out = []
44 text = textwrap.dedent(text)
45 obj = self.obj
46 lines = text.split('\n')
47 for line in lines:
48 out.append(self.obj(line))
49 return '\n'.join(out)
50
51
52class AfterInstallActionBase(object):
53
54 def _quote_list(self, data):
55 if isinstance(data, basestring):
56 out = ["'{0}'".format(data)]
57 else:
58 out = ["'{0}'".format(d) for d in data]
59 return ', '.join(out)
60
61class EasyInstall(AfterInstallActionBase):
62
63 CODE = """
64 for package in [{packages}]:
65 easy_install(package)
66 """
67
68 def __init__(self, packages):
69 self.packages = self._quote_list(packages)
70 self.fill = Filler(1)
71
72 def __call__(self):
73 code = self.CODE.format(packages=self.packages)
74 return self.fill(code)
75
76
77class HgClone(AfterInstallActionBase):
78
79 CODE = """
80 hg_clone('{url}', '{dest}')
81 """
82
83 def __init__(self, url, dest):
84 self.url = url
85 self.dest = dest
86 self.fill = Filler(1)
87
88 def __call__(self):
89 code = self.CODE.format(url=self.url, dest=self.dest)
90 return self.fill(code)
91
92
93class RunSetupCommand(AfterInstallActionBase):
94
95 CODE = """
96 for dir in [{dirs}]:
97 setup_py(dir, {command})
98 """
99
100 def __init__(self, dirs, command):
101 self.dirs = self._quote_list(dirs)
102 self.command = repr(command).strip('[]()')
103 self.fill = Filler(1)
104
105 def __call__(self):
106 code = self.CODE.format(dirs=self.dirs, command=self.command)
107 return self.fill(code)
108
109
110class RunPythonPrograms(AfterInstallActionBase):
111
112 CODE = """
113 for program in [{programs}]:
114 run_program(program)
115 """
116
117 def __init__(self, programs):
118 self.programs = self._quote_list(programs)
119 self.fill = Filler(1)
120
121 def __call__(self):
122 code = self.CODE.format(programs=self.programs)
123 return self.fill(code)
124
125
126class AfterInstall(object):
127
128 FILE = 'after_install.py'
129
130 CODE = '''
131 def after_install(options, home_dir):
132 paths = build_paths(home_dir)
133 easy_install = EasyInstall(paths)
134 hg_clone = HgClone(paths)
135 setup_py = SetupPy(paths)
136 run_program = RunPythonProgram(paths)
137 '''
138 def __init__(self):
139 self.fill = Filler(0)
140 self._code_from_file_ = None
141
142 @property
143 def _code_from_file(self):
144 if not self._code_from_file_:
145 path = os.path.dirname(os.path.realpath(__file__))
146 path = os.path.join(path, self.FILE)
147 fp = open(path, 'r')
148 self._code_from_file_ = fp.read()
149 fp.close()
150 return self._code_from_file_
151
152 def __call__(self, chain):
153 out = [self._code_from_file, self.fill(self.CODE)]
154 for obj in chain:
155 out.append(obj())
156 out = ''.join(out)
157 return out
158
159
160class VirtualEnvDev(object):
161
162 NAME = 'devstrap.py'
163 PACKAGES = ['nose', 'virtualenv', 'ipython', 'mercurial', 'pylint']
164 HG_URL = 'hg clone https://dodai.googlecode.com/hg'
165 HG_DEST = 'src'
166 AFTER_BUILD = []
167
168 def __init__(self, path, name):
169 self.name = '{0}-{1}'.format(name, self.NAME)
170 self.path = os.path.join(path, self.name)
171
172 def __call__(self):
173 self._write()
174 print "File Built: {0}".format(self.path)
175
176 def _write(self):
177 with open(self.path, 'w') as f:
178 f.write(self._data)
179
180 @property
181 def _after_install(self):
182 chain = [
183 EasyInstall(self.PACKAGES),
184 HgClone(self.HG_URL, self.HG_DEST),
185 RunSetupCommand(self.HG_DEST, 'develop'),
186 RunPythonPrograms(self.AFTER_BUILD)
187 ]
188 obj = AfterInstall()
189 return obj(chain)
190
191 @property
192 def _data(self):
193 return virtualenv.create_bootstrap_script(self._after_install)
194
195
196class devstrap(easy_install):
197
198 description = 'create a devstrap file used for installing a dev env'
199
200 user_options = easy_install.user_options
201 boolean_options = easy_install.boolean_options
202 command_consumes_arguments = False
203
204 def run(self):
205 virtual_env = VirtualEnvDev(self.prefix, self.distribution.get_name())
206 virtual_env()
207
208 def initialize_options(self):
209 easy_install.initialize_options(self)
210
211 def finalize_options(self):
212 if self.prefix:
213 if not os.path.exists(self.prefix):
214 os.makedirs(self.prefix)
215 else:
216 self.prefix = os.getcwd()
diff --git a/lib/dodai/build/after_install.py b/lib/dodai/build/after_install.py
new file mode 100644
index 0000000..16c1ec6
--- /dev/null
+++ b/lib/dodai/build/after_install.py
@@ -0,0 +1,84 @@
1import os
2from collections import namedtuple
3from subprocess import Popen
4from subprocess import call
5from subprocess import PIPE
6
7def build_paths(home_dir):
8
9 obj = namedtuple('Paths', 'wd, home, bin, src, python')
10
11 wd = os.getcwd()
12 if home_dir.startswith(os.sep):
13 home = home_dir
14 else:
15 home = os.path.realpath(os.path.join(wd, home_dir))
16 bin = os.path.join(home, 'bin')
17 src = os.path.join(home, 'src')
18 python = os.path.join(bin, 'python')
19
20 return obj(wd, home, bin, src, python)
21
22
23class EasyInstall(object):
24
25 def __init__(self, paths):
26 self._easy_install = os.path.join(paths.bin, 'easy_install')
27
28 def __call__(self, package):
29 cmd = [self._easy_install, '-Uv', package]
30 call(cmd)
31
32
33class HgClone(object):
34
35 def __init__(self, paths, easy_install=EasyInstall):
36 self._easy_install = easy_install(paths)
37 self._paths = paths
38 self._hg_ = None
39
40 @property
41 def _hg(self):
42 if not self._hg_:
43 cmd = ['which', 'hg']
44 self._hg_ = Popen(cmd, stdout=PIPE, stderr=PIPE).communicate()[0]\
45 .strip()
46 if not self._hg_:
47 self._hg_ = os.path.join(self._paths.bin, 'hg')
48 if not os.path.exists(self._hg_):
49 self._easy_install('mercurial')
50 return self._hg_
51
52 def __call__(self, url, dest):
53 if not dest.startswith(os.sep):
54 dest = os.path.join(self._paths.home, dest)
55 cmd = [self._hg, 'clone', url, dest]
56 call(cmd)
57
58
59class SetupPy(object):
60
61 FILE = 'setup.py'
62
63 def __init__(self, paths):
64 self._paths = paths
65
66 def __call__(self, dir, command):
67 path = os.path.join(self._paths.home, dir)
68 name = os.path.join(path, self.FILE)
69 if os.path.exists(name):
70 os.chdir(path)
71 cmd = [self._paths.python, name, command]
72 call(cmd)
73
74class RunPythonProgram(object):
75
76 def __init__(self, paths):
77 self._paths = paths
78
79 def __call__(self, program):
80 path = os.path.join(self._paths.bin, program)
81 if os.path.exists(path):
82 cmd = [self._paths.python, path]
83 call(cmd)
84