Skip to content

Commit

Permalink
Replace entry_points console_scripts
Browse files Browse the repository at this point in the history
The console scripts generated by entry_points are too complex for
our needs and make things run slowly in service of a multi-version
install that we don't use.

Instead, install a simple script which just does a direct import.

Change-Id: I1ec46837cea07db514f2fb6338c7bced34a83c4a
  • Loading branch information
emonty committed Jul 21, 2013
1 parent c84876d commit 8e58c2f
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 1 deletion.
1 change: 1 addition & 0 deletions pbr/hooks/commands.py
Expand Up @@ -38,6 +38,7 @@ def add_command(self, command):

def hook(self):
self.add_command('pbr.packaging.LocalSDist')
self.add_command('pbr.packaging.LocalInstallScripts')

if packaging.have_sphinx():
self.add_command('pbr.packaging.LocalBuildDoc')
Expand Down
64 changes: 64 additions & 0 deletions pbr/packaging.py
Expand Up @@ -30,7 +30,9 @@
import distutils.errors
from distutils import log
import pkg_resources
from setuptools.command import easy_install
from setuptools.command import install
from setuptools.command import install_scripts
from setuptools.command import sdist

try:
Expand Down Expand Up @@ -430,6 +432,68 @@ def have_nose():
return _have_nose


_script_text = """# PBR Generated from %(group)r
import sys
from %(module_name)s import %(func)s
if __name__ == "__main__":
sys.exit(%(func)s())
"""


def _get_script_args(dist, executable, is_wininst):
"""Override entrypoints console_script."""
header = easy_install.get_script_header("", executable, is_wininst)
for group in 'console_scripts', 'gui_scripts':
for name, ep in dist.get_entry_map(group).items():
script_text = _script_text % dict(
group=group,
module_name=ep.module_name,
func=ep.attrs[0])
yield (name, header+script_text)


class LocalInstallScripts(install_scripts.install_scripts):
"""Intercepts console scripts entry_points."""
command_name = 'install_scripts'

def run(self):
if os.name != 'nt':
get_script_args = _get_script_args
else:
get_script_args = easy_install.get_script_args

import distutils.command.install_scripts

self.run_command("egg_info")
if self.distribution.scripts:
# run first to set up self.outfiles
distutils.command.install_scripts.install_scripts.run(self)
else:
self.outfiles = []
if self.no_ep:
# don't install entry point scripts into .egg file!
return

ei_cmd = self.get_finalized_command("egg_info")
dist = pkg_resources.Distribution(
ei_cmd.egg_base,
pkg_resources.PathMetadata(ei_cmd.egg_base, ei_cmd.egg_info),
ei_cmd.egg_name, ei_cmd.egg_version,
)
bs_cmd = self.get_finalized_command('build_scripts')
executable = getattr(
bs_cmd, 'executable', easy_install.sys_executable)
is_wininst = getattr(
self.get_finalized_command("bdist_wininst"), '_is_running', False
)
for args in get_script_args(dist, executable, is_wininst):
self.write_script(*args)


class LocalSDist(sdist.sdist):
"""Builds the ChangeLog and Authors files from VC first."""

Expand Down
2 changes: 1 addition & 1 deletion pbr/tests/__init__.py
Expand Up @@ -100,7 +100,7 @@ def tearDown(self):
def run_setup(self, *args):
return self._run_cmd(sys.executable, ('setup.py',) + args)

def _run_cmd(self, cmd, args):
def _run_cmd(self, cmd, args=[]):
"""Run a command in the root of the test working copy.
Runs a command, with the given argument list, in the root of the test
Expand Down
25 changes: 25 additions & 0 deletions pbr/tests/test_core.py
Expand Up @@ -42,6 +42,8 @@
import os
import tarfile

import fixtures

from pbr import tests


Expand Down Expand Up @@ -73,3 +75,26 @@ def test_sdist_extra_files(self):
names = ['/'.join(p.split('/')[1:]) for p in tf.getnames()]

assert 'extra-file.txt' in names

def test_console_script_install(self):
"""Test that we install a non-pkg-resources console script."""

if os.name == 'nt':
self.skipTest('Windows support is passthrough')

stdout, _, return_code = self.run_setup(
'install_scripts', '--install-dir=%s' % self.temp_dir)

self.assertIn(
'Installing pbr_test_cmd script to %s' % self.temp_dir,
stdout)
self.assertNotIn(
'pkg_resources',
open(os.path.join(self.temp_dir, 'pbr_test_cmd'), 'r').read())

self.useFixture(
fixtures.EnvironmentVariable('PYTHONPATH', '.'))

stdout, _, return_code = self._run_cmd(
os.path.join(self.temp_dir, 'pbr_test_cmd'))
self.assertIn("PBR", stdout)
19 changes: 19 additions & 0 deletions pbr/tests/testpackage/pbr_testpackage/cmd.py
@@ -0,0 +1,19 @@
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import print_function


def main():
print("PBR Test Command")
4 changes: 4 additions & 0 deletions pbr/tests/testpackage/setup.cfg
Expand Up @@ -31,6 +31,10 @@ package-data = testpackage = package_data/*.txt
data-files = testpackage/data_files = data_files/*.txt
extra-files = extra-file.txt

[entry_points]
console_scripts =
pbr_test_cmd = pbr_testpackage.cmd:main

[extension=pbr_testpackage.testext]
sources = src/testext.c
optional = True
Expand Down
43 changes: 43 additions & 0 deletions tools/integration.sh
Expand Up @@ -90,6 +90,49 @@ extra-index-url = http://pypi.openstack.org/openstack
log = /home/jenkins/pip.log
EOF

eptest=$tmpdir/eptest
mkdir $eptest
cd $eptest

cat <<EOF > setup.cfg
[metadata]
name = test_project
[entry_points]
console_scripts =
test_cmd = test_project:main
[global]
setup-hooks =
pbr.hooks.setup_hook
EOF

cat <<EOF > setup.py
import setuptools
setuptools.setup(
setup_requires=['pbr'],
pbr=True)
EOF

mkdir test_project
cat <<EOF > test_project/__init__.py
def main():
print "Test cmd"
EOF

epvenv=$eptest/venv
mkvenv $epvenv setuptools pip

eppbrdir=$tmpdir/eppbrdir
git clone $REPODIR/pbr $eppbrdir
$epvenv/bin/pip install -e $eppbrdir

PBR_VERSION=0.0 $epvenv/bin/python setup.py install
cat $epvenv/bin/test_cmd
grep 'PBR Generated' $epvenv/bin/test_cmd
$epvenv/bin/test_cmd | grep 'Test cmd'

projectdir=$tmpdir/projects
mkdir -p $projectdir

Expand Down

0 comments on commit 8e58c2f

Please sign in to comment.