-
Notifications
You must be signed in to change notification settings - Fork 186
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Jyrki Pulliainen
committed
Oct 10, 2013
0 parents
commit c4eb511
Showing
21 changed files
with
1,660 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
*.py[oc] | ||
|
||
# Temp files | ||
*~ | ||
~* | ||
.*~ | ||
\#* | ||
.#* | ||
*# | ||
|
||
# Sphinx build | ||
doc/_build |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# dh-virtualenv | ||
|
||
dh-virtualenv is a tool that aims to combine Debian packaging with | ||
self-contained virtualenv based Python deployments. | ||
|
||
The idea behind the dh-virtualenv is to be able to combine power of | ||
Debian packaging with the sandboxed nature of virtualenvs. In addition | ||
to this, using virtualenv enables installing requirements via | ||
[Python Package Index](http://pypi.python.org) instead of relying on | ||
the operating system provided Python packages. The only limiting | ||
factor is that you have to run the same Python interpreter as the | ||
operating system. | ||
|
||
## Using dh-virtualenv | ||
|
||
Using dh-virtualenv is fairly straightforward. First, you need to | ||
define the requirements of your package in `requirements.txt` file, in | ||
[the format defined by pip](http://www.pip-installer.org/en/latest/cookbook.html#requirements-files). | ||
|
||
To build a package using dh-virtualenv, you need to add dh-virtualenv | ||
in to your build dependencies and write following `debian/rules` file: | ||
|
||
%: | ||
dh $@ --with python-virtualenv | ||
|
||
Note that you might need to provide | ||
additional build dependencies too, if your requirements require them. | ||
|
||
Once the package is built, you have a virtualenv contained in a Debian | ||
package and upon installation it gets placed, by default, under | ||
`/usr/share/python/<packagename>`. | ||
|
||
For more information and usage documentation, check the accompanying | ||
documentation in the `doc` folder. | ||
|
||
## How does it work? | ||
|
||
To do the packaging, the package extends debhelper's sequence by | ||
providing a new command in sequence, `dh_virtualenv`, which | ||
effectively replaces following commands from the sequence: | ||
|
||
* `dh_auto_install` | ||
* `dh_python2` | ||
* `dh_pycentral` | ||
* `dh_pysupport` | ||
|
||
In the sequence the dh_virtualenv is inserted right after dh_perl. | ||
|
||
## License | ||
|
||
Copyright (c) 2013 Spotify AB | ||
|
||
dh-virtualenv is licensed under GPL v2 or later. Full license is | ||
available in the `LICENSE` file. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
# Copyright (c) 2013 Spotify AB | ||
|
||
# This file is part of dh-virtualenv. | ||
|
||
# dh-virtualenv is free software: you can redistribute it and/or | ||
# modify it under the terms of the GNU General Public License as | ||
# published by the Free Software Foundation, either version 2 of the | ||
# License, or (at your option) any later version. | ||
|
||
# dh-virtualenv is distributed in the hope that it will be useful, but | ||
# WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
# General Public License for more details. | ||
|
||
# You should have received a copy of the GNU General Public License | ||
# along with dh-virtualenv. If not, see | ||
# <http://www.gnu.org/licenses/>. | ||
|
||
import logging | ||
import os | ||
import sys | ||
|
||
|
||
from optparse import OptionParser, SUPPRESS_HELP | ||
|
||
# The debpython resides here | ||
sys.path.insert(1, '/usr/share/python/') | ||
|
||
from debpython.debhelper import DebHelper | ||
from dh_virtualenv import Deployment | ||
|
||
logging.basicConfig(format='%(levelname).1s: %(module)s:%(lineno)d: ' | ||
'%(message)s') | ||
log = logging.getLogger(__name__) | ||
|
||
|
||
def main(): | ||
usage = '%prog [options]' | ||
parser = OptionParser(usage, version='%prog 0.1') | ||
parser.add_option('-p', '--package', action='append', | ||
help='act on the package named PACKAGE') | ||
parser.add_option('-N', '--no-package', action='append', | ||
help='do not act on the specified package') | ||
parser.add_option('-v', '--verbose', action='store_true', | ||
default=False, help='Turn on verbose mode') | ||
parser.add_option('--extra-index-url', action='append', | ||
help='extra index URL to pass to pip.', | ||
default=[]) | ||
parser.add_option('--preinstall', action='append', | ||
help=('package to install before processing ' | ||
'requirements.txt.'), | ||
default=[]) | ||
parser.add_option('--pypi-url', help='Base URL of the PyPI server') | ||
# Ignore user-specified option bunldes | ||
parser.add_option('-O', help=SUPPRESS_HELP) | ||
|
||
options, args = parser.parse_args( | ||
sys.argv[1:] + os.environ.get('DH_OPTIONS', '').split()) | ||
|
||
verbose = options.verbose or os.environ.get('DH_VERBOSE') == '1' | ||
if verbose: | ||
log.setLevel(logging.DEBUG) | ||
|
||
dh = DebHelper(options.package or None) | ||
for package, details in dh.packages.items(): | ||
def _info(msg): | ||
log.info('{0}: {1}'.format(package, msg)) | ||
|
||
_info('Processing package...') | ||
|
||
deploy = Deployment( | ||
package, | ||
extra_urls=options.extra_index_url, | ||
preinstall=options.preinstall, | ||
pypi_url=options.pypi_url, | ||
verbose=verbose, | ||
) | ||
|
||
_info('Creating virtualenv') | ||
deploy.create_virtualenv() | ||
|
||
deploy.install_dependencies() | ||
deploy.install_package() | ||
deploy.fix_shebangs() | ||
|
||
|
||
if __name__ == '__main__': | ||
sys.exit(main() or 0) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#! /usr/bin/perl | ||
# debhelper sequence for wrapping packages inside virtualenvs | ||
|
||
# Copyright (c) Spotify AB 2013 | ||
|
||
# This file is part of dh-virtualenv. | ||
|
||
# dh-virtualenv is free software: you can redistribute it and/or | ||
# modify it under the terms of the GNU General Public License as | ||
# published by the Free Software Foundation, either version 2 of the | ||
# License, or (at your option) any later version. | ||
|
||
# dh-virtualenv is distributed in the hope that it will be useful, but | ||
# WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
# General Public License for more details. | ||
|
||
# You should have received a copy of the GNU General Public License | ||
# along with dh-virtualenv. If not, see | ||
# <http://www.gnu.org/licenses/>. | ||
|
||
use warnings; | ||
use strict; | ||
use Debian::Debhelper::Dh_Lib; | ||
|
||
insert_after("dh_perl", "dh_virtualenv"); | ||
remove_command("dh_auto_install"); | ||
remove_command("dh_python2"); | ||
remove_command("dh_pycentral"); | ||
remove_command("dh_pysupport"); | ||
|
||
1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
dh-virtualenv (0.5-1) unstable; urgency=low | ||
|
||
* Initial public release | ||
|
||
-- Jyrki Pulliainen <jyrki@spotify.com> Wed, 09 Oct 2013 17:18:09 +0200 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
8 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
Source: dh-virtualenv | ||
Section: net | ||
Priority: extra | ||
Maintainer: Jyrki Pulliainen <jyrki@spotify.com> | ||
Build-Depends: debhelper (>= 8), python(>= 2.6.6-3~), | ||
python-setuptools, python-sphinx, python-mock | ||
Standards-Version: 3.9.3 | ||
X-Python-Version: >= 2.6 | ||
|
||
Package: dh-virtualenv | ||
Architecture: all | ||
Depends: ${python:Depends}, ${misc:Depends}, python-virtualenv (>= 1.7), | ||
grep | ||
Description: Wrap & build python packages using virtualenv | ||
This package provides a dh sequencer that helps you to deploy your | ||
virtualenv wrapped installation inside a Debian package. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ | ||
Upstream-Name: dh-virtualenv | ||
Upstream-Contact: Jyrki Pulliainen <jyrki@spotify.com> | ||
Source: http://www.github.com/spotify/dh-virtualenv | ||
|
||
Files: * | ||
Copyright: 2013 Spotify AB | ||
License: GPL-2+ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
debhelper/python_virtualenv.pm usr/share/perl5/Debian/Debhelper/Sequence |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#!/usr/bin/make -f | ||
|
||
%: | ||
dh $@ --with python2 | ||
|
||
override_dh_installdocs: | ||
python setup.py build_sphinx | ||
dh_installdocs doc/_build/html |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
# -*- coding: utf-8 -*- | ||
# Copyright (c) 2013 Spotify AB | ||
|
||
# This file is part of dh-virtualenv. | ||
|
||
# dh-virtualenv is free software: you can redistribute it and/or | ||
# modify it under the terms of the GNU General Public License as | ||
# published by the Free Software Foundation, either version 2 of the | ||
# License, or (at your option) any later version. | ||
|
||
# dh-virtualenv is distributed in the hope that it will be useful, but | ||
# WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
# General Public License for more details. | ||
|
||
# You should have received a copy of the GNU General Public License | ||
# along with dh-virtualenv. If not, see | ||
# <http://www.gnu.org/licenses/>. | ||
|
||
import os | ||
import shutil | ||
import subprocess | ||
import tempfile | ||
|
||
ROOT_ENV_KEY = 'DH_VIRTUALENV_INSTALL_ROOT' | ||
DEFAULT_INSTALL_DIR = '/usr/share/python/' | ||
|
||
|
||
class Deployment(object): | ||
def __init__(self, package, extra_urls=None, preinstall=None, | ||
pypi_url=None, verbose=False): | ||
self.package = package | ||
self.install_root = os.environ.get(ROOT_ENV_KEY, DEFAULT_INSTALL_DIR) | ||
root = self.install_root.lstrip('/') | ||
self.debian_root = os.path.join('debian', package, root) | ||
self.package_dir = os.path.join(self.debian_root, package) | ||
self.bin_dir = os.path.join(self.package_dir, 'bin') | ||
|
||
self.extra_urls = extra_urls if extra_urls is not None else [] | ||
self.preinstall = preinstall if preinstall is not None else [] | ||
self.pypi_url = pypi_url | ||
self.log_file = tempfile.NamedTemporaryFile() | ||
self.verbose = verbose | ||
|
||
def clean(self): | ||
shutil.rmtree(self.debian_root) | ||
|
||
def create_virtualenv(self): | ||
subprocess.check_call(['virtualenv', | ||
'--no-site-packages', | ||
self.package_dir]) | ||
|
||
# We need to prefix the pip run with the location of python | ||
# executable. Otherwise it would just blow up due to too long | ||
# shebang-line. | ||
self.pip_prefix = [ | ||
os.path.join(self.bin_dir, 'python'), | ||
os.path.join(self.bin_dir, 'pip'), | ||
] | ||
if self.verbose: | ||
self.pip_prefix.append('-v') | ||
|
||
self.pip_prefix.append('install') | ||
|
||
if self.pypi_url: | ||
self.pip_prefix.append('--pypi-url={0}'.format(self.pypi_url)) | ||
self.pip_prefix.extend([ | ||
'--extra-index-url={0}'.format(url) for url in self.extra_urls | ||
]) | ||
self.pip_prefix.append('--log={0}'.format(self.log_file.name)) | ||
|
||
def pip(self, *args): | ||
return self.pip_prefix + list(args) | ||
|
||
def install_dependencies(self): | ||
# Install preinstall stage packages. This is handy if you need | ||
# a custom package to install dependencies (think something | ||
# along lines of setuptools), but that does not get installed | ||
# by default virtualenv. | ||
if self.preinstall: | ||
subprocess.check_call(self.pip(*self.preinstall)) | ||
|
||
if os.path.exists('requirements.txt'): | ||
subprocess.check_call(self.pip('-r', 'requirements.txt')) | ||
|
||
def fix_shebangs(self): | ||
"""Translate /usr/bin/python and /usr/bin/env python sheband | ||
lines to point to our virtualenv python. | ||
""" | ||
grep_proc = subprocess.Popen( | ||
['grep', '-l', '-r', '-e', r'^#!.*bin/\(env \)\?python', | ||
self.bin_dir], | ||
stdout=subprocess.PIPE | ||
) | ||
files, stderr = grep_proc.communicate() | ||
files = files.strip() | ||
if not files: | ||
return | ||
|
||
pythonpath = os.path.join(self.install_root, self.package, 'bin/python') | ||
for f in files.split('\n'): | ||
subprocess.check_call( | ||
['sed', '-i', r's|^#!.*bin/\(env \)\?python|#!{0}|'.format( | ||
pythonpath), | ||
f]) | ||
|
||
def install_package(self): | ||
temp = tempfile.NamedTemporaryFile() | ||
subprocess.check_call([ | ||
os.path.join(self.bin_dir, 'python'), | ||
'setup.py', | ||
'install', | ||
'--record', temp.name, | ||
'--install-headers', | ||
os.path.join(self.package_dir, 'include/site/python2.6'), | ||
]) |
Oops, something went wrong.