1 |
--- |
2 |
.gitignore | 1 + |
3 |
Makefile | 215 -------------------- |
4 |
doc/Makefile | 11 - |
5 |
pym/portage/const.py | 4 +- |
6 |
setup.py | 557 +++++++++++++++++++++++++++++++++++++++++++++++++++ |
7 |
5 files changed, 560 insertions(+), 228 deletions(-) |
8 |
delete mode 100644 Makefile |
9 |
delete mode 100644 doc/Makefile |
10 |
create mode 100755 setup.py |
11 |
|
12 |
diff --git a/.gitignore b/.gitignore |
13 |
index 074bb86..c2dd534 100644 |
14 |
--- a/.gitignore |
15 |
+++ b/.gitignore |
16 |
@@ -1,4 +1,5 @@ |
17 |
*.py[co] |
18 |
__pycache__/ |
19 |
*.class |
20 |
+/build |
21 |
/tags |
22 |
diff --git a/Makefile b/Makefile |
23 |
deleted file mode 100644 |
24 |
index 9eb6e66..0000000 |
25 |
--- a/Makefile |
26 |
+++ /dev/null |
27 |
@@ -1,215 +0,0 @@ |
28 |
-SHELL = /bin/sh |
29 |
-PN ?= portage |
30 |
-PF ?= portage |
31 |
-HOMEPAGE ?= http://www.gentoo.org/proj/en/portage/index.xml |
32 |
-PWD ?= $(shell pwd) |
33 |
-S ?= $(PWD) |
34 |
-WORKDIR ?= $(PWD) |
35 |
-DESTDIR = $(PWD)/image/ |
36 |
-srcdir = $(S) |
37 |
-prefix = /usr |
38 |
-sysconfdir = /etc |
39 |
-exec_prefix = $(prefix) |
40 |
-bindir = $(exec_prefix)/bin |
41 |
-sbindir = $(exec_prefix)/sbin |
42 |
-libdir = $(exec_prefix)/lib |
43 |
-datarootdir = $(prefix)/share |
44 |
-datadir = $(datarootdir) |
45 |
-mandir = $(datarootdir)/man |
46 |
-docdir = $(datarootdir)/doc/$(PF) |
47 |
-htmldir = $(docdir)/html |
48 |
-portage_datadir = $(datarootdir)/$(PN) |
49 |
-portage_confdir = $(portage_datadir)/config |
50 |
-portage_setsdir = $(portage_confdir)/sets |
51 |
-portage_base = $(libdir)/$(PN) |
52 |
-EPYDOC_OPTS = -qqqqq --no-frames --show-imports |
53 |
-INSMODE = 0644 |
54 |
-EXEMODE = 0755 |
55 |
-DIRMODE = 0755 |
56 |
-SYSCONFDIR_FILES = etc-update.conf dispatch-conf.conf |
57 |
-PORTAGE_CONFDIR_FILES = make.conf.example make.globals repos.conf |
58 |
-LOGROTATE_FILES = elog-save-summary |
59 |
-BINDIR_FILES = ebuild egencache emerge emerge-webrsync \ |
60 |
- emirrordist portageq quickpkg repoman |
61 |
-SBINDIR_FILES = archive-conf dispatch-conf emaint \ |
62 |
- env-update etc-update fixpackages regenworld |
63 |
-DOCS = ChangeLog NEWS RELEASE-NOTES |
64 |
-LINGUAS ?= $(shell cd "$(srcdir)/man" && find -mindepth 1 -type d) |
65 |
- |
66 |
-ifdef PYTHONPATH |
67 |
- PYTHONPATH := $(srcdir)/pym:$(PYTHONPATH) |
68 |
-else |
69 |
- PYTHONPATH := $(srcdir)/pym |
70 |
-endif |
71 |
- |
72 |
-all: docbook epydoc |
73 |
- |
74 |
-docbook: |
75 |
- set -e; \ |
76 |
- touch "$(srcdir)/doc/fragment/date"; \ |
77 |
- $(MAKE) -C "$(srcdir)/doc" xhtml xhtml-nochunks |
78 |
- |
79 |
-epydoc: |
80 |
- set -e; \ |
81 |
- env PYTHONPATH="$(PYTHONPATH)" epydoc \ |
82 |
- -o "$(WORKDIR)/epydoc" \ |
83 |
- --name $(PN) \ |
84 |
- --url "$(HOMEPAGE)" \ |
85 |
- $(EPYDOC_OPTS) \ |
86 |
- $$(cd "$(srcdir)" && find pym -name '*.py' | sed \ |
87 |
- -e s:/__init__.py$$:: \ |
88 |
- -e s:\.py$$:: \ |
89 |
- -e s:^pym/:: \ |
90 |
- -e s:/:.:g \ |
91 |
- | sort); \ |
92 |
- rm -f "$(WORKDIR)/epydoc/api-objects.txt"; \ |
93 |
- |
94 |
-test: |
95 |
- set -e; \ |
96 |
- "$(srcdir)/pym/portage/tests/runTests.py"; \ |
97 |
- |
98 |
-install: |
99 |
- set -e; \ |
100 |
- cd "$(srcdir)/cnf"; \ |
101 |
- install -d -m$(DIRMODE) "$(DESTDIR)$(sysconfdir)"; \ |
102 |
- install -m$(INSMODE) $(SYSCONFDIR_FILES) "$(DESTDIR)$(sysconfdir)"; \ |
103 |
- \ |
104 |
- install -d -m$(DIRMODE) "$(DESTDIR)$(portage_confdir)"; \ |
105 |
- cd "$(srcdir)/cnf"; \ |
106 |
- install -m$(INSMODE) $(PORTAGE_CONFDIR_FILES) \ |
107 |
- "$(DESTDIR)$(portage_confdir)"; \ |
108 |
- install -d -m$(DIRMODE) "$(DESTDIR)$(portage_setsdir)"; \ |
109 |
- cd "$(S)/cnf/sets"; \ |
110 |
- install -m$(INSMODE) *.conf "$(DESTDIR)$(portage_setsdir)"; \ |
111 |
- \ |
112 |
- install -d -m$(DIRMODE) "$(DESTDIR)$(sysconfdir)/logrotate.d"; \ |
113 |
- cd "$(srcdir)/cnf/logrotate.d"; \ |
114 |
- install -m$(INSMODE) $(LOGROTATE_FILES) \ |
115 |
- "$(DESTDIR)$(sysconfdir)/logrotate.d"; \ |
116 |
- \ |
117 |
- for x in $$(cd "$(srcdir)" && find bin -type d) ; do \ |
118 |
- cd "$(srcdir)/$$x"; \ |
119 |
- install -d -m$(DIRMODE) "$(DESTDIR)$(portage_base)/$$x"; \ |
120 |
- files=$$(find . -mindepth 1 -maxdepth 1 -type f ! -type l); \ |
121 |
- if [ -n "$$files" ] ; then \ |
122 |
- install -m$(EXEMODE) $$files \ |
123 |
- "$(DESTDIR)$(portage_base)/$$x"; \ |
124 |
- fi; \ |
125 |
- symlinks=$$(find . -mindepth 1 -maxdepth 1 -type l); \ |
126 |
- if [ -n "$$symlinks" ] ; then \ |
127 |
- cp -P $$symlinks "$(DESTDIR)$(portage_base)/$$x"; \ |
128 |
- fi; \ |
129 |
- done; \ |
130 |
- \ |
131 |
- for x in $$(cd "$(srcdir)" && find pym/* -type d \ |
132 |
- ! -path "pym/portage/tests*") ; do \ |
133 |
- cd "$(srcdir)/$$x"; \ |
134 |
- files=$$(echo *.py); \ |
135 |
- if [ -z "$$files" ] || [ "$$files" = "*.py" ]; then \ |
136 |
- # __pycache__ directories contain no py files \ |
137 |
- continue; \ |
138 |
- fi; \ |
139 |
- install -d -m$(DIRMODE) "$(DESTDIR)$(portage_base)/$$x"; \ |
140 |
- install -m$(INSMODE) $$files "$(DESTDIR)$(portage_base)/$$x"; \ |
141 |
- done; \ |
142 |
- \ |
143 |
- install -d -m$(DIRMODE) "$(DESTDIR)$(bindir)"; \ |
144 |
- relative_path=".."; \ |
145 |
- x=$(bindir) ; \ |
146 |
- y="$(portage_base)"; \ |
147 |
- if [ "$${x#$(prefix)}" != "$$x" ] && \ |
148 |
- [ "$${y#$(prefix)}" != "$$y" ]; then \ |
149 |
- x=$${x#$(prefix)}; \ |
150 |
- y=$${y#$(prefix)}; \ |
151 |
- fi; \ |
152 |
- x=$${x%/*}; \ |
153 |
- while [ -n "$$x" ] ; do \ |
154 |
- relative_path=$${relative_path}/..; \ |
155 |
- x=$${x%/*}; \ |
156 |
- done; \ |
157 |
- relative_path=$$relative_path$$y; \ |
158 |
- for x in $(BINDIR_FILES) ; do \ |
159 |
- ln -sf "$$relative_path/bin/$$x" \ |
160 |
- "$(DESTDIR)$(bindir)/$$x"; \ |
161 |
- done; \ |
162 |
- \ |
163 |
- install -d -m$(DIRMODE) "$(DESTDIR)$(sbindir)"; \ |
164 |
- relative_path=".."; \ |
165 |
- x=$(sbindir) ; \ |
166 |
- y="$(portage_base)"; \ |
167 |
- if [ "$${x#$(prefix)}" != "$$x" ] && \ |
168 |
- [ "$${y#$(prefix)}" != "$$y" ]; then \ |
169 |
- x=$${x#$(prefix)}; \ |
170 |
- y=$${y#$(prefix)}; \ |
171 |
- fi; \ |
172 |
- x=$${x%/*}; \ |
173 |
- while [ -n "$$x" ] ; do \ |
174 |
- relative_path=$${relative_path}/..; \ |
175 |
- x=$${x%/*}; \ |
176 |
- done; \ |
177 |
- relative_path=$$relative_path$$y; \ |
178 |
- for x in $(SBINDIR_FILES) ; do \ |
179 |
- ln -sf "$$relative_path/bin/$$x" \ |
180 |
- "$(DESTDIR)$(sbindir)/$$x"; \ |
181 |
- done; \ |
182 |
- \ |
183 |
- ln -sf "$$relative_path/bin/env-update" \ |
184 |
- "$(DESTDIR)$(sbindir)/update-env"; \ |
185 |
- ln -sf "$$relative_path/bin/etc-update" \ |
186 |
- "$(DESTDIR)$(sbindir)/update-etc"; \ |
187 |
- \ |
188 |
- # We install some minimal tests for use as a preinst sanity check. \ |
189 |
- # These tests must be able to run without a full source tree and \ |
190 |
- # without relying on a previous portage instance being installed. \ |
191 |
- install -d -m$(DIRMODE) \ |
192 |
- "$(DESTDIR)$(portage_base)/pym/portage/tests"; \ |
193 |
- install -m$(EXEMODE) "$(srcdir)/pym/portage/tests/runTests" \ |
194 |
- "$(DESTDIR)$(portage_base)/pym/portage/tests"; \ |
195 |
- cd "$(srcdir)/pym/portage/tests"; \ |
196 |
- install -m$(INSMODE) *.py \ |
197 |
- "$(DESTDIR)$(portage_base)/pym/portage/tests"; \ |
198 |
- install -d -m$(DIRMODE) \ |
199 |
- "$(DESTDIR)$(portage_base)/pym/portage/tests/lint"; \ |
200 |
- cd "$(srcdir)/pym/portage/tests/lint"; \ |
201 |
- install -m$(INSMODE) *.py __test__ \ |
202 |
- "$(DESTDIR)$(portage_base)/pym/portage/tests/lint"; \ |
203 |
- \ |
204 |
- install -d -m$(DIRMODE) "$(DESTDIR)$(docdir)"; \ |
205 |
- cd "$(srcdir)"; \ |
206 |
- install -m $(INSMODE) $(DOCS) "$(DESTDIR)$(docdir)"; \ |
207 |
- \ |
208 |
- for x in "" $(LINGUAS); do \ |
209 |
- for y in 1 5 ; do \ |
210 |
- if [ -d "$(srcdir)/man/$$x" ]; then \ |
211 |
- cd "$(srcdir)/man/$$x"; \ |
212 |
- files=$$(echo *.$$y); \ |
213 |
- if [ -z "$$files" ] || [ "$$files" = "*.$$y" ]; then \ |
214 |
- continue; \ |
215 |
- fi; \ |
216 |
- install -d -m$(DIRMODE) "$(DESTDIR)$(mandir)/$$x/man$$y"; \ |
217 |
- install -m$(INSMODE) *.$$y "$(DESTDIR)$(mandir)/$$x/man$$y"; \ |
218 |
- fi; \ |
219 |
- done; \ |
220 |
- done; \ |
221 |
- \ |
222 |
- if [ -f "$(srcdir)/doc/portage.html" ] ; then \ |
223 |
- install -d -m$(DIRMODE) "$(DESTDIR)$(htmldir)"; \ |
224 |
- cd "$(srcdir)/doc"; \ |
225 |
- install -m$(INSMODE) *.html "$(DESTDIR)$(htmldir)"; \ |
226 |
- fi; \ |
227 |
- \ |
228 |
- if [ -d "$(WORKDIR)/epydoc" ] ; then \ |
229 |
- install -d -m$(DIRMODE) "$(DESTDIR)$(htmldir)"; \ |
230 |
- cp -pPR "$(WORKDIR)/epydoc" \ |
231 |
- "$(DESTDIR)$(htmldir)/api"; \ |
232 |
- cd "$(DESTDIR)$(htmldir)/api"; \ |
233 |
- find . -type d | xargs chmod $(DIRMODE); \ |
234 |
- find . -type f | xargs chmod $(INSMODE); \ |
235 |
- fi; \ |
236 |
- |
237 |
-clean: |
238 |
- set -e; \ |
239 |
- $(MAKE) -C "$(srcdir)/doc" clean; \ |
240 |
- rm -rf "$(WORKDIR)/epydoc"; \ |
241 |
- |
242 |
-.PHONY: all clean docbook epydoc install test |
243 |
diff --git a/doc/Makefile b/doc/Makefile |
244 |
deleted file mode 100644 |
245 |
index 261a0b4..0000000 |
246 |
--- a/doc/Makefile |
247 |
+++ /dev/null |
248 |
@@ -1,11 +0,0 @@ |
249 |
-all: xhtml xhtml-nochunks |
250 |
- |
251 |
-XMLTO_FLAGS = -m custom.xsl |
252 |
-man pdf txt xhtml xhtml-nochunks: |
253 |
- xmlto $@ $(XMLTO_FLAGS) portage.docbook |
254 |
- |
255 |
-clean distclean: |
256 |
- rm -f *.1 *.html portage.txt |
257 |
- |
258 |
-.PHONY: all clean distclean \ |
259 |
- man pdf txt xhtml xhtml-nochunks |
260 |
diff --git a/pym/portage/const.py b/pym/portage/const.py |
261 |
index f518b47..acb90f9 100644 |
262 |
--- a/pym/portage/const.py |
263 |
+++ b/pym/portage/const.py |
264 |
@@ -60,8 +60,8 @@ GLOBAL_CONFIG_PATH = "/usr/share/portage/config" |
265 |
# these variables are not used with target_root or config_root |
266 |
# NOTE: Use realpath(__file__) so that python module symlinks in site-packages |
267 |
# are followed back to the real location of the whole portage installation. |
268 |
-PORTAGE_BASE_PATH = os.path.join(os.sep, os.sep.join(os.path.realpath( |
269 |
- __file__.rstrip("co")).split(os.sep)[:-3])) |
270 |
+# NOTE: Please keep PORTAGE_BASE_PATH in one line to help substitutions. |
271 |
+PORTAGE_BASE_PATH = os.path.join(os.sep, os.sep.join(os.path.realpath(__file__.rstrip("co")).split(os.sep)[:-3])) |
272 |
PORTAGE_BIN_PATH = PORTAGE_BASE_PATH + "/bin" |
273 |
PORTAGE_PYM_PATH = os.path.realpath(os.path.join(__file__, '../..')) |
274 |
LOCALE_DATA_PATH = PORTAGE_BASE_PATH + "/locale" # FIXME: not used |
275 |
diff --git a/setup.py b/setup.py |
276 |
new file mode 100755 |
277 |
index 0000000..bd6e506 |
278 |
--- /dev/null |
279 |
+++ b/setup.py |
280 |
@@ -0,0 +1,557 @@ |
281 |
+#!/usr/bin/env python |
282 |
+# vim:fileencoding=utf-8 |
283 |
+# (c) 2010 Michał Górny <mgorny@g.o> |
284 |
+# Released under the terms of the 2-clause BSD license. |
285 |
+ |
286 |
+from distutils.core import setup, Command |
287 |
+from distutils.command.build_scripts import build_scripts |
288 |
+from distutils.command.clean import clean |
289 |
+from distutils.command.install import install |
290 |
+from distutils.command.install_data import install_data |
291 |
+from distutils.command.install_lib import install_lib |
292 |
+from distutils.command.install_scripts import install_scripts |
293 |
+from distutils.dir_util import remove_tree |
294 |
+from distutils.util import change_root, subst_vars |
295 |
+ |
296 |
+import codecs, collections, glob, os, os.path, re, subprocess, sys |
297 |
+ |
298 |
+# TODO: |
299 |
+# - smarter rebuilds of docs w/ 'install_docbook' and 'install_epydoc'. |
300 |
+ |
301 |
+package_name = 'portage' |
302 |
+package_version = '2.2.12' |
303 |
+package_homepage = 'https://wiki.gentoo.org/wiki/Project:Portage' |
304 |
+ |
305 |
+x_scripts = { |
306 |
+ 'bin': [ |
307 |
+ 'bin/ebuild', 'bin/egencache', 'bin/emerge', 'bin/emerge-webrsync', |
308 |
+ 'bin/emirrordist', 'bin/portageq', 'bin/quickpkg', 'bin/repoman' |
309 |
+ ], |
310 |
+ 'sbin': [ |
311 |
+ 'bin/archive-conf', 'bin/dispatch-conf', 'bin/emaint', 'bin/env-update', |
312 |
+ 'bin/etc-update', 'bin/fixpackages', 'bin/regenworld' |
313 |
+ ], |
314 |
+} |
315 |
+ |
316 |
+ |
317 |
+class docbook(Command): |
318 |
+ """ Build docs using docbook. """ |
319 |
+ |
320 |
+ user_options = [ |
321 |
+ ('doc-formats=', None, 'Documentation formats to build (all xmlto formats for docbook are allowed, comma-separated'), |
322 |
+ ] |
323 |
+ |
324 |
+ def initialize_options(self): |
325 |
+ self.doc_formats = 'xhtml,xhtml-nochunks' |
326 |
+ |
327 |
+ def finalize_options(self): |
328 |
+ self.doc_formats = self.doc_formats.replace(',', ' ').split() |
329 |
+ |
330 |
+ def run(self): |
331 |
+ with open('doc/fragment/date', 'w'): |
332 |
+ pass |
333 |
+ |
334 |
+ for f in self.doc_formats: |
335 |
+ print('Building docs in %s format...' % f) |
336 |
+ subprocess.check_call(['xmlto', '-o', 'doc', |
337 |
+ '-m', 'doc/custom.xsl', f, 'doc/portage.docbook']) |
338 |
+ |
339 |
+ |
340 |
+class epydoc(Command): |
341 |
+ """ Build API docs using epydoc. """ |
342 |
+ |
343 |
+ user_options = [ |
344 |
+ ] |
345 |
+ |
346 |
+ def initialize_options(self): |
347 |
+ self.build_lib = None |
348 |
+ |
349 |
+ def finalize_options(self): |
350 |
+ self.set_undefined_options('build_py', ('build_lib', 'build_lib')) |
351 |
+ |
352 |
+ def run(self): |
353 |
+ self.run_command('build_py') |
354 |
+ |
355 |
+ print('Building API documentation...') |
356 |
+ |
357 |
+ process_env = os.environ.copy() |
358 |
+ pythonpath = self.build_lib |
359 |
+ try: |
360 |
+ pythonpath += ':' + process_env['PYTHONPATH'] |
361 |
+ except KeyError: |
362 |
+ pass |
363 |
+ process_env['PYTHONPATH'] = pythonpath |
364 |
+ |
365 |
+ subprocess.check_call(['epydoc', '-o', 'epydoc', |
366 |
+ '--name', package_name, |
367 |
+ '--url', package_homepage, |
368 |
+ '-qq', '--no-frames', '--show-imports', |
369 |
+ '--exclude', 'portage.tests', |
370 |
+ '_emerge', 'portage', 'repoman'], |
371 |
+ env = process_env) |
372 |
+ os.remove('epydoc/api-objects.txt') |
373 |
+ |
374 |
+ |
375 |
+class install_docbook(install_data): |
376 |
+ """ install_data for docbook docs """ |
377 |
+ |
378 |
+ user_options = install_data.user_options |
379 |
+ |
380 |
+ def initialize_options(self): |
381 |
+ install_data.initialize_options(self) |
382 |
+ self.htmldir = None |
383 |
+ |
384 |
+ def finalize_options(self): |
385 |
+ self.set_undefined_options('install', ('htmldir', 'htmldir')) |
386 |
+ install_data.finalize_options(self) |
387 |
+ |
388 |
+ def run(self): |
389 |
+ if not os.path.exists('doc/portage.html'): |
390 |
+ self.run_command('docbook') |
391 |
+ self.data_files = [ |
392 |
+ (self.htmldir, glob.glob('doc/*.html')), |
393 |
+ ] |
394 |
+ install_data.run(self) |
395 |
+ |
396 |
+ |
397 |
+class install_epydoc(install_data): |
398 |
+ """ install_data for epydoc docs """ |
399 |
+ |
400 |
+ user_options = install_data.user_options |
401 |
+ |
402 |
+ def initialize_options(self): |
403 |
+ install_data.initialize_options(self) |
404 |
+ self.htmldir = None |
405 |
+ |
406 |
+ def finalize_options(self): |
407 |
+ self.set_undefined_options('install', ('htmldir', 'htmldir')) |
408 |
+ install_data.finalize_options(self) |
409 |
+ |
410 |
+ def run(self): |
411 |
+ if not os.path.exists('epydoc/index.html'): |
412 |
+ self.run_command('epydoc') |
413 |
+ self.data_files = [ |
414 |
+ (os.path.join(self.htmldir, 'api'), glob.glob('epydoc/*')), |
415 |
+ ] |
416 |
+ install_data.run(self) |
417 |
+ |
418 |
+ |
419 |
+class x_build_scripts_custom(build_scripts): |
420 |
+ def finalize_options(self): |
421 |
+ build_scripts.finalize_options(self) |
422 |
+ if 'dir_name' in dir(self): |
423 |
+ self.build_dir = os.path.join(self.build_dir, self.dir_name) |
424 |
+ if self.dir_name in x_scripts: |
425 |
+ self.scripts = x_scripts[self.dir_name] |
426 |
+ else: |
427 |
+ self.scripts = set(self.scripts) |
428 |
+ for other_files in x_scripts.values(): |
429 |
+ self.scripts.difference_update(other_files) |
430 |
+ |
431 |
+ def run(self): |
432 |
+ # group scripts by subdirectory |
433 |
+ split_scripts = collections.defaultdict(list) |
434 |
+ for f in self.scripts: |
435 |
+ dir_name = os.path.dirname(f[len('bin/'):]) |
436 |
+ split_scripts[dir_name].append(f) |
437 |
+ |
438 |
+ base_dir = self.build_dir |
439 |
+ base_scripts = self.scripts |
440 |
+ for d, files in split_scripts.items(): |
441 |
+ self.build_dir = os.path.join(base_dir, d) |
442 |
+ self.scripts = files |
443 |
+ self.copy_scripts() |
444 |
+ |
445 |
+ # restore previous values |
446 |
+ self.build_dir = base_dir |
447 |
+ self.scripts = base_scripts |
448 |
+ |
449 |
+ |
450 |
+class x_build_scripts_bin(x_build_scripts_custom): |
451 |
+ dir_name = 'bin' |
452 |
+ |
453 |
+ |
454 |
+class x_build_scripts_sbin(x_build_scripts_custom): |
455 |
+ dir_name = 'sbin' |
456 |
+ |
457 |
+ |
458 |
+class x_build_scripts_portagebin(x_build_scripts_custom): |
459 |
+ dir_name = 'portage' |
460 |
+ |
461 |
+ |
462 |
+class x_build_scripts(build_scripts): |
463 |
+ def initialize_option(self): |
464 |
+ pass |
465 |
+ |
466 |
+ def finalize_options(self): |
467 |
+ pass |
468 |
+ |
469 |
+ def run(self): |
470 |
+ self.run_command('build_scripts_bin') |
471 |
+ self.run_command('build_scripts_portagebin') |
472 |
+ self.run_command('build_scripts_sbin') |
473 |
+ |
474 |
+ |
475 |
+class x_clean(clean): |
476 |
+ """ clean extended for doc & post-test cleaning """ |
477 |
+ |
478 |
+ def clean_docs(self): |
479 |
+ def get_doc_outfiles(): |
480 |
+ for dirpath, dirnames, filenames in os.walk('doc'): |
481 |
+ for f in filenames: |
482 |
+ if f.endswith('.docbook') or f == 'custom.xsl': |
483 |
+ pass |
484 |
+ else: |
485 |
+ yield os.path.join(dirpath, f) |
486 |
+ |
487 |
+ # do not recurse |
488 |
+ break |
489 |
+ |
490 |
+ |
491 |
+ for f in get_doc_outfiles(): |
492 |
+ print('removing %s' % repr(f)) |
493 |
+ os.remove(f) |
494 |
+ |
495 |
+ if os.path.isdir('epydoc'): |
496 |
+ remove_tree('epydoc') |
497 |
+ |
498 |
+ def clean_tests(self): |
499 |
+ # do not remove incorrect dirs accidentally |
500 |
+ top_dir = os.path.normpath(os.path.join(self.build_lib, '..')) |
501 |
+ cprefix = os.path.commonprefix((self.build_base, top_dir)) |
502 |
+ if cprefix != self.build_base: |
503 |
+ return |
504 |
+ |
505 |
+ bin_dir = os.path.join(top_dir, 'bin') |
506 |
+ if os.path.exists(bin_dir): |
507 |
+ remove_tree(bin_dir) |
508 |
+ |
509 |
+ conf_dir = os.path.join(top_dir, 'cnf') |
510 |
+ if os.path.islink(conf_dir): |
511 |
+ print('removing %s symlink' % repr(conf_dir)) |
512 |
+ os.unlink(conf_dir) |
513 |
+ |
514 |
+ pni_file = os.path.join(top_dir, '.portage_not_installed') |
515 |
+ if os.path.exists(pni_file): |
516 |
+ print('removing %s' % repr(pni_file)) |
517 |
+ os.unlink(pni_file) |
518 |
+ |
519 |
+ def run(self): |
520 |
+ if self.all: |
521 |
+ self.clean_tests() |
522 |
+ self.clean_docs() |
523 |
+ |
524 |
+ clean.run(self) |
525 |
+ |
526 |
+ |
527 |
+class x_install(install): |
528 |
+ """ install command with extra Portage paths """ |
529 |
+ |
530 |
+ user_options = install.user_options + [ |
531 |
+ # note: $prefix and $exec_prefix are reserved for Python install |
532 |
+ ('system-prefix=', None, "Prefix for architecture-independent data"), |
533 |
+ ('system-exec-prefix=', None, "Prefix for architecture-specific data"), |
534 |
+ |
535 |
+ ('bindir=', None, "Install directory for main executables"), |
536 |
+ ('datarootdir=', None, "Data install root directory"), |
537 |
+ ('docdir=', None, "Documentation install directory"), |
538 |
+ ('htmldir=', None, "HTML documentation install directory"), |
539 |
+ ('mandir=', None, "Manpage root install directory"), |
540 |
+ ('portage-base=', 'b', "Portage install base"), |
541 |
+ ('portage-bindir=', None, "Install directory for Portage internal-use executables"), |
542 |
+ ('portage-datadir=', None, 'Install directory for data files'), |
543 |
+ ('sbindir=', None, "Install directory for superuser-intended executables"), |
544 |
+ ('sysconfdir=', None, 'System configuration path'), |
545 |
+ ] |
546 |
+ |
547 |
+ # note: the order is important for proper substitution |
548 |
+ paths = [ |
549 |
+ ('system_prefix', '/usr'), |
550 |
+ ('system_exec_prefix', '$system_prefix'), |
551 |
+ |
552 |
+ ('bindir', '$system_exec_prefix/bin'), |
553 |
+ ('sbindir', '$system_exec_prefix/sbin'), |
554 |
+ ('sysconfdir', '/etc'), |
555 |
+ |
556 |
+ ('datarootdir', '$system_prefix/share'), |
557 |
+ ('docdir', '$datarootdir/doc/%s-%s' % (package_name, package_version)), |
558 |
+ ('htmldir', '$docdir/html'), |
559 |
+ ('mandir', '$datarootdir/man'), |
560 |
+ |
561 |
+ ('portage_base', '$system_exec_prefix/lib/portage'), |
562 |
+ ('portage_bindir', '$portage_base/bin'), |
563 |
+ ('portage_datadir', '$datarootdir/portage'), |
564 |
+ |
565 |
+ # not customized at the moment |
566 |
+ ('logrotatedir', '$sysconfdir/logrotate'), |
567 |
+ ('portage_confdir', '$portage_datadir/config'), |
568 |
+ ('portage_setsdir', '$portage_confdir/sets'), |
569 |
+ ] |
570 |
+ |
571 |
+ def initialize_options(self): |
572 |
+ install.initialize_options(self) |
573 |
+ |
574 |
+ for key, default in self.paths: |
575 |
+ setattr(self, key, default) |
576 |
+ self.subst_paths = {} |
577 |
+ |
578 |
+ def finalize_options(self): |
579 |
+ install.finalize_options(self) |
580 |
+ |
581 |
+ # substitute variables |
582 |
+ new_paths = {} |
583 |
+ for key, default in self.paths: |
584 |
+ new_paths[key] = subst_vars(getattr(self, key), new_paths) |
585 |
+ setattr(self, key, new_paths[key]) |
586 |
+ self.subst_paths = new_paths |
587 |
+ |
588 |
+ |
589 |
+class x_install_data(install_data): |
590 |
+ """ install_data with customized path support """ |
591 |
+ |
592 |
+ user_options = install_data.user_options |
593 |
+ |
594 |
+ def initialize_options(self): |
595 |
+ install_data.initialize_options(self) |
596 |
+ self.paths = None |
597 |
+ |
598 |
+ def finalize_options(self): |
599 |
+ install_data.finalize_options(self) |
600 |
+ self.set_undefined_options('install', |
601 |
+ ('subst_paths', 'paths')) |
602 |
+ |
603 |
+ # substitute variables in data_files |
604 |
+ for f in self.data_files: |
605 |
+ f[0] = subst_vars(f[0], self.paths) |
606 |
+ |
607 |
+ |
608 |
+class x_install_lib(install_lib): |
609 |
+ """ install_lib command with Portage path substitution """ |
610 |
+ |
611 |
+ user_options = install_lib.user_options |
612 |
+ |
613 |
+ def initialize_options(self): |
614 |
+ install_lib.initialize_options(self) |
615 |
+ self.portage_base = None |
616 |
+ self.portage_bindir = None |
617 |
+ self.portage_confdir = None |
618 |
+ |
619 |
+ def finalize_options(self): |
620 |
+ install_lib.finalize_options(self) |
621 |
+ self.set_undefined_options('install', |
622 |
+ ('portage_base', 'portage_base'), |
623 |
+ ('portage_bindir', 'portage_bindir'), |
624 |
+ ('portage_confdir', 'portage_confdir')) |
625 |
+ |
626 |
+ def install(self): |
627 |
+ ret = install_lib.install(self) |
628 |
+ |
629 |
+ base_re = re.compile(r'(^PORTAGE_BASE_PATH.*=) .*$', re.MULTILINE) |
630 |
+ portage_bin_re = re.compile(r'(^PORTAGE_BIN_PATH.*=) .*$', re.MULTILINE) |
631 |
+ global_config_re = re.compile(r'(^GLOBAL_CONFIG_PATH.*=) .*$', re.MULTILINE) |
632 |
+ |
633 |
+ constfile = os.path.join(self.install_dir, 'portage', 'const.py') |
634 |
+ print('Rewriting %s' % constfile) |
635 |
+ with codecs.open(constfile, 'r', 'utf-8') as f: |
636 |
+ data = f.read() |
637 |
+ data = base_re.sub('\\1 %s' % repr(self.portage_base), data) |
638 |
+ data = portage_bin_re.sub('\\1 %s' % repr(self.portage_bindir), data) |
639 |
+ data = global_config_re.sub('\\1 %s' % repr(self.portage_confdir), data) |
640 |
+ with codecs.open(constfile, 'w', 'utf-8') as f: |
641 |
+ f.write(data) |
642 |
+ |
643 |
+ return ret |
644 |
+ |
645 |
+ |
646 |
+class x_install_scripts_custom(install_scripts): |
647 |
+ def initialize_options(self): |
648 |
+ install_scripts.initialize_options(self) |
649 |
+ self.root = None |
650 |
+ |
651 |
+ def finalize_options(self): |
652 |
+ self.set_undefined_options('install', |
653 |
+ ('root', 'root'), |
654 |
+ (self.var_name, 'install_dir')) |
655 |
+ install_scripts.finalize_options(self) |
656 |
+ self.build_dir = os.path.join(self.build_dir, self.dir_name) |
657 |
+ |
658 |
+ # prepend root |
659 |
+ if self.root is not None: |
660 |
+ self.install_dir = change_root(self.root, self.install_dir) |
661 |
+ |
662 |
+ |
663 |
+class x_install_scripts_bin(x_install_scripts_custom): |
664 |
+ dir_name = 'bin' |
665 |
+ var_name = 'bindir' |
666 |
+ |
667 |
+ |
668 |
+class x_install_scripts_sbin(x_install_scripts_custom): |
669 |
+ dir_name = 'sbin' |
670 |
+ var_name = 'sbindir' |
671 |
+ |
672 |
+ |
673 |
+class x_install_scripts_portagebin(x_install_scripts_custom): |
674 |
+ dir_name = 'portage' |
675 |
+ var_name = 'portage_bindir' |
676 |
+ |
677 |
+ |
678 |
+class x_install_scripts(install_scripts): |
679 |
+ def initialize_option(self): |
680 |
+ pass |
681 |
+ |
682 |
+ def finalize_options(self): |
683 |
+ pass |
684 |
+ |
685 |
+ def run(self): |
686 |
+ self.run_command('install_scripts_bin') |
687 |
+ self.run_command('install_scripts_portagebin') |
688 |
+ self.run_command('install_scripts_sbin') |
689 |
+ |
690 |
+ |
691 |
+class build_tests(x_build_scripts_custom): |
692 |
+ """ Prepare build dir for running tests. """ |
693 |
+ |
694 |
+ def initialize_options(self): |
695 |
+ x_build_scripts_custom.initialize_options(self) |
696 |
+ self.build_base = None |
697 |
+ self.build_lib = None |
698 |
+ |
699 |
+ def finalize_options(self): |
700 |
+ x_build_scripts_custom.finalize_options(self) |
701 |
+ self.set_undefined_options('build', |
702 |
+ ('build_base', 'build_base'), |
703 |
+ ('build_lib', 'build_lib')) |
704 |
+ |
705 |
+ # since we will be writing to $build_lib/.., it is important |
706 |
+ # that we do not leave $build_base |
707 |
+ self.top_dir = os.path.normpath(os.path.join(self.build_lib, '..')) |
708 |
+ cprefix = os.path.commonprefix((self.build_base, self.top_dir)) |
709 |
+ if cprefix != self.build_base: |
710 |
+ raise SystemError('build_lib must be a subdirectory of build_base') |
711 |
+ |
712 |
+ self.build_dir = os.path.join(self.top_dir, 'bin') |
713 |
+ |
714 |
+ def run(self): |
715 |
+ self.run_command('build_py') |
716 |
+ |
717 |
+ # install all scripts $build_lib/../bin |
718 |
+ # (we can't do a symlink since we want shebangs corrected) |
719 |
+ x_build_scripts_custom.run(self) |
720 |
+ |
721 |
+ # symlink 'cnf' directory |
722 |
+ conf_dir = os.path.join(self.top_dir, 'cnf') |
723 |
+ if os.path.exists(conf_dir): |
724 |
+ if not os.path.islink(conf_dir): |
725 |
+ raise SystemError('%s exists and is not a symlink (collision)' |
726 |
+ % repr(conf_dir)) |
727 |
+ os.unlink(conf_dir) |
728 |
+ conf_src = os.path.relpath('cnf', self.top_dir) |
729 |
+ print('Symlinking %s -> %s' % (conf_dir, conf_src)) |
730 |
+ os.symlink(conf_src, conf_dir) |
731 |
+ |
732 |
+ # create $build_lib/../.portage_not_installed |
733 |
+ # to enable proper paths in tests |
734 |
+ with open(os.path.join(self.top_dir, '.portage_not_installed'), 'w') as f: |
735 |
+ pass |
736 |
+ |
737 |
+ |
738 |
+class test(Command): |
739 |
+ """ run tests """ |
740 |
+ |
741 |
+ user_options = [] |
742 |
+ |
743 |
+ def initialize_options(self): |
744 |
+ self.build_lib = None |
745 |
+ |
746 |
+ def finalize_options(self): |
747 |
+ self.set_undefined_options('build', |
748 |
+ ('build_lib', 'build_lib')) |
749 |
+ |
750 |
+ def run(self): |
751 |
+ self.run_command('build_tests') |
752 |
+ subprocess.check_call([ |
753 |
+ sys.executable, '-bWd', |
754 |
+ os.path.join(self.build_lib, 'portage/tests/runTests.py') |
755 |
+ ]) |
756 |
+ |
757 |
+ |
758 |
+def find_packages(): |
759 |
+ for dirpath, dirnames, filenames in os.walk('pym'): |
760 |
+ if '__init__.py' in filenames: |
761 |
+ yield os.path.relpath(dirpath, 'pym') |
762 |
+ |
763 |
+ |
764 |
+def find_scripts(): |
765 |
+ for dirpath, dirnames, filenames in os.walk('bin'): |
766 |
+ for f in filenames: |
767 |
+ yield os.path.join(dirpath, f) |
768 |
+ |
769 |
+ |
770 |
+def get_manpages(): |
771 |
+ linguas = os.environ.get('LINGUAS') |
772 |
+ if linguas is not None: |
773 |
+ linguas = linguas.split() |
774 |
+ |
775 |
+ for dirpath, dirnames, filenames in os.walk('man'): |
776 |
+ groups = collections.defaultdict(list) |
777 |
+ for f in filenames: |
778 |
+ fn, suffix = f.rsplit('.', 1) |
779 |
+ groups[suffix].append(os.path.join(dirpath, f)) |
780 |
+ |
781 |
+ topdir = dirpath[len('man/'):] |
782 |
+ if not topdir or linguas is None or topdir in linguas: |
783 |
+ for g, mans in groups.items(): |
784 |
+ yield [os.path.join('$mandir', topdir, 'man%s' % g), mans] |
785 |
+ |
786 |
+setup( |
787 |
+ name = package_name, |
788 |
+ version = package_version, |
789 |
+ author = 'Gentoo Portage Development Team', |
790 |
+ author_email = 'dev-portage@g.o', |
791 |
+ url = package_homepage, |
792 |
+ |
793 |
+ package_dir = {'': 'pym'}, |
794 |
+ packages = list(find_packages()), |
795 |
+ # something to cheat build & install commands |
796 |
+ scripts = list(find_scripts()), |
797 |
+ |
798 |
+ data_files = list(get_manpages()) + [ |
799 |
+ ['$sysconfdir', ['cnf/etc-update.conf', 'cnf/dispatch-conf.conf']], |
800 |
+ ['$logrotatedir', ['cnf/logrotate.d/elog-save-summary']], |
801 |
+ ['$portage_confdir', [ |
802 |
+ 'cnf/make.conf.example', 'cnf/make.globals', 'cnf/repos.conf']], |
803 |
+ ['$portage_setsdir', ['cnf/sets/portage.conf']], |
804 |
+ ['$docdir', ['ChangeLog', 'NEWS', 'RELEASE-NOTES']], |
805 |
+ ], |
806 |
+ |
807 |
+ cmdclass = { |
808 |
+ 'build_scripts': x_build_scripts, |
809 |
+ 'build_scripts_bin': x_build_scripts_bin, |
810 |
+ 'build_scripts_portagebin': x_build_scripts_portagebin, |
811 |
+ 'build_scripts_sbin': x_build_scripts_sbin, |
812 |
+ 'build_tests': build_tests, |
813 |
+ 'clean': x_clean, |
814 |
+ 'docbook': docbook, |
815 |
+ 'epydoc': epydoc, |
816 |
+ 'install': x_install, |
817 |
+ 'install_data': x_install_data, |
818 |
+ 'install_docbook': install_docbook, |
819 |
+ 'install_epydoc': install_epydoc, |
820 |
+ 'install_lib': x_install_lib, |
821 |
+ 'install_scripts': x_install_scripts, |
822 |
+ 'install_scripts_bin': x_install_scripts_bin, |
823 |
+ 'install_scripts_portagebin': x_install_scripts_portagebin, |
824 |
+ 'install_scripts_sbin': x_install_scripts_sbin, |
825 |
+ 'test': test, |
826 |
+ }, |
827 |
+ |
828 |
+ classifiers = [ |
829 |
+ 'Development Status :: 5 - Production/Stable', |
830 |
+ 'Environment :: Console', |
831 |
+ 'Intended Audience :: System Administrators', |
832 |
+ 'License :: OSI Approved :: GNU General Public License v2 (GPLv2)', |
833 |
+ 'Operating System :: POSIX', |
834 |
+ 'Programming Language :: Python', |
835 |
+ 'Topic :: System :: Installation/Setup' |
836 |
+ ] |
837 |
+) |
838 |
-- |
839 |
2.0.4 |