Skip to content

Commit 8d68f7f

Browse files
committed
Merge pull request pypa#12 from qwcode/wheel_build
'pip wheel'
2 parents 6e481b1 + 7e36aae commit 8d68f7f

File tree

9 files changed

+383
-84
lines changed

9 files changed

+383
-84
lines changed

pip/commands/install.py

+12-79
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from pip.index import PackageFinder
1111
from pip.exceptions import InstallationError, CommandError
1212
from pip.backwardcompat import home_lib
13+
from pip.commands.options import *
1314

1415

1516
class InstallCommand(Command):
@@ -35,60 +36,14 @@ def __init__(self):
3536
'setup.py develop). You can run this on an existing directory/checkout (like '
3637
'pip install -e src/mycheckout). This option may be provided multiple times. '
3738
'Possible values for VCS are: svn, git, hg and bzr.')
38-
self.parser.add_option(
39-
'-r', '--requirement',
40-
dest='requirements',
41-
action='append',
42-
default=[],
43-
metavar='FILENAME',
44-
help='Install all the packages listed in the given requirements file. '
45-
'This option can be used multiple times.')
46-
self.parser.add_option(
47-
'-f', '--find-links',
48-
dest='find_links',
49-
action='append',
50-
default=[],
51-
metavar='URL',
52-
help='URL to look for packages at')
53-
self.parser.add_option(
54-
'-i', '--index-url', '--pypi-url',
55-
dest='index_url',
56-
metavar='URL',
57-
default='http://pypi.python.org/simple/',
58-
help='Base URL of Python Package Index (default %default)')
59-
self.parser.add_option(
60-
'--extra-index-url',
61-
dest='extra_index_urls',
62-
metavar='URL',
63-
action='append',
64-
default=[],
65-
help='Extra URLs of package indexes to use in addition to --index-url')
66-
self.parser.add_option(
67-
'--no-index',
68-
dest='no_index',
69-
action='store_true',
70-
default=False,
71-
help='Ignore package index (only looking at --find-links URLs instead)')
72-
self.parser.add_option(
73-
'-M', '--use-mirrors',
74-
dest='use_mirrors',
75-
action='store_true',
76-
default=False,
77-
help='Use the PyPI mirrors as a fallback in case the main index is down.')
78-
self.parser.add_option(
79-
'--mirrors',
80-
dest='mirrors',
81-
metavar='URL',
82-
action='append',
83-
default=[],
84-
help='Specific mirror URLs to query when --use-mirrors is used')
85-
86-
self.parser.add_option(
87-
'-b', '--build', '--build-dir', '--build-directory',
88-
dest='build_dir',
89-
metavar='DIR',
90-
default=build_prefix,
91-
help='Unpack packages into DIR (default %default) and build from there')
39+
self.parser.add_option(REQUIREMENTS)
40+
self.parser.add_option(FIND_LINKS)
41+
self.parser.add_option(INDEX_URL)
42+
self.parser.add_option(EXTRA_INDEX_URLS)
43+
self.parser.add_option(NO_INDEX)
44+
self.parser.add_option(USE_MIRRORS)
45+
self.parser.add_option(MIRRORS)
46+
self.parser.add_option(BUILD_DIR)
9247
self.parser.add_option(
9348
'-t', '--target',
9449
dest='target_dir',
@@ -101,19 +56,13 @@ def __init__(self):
10156
metavar='DIR',
10257
default=None,
10358
help='Download packages into DIR instead of installing them')
104-
self.parser.add_option(
105-
'--download-cache',
106-
dest='download_cache',
107-
metavar='DIR',
108-
default=None,
109-
help='Cache downloaded packages in DIR')
59+
self.parser.add_option(DOWNLOAD_CACHE)
11060
self.parser.add_option(
11161
'--src', '--source', '--source-dir', '--source-directory',
11262
dest='src_dir',
11363
metavar='DIR',
11464
default=src_prefix,
11565
help='Check out --editable packages into DIR (default %default)')
116-
11766
self.parser.add_option(
11867
'-U', '--upgrade',
11968
dest='upgrade',
@@ -147,23 +96,8 @@ def __init__(self):
14796
action="store_true",
14897
help="Don't download any packages, just install the ones already downloaded "
14998
"(completes an install run with --no-install)")
150-
151-
self.parser.add_option(
152-
'--install-option',
153-
dest='install_options',
154-
action='append',
155-
help="Extra arguments to be supplied to the setup.py install "
156-
"command (use like --install-option=\"--install-scripts=/usr/local/bin\"). "
157-
"Use multiple --install-option options to pass multiple options to setup.py install. "
158-
"If you are using an option with a directory path, be sure to use absolute path.")
159-
160-
self.parser.add_option(
161-
'--global-option',
162-
dest='global_options',
163-
action='append',
164-
help="Extra global options to be supplied to the setup.py "
165-
"call before the install command")
166-
99+
self.parser.add_option(INSTALL_OPTIONS)
100+
self.parser.add_option(GLOBAL_OPTIONS)
167101
self.parser.add_option(
168102
'--user',
169103
dest='use_user_site',
@@ -219,7 +153,6 @@ def run(self, options, args):
219153
src_dir=options.src_dir,
220154
download_dir=options.download_dir,
221155
download_cache=options.download_cache,
222-
use_wheel=options.use_wheel,
223156
upgrade=options.upgrade,
224157
as_egg=options.as_egg,
225158
ignore_installed=options.ignore_installed,

pip/commands/options.py

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
"""
2+
pip command options
3+
"""
4+
import os
5+
from optparse import make_option
6+
from pip.locations import build_prefix, src_prefix
7+
8+
REQUIREMENTS = make_option(
9+
'-r', '--requirement',
10+
dest='requirements',
11+
action='append',
12+
default=[],
13+
metavar='FILENAME',
14+
help='Install all the packages listed in the given requirements file. '
15+
'This option can be used multiple times.')
16+
17+
FIND_LINKS = make_option(
18+
'-f', '--find-links',
19+
dest='find_links',
20+
action='append',
21+
default=[],
22+
metavar='URL',
23+
help='URL to look for packages at')
24+
INDEX_URL = make_option(
25+
'-i', '--index-url', '--pypi-url',
26+
dest='index_url',
27+
metavar='URL',
28+
default='http://pypi.python.org/simple/',
29+
help='Base URL of Python Package Index (default %default)')
30+
31+
EXTRA_INDEX_URLS = make_option(
32+
'--extra-index-url',
33+
dest='extra_index_urls',
34+
metavar='URL',
35+
action='append',
36+
default=[],
37+
help='Extra URLs of package indexes to use in addition to --index-url')
38+
39+
NO_INDEX = make_option(
40+
'--no-index',
41+
dest='no_index',
42+
action='store_true',
43+
default=False,
44+
help='Ignore package index (only looking at --find-links URLs instead)')
45+
46+
USE_MIRRORS = make_option(
47+
'-M', '--use-mirrors',
48+
dest='use_mirrors',
49+
action='store_true',
50+
default=False,
51+
help='Use the PyPI mirrors as a fallback in case the main index is down.')
52+
53+
MIRRORS = make_option(
54+
'--mirrors',
55+
dest='mirrors',
56+
metavar='URL',
57+
action='append',
58+
default=[],
59+
help='Specific mirror URLs to query when --use-mirrors is used')
60+
61+
DOWNLOAD_CACHE = make_option(
62+
'--download-cache',
63+
dest='download_cache',
64+
metavar='DIR',
65+
default=None,
66+
help='Cache downloaded packages in DIR')
67+
68+
BUILD_DIR = make_option(
69+
'-b', '--build', '--build-dir', '--build-directory',
70+
dest='build_dir',
71+
metavar='DIR',
72+
default=build_prefix,
73+
help='Unpack packages into DIR (default %default) and build from there')
74+
75+
INSTALL_OPTIONS = make_option(
76+
'--install-option',
77+
dest='install_options',
78+
action='append',
79+
help="Extra arguments to be supplied to the setup.py install "
80+
"command (use like --install-option=\"--install-scripts=/usr/local/bin\"). "
81+
"Use multiple --install-option options to pass multiple options to setup.py install. "
82+
"If you are using an option with a directory path, be sure to use absolute path.")
83+
84+
GLOBAL_OPTIONS = make_option(
85+
'--global-option',
86+
dest='global_options',
87+
action='append',
88+
help="Extra global options to be supplied to the setup.py "
89+
"call before the install command")

pip/commands/wheel.py

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# -*- coding: utf-8 -*-
2+
from __future__ import absolute_import
3+
4+
import os
5+
import sys
6+
from pip.basecommand import Command
7+
from pip.commands.options import *
8+
from pip.index import PackageFinder
9+
from pip.log import logger
10+
from pip.exceptions import CommandError
11+
from pip.req import InstallRequirement, RequirementSet, parse_requirements
12+
from pip.util import normalize_path
13+
from pip.wheel import WheelBuilder
14+
15+
16+
DEFAULT_WHEEL_DIR = os.path.join(normalize_path(os.curdir), 'wheelhouse')
17+
18+
class WheelCommand(Command):
19+
name = 'wheel'
20+
usage = '%prog [OPTIONS] PACKAGE_NAMES...'
21+
summary = 'Build wheels from your requirements'
22+
23+
def __init__(self):
24+
super(WheelCommand, self).__init__()
25+
self.parser.add_option(
26+
'-w', '--wheel-dir',
27+
dest='wheel_dir',
28+
metavar='DIR',
29+
default=DEFAULT_WHEEL_DIR,
30+
help='Build wheels into DIR (default %default)')
31+
self.parser.add_option(
32+
'--unpack-only',
33+
dest='unpack_only',
34+
action='store_true',
35+
default=False,
36+
help='Only unpack')
37+
self.parser.add_option(REQUIREMENTS)
38+
self.parser.add_option(FIND_LINKS)
39+
self.parser.add_option(INDEX_URL)
40+
self.parser.add_option(EXTRA_INDEX_URLS)
41+
self.parser.add_option(NO_INDEX)
42+
self.parser.add_option(USE_MIRRORS)
43+
self.parser.add_option(MIRRORS)
44+
self.parser.add_option(DOWNLOAD_CACHE)
45+
self.parser.add_option(BUILD_DIR)
46+
self.parser.add_option(
47+
'--build-option',
48+
dest='build_options',
49+
action='append',
50+
help="Extra arguments to be supplied to setup.py bdist_wheel")
51+
self.parser.add_option(GLOBAL_OPTIONS)
52+
53+
def run(self, options, args):
54+
55+
if sys.version_info < (2, 6):
56+
raise CommandError("'pip wheel' requires Python 2.6 or greater.")
57+
58+
try:
59+
import wheel.bdist_wheel
60+
except ImportError:
61+
raise CommandError("'pip wheel' requires bdist_wheel from the 'wheel' distribution.")
62+
63+
index_urls = [options.index_url] + options.extra_index_urls
64+
if options.no_index:
65+
logger.notify('Ignoring indexes: %s' % ','.join(index_urls))
66+
index_urls = []
67+
68+
finder = PackageFinder(find_links=options.find_links,
69+
index_urls=index_urls,
70+
use_mirrors=options.use_mirrors,
71+
mirrors=options.mirrors,
72+
use_wheel=False)
73+
74+
options.build_dir = os.path.abspath(options.build_dir)
75+
requirement_set = RequirementSet(
76+
build_dir=options.build_dir,
77+
src_dir=None,
78+
download_dir=None,
79+
download_cache=options.download_cache,
80+
ignore_installed=True)
81+
82+
#parse args and/or requirements files
83+
for name in args:
84+
if name.endswith(".whl"):
85+
logger.notify("ignoring %s" % name)
86+
continue
87+
requirement_set.add_requirement(
88+
InstallRequirement.from_line(name, None))
89+
for filename in options.requirements:
90+
for req in parse_requirements(filename, finder=finder, options=options):
91+
if req.editable or (req.name is None and req.url.endswith(".whl")):
92+
logger.notify("ignoring %s" % req.url)
93+
continue
94+
requirement_set.add_requirement(req)
95+
96+
#fail if no requirements
97+
if not requirement_set.has_requirements:
98+
opts = {'name': self.name}
99+
msg = ('You must give at least one requirement '
100+
'to %(name)s (see "pip help %(name)s")' % opts)
101+
logger.error(msg)
102+
return
103+
104+
#if unpack-only, just prepare and return
105+
#'pip wheel' probably shouldn't be offering this? 'pip unpack'?
106+
if options.unpack_only:
107+
requirement_set.prepare_files(finder)
108+
return
109+
110+
#build wheels
111+
wb = WheelBuilder(
112+
requirement_set,
113+
finder,
114+
options.wheel_dir,
115+
build_options = options.build_options or [],
116+
global_options = options.global_options or []
117+
)
118+
wb.build()
119+
120+
requirement_set.cleanup_files()
121+
122+
123+
WheelCommand()

pip/req.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -822,8 +822,7 @@ class RequirementSet(object):
822822

823823
def __init__(self, build_dir, src_dir, download_dir, download_cache=None,
824824
upgrade=False, ignore_installed=False, as_egg=False,
825-
ignore_dependencies=False, force_reinstall=False, use_user_site=False,
826-
use_wheel=False):
825+
ignore_dependencies=False, force_reinstall=False, use_user_site=False):
827826
self.build_dir = build_dir
828827
self.src_dir = src_dir
829828
self.download_dir = download_dir
@@ -841,7 +840,6 @@ def __init__(self, build_dir, src_dir, download_dir, download_cache=None,
841840
self.reqs_to_cleanup = []
842841
self.as_egg = as_egg
843842
self.use_user_site = use_user_site
844-
self.use_wheel = use_wheel
845843

846844
def __str__(self):
847845
reqs = [req for req in self.requirements.values()

0 commit comments

Comments
 (0)