diff --git a/CHANGELOG b/CHANGELOG index 9617bd6..74d501e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,10 @@ +0.6.0 +----- + + - Use logger instead of print statements + - Update dependencies, fix deprecation warnings + - Use requests package for downloads on all platforms + 0.5.0 ----- diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f67b274..b1c94b7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,7 +16,7 @@ part of the development process. Pull requests are welcomed! Please try to adhere to the following. - code should conform to PEP8 and as well as the linting done by flake8 -- include any relevant documentation updates +- include any relevant documentation updates and test cases It's a good idea to make pull requests early on. A pull request represents the start of a discussion, and doesn't necessarily need to be the final, finished diff --git a/README.md b/README.md index 080c8f9..2cfe792 100644 --- a/README.md +++ b/README.md @@ -172,11 +172,11 @@ You can use this like: >>> compile_files([source_file_path], import_remappings=["zeppeling=/my-zeppelin-checkout-folder"]) ``` -[More information about solc import aliasing](http://solidity.readthedocs.io/en/develop/layout-of-source-files.html#paths) +[More information about solc import aliasing](http://solidity.readthedocs.io/en/latest/layout-of-source-files.html#paths) ## Development -This project was recently forked from [py-solc](https://github.com/ethereum/py-solc) and should be considered a beta. Comments, questions, criticisms and pull requests are welcomed. +This project was forked from [py-solc](https://github.com/ethereum/py-solc) and should be considered a beta. Comments, questions, criticisms and pull requests are welcomed. ### Tests diff --git a/requirements-dev.txt b/requirements-dev.txt index bdfaad9..a6c50ab 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,6 +1,6 @@ coveralls==1.7.0 pytest>=5.0.0 pytest-cov>=2.7.1 -semantic_version>=2.6.0 +semantic_version>=2.8.1,<3 twine==1.13.0 -requests>=2.19.0 \ No newline at end of file +requests>=2.19.0,<3 diff --git a/setup.py b/setup.py index 80cffbb..75e27bf 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setup( name='py-solc-x', - version='0.5.0', + version='0.6.0', description="""Python wrapper around the solc binary with 0.5.x support""", long_description_markdown_filename='README.md', author='Ben Hauser (forked from py-solc by Piper Merriam)', @@ -19,8 +19,8 @@ setup_requires=['setuptools-markdown'], python_requires='>=3.4, <4', install_requires=[ - "semantic_version>=2.8.1", - "requests>=2.9.1" + "semantic_version>=2.8.1,<3", + "requests>=2.19.0,<3" ], license="MIT", zip_safe=False, diff --git a/solcx/exceptions.py b/solcx/exceptions.py index 754a4ba..6eb6ce6 100644 --- a/solcx/exceptions.py +++ b/solcx/exceptions.py @@ -44,3 +44,7 @@ class ContractsNotFound(SolcError): class SolcNotInstalled(Exception): pass + + +class DownloadError(Exception): + pass diff --git a/solcx/install.py b/solcx/install.py index ce3d6f7..328f49a 100644 --- a/solcx/install.py +++ b/solcx/install.py @@ -13,10 +13,14 @@ import subprocess import sys import tarfile +import tempfile import zipfile import logging -from .exceptions import SolcNotInstalled +from .exceptions import ( + DownloadError, + SolcNotInstalled, +) DOWNLOAD_BASE = "https://github.com/ethereum/solidity/releases/download/{}/{}" ALL_RELEASES = "https://api.github.com/repos/ethereum/solidity/releases" @@ -233,18 +237,6 @@ def _chmod_plus_x(executable_path): executable_path.chmod(executable_path.stat().st_mode | stat.S_IEXEC) -def _wget(url, path): - try: - _check_subprocess_call( - ["wget", url, "-O", str(path)], - "Downloading solc from {}".format(url) - ) - except subprocess.CalledProcessError: - if path.exists(): - path.unlink() - raise - - def _check_for_installed_version(version): path = get_solc_folder().joinpath("solc-" + version) if path.exists(): @@ -254,20 +246,33 @@ def _check_for_installed_version(version): def _get_temp_folder(): - path = Path(__file__).parent.joinpath('temp') + path = Path(tempfile.gettempdir()).joinpath('py-solc-x-tmp') if path.exists(): shutil.rmtree(str(path)) path.mkdir() return path +def _download_solc(url): + response = requests.get(url) + if response.status_code != 200: + raise DownloadError( + "Received status code {} when attempting to download from {}".format( + response.status_code, + url + ) + ) + return response.content + + def _install_solc_linux(version): download = DOWNLOAD_BASE.format(version, "solc-static-linux") binary_path = _check_for_installed_version(version) if binary_path: - temp_path = _get_temp_folder().joinpath("solc-binary") - _wget(download, temp_path) - temp_path.rename(binary_path) + LOGGER.info("Downloading solc {} from {}".format(version, download)) + content = _download_solc(download) + with open(binary_path, 'wb') as fp: + fp.write(content) _chmod_plus_x(binary_path) @@ -276,46 +281,44 @@ def _install_solc_windows(version): install_folder = _check_for_installed_version(version) if install_folder: temp_path = _get_temp_folder() - LOGGER.info("Downloading solc {} from {}".format(version, download)) - request = requests.get(download) - with zipfile.ZipFile(BytesIO(request.content)) as zf: + content = _download_solc(download) + with zipfile.ZipFile(BytesIO(content)) as zf: zf.extractall(str(temp_path)) install_folder = get_solc_folder().joinpath("solc-" + version) temp_path.rename(install_folder) -def _install_solc_osx(version, allow): - if version.startswith("v0.4") and not allow: +def _install_solc_osx(version, allow_osx): + if version.startswith("v0.4") and not allow_osx: raise ValueError( "Py-solc-x cannot build solc versions 0.4.x on OSX. If you install solc 0.4.x " "using brew and reload solcx, the installed version will be available. " "See https://github.com/ethereum/homebrew-ethereum for installation instructions.\n\n" "To ignore this error, include 'allow_osx=True' when calling solcx.install_solc()" ) - temp_path = _get_temp_folder().joinpath("solc-source.tar.gz".format(version)) - source_folder = _get_temp_folder().joinpath("solidity_" + version[1:]) + temp_path = _get_temp_folder() download = DOWNLOAD_BASE.format(version, "solidity_{}.tar.gz".format(version[1:])) binary_path = _check_for_installed_version(version) if not binary_path: return - _wget(download, temp_path) - with tarfile.open(str(temp_path), "r") as tar: - tar.extractall(str(_get_temp_folder())) + content = _download_solc(download) + with tarfile.open(fileobj=BytesIO(content)) as tar: + tar.extractall(temp_path) + temp_path = temp_path.joinpath('solidity_{}'.format(version[1:])) _check_subprocess_call( - ["sh", str(source_folder.joinpath('scripts/install_deps.sh'))], + ["sh", str(temp_path.joinpath('scripts/install_deps.sh'))], message="Running dependency installation script `install_deps.sh` @ {}".format(temp_path) ) original_path = os.getcwd() - source_folder.joinpath('build').mkdir(exist_ok=True) - os.chdir(str(source_folder.joinpath('build').resolve())) + temp_path.joinpath('build').mkdir(exist_ok=True) + os.chdir(str(temp_path.joinpath('build').resolve())) try: for cmd in (["cmake", ".."], ["make"]): _check_subprocess_call(cmd, message="Running {}".format(cmd[0])) - os.chdir(original_path) - source_folder.joinpath('build/solc/solc').rename(binary_path) + temp_path.joinpath('build/solc/solc').rename(binary_path) except subprocess.CalledProcessError as e: raise OSError( "{} returned non-zero exit status {}".format(cmd[0], e.returncode) + @@ -324,7 +327,6 @@ def _install_solc_osx(version, allow): ) finally: os.chdir(original_path) - shutil.rmtree(str(temp_path.parent)) _chmod_plus_x(binary_path)