-
Notifications
You must be signed in to change notification settings - Fork 14
/
wheel-uploader
executable file
·133 lines (123 loc) · 4.78 KB
/
wheel-uploader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/usr/bin/env python
""" Download wheels from upstream URL, upload with twine
"""
from __future__ import print_function, absolute_import
import os
from os.path import join as pjoin, splitext, exists, expanduser
import sys
import re
from optparse import OptionParser, Option
if sys.version_info[0] >= 3:
from urllib.request import urlopen, urlretrieve
else:
from urllib import urlretrieve
from urllib2 import urlopen
from subprocess import check_call, PIPE
# From `pip install beautifulsoup4`
from bs4 import BeautifulSoup
__version__ = '0.1'
RACKSPACE_URL='http://wheels.scikit-image.org'
WHEEL_RE = re.compile('^.*\.whl$')
def get_wheel_names(url):
""" Get wheel names from HTML directory listing
"""
html = urlopen(url).read()
soup = BeautifulSoup(html, 'html.parser')
# This is almost certainly specific to the Rackspace directory
cells = soup.findAll('td', attrs='colname', text=WHEEL_RE)
if cells:
return [cell.text for cell in cells]
# Works for e.g. Apache directory listing, looking in contents of links
cells = soup.findAll('a', text=WHEEL_RE)
if cells:
return [cell.text for cell in cells]
cells = soup.findAll(text=WHEEL_RE)
return [str(cell) for cell in cells]
def main():
parser = OptionParser(
usage="%s PACKAGE_NAME VERSION\n\n" % sys.argv[0] + __doc__,
version="%prog " + __version__)
parser.add_option(
Option("-u", "--wheel-url-dir", type='string', default=RACKSPACE_URL,
help="URL for web directory containing wheels for uploading "
"[default %default]"))
parser.add_option(
Option("-w", "--wheel-dir",
action="store", type='string', default=os.getcwd(),
help="Directory to store downloaded wheels [defaults to "
"current working directory]"))
parser.add_option(
Option("-t", "--wheel-type",
action="store", type='string', default="macosx",
help="Platform type of wheels to download "
"[default %default], one of 'all', 'macosx', 'win', "
"'manylinux1', 'linux'"))
parser.add_option(
Option("-c", "--clobber",
action="store_true",
help="Overwrite pre-existing wheels"))
parser.add_option(
Option("-n", "--no-twine",
action="store_true",
help="Do not upload wheels with twine"))
parser.add_option(
Option("-s", "--sign",
action="store_true",
help="Sign wheels before upload"))
parser.add_option(
Option("-r", "--repository",
help="Repository to upload to [defaults to pypi]"))
parser.add_option(
Option("-v", "--verbose",
action="store_true",
help="Give more feedback"))
(opts, pkg_identifiers) = parser.parse_args()
wheel_dir = expanduser(opts.wheel_dir)
wheel_url_dir = opts.wheel_url_dir
if not wheel_url_dir.endswith('/'):
wheel_url_dir += '/'
if len(pkg_identifiers) != 2:
parser.print_help()
sys.exit(1)
pkg_name, pkg_version = pkg_identifiers
wheel_root = '{0}-{1}-'.format(pkg_name, pkg_version)
try:
check_call(['twine', '-h'], stdout=PIPE)
except OSError:
raise RuntimeError('Please install "twine" utility')
twine_opts = ['--sign'] if opts.sign else []
if opts.repository:
twine_opts += ['--repository=' + opts.repository]
wheel_names = get_wheel_names(wheel_url_dir)
copied_wheels = []
found_wheels = []
for wheel_name in wheel_names:
if not wheel_name.startswith(wheel_root):
continue
root, ext = splitext(wheel_name)
project, version, pyv, pycv, plat = root.split('-')
if opts.wheel_type != 'all' and not opts.wheel_type in plat:
continue
wheel_url = wheel_url_dir + wheel_name
wheel_path = pjoin(wheel_dir, wheel_name)
found_wheels.append(wheel_path)
if exists(wheel_path) and not opts.clobber:
if opts.verbose:
print('Not overwriting {0}'.format(wheel_path))
continue
if opts.verbose:
print("Downloading {0} to {1}".format(wheel_url, wheel_path))
urlretrieve(wheel_url, wheel_path)
copied_wheels.append(wheel_path)
if len (found_wheels) == 0:
raise RuntimeError('Found no wheels at {0} for {1} and type {2}'.format(
opts.wheel_url_dir, wheel_root, opts.wheel_type))
if opts.no_twine:
if opts.verbose:
print("Found wheels but not uploading because of "
"--no-twine flag\n{0}".format(
'\n'.join(found_wheels)))
return
check_call(['twine', 'upload'] + twine_opts + found_wheels)
if __name__ == '__main__':
main()