blob: 599e161139053c2e98a7db4da28814ab22272f1e [file] [log] [blame]
# Copyright (C) 2010-2018 Vincent Pelletier <plr.vincent@gmail.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
from __future__ import print_function
from setuptools import setup
from setuptools import Command
import setuptools.command.install
from codecs import open
import errno
import hashlib
import os
import subprocess
import sys
import versioneer
try:
from urllib.request import urlopen
from urllib.parse import urlsplit
from html.parser import HTMLParser
except ImportError:
# BBB: python 2.7
from urllib2 import urlopen
from urlparse import urlsplit
from HTMLParser import HTMLParser
if os.getenv('I_KNOW_HOW_TO_RELEASE_PYTHON_LIBUSB1') != '1' and any(
x in sys.argv for x in ('sdist', 'upload')
):
print('Use setup.sh to build')
sys.exit(1)
CURRENT_WINDOWS_7Z_SHA256 = (
'd3087e7d09ec4e463f5f4b394dcfec0b90e835545318af1a75575de59d2dfaac'
)
cmdclass = versioneer.get_cmdclass()
class install(setuptools.command.install.install):
def run(self):
# XXX: setuptools.command.install.install is an old-style class on
# python2.7 :(
setuptools.command.install.install.run(self)
if os.getenv('LIBUSB_BINARY'):
self.copy_file(
os.getenv('LIBUSB_BINARY'),
os.path.join(self.install_lib, 'usb1'),
)
cmdclass['install'] = install
class upload(Command):
def run(self):
print('This project uses signed releases. See KEYS for instructions.')
print('Hint:')
print(' twine upload dist/<release file> dist/<release file>.asc')
sys.exit(1)
cmdclass['upload'] = upload
class update_libusb(Command):
user_options = []
def initialize_options(self):
pass
def finalize_options(self):
pass
class WindowsBinariesArchiveLinkFinder(HTMLParser):
found = None
__a_href = None
def handle_starttag(self, tag, attrs):
if tag == 'a':
assert self.__a_href is None, repr(self.__a_href)
self.__a_href = dict(attrs).get('href')
def handle_endtag(self, tag):
if tag == 'a':
self.__a_href = None
def handle_data(self, data):
if self.__a_href is not None and data == 'Latest Windows Binaries':
assert self.found is None, repr(self.found)
self.found = self.__a_href
def run(self):
finder = self.WindowsBinariesArchiveLinkFinder()
finder.feed(urlopen('https://libusb.info/').read().decode('utf-8'))
finder.close()
url = finder.found
if url is None:
raise ValueError('Failed to locate current windows binary release')
build_dir = os.path.join(os.path.dirname(__file__), 'build')
download_cache_path = os.path.join(build_dir, 'download-cache')
archive_path = os.path.join(
download_cache_path,
urlsplit(url).path.rsplit('/', 1)[-1],
)
if not os.path.exists(archive_path):
os.makedirs(download_cache_path)
with open(archive_path, 'wb') as archive_file:
archive_file.write(urlopen(url).read())
with open(archive_path, 'rb') as archive_file:
archive_sha256 = hashlib.sha256(archive_file.read()).hexdigest()
if archive_sha256 != CURRENT_WINDOWS_7Z_SHA256:
raise ValueError(
'Windows release sha56 mismatch: %r fetched with a sha256 of %r' % (
url,
archive_sha256,
)
)
# py2 does not have subprocess.DEVNULL.
with open(os.devnull, 'wb') as devnull:
for arch_path, out_dir in (
('MS32/dll/libusb-1.0.dll', os.path.join(build_dir, 'win32')),
('MS64/dll/libusb-1.0.dll', os.path.join(build_dir, 'win_amd64')),
):
subprocess.check_call(
[
'7z', 'e', '-aoa',
'-o' + out_dir,
archive_path,
arch_path,
],
# 7z will not shut its pie hole.
stdout=devnull,
close_fds=True,
)
cmdclass['update_libusb'] = update_libusb
long_description = open(
os.path.join(os.path.dirname(__file__), 'README.rst'),
encoding='utf8',
).read()
setup(
name='libusb1',
description=next(x for x in long_description.splitlines() if x.strip()),
long_description='.. contents::\n\n' + long_description,
keywords='usb libusb',
version=versioneer.get_version(),
cmdclass=cmdclass,
author='Vincent Pelletier',
author_email='plr.vincent@gmail.com',
url='http://github.com/vpelletier/python-libusb1',
license='LGPLv2.1+',
platforms=['any'],
py_modules=['libusb1'],
packages=['usb1'],
classifiers=[
'Intended Audience :: Developers',
'License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)',
'Operating System :: OS Independent',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Software Development :: Libraries',
'Topic :: System :: Hardware :: Hardware Drivers',
],
setup_requires=[
'wheel',
],
use_2to3=True,
test_suite='usb1.testUSB1',
)