Skip to content

Commit 0afa53f

Browse files
committed
use setuptools-download to download binaries
1 parent 0d916f1 commit 0afa53f

File tree

2 files changed

+48
-157
lines changed

2 files changed

+48
-157
lines changed

setup.cfg

+45
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
[metadata]
22
name = shellcheck_py
3+
version = 0.9.0.6
34
description = Python wrapper around invoking shellcheck (https://www.shellcheck.net/)
45
long_description = file: README.md
56
long_description_content_type = text/markdown
@@ -17,3 +18,47 @@ classifiers =
1718

1819
[options]
1920
python_requires = >=3.8
21+
setup_requires =
22+
setuptools-download
23+
24+
[setuptools_download]
25+
download_scripts =
26+
[shellcheck]
27+
group = shellcheck-binary
28+
marker = sys_platform == "linux" and platform_machine == "armv6hf"
29+
marker = sys_platform == "linux" and platform_machine == "armv7l"
30+
url = https://github.com/koalaman/shellcheck/releases/download/v0.9.0/shellcheck-v0.9.0.linux.armv6hf.tar.xz
31+
sha256 = 03deed9ded9dd66434ccf9649815bcde7d275d6c9f6dcf665b83391673512c75
32+
extract = tar
33+
extract_path = shellcheck-v0.9.0/shellcheck
34+
[shellcheck]
35+
group = shellcheck-binary
36+
marker = sys_platform == "linux" and platform_machine == "aarch64"
37+
url = https://github.com/koalaman/shellcheck/releases/download/v0.9.0/shellcheck-v0.9.0.linux.aarch64.tar.xz
38+
sha256 = 179c579ef3481317d130adebede74a34dbbc2df961a70916dd4039ebf0735fae
39+
extract = tar
40+
extract_path = shellcheck-v0.9.0/shellcheck
41+
[shellcheck]
42+
group = shellcheck-binary
43+
marker = sys_platform == "linux" and platform_machine == "x86_64"
44+
url = https://github.com/koalaman/shellcheck/releases/download/v0.9.0/shellcheck-v0.9.0.linux.x86_64.tar.xz
45+
sha256 = 700324c6dd0ebea0117591c6cc9d7350d9c7c5c287acbad7630fa17b1d4d9e2f
46+
extract = tar
47+
extract_path = shellcheck-v0.9.0/shellcheck
48+
[shellcheck]
49+
group = shellcheck-binary
50+
marker = sys_platform == "darwin" and platform_machine == "x86_64"
51+
marker = sys_platform == "darwin" and platform_machine == "arm64"
52+
url = https://github.com/koalaman/shellcheck/releases/download/v0.9.0/shellcheck-v0.9.0.darwin.x86_64.tar.xz
53+
sha256 = 7d3730694707605d6e60cec4efcb79a0632d61babc035aa16cda1b897536acf5
54+
extract = tar
55+
extract_path = shellcheck-v0.9.0/shellcheck
56+
[shellcheck.exe]
57+
group = shellcheck-binary
58+
marker = sys_platform == "win32" and platform_machine == "AMD64"
59+
marker = sys_platform == "win32" and platform_machine == "ARM64"
60+
marker = sys_platform == "cygwin" and platform_machine == "x86_64"
61+
url = https://github.com/koalaman/shellcheck/releases/download/v0.9.0/shellcheck-v0.9.0.zip
62+
sha256 = ae58191b1ea4ffd9e5b15da9134146e636440302ce3e2f46863e8d71c8be1bbb
63+
extract = zip
64+
extract_path = shellcheck.exe

setup.py

+3-157
Original file line numberDiff line numberDiff line change
@@ -1,165 +1,11 @@
1-
#!/usr/bin/env python3
21
from __future__ import annotations
32

4-
import hashlib
5-
import http
6-
import io
7-
import os.path
8-
import platform
9-
import stat
10-
import sys
11-
import tarfile
12-
import urllib.request
13-
import zipfile
14-
15-
from distutils.command.build import build as orig_build
16-
from distutils.core import Command
173
from setuptools import setup
18-
from setuptools.command.install import install as orig_install
19-
20-
SHELLCHECK_VERSION = '0.9.0'
21-
POSTFIX_SHA256 = {
22-
('linux', 'armv6hf'): (
23-
'linux.armv6hf.tar.xz',
24-
'03deed9ded9dd66434ccf9649815bcde7d275d6c9f6dcf665b83391673512c75',
25-
),
26-
('linux', 'aarch64'): (
27-
'linux.aarch64.tar.xz',
28-
'179c579ef3481317d130adebede74a34dbbc2df961a70916dd4039ebf0735fae',
29-
),
30-
('linux', 'x86_64'): (
31-
'linux.x86_64.tar.xz',
32-
'700324c6dd0ebea0117591c6cc9d7350d9c7c5c287acbad7630fa17b1d4d9e2f',
33-
),
34-
('darwin', 'x86_64'): (
35-
'darwin.x86_64.tar.xz',
36-
'7d3730694707605d6e60cec4efcb79a0632d61babc035aa16cda1b897536acf5',
37-
),
38-
('win32', 'AMD64'): (
39-
'zip',
40-
'ae58191b1ea4ffd9e5b15da9134146e636440302ce3e2f46863e8d71c8be1bbb',
41-
),
42-
}
43-
POSTFIX_SHA256[('cygwin', 'x86_64')] = POSTFIX_SHA256[('win32', 'AMD64')]
44-
POSTFIX_SHA256[('win32', 'ARM64')] = POSTFIX_SHA256[('win32', 'AMD64')]
45-
POSTFIX_SHA256[('darwin', 'arm64')] = POSTFIX_SHA256[('darwin', 'x86_64')]
46-
POSTFIX_SHA256[('linux', 'armv7l')] = POSTFIX_SHA256[('linux', 'armv6hf')]
47-
PY_VERSION = '6'
48-
49-
50-
def get_download_url() -> tuple[str, str]:
51-
postfix, sha256 = POSTFIX_SHA256[(sys.platform, platform.machine())]
52-
url = (
53-
f'https://github.com/koalaman/shellcheck/releases/download/'
54-
f'v{SHELLCHECK_VERSION}/shellcheck-v{SHELLCHECK_VERSION}.{postfix}'
55-
)
56-
return url, sha256
57-
58-
59-
def download(url: str, sha256: str) -> bytes:
60-
with urllib.request.urlopen(url) as resp:
61-
code = resp.getcode()
62-
if code != http.HTTPStatus.OK:
63-
raise ValueError(f'HTTP failure. Code: {code}')
64-
data = resp.read()
65-
66-
checksum = hashlib.sha256(data).hexdigest()
67-
if checksum != sha256:
68-
raise ValueError(f'sha256 mismatch, expected {sha256}, got {checksum}')
69-
70-
return data
71-
72-
73-
def extract(url: str, data: bytes) -> bytes:
74-
with io.BytesIO(data) as bio:
75-
if '.tar.' in url:
76-
with tarfile.open(fileobj=bio) as tarf:
77-
for info in tarf.getmembers():
78-
if info.isfile() and info.name.endswith('shellcheck'):
79-
return tarf.extractfile(info).read()
80-
elif url.endswith('.zip'):
81-
with zipfile.ZipFile(bio) as zipf:
82-
for info in zipf.infolist():
83-
if info.filename.endswith('.exe'):
84-
return zipf.read(info.filename)
85-
86-
raise AssertionError(f'unreachable {url}')
87-
88-
89-
def save_executable(data: bytes, base_dir: str):
90-
exe = 'shellcheck' if sys.platform != 'win32' else 'shellcheck.exe'
91-
output_path = os.path.join(base_dir, exe)
92-
os.makedirs(base_dir, exist_ok=True)
93-
94-
with open(output_path, 'wb') as fp:
95-
fp.write(data)
96-
97-
# Mark as executable.
98-
# https://stackoverflow.com/a/14105527
99-
mode = os.stat(output_path).st_mode
100-
mode |= stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
101-
os.chmod(output_path, mode)
102-
103-
104-
class build(orig_build):
105-
sub_commands = orig_build.sub_commands + [('fetch_binaries', None)]
106-
107-
108-
class install(orig_install):
109-
sub_commands = orig_install.sub_commands + [('install_shellcheck', None)]
110-
111-
112-
class fetch_binaries(Command):
113-
build_temp = None
114-
115-
def initialize_options(self):
116-
pass
117-
118-
def finalize_options(self):
119-
self.set_undefined_options('build', ('build_temp', 'build_temp'))
120-
121-
def run(self):
122-
# save binary to self.build_temp
123-
url, sha256 = get_download_url()
124-
archive = download(url, sha256)
125-
data = extract(url, archive)
126-
save_executable(data, self.build_temp)
127-
128-
129-
class install_shellcheck(Command):
130-
description = 'install the shellcheck executable'
131-
outfiles = ()
132-
build_dir = install_dir = None
133-
134-
def initialize_options(self):
135-
pass
136-
137-
def finalize_options(self):
138-
# this initializes attributes based on other commands' attributes
139-
self.set_undefined_options('build', ('build_temp', 'build_dir'))
140-
self.set_undefined_options(
141-
'install', ('install_scripts', 'install_dir'),
142-
)
143-
144-
def run(self):
145-
self.outfiles = self.copy_tree(self.build_dir, self.install_dir)
146-
147-
def get_outputs(self):
148-
return self.outfiles
149-
150-
151-
command_overrides = {
152-
'install': install,
153-
'install_shellcheck': install_shellcheck,
154-
'build': build,
155-
'fetch_binaries': fetch_binaries,
156-
}
157-
1584

1595
try:
1606
from wheel.bdist_wheel import bdist_wheel as orig_bdist_wheel
1617
except ImportError:
162-
pass
8+
cmdclass = {}
1639
else:
16410
class bdist_wheel(orig_bdist_wheel):
16511
def finalize_options(self):
@@ -172,6 +18,6 @@ def get_tag(self):
17218
# We don't contain any python source, nor any python extensions
17319
return 'py2.py3', 'none', plat
17420

175-
command_overrides['bdist_wheel'] = bdist_wheel
21+
cmdclass = {'bdist_wheel': bdist_wheel}
17622

177-
setup(version=f'{SHELLCHECK_VERSION}.{PY_VERSION}', cmdclass=command_overrides)
23+
setup(cmdclass=cmdclass)

0 commit comments

Comments
 (0)