Skip to content

Commit

Permalink
Merge pull request #10 from iamdefinitelyahuman/v0.3.1
Browse files Browse the repository at this point in the history
v0.4.0
  • Loading branch information
iamdefinitelyahuman committed May 7, 2019
2 parents 03ab64f + 3e9e79c commit aa24257
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 65 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ develop-eggs
.installed.cfg
lib
lib64
venv

# Installer logs
pip-log.txt
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
0.4.0
-----

- Install new versions into solcx/temp - prevents issues with aborted installs
- set_solc_version raises instead of installing when requested version is not installed
- Do not allow version=None on installer methods

0.3.0
-----

Expand Down
26 changes: 12 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ pip install py-solc-x

## Installing the `solc` Executable

The first time py-solc-x is imported it will automatically check for an installed version of solc on your system. If none is found, it will install the most recently released version that is compatible with your operating system.

If you wish to install a different version you may do so from within python:
The first time py-solc-x is imported it will automatically check for an installed version of solc on your system. If none is found, you must manually install via `solcx.install_solc`

```python
>>> from solcx import install_solc
Expand All @@ -35,6 +33,16 @@ Or via the command line:
$ python -m solcx.install v0.4.25
```

Py-solc-x defaults to the most recent installed version set as the active one. To check or modify the active version:

```python
>>> from solcx import get_solc_version, set_solc_version
>>> get_solc_version()
Version('0.5.7+commit.6da8b019.Linux.gpp')
>>> set_solc_version('v0.4.25')
>>>
```

To install the highest compatible version based on the pragma version string:

