public inbox for gentoo-portage-dev@lists.gentoo.org
 help / color / mirror / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download: 
* [gentoo-portage-dev] [PATCH 5/6] Install Python modules using setup.py
  @ 2014-08-21 20:19 99% ` Michał Górny
  0 siblings, 0 replies; 1+ results
From: Michał Górny @ 2014-08-21 20:19 UTC (permalink / raw
  To: gentoo-portage-dev; +Cc: Michał Górny

---
 .gitignore           |   1 +
 Makefile             | 215 --------------------
 doc/Makefile         |  11 -
 pym/portage/const.py |   4 +-
 setup.py             | 557 +++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 560 insertions(+), 228 deletions(-)
 delete mode 100644 Makefile
 delete mode 100644 doc/Makefile
 create mode 100755 setup.py

diff --git a/.gitignore b/.gitignore
index 074bb86..c2dd534 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
 *.py[co]
 __pycache__/
 *.class
+/build
 /tags
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 9eb6e66..0000000
--- a/Makefile
+++ /dev/null
@@ -1,215 +0,0 @@
-SHELL = /bin/sh
-PN ?= portage
-PF ?= portage
-HOMEPAGE ?= http://www.gentoo.org/proj/en/portage/index.xml
-PWD ?= $(shell pwd)
-S ?= $(PWD)
-WORKDIR ?= $(PWD)
-DESTDIR = $(PWD)/image/
-srcdir = $(S)
-prefix = /usr
-sysconfdir = /etc
-exec_prefix = $(prefix)
-bindir = $(exec_prefix)/bin
-sbindir = $(exec_prefix)/sbin
-libdir = $(exec_prefix)/lib
-datarootdir = $(prefix)/share
-datadir = $(datarootdir)
-mandir = $(datarootdir)/man
-docdir = $(datarootdir)/doc/$(PF)
-htmldir = $(docdir)/html
-portage_datadir = $(datarootdir)/$(PN)
-portage_confdir = $(portage_datadir)/config
-portage_setsdir = $(portage_confdir)/sets
-portage_base = $(libdir)/$(PN)
-EPYDOC_OPTS = -qqqqq --no-frames --show-imports
-INSMODE = 0644
-EXEMODE = 0755
-DIRMODE = 0755
-SYSCONFDIR_FILES = etc-update.conf dispatch-conf.conf
-PORTAGE_CONFDIR_FILES = make.conf.example make.globals repos.conf
-LOGROTATE_FILES = elog-save-summary
-BINDIR_FILES = ebuild egencache emerge emerge-webrsync \
-	emirrordist portageq quickpkg repoman
-SBINDIR_FILES = archive-conf dispatch-conf emaint \
-	env-update etc-update fixpackages regenworld
-DOCS = ChangeLog NEWS RELEASE-NOTES
-LINGUAS ?= $(shell cd "$(srcdir)/man" && find -mindepth 1 -type d)
-
-ifdef PYTHONPATH
-	PYTHONPATH := $(srcdir)/pym:$(PYTHONPATH)
-else
-	PYTHONPATH := $(srcdir)/pym
-endif
-
-all: docbook epydoc
-
-docbook:
-	set -e; \
-	touch "$(srcdir)/doc/fragment/date"; \
-	$(MAKE) -C "$(srcdir)/doc" xhtml xhtml-nochunks
-
-epydoc:
-	set -e; \
-	env PYTHONPATH="$(PYTHONPATH)" epydoc \
-		-o "$(WORKDIR)/epydoc" \
-		--name $(PN) \
-		--url "$(HOMEPAGE)" \
-		$(EPYDOC_OPTS) \
-		$$(cd "$(srcdir)" && find pym -name '*.py' | sed \
-		-e s:/__init__.py$$:: \
-		-e s:\.py$$:: \
-		-e s:^pym/:: \
-		-e s:/:.:g \
-		| sort); \
-	rm -f "$(WORKDIR)/epydoc/api-objects.txt"; \
-
-test:
-	set -e; \
-	"$(srcdir)/pym/portage/tests/runTests.py"; \
-
-install:
-	set -e; \
-	cd "$(srcdir)/cnf"; \
-	install -d -m$(DIRMODE) "$(DESTDIR)$(sysconfdir)"; \
-	install -m$(INSMODE) $(SYSCONFDIR_FILES) "$(DESTDIR)$(sysconfdir)"; \
-	\
-	install -d -m$(DIRMODE) "$(DESTDIR)$(portage_confdir)"; \
-	cd "$(srcdir)/cnf"; \
-	install -m$(INSMODE) $(PORTAGE_CONFDIR_FILES) \
-		"$(DESTDIR)$(portage_confdir)"; \
-	install -d -m$(DIRMODE) "$(DESTDIR)$(portage_setsdir)"; \
-	cd "$(S)/cnf/sets"; \
-	install -m$(INSMODE) *.conf "$(DESTDIR)$(portage_setsdir)"; \
-	\
-	install -d -m$(DIRMODE) "$(DESTDIR)$(sysconfdir)/logrotate.d"; \
-	cd "$(srcdir)/cnf/logrotate.d"; \
-	install -m$(INSMODE) $(LOGROTATE_FILES) \
-		"$(DESTDIR)$(sysconfdir)/logrotate.d"; \
-	\
-	for x in $$(cd "$(srcdir)" && find bin -type d) ; do \
-		cd "$(srcdir)/$$x"; \
-		install -d -m$(DIRMODE) "$(DESTDIR)$(portage_base)/$$x"; \
-		files=$$(find . -mindepth 1 -maxdepth 1 -type f ! -type l); \
-		if [ -n "$$files" ] ; then \
-			install -m$(EXEMODE) $$files \
-				"$(DESTDIR)$(portage_base)/$$x"; \
-		fi; \
-		symlinks=$$(find . -mindepth 1 -maxdepth 1 -type l); \
-		if [ -n "$$symlinks" ] ; then \
-			cp -P $$symlinks "$(DESTDIR)$(portage_base)/$$x"; \
-		fi; \
-	done; \
-	\
-	for x in $$(cd "$(srcdir)" && find pym/* -type d \
-		! -path "pym/portage/tests*") ; do \
-		cd "$(srcdir)/$$x"; \
-		files=$$(echo *.py); \
-		if [ -z "$$files" ] || [ "$$files" = "*.py" ]; then \
-			# __pycache__ directories contain no py files \
-			continue; \
-		fi; \
-		install -d -m$(DIRMODE) "$(DESTDIR)$(portage_base)/$$x"; \
-		install -m$(INSMODE) $$files "$(DESTDIR)$(portage_base)/$$x"; \
-	done; \
-	\
-	install -d -m$(DIRMODE) "$(DESTDIR)$(bindir)"; \
-	relative_path=".."; \
-	x=$(bindir) ; \
-	y="$(portage_base)"; \
-	if [ "$${x#$(prefix)}" != "$$x" ] && \
-		[ "$${y#$(prefix)}" != "$$y" ]; then \
-		x=$${x#$(prefix)}; \
-		y=$${y#$(prefix)}; \
-	fi; \
-	x=$${x%/*}; \
-	while [ -n "$$x" ] ; do \
-		relative_path=$${relative_path}/..; \
-		x=$${x%/*}; \
-	done; \
-	relative_path=$$relative_path$$y; \
-	for x in $(BINDIR_FILES) ; do \
-		ln -sf "$$relative_path/bin/$$x" \
-			"$(DESTDIR)$(bindir)/$$x"; \
-	done; \
-	\
-	install -d -m$(DIRMODE) "$(DESTDIR)$(sbindir)"; \
-	relative_path=".."; \
-	x=$(sbindir) ; \
-	y="$(portage_base)"; \
-	if [ "$${x#$(prefix)}" != "$$x" ] && \
-		[ "$${y#$(prefix)}" != "$$y" ]; then \
-		x=$${x#$(prefix)}; \
-		y=$${y#$(prefix)}; \
-	fi; \
-	x=$${x%/*}; \
-	while [ -n "$$x" ] ; do \
-		relative_path=$${relative_path}/..; \
-		x=$${x%/*}; \
-	done; \
-	relative_path=$$relative_path$$y; \
-	for x in $(SBINDIR_FILES) ; do \
-		ln -sf "$$relative_path/bin/$$x" \
-			"$(DESTDIR)$(sbindir)/$$x"; \
-	done; \
-	\
-	ln -sf "$$relative_path/bin/env-update" \
-		"$(DESTDIR)$(sbindir)/update-env"; \
-	ln -sf "$$relative_path/bin/etc-update" \
-		"$(DESTDIR)$(sbindir)/update-etc"; \
-	\
-	# We install some minimal tests for use as a preinst sanity check. \
-	# These tests must be able to run without a full source tree and \
-	# without relying on a previous portage instance being installed. \
-	install -d -m$(DIRMODE) \
-		"$(DESTDIR)$(portage_base)/pym/portage/tests"; \
-	install -m$(EXEMODE) "$(srcdir)/pym/portage/tests/runTests" \
-		"$(DESTDIR)$(portage_base)/pym/portage/tests"; \
-	cd "$(srcdir)/pym/portage/tests"; \
-	install -m$(INSMODE) *.py \
-		"$(DESTDIR)$(portage_base)/pym/portage/tests"; \
-	install -d -m$(DIRMODE) \
-		"$(DESTDIR)$(portage_base)/pym/portage/tests/lint"; \
-	cd "$(srcdir)/pym/portage/tests/lint"; \
-	install -m$(INSMODE) *.py __test__ \
-		"$(DESTDIR)$(portage_base)/pym/portage/tests/lint"; \
-	\
-	install -d -m$(DIRMODE) "$(DESTDIR)$(docdir)"; \
-	cd "$(srcdir)"; \
-	install -m $(INSMODE) $(DOCS) "$(DESTDIR)$(docdir)"; \
-	\
-	for x in "" $(LINGUAS); do \
-		for y in 1 5 ; do \
-			if [ -d "$(srcdir)/man/$$x" ]; then \
-				cd "$(srcdir)/man/$$x"; \
-				files=$$(echo *.$$y); \
-				if [ -z "$$files" ] || [ "$$files" = "*.$$y" ]; then \
-					continue; \
-				fi; \
-				install -d -m$(DIRMODE) "$(DESTDIR)$(mandir)/$$x/man$$y"; \
-				install -m$(INSMODE) *.$$y "$(DESTDIR)$(mandir)/$$x/man$$y"; \
-			fi; \
-		done; \
-	done; \
-	\
-	if [ -f "$(srcdir)/doc/portage.html" ] ; then \
-		install -d -m$(DIRMODE) "$(DESTDIR)$(htmldir)"; \
-		cd "$(srcdir)/doc"; \
-		install -m$(INSMODE) *.html "$(DESTDIR)$(htmldir)"; \
-	fi; \
-	\
-	if [ -d "$(WORKDIR)/epydoc" ] ; then \
-		install -d -m$(DIRMODE) "$(DESTDIR)$(htmldir)"; \
-		cp -pPR "$(WORKDIR)/epydoc" \
-			"$(DESTDIR)$(htmldir)/api"; \
-		cd "$(DESTDIR)$(htmldir)/api"; \
-		find . -type d | xargs chmod $(DIRMODE); \
-		find . -type f | xargs chmod $(INSMODE); \
-	fi; \
-
-clean:
-	set -e; \
-	$(MAKE) -C "$(srcdir)/doc" clean; \
-	rm -rf "$(WORKDIR)/epydoc"; \
-
-.PHONY: all clean docbook epydoc install test
diff --git a/doc/Makefile b/doc/Makefile
deleted file mode 100644
index 261a0b4..0000000
--- a/doc/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-all: xhtml xhtml-nochunks
-
-XMLTO_FLAGS = -m custom.xsl
-man pdf txt xhtml xhtml-nochunks:
-	xmlto $@ $(XMLTO_FLAGS) portage.docbook
-
-clean distclean:
-	rm -f *.1 *.html portage.txt
-
-.PHONY: all clean distclean \
-        man pdf txt xhtml xhtml-nochunks
diff --git a/pym/portage/const.py b/pym/portage/const.py
index f518b47..acb90f9 100644
--- a/pym/portage/const.py
+++ b/pym/portage/const.py
@@ -60,8 +60,8 @@ GLOBAL_CONFIG_PATH       = "/usr/share/portage/config"
 # these variables are not used with target_root or config_root
 # NOTE: Use realpath(__file__) so that python module symlinks in site-packages
 # are followed back to the real location of the whole portage installation.
-PORTAGE_BASE_PATH        = os.path.join(os.sep, os.sep.join(os.path.realpath(
-                               __file__.rstrip("co")).split(os.sep)[:-3]))
+# NOTE: Please keep PORTAGE_BASE_PATH in one line to help substitutions.
+PORTAGE_BASE_PATH        = os.path.join(os.sep, os.sep.join(os.path.realpath(__file__.rstrip("co")).split(os.sep)[:-3]))
 PORTAGE_BIN_PATH         = PORTAGE_BASE_PATH + "/bin"
 PORTAGE_PYM_PATH         = os.path.realpath(os.path.join(__file__, '../..'))
 LOCALE_DATA_PATH         = PORTAGE_BASE_PATH + "/locale"  # FIXME: not used
diff --git a/setup.py b/setup.py
new file mode 100755
index 0000000..bd6e506
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,557 @@
+#!/usr/bin/env python
+#	vim:fileencoding=utf-8
+# (c) 2010 Michał Górny <mgorny@gentoo.org>
+# Released under the terms of the 2-clause BSD license.
+
+from distutils.core import setup, Command
+from distutils.command.build_scripts import build_scripts
+from distutils.command.clean import clean
+from distutils.command.install import install
+from distutils.command.install_data import install_data
+from distutils.command.install_lib import install_lib
+from distutils.command.install_scripts import install_scripts
+from distutils.dir_util import remove_tree
+from distutils.util import change_root, subst_vars
+
+import codecs, collections, glob, os, os.path, re, subprocess, sys
+
+# TODO:
+# - smarter rebuilds of docs w/ 'install_docbook' and 'install_epydoc'.
+
+package_name = 'portage'
+package_version = '2.2.12'
+package_homepage = 'https://wiki.gentoo.org/wiki/Project:Portage'
+
+x_scripts = {
+	'bin': [
+		'bin/ebuild', 'bin/egencache', 'bin/emerge', 'bin/emerge-webrsync',
+		'bin/emirrordist', 'bin/portageq', 'bin/quickpkg', 'bin/repoman'
+	],
+	'sbin': [
+		'bin/archive-conf', 'bin/dispatch-conf', 'bin/emaint', 'bin/env-update',
+		'bin/etc-update', 'bin/fixpackages', 'bin/regenworld'
+	],
+}
+
+
+class docbook(Command):
+	""" Build docs using docbook. """
+
+	user_options = [
+		('doc-formats=', None, 'Documentation formats to build (all xmlto formats for docbook are allowed, comma-separated'),
+	]
+
+	def initialize_options(self):
+		self.doc_formats = 'xhtml,xhtml-nochunks'
+
+	def finalize_options(self):
+		self.doc_formats = self.doc_formats.replace(',', ' ').split()
+
+	def run(self):
+		with open('doc/fragment/date', 'w'):
+			pass
+
+		for f in self.doc_formats:
+			print('Building docs in %s format...' % f)
+			subprocess.check_call(['xmlto', '-o', 'doc',
+				'-m', 'doc/custom.xsl', f, 'doc/portage.docbook'])
+
+
+class epydoc(Command):
+	""" Build API docs using epydoc. """
+
+	user_options = [
+	]
+
+	def initialize_options(self):
+		self.build_lib = None
+
+	def finalize_options(self):
+		self.set_undefined_options('build_py', ('build_lib', 'build_lib'))
+
+	def run(self):
+		self.run_command('build_py')
+
+		print('Building API documentation...')
+
+		process_env = os.environ.copy()
+		pythonpath = self.build_lib
+		try:
+			pythonpath += ':' + process_env['PYTHONPATH']
+		except KeyError:
+			pass
+		process_env['PYTHONPATH'] = pythonpath
+
+		subprocess.check_call(['epydoc', '-o', 'epydoc',
+			'--name', package_name,
+			'--url', package_homepage,
+			'-qq', '--no-frames', '--show-imports',
+			'--exclude', 'portage.tests',
+			'_emerge', 'portage', 'repoman'],
+			env = process_env)
+		os.remove('epydoc/api-objects.txt')
+
+
+class install_docbook(install_data):
+	""" install_data for docbook docs """
+
+	user_options = install_data.user_options
+
+	def initialize_options(self):
+		install_data.initialize_options(self)
+		self.htmldir = None
+
+	def finalize_options(self):
+		self.set_undefined_options('install', ('htmldir', 'htmldir'))
+		install_data.finalize_options(self)
+
+	def run(self):
+		if not os.path.exists('doc/portage.html'):
+			self.run_command('docbook')
+		self.data_files = [
+			(self.htmldir, glob.glob('doc/*.html')),
+		]
+		install_data.run(self)
+
+
+class install_epydoc(install_data):
+	""" install_data for epydoc docs """
+
+	user_options = install_data.user_options
+
+	def initialize_options(self):
+		install_data.initialize_options(self)
+		self.htmldir = None
+
+	def finalize_options(self):
+		self.set_undefined_options('install', ('htmldir', 'htmldir'))
+		install_data.finalize_options(self)
+
+	def run(self):
+		if not os.path.exists('epydoc/index.html'):
+			self.run_command('epydoc')
+		self.data_files = [
+			(os.path.join(self.htmldir, 'api'), glob.glob('epydoc/*')),
+		]
+		install_data.run(self)
+
+
+class x_build_scripts_custom(build_scripts):
+	def finalize_options(self):
+		build_scripts.finalize_options(self)
+		if 'dir_name' in dir(self):
+			self.build_dir = os.path.join(self.build_dir, self.dir_name)
+			if self.dir_name in x_scripts:
+				self.scripts = x_scripts[self.dir_name]
+			else:
+				self.scripts = set(self.scripts)
+				for other_files in x_scripts.values():
+					self.scripts.difference_update(other_files)
+
+	def run(self):
+		# group scripts by subdirectory
+		split_scripts = collections.defaultdict(list)
+		for f in self.scripts:
+			dir_name = os.path.dirname(f[len('bin/'):])
+			split_scripts[dir_name].append(f)
+
+		base_dir = self.build_dir
+		base_scripts = self.scripts
+		for d, files in split_scripts.items():
+			self.build_dir = os.path.join(base_dir, d)
+			self.scripts = files
+			self.copy_scripts()
+
+		# restore previous values
+		self.build_dir = base_dir
+		self.scripts = base_scripts
+
+
+class x_build_scripts_bin(x_build_scripts_custom):
+	dir_name = 'bin'
+
+
+class x_build_scripts_sbin(x_build_scripts_custom):
+	dir_name = 'sbin'
+
+
+class x_build_scripts_portagebin(x_build_scripts_custom):
+	dir_name = 'portage'
+
+
+class x_build_scripts(build_scripts):
+	def initialize_option(self):
+		pass
+
+	def finalize_options(self):
+		pass
+
+	def run(self):
+		self.run_command('build_scripts_bin')
+		self.run_command('build_scripts_portagebin')
+		self.run_command('build_scripts_sbin')
+
+
+class x_clean(clean):
+	""" clean extended for doc & post-test cleaning """
+
+	def clean_docs(self):
+		def get_doc_outfiles():
+			for dirpath, dirnames, filenames in os.walk('doc'):
+				for f in filenames:
+					if f.endswith('.docbook') or f == 'custom.xsl':
+						pass
+					else:
+						yield os.path.join(dirpath, f)
+
+				# do not recurse
+				break
+
+
+		for f in get_doc_outfiles():
+			print('removing %s' % repr(f))
+			os.remove(f)
+
+		if os.path.isdir('epydoc'):
+			remove_tree('epydoc')
+
+	def clean_tests(self):
+		# do not remove incorrect dirs accidentally
+		top_dir = os.path.normpath(os.path.join(self.build_lib, '..'))
+		cprefix = os.path.commonprefix((self.build_base, top_dir))
+		if cprefix != self.build_base:
+			return
+
+		bin_dir = os.path.join(top_dir, 'bin')
+		if os.path.exists(bin_dir):
+			remove_tree(bin_dir)
+
+		conf_dir = os.path.join(top_dir, 'cnf')
+		if os.path.islink(conf_dir):
+			print('removing %s symlink' % repr(conf_dir))
+			os.unlink(conf_dir)
+
+		pni_file = os.path.join(top_dir, '.portage_not_installed')
+		if os.path.exists(pni_file):
+			print('removing %s' % repr(pni_file))
+			os.unlink(pni_file)
+
+	def run(self):
+		if self.all:
+			self.clean_tests()
+			self.clean_docs()
+
+		clean.run(self)
+
+
+class x_install(install):
+	""" install command with extra Portage paths """
+
+	user_options = install.user_options + [
+		# note: $prefix and $exec_prefix are reserved for Python install
+		('system-prefix=', None, "Prefix for architecture-independent data"),
+		('system-exec-prefix=', None, "Prefix for architecture-specific data"),
+
+		('bindir=', None, "Install directory for main executables"),
+		('datarootdir=', None, "Data install root directory"),
+		('docdir=', None, "Documentation install directory"),
+		('htmldir=', None, "HTML documentation install directory"),
+		('mandir=', None, "Manpage root install directory"),
+		('portage-base=', 'b', "Portage install base"),
+		('portage-bindir=', None, "Install directory for Portage internal-use executables"),
+		('portage-datadir=', None, 'Install directory for data files'),
+		('sbindir=', None, "Install directory for superuser-intended executables"),
+		('sysconfdir=', None, 'System configuration path'),
+	]
+
+	# note: the order is important for proper substitution
+	paths = [
+		('system_prefix', '/usr'),
+		('system_exec_prefix', '$system_prefix'),
+
+		('bindir', '$system_exec_prefix/bin'),
+		('sbindir', '$system_exec_prefix/sbin'),
+		('sysconfdir', '/etc'),
+
+		('datarootdir', '$system_prefix/share'),
+		('docdir', '$datarootdir/doc/%s-%s' % (package_name, package_version)),
+		('htmldir', '$docdir/html'),
+		('mandir', '$datarootdir/man'),
+
+		('portage_base', '$system_exec_prefix/lib/portage'),
+		('portage_bindir', '$portage_base/bin'),
+		('portage_datadir', '$datarootdir/portage'),
+
+		# not customized at the moment
+		('logrotatedir', '$sysconfdir/logrotate'),
+		('portage_confdir', '$portage_datadir/config'),
+		('portage_setsdir', '$portage_confdir/sets'),
+	]
+
+	def initialize_options(self):
+		install.initialize_options(self)
+
+		for key, default in self.paths:
+			setattr(self, key, default)
+		self.subst_paths = {}
+
+	def finalize_options(self):
+		install.finalize_options(self)
+
+		# substitute variables
+		new_paths = {}
+		for key, default in self.paths:
+			new_paths[key] = subst_vars(getattr(self, key), new_paths)
+			setattr(self, key, new_paths[key])
+		self.subst_paths = new_paths
+
+
+class x_install_data(install_data):
+	""" install_data with customized path support """
+
+	user_options = install_data.user_options
+
+	def initialize_options(self):
+		install_data.initialize_options(self)
+		self.paths = None
+
+	def finalize_options(self):
+		install_data.finalize_options(self)
+		self.set_undefined_options('install',
+			('subst_paths', 'paths'))
+
+		# substitute variables in data_files
+		for f in self.data_files:
+			f[0] = subst_vars(f[0], self.paths)
+
+
+class x_install_lib(install_lib):
+	""" install_lib command with Portage path substitution """
+
+	user_options = install_lib.user_options
+
+	def initialize_options(self):
+		install_lib.initialize_options(self)
+		self.portage_base = None
+		self.portage_bindir = None
+		self.portage_confdir = None
+
+	def finalize_options(self):
+		install_lib.finalize_options(self)
+		self.set_undefined_options('install',
+			('portage_base', 'portage_base'),
+			('portage_bindir', 'portage_bindir'),
+			('portage_confdir', 'portage_confdir'))
+
+	def install(self):
+		ret = install_lib.install(self)
+
+		base_re = re.compile(r'(^PORTAGE_BASE_PATH.*=) .*$', re.MULTILINE)
+		portage_bin_re = re.compile(r'(^PORTAGE_BIN_PATH.*=) .*$', re.MULTILINE)
+		global_config_re = re.compile(r'(^GLOBAL_CONFIG_PATH.*=) .*$', re.MULTILINE)
+
+		constfile = os.path.join(self.install_dir, 'portage', 'const.py')
+		print('Rewriting %s' % constfile)
+		with codecs.open(constfile, 'r', 'utf-8') as f:
+			data = f.read()
+		data = base_re.sub('\\1 %s' % repr(self.portage_base), data)
+		data = portage_bin_re.sub('\\1 %s' % repr(self.portage_bindir), data)
+		data = global_config_re.sub('\\1 %s' % repr(self.portage_confdir), data)
+		with codecs.open(constfile, 'w', 'utf-8') as f:
+			f.write(data)
+
+		return ret
+
+
+class x_install_scripts_custom(install_scripts):
+	def initialize_options(self):
+		install_scripts.initialize_options(self)
+		self.root = None
+
+	def finalize_options(self):
+		self.set_undefined_options('install',
+			('root', 'root'),
+			(self.var_name, 'install_dir'))
+		install_scripts.finalize_options(self)
+		self.build_dir = os.path.join(self.build_dir, self.dir_name)
+
+		# prepend root
+		if self.root is not None:
+			self.install_dir = change_root(self.root, self.install_dir)
+
+
+class x_install_scripts_bin(x_install_scripts_custom):
+	dir_name = 'bin'
+	var_name = 'bindir'
+
+
+class x_install_scripts_sbin(x_install_scripts_custom):
+	dir_name = 'sbin'
+	var_name = 'sbindir'
+
+
+class x_install_scripts_portagebin(x_install_scripts_custom):
+	dir_name = 'portage'
+	var_name = 'portage_bindir'
+
+
+class x_install_scripts(install_scripts):
+	def initialize_option(self):
+		pass
+
+	def finalize_options(self):
+		pass
+
+	def run(self):
+		self.run_command('install_scripts_bin')
+		self.run_command('install_scripts_portagebin')
+		self.run_command('install_scripts_sbin')
+
+
+class build_tests(x_build_scripts_custom):
+	""" Prepare build dir for running tests. """
+
+	def initialize_options(self):
+		x_build_scripts_custom.initialize_options(self)
+		self.build_base = None
+		self.build_lib = None
+
+	def finalize_options(self):
+		x_build_scripts_custom.finalize_options(self)
+		self.set_undefined_options('build',
+			('build_base', 'build_base'),
+			('build_lib', 'build_lib'))
+
+		# since we will be writing to $build_lib/.., it is important
+		# that we do not leave $build_base
+		self.top_dir = os.path.normpath(os.path.join(self.build_lib, '..'))
+		cprefix = os.path.commonprefix((self.build_base, self.top_dir))
+		if cprefix != self.build_base:
+			raise SystemError('build_lib must be a subdirectory of build_base')
+
+		self.build_dir = os.path.join(self.top_dir, 'bin')
+
+	def run(self):
+		self.run_command('build_py')
+
+		# install all scripts $build_lib/../bin
+		# (we can't do a symlink since we want shebangs corrected)
+		x_build_scripts_custom.run(self)
+
+		# symlink 'cnf' directory
+		conf_dir = os.path.join(self.top_dir, 'cnf')
+		if os.path.exists(conf_dir):
+			if not os.path.islink(conf_dir):
+				raise SystemError('%s exists and is not a symlink (collision)'
+					% repr(conf_dir))
+			os.unlink(conf_dir)
+		conf_src = os.path.relpath('cnf', self.top_dir)
+		print('Symlinking %s -> %s' % (conf_dir, conf_src))
+		os.symlink(conf_src, conf_dir)
+
+		# create $build_lib/../.portage_not_installed
+		# to enable proper paths in tests
+		with open(os.path.join(self.top_dir, '.portage_not_installed'), 'w') as f:
+			pass
+
+
+class test(Command):
+	""" run tests """
+
+	user_options = []
+
+	def initialize_options(self):
+		self.build_lib = None
+
+	def finalize_options(self):
+		self.set_undefined_options('build',
+			('build_lib', 'build_lib'))
+
+	def run(self):
+		self.run_command('build_tests')
+		subprocess.check_call([
+			sys.executable, '-bWd',
+			os.path.join(self.build_lib, 'portage/tests/runTests.py')
+		])
+
+
+def find_packages():
+	for dirpath, dirnames, filenames in os.walk('pym'):
+		if '__init__.py' in filenames:
+			yield os.path.relpath(dirpath, 'pym')
+
+
+def find_scripts():
+	for dirpath, dirnames, filenames in os.walk('bin'):
+		for f in filenames:
+			yield os.path.join(dirpath, f)
+
+
+def get_manpages():
+	linguas = os.environ.get('LINGUAS')
+	if linguas is not None:
+		linguas = linguas.split()
+
+	for dirpath, dirnames, filenames in os.walk('man'):
+		groups = collections.defaultdict(list)
+		for f in filenames:
+			fn, suffix = f.rsplit('.', 1)
+			groups[suffix].append(os.path.join(dirpath, f))
+
+		topdir = dirpath[len('man/'):]
+		if not topdir or linguas is None or topdir in linguas:
+			for g, mans in groups.items():
+				yield [os.path.join('$mandir', topdir, 'man%s' % g), mans]
+
+setup(
+		name = package_name,
+		version = package_version,
+		author = 'Gentoo Portage Development Team',
+		author_email = 'dev-portage@gentoo.org',
+		url = package_homepage,
+
+		package_dir = {'': 'pym'},
+		packages = list(find_packages()),
+		# something to cheat build & install commands
+		scripts = list(find_scripts()),
+
+		data_files = list(get_manpages()) + [
+			['$sysconfdir', ['cnf/etc-update.conf', 'cnf/dispatch-conf.conf']],
+			['$logrotatedir', ['cnf/logrotate.d/elog-save-summary']],
+			['$portage_confdir', [
+				'cnf/make.conf.example', 'cnf/make.globals', 'cnf/repos.conf']],
+			['$portage_setsdir', ['cnf/sets/portage.conf']],
+			['$docdir', ['ChangeLog', 'NEWS', 'RELEASE-NOTES']],
+		],
+
+		cmdclass = {
+			'build_scripts': x_build_scripts,
+			'build_scripts_bin': x_build_scripts_bin,
+			'build_scripts_portagebin': x_build_scripts_portagebin,
+			'build_scripts_sbin': x_build_scripts_sbin,
+			'build_tests': build_tests,
+			'clean': x_clean,
+			'docbook': docbook,
+			'epydoc': epydoc,
+			'install': x_install,
+			'install_data': x_install_data,
+			'install_docbook': install_docbook,
+			'install_epydoc': install_epydoc,
+			'install_lib': x_install_lib,
+			'install_scripts': x_install_scripts,
+			'install_scripts_bin': x_install_scripts_bin,
+			'install_scripts_portagebin': x_install_scripts_portagebin,
+			'install_scripts_sbin': x_install_scripts_sbin,
+			'test': test,
+		},
+
+		classifiers = [
+			'Development Status :: 5 - Production/Stable',
+			'Environment :: Console',
+			'Intended Audience :: System Administrators',
+			'License :: OSI Approved :: GNU General Public License v2 (GPLv2)',
+			'Operating System :: POSIX',
+			'Programming Language :: Python',
+			'Topic :: System :: Installation/Setup'
+		]
+)
-- 
2.0.4



^ permalink raw reply related	[relevance 99%]

Results 1-1 of 1 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2014-08-21 20:19     [gentoo-portage-dev] [PATCHES] setup.py install for Portage Michał Górny
2014-08-21 20:19 99% ` [gentoo-portage-dev] [PATCH 5/6] Install Python modules using setup.py Michał Górny

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox