Skip to content

Commit

Permalink
Merge pull request #4 from iamdefinitelyahuman/0.2
Browse files Browse the repository at this point in the history
0.2
  • Loading branch information
iamdefinitelyahuman authored Apr 9, 2019
2 parents 21b8cb2 + 1c276ee commit 5117540
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 41 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
0.2.0
-----

- Fix "No input files given" bug in `solcx.compile_source()` on v0.5.x
- `install.py` - replace `os.path` with `pathlib.Path`
- Linux - copy from `which solc` path to save time installing solc
- OSX - copy solc versions from `usr/local/Cellar`, raise when attempting v0.4.x install

0.1.1
-----

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

setup(
name='py-solc-x',
version='0.1.1',
version='0.2.0',
description="""Python wrapper around the solc binary with 0.5.x support""",
long_description_markdown_filename='README.md',
author='Benjamin Hauser (forked from py-solc by Piper Merriam)',
Expand Down
11 changes: 5 additions & 6 deletions solcx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,20 @@
link_code,
)
from .install import (
import_installed_solc,
install_solc,
get_installed_solc_versions,
get_solc_folder,
set_solc_version
)

# check for an installed version of solc
# install if none found
# default to latest version

if not os.path.exists(get_solc_folder()):
os.mkdir(get_solc_folder())
# check for installed version of solc
import_installed_solc()

# if no installed version, download
if not get_installed_solc_versions():
print("Cannot find solc, installing...")
install_solc()

# default to latest version
set_solc_version(get_installed_solc_versions()[-1])
90 changes: 56 additions & 34 deletions solcx/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""
from io import BytesIO
import os
from pathlib import Path
import requests
import shutil
import stat
Expand All @@ -14,36 +15,54 @@
DOWNLOAD_BASE = "https://github.com/ethereum/solidity/releases/download/{}/{}"
API = "https://api.github.com/repos/ethereum/solidity/releases/latest"

sep = "\\" if sys.platform == "win32" else "/"
solc_version = None


def get_solc_folder():
return __file__[:__file__.rindex(sep)] + sep + "bin" + sep
path = Path(__file__).parent.joinpath('bin')
path.mkdir(exist_ok=True)
return path


def get_executable(version = None):
def import_installed_solc():
if sys.platform.startswith('linux'):
path_list = [subprocess.check_output(['which','solc']).decode().strip()]
if not path_list[0]:
return
elif sys.platform == 'darwin':
path_list = [str(i) for i in Path('/usr/local/Cellar').glob('solidity*/**/solc')]
else:
return
for path in path_list:
version = subprocess.check_output([path, '--version']).decode()
version = "v"+version[version.index("Version: ")+9:version.index('+')]
if version in get_installed_solc_versions():
continue
shutil.copy(path, str(get_solc_folder().joinpath("solc-" + version)))


def get_executable(version=None):
if not version:
version = solc_version
solc_bin = "{}solc-{}".format(get_solc_folder(), version)
solc_bin = get_solc_folder().joinpath("solc-" + version)
if sys.platform == "win32":
return solc_bin + sep + "solc.exe"
return solc_bin
return str(solc_bin.joinpath("solc.exe"))
return str(solc_bin)


def set_solc_version(version = None):
def set_solc_version(version=None):
version = _check_version(version)
if not os.path.exists(get_executable(version)):
if not Path(get_executable(version)).exists():
install_solc(version)
global solc_version
solc_version = version


def get_installed_solc_versions():
return sorted([i[5:] for i in os.listdir(get_solc_folder()) if 'solc-v' in i])
return sorted(i.name[5:] for i in get_solc_folder().glob('solc-v*'))


def install_solc(version = None):
def install_solc(version=None):
version = _check_version(version)
if sys.platform.startswith('linux'):
_install_solc_linux(version)
Expand Down Expand Up @@ -86,26 +105,25 @@ def _check_subprocess_call(command, message=None, verbose=True, **proc_kwargs):


def _chmod_plus_x(executable_path):
current_st = os.stat(executable_path)
os.chmod(executable_path, current_st.st_mode | stat.S_IEXEC)
executable_path.chmod(executable_path.stat().st_mode | stat.S_IEXEC)


def _wget(url, path):
try:
_check_subprocess_call(
["wget", url, "-O", path],
["wget", url, "-O", str(path)],
"Downloading solc from {}".format(url)
)
except subprocess.CalledProcessError:
if os.path.exists(path):
os.remove(path)
if path.exists():
path.unlink()
raise