```python
Expand All @@ -52,23 +60,13 @@ To set the version based on the pragma version string - this will use the highes
To view available and installed versions:

```python
>>> from solcx import get_installed_solc_versions, set_solc_version
>>> from solcx import get_installed_solc_versions, get_available_solc_versions
>>> get_installed_solc_versions()
['v0.4.25', 'v0.5.3']
>>> get_available_solc_versions()
['v0.5.8', 'v0.5.7', 'v0.5.6', 'v0.5.5', 'v0.5.4', 'v0.5.3', 'v0.5.2', 'v0.5.1', 'v0.5.0', 'v0.4.25', 'v0.4.24', 'v0.4.23', 'v0.4.22', 'v0.4.21', 'v0.4.20', 'v0.4.19', 'v0.4.18', 'v0.4.17', 'v0.4.16', 'v0.4.15', 'v0.4.14', 'v0.4.13', 'v0.4.12', 'v0.4.11']
```

To check or modify the active version:

```python
>>> from solcx import get_solc_version, set_solc_version
>>> solcx.get_solc_version()
Version('0.5.7+commit.6da8b019.Linux.gpp')
>>> set_solc_version('v0.4.25')
>>>
```

## Standard JSON Compilation

Use the `solcx.compile_standard` function to make use of the [standard-json](http://solidity.readthedocs.io/en/latest/using-the-compiler.html#compiler-input-and-output-json-description) compilation feature.
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.3.0',
version='0.4.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
8 changes: 2 additions & 6 deletions solcx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@
# 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])
if get_installed_solc_versions():
set_solc_version(get_installed_solc_versions()[-1])
4 changes: 4 additions & 0 deletions solcx/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,7 @@ def __str__(self):

class ContractsNotFound(SolcError):
message = "No contracts found during compilation"


class SolcNotInstalled(Exception):
pass
114 changes: 70 additions & 44 deletions solcx/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@
import tarfile
import zipfile

from .exceptions import SolcNotInstalled

DOWNLOAD_BASE = "https://github.com/ethereum/solidity/releases/download/{}/{}"
ALL_RELEASES = "https://api.github.com/repos/ethereum/solidity/releases"

MINIMAL_SOLC_VERSION = "0.4.11"
MINIMAL_SOLC_VERSION = "v0.4.11"
VERSION_REGEX = {
'darwin': "solidity_[0-9].[0-9].[0-9]{1,}.tar.gz",
'linux': "solc-static-linux",
Expand Down Expand Up @@ -80,16 +82,25 @@ def import_installed_solc():
def get_executable(version=None):
if not version:
version = solc_version
if not version:
raise SolcNotInstalled(
"Solc is not installed. Call solcx.get_available_solc_versions()"
" to view for available versions and solcx.install_solc() to install."
)
solc_bin = get_solc_folder().joinpath("solc-" + version)
if sys.platform == "win32":
return str(solc_bin.joinpath("solc.exe"))
solc_bin = solc_bin.joinpath("solc.exe")
if not solc_bin.exists():
raise SolcNotInstalled(
"solc {} has not been installed. ".format(version) +
"Use solcx.install_solc('{}') to install.".format(version)
)
return str(solc_bin)


def set_solc_version(version=None):
def set_solc_version(version):
version = _check_version(version)
if not Path(get_executable(version)).exists():
install_solc(version)
get_executable(version)
global solc_version
solc_version = version
print("Using solc version {}".format(solc_version))
Expand Down Expand Up @@ -141,20 +152,22 @@ def get_installed_solc_versions():
return sorted(i.name[5:] for i in get_solc_folder().glob('solc-v*'))


def install_solc(version=None):
def install_solc(version, allow_osx=False):
version = _check_version(version)
platform = _get_platform()
if platform == 'linux':
_install_solc_linux(version)
elif platform == 'darwin':
_install_solc_osx(version)
_install_solc_osx(version, allow_osx)
elif platform == 'win32':
_install_solc_windows(version)
binary_path = get_executable(version)
_check_subprocess_call(
[binary_path, '--version'],
message="Checking installed executable version @ {}".format(binary_path)
)
if not solc_version:
set_solc_version(version)
print("solc {} successfully installed at: {}".format(version, binary_path))


Expand Down Expand Up @@ -207,11 +220,9 @@ def _compare_versions(v1, v2, comp='='):


def _check_version(version):
if not version:
return get_available_solc_versions()[0]
version = "v0." + version.lstrip("v0.")
if version.count('.') != 2:
raise ValueError("solc version must be in the format v0.x.x")
raise ValueError("Invalid solc version '{}' - must be in the format v0.x.x".format(version))
v = [int(i) for i in version[1:].split('.')]
if v[1] < 4 or (v[1] == 4 and v[2] < 11):
raise ValueError("py-solc-x does not support solc versions <0.4.11")
Expand Down Expand Up @@ -246,52 +257,67 @@ def _wget(url, path):
raise


def _check_for_installed_version(version):
path = get_solc_folder().joinpath("solc-" + version)
if path.exists():
print("solc {} already installed at: {}".format(version, path))
return False
return path


def _get_temp_folder():
path = Path(__file__).parent.joinpath('temp')
if path.exists():
shutil.rmtree(str(path))
path.mkdir()
return path


def _install_solc_linux(version):
download = DOWNLOAD_BASE.format(version, "solc-static-linux")
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)
_chmod_plus_x(binary_path)
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)
_chmod_plus_x(binary_path)


def _install_solc_windows(version):
download = DOWNLOAD_BASE.format(version, "solidity-windows.zip")
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(str(install_folder))


def _install_solc_osx(version):
if "v0.4" in version:
install_folder = _check_for_installed_version(version)
if install_folder:
temp_path = _get_temp_folder()
print("Downloading solc {} from {}".format(version, download))
request = requests.get(download)
with zipfile.ZipFile(BytesIO(request.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:
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:])
"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:])
download = DOWNLOAD_BASE.format(version, "solidity_{}.tar.gz".format(version[1:]))
binary_path = get_solc_folder().joinpath("solc-" + version)

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

_wget(download, tar_path)

with tarfile.open(str(tar_path), "r") as tar:
tar.extractall(str(get_solc_folder()))
tar_path.unlink()
_wget(download, temp_path)
with tarfile.open(str(temp_path), "r") as tar:
tar.extractall(str(_get_temp_folder()))

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

original_path = os.getcwd()
Expand All @@ -310,7 +336,7 @@ def _install_solc_osx(version):
)
finally:
os.chdir(original_path)
shutil.rmtree(str(source_folder))
shutil.rmtree(str(temp_path.parent))

_chmod_plus_x(binary_path)

Expand Down

0 comments on commit aa24257

Please sign in to comment.