def _install_solc_linux(version):
download = DOWNLOAD_BASE.format(version, "solc-static-linux")
binary_path = get_solc_folder()+"solc-{}".format(version)
if os.path.exists(binary_path):
binary_path = get_solc_folder().joinpath("solc-" + version)
if binary_path.exists():
print("solc {} already installed at: {}".format(version, binary_path))
return
_wget(download, binary_path)
Expand All @@ -114,46 +132,50 @@ def _install_solc_linux(version):

def _install_solc_windows(version):
download = DOWNLOAD_BASE.format(version, "solidity-windows.zip")
zip_path = get_solc_folder() + 'solc_{}.zip'.format(version[1:])
install_folder = get_solc_folder()+"solc-{}".format(version)
if os.path.exists(install_folder):
install_folder = get_solc_folder().joinpath("solc-" + version)
if install_folder.exists():
print("solc {} already installed at: {}".format(version, install_folder))
return
print("Downloading solc {} from {}".format(version, download))
request = requests.get(download)
with zipfile.ZipFile(BytesIO(request.content)) as zf:
zf.extractall(install_folder)
zf.extractall(str(install_folder))


def _install_solc_osx(version):
tar_path = get_solc_folder() + "solc-{}.tar.gz".format(version)
source_folder = get_solc_folder() + "solidity_{}".format(version[1:])
if "v0.4" in version:
raise ValueError(
"Py-solc-x cannot build solc versions 0.4.x on OSX. If you install solc 0.4.x\n"
"using brew and reload solcx, the installed version will be available.\n\n"
"See https://github.com/ethereum/homebrew-ethereum for installation instructions.")
tar_path = get_solc_folder().joinpath("solc-{}.tar.gz".format(version))
source_folder = get_solc_folder().joinpath("solidity_" + version[1:])
download = DOWNLOAD_BASE.format(version, "solidity_{}.tar.gz".format(version[1:]))
binary_path = get_solc_folder()+"solc-{}".format(version)
if os.path.exists(binary_path):
binary_path = get_solc_folder().joinpath("solc-" + version)

if binary_path.exists():
print("solc {} already installed at: {}".format(version, binary_path))
return

_wget(download, tar_path)

with tarfile.open(tar_path, "r") as tar:
tar.extractall(get_solc_folder())
os.remove(tar_path)
with tarfile.open(str(tar_path), "r") as tar:
tar.extractall(str(get_solc_folder()))
tar_path.unlink()

_check_subprocess_call(
["sh", source_folder+'/scripts/install_deps.sh'],
["sh", str(source_folder.joinpath('scripts/install_deps.sh'))],
message="Running dependency installation script `install_deps.sh` @ {}".format(tar_path)
)

original_path = os.getcwd()
os.mkdir(source_folder+'/build')
os.chdir(source_folder+'/build')
source_folder.joinpath('build').mkdir(exist_ok=True)
os.chdir(str(source_folder.joinpath('build').resolve()))
try:
for cmd in (["cmake", ".."], ["make"]):
_check_subprocess_call(cmd, message="Running {}".format(cmd[0]))
os.chdir(original_path)
os.rename(source_folder+'/build/solc/solc', binary_path)
source_folder.joinpath('build/solc/solc').rename(binary_path)
except subprocess.CalledProcessError as e:
raise OSError(
"{} returned non-zero exit status {}".format(cmd[0], e.returncode) +
Expand All @@ -162,7 +184,7 @@ def _install_solc_osx(version):
)
finally:
os.chdir(original_path)
shutil.rmtree(source_folder)
shutil.rmtree(str(source_folder))

_chmod_plus_x(binary_path)

Expand Down
8 changes: 8 additions & 0 deletions solcx/wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ def solc_wrapper(solc_binary=None,
if "v0.5" in command[0]:
combined_json = combined_json.replace(',clone-bin','')
command.extend(('--combined-json', combined_json))

if gas:
command.append('--gas')

Expand Down Expand Up @@ -151,6 +152,13 @@ def solc_wrapper(solc_binary=None,
if evm_version:
command.extend(('--evm-version', evm_version))

if (
standard_json is None and
source_files is None and
"v0.5" in command[0]
):
command.append('-')

proc = subprocess.Popen(command,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
Expand Down

0 comments on commit 5117540

Please sign in to comment.